public static void iterate(final int startInstruction,
                             final Instruction @NotNull [] instructions,
                             final @NotNull Function<? super Instruction, Operation> closure,
                             boolean prev) {
    //noinspection SSBasedInspection
    final IntArrayList 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 the 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);
        }
      }
    }
  }
public static void iterate(final int startInstruction,
                             final Instruction @NotNull [] instructions,
                             final @NotNull Function<? super Instruction, Operation> closure,
                             boolean prev)