/**
   * Determines whether or not the given AST is in a valid hash code method. A valid hash code
   * method is considered to be a method of the signature {@code public int hashCode()}.
   *
   * @param aAST the AST from which to search for an enclosing hash code method definition
   * @return {@code true} if {@code aAST} is in the scope of a valid hash code method
   */
  private boolean isInHashCodeMethod(DetailAST aAST) {
    // if not in a code block, can't be in hashCode()
    if (!ScopeUtils.inCodeBlock(aAST)) {
      return false;
    }

    // find the method definition AST
    DetailAST methodDefAST = aAST.getParent();
    while ((null != methodDefAST) && (TokenTypes.METHOD_DEF != methodDefAST.getType())) {
      methodDefAST = methodDefAST.getParent();
    }

    if (null == methodDefAST) {
      return false;
    }

    // Check for 'hashCode' name.
    final DetailAST identAST = methodDefAST.findFirstToken(TokenTypes.IDENT);
    if (!"hashCode".equals(identAST.getText())) {
      return false;
    }

    // Check for no arguments.
    final DetailAST paramAST = methodDefAST.findFirstToken(TokenTypes.PARAMETERS);
    if (0 != paramAST.getChildCount()) {
      return false;
    }

    // we are in a 'public int hashCode()' method! The compiler will ensure
    // the method returns an 'int' and is public.
    return true;
  }
  /**
   * Finds the constant definition that contains aAST.
   *
   * @param aAST the AST
   * @return the constant def or null if aAST is not contained in a constant definition
   */
  private DetailAST findContainingConstantDef(DetailAST aAST) {
    DetailAST varDefAST = aAST;
    while ((varDefAST != null)
        && (varDefAST.getType() != TokenTypes.VARIABLE_DEF)
        && (varDefAST.getType() != TokenTypes.ENUM_CONSTANT_DEF)) {
      varDefAST = varDefAST.getParent();
    }

    // no containing variable definition?
    if (varDefAST == null) {
      return null;
    }

    // implicit constant?
    if (ScopeUtils.inInterfaceOrAnnotationBlock(varDefAST)
        || (varDefAST.getType() == TokenTypes.ENUM_CONSTANT_DEF)) {
      return varDefAST;
    }

    // explicit constant
    final DetailAST modifiersAST = varDefAST.findFirstToken(TokenTypes.MODIFIERS);
    if (modifiersAST.branchContains(TokenTypes.FINAL)) {
      return varDefAST;
    }

    return null;
  }
 /**
  * Determines whether an AST is a method definition for this check, with 0 parameters.
  *
  * @param aAST the method definition AST.
  * @return true if the method of aAST is a method for this check.
  */
 private boolean isOverridingMethod(DetailAST aAST) {
   if ((aAST.getType() != TokenTypes.METHOD_DEF)
       || ScopeUtils.inInterfaceOrAnnotationBlock(aAST)) {
     return false;
   }
   final DetailAST nameAST = aAST.findFirstToken(TokenTypes.IDENT);
   final String name = nameAST.getText();
   if (!getMethodName().equals(name)) {
     return false;
   }
   final DetailAST params = aAST.findFirstToken(TokenTypes.PARAMETERS);
   return (params.getChildCount() == 0);
 }
 @Override
 protected final boolean mustCheckName(DetailAST aAST) {
   final DetailAST modifiersAST = aAST.findFirstToken(TokenTypes.MODIFIERS);
   final boolean isFinal = (modifiersAST != null) && modifiersAST.branchContains(TokenTypes.FINAL);
   return (!isFinal && ScopeUtils.isLocalVariableDef(aAST));
 }
 /**
  * Determine the visibility modifier and raise the corresponding counter.
  *
  * @param aMethod The method-subtree from the AbstractSyntaxTree.
  */
 private void raiseCounter(DetailAST aMethod) {
   final MethodCounter actualCounter = mCounters.peek();
   final DetailAST temp = aMethod.findFirstToken(TokenTypes.MODIFIERS);
   final Scope scope = ScopeUtils.getScopeFromMods(temp);
   actualCounter.increment(scope);
 }