boolean () { if (dfsTree.isBackEmpty()) { return true; } int size = controlFlow.transitions.length; boolean[] loopEnters = dfsTree.loopEnters; IntOpenHashSet[] cycleIncoming = new IntOpenHashSet[size]; // really this may be array, since dfs already ensures no duplicates IntArrayList[] nonCycleIncoming = new IntArrayList[size]; int[] collapsedTo = new int[size]; int[] queue = new int[size]; int top; for (int i = 0; i < size; i++) { if (loopEnters[i]) { cycleIncoming[i] = new IntOpenHashSet(); } nonCycleIncoming[i] = new IntArrayList(); collapsedTo[i] = i; } // from whom back connections dfsTree.iterateBack((from, to) -> cycleIncoming[to].add(from)); // from whom ordinary connections dfsTree.iterateNonBack((from, to) -> nonCycleIncoming[to].add(from)); for (int w = size - 1; w >= 0 ; w--) { top = 0; // NB - it is modified later! IntOpenHashSet p = cycleIncoming[w]; if (p == null) { continue; } IntIterator it = p.iterator(); while (it.hasNext()) { queue[top++] = it.nextInt(); } while (top > 0) { int x = queue[--top]; IntList incoming = nonCycleIncoming[x]; for (int i = 0; i < incoming.size(); i++) { int y1 = collapsedTo[incoming.getInt(i)]; if (!dfsTree.isDescendant(y1, w)) { return false; } if (y1 != w && p.add(y1)) { queue[top++] = y1; } } } it = p.iterator(); while (it.hasNext()) { collapsedTo[it.next()] = w; } } return true; }