private void handleDo(Node node) {
   // The first edge can be the initial iteration as well as the iterations
   // after.
   createEdge(node, Branch.ON_TRUE, computeFallThrough(node.getFirstChild()));
   // The edge that leaves the do loop if the condition fails.
   createEdge(node, Branch.ON_FALSE, computeFollowNode(node));
   connectToPossibleExceptionHandler(node, NodeUtil.getConditionExpression(node));
 }
  private void handleWhile(Node node) {
    // Control goes to the first statement if the condition evaluates to true.
    createEdge(node, Branch.ON_TRUE, computeFallThrough(node.getFirstChild().getNext()));

    // Control goes to the follow() if the condition evaluates to false.
    createEdge(node, Branch.ON_FALSE, computeFollowNode(node));
    connectToPossibleExceptionHandler(node, NodeUtil.getConditionExpression(node));
  }
  private void handleIf(Node node) {
    Node thenBlock = node.getFirstChild().getNext();
    Node elseBlock = thenBlock.getNext();
    createEdge(node, Branch.ON_TRUE, computeFallThrough(thenBlock));

    if (elseBlock == null) {
      createEdge(node, Branch.ON_FALSE, computeFollowNode(node)); // not taken branch
    } else {
      createEdge(node, Branch.ON_FALSE, computeFallThrough(elseBlock));
    }
    connectToPossibleExceptionHandler(node, NodeUtil.getConditionExpression(node));
  }
  /**
   * @param n The node in question.
   * @param cfgNode The node to add
   * @param conditional true if the definition is not always executed.
   */
  private void computeMustDef(Node n, Node cfgNode, MustDef output, boolean conditional) {
    switch (n.getType()) {
      case Token.BLOCK:
      case Token.FUNCTION:
        return;

      case Token.WHILE:
      case Token.DO:
      case Token.IF:
        computeMustDef(NodeUtil.getConditionExpression(n), cfgNode, output, conditional);
        return;

      case Token.FOR:
        if (!NodeUtil.isForIn(n)) {
          computeMustDef(NodeUtil.getConditionExpression(n), cfgNode, output, conditional);
        } else {
          // for(x in y) {...}
          Node lhs = n.getFirstChild();
          Node rhs = lhs.getNext();
          if (NodeUtil.isVar(lhs)) {
            lhs = lhs.getLastChild(); // for(var x in y) {...}
          }
          if (NodeUtil.isName(lhs)) {
            addToDefIfLocal(lhs.getString(), cfgNode, rhs, output);
          }
        }
        return;

      case Token.AND:
      case Token.OR:
        computeMustDef(n.getFirstChild(), cfgNode, output, conditional);
        computeMustDef(n.getLastChild(), cfgNode, output, true);
        return;

      case Token.HOOK:
        computeMustDef(n.getFirstChild(), cfgNode, output, conditional);
        computeMustDef(n.getFirstChild().getNext(), cfgNode, output, true);
        computeMustDef(n.getLastChild(), cfgNode, output, true);
        return;

      case Token.VAR:
        for (Node c = n.getFirstChild(); c != null; c = c.getNext()) {
          if (c.hasChildren()) {
            computeMustDef(c.getFirstChild(), cfgNode, output, conditional);
            addToDefIfLocal(c.getString(), conditional ? null : cfgNode, c.getFirstChild(), output);
          }
        }
        return;

      default:
        if (NodeUtil.isAssignmentOp(n)) {
          if (NodeUtil.isName(n.getFirstChild())) {
            Node name = n.getFirstChild();
            computeMustDef(name.getNext(), cfgNode, output, conditional);
            addToDefIfLocal(
                name.getString(), conditional ? null : cfgNode, n.getLastChild(), output);
            return;
          } else if (NodeUtil.isGet(n.getFirstChild())) {
            // Treat all assignments to arguments as redefining the
            // parameters itself.
            Node obj = n.getFirstChild().getFirstChild();
            if (NodeUtil.isName(obj) && "arguments".equals(obj.getString())) {
              // TODO(user): More accuracy can be introduced
              // ie: We know exactly what arguments[x] is if x is a constant
              // number.
              escapeParameters(output);
            }
          }
        }

        if (NodeUtil.isName(n) && "arguments".equals(n.getString())) {
          escapeParameters(output);
        }

        // DEC and INC actually defines the variable.
        if (n.getType() == Token.DEC || n.getType() == Token.INC) {
          Node target = n.getFirstChild();
          if (NodeUtil.isName(target)) {
            addToDefIfLocal(target.getString(), conditional ? null : cfgNode, null, output);
            return;
          }
        }

        for (Node c = n.getFirstChild(); c != null; c = c.getNext()) {
          computeMustDef(c, cfgNode, output, conditional);
        }
    }
  }