/**
  * Initializes the object according to its class specification and given arguments.
  *
  * @param array $properties The values to give to the properties.
  */
 protected function initializeProperties($properties = null)
 {
     $this->getPropertiesInfo();
     // Initialize the properties that were defined using the Initialize / InitializeObject annotations
     $initializeValueValidationEnabled = Configuration::isInitializeValuesValidationEnabled();
     foreach ($this->_initialPropertiesValues as $propertyName => $initialization) {
         $value = null;
         switch ($initialization['type']) {
             case 'initialize':
                 $value = $initialization['value'];
                 break;
             default:
                 $className = $initialization['value'];
                 $value = new $className();
                 break;
         }
         if ($initializeValueValidationEnabled) {
             $this->assertPropertyValue($propertyName, $value);
         }
         $this->{$propertyName} = $value;
         $this->updateInitializedPropertyValue($propertyName, $value);
     }
     // Initialize the propeties using given arguments
     if ($this->_initializationNeededArguments !== null && $properties !== null) {
         $numberOfNeededArguments = count($this->_initializationNeededArguments);
         MethodCallManager::assertArgsNumber($numberOfNeededArguments, $properties);
         for ($i = 0; $i < $numberOfNeededArguments; $i++) {
             $propertyName = $this->_initializationNeededArguments[$i];
             $argument = $properties[$i];
             $this->assertPropertyValue($propertyName, $argument);
             $this->{$propertyName} = $argument;
             $this->updateInitializedPropertyValue($propertyName, $argument);
         }
     }
 }
 /**
  * This function will be called each time a getter or a setter that is not
  * already defined in the class is called.
  *
  * @param  string $name The name of the called function.
  *                      It must be a getter or a setter.
  * @param  array  $args The array of arguments for the called function.
  *                      It should be empty for a getter call,
  *                      and should have one item for a setter call.
  *
  * @return mixed    The value that should be returned by the function called if it is a getter,
  *                  the object itself if the function called is a setter.
  *
  * @throws \BadMethodCallException      When the method called is neither a getter nor a setter,
  *         						   		or if the access right has not be given for this method,
  *         						     	or if the method is a setter called without argument.
  * @throws \InvalidArgumentException    When the argument given to the method called (as a setter)
  *         								does not satisfy the constraints attached to the property
  *         								to modify.
  */
 public function __call($name, array $args)
 {
     $this->getPropertiesInfo();
     $methodCallInfo = $this->getMethodCallInfo($name);
     $method = $methodCallInfo['method'];
     $property = $methodCallInfo['property'];
     $collectionProperties = $methodCallInfo['collectionProperties'];
     $valuesToUpdate = array();
     switch ($method) {
         case 'get':
         case 'is':
         case 'call':
             MethodCallManager::assertArgsNumber(0, $args);
             return $this->{$property};
         case 'set':
             MethodCallManager::assertArgsNumber(1, $args);
             // we set a collection here if there is an association with it
             if (!empty($this->_collectionsItemNames['byProperty'][$property]) && !empty($this->_associationsList[$property])) {
                 $itemName = $this->_collectionsItemNames['byProperty'][$property]['itemName'];
                 $propertyAddMethod = 'add' . ucfirst($itemName);
                 $propertyRemoveMethod = 'remove' . ucfirst($itemName);
                 foreach ($this->{$property} as $item) {
                     $this->{$propertyRemoveMethod}($item);
                 }
                 foreach ($args[0] as $item) {
                     $this->{$propertyAddMethod}($item);
                 }
             } else {
                 $oldValue = $this->{$property};
                 $newValue = $args[0];
                 $valuesToUpdate = array('oldValue' => $oldValue, 'newValue' => $newValue);
                 // check that the setter argument respects the property constraints
                 $this->assertPropertyValue($property, $newValue);
                 $this->{$property} = $newValue;
             }
             break;
         case 'add':
         case 'remove':
             $valueToUpdate = $method === 'add' ? 'newValue' : 'oldValue';
             switch ($collectionProperties['behavior']) {
                 case 'list':
                     ListManager::$method($this->{$property}, $args);
                     $valuesToUpdate[$valueToUpdate] = $args[0];
                     break;
                 case 'map':
                     MapManager::$method($this->{$property}, $args);
                     break;
                 case 'set':
                     SetManager::$method($this->{$property}, $args);
                     $valuesToUpdate[$valueToUpdate] = $args[0];
                     break;
             }
             $this->assertPropertyValue($property, $this->{$property});
             break;
     }
     // manage associations
     if (in_array($method, array('set', 'add', 'remove'))) {
         $this->updatePropertyAssociation($property, $valuesToUpdate);
     }
     return $this;
 }