/**
   * @param scalar
   * @return true if the scalar is defines as $GLOBALS call
   */
  private static boolean checkGLOBALS(Scalar scalar) {
    final String stringValue = scalar.getStringValue();
    if (scalar.getScalarType() != Scalar.TYPE_STRING || stringValue.length() < 3) {
      return false;
    }
    final char charAtZero = stringValue.charAt(0);
    final char charAtEnd = stringValue.charAt(stringValue.length() - 1);

    if (!detectString(charAtZero) || !detectString(charAtEnd)) {
      return false;
    }

    if (scalar.getParent().getType() == ASTNode.ARRAY_ACCESS) {
      ArrayAccess arrayAccess = (ArrayAccess) scalar.getParent();
      final Expression variableName = arrayAccess.getName();
      if (variableName.getType() == ASTNode.VARIABLE) {
        Variable var = (Variable) variableName;
        if (var.isDollared() && var.getName() instanceof Identifier) {
          final Identifier id = (Identifier) var.getName();
          return id.getName().equals("_GLOBALS") // $NON-NLS-1$
              || id.getName().equals("GLOBALS"); // $NON-NLS-1$
        }
      }
    }
    return false;
  }
    public boolean apply(ASTNode node) {

      // stops when found - that's the reason to use ApplyAll
      if (exists) return false;

      if (node.getType() == ASTNode.CLASS_DECLARATION
          || node.getType() == ASTNode.FUNCTION_DECLARATION) {
        isGlobalScope = false;
        node.childrenAccept(this);
        isGlobalScope = true;
        return false;
      } else if (node instanceof Identifier) {
        Identifier identifier = (Identifier) node;
        if (identifier.getParent().getType() == ASTNode.VARIABLE) {
          Variable variable = (Variable) identifier.getParent();
          if (variable.isDollared() && isGlobalScope && name.equals(identifier.getName())) {
            exists = true;
          }
        }
      } else if (node.getType() == ASTNode.GLOBAL_STATEMENT) {
        GlobalStatement globalStatement = (GlobalStatement) node;
        final List<Variable> variables = globalStatement.variables();
        for (final Variable variable : variables) {
          final Expression variableName = variable.getName();
          if (variable.isDollared() && variableName instanceof Identifier) {
            Identifier identifier = (Identifier) variableName;
            if (name.equals(identifier.getName())) {
              exists = true;
            }
          }
        }
      }

      return true;
    }
    public boolean apply(ASTNode node) {
      // stops when found - that's the reason to use ApplyAll
      if (exists) return false;

      if (node.getType() == ASTNode.VARIABLE) {
        Variable variable = (Variable) node;
        if (variable.isDollared()) {
          assert variable.getName().getType() == ASTNode.IDENTIFIER;
          Identifier identifier = (Identifier) variable.getName();
          if (identifier.getName().equals(name)) {
            exists = true;
          }
        }
      }
      return true;
    }
  /**
   * @param targetIdentifier
   * @param variable
   * @param isGlobal
   * @param globalStatement
   * @return true is the
   */
  private static boolean checkGlobal(
      Identifier targetIdentifier, final GlobalStatement globalStatement) {
    final List<Variable> variables = globalStatement.variables();
    for (final Variable current : variables) {
      // if the variable is reflection (eg. global $$var) skip
      if (current.getName().getType() == ASTNode.IDENTIFIER) {
        Identifier id = (Identifier) current.getName();

        // variables are case sensative
        if (id.getName().equals(targetIdentifier.getName())) {
          return true;
        }
      }
    }
    return false;
  }
 public void endVisit(Variable variable) {
   if (variable.getParent().getType() != ASTNode.FIELD_ACCESS
       || (variable.getParent().getType() == ASTNode.FIELD_ACCESS
           && ((FieldAccess) variable.getParent()).getDispatcher() == variable)) {
     Expression varName = variable.getName();
     if (params.contains(((Identifier) varName).getName())
         && varName instanceof Identifier
         && variable.isDollared()
         && variable.getParent().getType() != ASTNode.STATIC_FIELD_ACCESS) {
       highlight(variable);
     }
   }
 }
 private static final boolean isThisVariable(Variable variable) {
   return (variable.isDollared()
       && variable.getName() instanceof Identifier
       && THIS.equalsIgnoreCase(((Identifier) variable.getName()).getName()));
 }