class B2ObjectListService implements ListService {

    @Override
    public AttributedList<Path> list(final Path directory, final ListProgressListener listener) throws BackgroundException {
        try {
            final AttributedList<Path> objects = new AttributedList<Path>();
            Marker marker;
            if(containerService.isContainer(directory)) {
                marker = new Marker(null, null);
            }
            else {
                marker = new Marker(String.format("%s%s", containerService.getKey(directory), Path.DELIMITER), null);
            }
            final String containerId = fileid.getFileid(containerService.getContainer(directory), new DisabledListProgressListener());
            // Seen placeholders
            final Map<String, Long> revisions = new HashMap<>();
            boolean hasDirectoryPlaceholder = containerService.isContainer(directory);
            do {
                if(log.isDebugEnabled()) {
                    log.debug(String.format("List directory %s with marker %s", directory, marker));
                }
                // In alphabetical order by file name, and by reverse of date/time uploaded for
                // versions of files with the same name.
                final B2ListFilesResponse response = session.getClient().listFileVersions(
                    containerId,
                    marker.nextFilename, marker.nextFileId, chunksize,
                    containerService.isContainer(directory) ? null : String.format("%s%s", containerService.getKey(directory), String.valueOf(Path.DELIMITER)),
                    String.valueOf(Path.DELIMITER));
                marker = this.parse(directory, objects, response, revisions);
                if(null == marker.nextFileId) {
                    if(!response.getFiles().isEmpty()) {
                        hasDirectoryPlaceholder = true;
                    }
                }
                listener.chunk(directory, objects);
            }
            while(marker.hasNext());
            if(!hasDirectoryPlaceholder && objects.isEmpty()) {
                throw new NotfoundException(directory.getAbsolute());
            }
            return objects;
        }
        catch(B2ApiException e) {
            throw new B2ExceptionMappingService().map("Listing directory {0} failed", e, directory);
        }
        catch(IOException e) {
            throw new DefaultIOExceptionMappingService().map(e);
        }
    }

    public  B2ObjectListService(final B2Session session, final B2FileidProvider fileid);
    public  B2ObjectListService(final B2Session session, final B2FileidProvider fileid, final int chunksize);

}