@Override
    public StatusOutputStream<Void> write(final Path file, final TransferStatus status, final ConnectionCallback callback) throws BackgroundException {
        try {
            final java.nio.file.Path p = session.toPath(file);
            final Set<OpenOption> options = new HashSet<>();
            options.add(StandardOpenOption.WRITE);
            if(status.isAppend()) {
                if(!status.isExists()) {
                    options.add(StandardOpenOption.CREATE);
                }
            }
            else {
                if(status.isExists()) {
                    if(file.isSymbolicLink()) {
                        Files.delete(p);
                        options.add(StandardOpenOption.CREATE);
                    }
                    else {
                        options.add(StandardOpenOption.TRUNCATE_EXISTING);
                    }
                }
                else {
                    options.add(StandardOpenOption.CREATE_NEW);
                }
            }
            final FileChannel channel = FileChannel.open(session.toPath(file), options.stream().toArray(OpenOption[]::new));
            channel.position(status.getOffset());
            return new VoidStatusOutputStream(Channels.newOutputStream(channel));
        }
        catch(IOException e) {
            throw new LocalExceptionMappingService().map("Upload {0} failed", e, file);
        }
    }
@Test
    public void testWriteRangeEndFirst() throws Exception {
        final LocalSession session = new LocalSession(new Host(new LocalProtocol(), new LocalProtocol().getDefaultHostname()));
        session.open(new DisabledProxyFinder(), new DisabledHostKeyCallback(), new DisabledLoginCallback(), new DisabledCancelCallback());
        session.login(new DisabledLoginCallback(), new DisabledCancelCallback());
        final LocalWriteFeature feature = new LocalWriteFeature(session);
        final Path workdir = new LocalHomeFinderFeature().find();
        final Path test = new Path(workdir, UUID.randomUUID().toString(), EnumSet.of(Path.Type.file));
        final byte[] content = RandomUtils.nextBytes(2048);
        {
            // Write end of file first
            final TransferStatus status = new TransferStatus();
            status.setLength(1024L);
            status.setOffset(1024L);
            status.setAppend(true);
            final OutputStream out = feature.write(test, status, new DisabledConnectionCallback());
            new StreamCopier(status, status).withOffset(status.getOffset()).withLimit(status.getLength()).transfer(new ByteArrayInputStream(content), out);
            out.flush();
            out.close();
        }
        assertEquals(2048, new DefaultAttributesFinderFeature(session).find(test).getSize());
        {
            // Write beginning of file up to the last chunk
            final TransferStatus status = new TransferStatus().exists(true);
            status.setOffset(0L);
            status.setLength(1024L);
            status.setAppend(true);
            final OutputStream out = feature.write(test, status, new DisabledConnectionCallback());
            new StreamCopier(status, status).withOffset(status.getOffset()).withLimit(status.getLength()).transfer(new ByteArrayInputStream(content), out);
            out.flush();
            out.close();
        }
        assertEquals(2048, new DefaultAttributesFinderFeature(session).find(test).getSize());
        final ByteArrayOutputStream out = new ByteArrayOutputStream(content.length);
        IOUtils.copy(new LocalReadFeature(session).read(test, new TransferStatus().withLength(content.length), new DisabledConnectionCallback()), out);
        assertArrayEquals(content, out.toByteArray());
        assertTrue(new DefaultFindFeature(session).find(test));
        assertEquals(content.length, new DefaultAttributesFinderFeature(session).find(test).getSize());
        new LocalDeleteFeature(session).delete(Collections.singletonList(test), new DisabledLoginCallback(), new Delete.DisabledCallback());
    }