private List<Expression> mergeExpressions(List<Expression> listExpressions, int precedenceLevel) {
    if (listExpressions.size() > 1) {
      Stack<Expression> stack = new Stack<>();

      stack.push(listExpressions.remove(0));
      while (! listExpressions.isEmpty()) {
        Expression exp = stack.pop();
        Expression left = stack.empty() ? null : stack.pop();
        Expression right = listExpressions.remove(0);
        stack.addAll(exp.merge(left, right, precedenceLevel));
      }
      return mergeExpressions(new ArrayList<>(stack), precedenceLevel - 1);
    }
    return listExpressions;
  }
Merge list of expressions into a tree of logical/relational expressions.
This is done recursively in several passes, one per level of precedence starting at the
highest precedence level. Recursion exits when a single expression remains.

@param listExpressions  list of expressions to merge
@param precedenceLevel  the precedence level that is to be merged

@return  tree of expressions with a single root expression
ambari-server/src/main/java/org/apache/ambari/server/api/predicate/QueryParser.java