@Override
    public AttributedList<Path> list(final Path directory, final ListProgressListener listener) throws BackgroundException {
        try {
            final CloudBlobContainer container = session.getClient().getContainerReference(containerService.getContainer(directory).getName());
            final AttributedList<Path> children = new AttributedList<>();
            ResultContinuation token = null;
            ResultSegment<ListBlobItem> result;
            String prefix = StringUtils.EMPTY;
            if(!containerService.isContainer(directory)) {
                prefix = containerService.getKey(directory);
                if(!prefix.endsWith(String.valueOf(Path.DELIMITER))) {
                    prefix += Path.DELIMITER;
                }
            }
            boolean hasDirectoryPlaceholder = containerService.isContainer(directory);
            do {
                final BlobRequestOptions options = new BlobRequestOptions();
                result = container.listBlobsSegmented(prefix, false, EnumSet.noneOf(BlobListingDetails.class),
                        new HostPreferences(session.getHost()).getInteger("azure.listing.chunksize"), token, options, context);
                for(ListBlobItem object : result.getResults()) {
                    if(new SimplePathPredicate(new Path(object.getUri().getPath(), EnumSet.of(Path.Type.directory))).test(directory)) {
                        if(log.isDebugEnabled()) {
                            log.debug(String.format("Skip placeholder key %s", object));
                        }
                        hasDirectoryPlaceholder = true;
                        continue;
                    }
                    final PathAttributes attributes = new PathAttributes();
                    if(object instanceof CloudBlob) {
                        final CloudBlob blob = (CloudBlob) object;
                        attributes.setSize(blob.getProperties().getLength());
                        attributes.setModificationDate(blob.getProperties().getLastModified().getTime());
                        attributes.setETag(blob.getProperties().getEtag());
                        if(StringUtils.isNotBlank(blob.getProperties().getContentMD5())) {
                            attributes.setChecksum(Checksum.parse(Hex.encodeHexString(Base64.decodeBase64(blob.getProperties().getContentMD5()))));
                        }
                    }
                    // A directory is designated by a delimiter character.
                    final EnumSet<Path.Type> types = object instanceof CloudBlobDirectory
                            ? EnumSet.of(Path.Type.directory, Path.Type.placeholder) : EnumSet.of(Path.Type.file);
                    final Path child = new Path(directory, PathNormalizer.name(object.getUri().getPath()), types, attributes);
                    children.add(child);
                }
                listener.chunk(directory, children);
                token = result.getContinuationToken();
            }
            while(result.getHasMoreResults());
            if(!hasDirectoryPlaceholder && children.isEmpty()) {
                if(log.isWarnEnabled()) {
                    log.warn(String.format("No placeholder found for directory %s", directory));
                }
                throw new NotfoundException(directory.getAbsolute());
            }
            return children;
        }
        catch(StorageException e) {
            throw new AzureExceptionMappingService().map("Listing directory {0} failed", e, directory);
        }
        catch(URISyntaxException e) {
            throw new NotfoundException(e.getMessage(), e);
        }
    }
@Test(expected = NotfoundException.class)
    public void testListNotfoundContainer() throws Exception {
        final Path container = new Path("notfound-cyberduck", EnumSet.of(Path.Type.directory, Path.Type.volume));
        new AzureObjectListService(session, null).list(container, new DisabledListProgressListener());
    }