diff --git a/core/lib/Drupal/Core/Config/Entity/Query/Query.php b/core/lib/Drupal/Core/Config/Entity/Query/Query.php
index c6320f3..905b147 100644
--- a/core/lib/Drupal/Core/Config/Entity/Query/Query.php
+++ b/core/lib/Drupal/Core/Config/Entity/Query/Query.php
@@ -9,7 +9,6 @@
 
 use Drupal\Core\Config\StorageInterface;
 use Drupal\Core\Entity\EntityManager;
-use Drupal\Core\Entity\EntityStorageControllerInterface;
 use Drupal\Core\Entity\Query\QueryBase;
 use Drupal\Core\Entity\Query\QueryInterface;
 
@@ -52,13 +51,6 @@ function __construct($entity_type, $conjunction, EntityManager $entity_manager,
   }
 
   /**
-   * Implements \Drupal\Core\Entity\Query\QueryInterface::conditionGroupFactory().
-   */
-  public function conditionGroupFactory($conjunction = 'AND') {
-    return new Condition($conjunction);
-  }
-
-  /**
    * Overrides \Drupal\Core\Entity\Query\QueryBase::condition().
    *
    * Additional to the syntax defined in the QueryInterface you can use
diff --git a/core/lib/Drupal/Core/Entity/Query/ConditionFundamentals.php b/core/lib/Drupal/Core/Entity/Query/ConditionFundamentals.php
index 828ff62..195479d 100644
--- a/core/lib/Drupal/Core/Entity/Query/ConditionFundamentals.php
+++ b/core/lib/Drupal/Core/Entity/Query/ConditionFundamentals.php
@@ -30,13 +30,21 @@
   protected $conjunction;
 
   /**
+   * The query this condition belongs to.
+   *
+   * @var \Drupal\Core\Entity\Query\QueryInterface
+   */
+  protected $query;
+
+  /**
    * Constructs a Condition object.
    *
    * @param string $conjunction
    *   The operator to use to combine conditions: 'AND' or 'OR'.
    */
