public Token[] tokens(String exp, Collection<String> ignoreProperties) throws InvalidQueryException {
    ScanContext ctx = new ScanContext();
    ctx.addPropertiesToIgnore(SET_IGNORE);
    ctx.addPropertiesToIgnore(ignoreProperties);

    for (String tok : parseStringTokens(exp)) {
      List<TokenHandler> listHandlers = TOKEN_HANDLERS.get(ctx.getLastTokenType());
      boolean            processed    = false;
      int                idx          = 0;

      while (!processed && idx < listHandlers.size()) {
        processed = listHandlers.get(idx++).handleToken(tok, ctx);
      }

      if (! processed) {
        throw new InvalidQueryException("Invalid Query Token: token='" +
            tok + "\', previous token type=" + ctx.getLastTokenType());
      }
    }

    ctx.validateEndState();

    return ctx.getTokenList().toArray(new Token[ctx.getTokenList().size()]);
  }
Scan the provided query and generate a token stream to be used by the query parser.

@param exp               the query expression to scan
@param ignoreProperties  property names which should be ignored

@return an array of tokens
@throws InvalidQueryException if the query is invalid
ambari-server/src/main/java/org/apache/ambari/server/api/predicate/QueryLexer.java