/**
  * Add required JOINs to resulting Query Builder.
  *
  * @param QueryBuilder $optimizedQueryBuilder
  * @param array        $originalQueryParts
  */
 protected function addJoins(QueryBuilder $optimizedQueryBuilder, array $originalQueryParts)
 {
     // Collect list of tables which should be added to new query
     $whereAliases = $this->qbTools->getUsedTableAliases($originalQueryParts['where']);
     $groupByAliases = $this->qbTools->getUsedTableAliases($originalQueryParts['groupBy']);
     $havingAliases = $this->qbTools->getUsedTableAliases($originalQueryParts['having']);
     $joinAliases = array_merge($whereAliases, $groupByAliases, $havingAliases);
     $joinAliases = array_unique($joinAliases);
     // this joins cannot be removed outside of this class
     $requiredJoinAliases = $joinAliases;
     $joinAliases = array_merge($joinAliases, $this->getNonSymmetricJoinAliases($originalQueryParts['from'], $originalQueryParts['join'], $groupByAliases));
     $rootAliases = [];
     /** @var Expr\From $from */
     foreach ($originalQueryParts['from'] as $from) {
         $rootAliases[] = $from->getAlias();
         $joinAliases = array_merge($joinAliases, $this->qbTools->getUsedJoinAliases($originalQueryParts['join'], $joinAliases, $from->getAlias()));
     }
     $allAliases = $this->context->getAliases();
     $joinAliases = array_intersect(array_diff(array_unique($joinAliases), $rootAliases), $allAliases);
     $requiredJoinAliases = array_intersect(array_diff($requiredJoinAliases, $rootAliases), $allAliases);
     $joinAliases = $this->dispatchQueryOptimizationEvent($joinAliases, $requiredJoinAliases);
     foreach ($rootAliases as $rootAlias) {
         if (!isset($originalQueryParts['join'][$rootAlias])) {
             continue;
         }
         /** @var Expr\Join $join */
         foreach ($originalQueryParts['join'][$rootAlias] as $join) {
             $alias = $join->getAlias();
             // To count results number join all tables with inner join and required to tables
             if ($join->getJoinType() === Expr\Join::INNER_JOIN || in_array($alias, $joinAliases, true)) {
                 $condition = $this->qbTools->replaceAliasesWithFields($join->getCondition());
                 $condition = $this->qbTools->replaceAliasesWithJoinPaths($condition);
                 if ($join->getJoinType() === Expr\Join::INNER_JOIN) {
                     $optimizedQueryBuilder->innerJoin($join->getJoin(), $alias, $join->getConditionType(), $condition, $join->getIndexBy());
                 } else {
                     $optimizedQueryBuilder->leftJoin($join->getJoin(), $alias, $join->getConditionType(), $condition, $join->getIndexBy());
                 }
             }
         }
     }
 }