@Override
    public void delete(final Map<Path, TransferStatus> files, final PasswordCallback prompt, final Callback callback) throws BackgroundException {
        final CountDownLatch signal = new CountDownLatch(1);
        final AtomicReference<BackgroundException> failure = new AtomicReference<>();
        final ScheduledThreadPool scheduler = new ScheduledThreadPool(new LoggingUncaughtExceptionHandler() {
            @Override
            public void uncaughtException(final Thread t, final Throwable e) {
                super.uncaughtException(t, e);
                failure.set(new BackgroundException(e));
                signal.countDown();
            }
        }, "deletebatch");
        try {
            final Map<Path, List<String>> containers = new HashMap<>();
            for(Path f : files.keySet()) {
                final Path container = containerService.getContainer(f);
                if(containers.containsKey(container)) {
                    containers.get(container).add(containerService.getKey(f));
                }
                else {
                    final List<String> keys = new ArrayList<>();
                    keys.add(containerService.getKey(f));
                    containers.put(container, keys);
                }
                callback.delete(f);
            }
            for(Path container : containers.keySet()) {
                final DbxUserFilesRequests requests = new DbxUserFilesRequests(session.getClient(container));
                final DeleteBatchLaunch job = requests.deleteBatch(containers.get(container).stream().map(DeleteArg::new).collect(Collectors.toList()));
                final ScheduledFuture<?> f = scheduler.repeat(() -> {
                    try {
                        // Poll status
                        final DeleteBatchJobStatus status = requests.deleteBatchCheck(job.getAsyncJobIdValue());
                        if(status.isComplete()) {
                            final List<DeleteBatchResultEntry> entries = status.getCompleteValue().getEntries();
                            for(DeleteBatchResultEntry entry : entries) {
                                if(entry.isFailure()) {
                                    switch(entry.getFailureValue().tag()) {
                                        case PATH_LOOKUP:
                                            failure.set(new NotfoundException(entry.getFailureValue().toString()));
                                            break;
                                        default:
                                            failure.set(new InteroperabilityException());
                                    }
                                }
                            }
                            signal.countDown();
                        }
                        if(status.isFailed()) {
                            signal.countDown();
                        }
                    }
                    catch(DbxException e) {
                        failure.set(new DropboxExceptionMappingService().map(e));
                        signal.countDown();
                    }
                }, new HostPreferences(session.getHost()).getLong("dropbox.delete.poll.interval.ms"), TimeUnit.MILLISECONDS);
                while(!Uninterruptibles.awaitUninterruptibly(signal, Duration.ofSeconds(1))) {
                    try {
                        if(f.isDone()) {
                            Uninterruptibles.getUninterruptibly(f);
                        }
                    }
                    catch(ExecutionException e) {
                        for(Throwable cause : ExceptionUtils.getThrowableList(e)) {
                            Throwables.throwIfInstanceOf(cause, BackgroundException.class);
                        }
                        throw new DefaultExceptionMappingService().map(Throwables.getRootCause(e));
                    }
                }
                if(null != failure.get()) {
                    throw failure.get();
                }
            }
        }
        catch(DbxException e) {
            throw new DropboxExceptionMappingService().map(e);
        }
        finally {
            scheduler.shutdown();
        }
    }
@Test
    public void testDeleteFiles() throws Exception {
        final Path file1 = new DropboxTouchFeature(session).touch(
                new Path(new DefaultHomeFinderService(session).find(), new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)), new TransferStatus());
        final Path file2 = new DropboxTouchFeature(session).touch(
                new Path(new DefaultHomeFinderService(session).find(), new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)), new TransferStatus());
        new DropboxBatchDeleteFeature(session).delete(Arrays.asList(file1, file2), new DisabledLoginCallback(), new Delete.DisabledCallback());
        assertFalse(new DropboxFindFeature(session).find(file1));
        assertFalse(new DropboxFindFeature(session).find(file2));
    }