List<Integer> (int headNode) { final List<Integer> nodeIndexes = new ArrayList<>(); assert !myDoneNodes.get(headNode); myDoneNodes.set(headNode, true); nodeIndexes.add(headNode); final int startLayout = myGraphLayout.getLayoutIndex(headNode); DfsUtilKt.walk(headNode, currentNode -> { int currentLayout = myGraphLayout.getLayoutIndex(currentNode); List<Integer> downNodes = getDownNodes(myPermanentGraph, currentNode); for (int i = downNodes.size() - 1; i >= 0; i--) { int downNode = downNodes.get(i); if (myDoneNodes.get(downNode)) { if (myGraphLayout.getLayoutIndex(downNode) < startLayout) myEdgeRestrictions.addRestriction(currentNode, downNode); } else if (currentLayout <= myGraphLayout.getLayoutIndex(downNode)) { // almost ok node, except (may be) up nodes boolean hasUndoneUpNodes = false; for (int upNode : getUpNodes(myPermanentGraph, downNode)) { if (!myDoneNodes.get(upNode) && myGraphLayout.getLayoutIndex(upNode) <= myGraphLayout.getLayoutIndex(downNode)) { hasUndoneUpNodes = true; break; } } if (!hasUndoneUpNodes) { myDoneNodes.set(downNode, true); nodeIndexes.add(downNode); return downNode; } } } return Dfs.NextNode.NODE_NOT_FOUND; }); return nodeIndexes; }