@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);
  }
  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;
  }
  @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);
  }