diff --git includes/bootstrap.inc includes/bootstrap.inc
index 590f1ba..b02ebea 100644
--- includes/bootstrap.inc
+++ includes/bootstrap.inc
@@ -1676,10 +1676,6 @@ function drupal_get_schema($table = NULL, $rebuild = FALSE) {
 function drupal_function_exists($function) {
   static $checked = array();
 
-  if (defined('MAINTENANCE_MODE')) {
-    return function_exists($function);
-  }
-
   if (isset($checked[$function])) {
     return $checked[$function];
   }
@@ -1746,7 +1742,9 @@ function _registry_check_code($type, $name = NULL) {
 
   if (!isset($lookup_cache)) {
     $lookup_cache = array();
-    if ($cache = cache_get('lookup_cache', 'cache_registry')) {
+    // Check if we have access to caching so we don't blow up in places like
+    // the installer.
+    if (function_exists('cache_get') && $cache = cache_get('lookup_cache', 'cache_registry')) {
       $lookup_cache = $cache->data;
     }
   }
@@ -1768,39 +1766,37 @@ function _registry_check_code($type, $name = NULL) {
     return;
   }
 
-  // $type can be one of 'function', 'interface' or 'class', so we only need the
-  // first letter to keep the cache key unique.
-  $cache_key = $type[0] . $name;
-  if (isset($lookup_cache[$cache_key])) {
-    if ($lookup_cache[$cache_key]) {
-      require_once DRUPAL_ROOT . '/' . $lookup_cache[$cache_key];
+  if (isset($lookup_cache[$type][$name])) {
+    if ($lookup_cache[$type][$name]) {
+      require_once DRUPAL_ROOT . '/' . $lookup_cache[$type][$name];
     }
-    return $lookup_cache[$cache_key];
+    return $lookup_cache[$type][$name];
+  }
+
+  if (db_is_active()) {
+    // This function may get called when the default database is not active, but
+    // there is no reason we'd ever want to not use the default database for
+    // this query.
+    // Note: Misses are valuable information worth caching, so cache even if
+    // $file is FALSE.
+    $lookup_cache[$type][$name] = Database::getConnection('default', 'default')->query("SELECT filename FROM {registry} WHERE name = :name AND type = :type", array(
+        ':name' => $name,
+        ':type' => $type,
+      ))
+      ->fetchField();
+
+    // Flag that we've run a lookup query and need to update the cache.
+    $cache_update_needed = TRUE;
   }
 
-  // This function may get called when the default database is not active, but
-  // there is no reason we'd ever want to not use the default database for
-  // this query.
-  $file = Database::getConnection('default', 'default')->query("SELECT filename FROM {registry} WHERE name = :name AND type = :type", array(
-      ':name' => $name,
-      ':type' => $type,
-    ))
-    ->fetchField();
-
-  // Flag that we've run a lookup query and need to update the cache.
-  $cache_update_needed = TRUE;
-
-  // Misses are valuable information worth caching, so cache even if
-  // $file is FALSE.
-  $lookup_cache[$cache_key] = $file;
+  drupal_alter('registry', $lookup_cache);
 
-  if ($file) {
-    require_once DRUPAL_ROOT . '/' . $file;
+  if (isset($lookup_cache[$type][$name]) && $lookup_cache[$type][$name]) {
+    require_once DRUPAL_ROOT . '/' . $lookup_cache[$type][$name];
     return TRUE;
   }
-  else {
-    return FALSE;
-  }
+
+  return $lookup_cache[$type][$name] = FALSE;
 }
 
 /**
diff --git modules/system/system.module modules/system/system.module
index e4bb758..74f08d3 100644
--- modules/system/system.module
+++ modules/system/system.module
@@ -163,6 +163,16 @@ function system_theme() {
 }
 
 /**
+ * Implementation of hook_registry_lookup_alter().
+ */
+function system_registry_alter(&$lookup) {
+  if (MAINTENANCE_MODE == 'install') {
+    // Provide theme_system_report function to our installer.
+    $lookup['function']['theme_status_report'] = drupal_get_path('module', 'system') . '/system.admin.inc';
+  }
+}
+
+/**
  * Implementation of hook_perm().
  */
 function system_perm() {
