diff --git a/Filter/AbstractFilter.php b/Filter/AbstractFilter.php
deleted file mode 100644
index bf5d837a053d8674df945d53d739094a51fe5ae0..0000000000000000000000000000000000000000
--- a/Filter/AbstractFilter.php
+++ /dev/null
@@ -1,82 +0,0 @@
-<?php
-
-/*
- * This file is part of the ONGR package.
- *
- * (c) NFQ Technologies UAB <info@nfq.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace ONGR\ElasticsearchBundle\DSL\Filter;
-
-use ONGR\ElasticsearchBundle\DSL\Bool\Bool;
-use ONGR\ElasticsearchBundle\DSL\BuilderInterface;
-
-/**
- * AbstractFilter class.
- */
-abstract class AbstractFilter
-{
-    /**
-     * @var BuilderInterface
-     */
-    protected $filters;
-
-    /**
-     * Initializes bool filter.
-     *
-     * @param array $boolParams Bool parameters.
-     */
-    public function __construct($boolParams = [])
-    {
-        $this->filters = new Bool();
-        $this->filters->setParameters($boolParams);
-    }
-
-    /**
-     * @param BuilderInterface $filter   Filter.
-     * @param string           $boolType Possible boolType values:
-     *                                   - must
-     *                                   - must_not
-     *                                   - should.
-     */
-    public function addFilter(BuilderInterface $filter, $boolType = 'must')
-    {
-        $this->filters->addToBool($filter, $boolType);
-    }
-
-    /**
-     * Overrides filters.
-     *
-     * @param BuilderInterface $filters
-     *
-     * @return $this
-     */
-    public function setFilter(BuilderInterface $filters)
-    {
-        $this->filters = $filters;
-
-        return $this;
-    }
-
-    /**
-     * @param array $boolParams
-     */
-    public function setBoolParameters($boolParams)
-    {
-        $this->filters->setParameters($boolParams);
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function toArray()
-    {
-        $output = [];
-        $output[$this->filters->getType()] = $this->filters->toArray();
-
-        return $output;
-    }
-}
diff --git a/Filter/PostFilter.php b/Filter/PostFilter.php
index aa49e3c08b521efe6ac78ba6affebba1af20c2b0..b04b04ff2d18a4545bea9e1060fd93101ff60ab1 100644
--- a/Filter/PostFilter.php
+++ b/Filter/PostFilter.php
@@ -14,18 +14,67 @@ namespace ONGR\ElasticsearchBundle\DSL\Filter;
 use ONGR\ElasticsearchBundle\DSL\BuilderInterface;
 
 /**
- * Filters container.
+ * Represents Elasticsearch "post_filter" filter.
+ *
+ * @link http://www.elastic.co/guide/en/elasticsearch/guide/current/_post_filter.html
  */
-class PostFilter extends AbstractFilter implements BuilderInterface
+class PostFilter implements BuilderInterface
 {
+    /**
+     * @var BuilderInterface
+     */
+    private $filter;
+
+    /**
+     * Sets a filter.
+     *
+     * @param BuilderInterface $filter
+     */
+    public function __construct(BuilderInterface $filter = null)
+    {
+        if ($this->filter !== null) {
+            $this->setFilter($filter);
+        }
+    }
+    
     /**
      * Checks if bool filter is relevant.
      *
      * @return bool
+     *
+     * @deprecated Will be removed in 1.0. Use getFilter() method.
      */
     public function isRelevant()
     {
-        return $this->filters->isRelevant();
+        return isset($this->filter);
+    }
+
+    /**
+     * Returns filter.
+     *
+     * @return BuilderInterface
+     */
+    public function getFilter()
+    {
+        return $this->filter;
+    }
+
+    /**
+     * Sets filter.
+     *
+     * @param BuilderInterface $filter
+     */
+    public function setFilter(BuilderInterface $filter)
+    {
+        $this->filter = $filter;
+    }
+    
+    /**
+     * {@inheritdoc}
+     */
+    public function toArray()
+    {
+        return [$this->getFilter()->getType() => $this->getFilter()->toArray()];
     }
 
     /**
diff --git a/NamedBuilderBag.php b/NamedBuilderBag.php
index a73f6e0613229f1aca5ae00fe687ca834e1c6843..4fb69da8455e039eee21b4d18e3758b8a4e43a46 100644
--- a/NamedBuilderBag.php
+++ b/NamedBuilderBag.php
@@ -104,9 +104,8 @@ class NamedBuilderBag
     {
         return array_filter(
             $this->bag,
+            /** @var NamedBuilderInterface $builder */
             function ($builder) use ($type) {
-                /** @var NamedBuilderInterface $builder */
-
                 return $type === null || $builder->getType() == $type;
             }
         );
diff --git a/Query/FilteredQuery.php b/Query/FilteredQuery.php
index 3c3d3683837e4e85d9cb2faa1c5743e2207f9cd7..f20040bf4a2899f5dfa18394d4ca339b0c688381 100644
--- a/Query/FilteredQuery.php
+++ b/Query/FilteredQuery.php
@@ -12,45 +12,76 @@
 namespace ONGR\ElasticsearchBundle\DSL\Query;
 
 use ONGR\ElasticsearchBundle\DSL\BuilderInterface;
-use ONGR\ElasticsearchBundle\DSL\Filter\AbstractFilter;
+use ONGR\ElasticsearchBundle\DSL\ParametersTrait;
 
 /**
- * Filtered query class.
+ * Represents Elasticsearch "bool" filter.
+ *
+ * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-filtered-query.html
  */
-class FilteredQuery extends AbstractFilter implements BuilderInterface
+class FilteredQuery implements BuilderInterface
 {
+    use ParametersTrait;
+    
     /**
-     * @var Query Used inside filtered area.
+     * @var BuilderInterface Used query inside filtered query.
      */
     private $query;
 
     /**
-     * @param Query $query
+     * @var BuilderInterface Used filter inside filtered query.
      */
-    public function __construct($query = null)
+    private $filter;
+
+    /**
+     * @param BuilderInterface $query
+     * @param BuilderInterface $filter
+     */
+    public function __construct($query = null, $filter = null)
+    {
+        if ($query !== null) {
+            $this->setQuery($query);
+        }
+        
+        if ($filter !== null) {
+            $this->setFilter($filter);
+        }
+    }
+
+    /**
+     * Sets query.
+     *
+     * @param BuilderInterface $query
+     */
+    public function setQuery(BuilderInterface $query)
     {
-        parent::__construct();
         $this->query = $query;
     }
 
     /**
-     * @return Query
+     * @return BuilderInterface
      */
     public function getQuery()
     {
-        if ($this->query === null) {
-            $this->query = new Query();
-        }
-
         return $this->query;
     }
 
     /**
-     * @param BuilderInterface $query
+     * Sets filter.
+     *
+     * @param BuilderInterface $filter
      */
-    public function setQuery(BuilderInterface $query)
+    public function setFilter(BuilderInterface $filter)
     {
-        $this->query = $query;
+        $this->filter = $filter;
+    }
+
+    /**
+     * @return BuilderInterface
+     */
+    public function getFilter()
+    {
+        return $this->filter;
     }
 
     /**
@@ -67,12 +98,15 @@ class FilteredQuery extends AbstractFilter implements BuilderInterface
     public function toArray()
     {
         $output = [];
-        $output['filter'] = parent::toArray();
+        
+        if ($this->getFilter()) {
+            $output['filter'][$this->getFilter()->getType()] = $this->getFilter()->toArray();
+        }
 
-        if ($this->query) {
+        if ($this->getQuery()) {
             $output['query'][$this->getQuery()->getType()] = $this->getQuery()->toArray();
         }
 
-        return $output;
+        return count($output) > 0 ? $this->processArray($output) : [];
     }
 }
diff --git a/SearchEndpoint/FilterEndpoint.php b/SearchEndpoint/FilterEndpoint.php
index 45e572b9efe92cdd7b74d4d0d916264d9cf66fd8..1ccfbcb6cf3f667d181950cfcea4fe81a85c6507 100644
--- a/SearchEndpoint/FilterEndpoint.php
+++ b/SearchEndpoint/FilterEndpoint.php
@@ -11,6 +11,7 @@
 
 namespace ONGR\ElasticsearchBundle\DSL\SearchEndpoint;
 
+use ONGR\ElasticsearchBundle\DSL\Filter\BoolFilter;
 use ONGR\ElasticsearchBundle\DSL\Query\FilteredQuery;
 use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
 
@@ -26,7 +27,7 @@ class FilterEndpoint extends QueryEndpoint
     {
         if ($this->getBuilder()) {
             $query = new FilteredQuery();
-            $query->setBoolParameters($this->getParameters());
+            !$this->isBool() ? : $this->getBuilder()->setParameters($this->getParameters());
             $query->setFilter($this->getBuilder());
             $this->addReference('filtered_query', $query);
         }
@@ -39,4 +40,12 @@ class FilterEndpoint extends QueryEndpoint
     {
         return 1;
     }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getBoolInstance()
+    {
+        return new BoolFilter();
+    }
 }
diff --git a/SearchEndpoint/PostFilterEndpoint.php b/SearchEndpoint/PostFilterEndpoint.php
index acd0967a68e32fdfd636e84e5b00ad40a73aa9af..32d369f93e733f87df193814c43092fc1797d9b0 100644
--- a/SearchEndpoint/PostFilterEndpoint.php
+++ b/SearchEndpoint/PostFilterEndpoint.php
@@ -17,7 +17,7 @@ use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
 /**
  * Search post filter dsl endpoint.
  */
-class PostFilterEndpoint extends QueryEndpoint
+class PostFilterEndpoint extends FilterEndpoint
 {
     /**
      * {@inheritdoc}
@@ -26,7 +26,7 @@ class PostFilterEndpoint extends QueryEndpoint
     {
         if ($this->getBuilder()) {
             $postFilter = new PostFilter();
-            $postFilter->setBoolParameters($this->getParameters());
+            !$this->isBool() ? : $this->getBuilder()->setParameters($this->getParameters());
             $postFilter->setFilter($this->getBuilder());
 
             return $postFilter->toArray();
diff --git a/SearchEndpoint/QueryEndpoint.php b/SearchEndpoint/QueryEndpoint.php
index ddf4ec414e4d8e50cad1c5a6e922fa3b704a23a8..c74770b704d7594fabbe9fea581ff79c036a1757 100644
--- a/SearchEndpoint/QueryEndpoint.php
+++ b/SearchEndpoint/QueryEndpoint.php
@@ -11,9 +11,9 @@
 
 namespace ONGR\ElasticsearchBundle\DSL\SearchEndpoint;
 
-use ONGR\ElasticsearchBundle\DSL\Bool\Bool;
 use ONGR\ElasticsearchBundle\DSL\BuilderInterface;
 use ONGR\ElasticsearchBundle\DSL\ParametersTrait;
+use ONGR\ElasticsearchBundle\DSL\Query\BoolQuery;
 use ONGR\ElasticsearchBundle\DSL\Query\FilteredQuery;
 use ONGR\ElasticsearchBundle\Serializer\Normalizer\OrderedNormalizerInterface;
 use Symfony\Component\OptionsResolver\OptionsResolver;
@@ -27,7 +27,7 @@ class QueryEndpoint extends AbstractSearchEndpoint implements OrderedNormalizerI
     use ParametersTrait;
 
     /**
-     * @var BuilderInterface|Bool
+     * @var BuilderInterface|BoolQuery
      */
     private $query;
 
@@ -54,8 +54,8 @@ class QueryEndpoint extends AbstractSearchEndpoint implements OrderedNormalizerI
             $this->setBuilder($builder);
         } else {
             $parameters = $this->resolver->resolve(array_filter($parameters));
-            $this->query instanceof Bool ? : $this->convertToBool();
-            $this->query->addToBool($builder, $parameters['bool_type']);
+            $this->isBool() ? : $this->convertToBool();
+            $this->query->add($builder, $parameters['bool_type']);
         }
 
         return $this;
@@ -123,19 +123,39 @@ class QueryEndpoint extends AbstractSearchEndpoint implements OrderedNormalizerI
     {
         $resolver
             ->setDefaults(
-                ['bool_type' => Bool::MUST]
+                ['bool_type' => BoolQuery::MUST]
             );
     }
 
+    /**
+     * Returns true if query is bool.
+     *
+     * @return bool
+     */
+    protected function isBool()
+    {
+        return $this->getBuilder() instanceof BoolQuery;
+    }
+
+    /**
+     * Returns bool instance for this endpoint case.
+     *
+     * @return BoolQuery
+     */
+    protected function getBoolInstance()
+    {
+        return new BoolQuery();
+    }
+
     /**
      * Converts query to bool.
      */
     private function convertToBool()
     {
-        $bool = new Bool();
+        $bool = $this->getBoolInstance();
 
         if ($this->query !== null) {
-            $bool->addToBool($this->query);
+            $bool->add($this->query);
         }
 
         $this->query = $bool;