diff -Naur moodle/grade/report/grader/lib.php moodle_sum/grade/report/grader/lib.php
--- moodle/grade/report/grader/lib.php	2008-10-13 20:20:43.000000000 -0400
+++ moodle_sum/grade/report/grader/lib.php	2008-11-19 14:38:14.000000000 -0500
@@ -865,7 +865,7 @@
                         $studentshtml .= '<span class="gradingerror'.$hidden.$gradepass.'">'.get_string('error').'</span>';
 
                     } else {
-                        $studentshtml .= '<span class="gradevalue'.$hidden.$gradepass.'">'.grade_format_gradevalue($gradeval, $item, true, $gradedisplaytype, null).'</span>';
+                        $studentshtml .= '<span class="gradevalue'.$hidden.$gradepass.'">'.grade_format_gradevalue($gradeval, $item, true, $gradedisplaytype, null, $grade).'</span>';
                     }
 
                     // Close feedback span
@@ -939,6 +939,7 @@
                      WHERE gi.courseid = $this->courseid
                            AND ra.roleid in ($this->gradebookroles)
                            AND ra.contextid ".get_related_contexts_string($this->context)."
+                           AND g.excluded = '0'
                            AND g.finalgrade IS NOT NULL
                            $groupwheresql
                   GROUP BY g.itemid";
@@ -972,7 +973,10 @@
                      WHERE gi.courseid = $this->courseid
                            AND ra.roleid in ($this->gradebookroles)
                            AND ra.contextid ".get_related_contexts_string($this->context)."
-                           AND g.id IS NULL
+                           AND (
+                                g.id IS NULL
+                                OR g.excluded != '0'
+                           )
                            $groupwheresql
                   GROUP BY gi.id";
 
diff -Naur moodle/grade/report/user/lib.php moodle_sum/grade/report/user/lib.php
--- moodle/grade/report/user/lib.php	2008-10-10 20:20:03.000000000 -0400
+++ moodle_sum/grade/report/user/lib.php	2008-11-19 14:40:57.000000000 -0500
@@ -245,25 +245,31 @@
                 $excluded = '';
             }
 
+            if ($grade_item->aggregationcoef > 0) {
+                $ec = 'Extra Credit: ';
+            } else {
+                $ec = '';
+            }
+
             if ($grade_item->needsupdate) {
                 $data[] = '<span class="'.$hidden.$class.' gradingerror">'.get_string('error').'</span>';
 
             } else if (!empty($CFG->grade_hiddenasdate) and $grade_grade->get_datesubmitted() and !$canviewhidden and $grade_grade->is_hidden()
                    and !$grade_item->is_category_item() and !$grade_item->is_course_item()) {
                 // the problem here is that we do not have the time when grade value was modified, 'timemodified' is general modification date for grade_grades records
-                $data[] = '<span class="'.$hidden.$class.' datesubmitted">'.$excluded.get_string('submittedon', 'grades', userdate($grade_grade->get_datesubmitted(), get_string('strftimedatetimeshort'))).'</span>';
+                $data[] = '<span class="'.$hidden.$class.' datesubmitted">'.$ec.$excluded.get_string('submittedon', 'grades', userdate($grade_grade->get_datesubmitted(), get_string('strftimedatetimeshort'))).'</span>';
 
             } else {
-                $data[] = '<span class="'.$hidden.$class.'">'.$excluded.grade_format_gradevalue($gradeval, $grade_item, true).'</span>';
+                $data[] = '<span class="'.$hidden.$class.$ec_class.'">'.$ec.$excluded.grade_format_gradevalue($gradeval, $grade_item, true, null, null, $grade_grade).'</span>';
             }
 
             /// prints percentage
             if ($this->showpercentage) {
                 if ($grade_item->needsupdate) {
-                    $data[] = '<span class="'.$hidden.$class.'gradingerror">'.get_string('error').'</span>';
+                    $data[] = '<span class="'.$hidden.$class.' gradingerror">'.$ec.get_string('error').'</span>';
 
                 } else {
-                    $data[] = '<span class="'.$hidden.$class.'">'.grade_format_gradevalue($gradeval, $grade_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE).'</span>';
+                    $data[] = '<span class="'.$hidden.$class.'">'.$ec.grade_format_gradevalue($gradeval, $grade_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE, null, $grade_grade).'</span>';
                 }
             }
 
