@Override
    public AttributedList<Path> list(final Path directory, final ListProgressListener listener) throws BackgroundException {
        final AttributedList<Path> children = new AttributedList<Path>();
        try (RemoteDirectory handle = session.sftp().openDir(directory.getAbsolute())) {
            for(List<RemoteResourceInfo> list : ListUtils.partition(handle.scan(new RemoteResourceFilter() {
                        @Override
                        public boolean accept(RemoteResourceInfo remoteResourceInfo) {
                            return true;
                        }
                    }),
                    new HostPreferences(session.getHost()).getInteger("sftp.listing.chunksize"))) {
                for(RemoteResourceInfo f : list) {
                    final PathAttributes attr = attributes.toAttributes(f.getAttributes());
                    final EnumSet<Path.Type> type = EnumSet.noneOf(Path.Type.class);
                    switch(f.getAttributes().getType()) {
                        case DIRECTORY:
                            type.add(Path.Type.directory);
                            break;
                        case SYMLINK:
                            type.add(Path.Type.symboliclink);
                            break;
                        default:
                            type.add(Path.Type.file);
                            break;
                    }
                    final Path file = new Path(directory, f.getName(), type, attr);
                    if(this.post(file)) {
                        children.add(file);
                        listener.chunk(directory, children);
                    }
                }
            }
            return children;
        }
        catch(IOException e) {
            throw new SFTPExceptionMappingService().map("Listing directory {0} failed", e, directory);
        }
    }
@Test
    public void testList() throws Exception {
        final Path home = new SFTPHomeDirectoryService(session).find();
        final String filename = String.format("%s%s", new AlphanumericRandomStringService().random(), new NFDNormalizer().normalize("ä"));
        final Path file = new Path(home, filename, EnumSet.of(Path.Type.file));
        final Path symlinkRelative = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file, AbstractPath.Type.symboliclink));
        final Path symlinkAbsolute = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file, AbstractPath.Type.symboliclink));
        final Path directory = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory));
        new SFTPTouchFeature(session).touch(file, new TransferStatus());
        new SFTPSymlinkFeature(session).symlink(symlinkRelative, file.getName());
        new SFTPSymlinkFeature(session).symlink(symlinkAbsolute, file.getAbsolute());
        new SFTPDirectoryFeature(session).mkdir(directory, new TransferStatus());
        final Permission permission = new Permission(Permission.Action.read_write, Permission.Action.read_write, Permission.Action.read_write);
        new SFTPUnixPermissionFeature(session).setUnixPermission(file, permission);
        final AttributedList<Path> list = new SFTPListService(session).list(home, new DisabledListProgressListener());
        assertTrue(list.contains(file));
        assertEquals(permission, list.get(file).attributes().getPermission());
        assertTrue(list.contains(directory));
        assertTrue(list.contains(symlinkRelative));
        assertEquals(file, list.get(symlinkRelative).getSymlinkTarget());
        assertTrue(list.contains(symlinkAbsolute));
        assertEquals(file, list.get(symlinkAbsolute).getSymlinkTarget());
        new SFTPDeleteFeature(session).delete(Arrays.asList(file, symlinkAbsolute, symlinkRelative, directory), new DisabledLoginCallback(), new Delete.DisabledCallback());
    }