/**
   * @see
   *     <a>http://www.elasticsearch.org/guide/en/elasticsearch/client/java-api/current/query-dsl-filters.html</a>
   */
  private Query build(List<ColumnFilter> filterList, Operator operator) {
    if (filterList == null) return null;

    List<Query> results = new LinkedList<Query>();

    for (ColumnFilter filter : filterList) {
      Query result = null;

      // Core functions.
      if (filter instanceof CoreFunctionFilter) {
        result = buildColumnCoreFunctionFilter((CoreFunctionFilter) filter, metadata);
      }
      // Logical expressions.
      else if (filter instanceof LogicalExprFilter) {
        LogicalExprFilter f = (LogicalExprFilter) filter;
        LogicalExprType type = f.getLogicalOperator();
        if (LogicalExprType.AND.equals(type)) {
          result = buildLogicalExpressionFilter(f, Operator.AND);
        } else if (LogicalExprType.OR.equals(type)) {
          result = buildLogicalExpressionFilter(f, Operator.OR);
        } else if (LogicalExprType.NOT.equals(type)) {
          result = buildLogicalExpressionFilter(f, Operator.NOT);
        }
      }

      if (result != null) results.add(result);
    }

    return joinQueriesAndFilters(results, operator);
  }
  protected Query buildLogicalExpressionFilter(LogicalExprFilter filter, Operator operator) {
    if (filter == null) return null;

    List<ColumnFilter> columnFilters = filter.getLogicalTerms();
    if (columnFilters != null && !columnFilters.isEmpty()) {
      return build(columnFilters, operator);
    }

    return null;
  }