@Override
    public HttpResponseOutputStream<Chunk> write(final Path file, final TransferStatus status, final ConnectionCallback callback) throws BackgroundException {
        final String uploadUri;
        final String resourceId;
        if(null == status.getUrl()) {
            if(status.isExists()) {
                resourceId = fileid.getFileId(file);
                uploadUri = EueUploadHelper.updateResource(session, resourceId, status, UploadType.SIMPLE).getUploadURI();
            }
            else {
                final ResourceCreationResponseEntry uploadResourceCreationResponseEntry = EueUploadHelper
                        .createResource(session, fileid.getFileId(file.getParent()), file.getName(),
                                status, UploadType.SIMPLE);
                resourceId = EueResourceIdProvider.getResourceIdFromResourceUri(uploadResourceCreationResponseEntry.getHeaders().getLocation());
                uploadUri = uploadResourceCreationResponseEntry.getEntity().getUploadURI();
            }
        }
        else {
            uploadUri = status.getUrl();
            resourceId = status.getParameters().get(RESOURCE_ID);
        }
        final HttpResponseOutputStream<Chunk> stream = this.write(file, status,
                new DelayedHttpEntityCallable<Chunk>(file) {
                    @Override
                    public Chunk call(final HttpEntity entity) throws BackgroundException {
                        try {
                            final HttpResponse response;
                            final StringBuilder uploadUriWithParameters = new StringBuilder(uploadUri);
                            if(!Checksum.NONE.equals(status.getChecksum())) {
                                uploadUriWithParameters.append(String.format("&x_cdash64=%s",
                                        new ChunkListSHA256ChecksumCompute().compute(status.getLength(), Hex.decodeHex(status.getChecksum().hash))));
                            }
                            if(status.getLength() != -1) {
                                uploadUriWithParameters.append(String.format("&x_size=%d", status.getLength()));
                            }
                            if(status.isSegment()) {
                                // Chunked upload from large upload service
                                uploadUriWithParameters.append(String.format("&x_offset=%d",
                                        new HostPreferences(session.getHost()).getLong("eue.upload.multipart.size") * (status.getPart() - 1)));
                                final HttpPut request = new HttpPut(uploadUriWithParameters.toString());
                                request.setEntity(entity);
                                response = session.getClient().execute(request);
                            }
                            else {
                                final HttpPost request = new HttpPost(uploadUriWithParameters.toString());
                                request.setEntity(entity);
                                request.setHeader(HttpHeaders.CONTENT_TYPE, MimeTypeService.DEFAULT_CONTENT_TYPE);
                                response = session.getClient().execute(request);
                            }
                            try {
                                if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                                    return new Chunk(resourceId, status.getPart(), status.getLength(), status.getChecksum());
                                }
                                EntityUtils.updateEntity(response, new BufferedHttpEntity(response.getEntity()));
                                throw new EueExceptionMappingService().map(response);
                            }
                            finally {
                                EntityUtils.consume(response.getEntity());
                            }
                        }
                        catch(HttpResponseException e) {
                            throw new DefaultHttpResponseExceptionMappingService().map("Upload {0} failed", e, file);
                        }
                        catch(IOException e) {
                            throw new DefaultIOExceptionMappingService().map("Upload {0} failed", e, file);
                        }
                        catch(DecoderException e) {
                            throw new ChecksumException(LocaleFactory.localizedString("Checksum failure", "Error"), e);
                        }
                    }

                    @Override
                    public long getContentLength() {
                        return status.getLength();
                    }
                }
        );
        fileid.cache(file, resourceId);
        return stream;
    }
@Test(expected = TransferStatusCanceledException.class)
    public void testWriteCancel() throws Exception {
        final EueResourceIdProvider fileid = new EueResourceIdProvider(session);
        final EueWriteFeature writer = new EueWriteFeature(session, fileid);
        final byte[] content = RandomUtils.nextBytes(32769);
        final Path test = new Path(String.format("{%s", new AlphanumericRandomStringService().random()), EnumSet.of(Path.Type.file));
        {
            final BytecountStreamListener count = new BytecountStreamListener();
            final TransferStatus status = new TransferStatus() {
                @Override
                public void validate() throws ConnectionCanceledException {
                    if(count.getSent() >= 32768) {
                        throw new TransferStatusCanceledException();
                    }
                    super.validate();
                }
            };
            status.setLength(content.length);
            final StatusOutputStream<EueWriteFeature.Chunk> out = writer.write(test, status, new DisabledConnectionCallback());
            assertNotNull(out);
            new StreamCopier(status, status).withListener(count).transfer(new ByteArrayInputStream(content), out);
            assertFalse(new DefaultFindFeature(session).find(test));
            try {
                out.getStatus();
                fail();
            }
            catch(TransferCanceledException e) {
                //
            }
        }
        // Rewrite
        final TransferStatus status = new TransferStatus();
        status.setLength(content.length);
        final StatusOutputStream<EueWriteFeature.Chunk> out = writer.write(test, status, new DisabledConnectionCallback());
        assertNotNull(out);
        new StreamCopier(status, status).transfer(new ByteArrayInputStream(content), out);
        assertFalse(new DefaultFindFeature(session).find(test));
        new EueDeleteFeature(session, fileid).delete(Collections.singletonList(test), new DisabledLoginCallback(), new Delete.DisabledCallback());
    }