/**
  * Make a new child for this object with the given key.  The
  * $nosave flag should only be set when populating a parent
  * node from storage.
  *
  * @param scalar $key.  If a boolean and true, we add to the
  * end of the array.  Otherwise we use the given key as a key.
  *
  * @param boolean $save Set to true to not save the parent
  * after creating this child.
  *
  * @returns I2CE_MagicDataNode The child that was created or
  * null on failure
  */
 protected function newChild($key, $save = TRUE)
 {
     if ($this->type == self::TYPE_NOT_POPULATED) {
         if (!$this->populate()) {
             I2CE::raiseError("Could not populate at " . $this->getPath(FALSE));
             return NULL;
         }
     }
     if ($this->type > 0) {
         self::raiseError("Trying to add a child, {$key}, to a scalar " . "value node at " . $this->getPath());
         return NULL;
     }
     // pushing on to the end.
     if (is_bool($key) && $key) {
         $this->children[] = NULL;
         end($this->children);
         $key = key($this->children);
         unset($this->children[$key]);
     } else {
         if (array_key_exists($key, $this->children)) {
             return $this->children[$key];
         }
     }
     $this->type = self::TYPE_PARENT;
     $child = new I2CE_MagicDataNode($key, $this);
     $this->children[$key] = $child;
     if ($this->volatile) {
         // set the child to have the same volatility as the parent
         $child->volatile(true);
     }
     if ($save) {
         if (!$this->save()) {
             self::raiseError("Could not save new child {$key} at " . $this->getPath());
         }
     }
     return $this->children[$key];
 }
 /**
  * Retrieve the given magic data node (which should be a
  * descendent of this instance.)
  *
  * @param I2CE_MagicDataNode $node
  * @return array
  */
 public function retrieve($node)
 {
     $node_data = array();
     $i_start = 0;
     if ($node->volatile()) {
         //if the node is volatile we want to retrieve if from the
         //last storage mechanism added as
         //it is considered the most secure
         $i_start = $this->num_storage - 1;
     }
     for ($i = $i_start; $i < $this->num_storage; $i++) {
         $node_data = $this->storage[$i]->retrieve($node);
         if (is_array($node_data) && count($node_data) > 0) {
             if (!(array_key_exists('type', $node_data) && array_key_exists('value', $node_data) && array_key_exists('children', $node_data))) {
                 I2CE_MagicDataNode::raiseError($node->getPath() . ": got invalid data " . print_r($node_data, true) . " from " . get_class($this->storage[$i]), E_ERROR);
                 $node_data = array();
             } else {
                 if ($node_data['type'] == I2CE_MagicDataNode::TYPE_NOT_POPULATED) {
                     I2CE_MagicDataNode::raiseError("Retreived unpopulated type at " . $node->getPath() . " from " . get_class($this->storage[$i]));
                     $node_data = array();
                 } else {
                     break;
                 }
             }
         }
     }
     return array("storage_idx" => $i, "data" => $node_data);
 }