private Promise<List<TreePath>> expand(@NotNull JTree tree) {
    if (TreeUtil.isBulkExpandCollapseSupported(tree) && tree instanceof Tree jbTree && Registry.is("ide.tree.bulk.expand.tree.state", false)) {
      var promise = new AsyncPromise<List<TreePath>>();
      var bulkExpandVisitor = new MultiplePathsVisitor(myExpandedPaths);
      TreeUtil.promiseVisit(tree, bulkExpandVisitor).onProcessed(lastPathFound -> {
        jbTree.expandPaths(bulkExpandVisitor.pathsFound);
        promise.setResult(bulkExpandVisitor.pathsFound);
      });
      return promise;
    }
    else {
      if (myPresentationData == null) {
        return TreeUtil.promiseExpand(tree, myExpandedPaths.stream().map(elements -> new SinglePathVisitor(elements)));
      }
      else {
        // If we have cached presentation data, then everything is already shown and expanded,
        // and if the user collapses one of those nodes, we don't want to expand it again here,
        // as that looks and feels weird.
        // So instead, only load these nodes so they can replace the cached ones.
        var promise = new AsyncPromise<List<TreePath>>();
        var visitor = new MultiplePathsVisitor(myExpandedPaths);
        TreeUtil.promiseVisit(tree, visitor).onProcessed(lastPathFound -> {
          promise.setResult(visitor.pathsFound);
        });
        return promise;
      }
    }
  }
private Promise<List<TreePath>> expand(@NotNull JTree tree)