/**
  * @param Model $model
  * @param Property $property
  * @return string
  */
 protected function getPropertyName(Model $model, Property $property)
 {
     return $model->getPrefix() . $property->getName();
 }
 private function getModel($id, $prefix = null, $depth = 0)
 {
     if (!isset($this->library[$id])) {
         throw new ModelNotDefined("Model " . $id . " was not found in swagger specifications.");
     }
     $data = $this->library[$id];
     $model = new Model($data['id']);
     $model->setPrefix($prefix);
     // Has reached depth? In that case, ignore teh properties.
     if ($this->hasReachedDepth($depth)) {
         return $model;
     }
     /** @var Property[] $properties */
     $properties = array();
     if (isset($data['properties'])) {
         foreach ($data['properties'] as $propName => $property) {
             if (!empty($property['$ref'])) {
                 $subModel = $this->getModel($property['$ref'], $model->getPrefix() . $property['$ref'] . '.', $depth + 1);
                 $properties[$propName] = new ModelProperty($subModel, $propName);
                 $model->addProperty($properties[$propName]);
             } else {
                 if (isset($property['$ref'])) {
                     // Do nothing.
                     throw new \InvalidArgumentException("Empty reference found.");
                 } else {
                     if (isset($property['type']) && strtolower($property['type']) == 'array') {
                         // Is array specified?
                         if (isset($property['items'])) {
                             if (isset($property['items']['$ref'])) {
                                 $subModel = $this->getModel($property['items']['$ref'], $model->getPrefix() . $property['items']['$ref'] . '[].', $depth + 1);
                                 $childProperty = new ModelProperty($subModel, $propName);
                             } else {
                                 if (isset($property['items']['type'])) {
                                     $childProperty = new Property($propName);
                                     $childProperty->addRequirement(new IsType($property['items']['type']));
                                 } else {
                                     throw new \InvalidArgumentException('Array without type or $ref found.');
                                 }
                             }
                             // Nope? Regular array.
                             $properties[$propName] = new ArrayProperty($propName, $childProperty);
                             $model->addProperty($properties[$propName]);
                             $properties[$propName]->addRequirement(new IsArray());
                         } else {
                             // Nope? Regular array.
                             $properties[$propName] = new Property($propName);
                             $model->addProperty($properties[$propName]);
                             $properties[$propName]->addRequirement(new IsArray());
                         }
                     } else {
                         $properties[$propName] = new Property($propName);
                         $model->addProperty($properties[$propName]);
                         if (isset($property['type'])) {
                             $properties[$propName]->addRequirement(new IsType($property['type']));
                         }
                     }
                 }
             }
         }
     }
     // Requirements
     if (isset($data['required'])) {
         foreach ($data['required'] as $v) {
             $properties[$v]->addRequirement(new Exists());
         }
     }
     return $model;
 }