diff --git a/CHANGELOG.md b/CHANGELOG.md
index c52936900ca24b4e62eacf406a460893ff36d1f0..340e0e4dca6e9b3a08a338ac6a0869eb9b4793a5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,11 +1,17 @@
 CHANGELOG
 =========
-
+   
 v2.0.0 (2016-x)
 ---
 
 - [BC break] Aggregation name is not prefixed anymore
 
+v1.1.1 (2016-01-26)
+---
+
+- Fixed query endpoint normalization when called repeatedly [#56](https://github.com/ongr-io/ElasticsearchDSL/pull/56)
+- Deprecated `DslTypeAwareTrait` and `FilterOrQueryDetectionTrait` traits
+
 v1.1.0 (2015-12-28)
 ---
 
diff --git a/docs/HowTo/HowToSearch.md b/docs/HowTo/HowToSearch.md
index e8914418c4dc853d9a6a83b328ed65a1cd1dcdc5..36e32297eff549f7ae41d64eb43388ad0c073b8d 100644
--- a/docs/HowTo/HowToSearch.md
+++ b/docs/HowTo/HowToSearch.md
@@ -43,16 +43,22 @@ At the end it will form this query:
 
 ### Form a Filter
 
+> Since Elasticsearch 2.0 all filters were replaced by queries. Queries acts like
+> filters when you use them in filter context. For easier future migration use query
+> classes instead of filter. (Note, for Elasticsearch 1.* you still should use `ScriptFilter`,
+> `HasChildFilter`, `HasParentFilter`, `IndicesFilter`, `NestedFilter`, `PrefixFilter`,
+> `RegexpFilter`, `TermFilter` instead of query as they has different structure.)
+
 To add a filter is the same way like a query. First, lets create some `Filter` object.
 
 ```php
-$matchAllFilter = new MatchAllFilter();
+$matchAllQuery = new MatchAllQuery();
 ```
 
 And simply add to the `Search`:
 
 ```php
-$search->addFilter($matchAllFilter);
+$search->addFilter($matchAllQuery);
 ```
 
 Unlike `Query`, when we add a `Filter` with our DSL library it will add a query and all necessary stuff for you. So when we add one filter we will get this query:
@@ -115,8 +121,8 @@ The same way it works with a `Filter`. Take a look at this example:
 ```php
 $search = new Search();
 $termFilter = new TermFilter('name', 'ongr');
-$missingFilter = new MissingFilter('disabled');
-$existsFilter = new ExistsFilter('tag');
+$missingFilter = new MissingQuery('disabled');
+$existsFilter = new ExistsQuery('tag');
 $search->addFilter($termFilter);
 $search->addFilter($missingFilter);
 $search->addFilter($existsFilter, BoolQuery::MUST_NOT);
diff --git a/docs/Query/Filtered.md b/docs/Query/Filtered.md
index dd88dc654523cf06ebf9712f3e7bc3f53757966c..ab7444ced42260092274820fbfb294d0636f576d 100644
--- a/docs/Query/Filtered.md
+++ b/docs/Query/Filtered.md
@@ -1,5 +1,7 @@
 # Filtered query
 
+__DEPRECATED__: filtered query is deprecated and will be removed in ElasticsearchDSL 2.0
+
 > More info about filtered query is in the [official elasticsearch docs][1]
 
 The filtered query is used to combine another query with any filter. Filters are usually faster than queries.
diff --git a/src/BuilderInterface.php b/src/BuilderInterface.php
index 6e5b7f54a6d6f648576802f8a7f09af737c55259..d30cefbe38ad984372ccbad75e9dd4081c3a3fab 100644
--- a/src/BuilderInterface.php
+++ b/src/BuilderInterface.php
@@ -19,6 +19,9 @@ interface BuilderInterface
     /**
      * Generates array which will be passed to elasticsearch-php client.
      *
+     * WARNING: the output of this method will change in version v2.0. It will
+     * always return array WITH query/aggregation type as key.
+     *
      * @return array|object
      */
     public function toArray();
diff --git a/src/DslTypeAwareTrait.php b/src/DslTypeAwareTrait.php
index 2bfc282379d2118ad0cbeca22bee86ddd75e2969..0b3ead2e44653817e472225548baf6d71ef03c40 100644
--- a/src/DslTypeAwareTrait.php
+++ b/src/DslTypeAwareTrait.php
@@ -13,6 +13,8 @@ namespace ONGR\ElasticsearchDSL;
 
 /**
  * A trait which handles dsl type.
+ *
+ * @deprecated Will be removed in 2.0.
  */
 trait DslTypeAwareTrait
 {
diff --git a/src/FilterOrQueryDetectionTrait.php b/src/FilterOrQueryDetectionTrait.php
index ae6e394541d5d61747087ca423e65581e5dddd13..1d3f15ecda645f2d2d94319a51ab8a7edd23385d 100644
--- a/src/FilterOrQueryDetectionTrait.php
+++ b/src/FilterOrQueryDetectionTrait.php
@@ -13,6 +13,8 @@ namespace ONGR\ElasticsearchDSL;
 
 /**
  * A trait which can detect query or filter is passed.
+ *
+ * @deprecated Will be removed in 2.0.
  */
 trait FilterOrQueryDetectionTrait
 {
diff --git a/src/Query/TypeQuery.php b/src/Query/TypeQuery.php
index 843fca9d0e62cb959e279c33f06d9819e67a87e9..3c2ed250e457165bab21d85e28accacbd8174e56 100644
--- a/src/Query/TypeQuery.php
+++ b/src/Query/TypeQuery.php
@@ -18,7 +18,7 @@ use ONGR\ElasticsearchDSL\BuilderInterface;
  *
  * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-type-query.html
  */
-class TypeQuery implements BuilderInterface  // TODO: add test
+class TypeQuery implements BuilderInterface
 {
     /**
      * @var string
diff --git a/src/Search.php b/src/Search.php
index b9d9d9d49f01f142d487bd71ffec921925db1112..931f38b36ae627dd6a3e6e450ea4f46c5d5def64 100644
--- a/src/Search.php
+++ b/src/Search.php
@@ -221,7 +221,9 @@ class Search
      */
     public function addFilter(BuilderInterface $filter, $boolType = BoolQuery::MUST, $key = null)
     {
+        // Trigger creation of QueryEndpoint as filters depends on it
         $this->getEndpoint(QueryEndpoint::NAME);
+
         $endpoint = $this->getEndpoint(FilterEndpoint::NAME);
         $endpoint->addToBool($filter, $boolType, $key);
 
diff --git a/src/SearchEndpoint/FilterEndpoint.php b/src/SearchEndpoint/FilterEndpoint.php
index 17117c1f2a2e8e43a68485f17dbd3b592d29bbd6..e9c3d8f57e5f03133a22dafb5554a5b2028dc0da 100644
--- a/src/SearchEndpoint/FilterEndpoint.php
+++ b/src/SearchEndpoint/FilterEndpoint.php
@@ -11,7 +11,6 @@
 
 namespace ONGR\ElasticsearchDSL\SearchEndpoint;
 
-use ONGR\ElasticsearchDSL\Query\BoolQuery;
 use ONGR\ElasticsearchDSL\Query\FilteredQuery;
 use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
 
@@ -47,14 +46,4 @@ class FilterEndpoint extends QueryEndpoint
     {
         return 1;
     }
-
-    /**
-     * Returns bool instance for this endpoint case.
-     *
-     * @return BoolQuery
-     */
-    protected function getBoolInstance()
-    {
-        return new BoolQuery();
-    }
 }
diff --git a/src/SearchEndpoint/QueryEndpoint.php b/src/SearchEndpoint/QueryEndpoint.php
index f723e92e37845cf24041e85cb84cb392223dfbdd..9f14df543c3a4c0f3f463501901c97987a65b40c 100644
--- a/src/SearchEndpoint/QueryEndpoint.php
+++ b/src/SearchEndpoint/QueryEndpoint.php
@@ -37,20 +37,24 @@ class QueryEndpoint extends AbstractSearchEndpoint implements OrderedNormalizerI
      */
     public function normalize(NormalizerInterface $normalizer, $format = null, array $context = [])
     {
+        $query = $this->getBool();
+
         if ($this->hasReference('filtered_query')) {
             /** @var FilteredQuery $filteredQuery */
             $filteredQuery = $this->getReference('filtered_query');
-            $this->add($filteredQuery);
+
+            if ($query) {
+                $filteredQuery->setQuery($query);
+            }
+
+            $query = $filteredQuery;
         }
 
-        if (!$this->bool) {
+        if (!$query) {
             return null;
         }
 
-        $queryArray = $this->bool->toArray();
-        $queryArray = [$this->bool->getType() => $queryArray];
-
-        return $queryArray;
+        return [$query->getType() => $query->toArray()];
     }
 
     /**
diff --git a/tests/Query/GeoBoundingBoxQueryTest.php b/tests/Query/GeoBoundingBoxQueryTest.php
index 93c70ab75d601a0bd1941f889df695493baeed13..65b329a642fac1c05137ea7e171c62752913ff62 100644
--- a/tests/Query/GeoBoundingBoxQueryTest.php
+++ b/tests/Query/GeoBoundingBoxQueryTest.php
@@ -11,7 +11,7 @@
 
 namespace ONGR\ElasticsearchDSL\Tests\Query;
 
-use ONGR\ElasticsearchDSL\Filter\GeoBoundingBoxFilter;
+use ONGR\ElasticsearchDSL\Query\GeoBoundingBoxQuery;
 
 class GeoBoundingBoxQueryTest extends \PHPUnit_Framework_TestCase
 {
@@ -20,10 +20,10 @@ class GeoBoundingBoxQueryTest extends \PHPUnit_Framework_TestCase
      *
      * @expectedException \LogicException
      */
-    public function testGeoBoundBoxFilterException()
+    public function testGeoBoundBoxQueryException()
     {
-        $filter = new GeoBoundingBoxFilter('location', []);
-        $filter->toArray();
+        $query = new GeoBoundingBoxQuery('location', []);
+        $query->toArray();
     }
 
     /**
@@ -80,8 +80,8 @@ class GeoBoundingBoxQueryTest extends \PHPUnit_Framework_TestCase
      */
     public function testToArray($field, $values, $parameters, $expected)
     {
-        $filter = new GeoBoundingBoxFilter($field, $values, $parameters);
-        $result = $filter->toArray();
+        $query = new GeoBoundingBoxQuery($field, $values, $parameters);
+        $result = $query->toArray();
         $this->assertEquals($expected, $result);
     }
 }
diff --git a/tests/Query/HasChildQueryTest.php b/tests/Query/HasChildQueryTest.php
index 2caa3a0f0fde7aed1ff6299611909c4eba7f0acf..da8852af5d3b854b6331cb79071bf0321273fc93 100644
--- a/tests/Query/HasChildQueryTest.php
+++ b/tests/Query/HasChildQueryTest.php
@@ -20,10 +20,8 @@ class HasChildQueryTest extends \PHPUnit_Framework_TestCase
      */
     public function testConstructor()
     {
-        $missingFilterMock = $this->getMockBuilder('ONGR\ElasticsearchDSL\Filter\MissingFilter')
-            ->setConstructorArgs(['test_field'])
-            ->getMock();
-        $query = new HasChildQuery('test_type', $missingFilterMock, ['test_parameter1']);
+        $childQuery = $this->getMock('ONGR\ElasticsearchDSL\BuilderInterface');
+        $query = new HasChildQuery('test_type', $childQuery, ['test_parameter1']);
         $this->assertEquals(['test_parameter1'], $query->getParameters());
     }
 }
diff --git a/tests/Query/HasParentQueryTest.php b/tests/Query/HasParentQueryTest.php
index 623d914451def0531666e58fb59e1677649b0b18..d2069097c870fc64cde8abed2051f69018768ef1 100644
--- a/tests/Query/HasParentQueryTest.php
+++ b/tests/Query/HasParentQueryTest.php
@@ -20,10 +20,8 @@ class HasParentQueryTest extends \PHPUnit_Framework_TestCase
      */
     public function testConstructor()
     {
-        $missingFilter = $this->getMockBuilder('ONGR\ElasticsearchDSL\Filter\MissingFilter')
-            ->setConstructorArgs(['test_field'])
-            ->getMock();
-        $query = new HasParentQuery('test_type', $missingFilter, ['test_parameter1']);
+        $parentQuery = $this->getMock('ONGR\ElasticsearchDSL\BuilderInterface');
+        $query = new HasParentQuery('test_type', $parentQuery, ['test_parameter1']);
         $this->assertEquals(['test_parameter1'], $query->getParameters());
     }
 }
diff --git a/tests/SearchEndpoint/FilterEndpointTest.php b/tests/SearchEndpoint/FilterEndpointTest.php
index 5e3b4ade0408c7de33f42e8dde97b49b512a2129..c8c8eb8e75830902953775b61e1961a3400e440b 100644
--- a/tests/SearchEndpoint/FilterEndpointTest.php
+++ b/tests/SearchEndpoint/FilterEndpointTest.php
@@ -11,8 +11,8 @@
 
 namespace ONGR\ElasticsearchDSL\Tests\Unit\SearchEndpoint;
 
-use ONGR\ElasticsearchDSL\Filter\MatchAllFilter;
 use ONGR\ElasticsearchDSL\Query\FilteredQuery;
+use ONGR\ElasticsearchDSL\Query\MatchAllQuery;
 use ONGR\ElasticsearchDSL\SearchEndpoint\FilterEndpoint;
 use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
 use PHPUnit_Framework_MockObject_MockObject as MockObject;
@@ -55,7 +55,7 @@ class FilterEndpointTest extends \PHPUnit_Framework_TestCase
         $this->assertNull($instance->normalize($normalizerInterface));
         $this->assertFalse($instance->hasReference('filtered_query'));
 
-        $matchAllFilter = new MatchAllFilter();
+        $matchAllFilter = new MatchAllQuery();
         $instance->add($matchAllFilter);
 
         $this->assertNull($instance->normalize($normalizerInterface));
@@ -81,7 +81,7 @@ class FilterEndpointTest extends \PHPUnit_Framework_TestCase
     public function testEndpointGetter()
     {
         $filterName = 'acme_filter';
-        $filter = new MatchAllFilter();
+        $filter = new MatchAllQuery();
         $endpoint = new FilterEndpoint();
         $endpoint->add($filter, $filterName);
         $builders = $endpoint->getAll();
diff --git a/tests/SearchEndpoint/PostFilterEndpointTest.php b/tests/SearchEndpoint/PostFilterEndpointTest.php
index 7c22d4acb5edd22616ddddc6e0d0aed1d4d623c5..297249b762aa67b8f0bf6ecc43d8f57b1f259983 100644
--- a/tests/SearchEndpoint/PostFilterEndpointTest.php
+++ b/tests/SearchEndpoint/PostFilterEndpointTest.php
@@ -11,7 +11,7 @@
 
 namespace ONGR\ElasticsearchDSL\Tests\Unit\SearchEndpoint;
 
-use ONGR\ElasticsearchDSL\Filter\MatchAllFilter;
+use ONGR\ElasticsearchDSL\Query\MatchAllQuery;
 use ONGR\ElasticsearchDSL\SearchEndpoint\PostFilterEndpoint;
 use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
 use PHPUnit_Framework_MockObject_MockObject as MockObject;
@@ -50,7 +50,7 @@ class PostFilterEndpointTest extends \PHPUnit_Framework_TestCase
         );
         $this->assertNull($instance->normalize($normalizerInterface));
 
-        $matchAll = new MatchAllFilter();
+        $matchAll = new MatchAllQuery();
         $instance->add($matchAll);
 
         $this->assertEquals(
@@ -65,7 +65,7 @@ class PostFilterEndpointTest extends \PHPUnit_Framework_TestCase
     public function testEndpointGetter()
     {
         $filterName = 'acme_post_filter';
-        $filter = new MatchAllFilter();
+        $filter = new MatchAllQuery();
 
         $endpoint = new PostFilterEndpoint();
         $endpoint->add($filter, $filterName);