public function getQueryBuilderPath($propertyPath)
    {
        if (false === strpos($propertyPath, '.')) {
            return $this->alias . '.' . $propertyPath;
        }

        if (isset($this->paths[$propertyPath])) {
            return $this->paths[$propertyPath];
        }

        $paths = explode('.', $propertyPath);
        $property = array_pop($paths);

        $path = implode('.', array_slice($paths, 0, $i = count($paths)));

        if (!isset($this->aliases[$path])) {
            // Skip already defined aliases
            do {
                $i--;
                $path = implode('.', array_slice($paths, 0, $i));
                if (isset($this->aliases[$path])) {
                    break;
                }
            } while ($i > 0);

            do {
                // TODO Join may have been made by the source's query builder initializer : retrieve the configured alias
                //$this->queryBuilder->getDQLPart('join');

                $alias = chr(98 + count($this->aliases));

                $this->queryBuilder->leftJoin(($i == 0 ? $this->alias : $this->aliases[$path]) . '.' . $paths[$i], $alias);

                // Add select if manyToOne and lvl = 1 (ex: product.brand => b)
                if ($i == 0 && $this->getClassMetadata()->isSingleValuedAssociation($paths[$i])) {
                    $this->queryBuilder->addSelect($alias);
                }

                $i++;
                $path = implode('.', array_slice($paths, 0, $i));
                $this->aliases[$path] = $alias;
            } while ($i < count($paths));
        }

        return $this->paths[$propertyPath] = $this->aliases[$path] . '.' . $property;
    }