/**
  * @param RedBeanModel $model
  * @param $relation
  * @param null $modelToForgetCache
  * @return bool true if the $model passed in needs to be saved again. Otherwise false if not.
  * @throws NotSupportedException
  * @throws FailedToSaveModelException
  */
 protected function resolveCreateModel(RedBeanModel $model, $relation, &$modelToForgetCache = null)
 {
     assert('is_string($relation)');
     $modelClassName = get_class($model);
     if ($model->isADerivedRelationViaCastedUpModel($relation) && $model->getDerivedRelationType($relation) == RedBeanModel::MANY_MANY) {
         $relationModelClassName = $model->getDerivedRelationModelClassName($relation);
         $inferredRelationName = $model->getDerivedRelationViaCastedUpModelOpposingRelationName($relation);
         $newModel = new $relationModelClassName();
         self::processActionAttributesForActionBeforeSave($this->action, $newModel, $this->triggeredByUser, $this->triggeredModel, true);
         $newModel->{$inferredRelationName}->add($model);
         $saved = $newModel->save();
         if (!$saved) {
             throw new FailedToSaveModelException();
         }
         self::processActionAttributesForActionAfterSave($this->action, $newModel, $this->triggeredByUser, $this->triggeredModel);
         return false;
     } elseif ($model->getInferredRelationModelClassNamesForRelation(ModelRelationsAndAttributesToWorkflowAdapter::resolveRealAttributeName($relation)) != null) {
         $relationModelClassName = ModelRelationsAndAttributesToWorkflowAdapter::getInferredRelationModelClassName($relation);
         $newModel = new $relationModelClassName();
         self::processActionAttributesForActionBeforeSave($this->action, $newModel, $this->triggeredByUser, $this->triggeredModel, true);
         $saved = $newModel->save();
         if (!$saved) {
             throw new FailedToSaveModelException();
         }
         self::processActionAttributesForActionAfterSave($this->action, $newModel, $this->triggeredByUser, $this->triggeredModel);
         $model->{ModelRelationsAndAttributesToWorkflowAdapter::resolveRealAttributeName($relation)}->add($newModel);
         return true;
     } elseif ($model->{$relation} instanceof RedBeanMutableRelatedModels) {
         $relationModelClassName = $model->getRelationModelClassName($relation);
         $newModel = new $relationModelClassName();
         self::processActionAttributesForActionBeforeSave($this->action, $newModel, $this->triggeredByUser, $this->triggeredModel, true);
         $this->resolveOneToManyPostCreateActionSaveModelCache($model, $relation, $newModel);
         $saved = $newModel->save();
         if (!$saved) {
             throw new FailedToSaveModelException();
         }
         self::processActionAttributesForActionAfterSave($this->action, $newModel, $this->triggeredByUser, $this->triggeredModel);
         $model->{$relation}->add($newModel);
         $modelToForgetCache = $newModel;
         return true;
     } elseif ($modelClassName::isRelationTypeAHasOneVariant($relation) && !$modelClassName::isOwnedRelation($relation)) {
         $relatedModel = $model->{$relation};
         if ($relatedModel->id > 0) {
             return;
         }
         self::processActionAttributesForActionBeforeSave($this->action, $relatedModel, $this->triggeredByUser, $this->triggeredModel, true);
         if (!$relatedModel->save()) {
             throw new FailedToSaveModelException();
         }
         self::processActionAttributesForActionAfterSave($this->action, $relatedModel, $this->triggeredByUser, $this->triggeredModel);
         return true;
     } else {
         throw new NotSupportedException();
     }
 }
 /**
  * @param string $relation
  * @param $model
  * @return array of models
  */
 public static function getInferredModelsByAtrributeAndModel($relation, $model)
 {
     assert('is_string($relation)');
     $realAttributeName = ModelRelationsAndAttributesToWorkflowAdapter::resolveRealAttributeName($relation);
     $relationModelClassName = ModelRelationsAndAttributesToWorkflowAdapter::getInferredRelationModelClassName($relation);
     $relatedModels = array();
     foreach ($model->{$realAttributeName} as $item) {
         try {
             $modelDerivationPathToItem = RuntimeUtil::getModelDerivationPathToItem($relationModelClassName);
             $relatedModels[] = $item->castDown(array($modelDerivationPathToItem));
         } catch (NotFoundException $e) {
         }
     }
     return $relatedModels;
 }
 /**
  * @return string
  * @throws NotSupportedException
  */
 protected function resolveModelClassName()
 {
     $modelClassName = $this->modelClassName;
     if ($this->relation == null) {
         return $modelClassName;
     }
     if ($modelClassName::isADerivedRelationViaCastedUpModel($this->relation) && $modelClassName::getDerivedRelationType($this->relation) == RedBeanModel::MANY_MANY) {
         return $modelClassName::getDerivedRelationModelClassName($this->relation);
     } elseif ($modelClassName::getInferredRelationModelClassNamesForRelation(ModelRelationsAndAttributesToWorkflowAdapter::resolveRealAttributeName($this->relation)) != null) {
         return ModelRelationsAndAttributesToWorkflowAdapter::getInferredRelationModelClassName($this->relation);
     } elseif ($modelClassName::isRelationTypeAHasManyVariant($this->relation) || $modelClassName::isRelationTypeAHasOneVariant($this->relation)) {
         return $modelClassName::getRelationModelClassName($this->relation);
     } else {
         throw new NotSupportedException();
     }
 }