--- includes/update.inc	Sun Oct 11 11:34:10 2009 -0700
+++ includes/update.inc	Sun Oct 11 14:10:37 2009 -0700
@@ -22,10 +22,10 @@
     }
   }
   if (!empty($incompatible)) {
-  	db_update('system')
-  	  ->fields(array('status' => 0))
-  	  ->condition('name', $incompatible, 'IN')
-  	  ->execute();
+    db_update('system')
+      ->fields(array('status' => 0))
+      ->condition('name', $incompatible, 'IN')
+      ->execute();
   }
 }
 
@@ -350,7 +350,107 @@
 class DrupalUpdateException extends Exception { }
 
 /**
+ * Calculate an ordered update scheme
+ * 
+ * We build the graph of requested schema version start points
+ * to the final available versions.
+ * 
+ * In the process we add @required and @blocked schema versions of other modules
+ * to the graph.
+ * 
+ * In the end we sort this to a Topological Sorted List of which we remove all
+ * but the modules named in $start.
+ * 
+ * TODO: validate the update process before calling this update_batch.
+ * What we have done so far is adding the doxygen dependants to the graph for 
+ * ordening purpose only. They are removed from the actual list because there
+ * were not requested through the update.php form.
+ * 
+ * @param $start
+ * @return Sorted Topological Sorted List of module/schema versions
+ */
+function _update_calculate_graph($start) {
+  // Build the graph of the updates.
+  $updates_graph = array();
+
+  // Set the installed version so updates start at the correct place.
+  foreach ($start as $module => $version) {
+    //TODO: why set schema -1 ?
+    drupal_set_installed_schema_version($module, $version - 1);
+    $updates = drupal_get_schema_versions($module);
+    //TODO: why test for maximum version?
+    $max_version = max($updates);
+    if ($version > $max_version) {
+      continue;
+    }
+
+    while ($update = array_shift($updates)) {
+      // We cannot choose a version anymore on update.php right?
+      if ($update < $version) {
+        continue;
+      }
+
+      $updates_graph[$module . '_update_' . $update]['module'] = $module;
+      $updates_graph[$module . '_update_' . $update]['update'] = $update;
+
+      // Update N+1 depends on update N of the same module.
+      if ($next_update = reset($updates)) {
+        $updates_graph[$module . '_update_' . $update]['edges'][$module . '_update_' . $next_update] = TRUE;
+      }
+
+      // Fetch dependencies from the update Doxygen.
+      $func = new ReflectionFunction($module . '_update_' . $update);
+      $func_doxygen = $func->getDocComment();
+
+      // @after : forward dependency.
+      if (preg_match_all('/^\s*\*\s+@after\s+(.*)$/m', $func_doxygen, $matches)) {
+        foreach ($matches[1] as $function) {
+          $updates_graph[$function]['edges'][$module . '_update_' . $update] = TRUE;
+          // Add $function as participant to the graph
+          // TODO : sloppy code
+          $split=split('_update_', $function);
+          $updates_graph[$function]['module'] = $split[0];
+          $updates_graph[$function]['update'] = $split[1];
+        }
+      }
+
+      // @before : reverse dependency
+      if (preg_match_all('/^\s*\*\s+@before\s+(.*)$/m', $func_doxygen, $matches)) {
+        foreach ($matches[1] as $function) {
+          $updates_graph[$module . '_update_' . $update]['edges'][$function] = TRUE;
+          // Add $function as participant to the graph
+          // TODO : sloppy code
+          $split=split('_update_', $function);
+          $updates_graph[$function]['module'] = $split[0];
+          $updates_graph[$function]['update'] = $split[1];
+        }
+      }
+    }
+  }
+
+  // Determine the update order based on a topological sort of the update graph.
+  drupal_depth_first_search($updates_graph);
+  uasort($updates_graph, 'drupal_sort_weight');
+
+  // Remove non requested modules
+  $result=array();
+  foreach ($updates_graph as $function => $graph_node) {
+    if (array_key_exists($graph_node['module'], $start)) {
+      $result[$function] = $graph_node;
+    }
+  }
+    
+  return $result;
+}
+
+/**
  * Start the database update batch process.
+ * 
+ * This batch uses _update_calculate_graph() which returns
+ * an ordered list of versions.
+ * 
+ * TODO: But there is no test for not being able to install the requested
+ * dependencies in full order. This should be done on the update.php form(s) 
  *
  * @param $start
  *   An array of all the modules and which update to start at.
@@ -374,19 +474,13 @@
   }
 
   $operations = array();
-  // Set the installed version so updates start at the correct place.
-  foreach ($start as $module => $version) {
-    drupal_set_installed_schema_version($module, $version - 1);
-    $updates = drupal_get_schema_versions($module);
-    $max_version = max($updates);
-    if ($version <= $max_version) {
-      foreach ($updates as $update) {
-        if ($update >= $version) {
-          $operations[] = array('update_do_one', array($module, $update));
-        }
-      }
-    }
+  
+  $updates_graph = _update_calculate_graph($start);
+
+  foreach ($updates_graph as $function => $graph_node) {
+    $operations[] = array('update_do_one', array($graph_node['module'], $graph_node['update']));
   }
+
   $batch['operations'] = $operations;
   $batch += array(
     'title' => 'Updating',
--- modules/comment/comment.install	Sun Oct 11 11:34:10 2009 -0700
+++ modules/comment/comment.install	Sun Oct 11 14:10:37 2009 -0700
@@ -114,6 +114,8 @@
 
 /**
  * Create comment Field API bundles.
+ *
+ * @after system_update_7038
  */
 function comment_update_7005() {
   foreach (node_type_get_types() as $info) {
--- modules/simpletest/simpletest.info	Sun Oct 11 11:34:10 2009 -0700
+++ modules/simpletest/simpletest.info	Sun Oct 11 14:10:37 2009 -0700
@@ -34,4 +34,5 @@
 files[] = tests/session.test
 files[] = tests/theme.test
 files[] = tests/unicode.test
+files[] = tests/update.test
 files[] = tests/xmlrpc.test
