/**
  * <p>
  * Reads the value of a <tt>&lt;property></tt> element. If the property is
  * a reference property (e.g. <tt>&lt;property name="{name}" ref="{object-id}" /></tt>)
  * then the object instance of the referenced object will be returned as the
  * property's value. Otherwise the value of the property will be parsed and
  * returned.
  * </p>
  * <p>
  * A property may contain an object reference while not explicitly being
  * identified as a <i>reference property</i>. In this event, the evaluation
  * of the <tt>getValue()</tt> method will return the object instance.
  * </p>
  *
  * @param XmlElement $element
  * @return Property the property.
  */
 public function parseProperty(XmlElement $element)
 {
     // ** Assert that the $element is an instance of PHP's SimpleXMLElement...
     if (!$element instanceof \SimpleXMLElement) {
         throw new \InvalidArgumentException('Parse property expects a valid <property> XML element. Given: ' . gettype($element));
     }
     $metadata = PropertyMetadataParser::parseMetadata($element);
     // **
     // If this property is an object-reference property, e.g. it is in the
     // form: <property name="{name}" ref="{object-id}" /> then we should
     // try to reconcile the object reference and return that as the value
     // [SWQ]
     $ref = $metadata->getRef();
     if (!empty($ref)) {
         $value = $this->getReference($ref);
         $instance = $value->getInstance();
         if ($metadata->hasField()) {
             $field = $metadata->getField();
             $property = new Property($metadata, $field->resolve($instance));
             return $property;
         }
         $property = new Property($metadata, $value->getInstance());
         return $property;
     }
     $statement = $metadata->getQuery();
     if (!empty($statement)) {
         $type = $metadata->getType();
         if (empty($type)) {
             throw new \InvalidArgumentException('Error parsing query property: query properties require a type to be specified.');
         }
         $class = $metadata->getTypeAsClassName();
         $projection = $metadata->getProjection();
         $_query = new Query($class, $statement, $projection);
         $value = $this->query($query);
         $property = new Property($metadata, $value);
         return $property;
     }
     $value = $this->getValue($element, $metadata->getType());
     $property = new Property($metadata, $value);
     return $property;
 }
 /**
  *
  */
 public static function parseMetadata($xml)
 {
     $parser = new PropertyMetadataParser();
     return $parser->parse($xml);
 }