Promise<Boolean> (@NotNull NodeDescriptor<?> nodeDescriptor, boolean now) { Promise<Boolean> promise; if (now || isPassthroughMode()) { promise = Promises.resolvedPromise(update(nodeDescriptor)); } else { AsyncPromise<Boolean> result = new AsyncPromise<>(); promise = result; boolean bgLoading = isToBuildInBackground(nodeDescriptor); boolean edt = isEdt(); if (bgLoading) { if (edt) { AtomicBoolean changes = new AtomicBoolean(); queueToBackground(new TreeRunnable("AbstractTreeUi.update: build") { @Override public void perform() { changes.set(update(nodeDescriptor)); } }, new TreeRunnable("AbstractTreeUi.update: post") { @Override public void perform() { result.setResult(changes.get()); } } ); } else { result.setResult(update(nodeDescriptor)); } } else { if (edt || !myWasEverShown) { result.setResult(update(nodeDescriptor)); } else { invokeLaterIfNeeded(false, new TreeRunnable("AbstractTreeUi.update: later") { @Override public void perform() { execute(new TreeRunnable("AbstractTreeUi.update: later execute") { @Override public void perform() { result.setResult(update(nodeDescriptor)); } }); } }); } } } promise.onSuccess(changes -> { if (!changes) { return; } invokeLaterIfNeeded(false, new TreeRunnable("AbstractTreeUi.update: on done result") { @Override public void perform() { Object element = nodeDescriptor.getElement(); DefaultMutableTreeNode node = element == null ? null : getNodeForElement(element, false); if (node != null) { TreePath path = getPathFor(node); if (myTree.isVisible(path)) { updateNodeImageAndPosition(node); } } } }); }); return promise; }