diff -uNr moodle.orig/lib/questionlib.php moodle/lib/questionlib.php
--- moodle.orig/lib/questionlib.php	2007-03-19 17:01:39.000000000 +0000
+++ moodle/lib/questionlib.php	2007-03-19 17:07:57.000000000 +0000
@@ -562,7 +562,7 @@
 * @param object $attempt  The attempt for which the question sessions are
 *                         to be restored or created.
 */
-function get_question_states(&$questions, $cmoptions, $attempt) {
+function get_question_states(&$questions, $cmoptions, $attempt, $lastattemptid=null) {
     global $CFG, $QTYPES;
 
     // get the question ids
@@ -601,8 +601,33 @@
                 $states[$i]->last_graded = clone($states[$i]);
             }
         } else {
-            // create a new empty state
-            $states[$i] = new object;
+            // If the new attempt is to be based on a previous attempt get it and clean things
+            // Having lastattemptid filled implies that (should we double check?):
+            //    $attempt->attempt > 1 and $cmoptions->attemptonlast and !$attempt->preview
+            if ($lastattemptid) {
+                // find the responses from the previous attempt and save them to the new session
+
+                // Load the last graded state for the question
+                $statefields = 'n.questionid as question, s.*, n.sumpenalty';
+                $sql = "SELECT $statefields".
+                       "  FROM {$CFG->prefix}question_states s,".
+                       "       {$CFG->prefix}question_sessions n".
+                       " WHERE s.id = n.newgraded".
+                       "   AND n.attemptid = '$lastattemptid'".
+                       "   AND n.questionid = '$i'";
+                if (!$laststate = get_record_sql($sql)) {
+                    // Only restore previous responses that have been graded
+                    continue;
+                }
+                // Restore the state so that the responses will be restored
+                restore_question_state($questions[$i], $laststate);
+                $states[$i] = clone ($laststate);
+            } else {
+               // create a new empty state
+               $states[$i] = new object;
+            }
+
+            // now fill/overide initial values
             $states[$i]->attempt = $attempt->uniqueid;
             $states[$i]->question = (int) $i;
             $states[$i]->seq_number = 0;
@@ -613,15 +638,36 @@
             $states[$i]->penalty = 0;
             $states[$i]->sumpenalty = 0;
             $states[$i]->comment = '';
-            $states[$i]->responses = array('' => '');
+
+            // if building on last attempt we want to preserve responses  
+            if (!$lastattemptid) {
+              $states[$i]->responses = array('' => '');
+            }
             // Prevent further changes to the session from incrementing the
             // sequence number
             $states[$i]->changed = true;
 
-            // Create the empty question type specific information
-            if (!$QTYPES[$questions[$i]->qtype]
-             ->create_session_and_responses($questions[$i], $states[$i], $cmoptions, $attempt)) {
-                return false;
+            if ($lastattemptid) {
+                // prepare the previous responses for new processing
+                $action = new stdClass;
+                $action->responses = $laststate->responses;
+                $action->timestamp = $laststate->timestamp;
+                $action->event = QUESTION_EVENTSAVE; //emulate save of questions from all pages MDL-7631
+
+                // Process these responses ...
+                question_process_responses($questions[$i], $states[$i], $action, $cmoptions, $attempt);
+
+                // Fix for Bug #5506: When each attempt is built on the last one,
+                // preserve the options from any previous attempt. 
+                if ( isset($laststate->options) ) {
+                    $states[$i]->options = $laststate->options;
+                }
+            } else {
+                // Create the empty question type specific information
+                if (!$QTYPES[$questions[$i]->qtype]
+                ->create_session_and_responses($questions[$i], $states[$i], $cmoptions, $attempt)) {
+                    return false;
+                }
             }
             $states[$i]->last_graded = clone($states[$i]);
         }
diff -uNr moodle.orig/mod/quiz/attempt.php moodle/mod/quiz/attempt.php
--- moodle.orig/mod/quiz/attempt.php	2007-03-19 17:31:43.000000000 +0000
+++ moodle/mod/quiz/attempt.php	2007-03-19 17:02:34.000000000 +0000
@@ -280,9 +280,17 @@
         error('Could not load question options');
     }
 
+    // If the new attempt is to be based on a previous attempt find its id 
+    if ($newattempt and $attempt->attempt > 1 and $quiz->attemptonlast and !$attempt->preview) {
+        // Find the previous attempt
+        if (!$lastattemptid = get_field('quiz_attempts', 'uniqueid', 'quiz', $attempt->quiz, 'userid', $attempt->userid, 'attempt', $attempt->attempt-1)) {
+            error('Could not find previous attempt to build on');
+        }
+    }
+
     // Restore the question sessions to their most recent states
     // creating new sessions where required
-    if (!$states = get_question_states($questions, $quiz, $attempt)) {
+    if (!$states = get_question_states($questions, $quiz, $attempt, $lastattemptid)) {
         error('Could not restore question sessions');
     }
 
@@ -293,49 +301,6 @@
         }
     }
 
-    // If the new attempt is to be based on a previous attempt copy responses over
-    if ($newattempt and $attempt->attempt > 1 and $quiz->attemptonlast and !$attempt->preview) {
-        // Find the previous attempt
-        if (!$lastattemptid = get_field('quiz_attempts', 'uniqueid', 'quiz', $attempt->quiz, 'userid', $attempt->userid, 'attempt', $attempt->attempt-1)) {
-            error('Could not find previous attempt to build on');
-        }
-        // For each question find the responses from the previous attempt and save them to the new session
-        foreach ($questions as $i => $question) {
-            // Load the last graded state for the question
-            $statefields = 'n.questionid as question, s.*, n.sumpenalty';
-            $sql = "SELECT $statefields".
-                   "  FROM {$CFG->prefix}question_states s,".
-                   "       {$CFG->prefix}question_sessions n".
-                   " WHERE s.id = n.newgraded".
-                   "   AND n.attemptid = '$lastattemptid'".
-                   "   AND n.questionid = '$i'";
-            if (!$laststate = get_record_sql($sql)) {
-                // Only restore previous responses that have been graded
-                continue;
-            }
-            // Restore the state so that the responses will be restored
-            restore_question_state($questions[$i], $laststate);
-            // prepare the previous responses for new processing
-            $action = new stdClass;
-            $action->responses = $laststate->responses;
-            $action->timestamp = $laststate->timestamp;
-            $action->event = QUESTION_EVENTSAVE; //emulate save of questions from all pages MDL-7631
-
-            // Process these responses ...
-            question_process_responses($questions[$i], $states[$i], $action, $quiz, $attempt);
-
-            // Fix for Bug #5506: When each attempt is built on the last one,
-            // preserve the options from any previous attempt. 
-            if ( isset($laststate->options) ) {
-                $states[$i]->options = $laststate->options;
-            }
-
-            // ... and save the new states
-            save_question_session($questions[$i], $states[$i]);
-        }
-    }
-
-
 /// Process form data /////////////////////////////////////////////////
 
     if ($responses = data_submitted() and empty($_POST['quizpassword'])) {
