public function populateRelation($name, &$primaryModels)
    {
        if (!is_array($this->link)) {
            throw new InvalidConfigException('Invalid link: it must be an array of key-value pairs.');
        }
        $viaQuery = null;
        $viaModels = null;
        $viaModelsUsed = true;
        if ($this->via instanceof self) {
            // via junction table
            /* @var $viaQuery ActiveRelationTrait */
            $viaQuery = $this->via;
            $filterPr = $viaQuery->findJunctionRows($primaryModels)->otherwise(
                function() {
                    return [];
                }
            );
        } elseif (is_array($this->via)) {
            // via relation
            /* @var $viaQuery ActiveRelationTrait|ActiveQueryTrait */
            list($viaName, $viaQuery) = $this->via;
            if ($viaQuery->asArray === null) {
                // inherit asArray from primary query
                $viaQuery->asArray($this->asArray);
            }
            $viaQuery->primaryModel = null;
            $filterPr = $viaQuery->populateRelation($viaName, $primaryModels)->otherwise(
                function() {
                    return [];
                }
            );
        } else {
            $viaModelsUsed = false;
            $filterPr = resolve($primaryModels);
        }
        $filterPr->then(function($filterModels) use (&$viaModelsUsed, &$viaModels) {
            if ($viaModelsUsed) {
                $viaModels = $filterModels;
            }
            $this->filterByModels($filterModels);
            return true;
        })->then(function() use ($name, &$primaryModels, &$viaModels, &$viaQuery) {
            if (!$this->multiple && count($primaryModels) === 1) {
                return $this->populateRelationAsyncSingle($name, $primaryModels);
            } else {
                return $this->populateRelationAsyncMultiple($name, $primaryModels, $viaModels, $viaQuery);
            }
        });
        return $filterPr;
    }