void (final int startInstruction, final Instruction @NotNull [] instructions, final @NotNull Function<? super Instruction, Operation> closure, boolean prev) { final IntStack stack = new IntArrayList(instructions.length); final boolean[] visited = new boolean[instructions.length]; stack.push(startInstruction); while (!stack.isEmpty()) { ProgressManager.checkCanceled(); final int num = stack.popInt(); final Instruction instr = instructions[num]; final Operation nextOperation = closure.fun(instr); // Just ignore previous instructions for current node and move further if (nextOperation == Operation.CONTINUE) { continue; } // STOP iteration if (nextOperation == Operation.BREAK) { break; } // If we are here, we should process previous nodes in natural way assert nextOperation == Operation.NEXT; Collection<Instruction> nextToProcess = prev ? instr.allPred() : instr.allSucc(); for (Instruction pred : nextToProcess) { final int predNum = pred.num(); if (!visited[predNum]) { visited[predNum] = true; stack.push(predNum); } } } }