void expandPaths(@NotNull Iterable<@NotNull TreePath> paths) {
      var started = 0L;
      var count = 0L;
      if (LOG.isDebugEnabled()) {
        started = System.currentTimeMillis();
      }
      var pathList = toList(paths);
      if (pathList.size() == 1) {
        var path = pathList.get(0);
        if (isNotLeaf(path)) {
          setExpandedState(path, true);
        }
        return;
      }
      pathList.sort(Comparator.comparing(TreePath::getPathCount));
      Set<TreePath> toExpand = new LinkedHashSet<>();
      Set<TreePath> toNotExpand = new HashSet<>();
      for (TreePath path : pathList) {
        ++count;
        shouldAllParentsBeExpanded(path, toExpand, toNotExpand);
      }
      Set<TreePath> expandRoots = new LinkedHashSet<>();
      try {
        beginBulkOperation();
        fireBulkExpandStarted();
        suspendExpandCollapseAccessibilityAnnouncements();
        for (TreePath path : toExpand) {
          if (isNotLeaf(path)) {
            markPathExpanded(path);
            fireTreeExpanded(path);
            var parent = path.getParentPath();
            if (parent == null || !toExpand.contains(parent)) {
              expandRoots.add(path);
            }
          }
        }
      }
      finally {
        resumeExpandCollapseAccessibilityAnnouncements();
        fireBulkExpandEnded();
        endBulkOperation();
      }
      if (accessibleContext != null) {
        // Only announce the topmost expanded nodes, to avoid spamming announcements.
        for (TreePath expandRoot : expandRoots) {
          fireAccessibleTreeExpanded(expandRoot);
        }
        ((AccessibleJTree)accessibleContext).fireVisibleDataPropertyChange();
      }
      if (LOG.isDebugEnabled()) {
        LOG.debug("Expanded " + count + " paths, time: " + (System.currentTimeMillis() - started) + " ms");
      }
    }
void expandPaths(@NotNull Iterable<@NotNull TreePath> paths)