Index: system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.901
diff -u -r1.901 system.module
--- modules/system/system.module	13 Mar 2010 06:55:50 -0000	1.901
+++ modules/system/system.module	17 Mar 2010 12:53:10 -0000
@@ -2214,20 +2214,42 @@
   system_list_reset();
 }
 
+function _system_info_cache($cache_key, $function) {
+  $data = &$drupal_static($cache_key);
+  if (!isset($data)) {
+    $data = $function();
+  }
+  // We don't return the original objects,
+  // because we don't want them to be manipulated by other functions.
+  $data_cloned = array();
+  foreach ($data as $key => $object) {
+    $data_cloned[$key] = clone $object;
+  }
+  return $data_cloned;
+}
+
 /**
- * Helper function to scan and collect theme .info data and their engines.
- *
- * @return
- *   An associative array of themes information.
+ * Scan theme directories for *.info files.
+ * The data is cached in a static variable.
+ * The data depends on nothing but the filesystem, so it doesn't need to be reset.
+ * 
+ * @return :array
+ *   Array of data from theme *.info files, keyed by theme name.
+ *   The information is cached.
+ *   The data depends on the install profile.
  */
-function _system_rebuild_theme_data() {
-  $themes_info = &drupal_static(__FUNCTION__, array());
+function system_scan_theme_info() {
+  return _system_info_cache('system_scan_theme_info', '_system_scan_theme_info');
+}
 
-  if (empty($themes_info)) {
+/**
+ * Helper function for system_scan_theme_info()
+ */
+function _system_scan_theme_info() {
+  $raw_themes_info = array();
+  if (TRUE /* avoid indentation change for this patch */) {
     // Find themes
     $themes = drupal_system_listing('/\.info$/', 'themes');
-    // Find theme engines
-    $engines = drupal_system_listing('/\.engine$/', 'themes/engines');
 
     // Set defaults for theme info.
     $defaults = array(
@@ -2258,12 +2280,39 @@
       'php' => DRUPAL_MINIMUM_PHP,
     );
 
-    $sub_themes = array();
     // Read info files for each theme
     foreach ($themes as $key => $theme) {
-      $themes[$key]->filename = $theme->uri;
-      $themes[$key]->info = drupal_parse_info_file($theme->uri) + $defaults;
+      $raw_themes_info[$key]->filename = $theme->uri;
+      $raw_themes_info[$key]->info = drupal_parse_info_file($theme->uri) + $defaults;
+    }
+  }
+  
+  return $raw_themes_info;
+}
 
+/**
+ * Helper function to scan and collect theme .info data and their engines.
+ *
+ * @return
+ *   An associative array of themes information.
+ */
+function _system_rebuild_theme_data_rescan() {
+  return _system_info_cache('_system_rebuild_theme_data', '_system_rebuild_theme_data_rescan');
+}
+
+/**
+ * TODO: The function name sucks.
+ */
+function _system_rebuild_theme_info() {
+  if (TRUE) {
+    // Find themes
+    $themes = system_scan_theme_info();
+    // Find theme engines. drupal_system_listing() can have its own cache.
+    $engines = drupal_system_listing('/\.engine$/', 'themes/engines');
+
+    $sub_themes = array();
+    // Read info files for each theme
+    foreach ($themes as $key => $theme) {
       // Invoke hook_system_info_alter() to give installed modules a chance to
       // modify the data in the .info files if necessary.
       $type = 'theme';
@@ -2341,7 +2390,7 @@
 
     $themes_info = $themes;
   }
-
+  
   return $themes_info;
 }
 

