class UploadTransfer extends Transfer {

    @Override
    public AbstractUploadFilter filter(final Session<?> source, final Session<?> destination, final TransferAction action, final ProgressListener listener) {
        if(log.isDebugEnabled()) {
            log.debug(String.format("Filter transfer with action %s and options %s", action, options));
        }
        final Symlink symlink = source.getFeature(Symlink.class);
        final UploadSymlinkResolver resolver = new UploadSymlinkResolver(symlink, roots);
        if(options.temporary) {
            options.withTemporary(source.getFeature(Write.class).temporary());
        }
        if(action.equals(TransferAction.resume)) {
            return new ResumeFilter(resolver, source, options).withCache(cache);
        }
        if(action.equals(TransferAction.rename)) {
            return new RenameFilter(resolver, source, options).withCache(cache);
        }
        if(action.equals(TransferAction.renameexisting)) {
            return new RenameExistingFilter(resolver, source, options).withCache(cache);
        }
        if(action.equals(TransferAction.skip)) {
            return new SkipFilter(resolver, source, options).withCache(cache);
        }
        if(action.equals(TransferAction.comparison)) {
            return new CompareFilter(resolver, source, options, listener).withCache(cache);
        }
        return new OverwriteFilter(resolver, source, options).withCache(cache);
    }

    public  UploadTransfer(final Host host, final Path root, final Local local);
    public  UploadTransfer(final Host host, final Path root, final Local local, final Filter<Local> f);
    public  UploadTransfer(final Host host, final List<TransferItem> roots);
    public  UploadTransfer(final Host host, final List<TransferItem> roots, final Filter<Local> f);
    public  UploadTransfer(final Host host, final List<TransferItem> roots, final Filter<Local> f, final Comparator<Local> comparator);

}