private function queryFor(
        MapInterface $changesets,
        MapInterface $entities
    ): Query {
        $this->variables = new Map(Str::class, MapInterface::class);

        $query = $changesets->reduce(
            new Query\Query,
            function(Query $carry, Identity $identity, MapInterface $changeset) use ($entities): Query {
                $entity = $entities->get($identity);
                $meta = ($this->metadata)(\get_class($entity));

                if ($meta instanceof Aggregate) {
                    return $this->matchAggregate(
                        $identity,
                        $entity,
                        $meta,
                        $changeset,
                        $carry
                    );
                } else if ($meta instanceof Relationship) {
                    return $this->matchRelationship(
                        $identity,
                        $entity,
                        $meta,
                        $changeset,
                        $carry
                    );
                }
            }
        );
        $query = $this
            ->variables
            ->reduce(
                $query,
                function(Query $carry, Str $variable, MapInterface $changeset): Query {
                    return $this->update($variable, $changeset, $carry);
                }
            );
        $this->variables = null;

        return $query;
    }