Promise<TreePath> (boolean refilterOnly, Object selection, @Nullable Long rebuildStartTime) { if (rebuildStartTime == null) { rebuildStartTime = System.nanoTime(); } AsyncPromise<TreePath> result = new AsyncPromise<>(); Long finalLastRebuildStartTime = rebuildStartTime; myStructureTreeModel.getInvoker().invoke(() -> { if (refilterOnly) { myFilteringStructure.refilter(); myStructureTreeModel.invalidateAsync().thenRun(() -> { (selection == null ? myAsyncTreeModel.accept(o -> TreeVisitor.Action.CONTINUE) : select(selection)) .onError(ignore2 -> { result.setError("rejected"); mySpeedSearch.refreshSelection(); // Selection failed, let the speed search reflect that by coloring itself red. }) .onSuccess(p -> EdtInvocationManager.invokeLaterIfNeeded(() -> { TreeUtil.expand(getTree(), myTreeModel instanceof StructureViewCompositeModel ? 3 : 2); TreeUtil.ensureSelection(myTree); mySpeedSearch.refreshSelection(); result.setResult(p); FileStructurePopupTimeTracker.logRebuildTime(System.nanoTime() - finalLastRebuildStartTime); })); }); } else { myTreeStructure.rebuildTree(); myStructureTreeModel.invalidateAsync().thenRun(() -> rebuildAndSelect(true, selection, finalLastRebuildStartTime).processed(result)); } }).onError(throwable -> result.setError(throwable)); return result; }