/**
  * Adds an attribute field.
  *
  * @param   AttributeMetadata   $attribute
  * @return  self
  * @throws  MetadataException   If the attribute key already exists as a relationship.
  */
 public function addAttribute(AttributeMetadata $attribute)
 {
     if (isset($this->relationships[$attribute->getKey()])) {
         throw MetadataException::fieldKeyInUse('attribute', 'relationship', $attribute->getKey(), $this->type);
     }
     $this->attributes[$attribute->getKey()] = $attribute;
     ksort($this->attributes);
     return $this;
 }
 /**
  * Sets the entity attribute metadata from the metadata mapping.
  *
  * @todo    Add support for complex attributes, like arrays and objects.
  * @param   Metadata\Interfaces\AttributeInterface  $metadata
  * @param   array                                   $attrMapping
  * @return  Metadata\EntityMetadata
  */
 protected function setAttributes(Metadata\Interfaces\AttributeInterface $metadata, array $attrMapping)
 {
     foreach ($attrMapping as $key => $mapping) {
         if (!is_array($mapping)) {
             $mapping = ['type' => null];
         }
         if (!isset($mapping['type'])) {
             $mapping['type'] = null;
         }
         if (!isset($mapping['search'])) {
             $mapping['search'] = [];
         }
         $attribute = new Metadata\AttributeMetadata($key, $mapping['type'], $this->isMixin($metadata));
         // @todo Handle complex attribute types.
         if (isset($mapping['description'])) {
             $attribute->description = $mapping['description'];
         }
         if (isset($mapping['defaultValue'])) {
             $attribute->defaultValue = $mapping['defaultValue'];
         }
         if (isset($mapping['calculated']) && is_array($mapping['calculated'])) {
             $calculated = $mapping['calculated'];
             if (isset($calculated['class']) && isset($calculated['method'])) {
                 $attribute->calculated['class'] = $calculated['class'];
                 $attribute->calculated['method'] = $calculated['method'];
             }
         }
         if (isset($mapping['search']['autocomplete'])) {
             $attribute->setAutocomplete(true);
         } else {
             if (isset($mapping['search']['store'])) {
                 $attribute->setSearchProperty(true);
             }
         }
         $metadata->addAttribute($attribute);
     }
     return $metadata;
 }