diff --git a/src/main/java/org/elasticsearch/action/percolate/PercolateRequest.java b/src/main/java/org/elasticsearch/action/percolate/PercolateRequest.java
index c60c8452ff1..f68745e0adf 100644
--- a/src/main/java/org/elasticsearch/action/percolate/PercolateRequest.java
+++ b/src/main/java/org/elasticsearch/action/percolate/PercolateRequest.java
@@ -30,11 +30,9 @@ import org.elasticsearch.common.bytes.BytesArray;
 import org.elasticsearch.common.bytes.BytesReference;
 import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.io.stream.StreamOutput;
-import org.elasticsearch.common.xcontent.ToXContent;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.common.xcontent.XContentFactory;
 import org.elasticsearch.common.xcontent.XContentType;
-import org.elasticsearch.search.builder.SearchSourceBuilderException;
 
 import java.io.IOException;
 import java.util.List;
@@ -227,13 +225,7 @@ public class PercolateRequest extends BroadcastOperationRequest<PercolateRequest
      * This is the preferred way to set the request body.
      */
     public PercolateRequest source(PercolateSourceBuilder sourceBuilder) {
-        try {
-            XContentBuilder builder = XContentFactory.contentBuilder(Requests.CONTENT_TYPE);
-            sourceBuilder.toXContent(builder, ToXContent.EMPTY_PARAMS);
-            this.source = builder.bytes();
-        } catch (Exception e) {
-            throw new SearchSourceBuilderException("Failed to build search source", e);
-        }
+        this.source = sourceBuilder.buildAsBytes(Requests.CONTENT_TYPE);
         return this;
     }
 
diff --git a/src/main/java/org/elasticsearch/action/percolate/PercolateSourceBuilder.java b/src/main/java/org/elasticsearch/action/percolate/PercolateSourceBuilder.java
index f40dab0ff7d..af8aa43837e 100644
--- a/src/main/java/org/elasticsearch/action/percolate/PercolateSourceBuilder.java
+++ b/src/main/java/org/elasticsearch/action/percolate/PercolateSourceBuilder.java
@@ -22,6 +22,7 @@ package org.elasticsearch.action.percolate;
 import com.google.common.collect.Lists;
 
 import org.elasticsearch.ElasticsearchGenerationException;
+import org.elasticsearch.action.support.ToXContentToBytes;
 import org.elasticsearch.client.Requests;
 import org.elasticsearch.common.bytes.BytesArray;
 import org.elasticsearch.common.bytes.BytesReference;
@@ -44,7 +45,7 @@ import java.util.Map;
 /**
  * Builder to create the percolate request body.
  */
-public class PercolateSourceBuilder implements ToXContent {
+public class PercolateSourceBuilder extends ToXContentToBytes {
 
     private DocBuilder docBuilder;
     private QueryBuilder queryBuilder;
diff --git a/src/main/java/org/elasticsearch/action/support/QuerySourceBuilder.java b/src/main/java/org/elasticsearch/action/support/QuerySourceBuilder.java
index 3fa385d7fb1..9266310a48b 100644
--- a/src/main/java/org/elasticsearch/action/support/QuerySourceBuilder.java
+++ b/src/main/java/org/elasticsearch/action/support/QuerySourceBuilder.java
@@ -19,18 +19,14 @@
 
 package org.elasticsearch.action.support;
 
-import org.elasticsearch.ExceptionsHelper;
 import org.elasticsearch.common.bytes.BytesReference;
-import org.elasticsearch.common.xcontent.ToXContent;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.common.xcontent.XContentFactory;
-import org.elasticsearch.common.xcontent.XContentType;
 import org.elasticsearch.index.query.QueryBuilder;
-import org.elasticsearch.search.builder.SearchSourceBuilderException;
 
 import java.io.IOException;
 
-public class QuerySourceBuilder implements ToXContent {
+public class QuerySourceBuilder extends ToXContentToBytes {
 
     private QueryBuilder queryBuilder;
 
@@ -68,25 +64,4 @@ public class QuerySourceBuilder implements ToXContent {
             }
         }
     }
-
-    public BytesReference buildAsBytes(XContentType contentType) throws SearchSourceBuilderException {
-        try {
-            XContentBuilder builder = XContentFactory.contentBuilder(contentType);
-            toXContent(builder, ToXContent.EMPTY_PARAMS);
-            return builder.bytes();
-        } catch (Exception e) {
-            throw new SearchSourceBuilderException("Failed to build search source", e);
-        }
-    }
-
-    @Override
-    public String toString() {
-        try {
-            XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON).prettyPrint();
-            toXContent(builder, ToXContent.EMPTY_PARAMS);
-            return builder.string();
-        } catch (Exception e) {
-            return "{ \"error\" : \"" + ExceptionsHelper.detailedMessage(e) + "\"}";
-        }
-    }
 }
diff --git a/src/main/java/org/elasticsearch/action/support/ToXContentToBytes.java b/src/main/java/org/elasticsearch/action/support/ToXContentToBytes.java
new file mode 100644
index 00000000000..b78e291ffaa
--- /dev/null
+++ b/src/main/java/org/elasticsearch/action/support/ToXContentToBytes.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.action.support;
+
+import org.elasticsearch.ElasticsearchException;
+import org.elasticsearch.ExceptionsHelper;
+import org.elasticsearch.client.Requests;
+import org.elasticsearch.common.bytes.BytesReference;
+import org.elasticsearch.common.xcontent.ToXContent;
+import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.common.xcontent.XContentFactory;
+import org.elasticsearch.common.xcontent.XContentType;
+
+/**
+ * Base class for {@link ToXContent} implementation that also support conversion to {@link BytesReference} for serialization purposes
+ */
+public abstract class ToXContentToBytes implements ToXContent {
+
+    private final XContentType defaultType;
+
+    protected ToXContentToBytes() {
+        this.defaultType = Requests.CONTENT_TYPE;
+    }
+
+    protected ToXContentToBytes(XContentType defaultType) {
+        this.defaultType = defaultType;
+    }
+
+    /**
+     * Returns a {@link org.elasticsearch.common.bytes.BytesReference}
+     * containing the {@link ToXContent} output in binary format.
+     * Builds the request based on the default {@link XContentType}, either {@link Requests#CONTENT_TYPE} or provided as a constructor argument
+     */
+    public final BytesReference buildAsBytes() {
+        return buildAsBytes(defaultType);
+    }
+
+    /**
+     * Returns a {@link org.elasticsearch.common.bytes.BytesReference}
+     * containing the {@link ToXContent} output in binary format.
+     * Builds the request as the provided <code>contentType</code>
+     */
+    public final BytesReference buildAsBytes(XContentType contentType) {
+        try {
+            XContentBuilder builder = XContentFactory.contentBuilder(contentType);
+            toXContent(builder, ToXContent.EMPTY_PARAMS);
+            return builder.bytes();
+        } catch (Exception e) {
+            throw new ElasticsearchException("Failed to build ToXContent", e);
+        }
+    }
+
+    @Override
+    public final String toString() {
+        try {
+            XContentBuilder builder = XContentFactory.jsonBuilder();
+            builder.prettyPrint();
+            toXContent(builder, EMPTY_PARAMS);
+            return builder.string();
+        } catch (Exception e) {
+            return "{ \"error\" : \"" + ExceptionsHelper.detailedMessage(e) + "\"}";
+        }
+    }
+}
diff --git a/src/main/java/org/elasticsearch/index/query/AndQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/AndQueryBuilder.java
index 8acd58774ef..e0ecafca285 100644
--- a/src/main/java/org/elasticsearch/index/query/AndQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/AndQueryBuilder.java
@@ -30,7 +30,7 @@ import java.util.ArrayList;
  * @deprecated Use {@link BoolQueryBuilder} instead
  */
 @Deprecated
