Index: modules/system/system.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.admin.inc,v
retrieving revision 1.63.2.8
diff -u -p -r1.63.2.8 system.admin.inc
--- modules/system/system.admin.inc	9 Jun 2009 10:58:09 -0000	1.63.2.8
+++ modules/system/system.admin.inc	18 Jun 2009 06:58:36 -0000
@@ -198,13 +198,19 @@ function system_themes_form() {
 
   foreach ($themes as $theme) {
     $screenshot = NULL;
-    $theme_key = $theme->name;
-    while ($theme_key) {
-      if (file_exists($themes[$theme_key]->info['screenshot'])) {
+    // Create a list which includes the current theme and all its base themes.
+    if (isset($themes[$theme->name]->base_themes)) {
+      $theme_keys = array_keys($themes[$theme->name]->base_themes) + array($theme->name);
+    }
+    else {
+      $theme_keys = array($theme->name);
+    }
+    // Look for the most accurate screenshot.
+    foreach (array_reverse($theme_keys) AS $theme_key) {
+      if (isset($themes[$theme_key]) && file_exists($themes[$theme_key]->info['screenshot'])) {
         $screenshot = $themes[$theme_key]->info['screenshot'];
         break;
       }
-      $theme_key = isset($themes[$theme_key]->info['base theme']) ? $themes[$theme_key]->info['base theme'] : NULL;
     }
     $screenshot = $screenshot ? theme('image', $screenshot, t('Screenshot for %theme theme', array('%theme' => $theme->info['name'])), '', array('class' => 'screenshot'), FALSE) : t('no screenshot');
 
Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.585.2.37
diff -u -p -r1.585.2.37 system.module
--- modules/system/system.module	13 May 2009 19:48:02 -0000	1.585.2.37
+++ modules/system/system.module	18 Jun 2009 06:58:36 -0000
@@ -893,10 +893,15 @@ function _system_theme_data() {
     // Now that we've established all our master themes, go back and fill in
     // data for subthemes.
     foreach ($sub_themes as $key) {
-      $base_key = system_find_base_theme($themes, $key);
-      if (!$base_key) {
+      $themes[$key]->base_themes = system_find_base_themes($themes, $key);
+      // Don't continue if there was a problem with the root base theme.
+      if (!current($themes[$key]->base_themes)) {
         continue;
       }
+      $base_key = key($themes[$key]->base_themes);
+      foreach (array_keys($themes[$key]->base_themes) AS $base_theme) {
+        $themes[$base_theme]->sub_themes[$key] = $themes[$key]->info['name'];
+      }
       // Copy the 'owner' and 'engine' over if the top level theme uses a
       // theme engine.
       if (isset($themes[$base_key]->owner)) {
@@ -918,6 +923,49 @@ function _system_theme_data() {
 }
 
 /**
+ * Find all the base themes for the specified theme.
+ *
+ * Themes can inherit templates and function implementations from earlier themes.
+ *
+ * @param $themes
+ *   An array of available themes.
+ * @param $key
+ *   The name of the theme whose base we are looking for.
+ * @param $used_keys
+ *   A recursion parameter preventing endless loops.
+ * @return
+ *   Returns an array of all of the theme's ancestors; the first element's value
+ *   will be NULL if an error occurred.
+ */
+function system_find_base_themes($themes, $key, $used_keys = array()) {
+  $base_key = $themes[$key]->info['base theme'];
+  // Does the base theme exist?
+  if (!isset($themes[$base_key])) {
+    return array($base_key => NULL);
+  }
+
+  $current_base_theme = array($base_key => $themes[$base_key]->info['name']);
+
+  // Is the base theme itself a child of another theme?
+  if (isset($themes[$base_key]->info['base theme'])) {
+    // Do we already know the base themes of this theme?
+    if (isset($themes[$base_key]->base_themes)) {
+      return $themes[$base_key]->base_themes + $current_base_theme;
+    }
+    // Prevent loops.
+    if (!empty($used_keys[$base_key])) {
+      return array($base_key => NULL);
+    }
+    $used_keys[$base_key] = TRUE;
+    return system_find_base_themes($themes, $base_key, $used_keys) + $current_base_theme;
+  }
+  // If we get here, then this is our parent theme.
+  return $current_base_theme;
+}
+
+/**
+ * This function has been deprecated in favor of system_find_base_themes().
+ *
  * Recursive function to find the top level base theme. Themes can inherit
  * templates and function implementations from earlier themes.
  *
