/**
  * Extracts objects recursively from $row.
  *
  * Checks if $row contains new objects defined in $relations. If this is
  * the case, the objects will be extracted and added as related objects of
  * their class for the object of $parentClass with $parentId. If
  * sub-sequent relations exist for an extracted object, this method is
  * called recursively. If $restricted is set to true, named related object
  * sets will be created instead of normal related object sets.
  * 
  * @param array(string=>string) $row 
  * @param array(ezcPersistentRelationFindDefinition) $relations 
  * @param ezcPersistentObject $parent
  * @param bool $restricted
  */
 protected function extractObjectsRecursive(array $row, array $relations, $parent, $restricted = false)
 {
     foreach ($relations as $tableAlias => $relation) {
         $id = $row[$this->getColumnAlias($relation->definition->idProperty->propertyName, $tableAlias)];
         if ($id === null) {
             // Related object not present, check if a relation is recorded
             // in general, to potentially add an empty set
             if ($restricted) {
                 $relatedObjects = $this->idMap->getRelatedObjectSet($parent, $tableAlias);
                 if ($relatedObjects === null) {
                     $this->idMap->setRelatedObjectSet($parent, array(), $tableAlias);
                 }
             } else {
                 $relatedObjects = $this->idMap->getRelatedObjects($parent, $relation->relatedClass, $relation->relationName);
                 if ($relatedObjects === null) {
                     $this->idMap->setRelatedObjects($parent, array(), $relation->relatedClass, $relation->relationName);
                 }
             }
             // Skip further processing since this related object did not exist
             continue;
         }
         // Check if object was already extracted
         $object = $this->idMap->getIdentity($relation->relatedClass, $id);
         if ($this->options->refetch || $object === null) {
             $object = $this->createObject($row, $tableAlias, $relation);
             $this->idMap->setIdentity($object);
         }
         // Check if relations from $parentClass to $relation->relatedClass
         // were already recorded
         if ($restricted) {
             $relatedObjects = $this->idMap->getRelatedObjectSet($parent, $tableAlias);
         } else {
             $relatedObjects = $this->idMap->getRelatedObjects($parent, $relation->relatedClass, $relation->relationName);
         }
         if ($relatedObjects === null) {
             // No relation set recorded, create
             $relatedObjects = array();
         }
         // Check if relation itself is already recorded and only set the
         // identities if not
         if ($this->options->refetch || !isset($relatedObjects[$id])) {
             $relatedObjects[$id] = $object;
             // This performs the full setting process on every new object,
             // which is somewhat expensive but not really possible in a
             // different way, since adding new related objects invalidates
             // named related sets.
             if ($restricted) {
                 $this->idMap->setRelatedObjectSet($parent, $relatedObjects, $tableAlias);
             } else {
                 $this->idMap->setRelatedObjects($parent, $relatedObjects, $relation->relatedClass, $relation->relationName);
             }
         }
         // Recurse
         $this->extractObjectsRecursive($row, $relation->furtherRelations, $object, $restricted);
     }
 }
 /**
  * Returns the next persistent object in the result set.
  *
  * The next object is set to the current object of the iterator.
  * Returns null and sets the current object to null if there
  * are no more results in the result set.
  *
  * @return object
  */
 public function next()
 {
     $object = parent::next();
     if ($object !== null) {
         $identity = null;
         if (!$this->options->refetch) {
             $class = get_class($object);
             $state = $object->getState();
             $identity = $this->idMap->getIdentity($class, $state[$this->def->idProperty->propertyName]);
         }
         if ($identity !== null) {
             $this->object = $identity;
         } else {
             $this->idMap->setIdentity($object);
         }
     }
     return $this->object;
 }