@Override
    public void apply(final Path file, final Local local, final TransferStatus status,
                      final ProgressListener listener) throws BackgroundException {
        // Rename existing file before putting new file in place
        if(status.isExists()) {
            Path rename;
            do {
                final String proposal = MessageFormat.format(PreferencesFactory.get().getProperty("queue.upload.file.rename.format"),
                    FilenameUtils.getBaseName(file.getName()),
                    UserDateFormatterFactory.get().getMediumFormat(System.currentTimeMillis(), false).replace(Path.DELIMITER, '-').replace(':', '-'),
                    StringUtils.isNotBlank(file.getExtension()) ? String.format(".%s", file.getExtension()) : StringUtils.EMPTY);
                rename = new Path(file.getParent(), proposal, file.getType());
            }
            while(find.find(rename));
            if(log.isInfoEnabled()) {
                log.info(String.format("Rename existing file %s to %s", file, rename));
            }
            move.move(file, rename, new TransferStatus().exists(false), new Delete.DisabledCallback(), new DisabledConnectionCallback());
            if(log.isDebugEnabled()) {
                log.debug(String.format("Clear exist flag for file %s", file));
            }
            status.exists(false).getDisplayname().exists(false);
        }
        super.apply(file, local, status, listener);
    }
@Test
    public void testFileUploadWithTemporaryFilename() throws Exception {
        final Path file = new Path("/t", EnumSet.of(Path.Type.file));
        final AtomicBoolean found = new AtomicBoolean();
        final AtomicInteger moved = new AtomicInteger();
        final Find find = new Find() {
            @Override
            public boolean find(final Path f, final ListProgressListener listener) {
                if(f.equals(file)) {
                    found.set(true);
                    return true;
                }
                return false;
            }
        };
        final AttributesFinder attributes = new AttributesFinder() {
            @Override
            public PathAttributes find(final Path file, final ListProgressListener listener) {
                return new PathAttributes();
            }
        };
        final Host host = new Host(new TestProtocol());
        final NullSession session = new NullSession(host) {
            @Override
            @SuppressWarnings("unchecked")
            public <T> T _getFeature(final Class<T> type) {
                if(type.equals(Move.class)) {
                    return (T) new Move() {
                        @Override
                        public Path move(final Path source, final Path renamed, final TransferStatus status, final Delete.Callback callback, final ConnectionCallback connectionCallback) {
                            if(moved.incrementAndGet() == 1) {
                                // Rename existing target file
                                assertEquals(file, source);
                            }
                            else if(moved.get() == 2) {
                                // Move temporary renamed file in place
                                assertEquals(file, renamed);
                            }
                            else {
                                fail();
                            }
                            return renamed;
                        }

                        @Override
                        public boolean isRecursive(final Path source, final Path target) {
                            return true;
                        }

                    };
                }
                if(type.equals(Write.class)) {
                    return (T) new Write<Void>() {
                        @Override
                        public StatusOutputStream write(final Path file, final TransferStatus status, final ConnectionCallback callback) {
                            fail();
                            return null;
                        }
                    };
                }
                return null;
            }
        };
        final UploadFilterOptions options = new UploadFilterOptions(host).withTemporary(true);
        final RenameExistingFilter f = new RenameExistingFilter(new DisabledUploadSymlinkResolver(), session,
            options);
        f.withFinder(find).withAttributes(attributes);
        assertTrue(options.temporary);
        final TransferStatus status = f.prepare(file, new NullLocal("t"), new TransferStatus().exists(true), new DisabledProgressListener());
        f.apply(file, new NullLocal("t"), status, new DisabledProgressListener());
        assertFalse(status.isExists());
        assertFalse(status.getDisplayname().exists);
        assertNotNull(status.getRename());
        assertNotNull(status.getRename().remote);
        assertEquals(file, status.getDisplayname().remote);
        assertNull(status.getRename().local);
        f.apply(file, new NullLocal("t"), status, new DisabledProgressListener());
        // Complete
        status.setComplete();
        f.complete(file, new NullLocal("t"), status, new DisabledProgressListener());
        assertTrue(found.get());
        assertEquals(2, moved.get());
    }