protected function decode_random_attempt($qstates, $maxmark)
 {
     $realquestionid = null;
     foreach ($qstates as $i => $state) {
         if (strpos($state->answer, '-') < 6) {
             // Broken state, skip it.
             $this->logger->log_assumption("Had to skip brokes state {$state->id}\n                        for question {$state->question}.");
             unset($qstates[$i]);
             continue;
         }
         list($randombit, $realanswer) = explode('-', $state->answer, 2);
         $newquestionid = substr($randombit, 6);
         if ($realquestionid && $realquestionid != $newquestionid) {
             throw new coding_exception("Question session {$this->qsession->id}\n                        for random question points to two different real questions\n                        {$realquestionid} and {$newquestionid}.");
         }
         $qstates[$i]->answer = $realanswer;
     }
     if (empty($newquestionid)) {
         // This attempt only had broken states. Set a fake $newquestionid to
         // prevent a null DB error later.
         $newquestionid = 0;
     }
     $newquestion = $this->load_question($newquestionid);
     $newquestion->maxmark = $maxmark;
     return array($newquestion, $qstates);
 }
 protected function process0($step, $state)
 {
     if ($this->startstate) {
         if ($state->answer == reset($this->qstates)->answer) {
             return;
         } else {
             if ($this->quiz->attemptonlast && $this->sequencenumber == 1) {
                 // There was a bug in attemptonlast in the past, which meant that
                 // it created two inconsistent open states, with the second taking
                 // priority. Simulate that be discarding the first open state, then
                 // continuing.
                 $this->logger->log_assumption("Ignoring bogus state in attempt at question {$state->question}");
                 $this->sequencenumber = 0;
                 $this->qa->steps = array();
             } else {
                 if ($state->answer == '') {
                     $this->logger->log_assumption("Ignoring second start state with blank answer in attempt at question {$state->question}");
                     return;
                 } else {
                     throw new coding_exception("Two inconsistent open states for question session {$this->qsession->id}.");
                 }
             }
         }
     }
     $step->state = 'todo';
     $this->startstate = $state;
     $this->add_step($step);
 }