@Override
  public Object visit(ASTIfStatement node, Object data) {
    // (npath of if + npath of else (or 1) + bool_comp of if) * npath of
    // next

    int boolCompIf = sumExpressionComplexity(node.getFirstChildOfType(ASTExpression.class));

    int complexity = 0;

    List<JavaNode> statementChildren = new ArrayList<JavaNode>();
    for (int i = 0; i < node.jjtGetNumChildren(); i++) {
      if (node.jjtGetChild(i).getClass() == ASTStatement.class) {
        statementChildren.add((JavaNode) node.jjtGetChild(i));
      }
    }

    if (statementChildren.isEmpty()
        || statementChildren.size() == 1 && node.hasElse()
        || statementChildren.size() != 1 && !node.hasElse()) {
      throw new IllegalStateException("If node has wrong number of children");
    }

    // add path for not taking if
    if (!node.hasElse()) {
      complexity++;
    }

    for (JavaNode element : statementChildren) {
      complexity += (Integer) element.jjtAccept(this, data);
    }

    return Integer.valueOf(boolCompIf + complexity);
  }
 @Override
 public String toString() {
   return getImage()
       + ":"
       + location.getBeginLine()
       + ":"
       + location.getClass()
       + (this.isMethodOrConstructorInvocation() ? "(method call)" : "");
 }
  private int complexitySumOf(JavaNode node, int npathStart, Object data) {

    int npath = npathStart;
    JavaNode n;

    for (int i = 0; i < node.jjtGetNumChildren(); i++) {
      n = (JavaNode) node.jjtGetChild(i);
      npath += (Integer) n.jjtAccept(this, data);
    }

    return npath;
  }
 /**
  * Simply return if the image start with keyword 'this' or 'super'.
  *
  * @return true, if keyword is used, false otherwise.
  */
 public boolean useThisOrSuper() {
   Node node = location.jjtGetParent();
   if (node instanceof ASTPrimaryExpression) {
     ASTPrimaryExpression primaryExpression = (ASTPrimaryExpression) node;
     ASTPrimaryPrefix prefix = (ASTPrimaryPrefix) primaryExpression.jjtGetChild(0);
     if (prefix != null) {
       return prefix.usesSuperModifier() || prefix.usesThisModifier();
     }
   }
   return image.startsWith(THIS_DOT) || image.startsWith(SUPER_DOT);
 }
  @Override
  public Object visit(ASTSwitchStatement node, Object data) {
    // bool_comp of switch + sum(npath(case_range))

    int boolCompSwitch = sumExpressionComplexity(node.getFirstChildOfType(ASTExpression.class));

    int npath = 0;
    int caseRange = 0;
    for (int i = 0; i < node.jjtGetNumChildren(); i++) {
      JavaNode n = (JavaNode) node.jjtGetChild(i);

      // Fall-through labels count as 1 for complexity
      if (n instanceof ASTSwitchLabel) {
        npath += caseRange;
        caseRange = 1;
      } else {
        Integer complexity = (Integer) n.jjtAccept(this, data);
        caseRange *= complexity;
      }
    }
    // add in npath of last label
    npath += caseRange;
    return Integer.valueOf(boolCompSwitch + npath);
  }
  public boolean isOnLeftHandSide() {
    // I detest this method with every atom of my being
    Node primaryExpression;
    if (location.jjtGetParent() instanceof ASTPrimaryExpression) {
      primaryExpression = location.jjtGetParent().jjtGetParent();
    } else if (location.jjtGetParent().jjtGetParent() instanceof ASTPrimaryExpression) {
      primaryExpression = location.jjtGetParent().jjtGetParent().jjtGetParent();
    } else {
      throw new RuntimeException(
          "Found a NameOccurrence that didn't have an ASTPrimary Expression as parent or grandparent.  Parent = "
              + location.jjtGetParent()
              + " and grandparent = "
              + location.jjtGetParent().jjtGetParent());
    }

    if (isStandAlonePostfix(primaryExpression)) {
      return true;
    }

    if (primaryExpression.jjtGetNumChildren() <= 1) {
      return false;
    }

    if (!(primaryExpression.jjtGetChild(1) instanceof ASTAssignmentOperator)) {
      return false;
    }

    if (isPartOfQualifiedName() /* or is an array type */) {
      return false;
    }

    if (isCompoundAssignment(primaryExpression)) {
      return false;
    }

    return true;
  }
 public boolean isOnRightHandSide() {
   Node node = location.jjtGetParent().jjtGetParent().jjtGetParent();
   return node instanceof ASTExpression && node.jjtGetNumChildren() == 3;
 }