void (@NotNull final List<? extends AbstractTreeNode<?>> kids, int i, final @NotNull Condition<? super AbstractTreeNode<?>> nonStopCondition, final VirtualFile file, final Object element, @NotNull final AsyncPromise<? super AbstractTreeNode<?>> async, @NotNull final ProgressIndicator indicator, final Ref<Object> virtualSelectTarget) { while (i < kids.size()) { final AbstractTreeNode<?> eachKid = kids.get(i); final boolean[] nodeWasCollapsed = {true}; final DefaultMutableTreeNode nodeForElement = getNodeForElement(eachKid); if (nodeForElement != null) { nodeWasCollapsed[0] = getTree().isCollapsed(new TreePath(nodeForElement.getPath())); } if (nonStopCondition.value(eachKid)) { final Promise<AbstractTreeNode<?>> result = expandPathTo(file, eachKid, element, nonStopCondition, indicator, virtualSelectTarget); result.onSuccess(abstractTreeNode -> { indicator.checkCanceled(); async.setResult(abstractTreeNode); }); if (result.getState() == Promise.State.PENDING) { final int next = i + 1; result.onError(error -> { indicator.checkCanceled(); if (nodeWasCollapsed[0] && virtualSelectTarget == null) { collapseChildren(eachKid, null); } expandChild(kids, next, nonStopCondition, file, element, async, indicator, virtualSelectTarget); }); return; } else { if (result.getState() == Promise.State.REJECTED) { indicator.checkCanceled(); if (nodeWasCollapsed[0] && virtualSelectTarget == null) { collapseChildren(eachKid, null); } i++; } else { return; } } } else { //filter tells us to stop here (for instance, in case of module nodes) break; } } async.cancel(); }