@Override
  public void visitToken(DetailAST ast) {
    final int parentType = ast.getParent().getType();

    switch (ast.getType()) {
      case TokenTypes.OBJBLOCK:
        scopeStates.push(new ScopeState());
        break;
      case TokenTypes.MODIFIERS:
        if (parentType == TokenTypes.VARIABLE_DEF
            && ast.getParent().getParent().getType() == TokenTypes.OBJBLOCK) {
          processModifiers(ast);
        }
        break;
      case TokenTypes.CTOR_DEF:
        if (parentType == TokenTypes.OBJBLOCK) {
          processConstructor(ast);
        }
        break;
      case TokenTypes.METHOD_DEF:
        if (parentType == TokenTypes.OBJBLOCK) {
          final ScopeState state = scopeStates.peek();
          // nothing can be bigger than method's state
          state.currentScopeState = STATE_METHOD_DEF;
        }
        break;
      default:
        break;
    }
  }
  @Override
  public void visitToken(DetailAST ast) {
    final int parentType = ast.getParent().getType();

    switch (ast.getType()) {
      case TokenTypes.OBJBLOCK:
        scopeStates.push(new ScopeState());
        break;

      case TokenTypes.CTOR_DEF:
        if (parentType != TokenTypes.OBJBLOCK) {
          return;
        }

        processConstructor(ast);
        break;

      case TokenTypes.METHOD_DEF:
        if (parentType != TokenTypes.OBJBLOCK) {
          return;
        }

        processMethod(ast);
        break;

      case TokenTypes.MODIFIERS:
        if (parentType != TokenTypes.VARIABLE_DEF
            || ast.getParent().getParent().getType() != TokenTypes.OBJBLOCK) {
          return;
        }

        processModifiers(ast);
        break;

      default:
        break;
    }
  }