@Override
    public Boolean run(final Session<?> session) throws BackgroundException {
        final Metadata feature = session.getFeature(Metadata.class);
        if(log.isDebugEnabled()) {
            log.debug(String.format("Run with feature %s", feature));
        }
        for(Path file : files) {
            if(this.isCanceled()) {
                throw new ConnectionCanceledException();
            }
            this.write(session, feature, file);
        }
        return true;
    }
@Test
    public void testRunDifferent() throws Exception {
        final PathAttributes attributesA = new PathAttributes();
        {
            final Map<String, String> map = new HashMap<>();
            map.put("equal", "equal");
            map.put("different", "diff1");
            map.put("unique", "unique");
            attributesA.setMetadata(map);
        }
        final PathAttributes attributesB = new PathAttributes();
        {
            final Map<String, String> map = new HashMap<>();
            map.put("equal", "equal");
            map.put("different", "diff2");
            attributesB.setMetadata(map);
        }
        final List<Path> files = Arrays.asList(
            new Path("a", EnumSet.of(Path.Type.file),
                attributesA),
            new Path("b", EnumSet.of(Path.Type.file),
                attributesB));

        final Map<String, String> updated = new HashMap<>();
        updated.put("equal", "equal-changed");
        updated.put("unique", null);
        updated.put("different", null);

        WriteMetadataWorker worker = new WriteMetadataWorker(files, updated, false, new DisabledProgressListener()) {
            @Override
            public void cleanup(final Boolean map) {
                fail();
            }
        };
        final AtomicBoolean call = new AtomicBoolean();
        worker.run(new NullSession(new Host(new TestProtocol())) {
            @Override
            @SuppressWarnings("unchecked")
            public <T> T _getFeature(final Class<T> type) {
                if(type == Metadata.class) {
                    return (T) new Metadata() {
                        @Override
                        public Map<String, String> getDefault(final Local local) {
                            return Collections.emptyMap();
                        }

                        @Override
                        public Map<String, String> getMetadata(final Path file) {
                            throw new UnsupportedOperationException();
                        }

                        @Override
                        public void setMetadata(final Path file, final TransferStatus status) {
                            assertTrue(status.getMetadata().containsKey("equal"));
                            assertTrue(status.getMetadata().containsKey("different"));
                            assertEquals("equal-changed", status.getMetadata().get("equal"));

                            switch(file.getName()) {
                                case "a":
                                    assertTrue(status.getMetadata().containsKey("unique"));

                                    assertEquals("diff1", status.getMetadata().get("different"));
                                    assertEquals("unique", status.getMetadata().get("unique"));
                                    break;
                                case "b":
                                    assertFalse(status.getMetadata().containsKey("unique"));

                                    assertEquals("diff2", status.getMetadata().get("different"));
                                    break;
                                default:
                                    fail();
                                    break;
                            }
                            call.set(true);
                        }
                    };
                }
                return super._getFeature(type);
            }
        });
        assertTrue(call.get());
    }