-  public function __construct($conjunction = 'AND') {
+  public function __construct($conjunction, QueryInterface $query) {
     $this->conjunction = $conjunction;
+    $this->query = $query;
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Entity/Query/QueryBase.php b/core/lib/Drupal/Core/Entity/Query/QueryBase.php
index c3c6932..b4b2ea7 100644
--- a/core/lib/Drupal/Core/Entity/Query/QueryBase.php
+++ b/core/lib/Drupal/Core/Entity/Query/QueryBase.php
@@ -171,6 +171,24 @@ public function range($start = NULL, $length = NULL) {
   }
 
   /**
+   * Creates an object holding a group of conditions.
+   *
+   * See andConditionGroup() and orConditionGroup() for more.
+   *
+   * @param $conjunction
+   *   - AND (default): this is the equivalent of andConditionGroup().
+   *   - OR: this is the equivalent of orConditionGroup().
+   *
+   * return \Drupal\Core\Entity\Query\ConditionInterface
+   *   An object holding a group of conditions.
+   */
+  protected function conditionGroupFactory($conjunction = 'AND') {
+    preg_match('/^(.*)\\\\/', get_class($this), $matches);
+    $class = $matches[1] .'\\Condition';
+    return new $class($conjunction, $this);
+  }
+
+  /**
    * Implements \Drupal\Core\Entity\Query\QueryInterface::andConditionGroup().
    */
   public function andConditionGroup() {
diff --git a/core/lib/Drupal/Core/Entity/Query/QueryInterface.php b/core/lib/Drupal/Core/Entity/Query/QueryInterface.php
index 4e27ad8..c82a3da 100644
--- a/core/lib/Drupal/Core/Entity/Query/QueryInterface.php
+++ b/core/lib/Drupal/Core/Entity/Query/QueryInterface.php
@@ -177,20 +177,6 @@ public function age($age = FIELD_LOAD_CURRENT);
   public function execute();
 
   /**
-   * Creates an object holding a group of conditions.
-   *
-   * See andConditionGroup() and orConditionGroup() for more.
-   *
-   * @param $conjunction
-   *   - AND (default): this is the equivalent of andConditionGroup().
-   *   - OR: this is the equivalent of andConditionGroup().
-   *
-   * return ConditionInterface
-   *   An object holding a group of conditions.
-   */
-  public function conditionGroupFactory($conjunction = 'AND');
-
-  /**
    * Creates a new group of conditions ANDed together.
    *
    * For example, consider a drawing entity type with a 'figures' multi-value
diff --git a/core/lib/Drupal/Core/Entity/Query/Sql/Condition.php b/core/lib/Drupal/Core/Entity/Query/Sql/Condition.php
index 7323586..6630c47 100644
--- a/core/lib/Drupal/Core/Entity/Query/Sql/Condition.php
+++ b/core/lib/Drupal/Core/Entity/Query/Sql/Condition.php
@@ -15,6 +15,11 @@
 class Condition extends ConditionBase {
 
   /**
+   * @var \Drupal\Core\Entity\Query\Sql\Query
+   */
+  protected $query;
+
+  /**
    * Implements Drupal\Core\Entity\Query\ConditionInterface::compile().
    */
   public function compile($conditionContainer) {
@@ -24,7 +29,7 @@ public function compile($conditionContainer) {
     // can join tables as necessary. On the other hand, conditions need to be
     // added to the $conditionContainer object to keep grouping.
     $sqlQuery = $conditionContainer instanceof SelectInterface ? $conditionContainer : $conditionContainer->sqlQuery;
-    $tables = new Tables($sqlQuery);
+    $tables = $this->query->getTables($sqlQuery);
     foreach ($this->conditions as $condition) {
       if ($condition['field'] instanceOf ConditionInterface) {
         $sqlCondition = new SqlCondition($condition['field']->getConjunction());
diff --git a/core/lib/Drupal/Core/Entity/Query/Sql/Query.php b/core/lib/Drupal/Core/Entity/Query/Sql/Query.php
index 6fbae92..fa0f7fd 100644
--- a/core/lib/Drupal/Core/Entity/Query/Sql/Query.php
+++ b/core/lib/Drupal/Core/Entity/Query/Sql/Query.php
@@ -8,6 +8,7 @@
 namespace Drupal\Core\Entity\Query\Sql;
 
 use Drupal\Core\Database\Connection;
+use Drupal\Core\Database\Query\SelectInterface;
 use Drupal\Core\Entity\EntityManager;
 use Drupal\Core\Entity\Query\QueryBase;
 use Drupal\Core\Entity\Query\QueryException;
@@ -87,13 +88,6 @@ public function __construct($entity_type, EntityManager $entity_manager, $conjun
 
 
   /**
-   * Implements Drupal\Core\Entity\Query\QueryInterface::conditionGroupFactory().
-   */
-  public function conditionGroupFactory($conjunction = 'AND') {
-    return new Condition($conjunction);
-  }
-
-  /**
    * Implements \Drupal\Core\Entity\Query\QueryInterface::execute().
    */
   public function execute() {
@@ -289,7 +283,7 @@ protected function result() {
    */
   protected function getSqlField($field, $langcode) {
     if (!isset($this->tables)) {
-      $this->tables = new Tables($this->sqlQuery);
+      $this->tables = $this->getTables($this->sqlQuery);
     }
     $base_property = "base_table.$field";
     if (isset($this->sqlFields[$base_property])) {
@@ -320,4 +314,15 @@ public function __clone() {
     $this->sqlGroupBy = array();
   }
 
+  /**
+   * Gets the Tables object for this query.
+   *
+   * @return \Drupal\Core\Entity\Query\Sql\TablesInterface
+   */
+  public function getTables(SelectInterface $sql_query) {
+    preg_match('/^(.*)\\\\/', get_class($this), $matches);
+    $class = $matches[1] .'\\Tables';
+    return new $class($sql_query);
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Entity/Query/Sql/QueryFactory.php b/core/lib/Drupal/Core/Entity/Query/Sql/QueryFactory.php
index 2a45e05..00974a7 100644
--- a/core/lib/Drupal/Core/Entity/Query/Sql/QueryFactory.php
+++ b/core/lib/Drupal/Core/Entity/Query/Sql/QueryFactory.php
@@ -32,7 +32,7 @@ class QueryFactory implements QueryFactoryInterface {
    * @param \Drupal\Core\Database\Connection $connection
    *   The database connection used by the entity query.
    */
-  function __construct(Connection $connection) {
+  public function __construct(Connection $connection) {
     $this->connection = $connection;
   }
 
@@ -48,8 +48,10 @@ function __construct(Connection $connection) {
    * @return \Drupal\Core\Entity\Query\Sql\Query
    *   The factored query.
    */
-  function get($entity_type, $conjunction, EntityManager $entity_manager) {
-    return new Query($entity_type, $entity_manager, $conjunction, $this->connection);
+  public function get($entity_type, $conjunction, EntityManager $entity_manager) {
+    preg_match('/^(.*)\\\\/', get_class($this), $matches);
+    $class = $matches[1] .'\\Query';
+    return new $class($entity_type, $entity_manager, $conjunction, $this->connection);
   }
 
   /**
@@ -64,8 +66,10 @@ function get($entity_type, $conjunction, EntityManager $entity_manager) {
    * @return \Drupal\Core\Entity\Query\Sql\QueryAggregate
    *   The factored aggregation query.
    */
-  function getAggregate($entity_type, $conjunction, EntityManager $entity_manager) {
-    return new QueryAggregate($entity_type, $entity_manager, $conjunction, $this->connection);
+  public function getAggregate($entity_type, $conjunction, EntityManager $entity_manager) {
+    preg_match('/^(.*)\\\\/', get_class($this), $matches);
+    $class = $matches[1] .'\\QueryAggregate';
+    return new $class($entity_type, $entity_manager, $conjunction, $this->connection);
   }
 
 }
diff --git a/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php b/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php
index 2f7156a..4eb1ca7 100644
--- a/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php
+++ b/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php
@@ -45,22 +45,14 @@ class Tables {
   /**
    * @param \Drupal\Core\Database\Query\SelectInterface $sql_query
    */
-  function __construct(SelectInterface $sql_query) {
+  public function __construct(SelectInterface $sql_query) {
     $this->sqlQuery = $sql_query;
   }
 
   /**
-   * @param string $field
-   *   If it contains a dot, then field name dot field column. If it doesn't
-   *   then entity property name.
-   * @param string $type
-   *   Join type, can either be INNER or LEFT.
-   * @return string
-   *   The return value is a string containing the alias of the table, a dot
-   *   and the appropriate SQL column as passed in. This allows the direct use
-   *   of this in a query for a condition or sort.
+   * {@inheritdoc}
    */
-  function addField($field, $type, $langcode) {
+  public function addField($field, $type, $langcode) {
     $entity_type = $this->sqlQuery->getMetaData('entity_type');
     $age = $this->sqlQuery->getMetaData('age');
     // This variable ensures grouping works correctly. For example:
diff --git a/core/lib/Drupal/Core/Entity/Query/Sql/TablesInterface.php b/core/lib/Drupal/Core/Entity/Query/Sql/TablesInterface.php
new file mode 100644
index 0000000..4f72d71
--- /dev/null
+++ b/core/lib/Drupal/Core/Entity/Query/Sql/TablesInterface.php
@@ -0,0 +1,29 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Entity\Query\Sql\TablesInterface.
+ */
+
+
+namespace Drupal\Core\Entity\Query\Sql;
+
+
+/**
+ * Adds tables and fields to the SQL entity query.
+ */
+interface TablesInterface {
+  /**
+   * @param string $field
+   *   If it contains a dot, then field name dot field column. If it doesn't
+   *   then entity property name.
+   * @param string $type
+   *   Join type, can either be INNER or LEFT.
+   *
+   * @return string
+   *   The return value is a string containing the alias of the table, a dot
+   *   and the appropriate SQL column as passed in. This allows the direct use
+   *   of this in a query for a condition or sort.
+   */
+  public function addField($field, $type, $langcode);
+}
