diff -uNr moodle.orig/lib/questionlib.php moodle/lib/questionlib.php
--- moodle.orig/lib/questionlib.php	2007-09-20 03:35:55.000000000 +0100
+++ moodle/lib/questionlib.php	2008-05-06 13:17:43.000000000 +0100
@@ -743,6 +743,10 @@
             $states[$i]->last_graded = clone($states[$i]);
         }
     }
+
+    // make sure sumgrades are non-negative
+    $attempt->sumgrades = max($attempt->sumgrades, 0.0);
+
     return $states;
 }
 
@@ -1255,7 +1259,14 @@
     }
 
     // Ensure that the grade does not go down
-    $state->grade = max($state->grade, $state->last_graded->grade);
+    //
+    // This is specific to penalties/timelimit/closing time, so it should not run always!
+    if ($cmoptions->penaltyscheme or $cmoptions->timelimit or $cmoptions->timeclose) {
+       // The structures are initialized to zero, so on the first time it will reset any negative value to zero.
+       if ($state->last_graded->seq_number != 0) {
+          $state->grade = max($state->grade, $state->last_graded->grade);
+       }
+    }
 }
 
 /**
diff -uNr moodle.orig/mod/quiz/attempt.php moodle/mod/quiz/attempt.php
--- moodle.orig/mod/quiz/attempt.php	2007-10-31 02:40:11.000000000 +0000
+++ moodle/mod/quiz/attempt.php	2008-05-06 13:27:47.000000000 +0100
@@ -343,6 +343,9 @@
             save_question_session($questions[$i], $states[$i]);
         }
 
+        // make sure sumgrades are non-negative
+        $attempt->sumgrades = max($attempt->sumgrades, 0.0);
+
         $attempt->timemodified = $timestamp;
 
     // We have now finished processing form data
@@ -383,6 +386,9 @@
             save_question_session($question, $closestates[$key]);
         }
 
+        // make sure sumgrades are non-negative
+        $attempt->sumgrades = max($attempt->sumgrades, 0.0);
+
         add_to_log($course->id, 'quiz', 'close attempt',
                            "review.php?attempt=$attempt->id",
                            "$quiz->id", $cm->id);
diff -uNr moodle.orig/question/type/multianswer/questiontype.php moodle/question/type/multianswer/questiontype.php
--- moodle.orig/question/type/multianswer/questiontype.php	2008-02-20 02:14:58.000000000 +0000
+++ moodle/question/type/multianswer/questiontype.php	2008-05-06 13:33:05.000000000 +0100
@@ -406,7 +406,7 @@
             $state->raw_grade += $teststate->raw_grade;
         }
         $state->raw_grade /= $question->defaultgrade;
-        $state->raw_grade = min(max((float) $state->raw_grade, 0.0), 1.0)
+        $state->raw_grade = min(max((float) $state->raw_grade, -1.0), 1.0)
          * $question->maxgrade;
 
         if (empty($state->raw_grade)) {
diff -uNr moodle.orig/question/type/multichoice/questiontype.php moodle/question/type/multichoice/questiontype.php
--- moodle.orig/question/type/multichoice/questiontype.php	2008-01-09 02:15:43.000000000 +0000
+++ moodle/question/type/multichoice/questiontype.php	2008-05-06 13:37:40.000000000 +0100
@@ -368,7 +368,7 @@
 
         // Make sure we don't assign negative or too high marks
         $state->raw_grade = min(max((float) $state->raw_grade,
-                            0.0), 1.0) * $question->maxgrade;
+                           -1.0), 1.0) * $question->maxgrade;
 
         // Apply the penalty for this attempt
         $state->penalty = $question->penalty * $question->maxgrade;