-public class AndQueryBuilder extends BaseQueryBuilder {
+public class AndQueryBuilder extends QueryBuilder {
 
     private ArrayList<QueryBuilder> filters = Lists.newArrayList();
 
diff --git a/src/main/java/org/elasticsearch/index/query/BaseQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/BaseQueryBuilder.java
deleted file mode 100644
index daa61f9d6e5..00000000000
--- a/src/main/java/org/elasticsearch/index/query/BaseQueryBuilder.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Licensed to Elasticsearch under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.elasticsearch.index.query;
-
-import org.elasticsearch.ElasticsearchException;
-import org.elasticsearch.common.bytes.BytesReference;
-import org.elasticsearch.common.xcontent.XContentBuilder;
-import org.elasticsearch.common.xcontent.XContentFactory;
-import org.elasticsearch.common.xcontent.XContentType;
-
-import java.io.IOException;
-
-/**
- *
- */
-public abstract class BaseQueryBuilder implements QueryBuilder {
-
-    @Override
-    public String toString() {
-        try {
-            XContentBuilder builder = XContentFactory.jsonBuilder();
-            builder.prettyPrint();
-            toXContent(builder, EMPTY_PARAMS);
-            return builder.string();
-        } catch (Exception e) {
-            throw new ElasticsearchException("Failed to build query", e);
-        }
-    }
-
-    @Override
-    public BytesReference buildAsBytes() {
-        return buildAsBytes(XContentType.JSON);
-    }
-
-    @Override
-    public BytesReference buildAsBytes(XContentType contentType) {
-        try {
-            XContentBuilder builder = XContentFactory.contentBuilder(contentType);
-            toXContent(builder, EMPTY_PARAMS);
-            return builder.bytes();
-        } catch (Exception e) {
-            throw new ElasticsearchException("Failed to build query", e);
-        }
-    }
-
-    @Override
-    public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
-        builder.startObject();
-        doXContent(builder, params);
-        builder.endObject();
-        return builder;
-    }
-
-    protected abstract void doXContent(XContentBuilder builder, Params params) throws IOException;
-}
diff --git a/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java
index da5c93fe380..56cee6e38fc 100644
--- a/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java
@@ -29,7 +29,7 @@ import java.util.List;
 /**
  * A Query that matches documents matching boolean combinations of other queries.
  */
-public class BoolQueryBuilder extends BaseQueryBuilder implements BoostableQueryBuilder<BoolQueryBuilder> {
+public class BoolQueryBuilder extends QueryBuilder implements BoostableQueryBuilder<BoolQueryBuilder> {
 
     private final List<QueryBuilder> mustClauses = new ArrayList<>();
 
diff --git a/src/main/java/org/elasticsearch/index/query/BoostingQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/BoostingQueryBuilder.java
index fef3cd30734..9d67469deb0 100644
--- a/src/main/java/org/elasticsearch/index/query/BoostingQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/BoostingQueryBuilder.java
@@ -35,7 +35,7 @@ import java.io.IOException;
  * multiplied by the supplied "boost" parameter, so this should be less than 1 to achieve a
  * demoting effect
  */
-public class BoostingQueryBuilder extends BaseQueryBuilder implements BoostableQueryBuilder<BoostingQueryBuilder> {
+public class BoostingQueryBuilder extends QueryBuilder implements BoostableQueryBuilder<BoostingQueryBuilder> {
 
     private QueryBuilder positiveQuery;
 
diff --git a/src/main/java/org/elasticsearch/index/query/CommonTermsQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/CommonTermsQueryBuilder.java
index 3e313ce8408..9381064191c 100644
--- a/src/main/java/org/elasticsearch/index/query/CommonTermsQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/CommonTermsQueryBuilder.java
@@ -42,7 +42,7 @@ import java.io.IOException;
  * execution times significantly if applicable.
  * <p>
  */
-public class CommonTermsQueryBuilder extends BaseQueryBuilder implements BoostableQueryBuilder<CommonTermsQueryBuilder> {
+public class CommonTermsQueryBuilder extends QueryBuilder implements BoostableQueryBuilder<CommonTermsQueryBuilder> {
 
     public static enum Operator {
         OR, AND
diff --git a/src/main/java/org/elasticsearch/index/query/ConstantScoreQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/ConstantScoreQueryBuilder.java
index 5ad250dde97..bdcbe9cc76c 100644
--- a/src/main/java/org/elasticsearch/index/query/ConstantScoreQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/ConstantScoreQueryBuilder.java
@@ -27,10 +27,8 @@ import java.util.Objects;
 /**
  * A query that wraps a filter and simply returns a constant score equal to the
  * query boost for every document in the filter.
- *
- *
  */
-public class ConstantScoreQueryBuilder extends BaseQueryBuilder implements BoostableQueryBuilder<ConstantScoreQueryBuilder> {
+public class ConstantScoreQueryBuilder extends QueryBuilder implements BoostableQueryBuilder<ConstantScoreQueryBuilder> {
 
     private final QueryBuilder filterBuilder;
 
diff --git a/src/main/java/org/elasticsearch/index/query/DisMaxQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/DisMaxQueryBuilder.java
index 3be2370e081..ddf9d95d166 100644
--- a/src/main/java/org/elasticsearch/index/query/DisMaxQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/DisMaxQueryBuilder.java
@@ -30,10 +30,8 @@ import static com.google.common.collect.Lists.newArrayList;
  * A query that generates the union of documents produced by its sub-queries, and that scores each document
  * with the maximum score for that document as produced by any sub-query, plus a tie breaking increment for any
  * additional matching sub-queries.
- *
- *
  */
-public class DisMaxQueryBuilder extends BaseQueryBuilder implements BoostableQueryBuilder<DisMaxQueryBuilder> {
+public class DisMaxQueryBuilder extends QueryBuilder implements BoostableQueryBuilder<DisMaxQueryBuilder> {
 
     private ArrayList<QueryBuilder> queries = newArrayList();
 
diff --git a/src/main/java/org/elasticsearch/index/query/ExistsQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/ExistsQueryBuilder.java
index 7613ce56515..9980d819ea4 100644
--- a/src/main/java/org/elasticsearch/index/query/ExistsQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/ExistsQueryBuilder.java
@@ -26,7 +26,7 @@ import java.io.IOException;
 /**
  * Constructs a query that only match on documents that the field has a value in them.
  */
-public class ExistsQueryBuilder extends BaseQueryBuilder {
+public class ExistsQueryBuilder extends QueryBuilder {
 
     private String name;
 
diff --git a/src/main/java/org/elasticsearch/index/query/FieldMaskingSpanQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/FieldMaskingSpanQueryBuilder.java
index 3c397b78f1b..c118416bfd0 100644
--- a/src/main/java/org/elasticsearch/index/query/FieldMaskingSpanQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/FieldMaskingSpanQueryBuilder.java
@@ -23,10 +23,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
 
 import java.io.IOException;
 
-/**
- *
- */
-public class FieldMaskingSpanQueryBuilder extends BaseQueryBuilder implements SpanQueryBuilder, BoostableQueryBuilder<FieldMaskingSpanQueryBuilder> {
+public class FieldMaskingSpanQueryBuilder extends SpanQueryBuilder implements BoostableQueryBuilder<FieldMaskingSpanQueryBuilder> {
 
     private final SpanQueryBuilder queryBuilder;
 
diff --git a/src/main/java/org/elasticsearch/index/query/FilteredQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/FilteredQueryBuilder.java
index 9315fd65686..93507cfe14b 100644
--- a/src/main/java/org/elasticsearch/index/query/FilteredQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/FilteredQueryBuilder.java
@@ -29,7 +29,7 @@ import java.io.IOException;
  * @deprecated Use {@link BoolQueryBuilder} instead.
  */
 @Deprecated
-public class FilteredQueryBuilder extends BaseQueryBuilder implements BoostableQueryBuilder<FilteredQueryBuilder> {
+public class FilteredQueryBuilder extends QueryBuilder implements BoostableQueryBuilder<FilteredQueryBuilder> {
 
     private final QueryBuilder queryBuilder;
 
diff --git a/src/main/java/org/elasticsearch/index/query/FuzzyQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/FuzzyQueryBuilder.java
index cc74c4df8d2..d1143f9a5ce 100644
--- a/src/main/java/org/elasticsearch/index/query/FuzzyQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/FuzzyQueryBuilder.java
@@ -26,10 +26,8 @@ import java.io.IOException;
 
 /**
  * A Query that does fuzzy matching for a specific value.
- *
- *
  */
-public class FuzzyQueryBuilder extends BaseQueryBuilder implements MultiTermQueryBuilder, BoostableQueryBuilder<FuzzyQueryBuilder> {
+public class FuzzyQueryBuilder extends MultiTermQueryBuilder implements BoostableQueryBuilder<FuzzyQueryBuilder> {
 
     private final String name;
 
diff --git a/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilder.java
index 66f2ba5bcd2..9b376ca851e 100644
--- a/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilder.java
@@ -25,10 +25,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
 
 import java.io.IOException;
 
-/**
- *
- */
-public class GeoBoundingBoxQueryBuilder extends BaseQueryBuilder {
+public class GeoBoundingBoxQueryBuilder extends QueryBuilder {
 
     public static final String TOP_LEFT = GeoBoundingBoxQueryParser.TOP_LEFT;
     public static final String BOTTOM_RIGHT = GeoBoundingBoxQueryParser.BOTTOM_RIGHT;
diff --git a/src/main/java/org/elasticsearch/index/query/GeoDistanceQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/GeoDistanceQueryBuilder.java
index 2ea4e92a567..0995a5ecacf 100644
--- a/src/main/java/org/elasticsearch/index/query/GeoDistanceQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/GeoDistanceQueryBuilder.java
@@ -26,10 +26,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
 import java.io.IOException;
 import java.util.Locale;
 
-/**
- *
- */
-public class GeoDistanceQueryBuilder extends BaseQueryBuilder {
+public class GeoDistanceQueryBuilder extends QueryBuilder {
 
     private final String name;
 
diff --git a/src/main/java/org/elasticsearch/index/query/GeoDistanceRangeQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/GeoDistanceRangeQueryBuilder.java
index e16680de1b6..d21810f97e3 100644
--- a/src/main/java/org/elasticsearch/index/query/GeoDistanceRangeQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/GeoDistanceRangeQueryBuilder.java
@@ -25,10 +25,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
 import java.io.IOException;
 import java.util.Locale;
 
-/**
- *
- */
-public class GeoDistanceRangeQueryBuilder extends BaseQueryBuilder {
+public class GeoDistanceRangeQueryBuilder extends QueryBuilder {
 
     private final String name;
 
diff --git a/src/main/java/org/elasticsearch/index/query/GeoPolygonQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/GeoPolygonQueryBuilder.java
index 609eb55d656..4fd2f4153d9 100644
--- a/src/main/java/org/elasticsearch/index/query/GeoPolygonQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/GeoPolygonQueryBuilder.java
@@ -28,10 +28,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
 import java.io.IOException;
 import java.util.List;
 
-/**
- *
- */
-public class GeoPolygonQueryBuilder extends BaseQueryBuilder {
+public class GeoPolygonQueryBuilder extends QueryBuilder {
 
     public static final String POINTS = GeoPolygonQueryParser.POINTS;
     
diff --git a/src/main/java/org/elasticsearch/index/query/GeoShapeQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/GeoShapeQueryBuilder.java
index 7e1beb19180..4fe83a1a890 100644
--- a/src/main/java/org/elasticsearch/index/query/GeoShapeQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/GeoShapeQueryBuilder.java
@@ -29,7 +29,7 @@ import java.io.IOException;
 /**
  * {@link QueryBuilder} that builds a GeoShape Filter
  */
-public class GeoShapeQueryBuilder extends BaseQueryBuilder {
+public class GeoShapeQueryBuilder extends QueryBuilder {
 
     private final String name;
 
diff --git a/src/main/java/org/elasticsearch/index/query/GeohashCellQuery.java b/src/main/java/org/elasticsearch/index/query/GeohashCellQuery.java
index c2ec86d182a..2e0089ded4f 100644
--- a/src/main/java/org/elasticsearch/index/query/GeohashCellQuery.java
+++ b/src/main/java/org/elasticsearch/index/query/GeohashCellQuery.java
@@ -90,7 +90,7 @@ public class GeohashCellQuery {
      * <code>geohash</code> to be set. the default for a neighbor filteing is
      * <code>false</code>.
      */
-    public static class Builder extends BaseQueryBuilder {
+    public static class Builder extends QueryBuilder {
         // we need to store the geohash rather than the corresponding point,
         // because a transformation from a geohash to a point an back to the
         // geohash will extend the accuracy of the hash to max precision
diff --git a/src/main/java/org/elasticsearch/index/query/HasChildQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/HasChildQueryBuilder.java
index eec068a7101..74a6a5ce8b2 100644
--- a/src/main/java/org/elasticsearch/index/query/HasChildQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/HasChildQueryBuilder.java
@@ -23,10 +23,7 @@ import org.elasticsearch.index.query.support.QueryInnerHitBuilder;
 
 import java.io.IOException;
 
-/**
- *
- */
-public class HasChildQueryBuilder extends BaseQueryBuilder implements BoostableQueryBuilder<HasChildQueryBuilder> {
+public class HasChildQueryBuilder extends QueryBuilder implements BoostableQueryBuilder<HasChildQueryBuilder> {
 
     private final QueryBuilder queryBuilder;
 
diff --git a/src/main/java/org/elasticsearch/index/query/HasParentQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/HasParentQueryBuilder.java
index fbdc4f34a7a..743ad76c898 100644
--- a/src/main/java/org/elasticsearch/index/query/HasParentQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/HasParentQueryBuilder.java
@@ -26,7 +26,7 @@ import java.io.IOException;
 /**
  * Builder for the 'has_parent' query.
  */
-public class HasParentQueryBuilder extends BaseQueryBuilder implements BoostableQueryBuilder<HasParentQueryBuilder> {
+public class HasParentQueryBuilder extends QueryBuilder implements BoostableQueryBuilder<HasParentQueryBuilder> {
 
     private final QueryBuilder queryBuilder;
     private final String parentType;
diff --git a/src/main/java/org/elasticsearch/index/query/IdsQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/IdsQueryBuilder.java
index d926fa504fe..db343bf3555 100644
--- a/src/main/java/org/elasticsearch/index/query/IdsQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/IdsQueryBuilder.java
@@ -29,7 +29,7 @@ import java.util.List;
 /**
  * A query that will return only documents matching specific ids (and a type).
  */
-public class IdsQueryBuilder extends BaseQueryBuilder implements BoostableQueryBuilder<IdsQueryBuilder> {
+public class IdsQueryBuilder extends QueryBuilder implements BoostableQueryBuilder<IdsQueryBuilder> {
 
     private final List<String> types;
 
diff --git a/src/main/java/org/elasticsearch/index/query/IndicesQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/IndicesQueryBuilder.java
index 5b1434a0f6c..7c2af81b268 100644
--- a/src/main/java/org/elasticsearch/index/query/IndicesQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/IndicesQueryBuilder.java
@@ -27,7 +27,7 @@ import java.io.IOException;
  * A query that will execute the wrapped query only for the specified indices, and "match_all" when
  * it does not match those indices (by default).
  */
-public class IndicesQueryBuilder extends BaseQueryBuilder {
+public class IndicesQueryBuilder extends QueryBuilder {
 
     private final QueryBuilder queryBuilder;
 
diff --git a/src/main/java/org/elasticsearch/index/query/LimitQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/LimitQueryBuilder.java
index 23497429581..9d44f39f2ec 100644
--- a/src/main/java/org/elasticsearch/index/query/LimitQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/LimitQueryBuilder.java
@@ -28,7 +28,7 @@ import java.io.IOException;
  * @deprecated Use {@link SearchRequestBuilder#setTerminateAfter(int)} instead.
  */
 @Deprecated
-public class LimitQueryBuilder extends BaseQueryBuilder {
+public class LimitQueryBuilder extends QueryBuilder {
 
     private final int limit;
 
diff --git a/src/main/java/org/elasticsearch/index/query/MatchAllQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/MatchAllQueryBuilder.java
index 78a91a7fb73..b09bc9f1dc9 100644
--- a/src/main/java/org/elasticsearch/index/query/MatchAllQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/MatchAllQueryBuilder.java
@@ -25,10 +25,8 @@ import java.io.IOException;
 
 /**
  * A query that matches on all documents.
- *
- *
  */
-public class MatchAllQueryBuilder extends BaseQueryBuilder implements BoostableQueryBuilder<MatchAllQueryBuilder> {
+public class MatchAllQueryBuilder extends QueryBuilder implements BoostableQueryBuilder<MatchAllQueryBuilder> {
 
     private float boost = -1;
 
diff --git a/src/main/java/org/elasticsearch/index/query/MatchQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/MatchQueryBuilder.java
index 1f90999d525..e4a643f1350 100644
--- a/src/main/java/org/elasticsearch/index/query/MatchQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/MatchQueryBuilder.java
@@ -29,14 +29,14 @@ import java.util.Locale;
  * Match query is a query that analyzes the text and constructs a query as the result of the analysis. It
  * can construct different queries based on the type provided.
  */
-public class MatchQueryBuilder extends BaseQueryBuilder implements BoostableQueryBuilder<MatchQueryBuilder> {
+public class MatchQueryBuilder extends QueryBuilder implements BoostableQueryBuilder<MatchQueryBuilder> {
 
-    public static enum Operator {
+    public enum Operator {
         OR,
         AND
     }
 
-    public static enum Type {
+    public enum Type {
         /**
          * The text is analyzed and terms are added to a boolean query.
          */
@@ -51,7 +51,7 @@ public class MatchQueryBuilder extends BaseQueryBuilder implements BoostableQuer
         PHRASE_PREFIX
     }
 
-    public static enum ZeroTermsQuery {
+    public enum ZeroTermsQuery {
         NONE,
         ALL
     }
diff --git a/src/main/java/org/elasticsearch/index/query/MissingQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/MissingQueryBuilder.java
index b01b8817d55..ac3f279d4d1 100644
--- a/src/main/java/org/elasticsearch/index/query/MissingQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/MissingQueryBuilder.java
@@ -26,7 +26,7 @@ import java.io.IOException;
 /**
  * Constructs a filter that only match on documents that the field has a value in them.
  */
-public class MissingQueryBuilder extends BaseQueryBuilder {
+public class MissingQueryBuilder extends QueryBuilder {
 
     private String name;
 
diff --git a/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java
index 1f3b6adbeb0..a4d803878bf 100644
--- a/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java
@@ -37,7 +37,7 @@ import java.util.Locale;
  * A more like this query that finds documents that are "like" the provided {@link #likeText(String)}
  * which is checked against the fields the query is constructed with.
  */
-public class MoreLikeThisQueryBuilder extends BaseQueryBuilder implements BoostableQueryBuilder<MoreLikeThisQueryBuilder> {
+public class MoreLikeThisQueryBuilder extends QueryBuilder implements BoostableQueryBuilder<MoreLikeThisQueryBuilder> {
 
     /**
      * A single get item. Pure delegate to multi get.
diff --git a/src/main/java/org/elasticsearch/index/query/MultiMatchQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/MultiMatchQueryBuilder.java
index d07f6d56c32..8c242854458 100644
--- a/src/main/java/org/elasticsearch/index/query/MultiMatchQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/MultiMatchQueryBuilder.java
@@ -36,7 +36,7 @@ import java.util.Locale;
 /**
  * Same as {@link MatchQueryBuilder} but supports multiple fields.
  */
-public class MultiMatchQueryBuilder extends BaseQueryBuilder implements BoostableQueryBuilder<MultiMatchQueryBuilder> {
+public class MultiMatchQueryBuilder extends QueryBuilder implements BoostableQueryBuilder<MultiMatchQueryBuilder> {
 
     private final Object text;
 
diff --git a/src/main/java/org/elasticsearch/index/query/MultiTermQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/MultiTermQueryBuilder.java
index f34f6aa5993..9c7383dc251 100644
--- a/src/main/java/org/elasticsearch/index/query/MultiTermQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/MultiTermQueryBuilder.java
@@ -18,9 +18,6 @@
  */
 package org.elasticsearch.index.query;
 
-/**
- *
- */
-public interface MultiTermQueryBuilder extends QueryBuilder{
+public abstract class MultiTermQueryBuilder extends QueryBuilder {
 
 }
diff --git a/src/main/java/org/elasticsearch/index/query/NestedQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/NestedQueryBuilder.java
index d82dde7f891..63b40dcaef1 100644
--- a/src/main/java/org/elasticsearch/index/query/NestedQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/NestedQueryBuilder.java
@@ -25,7 +25,7 @@ import org.elasticsearch.index.query.support.QueryInnerHitBuilder;
 import java.io.IOException;
 import java.util.Objects;
 
-public class NestedQueryBuilder extends BaseQueryBuilder implements BoostableQueryBuilder<NestedQueryBuilder> {
+public class NestedQueryBuilder extends QueryBuilder implements BoostableQueryBuilder<NestedQueryBuilder> {
 
     private final QueryBuilder queryBuilder;
 
diff --git a/src/main/java/org/elasticsearch/index/query/NotQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/NotQueryBuilder.java
index 4545c7ae7d5..c16cf6450ea 100644
--- a/src/main/java/org/elasticsearch/index/query/NotQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/NotQueryBuilder.java
@@ -26,10 +26,8 @@ import java.util.Objects;
 
 /**
  * A filter that matches documents matching boolean combinations of other filters.
- *
- *
  */
-public class NotQueryBuilder extends BaseQueryBuilder {
+public class NotQueryBuilder extends QueryBuilder {
 
     private final QueryBuilder filter;
 
diff --git a/src/main/java/org/elasticsearch/index/query/OrQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/OrQueryBuilder.java
index df05973ab8a..19ad3e49eb0 100644
--- a/src/main/java/org/elasticsearch/index/query/OrQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/OrQueryBuilder.java
@@ -24,22 +24,21 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Collections;
 
 /**
  * A filter that matches documents matching boolean combinations of other filters.
  * @deprecated Use {@link BoolQueryBuilder} instead
  */
 @Deprecated
-public class OrQueryBuilder extends BaseQueryBuilder {
+public class OrQueryBuilder extends QueryBuilder {
 
     private ArrayList<QueryBuilder> filters = Lists.newArrayList();
 
     private String queryName;
 
     public OrQueryBuilder(QueryBuilder... filters) {
-        for (QueryBuilder filter : filters) {
-            this.filters.add(filter);
-        }
+        Collections.addAll(this.filters, filters);
     }
 
     /**
diff --git a/src/main/java/org/elasticsearch/index/query/PrefixQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/PrefixQueryBuilder.java
index c5bea414f6c..c890d60ee7c 100644
--- a/src/main/java/org/elasticsearch/index/query/PrefixQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/PrefixQueryBuilder.java
@@ -25,10 +25,8 @@ import java.io.IOException;
 
 /**
  * A Query that matches documents containing terms with a specified prefix.
- *
- *
  */
-public class PrefixQueryBuilder extends BaseQueryBuilder implements MultiTermQueryBuilder, BoostableQueryBuilder<PrefixQueryBuilder> {
+public class PrefixQueryBuilder extends MultiTermQueryBuilder implements BoostableQueryBuilder<PrefixQueryBuilder> {
 
     private final String name;
 
diff --git a/src/main/java/org/elasticsearch/index/query/QueryBuilder.java b/src/main/java/org/elasticsearch/index/query/QueryBuilder.java
index 87025de9bb6..fa11d3277fd 100644
--- a/src/main/java/org/elasticsearch/index/query/QueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/QueryBuilder.java
@@ -19,17 +19,25 @@
 
 package org.elasticsearch.index.query;
 
-import org.elasticsearch.ElasticsearchException;
-import org.elasticsearch.common.bytes.BytesReference;
-import org.elasticsearch.common.xcontent.ToXContent;
+import org.elasticsearch.action.support.ToXContentToBytes;
+import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.common.xcontent.XContentType;
 
-/**
- *
- */
-public interface QueryBuilder extends ToXContent {
+import java.io.IOException;
 
-    BytesReference buildAsBytes();
+public abstract class QueryBuilder extends ToXContentToBytes {
 
-    BytesReference buildAsBytes(XContentType contentType);
+    protected QueryBuilder() {
+        super(XContentType.JSON);
+    }
+
+    @Override
+    public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
+        builder.startObject();
+        doXContent(builder, params);
+        builder.endObject();
+        return builder;
+    }
+
+    protected abstract void doXContent(XContentBuilder builder, Params params) throws IOException;
 }
diff --git a/src/main/java/org/elasticsearch/index/query/QueryFilterBuilder.java b/src/main/java/org/elasticsearch/index/query/QueryFilterBuilder.java
index 9c602b06f86..936e466c0f6 100644
--- a/src/main/java/org/elasticsearch/index/query/QueryFilterBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/QueryFilterBuilder.java
@@ -29,7 +29,7 @@ import java.io.IOException;
  *             query as a filter directly.
  */
 @Deprecated
-public class QueryFilterBuilder extends BaseQueryBuilder {
+public class QueryFilterBuilder extends QueryBuilder {
 
     private final QueryBuilder queryBuilder;
 
diff --git a/src/main/java/org/elasticsearch/index/query/QueryStringQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/QueryStringQueryBuilder.java
index 7eb0de6b52a..7965eecea17 100644
--- a/src/main/java/org/elasticsearch/index/query/QueryStringQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/QueryStringQueryBuilder.java
@@ -38,9 +38,9 @@ import static com.google.common.collect.Lists.newArrayList;
  * them either using DisMax or a plain boolean query (see {@link #useDisMax(boolean)}).
  * <p/>
  */
-public class QueryStringQueryBuilder extends BaseQueryBuilder implements BoostableQueryBuilder<QueryStringQueryBuilder> {
+public class QueryStringQueryBuilder extends QueryBuilder implements BoostableQueryBuilder<QueryStringQueryBuilder> {
 
-    public static enum Operator {
+    public enum Operator {
         OR,
         AND
     }
diff --git a/src/main/java/org/elasticsearch/index/query/RangeQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/RangeQueryBuilder.java
index ac2c210367f..39e7972ad82 100644
--- a/src/main/java/org/elasticsearch/index/query/RangeQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/RangeQueryBuilder.java
@@ -25,10 +25,8 @@ import java.io.IOException;
 
 /**
  * A Query that matches documents within an range of terms.
- *
- *
  */
-public class RangeQueryBuilder extends BaseQueryBuilder implements MultiTermQueryBuilder, BoostableQueryBuilder<RangeQueryBuilder> {
+public class RangeQueryBuilder extends MultiTermQueryBuilder implements BoostableQueryBuilder<RangeQueryBuilder> {
 
     private final String name;
 
diff --git a/src/main/java/org/elasticsearch/index/query/RegexpQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/RegexpQueryBuilder.java
index 8d4ba6cefca..43b5b2f77ef 100644
--- a/src/main/java/org/elasticsearch/index/query/RegexpQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/RegexpQueryBuilder.java
@@ -26,10 +26,8 @@ import java.io.IOException;
 
 /**
  * A Query that does fuzzy matching for a specific value.
- *
- *
  */
-public class RegexpQueryBuilder extends BaseQueryBuilder implements BoostableQueryBuilder<RegexpQueryBuilder>, MultiTermQueryBuilder {
+public class RegexpQueryBuilder extends MultiTermQueryBuilder implements BoostableQueryBuilder<RegexpQueryBuilder> {
 
     private final String name;
     private final String regexp;
diff --git a/src/main/java/org/elasticsearch/index/query/ScriptQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/ScriptQueryBuilder.java
index 00f6ddff62b..9ae05159953 100644
--- a/src/main/java/org/elasticsearch/index/query/ScriptQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/ScriptQueryBuilder.java
@@ -26,10 +26,7 @@ import java.util.Map;
 
 import static com.google.common.collect.Maps.newHashMap;
 
-/**
- *
- */
-public class ScriptQueryBuilder extends BaseQueryBuilder {
+public class ScriptQueryBuilder extends QueryBuilder {
 
     private final String script;
 
diff --git a/src/main/java/org/elasticsearch/index/query/SimpleQueryStringBuilder.java b/src/main/java/org/elasticsearch/index/query/SimpleQueryStringBuilder.java
index f0cc2bbeb6d..9e8e51a5d90 100644
--- a/src/main/java/org/elasticsearch/index/query/SimpleQueryStringBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/SimpleQueryStringBuilder.java
@@ -30,7 +30,7 @@ import java.util.Map;
  * SimpleQuery is a query parser that acts similar to a query_string
  * query, but won't throw exceptions for any weird string syntax.
  */
-public class SimpleQueryStringBuilder extends BaseQueryBuilder {
+public class SimpleQueryStringBuilder extends QueryBuilder {
     private Map<String, Float> fields = new HashMap<>();
     private String analyzer;
     private Operator operator;
diff --git a/src/main/java/org/elasticsearch/index/query/SpanContainingQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/SpanContainingQueryBuilder.java
index 6fd2dee013a..0b7a3cd92c9 100644
--- a/src/main/java/org/elasticsearch/index/query/SpanContainingQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/SpanContainingQueryBuilder.java
@@ -24,9 +24,9 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
 import java.io.IOException;
 
 /**
- * Builder for {@link SpanContainingQuery}.
+ * Builder for {@link org.apache.lucene.search.spans.SpanContainingQuery}.
  */
-public class SpanContainingQueryBuilder extends BaseQueryBuilder implements SpanQueryBuilder, BoostableQueryBuilder<SpanContainingQueryBuilder> {
+public class SpanContainingQueryBuilder extends SpanQueryBuilder implements BoostableQueryBuilder<SpanContainingQueryBuilder> {
 
     private SpanQueryBuilder big;
     private SpanQueryBuilder little;
diff --git a/src/main/java/org/elasticsearch/index/query/SpanFirstQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/SpanFirstQueryBuilder.java
index 5773538faec..2e2c1fd5e74 100644
--- a/src/main/java/org/elasticsearch/index/query/SpanFirstQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/SpanFirstQueryBuilder.java
@@ -23,10 +23,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
 
 import java.io.IOException;
 
-/**
- *
- */
-public class SpanFirstQueryBuilder extends BaseQueryBuilder implements SpanQueryBuilder, BoostableQueryBuilder<SpanFirstQueryBuilder> {
+public class SpanFirstQueryBuilder extends SpanQueryBuilder implements BoostableQueryBuilder<SpanFirstQueryBuilder> {
 
     private final SpanQueryBuilder matchBuilder;
 
diff --git a/src/main/java/org/elasticsearch/index/query/SpanMultiTermQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/SpanMultiTermQueryBuilder.java
index 72bc58dcb85..11b98972c51 100644
--- a/src/main/java/org/elasticsearch/index/query/SpanMultiTermQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/SpanMultiTermQueryBuilder.java
@@ -22,10 +22,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
 
 import java.io.IOException;
 
-/**
- *
- */
-public class SpanMultiTermQueryBuilder extends BaseQueryBuilder implements SpanQueryBuilder {
+public class SpanMultiTermQueryBuilder extends SpanQueryBuilder {
 
     private MultiTermQueryBuilder multiTermQueryBuilder;
 
diff --git a/src/main/java/org/elasticsearch/index/query/SpanNearQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/SpanNearQueryBuilder.java
index 2e89d2ff93f..cb05e084c4f 100644
--- a/src/main/java/org/elasticsearch/index/query/SpanNearQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/SpanNearQueryBuilder.java
@@ -24,10 +24,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
 import java.io.IOException;
 import java.util.ArrayList;
 
-/**
- *
- */
-public class SpanNearQueryBuilder extends BaseQueryBuilder implements SpanQueryBuilder, BoostableQueryBuilder<SpanNearQueryBuilder> {
+public class SpanNearQueryBuilder extends SpanQueryBuilder implements BoostableQueryBuilder<SpanNearQueryBuilder> {
 
     private ArrayList<SpanQueryBuilder> clauses = new ArrayList<>();
 
diff --git a/src/main/java/org/elasticsearch/index/query/SpanNotQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/SpanNotQueryBuilder.java
index 2bcbab5487b..e37cd80a5a7 100644
--- a/src/main/java/org/elasticsearch/index/query/SpanNotQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/SpanNotQueryBuilder.java
@@ -23,10 +23,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
 
 import java.io.IOException;
 
-/**
- *
- */
-public class SpanNotQueryBuilder extends BaseQueryBuilder implements SpanQueryBuilder, BoostableQueryBuilder<SpanNotQueryBuilder> {
+public class SpanNotQueryBuilder extends SpanQueryBuilder implements BoostableQueryBuilder<SpanNotQueryBuilder> {
 
     private SpanQueryBuilder include;
 
diff --git a/src/main/java/org/elasticsearch/index/query/SpanOrQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/SpanOrQueryBuilder.java
index b453809e837..0042aa7c44c 100644
--- a/src/main/java/org/elasticsearch/index/query/SpanOrQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/SpanOrQueryBuilder.java
@@ -24,10 +24,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
 import java.io.IOException;
 import java.util.ArrayList;
 
-/**
- *
- */
-public class SpanOrQueryBuilder extends BaseQueryBuilder implements SpanQueryBuilder, BoostableQueryBuilder<SpanOrQueryBuilder> {
+public class SpanOrQueryBuilder extends SpanQueryBuilder implements BoostableQueryBuilder<SpanOrQueryBuilder> {
 
     private ArrayList<SpanQueryBuilder> clauses = new ArrayList<>();
 
diff --git a/src/main/java/org/elasticsearch/index/query/SpanQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/SpanQueryBuilder.java
index 5c1248946c2..4216f2257a3 100644
--- a/src/main/java/org/elasticsearch/index/query/SpanQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/SpanQueryBuilder.java
@@ -19,9 +19,6 @@
 
 package org.elasticsearch.index.query;
 
-/**
- *
- */
-public interface SpanQueryBuilder extends QueryBuilder {
+public abstract class SpanQueryBuilder extends QueryBuilder {
 
 }
diff --git a/src/main/java/org/elasticsearch/index/query/SpanTermQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/SpanTermQueryBuilder.java
index 80b696edc14..9d0176e2974 100644
--- a/src/main/java/org/elasticsearch/index/query/SpanTermQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/SpanTermQueryBuilder.java
@@ -23,10 +23,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
 
 import java.io.IOException;
 
-/**
- *
- */
-public class SpanTermQueryBuilder extends BaseQueryBuilder implements SpanQueryBuilder, BoostableQueryBuilder<SpanTermQueryBuilder> {
+public class SpanTermQueryBuilder extends SpanQueryBuilder implements BoostableQueryBuilder<SpanTermQueryBuilder> {
 
     private final String name;
 
diff --git a/src/main/java/org/elasticsearch/index/query/SpanWithinQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/SpanWithinQueryBuilder.java
index 88e1538bff4..d2b2fdc408b 100644
--- a/src/main/java/org/elasticsearch/index/query/SpanWithinQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/SpanWithinQueryBuilder.java
@@ -24,9 +24,9 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
 import java.io.IOException;
 
 /**
- * Builder for {@link SpanWithinQuery}.
+ * Builder for {@link org.apache.lucene.search.spans.SpanWithinQuery}.
  */
-public class SpanWithinQueryBuilder extends BaseQueryBuilder implements SpanQueryBuilder, BoostableQueryBuilder<SpanWithinQueryBuilder> {
+public class SpanWithinQueryBuilder extends SpanQueryBuilder implements BoostableQueryBuilder<SpanWithinQueryBuilder> {
 
     private SpanQueryBuilder big;
     private SpanQueryBuilder little;
diff --git a/src/main/java/org/elasticsearch/index/query/TemplateQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/TemplateQueryBuilder.java
index ca35a42ae3b..7154fe93fc0 100644
--- a/src/main/java/org/elasticsearch/index/query/TemplateQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/TemplateQueryBuilder.java
@@ -27,7 +27,7 @@ import java.util.Map;
 /**
  * Facilitates creating template query requests.
  * */
-public class TemplateQueryBuilder extends BaseQueryBuilder {
+public class TemplateQueryBuilder extends QueryBuilder {
 
     /** Parameters to fill the template with. */
     private Map<String, Object> vars;
diff --git a/src/main/java/org/elasticsearch/index/query/TermQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/TermQueryBuilder.java
index fbedfe33a8f..5bd911a2e59 100644
--- a/src/main/java/org/elasticsearch/index/query/TermQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/TermQueryBuilder.java
@@ -25,10 +25,8 @@ import java.io.IOException;
 
 /**
  * A Query that matches documents containing a term.
- *
- *
  */
-public class TermQueryBuilder extends BaseQueryBuilder implements BoostableQueryBuilder<TermQueryBuilder> {
+public class TermQueryBuilder extends QueryBuilder implements BoostableQueryBuilder<TermQueryBuilder> {
 
     private final String name;
 
diff --git a/src/main/java/org/elasticsearch/index/query/TermsLookupQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/TermsLookupQueryBuilder.java
index abffc4fa442..e5daab55640 100644
--- a/src/main/java/org/elasticsearch/index/query/TermsLookupQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/TermsLookupQueryBuilder.java
@@ -26,7 +26,7 @@ import java.io.IOException;
 /**
  * A filer for a field based on several terms matching on any of them.
  */
-public class TermsLookupQueryBuilder extends BaseQueryBuilder {
+public class TermsLookupQueryBuilder extends QueryBuilder {
 
     private final String name;
     private String lookupIndex;
diff --git a/src/main/java/org/elasticsearch/index/query/TermsQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/TermsQueryBuilder.java
index 885ecac5e2d..63f9017ed8f 100644
--- a/src/main/java/org/elasticsearch/index/query/TermsQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/TermsQueryBuilder.java
@@ -26,7 +26,7 @@ import java.io.IOException;
 /**
  * A filer for a field based on several terms matching on any of them.
  */
-public class TermsQueryBuilder extends BaseQueryBuilder {
+public class TermsQueryBuilder extends QueryBuilder {
 
     private final String name;
 
diff --git a/src/main/java/org/elasticsearch/index/query/TypeQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/TypeQueryBuilder.java
index 3ce13dac1d6..2a9a6c500a6 100644
--- a/src/main/java/org/elasticsearch/index/query/TypeQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/TypeQueryBuilder.java
@@ -23,7 +23,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
 
 import java.io.IOException;
 
-public class TypeQueryBuilder extends BaseQueryBuilder {
+public class TypeQueryBuilder extends QueryBuilder {
 
     private final String type;
 
diff --git a/src/main/java/org/elasticsearch/index/query/WildcardQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/WildcardQueryBuilder.java
index 245404f4044..002d408dd77 100644
--- a/src/main/java/org/elasticsearch/index/query/WildcardQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/WildcardQueryBuilder.java
@@ -30,10 +30,8 @@ import java.io.IOException;
  * needs to iterate over many terms. In order to prevent extremely slow WildcardQueries,
  * a Wildcard term should not start with one of the wildcards <tt>*</tt> or
  * <tt>?</tt>.
- *
- *
  */
-public class WildcardQueryBuilder extends BaseQueryBuilder implements MultiTermQueryBuilder, BoostableQueryBuilder<WildcardQueryBuilder> {
+public class WildcardQueryBuilder extends MultiTermQueryBuilder implements BoostableQueryBuilder<WildcardQueryBuilder> {
 
     private final String name;
 
diff --git a/src/main/java/org/elasticsearch/index/query/WrapperQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/WrapperQueryBuilder.java
index 80e15fbc102..6fde3c77662 100644
--- a/src/main/java/org/elasticsearch/index/query/WrapperQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/WrapperQueryBuilder.java
@@ -39,7 +39,7 @@ import java.io.IOException;
  * }
  * </pre>
  */
-public class WrapperQueryBuilder extends BaseQueryBuilder {
+public class WrapperQueryBuilder extends QueryBuilder {
 
     private final byte[] source;
     private final int offset;
diff --git a/src/main/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilder.java
index 966d85e183f..dc7571a6696 100644
--- a/src/main/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilder.java
@@ -21,7 +21,6 @@ package org.elasticsearch.index.query.functionscore;
 
 import org.elasticsearch.common.lucene.search.function.CombineFunction;
 import org.elasticsearch.common.xcontent.XContentBuilder;
-import org.elasticsearch.index.query.BaseQueryBuilder;
 import org.elasticsearch.index.query.BoostableQueryBuilder;
 import org.elasticsearch.index.query.QueryBuilder;
 
@@ -32,7 +31,7 @@ import java.util.ArrayList;
  * A query that uses a filters with a script associated with them to compute the
  * score.
  */
-public class FunctionScoreQueryBuilder extends BaseQueryBuilder implements BoostableQueryBuilder<FunctionScoreQueryBuilder> {
+public class FunctionScoreQueryBuilder extends QueryBuilder implements BoostableQueryBuilder<FunctionScoreQueryBuilder> {
 
     private final QueryBuilder queryBuilder;
 
diff --git a/src/main/java/org/elasticsearch/index/query/functionscore/weight/WeightBuilder.java b/src/main/java/org/elasticsearch/index/query/functionscore/weight/WeightBuilder.java
index 50f704de810..5b6284326a6 100644
--- a/src/main/java/org/elasticsearch/index/query/functionscore/weight/WeightBuilder.java
+++ b/src/main/java/org/elasticsearch/index/query/functionscore/weight/WeightBuilder.java
@@ -30,7 +30,6 @@ import java.io.IOException;
  */
 public class WeightBuilder extends ScoreFunctionBuilder {
 
-
     @Override
     public String getName() {
         return "weight";
diff --git a/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java b/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java
index c56016d9464..57dfe4a362b 100644
--- a/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java
+++ b/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java
@@ -24,18 +24,16 @@ import com.google.common.base.Charsets;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 import org.elasticsearch.ElasticsearchGenerationException;
-import org.elasticsearch.ExceptionsHelper;
 import org.elasticsearch.action.support.QuerySourceBuilder;
+import org.elasticsearch.action.support.ToXContentToBytes;
 import org.elasticsearch.client.Requests;
 import org.elasticsearch.common.Nullable;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.common.bytes.BytesArray;
 import org.elasticsearch.common.bytes.BytesReference;
 import org.elasticsearch.common.unit.TimeValue;
-import org.elasticsearch.common.xcontent.ToXContent;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.common.xcontent.XContentFactory;
-import org.elasticsearch.common.xcontent.XContentType;
 import org.elasticsearch.index.query.QueryBuilder;
 import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
 import org.elasticsearch.search.fetch.innerhits.InnerHitsBuilder;
@@ -61,7 +59,7 @@ import java.util.Map;
  *
  * @see org.elasticsearch.action.search.SearchRequest#source(SearchSourceBuilder)
  */
-public class SearchSourceBuilder implements ToXContent {
+public class SearchSourceBuilder extends ToXContentToBytes {
 
     /**
      * A static factory method to construct a new search source.
@@ -667,31 +665,6 @@ public class SearchSourceBuilder implements ToXContent {
         return this;
     }
 
-    @Override
-    public String toString() {
-        try {
-            XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON).prettyPrint();
-            toXContent(builder, ToXContent.EMPTY_PARAMS);
-            return builder.string();
-        } catch (Exception e) {
-            return "{ \"error\" : \"" + ExceptionsHelper.detailedMessage(e) + "\"}";
-        }
-    }
-
-    public BytesReference buildAsBytes() throws SearchSourceBuilderException {
-        return buildAsBytes(Requests.CONTENT_TYPE);
-    }
-
-    public BytesReference buildAsBytes(XContentType contentType) throws SearchSourceBuilderException {
-        try {
-            XContentBuilder builder = XContentFactory.contentBuilder(contentType);
-            toXContent(builder, ToXContent.EMPTY_PARAMS);
-            return builder.bytes();
-        } catch (Exception e) {
-            throw new SearchSourceBuilderException("Failed to build search source", e);
-        }
-    }
-
     @Override
     public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
         builder.startObject();
diff --git a/src/main/java/org/elasticsearch/search/suggest/SuggestBuilder.java b/src/main/java/org/elasticsearch/search/suggest/SuggestBuilder.java
index 5399820dd94..57d18c3cddb 100644
--- a/src/main/java/org/elasticsearch/search/suggest/SuggestBuilder.java
+++ b/src/main/java/org/elasticsearch/search/suggest/SuggestBuilder.java
@@ -18,20 +18,16 @@
  */
 package org.elasticsearch.search.suggest;
 
+import org.elasticsearch.action.support.ToXContentToBytes;
+import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.search.suggest.context.CategoryContextMapping;
+import org.elasticsearch.search.suggest.context.ContextMapping.ContextQuery;
+import org.elasticsearch.search.suggest.context.GeolocationContextMapping;
+
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.elasticsearch.client.Requests;
-import org.elasticsearch.common.bytes.BytesReference;
-import org.elasticsearch.common.xcontent.ToXContent;
-import org.elasticsearch.common.xcontent.XContentBuilder;
-import org.elasticsearch.common.xcontent.XContentFactory;
-import org.elasticsearch.common.xcontent.XContentType;
-import org.elasticsearch.search.suggest.context.ContextMapping.ContextQuery;
-import org.elasticsearch.search.suggest.context.CategoryContextMapping;
-import org.elasticsearch.search.suggest.context.GeolocationContextMapping;
-
 /**
  * Defines how to perform suggesting. This builders allows a number of global options to be specified and
  * an arbitrary number of {@link org.elasticsearch.search.suggest.term.TermSuggestionBuilder} instances.
@@ -39,7 +35,7 @@ import org.elasticsearch.search.suggest.context.GeolocationContextMapping;
  * Suggesting works by suggesting terms that appear in the suggest text that are similar compared to the terms in
  * provided text. These spelling suggestions are based on several options described in this class.
  */
-public class SuggestBuilder implements ToXContent {
+public class SuggestBuilder extends ToXContentToBytes {
 
     private final String name;
     private String globalText;
@@ -100,31 +96,7 @@ public class SuggestBuilder implements ToXContent {
         return builder;
     }
 
-    /**
-     * Returns a {@link org.elasticsearch.common.bytes.BytesReference}
-     * representing the suggest lookup request.
-     * Builds the request as {@link org.elasticsearch.client.Requests#CONTENT_TYPE}
-     */
-    public BytesReference buildAsBytes() {
-        return this.buildAsBytes(Requests.CONTENT_TYPE);
-    }
-
-    /**
-     * Returns a {@link org.elasticsearch.common.bytes.BytesReference}
-     * representing the suggest lookup request.
-     * Builds the request as the provided <code>contentType</code>
-     */
-    public BytesReference buildAsBytes(XContentType contentType) {
-        try {
-            XContentBuilder builder = XContentFactory.contentBuilder(contentType);
-            toXContent(builder, ToXContent.EMPTY_PARAMS);
-            return builder.bytes();
-        } catch (Exception e) {
-            throw new SuggestBuilderException("Failed to build suggest query", e);
-        }
-    }
-
-    public static abstract class SuggestionBuilder<T> implements ToXContent {
+    public static abstract class SuggestionBuilder<T> extends ToXContentToBytes {
 
         private String name;
         private String suggester;
@@ -308,19 +280,5 @@ public class SuggestBuilder implements ToXContent {
             this.shardSize = shardSize;
             return (T)this;
         }
-
-        public BytesReference buildAsBytes() {
-            return this.buildAsBytes(Requests.CONTENT_TYPE);
-        }
-
-        public BytesReference buildAsBytes(XContentType contentType) {
-            try {
-                XContentBuilder builder = XContentFactory.contentBuilder(contentType);
-                toXContent(builder, ToXContent.EMPTY_PARAMS);
-                return builder.bytes();
-            } catch (Exception e) {
-                throw new SuggestBuilderException("Failed to build suggest", e);
-            }
-        }
     }
 }
diff --git a/src/test/java/org/elasticsearch/index/query/SimpleIndexQueryParserTests.java b/src/test/java/org/elasticsearch/index/query/SimpleIndexQueryParserTests.java
index a23f5e312ca..fddd7a5c0a2 100644
--- a/src/test/java/org/elasticsearch/index/query/SimpleIndexQueryParserTests.java
+++ b/src/test/java/org/elasticsearch/index/query/SimpleIndexQueryParserTests.java
@@ -188,7 +188,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest {
         
     }
 
-    private static class DummyQueryBuilder extends BaseQueryBuilder {
+    private static class DummyQueryBuilder extends QueryBuilder {
         @Override
         protected void doXContent(XContentBuilder builder, Params params) throws IOException {
             builder.startObject("dummy").endObject();
diff --git a/src/test/java/org/elasticsearch/search/innerhits/InnerHitsTests.java b/src/test/java/org/elasticsearch/search/innerhits/InnerHitsTests.java
index 6c517fa199b..6974f0b7c03 100644
--- a/src/test/java/org/elasticsearch/search/innerhits/InnerHitsTests.java
+++ b/src/test/java/org/elasticsearch/search/innerhits/InnerHitsTests.java
@@ -447,7 +447,7 @@ public class InnerHitsTests extends ElasticsearchIntegrationTest {
                     .addInnerHit("comment", new InnerHitsBuilder.InnerHit())
                     .get();
         } catch (Exception e) {
-            assertThat(e.getMessage(), containsString("Failed to build search source"));
+            assertThat(e.getMessage(), containsString("Failed to build"));
         }
 
     }