void (@NotNull TreeNode node, @NotNull TreePath path, @NotNull List<? super Node> result) { ThreadingAssertions.assertEventDispatchThread(); boolean shouldCheckChildren = true; if (myTree.isCollapsed(path)) { if (node instanceof Node) { ((Node)node).markNeedUpdate(); } shouldCheckChildren = false; // optimization: do not call expensive update() on invisible node } UsageViewTreeCellRenderer.RowLocation isVisible = myUsageViewTreeCellRenderer.isRowVisible(myTree.getRowForPath(new TreePath(((DefaultMutableTreeNode)node).getPath())), myTree.getVisibleRect()); // if row is below visible rectangle, no sense to update it or any children if (shouldCheckChildren && isVisible != UsageViewTreeCellRenderer.RowLocation.AFTER_VISIBLE_RECT) { for (int i = 0; i < node.getChildCount(); i++) { TreeNode child = node.getChildAt(i); checkNodeValidity(child, path.pathByAddingChild(child), result); } } // call update last, to let children a chance to update their cache first if (node instanceof Node && node != getModelRoot() && isVisible == UsageViewTreeCellRenderer.RowLocation.INSIDE_VISIBLE_RECT) { result.add((Node)node); } }