private ExplorerNode addChildren(final ExplorerNode rootNode,
                                     final ExplorerNode parent,
                                     final FilteredTreeModel filteredModel,
                                     final OpenItems openItems,
                                     final int currentDepth,
                                     final List<ExplorerNodeKey> openedItems,
                                     final LocalMetrics metrics) {
        return metrics.measure("addChildren", () -> {
            ExplorerNode.Builder builder = parent.copy();
            builder.depth(currentDepth);

            final ExplorerNodeKey parentNodeKey = parent.getUniqueKey();

            // Remember if this item was forced open. This allows us to filter down the items that were actually opened
            // in the filtered tree as a result of forcing.
            if (openItems.isForcedOpen(parentNodeKey)) {
                openedItems.add(parentNodeKey);
            }

            final List<ExplorerNode> children = filteredModel.getChildren(parent);
            if (!parent.hasNodeFlagGroup(NodeFlagGroups.EXPANDER_GROUP) && NullSafe.isEmptyCollection(children)) {
                builder.setGroupedNodeFlag(NodeFlagGroups.EXPANDER_GROUP, NodeFlag.LEAF);
            } else if (openItems.isOpen(parentNodeKey)) {
                final List<ExplorerNode> newChildren = new ArrayList<>();
                for (final ExplorerNode child : NullSafe.list(children)) {
                    final ExplorerNode copy = addChildren(
                            rootNode,
                            child,
                            filteredModel,
                            openItems,
                            currentDepth + 1,
                            openedItems,
                            metrics);
                    newChildren.add(copy);
                }

                builder.setGroupedNodeFlag(NodeFlagGroups.EXPANDER_GROUP, NodeFlag.OPEN);
                builder.children(newChildren);
                builder.rootNodeUuid(rootNode);
            } else {
                builder.setGroupedNodeFlag(NodeFlagGroups.EXPANDER_GROUP, NodeFlag.CLOSED);
            }

            return builder.build();
        });
    }
@return True if any one of childNodes (or their descendants) has node info and is included
in treeModelOut
stroom-explorer/stroom-explorer-impl/src/main/java/stroom/explorer/impl/ExplorerServiceImpl.java