// Path: startupheroes-checks/src/main/java/es/startuphero/checkstyle/util/VariableUtils.java
// public static Scope getScopeOf(DetailAST variableAst) {
//   DetailAST variableModifiersNode = variableAst.findFirstToken(TokenTypes.MODIFIERS);
//   return ScopeUtil.getScopeFromMods(variableModifiersNode);
// }
// 
// Path: startupheroes-checks/src/main/java/es/startuphero/checkstyle/util/VariableUtils.java
// public static Map<String, DetailAST> getVariableNameAstMap(DetailAST classAst) {
//   List<DetailAST> variables = getVariables(classAst);
//   return variables.stream().collect(toMap(VariableUtils::getVariableName,
//                                           Function.identity(), (v1, v2) -> null,
//                                           LinkedHashMap::new));
// }


import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.api.Scope;
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static es.startuphero.checkstyle.util.VariableUtils.getScopeOf;
import static es.startuphero.checkstyle.util.VariableUtils.getVariableNameAstMap;
package es.startuphero.checkstyle.checks.coding;



/**
 * @author ozlem.ulag
 */
public class VariableDeclarationOrderCheck extends AbstractCheck {

  /**
   * A key is pointing to the warning message text in "messages.properties" file.
   */
  private static final String MSG_KEY = "illegal.variable.declaration.order";

  /**
   * set variable name to check declaration order.
   */
  private String variableName;

  /**
   * set declaration order of given variable.
   */
  private Integer declarationOrder;

  @Override
  public int[] getDefaultTokens() {
    return getAcceptableTokens();
  }

  @Override
  public int[] getAcceptableTokens() {
    return new int[] {TokenTypes.CLASS_DEF,
                      TokenTypes.INTERFACE_DEF,
                      TokenTypes.ENUM_DEF,
                      TokenTypes.ANNOTATION_DEF};
  }

  @Override
  public int[] getRequiredTokens() {
    return getAcceptableTokens();
  }

  @Override
  public void visitToken(DetailAST ast) {
    Map<String, DetailAST> variableNameAstMap = getVariableNameAstMap(ast);
    if (variableNameAstMap.containsKey(variableName)) {
      DetailAST variableAst = variableNameAstMap.get(variableName);
      Scope scopeOfVariable = getScopeOf(variableAst);
      variableNameAstMap = getVariableNameAstMap(ast, scopeOfVariable);
      if (isVariableNotInCorrectOrder(variableNameAstMap)) {
// Path: startupheroes-checks/src/main/java/es/startuphero/checkstyle/util/VariableUtils.java
// public static Scope getScopeOf(DetailAST variableAst) {
//   DetailAST variableModifiersNode = variableAst.findFirstToken(TokenTypes.MODIFIERS);
//   return ScopeUtil.getScopeFromMods(variableModifiersNode);
// }
// 
// Path: startupheroes-checks/src/main/java/es/startuphero/checkstyle/util/VariableUtils.java
// public static Map<String, DetailAST> getVariableNameAstMap(DetailAST classAst) {
//   List<DetailAST> variables = getVariables(classAst);
//   return variables.stream().collect(toMap(VariableUtils::getVariableName,
//                                           Function.identity(), (v1, v2) -> null,
//                                           LinkedHashMap::new));
// }


// Path: startupheroes-checks/src/main/java/es/startuphero/checkstyle/checks/coding/VariableDeclarationOrderCheck.java
import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.api.Scope;
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static es.startuphero.checkstyle.util.VariableUtils.getScopeOf;
import static es.startuphero.checkstyle.util.VariableUtils.getVariableNameAstMap;

package es.startuphero.checkstyle.checks.coding;



/**
 * @author ozlem.ulag
 */
public class VariableDeclarationOrderCheck extends AbstractCheck {

  /**
   * A key is pointing to the warning message text in "messages.properties" file.
   */
  private static final String MSG_KEY = "illegal.variable.declaration.order";

  /**
   * set variable name to check declaration order.
   */
  private String variableName;

  /**
   * set declaration order of given variable.
   */
  private Integer declarationOrder;

  @Override
  public int[] getDefaultTokens() {
    return getAcceptableTokens();
  }

  @Override
  public int[] getAcceptableTokens() {
    return new int[] {TokenTypes.CLASS_DEF,
                      TokenTypes.INTERFACE_DEF,
                      TokenTypes.ENUM_DEF,
                      TokenTypes.ANNOTATION_DEF};
  }

  @Override
  public int[] getRequiredTokens() {
    return getAcceptableTokens();
  }

  @Override
  public void visitToken(DetailAST ast) {
    Map<String, DetailAST> variableNameAstMap = getVariableNameAstMap(ast);
    if (variableNameAstMap.containsKey(variableName)) {
      DetailAST variableAst = variableNameAstMap.get(variableName);
      Scope scopeOfVariable = getScopeOf(variableAst);
      variableNameAstMap = getVariableNameAstMap(ast, scopeOfVariable);
      if (isVariableNotInCorrectOrder(variableNameAstMap)) {
        log(variableAst.getLineNo(), MSG_KEY, variableName, declarationOrder);