protected function dereference($id): string
    {
        if ($id instanceof Reference) {
            $id = $id->getId();
        }

        if (!isset($this->definitions[$id]) || !$this->definitions[$id] instanceof Reference) {
            return $id;
        }

        if (isset($this->dereferencing[$id])) {
            throw new CircularReferenceException(sprintf(
                'Circular reference to "%s" detected while dereferencing: %s; building: %s',
                $id,
                implode(',', array_keys($this->dereferencing)),
                implode(',', array_keys($this->building))
            ));
        }

        $this->dereferencing[$id] = 1;
        $newId = $this->dereference($this->definitions[$id]->getId());
        unset($this->dereferencing[$id]);

        return $newId;
    }