@Override
    public InputStream read(final Path file, final TransferStatus status, final ConnectionCallback callback) throws BackgroundException {
        final SMBSession.DiskShareWrapper share = session.openShare(file);
        try {
            final File entry = share.get().openFile(new SMBPathContainerService(session).getKey(file),
                    Collections.singleton(AccessMask.FILE_READ_DATA),
                    Collections.singleton(FileAttributes.FILE_ATTRIBUTE_NORMAL),
                    Collections.singleton(SMB2ShareAccess.FILE_SHARE_READ),
                    SMB2CreateDisposition.FILE_OPEN,
                    Collections.singleton(SMB2CreateOptions.FILE_NON_DIRECTORY_FILE));
            final InputStream stream = entry.getInputStream();
            if(status.isAppend()) {
                stream.skip(status.getOffset());
            }
            return new SMBInputStream(file, stream, entry);
        }
        catch(SMBRuntimeException e) {
            throw new SMBExceptionMappingService().map("Download {0} failed", e, file);
        }
        catch(IOException e) {
            throw new SMBTransportExceptionMappingService().map("Download {0} failed", e, file);
        }
        finally {
            session.releaseShare(share);
        }
    }
@Test
    public void testReadWriteConcurrency() throws Exception {
        final Path home = new DefaultHomeFinderService(session).find();
        final ExecutorService executor = Executors.newFixedThreadPool(50);
        final List<Future<Object>> results = new ArrayList<>();
        for(int i = 0; i < 100; i++) {
            final Future<Object> submitted = executor.submit(new Callable<Object>() {
                @Override
                public Object call() throws Exception {
                    final TransferStatus status = new TransferStatus();
                    final int length = 274;
                    final byte[] content = RandomUtils.nextBytes(length);
                    status.setLength(content.length);
                    final Path folder = new SMBDirectoryFeature(session).mkdir(
                            new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)), new TransferStatus());
                    final Path test = new SMBTouchFeature(session).touch(
                            new Path(folder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)), new TransferStatus());
                    final Write writer = new SMBWriteFeature(session);
                    status.setChecksum(writer.checksum(test, status).compute(new ByteArrayInputStream(content), status));
                    final OutputStream out = writer.write(test, status.exists(true), new DisabledConnectionCallback());
                    assertNotNull(out);
                    new StreamCopier(status, status).transfer(new ByteArrayInputStream(content), out);
                    final ByteArrayOutputStream buffer = new ByteArrayOutputStream(content.length);
                    final InputStream in = new SMBReadFeature(session).read(test, new TransferStatus().withLength(content.length), new DisabledConnectionCallback());
                    new StreamCopier(status, status).transfer(in, buffer);
                    assertArrayEquals(content, buffer.toByteArray());
                    return null;
                }
            });
            results.add(submitted);
        }
        for(Future<Object> result : results) {
            result.get();
        }
        executor.shutdown();
    }