=== modified file 'includes/common.inc'
--- includes/common.inc	2009-10-13 21:16:42 +0000
+++ includes/common.inc	2009-10-14 03:25:48 +0000
@@ -4308,6 +4308,22 @@ function drupal_alter($type, &$data, &$c
     $function = $module . '_' . $hook;
     $function($data, $context1, $context2);
   }
+  // Allow the theme to alter variables after the theme system has been
+  // initialized.
+  global $theme, $base_theme_info;
+  if (isset($theme)) {
+    $theme_keys = array();
+    foreach ($base_theme_info as $base) {
+      $theme_keys[] = $base->name;
+    }
+    $theme_keys[] = $theme;
+    foreach ($theme_keys as $theme_key) {
+      $function = $theme_key . '_' . $hook;
+      if (function_exists($function)) {
+        $function($data, $context1, $context2);
+      }
+    }
+  }
 }
 
 /**

=== modified file 'includes/theme.maintenance.inc'
--- includes/theme.maintenance.inc	2009-10-09 00:59:53 +0000
+++ includes/theme.maintenance.inc	2009-10-14 03:28:42 +0000
@@ -33,7 +33,7 @@ function _drupal_maintenance_theme() {
 
   // Install and update pages are treated differently to prevent theming overrides.
   if (defined('MAINTENANCE_MODE') && (MAINTENANCE_MODE == 'install' || MAINTENANCE_MODE == 'update')) {
-    $theme = 'minnelli';
+    $custom_theme = 'minnelli';
   }
   else {
     if (!db_is_active()) {
@@ -46,11 +46,16 @@ function _drupal_maintenance_theme() {
       drupal_load('module', 'filter');
     }
 
-    $theme = variable_get('maintenance_theme', 'minnelli');
+    $custom_theme = variable_get('maintenance_theme', 'minnelli');
   }
 
   $themes = list_themes();
 
+  // list_themes() triggers a drupal_alter() in maintenance mode, but we can't
+  // let themes alter the .info data until we know a theme's base themes. So
+  // don't set global $theme until after list_themes() builds its cache.
+  $theme = $custom_theme;
+
   // Store the identifier for retrieving theme settings with.
   $theme_key = $theme;
 

=== modified file 'modules/simpletest/tests/common.test'
--- modules/simpletest/tests/common.test	2009-10-13 16:38:42 +0000
+++ modules/simpletest/tests/common.test	2009-10-14 03:09:33 +0000
@@ -29,24 +29,24 @@ class DrupalAlterTestCase extends Drupal
 
     // Verify alteration of a single argument.
     $array_copy = $array;
-    $array_expected = array('foo' => 'Drupal');
+    $array_expected = array('foo' => 'Drupal theme');
     drupal_alter('drupal_alter', $array_copy);
     $this->assertEqual($array_copy, $array_expected, t('Single array was altered.'));
 
     $object_copy = clone $object;
     $object_expected = clone $object;
-    $object_expected->foo = 'Drupal';
+    $object_expected->foo = 'Drupal theme';
     drupal_alter('drupal_alter', $object_copy);
     $this->assertEqual($object_copy, $object_expected, t('Single object was altered.'));
 
     // Verify alteration of multiple arguments.
     $array_copy = $array;
-    $array_expected = array('foo' => 'Drupal');
+    $array_expected = array('foo' => 'Drupal theme');
     $object_copy = clone $object;
     $object_expected = clone $object;
-    $object_expected->foo = 'Drupal';
+    $object_expected->foo = 'Drupal theme';
     $array2_copy = $array;
-    $array2_expected = array('foo' => 'Drupal');
+    $array2_expected = array('foo' => 'Drupal theme');
     drupal_alter('drupal_alter', $array_copy, $object_copy, $array2_copy);
     $this->assertEqual($array_copy, $array_expected, t('First argument to drupal_alter() was altered.'));
     $this->assertEqual($object_copy, $object_expected, t('Second argument to drupal_alter() was altered.'));

=== modified file 'modules/simpletest/tests/common_test.module'
--- modules/simpletest/tests/common_test.module	2009-10-13 16:38:42 +0000
+++ modules/simpletest/tests/common_test.module	2009-10-14 03:09:33 +0000
@@ -101,6 +101,40 @@ function common_test_drupal_alter_alter(
 }
 
 /**
+ * Implement hook_TYPE_alter() on behalf of Garland theme.
+ *
+ * Same as common_test_drupal_alter_alter(), but here, we verify that themes
+ * can also alter and come last.
+ */
+function garland_drupal_alter_alter(&$data, &$arg2 = NULL, &$arg3 = NULL) {
+  // Alter first argument.
+  if (is_array($data)) {
+    $data['foo'] .= ' theme';
+  }
+  elseif (is_object($data)) {
+    $data->foo .= ' theme';
+  }
+  // Alter second argument, if present.
+  if (isset($arg2)) {
+    if (is_array($arg2)) {
+      $arg2['foo'] .= ' theme';
+    }
+    elseif (is_object($arg2)) {
+      $arg2->foo .= ' theme';
+    }
+  }
+  // Try to alter third argument, if present.
+  if (isset($arg3)) {
+    if (is_array($arg3)) {
+      $arg3['foo'] .= ' theme';
+    }
+    elseif (is_object($arg3)) {
+      $arg3->foo .= ' theme';
+    }
+  }
+}
+
+/**
  * Implement hook_theme().
  */
 function common_test_theme() {

