/**
  * Returns the last node on a path. If the path does not exist 
  * in the the tree, creates the nodes if $create is set to true.
  * Path is given in an array.
  * @param array $path
  * @return false|epQueryPathNode
  * @throws epExceptionQueryPath
  */
 protected function &_obtainNodeByPath(&$path, $create = true)
 {
     // get the first non-empty piece in path
     while (!($piece = array_shift($path)) && $path) {
     }
     // this is the end if piece is empty
     if (!$piece) {
         return $this;
     }
     // check if piece is a child
     if ($child =& $this->getChild($piece)) {
         // if so, recursion on child
         return $child->_obtainNodeByPath($path, $create);
     }
     // check if we need to create path if it does not exist
     if (!$create) {
         return self::$false;
     }
     // get the class and field map for this node
     $fm = null;
     if ($this->isRoot()) {
         $cm = $this->getMap();
     } else {
         $fm = $this->getMap();
         $cm = $this->_em()->getClassMap($fm->getClass());
     }
     //
     // 1. if the node is a many-valued relationship, then create an contained root node
     //
     if ($fm && !$fm->isPrimitive() && $fm->isMany()) {
         // create a child - an alias root
         if (!($child =& new epQueryPathRoot($cm, $piece, epQueryPathRoot::CONTAINED))) {
             throw new epExceptionQueryPath("cannot create a node for '{$piece}'");
             return false;
         }
         // add child into this node
         $this->addChild($child);
         // recursion on child
         return $child->_obtainNodeByPath($path, $create);
     }
     //
     // 2. otherwise, create a field node
     //
     // get field map for the piece
     if ($piece == 'oid') {
         $fm = new epFieldMapPrimitive('oid', epFieldMap::DT_INTEGER, array(), $cm);
         $fm->setColumnName($cm->getOidColumn());
     } else {
         // get field map
         if (!($fm =& $cm->getField($piece))) {
             throw new epExceptionQueryPath("no field map for '{$piece}'");
             return self::$false;
         }
     }
     // create a child
     if (!($child =& new epQueryPathField($fm))) {
         throw new epExceptionQueryPath("cannot create a node for '{$piece}'");
         return self::$false;
     }
     // add it into parent
     $this->addChild($child);
     // recursion on child
     return $child->_obtainNodeByPath($path, $create);
 }
 /**
  * Actually processes a variable by consulting epManager
  * @param string $alias the starting alias for a variable
  * @param array $parts the array of attributes for the variable
  * @return false|array
  * @throws epExceptionQueryBuilder
  */
 protected function _processVariable($node, $alias, $parts)
 {
     // get class name for alias
     if (!($class = $this->aliases[$alias])) {
         throw new epExceptionQueryBuilder($this->_e('Class for alias [' . $alias . '] not found', $node));
         return false;
     }
     // get class map
     if (!($cm = $this->em->getMap($class))) {
         throw new epExceptionQueryBuilder($this->_e('Class [' . $class . '] not found', $node));
         return false;
     }
     // go through each var
     $fms = array();
     foreach ($parts as $part) {
         // make sure we have class map
         if (!$cm) {
             throw new epExceptionQueryBuilder($this->_e('Variable [' . $class . '::' . $part . '] not existing', $node));
             return false;
         }
         // fake a fieldmap if part is 'oid'
         if ($part == 'oid') {
             $fm = new epFieldMapPrimitive('oid', epFieldMap::DT_INTEGER, array(), $cm);
             $fm->setColumnName($cm->getOidColumn());
         } else {
             if (!($fm = $cm->getField($part))) {
                 throw new epExceptionQueryBuilder($this->_e('Variable [' . $class . '::' . $part . '] not existing', $node));
                 return false;
             }
         }
         // collect this field map
         $fms[] = $fm;
         // must be a relationship field map
         $cm = null;
         if ($fm instanceof epFieldMapRelationship) {
             $cm = $this->em->getClassMap($fm->getClass());
             $class = $cm->getName();
         }
     }
     return $fms;
 }