/**
  * Retrieve an AssessmentTestSession object from storage by $sessionId.
  *
  * @param \qtism\data\AssessmentTest $test
  * @param string $sessionId
  * @return \qtism\runtime\tests\AssessmentTestSession An AssessmentTestSession object.
  * @throws \qtism\runtime\storage\common\StorageException If the AssessmentTestSession could not be retrieved from storage.
  */
 public function retrieve(AssessmentTest $test, $sessionId)
 {
     try {
         $stream = $this->getRetrievalStream($sessionId);
         $stream->open();
         $access = $this->createBinaryStreamAccess($stream);
         // -- Deal with intrinsic values of the Test Session.
         $assessmentTestSessionState = $access->readTinyInt();
         $currentPosition = $access->readTinyInt();
         if ($access->readBoolean() === true) {
             $timeReference = $access->readDateTime();
         } else {
             $timeReference = null;
         }
         // Build the route and the item sessions.
         $route = new Route();
         $lastOccurenceUpdate = new SplObjectStorage();
         $itemSessionStore = new AssessmentItemSessionStore();
         $pendingResponseStore = new PendingResponseStore();
         $routeCount = $access->readTinyInt();
         // Create the item session factory that will be used to instantiate
         // new item sessions.
         for ($i = 0; $i < $routeCount; $i++) {
             $routeItem = $access->readRouteItem($this->getSeeker());
             $route->addRouteItemObject($routeItem);
             // An already instantiated session for this route item?
             if ($access->readBoolean() === true) {
                 $itemSession = $access->readAssessmentItemSession($this->getManager(), $this->getSeeker());
                 // last-update
                 if ($access->readBoolean() === true) {
                     $lastOccurenceUpdate[$routeItem->getAssessmentItemRef()] = $routeItem->getOccurence();
                 }
                 // pending-responses
                 if ($access->readBoolean() === true) {
                     $pendingResponseStore->addPendingResponses($access->readPendingResponses($this->getSeeker()));
                 }
                 $itemSessionStore->addAssessmentItemSession($itemSession, $routeItem->getOccurence());
             }
         }
         $route->setPosition($currentPosition);
         $manager = $this->getManager();
         $assessmentTestSession = $manager->createAssessmentTestSession($test, $route);
         $assessmentTestSession->setAssessmentItemSessionStore($itemSessionStore);
         $assessmentTestSession->setSessionId($sessionId);
         $assessmentTestSession->setState($assessmentTestSessionState);
         $assessmentTestSession->setLastOccurenceUpdate($lastOccurenceUpdate);
         $assessmentTestSession->setPendingResponseStore($pendingResponseStore);
         $assessmentTestSession->setTimeReference($timeReference);
         // Deal with test session configuration.
         // -- AutoForward (not in use anymore, consume it anyway).
         $access->readBoolean();
         // Build the test-level global scope, composed of Outcome Variables.
         foreach ($test->getOutcomeDeclarations() as $outcomeDeclaration) {
             $outcomeVariable = OutcomeVariable::createFromDataModel($outcomeDeclaration);
             $access->readVariableValue($outcomeVariable);
             $assessmentTestSession->setVariable($outcomeVariable);
         }
         // Build the duration store.
         $durationStore = new DurationStore();
         $durationCount = $access->readShort();
         for ($i = 0; $i < $durationCount; $i++) {
             $varName = $access->readString();
             $durationVariable = new OutcomeVariable($varName, Cardinality::SINGLE, BaseType::DURATION);
             $access->readVariableValue($durationVariable);
             $durationStore->setVariable($durationVariable);
         }
         $assessmentTestSession->setDurationStore($durationStore);
         $stream->close();
         return $assessmentTestSession;
     } catch (Exception $e) {
         $msg = "An error occured while retrieving AssessmentTestSession. " . $e->getMessage();
         throw new StorageException($msg, StorageException::RETRIEVAL, $e);
     }
 }
 public function testSetVariableWrongVariableType()
 {
     $durations = new DurationStore();
     $this->setExpectedException('\\InvalidArgumentException', 'The DurationStore only aims at storing OutcomeVariable objects, qtism\\runtime\\common\\ResponseVariable object given.');
     $durations->setVariable(new ResponseVariable('duration1', Cardinality::SINGLE, BaseType::DURATION, new Duration('PT0S')));
 }