/**
  * Short description of method takeOverFrom
  *
  * @access public
  * @author Joel Bout, <*****@*****.**>
  * @param  ResponseProcessing responseProcessing
  * @param  Item item
  * @return oat\taoQtiItem\model\qti\response\ResponseProcessing
  */
 public static function takeOverFrom(ResponseProcessing $responseProcessing, Item $item)
 {
     $returnValue = null;
     if ($responseProcessing instanceof self) {
         return $responseProcessing;
     }
     if ($responseProcessing instanceof Template) {
         $returnValue = new TemplatesDriven();
         // theoretic only interaction 'RESPONSE' should be considered
         foreach ($item->getInteractions() as $interaction) {
             $returnValue->setTemplate($interaction->getResponse(), $responseProcessing->getUri());
         }
         $returnValue->setRelatedItem($item);
     } else {
         throw new TakeoverFailedException();
     }
     return $returnValue;
 }
 /**
  * Short description of method buildTemplatedrivenResponse
  *
  * @access public
  * @author Joel Bout, <*****@*****.**>
  * @param  DOMElement data
  * @param  array interactions
  * @return oat\taoQtiItem\model\qti\response\ResponseProcessing
  */
 protected function buildTemplatedrivenResponse(DOMElement $data, $interactions)
 {
     $patternCorrectTAO = '/responseCondition [count(./*) = 1 ] [name(./*[1]) = "responseIf" ] [count(./responseIf/*) = 2 ] [name(./responseIf/*[1]) = "match" ] [name(./responseIf/match/*[1]) = "variable" ] [name(./responseIf/match/*[2]) = "correct" ] [name(./responseIf/*[2]) = "setOutcomeValue" ] [name(./responseIf/setOutcomeValue/*[1]) = "sum" ] [name(./responseIf/setOutcomeValue/sum/*[1]) = "variable" ] [name(./responseIf/setOutcomeValue/sum/*[2]) = "baseValue"]';
     $patternMappingTAO = '/responseCondition [count(./*) = 1] [name(./*[1]) = "responseIf"] [count(./responseIf/*) = 2] [name(./responseIf/*[1]) = "not"] [name(./responseIf/not/*[1]) = "isNull"] [name(./responseIf/not/isNull/*[1]) = "variable"] [name(./responseIf/*[2]) = "setOutcomeValue"] [name(./responseIf/setOutcomeValue/*[1]) = "sum"] [name(./responseIf/setOutcomeValue/sum/*[1]) = "variable"] [name(./responseIf/setOutcomeValue/sum/*[2]) = "mapResponse"]';
     $patternMappingPointTAO = '/responseCondition [count(./*) = 1] [name(./*[1]) = "responseIf"] [count(./responseIf/*) = 2] [name(./responseIf/*[1]) = "not"] [name(./responseIf/not/*[1]) = "isNull"] [name(./responseIf/not/isNull/*[1]) = "variable"] [name(./responseIf/*[2]) = "setOutcomeValue"] [name(./responseIf/setOutcomeValue/*[1]) = "sum"] [name(./responseIf/setOutcomeValue/sum/*[1]) = "variable"] [name(./responseIf/setOutcomeValue/sum/*[2]) = "mapResponsePoint"]';
     $subPatternFeedbackOperatorIf = '[name(./*[1]) = "responseIf" ] [count(./responseIf/*) = 2 ] [contains(name(./responseIf/*[1]/*[1]), "map")] [name(./responseIf/*[1]/*[2]) = "baseValue" ] [name(./responseIf/*[2]) = "setOutcomeValue" ] [name(./responseIf/setOutcomeValue/*[1]) = "baseValue" ]';
     $subPatternFeedbackElse = '[name(./*[2]) = "responseElse"] [count(./responseElse/*) = 1 ] [name(./responseElse/*[1]) = "setOutcomeValue"] [name(./responseElse/setOutcomeValue/*[1]) = "baseValue"]';
     $subPatternFeedbackCorrect = '[name(./*[1]) = "responseIf" ] [count(./responseIf/*) = 2 ] [name(./responseIf/*[1]) = "match" ] [name(./responseIf/*[1]/*[1]) = "variable" ] [name(./responseIf/*[1]/*[2]) = "correct" ] [name(./responseIf/*[2]) = "setOutcomeValue" ] [name(./responseIf/setOutcomeValue/*[1]) = "baseValue" ]';
     $subPatternFeedbackIncorrect = '[name(./*[1]) = "responseIf" ] [count(./responseIf/*) = 2 ] [name(./responseIf/*[1]) = "not" ] [count(./responseIf/not) = 1 ] [name(./responseIf/not/*[1]) = "match" ] [name(./responseIf/not/*[1]/*[1]) = "variable" ] [name(./responseIf/not/*[1]/*[2]) = "correct" ] [name(./responseIf/*[2]) = "setOutcomeValue" ] [name(./responseIf/setOutcomeValue/*[1]) = "baseValue" ]';
     $patternFeedbackOperator = '/responseCondition [count(./*) = 1 ]' . $subPatternFeedbackOperatorIf;
     $patternFeedbackOperatorWithElse = '/responseCondition [count(./*) = 2 ]' . $subPatternFeedbackOperatorIf . $subPatternFeedbackElse;
     $patternFeedbackCorrect = '/responseCondition [count(./*) = 1 ]' . $subPatternFeedbackCorrect;
     $patternFeedbackCorrectWithElse = '/responseCondition [count(./*) = 2 ]' . $subPatternFeedbackCorrect . $subPatternFeedbackElse;
     $patternFeedbackIncorrect = '/responseCondition [count(./*) = 1 ]' . $subPatternFeedbackIncorrect;
     $patternFeedbackIncorrectWithElse = '/responseCondition [count(./*) = 2 ]' . $subPatternFeedbackIncorrect . $subPatternFeedbackElse;
     $rules = array();
     $simpleFeedbackRules = array();
     $data = simplexml_import_dom($data);
     foreach ($data as $responseRule) {
         $subtree = new SimpleXMLElement($responseRule->asXML());
         if (count($subtree->xpath($patternCorrectTAO)) > 0) {
             $responseIdentifier = (string) $subtree->responseIf->match->variable['identifier'];
             $rules[$responseIdentifier] = Template::MATCH_CORRECT;
         } elseif (count($subtree->xpath($patternMappingTAO)) > 0) {
             $responseIdentifier = (string) $subtree->responseIf->not->isNull->variable['identifier'];
             $rules[$responseIdentifier] = Template::MAP_RESPONSE;
         } elseif (count($subtree->xpath($patternMappingPointTAO)) > 0) {
             $responseIdentifier = (string) $subtree->responseIf->not->isNull->variable['identifier'];
             $rules[$responseIdentifier] = Template::MAP_RESPONSE_POINT;
         } elseif (count($subtree->xpath($patternFeedbackCorrect)) > 0 || count($subtree->xpath($patternFeedbackCorrectWithElse)) > 0) {
             $responseIdentifier = (string) $subtree->responseIf->match->variable['identifier'];
             $feedbackOutcomeIdentifier = (string) $subtree->responseIf->setOutcomeValue['identifier'];
             $feedbackIdentifier = (string) $subtree->responseIf->setOutcomeValue->baseValue;
             try {
                 $response = $this->getResponse($responseIdentifier);
                 $outcome = $this->getOutcome($feedbackOutcomeIdentifier);
                 $feedbackThen = $this->getModalFeedback($feedbackIdentifier);
                 $feedbackElse = null;
                 if ($subtree->responseElse->getName()) {
                     $feedbackElseIdentifier = (string) $subtree->responseElse->setOutcomeValue->baseValue;
                     $feedbackElse = $this->getModalFeedback($feedbackElseIdentifier);
                 }
                 $feedbackRule = new SimpleFeedbackRule($outcome, $feedbackThen, $feedbackElse);
                 $feedbackRule->setCondition($response, 'correct');
                 if (!isset($simpleFeedbackRules[$responseIdentifier])) {
                     $simpleFeedbackRules[$responseIdentifier] = array();
                 }
                 $simpleFeedbackRules[$responseIdentifier][] = $feedbackRule;
             } catch (ParsingException $e) {
                 throw new UnexpectedResponseProcessing('Feedback resources not found. Not template driven, unknown rule');
             }
         } elseif (count($subtree->xpath($patternFeedbackIncorrect)) > 0 || count($subtree->xpath($patternFeedbackIncorrectWithElse)) > 0) {
             $responseIdentifier = (string) $subtree->responseIf->not->match->variable['identifier'];
             $feedbackOutcomeIdentifier = (string) $subtree->responseIf->setOutcomeValue['identifier'];
             $feedbackIdentifier = (string) $subtree->responseIf->setOutcomeValue->baseValue;
             try {
                 $response = $this->getResponse($responseIdentifier);
                 $outcome = $this->getOutcome($feedbackOutcomeIdentifier);
                 $feedbackThen = $this->getModalFeedback($feedbackIdentifier);
                 $feedbackElse = null;
                 if ($subtree->responseElse->getName()) {
                     $feedbackElseIdentifier = (string) $subtree->responseElse->setOutcomeValue->baseValue;
                     $feedbackElse = $this->getModalFeedback($feedbackElseIdentifier);
                 }
                 $feedbackRule = new SimpleFeedbackRule($outcome, $feedbackThen, $feedbackElse);
                 $feedbackRule->setCondition($response, 'incorrect');
                 if (!isset($simpleFeedbackRules[$responseIdentifier])) {
                     $simpleFeedbackRules[$responseIdentifier] = array();
                 }
                 $simpleFeedbackRules[$responseIdentifier][] = $feedbackRule;
             } catch (ParsingException $e) {
                 throw new UnexpectedResponseProcessing('Feedback resources not found. Not template driven, unknown rule');
             }
         } elseif (count($subtree->xpath($patternFeedbackOperator)) > 0 || count($subtree->xpath($patternFeedbackOperatorWithElse)) > 0) {
             $operator = '';
             $responseIdentifier = '';
             $value = '';
             foreach ($subtree->responseIf->children() as $child) {
                 $operator = $child->getName();
                 $map = null;
                 foreach ($child->children() as $granChild) {
                     $map = $granChild->getName();
                     $responseIdentifier = (string) $granChild['identifier'];
                     break;
                 }
                 $value = (string) $child->baseValue;
                 break;
             }
             $feedbackOutcomeIdentifier = (string) $subtree->responseIf->setOutcomeValue['identifier'];
             $feedbackIdentifier = (string) $subtree->responseIf->setOutcomeValue->baseValue;
             try {
                 $response = $this->getResponse($responseIdentifier);
                 $outcome = $this->getOutcome($feedbackOutcomeIdentifier);
                 $feedbackThen = $this->getModalFeedback($feedbackIdentifier);
                 $feedbackElse = null;
                 if ($subtree->responseElse->getName()) {
                     $feedbackElseIdentifier = (string) $subtree->responseElse->setOutcomeValue->baseValue;
                     $feedbackElse = $this->getModalFeedback($feedbackElseIdentifier);
                 }
                 $feedbackRule = new SimpleFeedbackRule($outcome, $feedbackThen, $feedbackElse);
                 $feedbackRule->setCondition($response, $operator, $value);
                 if (!isset($simpleFeedbackRules[$responseIdentifier])) {
                     $simpleFeedbackRules[$responseIdentifier] = array();
                 }
                 $simpleFeedbackRules[$responseIdentifier][] = $feedbackRule;
             } catch (ParsingException $e) {
                 throw new UnexpectedResponseProcessing('Feedback resources not found. Not template driven, unknown rule');
             }
         } else {
             throw new UnexpectedResponseProcessing('Not template driven, unknown rule');
         }
         //add simple feedback rules parsing here
     }
     $responseIdentifiers = array();
     foreach ($interactions as $interaction) {
         $interactionResponse = $interaction->getResponse();
         $responseIdentifier = $interactionResponse->getIdentifier();
         $responseIdentifiers[] = $responseIdentifier;
         //create and set simple feedback rule here
         if (isset($simpleFeedbackRules[$responseIdentifier])) {
             foreach ($simpleFeedbackRules[$responseIdentifier] as $rule) {
                 $interactionResponse->addFeedbackRule($rule);
             }
         }
     }
     if (count(array_diff($responseIdentifiers, array_keys($rules))) > 0 || count(array_diff(array_keys($rules), $responseIdentifiers)) > 0) {
         throw new UnexpectedResponseProcessing('Not template driven, responseIdentifiers are ' . implode(',', $responseIdentifiers) . ' while rules are ' . implode(',', array_keys($rules)));
     }
     $templatesDrivenRP = new TemplatesDriven();
     foreach ($interactions as $interaction) {
         $pattern = $rules[$interaction->getResponse()->getIdentifier()];
         $templatesDrivenRP->setTemplate($interaction->getResponse(), $pattern);
     }
     $templatesDrivenRP->setRelatedItem($this->item);
     $returnValue = $templatesDrivenRP;
     return $returnValue;
 }