@Override
    public AttributedList<Path> list(final Path directory, final ListProgressListener listener) throws BackgroundException {
        if(directory.isRoot()) {
            return new DeepBoxesListService().list(directory, listener);
        }
        if(containerService.isDeepbox(directory)) { // in DeepBox
            return new BoxesListService().list(directory, listener);
        }
        if(containerService.isBox(directory)) { // in Box
            return new BoxListService().list(directory, listener);
        }
        final String deepBoxNodeId = fileid.getDeepBoxNodeId(directory);
        final String boxNodeId = fileid.getBoxNodeId(directory);
        if(containerService.isThirdLevel(directory)) { // in Inbox/Documents/Trash
            // N.B. although Documents and Trash have a nodeId, calling the listFiles1/listTrash1 API with
            // parentNode may fail!
            if(containerService.isInInbox(directory)) {
                return new NodeListService(new Contents() {
                    @Override
                    public NodeContent getNodes(final int offset) throws ApiException {
                        return new BoxRestControllerApi(session.getClient()).listQueue(deepBoxNodeId,
                                boxNodeId,
                                null,
                                offset, chunksize, "displayName asc");
                    }
                }).list(directory, listener);
            }
            if(containerService.isInDocuments(directory)) {
                return new NodeListService(new Contents() {
                    @Override
                    public NodeContent getNodes(final int offset) throws ApiException {
                        return new BoxRestControllerApi(session.getClient()).listFiles(
                                deepBoxNodeId,
                                boxNodeId,
                                offset, chunksize, "displayName asc");
                    }
                }).list(directory, listener);
            }
            if(containerService.isInTrash(directory)) {
                return new NodeListService(new Contents() {
                    @Override
                    public NodeContent getNodes(final int offset) throws ApiException {
                        return new BoxRestControllerApi(session.getClient()).listTrash(
                                deepBoxNodeId,
                                boxNodeId,
                                offset, chunksize, "displayName asc");
                    }
                }).list(directory, listener);
            }
        }
        // in subfolder of  Documents/Trash (Inbox has no subfolders)
        final String nodeId = fileid.getFileId(directory);
        if(containerService.isInTrash(directory)) {
            return new NodeListService(new Contents() {
                @Override
                public NodeContent getNodes(final int offset) throws ApiException {
                    return new BoxRestControllerApi(session.getClient()).listTrash1(
                            deepBoxNodeId,
                            boxNodeId,
                            nodeId,
                            offset, chunksize, "displayName asc");
                }
            }).list(directory, listener);
        }
        return new NodeListService(new Contents() {
            @Override
            public NodeContent getNodes(final int offset) throws ApiException {
                return new BoxRestControllerApi(session.getClient()).listFiles1(
                        deepBoxNodeId,
                        boxNodeId,
                        nodeId,
                        offset, chunksize, "displayName asc");
            }
        }).list(directory, listener);
    }
@Test
    public void testDuplicatesListing() throws Exception {
        final DeepboxIdProvider nodeid = new DeepboxIdProvider(session);

        final Path auditing = new Path("/ORG 4 - DeepBox Desktop App/ORG3:Box1/Documents/Invoices : Receipts/", EnumSet.of(Path.Type.directory));
        final Path folder = new Path(auditing, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory));
        new DeepboxDirectoryFeature(session, nodeid).mkdir(folder, new TransferStatus());

        final Path file = new Path(folder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file));
        for(int i = 0; i < 2; i++) {
            final HttpEntityEnclosingRequestBase request = new HttpPost(String.format("%s/api/v1/deepBoxes/%s/boxes/%s/files/%s",
                    session.getClient().getBasePath(),
                    nodeid.getDeepBoxNodeId(folder),
                    nodeid.getBoxNodeId(folder),
                    nodeid.getFileId(folder)));

            final MultipartEntityBuilder multipart = MultipartEntityBuilder.create();
            final ByteArrayOutputStream out = new ByteArrayOutputStream();
            out.write(new AlphanumericRandomStringService().random().getBytes(StandardCharsets.UTF_8));
            multipart.addBinaryBody("files", out.toByteArray(), ContentType.APPLICATION_OCTET_STREAM, file.getName());
            request.setEntity(multipart.build());
            CloseableHttpResponse execute = session.getClient().getClient().execute(request);
            assertEquals(201, execute.getStatusLine().getStatusCode());
        }

        final CoreRestControllerApi core = new CoreRestControllerApi(session.getClient());
        final NodeContent nodeContent = core.listNodeContent(nodeid.getFileId(folder), null, null, "modifiedTime desc");
        assertEquals(2, nodeContent.getNodes().size());
        final AttributedList<Path> listing = new DeepboxListService(session, nodeid).list(folder, new DisabledListProgressListener());
        assertEquals(2, listing.size());
        for(Path f : listing) {
            assertTrue(f.attributes().isDuplicate());
        }
        assertTrue(nodeContent.getNodes().get(0).getNodeId().equals(nodeid.getFileId(file)) ||
                nodeContent.getNodes().get(1).getNodeId().equals(nodeid.getFileId(file))
        );
        new DeepboxDeleteFeature(session, nodeid).delete(Collections.singletonList(folder), new DisabledLoginCallback(), new Delete.DisabledCallback());
    }