class ResumeFilter extends AbstractDownloadFilter {

    @Override
    public TransferStatus prepare(final Path file, final Local local, final TransferStatus parent, final ProgressListener progress) throws BackgroundException {
        final TransferStatus status = super.prepare(file, local, parent, progress);
        if(status.isSegmented()) {
            for(TransferStatus segmentStatus : status.getSegments()) {
                final Local segmentFile = segmentStatus.getRename().local;
                if(segmentFile.exists()) {
                    if(log.isInfoEnabled()) {
                        log.info(String.format("Determine if part %s can be skipped", segmentStatus));
                    }
                    if(segmentFile.attributes().getSize() > 0) {
                        segmentStatus.setAppend(true);
                        segmentStatus.setLength(segmentStatus.getLength() - segmentFile.attributes().getSize());
                        segmentStatus.setOffset(segmentStatus.getOffset() + segmentFile.attributes().getSize());
                        if(segmentStatus.getLength() == 0L) {
                            segmentStatus.setComplete();
                        }
                        // Recalculate transfer length
                        status.setAppend(true);
                        status.setLength(status.getLength() - segmentFile.attributes().getSize());
                    }
                }
            }
        }
        else {
            if(download.offset(file)) {
                if(local.isFile()) {
                    if(local.exists()) {
                        if(local.attributes().getSize() > 0) {
                            status.setAppend(true);
                            status.setLength(status.getLength() - local.attributes().getSize());
                            status.setOffset(status.getOffset() + local.attributes().getSize());
                            status.rename((Local) null);
                            if(status.getLength() == 0L) {
                                status.setComplete();
                            }
                        }
                    }
                }
            }
        }
        return status;
    }

    public  ResumeFilter(final SymlinkResolver<Path> symlinkResolver, final Session<?> session);
    public  ResumeFilter(final SymlinkResolver<Path> symlinkResolver, final Session<?> session,
                        final DownloadFilterOptions options);
    public  ResumeFilter(final SymlinkResolver<Path> symlinkResolver, final Session<?> session,
                        final DownloadFilterOptions options, final Download download);

}