private void changeHostNameToLowerCase(List<Expression> listExpressions) {
    try {
      for (Expression expression : listExpressions) {
        Object keyObject = expression.getLeftOperand();
        if (keyObject != null) {
          String key = keyObject.toString();
          if (key.endsWith("/host_name")) {
            if (expression.getRightOperand() != null) {
              expression.setRightOperand(expression.getRightOperand().toString().toLowerCase());
            }
          }
        }
      }
    } catch(Exception e) {
      LOG.error("Lowercase host_name value in expression failed with error:" + e);
    }
  }
Generate a Predicate instance from an array of tokens.
Each input token contains a type and a value.

Based on the token type and location, the tokens are first translated into a list of
expressions, both relational and logical.  These expressions are then merged into a tree
of expressions with a single root following operator precedence and explicit grouping rules.
Depending on the query, this merging of expressions into a tree of expressions may occur in
several passes, one pass per level of precedence starting at the highest level of precedence.

 The predicate is built by traversing the expression tree in-order with each node expressing itself
 as a predicate.

@param tokens  an array of tokens which represent the query,
               each token contains type and value information

@return a new predicate instance based on the supplied tokens
@throws InvalidQueryException if unable to parse the tokens and produce a predicate
ambari-server/src/main/java/org/apache/ambari/server/api/predicate/QueryParser.java