static ExpressionTree flatten(ExpressionTree root) {
      if (root.getChildren() != null) {
        // iterate through the index, so that if we add more children,
        // they don't get re-visited
        for(int i=0; i < root.getChildren().size(); ++i) {
          ExpressionTree child = flatten(root.getChildren().get(i));
          // do we need to flatten?
          if (child.getOperator() == root.getOperator() &&
              child.getOperator() != ExpressionTree.Operator.NOT) {
            boolean first = true;
            for(ExpressionTree grandkid: child.getChildren()) {
              // for the first grandkid replace the original parent
              if (first) {
                first = false;
                root.getChildren().set(i, grandkid);
              } else {
                root.getChildren().add(++i, grandkid);
              }
            }
          } else {
            root.getChildren().set(i, child);
          }
        }
        // if we have a singleton AND or OR, just return the child
        if ((root.getOperator() == ExpressionTree.Operator.OR ||
            root.getOperator() == ExpressionTree.Operator.AND) &&
            root.getChildren().size() == 1) {
          return root.getChildren().get(0);
        }
      }
      return root;
    }
Converts multi-level ands and ors into single level ones.
@param root the expression to flatten
@return the flattened expression, which will always be root with
  potentially modified children.
storage-api/src/java/org/apache/hadoop/hive/ql/io/sarg/SearchArgumentImpl.java