void (@NotNull DefaultMutableTreeNode node, @NotNull TreeUpdatePass pass, @Nullable LoadedChildren loadedChildren, boolean forcedNow, boolean toSmartExpand, boolean forceUpdate, boolean descriptorIsUpToDate, boolean updateChildren) { try { NodeDescriptor<?> descriptor = getDescriptorFrom(node); if (descriptor == null) { removeFromUnbuilt(node); removeLoading(node, true); return; } boolean descriptorIsReady = descriptorIsUpToDate || pass.isUpdated(descriptor); boolean wasExpanded = myTree.isExpanded(new TreePath(node.getPath())) || isAutoExpand(node); boolean wasLeaf = node.getChildCount() == 0; boolean bgBuild = isToBuildInBackground(descriptor); boolean requiredToUpdateChildren = forcedNow || wasExpanded; if (!requiredToUpdateChildren && forceUpdate) { boolean alwaysPlus = getBuilder().isAlwaysShowPlus(descriptor); if (alwaysPlus && wasLeaf) { requiredToUpdateChildren = true; } else { requiredToUpdateChildren = !alwaysPlus; if (!requiredToUpdateChildren && !myUnbuiltNodes.contains(node)) { removeChildren(node); } } } AtomicReference<LoadedChildren> preloaded = new AtomicReference<>(loadedChildren); if (!requiredToUpdateChildren) { if (myUnbuiltNodes.contains(node) && node.getChildCount() == 0) { insertLoadingNode(node, true); } if (!descriptorIsReady) { update(descriptor, false); } return; } if (!forcedNow && !bgBuild && myUnbuiltNodes.contains(node)) { if (!descriptorIsReady) { update(descriptor, true); descriptorIsReady = true; } if (processAlwaysLeaf(node) || !updateChildren) { return; } Pair<Boolean, LoadedChildren> unbuilt = processUnbuilt(node, descriptor, pass, wasExpanded, null); if (unbuilt.getFirst()) { return; } preloaded.set(unbuilt.getSecond()); } boolean childForceUpdate = isChildNodeForceUpdate(node, forceUpdate, wasExpanded); if (!forcedNow && isToBuildInBackground(descriptor)) { boolean alwaysLeaf = processAlwaysLeaf(node); queueBackgroundUpdate( new UpdateInfo(descriptor, pass, canSmartExpand(node, toSmartExpand), wasExpanded, childForceUpdate, descriptorIsReady, !alwaysLeaf && updateChildren), node); } else { if (!descriptorIsReady) { update(descriptor, false) .onSuccess(new TreeConsumer<>("AbstractTreeUi.doUpdateChildren") { @Override public void perform() { if (processAlwaysLeaf(node) || !updateChildren) return; updateNodeChildrenNow(node, pass, preloaded.get(), toSmartExpand, wasExpanded, childForceUpdate); } }); } else { if (processAlwaysLeaf(node) || !updateChildren) return; updateNodeChildrenNow(node, pass, preloaded.get(), toSmartExpand, wasExpanded, childForceUpdate); } } } finally { if (!isReleased()) { processNodeActionsIfReady(node); } } }