@Override
    public Boolean run(final Session<?> session) throws BackgroundException {
        final UnixPermission feature = session.getFeature(UnixPermission.class);
        if(log.isDebugEnabled()) {
            log.debug(String.format("Run with feature %s", feature));
        }
        for(Path file : files) {
            if(this.isCanceled()) {
                throw new ConnectionCanceledException();
            }
            final Permission merged = permissions.get(file);
            this.write(session, feature, file, merged);
        }
        return true;
    }
@Test
    public void testRun() throws Exception {
        final PermissionOverwrite permission = new PermissionOverwrite(
                new PermissionOverwrite.Action(true, true, true),
                new PermissionOverwrite.Action(null, false, false),
                new PermissionOverwrite.Action(true, false, false)
        );
        // Tests all actions set to read
        final Path path = new Path("a", EnumSet.of(Path.Type.directory), new TestPermissionAttributes(Permission.Action.read));
        final WritePermissionWorker worker = new WritePermissionWorker(Collections.singletonList(path), permission, new BooleanRecursiveCallback<>(true), new DisabledProgressListener());
        worker.run(new NullSession(new Host(new TestProtocol())) {
            @Override
            public AttributedList<Path> list(final Path file, final ListProgressListener listener) {
                final AttributedList<Path> children = new AttributedList<>();
                // test just group set to read
                children.add(new Path("b", EnumSet.of(Path.Type.file), new TestPermissionAttributes(Permission.Action.none, Permission.Action.read, Permission.Action.none)));
                return children;
            }

            @Override
            @SuppressWarnings("unchecked")
            public <T> T _getFeature(final Class<T> type) {
                if(type == UnixPermission.class) {
                    return (T) new UnixPermission() {
                        @Override
                        public void setUnixOwner(final Path file, final String owner) {
                            throw new UnsupportedOperationException();
                        }

                        @Override
                        public void setUnixGroup(final Path file, final String group) {
                            throw new UnsupportedOperationException();
                        }

                        @Override
                        public Permission getUnixPermission(final Path file) {
                            throw new UnsupportedOperationException();
                        }

                        @Override
                        public void setUnixPermission(final Path file, final TransferStatus status) throws BackgroundException {
                            assertEquals(new Permission(744), status.getPermission());
                        }
                    };
                }
                return super._getFeature(type);
            }
        });
    }