diff -Naur moodle/lib/grade/grade_category.php moodle_sum/lib/grade/grade_category.php
--- moodle/lib/grade/grade_category.php	2008-03-12 22:15:18.000000000 -0400
+++ moodle_sum/lib/grade/grade_category.php	2008-11-19 15:09:41.000000000 -0500
@@ -686,21 +686,75 @@
      * @return boolean (just plain return;)
      */
     function sum_grades(&$grade, $oldfinalgrade, $items, $grade_values, $excluded) {
-        // ungraded and exluded items are not used in aggregation
-        foreach ($grade_values as $itemid=>$v) {
-            if (is_null($v)) {
-                unset($grade_values[$itemid]);
-            } else if (in_array($itemid, $excluded)) {
-                unset($grade_values[$itemid]);
-            }
-        }
+        // @todo There is a problem with empty categories
+        // being aggregated into the course total.
+        // the solution is to check if they have children or not.
+        // the code below doesn't work.
+
+        // if we encounter a category with no children, unset it.
+//        foreach ($items as $id=>$item) {
+//            //if ($item->itemtype == 'course' || $item->itemtype == 'category') {
+//            if (count($item->get_children()) < 1) {
+//                unset($items[$id]);
+//            }
+//        }
+
+        $grade_rank = array();
 
         // use 0 if grade missing, droplow used and aggregating all items
         if (!$this->aggregateonlygraded and !empty($this->droplow)) {
             foreach($items as $itemid=>$value) {
+                # Only set the item grade to zero if it is not set and we've
+                # been asked to drop lowest grades
                 if (!isset($grade_values[$itemid]) and !in_array($itemid, $excluded)) {
                     $grade_values[$itemid] = 0;
                 }
+                #$grade_rank[$itemid] = $grade_values[$itemid] / $value->grademax;
+                //Collect the absolute value of the grades as opposed to a
+                //normalized value above.
+                $grade_rank[$itemid] = $grade_values[$itemid];
+                debugging("itemid = " . $itemid . " = " . $grade_rank[$itemid]);
+            }
+        }
+
+        $negmax = 0;
+        if (!empty($this->droplow))
+        {
+            //sort the grade_rank from worst to best
+            asort($grade_rank);
+            $drop_cnt = $this->droplow;
+            foreach ($grade_rank as $itemid => $value)
+            {
+                //Drop the lowest $drop_cnt and also remove their maxvalue from
+                //the total number of points.  NOTE: this max value is possibly
+                //different for each user if the items in the category have
+                //different maxgrade values.  This breaks the "range" number in
+                //the grader report to be the max maximum value for all users of
+                //the item.
+                if ($drop_cnt < 1) { break; }
+                if ($items[$itemid]->gradetype == GRADE_TYPE_VALUE)
+                {
+                   $negmax += $items[$itemid]->grademax;
+                } else if ($items[$itemid]->gradetype == GRADE_TYPE_SCALE)
+                {
+                   $negmax += $items[$itemid]->grademax - 1; // scales min is 1
+                }
+                $grade_values[$itemid] = 0;
+                $drop_cnt--;
+            }
+        }
+
+        // go through and remove all assignments that have an aggr coef > 1
+        // or are exempted.
+        if (is_array($excluded) && count($excluded)>0) {
+            foreach ($excluded as $exclude_id) {
+                if ($items[$exclude_id]->gradetype == GRADE_TYPE_VALUE)
+                {
+                   $negmax += $items[$exclude_id]->grademax;
+                } else if ($items[$exclude_id]->gradetype == GRADE_TYPE_SCALE)
+                {
+                   $negmax += $items[$exclude_id]->grademax - 1; // scales min is 1
+                }
             }
         }
 
@@ -708,16 +762,34 @@
 
         //find max grade
         foreach ($items as $item) {
-            if ($item->aggregationcoef > 0) {
-                // extra credit from this activity - does not affect total
-                continue;
-            }
-            if ($item->gradetype == GRADE_TYPE_VALUE) {
-                $max += $item->grademax;
-            } else if ($item->gradetype == GRADE_TYPE_SCALE) {
-                $max += $item->grademax - 1; // scales min is 1
+            // special cases to deal with category totals.
+            if ($item->itemtype == 'category') {
+                $params = array(
+                    'userid' => $grade->userid,
+                    'itemid' => $item->id
+                );
+                $category_total = new grade_grade($params);
+                $max += $category_total->rawgrademax;
+                //print "Adding {$category_total->rawgrademax} instead of {$item->grademax}<br>\n";
+            } else {
+
+                if ($item->aggregationcoef > 0) {
+                    // extra credit from this activity - does not affect total
+                    continue;
+                }
+
+                if ($item->gradetype == GRADE_TYPE_VALUE) {
+                    $max += $item->grademax;
+                } else if ($item->gradetype == GRADE_TYPE_SCALE) {
+                    $max += $item->grademax - 1; // scales min is 1
+                }
             }
         }
+        // update the category "grade" for the student
+        // setting the rawgrademax to the correct value.
+        $grade_max = $max - $negmax;
+        $grade->rawgrademax = $grade_max;
+        $grade->update();
 
         if ($this->grade_item->grademax != $max or $this->grade_item->grademin != 0 or $this->grade_item->gradetype != GRADE_TYPE_VALUE){
             $this->grade_item->grademax = $max;
diff -Naur moodle/lib/gradelib.php moodle_sum/lib/gradelib.php
--- moodle/lib/gradelib.php	2008-05-13 20:17:46.000000000 -0400
+++ moodle_sum/lib/gradelib.php	2008-11-19 15:07:41.000000000 -0500
@@ -637,9 +637,23 @@
  * @param bool $localized use localised decimal separator
  * @param int $displaytype type of display - GRADE_DISPLAY_TYPE_REAL, GRADE_DISPLAY_TYPE_PERCENTAGE, GRADE_DISPLAY_TYPE_LETTER
  * @param int $decimalplaces number of decimal places when displaying float values
+ * @param object $grade - grade_grade object for current item.
  * @return string
  */
-function grade_format_gradevalue($value, &$grade_item, $localized=true, $displaytype=null, $decimals=null) {
+function grade_format_gradevalue($value, &$grade_item, $localized=true, $displaytype=null, $decimals=null, $grade=null) {
+    $min = $grade_item->grademin;
+    $max = $grade_item->grademax;
+
+    // fix for excluded assignments
+    // pull the max from the grade_grade item for the category
+    if ($grade_item->itemtype == 'category' || $grade_item->itemtype == 'course') {
+        if (is_object($grade)) {
+            $min = $grade->rawgrademin;
+            $max = $grade->rawgrademax;
+            $this_grade = $grade->finalgrade;
+        }
+     }
+
     if ($grade_item->gradetype == GRADE_TYPE_NONE or $grade_item->gradetype == GRADE_TYPE_TEXT) {
         return '';
     }
@@ -669,7 +683,7 @@
                     return get_string('error');
                 }
 
-                $value = (int)bounded_number($grade_item->grademin, $value, $grade_item->grademax);
+                $value = (int)bounded_number($min, $value, $max);
                 return format_string($scale->scale_items[$value-1]);
 
             } else {
@@ -684,7 +698,7 @@
             }
             $value = bounded_number($min, $value, $max);
             $percentage = (($value-$min)*100)/($max-$min);
-            return format_float($percentage, $decimals, $localized).' %';
+            return format_float($percentage, $decimals, $localized).' % ';
 
         case GRADE_DISPLAY_TYPE_LETTER:
             $context = get_context_instance(CONTEXT_COURSE, $grade_item->courseid);
@@ -692,7 +706,7 @@
                 return ''; // no letters??
             }
 
-            $value = grade_grade::standardise_score($value, $grade_item->grademin, $grade_item->grademax, 0, 100);
+            $value = grade_grade::standardise_score($value, $min, $max, 0, 100);
             $value = bounded_number(0, $value, 100); // just in case
             foreach ($letters as $boundary => $letter) {
                 if ($value >= $boundary) {
