/**
  * Process the OutcomeCondition/ResponseCondition according to the current state.
  *
  * @throws \qtism\runtime\rules\RuleProcessingException
  */
 public function process()
 {
     $state = $this->getState();
     $this->pushTrail($this->getRule());
     $className = ucfirst($this->getQtiNature());
     $nsClass = 'qtism\\data\\rules\\' . $className . 'Condition';
     $ruleGetter = "get{$className}Rules";
     $statementGetter = "get{$className}";
     // + 'If'|'ElseIf'|'Else'
     while (count($this->getTrail()) > 0) {
         $rule = $this->popTrail();
         if (get_class($rule) === $nsClass) {
             // Let's try for if.
             $ifStatement = call_user_func(array($rule, $statementGetter . 'If'));
             $ifExpression = $ifStatement->getExpression();
             $exprEngine = new ExpressionEngine($ifExpression, $state);
             $value = $exprEngine->process();
             if ($value !== null && $value->getValue() === true) {
                 // Follow the if.
                 $this->pushTrail(call_user_func(array($ifStatement, $ruleGetter)));
             } else {
                 // Let's try for else ifs.
                 $followElseIf = false;
                 $elseIfStatements = call_user_func(array($rule, $statementGetter . 'ElseIfs'));
                 foreach ($elseIfStatements as $elseIfStatement) {
                     $elseIfExpression = $elseIfStatement->getExpression();
                     $exprEngine->setComponent($elseIfExpression);
                     $value = $exprEngine->process();
                     if ($value !== null && $value->getValue() === true) {
                         // Follow the current else if.
                         $this->pushTrail(call_user_func(array($elseIfStatement, $ruleGetter)));
                         $followElseIf = true;
                         break;
                     }
                 }
                 $elseStatement = call_user_func(array($rule, $statementGetter . 'Else'));
                 if ($followElseIf === false && is_null($elseStatement) === false) {
                     // No else if followed, the last resort is the else.
                     $this->pushTrail(call_user_func(array($elseStatement, $ruleGetter)));
                 }
             }
         } else {
             // $rule is another Rule than OutcomeCondition/ResponseCondition.
             $processor = $this->getRuleProcessorFactory()->createProcessor($rule);
             $processor->setState($state);
             $processor->process();
         }
     }
 }