private void handleFetchResult(final FetchExplorerNodesRequest criteria,
                                   final FetchExplorerNodeResult result) {
//        GWT.log("handleFetchResult - filter: " + result.getQualifiedFilterInput()
//                + " openItems: " + NullSafe.size(result.getOpenedItems())
//                + " tempOpenedItems: " + NullSafe.size(result.getTemporaryOpenedItems()));

        fetching = false;
        // Check if the filter settings have changed
        // since we were asked to fetch.
        if (criteria != currentCriteria) {
            // Some settings have changed so try again with the new settings.
            refresh();
        } else {
            onDataChanged(result);
            // If we have asked the server to ensure one or more nodes are visible then some
            // folders might have been opened to make this happen. The server will tell us which
            // folders these were, so we can add them to the set of open folders to ensure they
            // aren't immediately closed on the next refresh.
            if (result.getOpenedItems() != null) {
                for (final ExplorerNodeKey openedItem : result.getOpenedItems()) {
                    openItems.open(openedItem);
                }
            }
            if (result.getTemporaryOpenedItems() != null) {
                openItems.setTemporaryOpenItems(result.getTemporaryOpenedItems());
            }

            // Remember the new tree structure.
            this.currentRootNodes = result.getRootNodes();
            // Update the tree.
            final List<ExplorerNode> rows = update();

            // If we have been asked to ensure something is visible then chances are we are
            // expected to select it as well.
            // Try and find the item we have asked to make visible first and if we can't find
            // that try and select one of the folders that has been forced open in an attempt to
            // make the requested item visible.
            ExplorerNode nextSelection = forceSelection;
            if (nextSelection == null && NullSafe.hasItems(criteria.getEnsureVisible())) {
                final ExplorerNodeKey ensureVisibleUniqueKey = criteria.getEnsureVisible().iterator().next();
                nextSelection = NullSafe.get(ensureVisibleUniqueKey, ExplorerNode::fromExplorerNodeKey);

                // If we are allowing null selection then select the NULL node if we have been
                // asked to ensure NULL is selected after refresh.
                if (nextSelection == null && includeNullSelection) {
                    nextSelection = NULL_SELECTION;
                }
                int index = rows.indexOf(nextSelection);
                if (index == -1) {
                    nextSelection = null;

                    // In some use cases, like copy/move, the selected item will not be found as it is not
                    // a folder, so we want to select the parent of the 'selected item' so we can copy/move
                    // into that folder as a default.
                    if (selectParentIfNotFound) {
                        if (result.getOpenedItems() != null) {
                            final int openedItemsCnt = result.getOpenedItems().size();
                            for (int i = openedItemsCnt - 1; i >= 0 && nextSelection == null; i--) {
                                final ExplorerNodeKey item = result.getOpenedItems().get(i);
                                final ExplorerNode explorerNode = ExplorerNode.builder()
                                        .type(item.getType())
                                        .uuid(item.getUuid())
                                        .rootNodeUuid(item.getRootNodeUuid())
                                        .build();
                                if (rows.contains(explorerNode)) {
                                    nextSelection = explorerNode;
                                }
                            }
                        }
                    }
                } else {
                    // Reassign the selection because matches are only by UUID and this will ensure
                    // that we get the latest version with any new name it might have.
                    nextSelection = rows.get(index);
                }
            }
            if (nextSelection != null) {
//                GWT.log("nextSelection: " + nextSelection);
                explorerTree.setInitialSelectedItem(nextSelection);
            }

            // We do not want the root to always be forced open.
            minDepth = 0;

            // We do not want to ensure specific items are visible on every refresh as we might
            // want to close some folders. To do this we need to forget which nodes we wanted to
            // ensure visibility of. We can forget them now as we have a result that should have
            // opened required folders to make them visible.
            if (nextSelection != null && !NULL_SELECTION.equals(nextSelection)) {
//                GWT.log("Clearing ensureVisible & forceSelection");
                ensureVisible = null;
                forceSelection = null;
            }
        }
    }
For use when setting an initial value for the filter.
stroom-core-client/src/main/java/stroom/explorer/client/presenter/ExplorerTreeModel.java