private static void markBranchReachable(
     ConditionalGotoInstruction instruction, boolean isTrueBranch) {
   if (isTrueBranch ^ instruction.isNegated()) {
     instruction.setTrueReachable();
   } else {
     instruction.setFalseReachable();
   }
 }
  public DfaInstructionState[] visitConditionalGoto(
      ConditionalGotoInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
    DfaValue cond = memState.pop();

    DfaValue condTrue;
    DfaValue condFalse;

    if (instruction.isNegated()) {
      condFalse = cond;
      condTrue = cond.createNegated();
    } else {
      condTrue = cond;
      condFalse = cond.createNegated();
    }

    if (condTrue == runner.getFactory().getConstFactory().getTrue()) {
      markBranchReachable(instruction, true);
      return new DfaInstructionState[] {
        new DfaInstructionState(runner.getInstruction(instruction.getOffset()), memState)
      };
    }

    if (condFalse == runner.getFactory().getConstFactory().getTrue()) {
      markBranchReachable(instruction, false);
      return nextInstruction(instruction, runner, memState);
    }

    ArrayList<DfaInstructionState> result = new ArrayList<DfaInstructionState>();

    DfaMemoryState thenState = memState.createCopy();
    DfaMemoryState elseState = memState.createCopy();

    if (thenState.applyCondition(condTrue)) {
      result.add(
          new DfaInstructionState(runner.getInstruction(instruction.getOffset()), thenState));
      markBranchReachable(instruction, true);
    }

    if (elseState.applyCondition(condFalse)) {
      result.add(
          new DfaInstructionState(runner.getInstruction(instruction.getIndex() + 1), elseState));
      markBranchReachable(instruction, false);
    }

    return result.toArray(new DfaInstructionState[result.size()]);
  }