public void visitIfStatement(GrIfStatement ifStatement) {
    InstructionImpl ifInstruction = startNode(ifStatement);

    final GrCondition condition = ifStatement.getCondition();
    final GrStatement thenBranch = ifStatement.getThenBranch();
    final GrStatement elseBranch = ifStatement.getElseBranch();

    InstructionImpl conditionEnd = null;
    InstructionImpl thenEnd = null;
    InstructionImpl elseEnd = null;

    if (condition != null) {
      condition.accept(this);
      conditionEnd = myHead;
    }

    List<GotoInstruction> negations = collectAndRemoveAllPendingNegations(ifStatement);

    if (thenBranch != null) {
      thenBranch.accept(this);
      handlePossibleReturn(thenBranch);
      thenEnd = myHead;
      interruptFlow();
      readdPendingEdge(ifStatement);
    }

    myHead = reduceAllNegationsIntoInstruction(ifStatement, negations);
    if (myHead == null && conditionEnd != null) {
      myHead = conditionEnd;
    }
    if (elseBranch != null) {
      elseBranch.accept(this);
      handlePossibleReturn(elseBranch);
      elseEnd = myHead;
      interruptFlow();
    }

    if (thenBranch != null || elseBranch != null) {
      if (thenEnd != null || elseEnd != null || elseBranch == null) {
        final InstructionImpl end = new IfEndInstruction(ifStatement);
        addNode(end);

        if (thenEnd != null) {
          addEdge(thenEnd, end);
        }

        if (elseEnd != null) {
          addEdge(elseEnd, end);
        } else if (elseBranch == null) {
          addEdge(conditionEnd != null ? conditionEnd : ifInstruction, end);
        }
      }
    }

    finishNode(ifInstruction);
  }
 public void visitSwitchStatement(GrSwitchStatement switchStatement) {
   final GrCondition condition = switchStatement.getCondition();
   if (condition != null) {
     condition.accept(this);
   }
   final InstructionImpl instruction = startNode(switchStatement);
   final GrCaseSection[] sections = switchStatement.getCaseSections();
   if (!containsAllCases(switchStatement)) {
     addPendingEdge(switchStatement, instruction);
   }
   for (GrCaseSection section : sections) {
     myHead = instruction;
     section.accept(this);
   }
   finishNode(instruction);
 }
 public void visitWhileStatement(GrWhileStatement whileStatement) {
   final InstructionImpl instruction = startNode(whileStatement);
   final GrCondition condition = whileStatement.getCondition();
   if (condition != null) {
     condition.accept(this);
   }
   if (!alwaysTrue(condition)) {
     addPendingEdge(whileStatement, myHead); // break
   }
   final GrCondition body = whileStatement.getBody();
   if (body != null) {
     body.accept(this);
   }
   checkPending(instruction); // check for breaks targeted here
   if (myHead != null) addEdge(myHead, instruction); // loop
   interruptFlow();
   finishNode(instruction);
 }