diff -uNr moodle.orig/lib/questionlib.php moodle/lib/questionlib.php
--- moodle.orig/lib/questionlib.php	2008-07-18 01:15:47.000000000 +0100
+++ moodle/lib/questionlib.php	2008-09-08 08:32:32.000000000 +0100
@@ -768,6 +768,10 @@
             $states[$i]->last_graded = clone($states[$i]);
         }
     }
+
+    // make sure sumgrades are non-negative
+    $attempt->sumgrades = max($attempt->sumgrades, 0.0);
+
     return $states;
 }
 
@@ -1280,7 +1284,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	2008-04-18 01:13:46.000000000 +0100
+++ moodle/mod/quiz/attempt.php	2008-09-08 08:32:32.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-06-20 01:16:41.000000000 +0100
+++ moodle/question/type/multianswer/questiontype.php	2008-09-08 08:32:32.000000000 +0100
@@ -482,7 +482,7 @@
         }
         }
         $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-09-08 08:32:32.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;
