private void addDocumentPermissions(final DocRef source,
                                        final DocRef dest,
                                        final boolean setOwnerPerm,
                                        final boolean cascade) {
        final UserRef userRef = securityContext.getUserRef();
        final boolean isFolder = NullSafe.test(source, DocRef::getType, DocumentTypes::isFolder);

        final Consumer<DocRef> docRefConsumer = destDocRef -> {
            if (setOwnerPerm) {
                // We are making them the owner therefore, they won't hold owner, and thus we will get
                // a perm exception as they need owner to change the perms. Hence, run as proc user.
                securityContext.asProcessingUser(() ->
                        documentPermissionService.setPermission(destDocRef, userRef, DocumentPermission.OWNER));
            }
            // User should now be in a position to add other perms
            if (source != null) {
                documentPermissionService.addDocumentPermissions(source, destDocRef);
            }
        };

        if (cascade && isFolder) {
            getDescendants(dest).forEach(descendant -> {
                final DocRef descendantDocRef = descendant.getDocRef();
                docRefConsumer.accept(descendantDocRef);
            });
        }

        docRefConsumer.accept(dest);
    }
General form a function that returns a list of explorer nodes from the tree DAO

@param folderDocRef  The root doc ref of the query
@param fetchFunction The function to call to get the list of ExplorerTreeNodes given a root ExplorerTreeNode
@return The list of converted ExplorerNodes
stroom-explorer/stroom-explorer-impl/src/main/java/stroom/explorer/impl/ExplorerNodeServiceImpl.java