/**
  * @param string $key
  * @param ArrayOf $model
  * @param array $data
  * @throws \Exception
  */
 public function decodeArrayOf($key, $model, $data)
 {
     if ($data == null) {
         $data = array();
     }
     CodeGuard::checkTypeAndThrow($data, 'array');
     $propertiesToKeep = array();
     // check if array item class has any private, read-only or recursive properties
     if (get_class($this) != 'Api\\Model\\Shared\\Mapper\\MongoDecoder' && $model->hasGenerator()) {
         $arrayItem = $model->generate();
         $propertiesToKeep = $this->getPrivateAndReadOnlyProperties($arrayItem);
         $propertiesToKeep = $this->getRecursiveProperties($arrayItem, $propertiesToKeep);
     }
     $oldModelArray = $model->exchangeArray(array());
     foreach ($data as $index => $item) {
         if ($model->hasGenerator()) {
             $object = $model->generate($item);
             // put back private, read-only and recursive properties into new object that was just generated
             foreach ($propertiesToKeep as $property) {
                 if (array_key_exists($index, $oldModelArray)) {
                     $object->{$property} = $oldModelArray[$index]->{$property};
                 }
             }
             $this->_decode($object, $item, '');
             $model[] = $object;
         } else {
             if (is_array($item)) {
                 throw new \Exception("Must not decode array for value type '{$key}'");
             }
             $model[] = $item;
         }
     }
 }