@Override
    public InputStream read(final Path file, final TransferStatus status, final ConnectionCallback callback) throws BackgroundException {
        // Make sure file is available in cache
        final List<TransferStatus> chunks = bulk.query(Transfer.Type.download, file, status);
        // Sort chunks by offset
        chunks.sort(Comparator.comparingLong(TransferStatus::getOffset));
        final List<LazyInputStream> streams = new ArrayList<>();
        for(TransferStatus chunk : chunks) {
            final LazyInputStream in = new LazyInputStream(new LazyInputStream.OpenCallback() {
                @Override
                public InputStream open() throws IOException {
                    try {
                        return session.getClient().getObjectImpl(
                            false,
                            containerService.getContainer(file).getName(),
                            containerService.getKey(file),
                            null,
                            null,
                            null,
                            null,
                            null,
                            null,
                            file.attributes().getVersionId(),
                            new HashMap<String, Object>(),
                            chunk.getParameters())
                            .getDataInputStream();
                    }
                    catch(ServiceException e) {
                        throw new IOException(e.getMessage(), e);
                    }
                }
            });
            streams.add(in);
        }
        // Concatenate streams
        return new SequenceInputStream(Collections.enumeration(streams));
    }
@Test
    public void testReadNotFound() throws Exception {
        final TransferStatus status = new TransferStatus();
        final Path container = new SpectraDirectoryFeature(session, new SpectraWriteFeature(session)).mkdir(
                new Path(new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory, Path.Type.volume)), new TransferStatus());
        final Path test = new Path(container, "nosuchname", EnumSet.of(Path.Type.file));
        try {
            new SpectraBulkService(session).pre(Transfer.Type.download, Collections.singletonMap(new TransferItem(test), status), new DisabledConnectionCallback());
            new SpectraReadFeature(session).read(test, status, new DisabledConnectionCallback());
            fail();
        }
        catch(NotfoundException e) {
            // Expected
        }
        new SpectraDeleteFeature(session).delete(Collections.singletonList(container), new DisabledLoginCallback(), new Delete.DisabledCallback());
    }