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;
    }
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;
    }
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 ; }
Follows references recursively to find the deepest ID.

@param string $id
@return string
@throws CircularReferenceException when circular reference gets detected
Follows references recursively to find the deepest ID .