diff --git a/core/includes/module.inc b/core/includes/module.inc
index 6b4604a..29c9712 100644
--- a/core/includes/module.inc
+++ b/core/includes/module.inc
@@ -105,6 +105,7 @@ function module_list($refresh = FALSE, $bootstrap_refresh = FALSE, $sort = FALSE
       }
       else {
         // Not using drupal_map_assoc() here as that requires common.inc.
+        // @todo MEH @ array_keys()
         $list = array_keys(system_list('module_enabled'));
         $list = (!empty($list) ? array_combine($list, $list) : array());
       }
@@ -139,6 +140,7 @@ function module_list($refresh = FALSE, $bootstrap_refresh = FALSE, $sort = FALSE
  * @see list_themes()
  */
 function system_list($type) {
+  // @todo Drop this cache as soon as config caches already.
   $lists = &drupal_static(__FUNCTION__);
 
   // For bootstrap modules, attempt to fetch the list from cache if possible.
@@ -168,7 +170,7 @@ function system_list($type) {
   }
   // Otherwise build the list for enabled modules and themes.
   elseif (!isset($lists['module_enabled'])) {
-    if ($cached = cache('bootstrap')->get('system_list')) {
+    if (0 && $cached = cache('bootstrap')->get('system_list')) {
       $lists = $cached->data;
     }
     else {
@@ -177,55 +179,51 @@ function system_list($type) {
         'theme' => array(),
         'filepaths' => array(),
       );
+
       // The module name (rather than the filename) is used as the fallback
       // weighting in order to guarantee consistent behavior across different
       // Drupal installations, which might have modules installed in different
       // locations in the file system. The ordering here must also be
       // consistent with the one used in module_implements().
-      $result = db_query("SELECT * FROM {system} WHERE type = 'theme' OR (type = 'module' AND status = 1) ORDER BY weight ASC, name ASC");
-      foreach ($result as $record) {
-        $record->info = unserialize($record->info);
-        // Build a list of all enabled modules.
-        if ($record->type == 'module') {
-          $lists['module_enabled'][$record->name] = $record;
-        }
-        // Build a list of themes.
-        if ($record->type == 'theme') {
-          $lists['theme'][$record->name] = $record;
-        }
-        // Build a list of filenames so drupal_get_filename can use it.
-        if ($record->status) {
-          $lists['filepaths'][] = array('type' => $record->type, 'name' => $record->name, 'filepath' => $record->filename);
-        }
+      // @todo ^^ NFIAA how to migrate that. ^^
+
+      // @todo Upgrade path.
+      $config_modules = config('system.modules');
+      $lists['module_enabled'] = $config_modules->get('enabled');
+      uasort($lists['module_enabled'], 'drupal_sort_weight');
+      // @todo Fix calling code to not rely on a duplicated $name within $record.
+      // @todo Fix calling code to not assume that system_list() would ever return
+      //   something disabled [status].
+      // @todo Adjust calling code to use arrays instead of objects.
+      foreach ($lists['module_enabled'] as $name => $record) {
+        $record['name'] = $name;
+        $record['status'] = 1;
+        $lists['module_enabled'][$name] = (object) $record;
+
+        $lists['filepaths'][] = array('type' => 'module', 'name' => $name, 'filepath' => $record['filename']);
       }
-      foreach ($lists['theme'] as $key => $theme) {
-        if (!empty($theme->info['base theme'])) {
-          // Make a list of the theme's base themes.
-          $lists['theme'][$key]->base_themes = drupal_find_base_themes($lists['theme'], $key);
-          // Don't proceed if there was a problem with the root base theme.
-          if (!current($lists['theme'][$key]->base_themes)) {
-            continue;
-          }
-          // Determine the root base theme.
-          $base_key = key($lists['theme'][$key]->base_themes);
-          // Add to the list of sub-themes for each of the theme's base themes.
-          foreach (array_keys($lists['theme'][$key]->base_themes) as $base_theme) {
-            $lists['theme'][$base_theme]->sub_themes[$key] = $lists['theme'][$key]->info['name'];
-          }
-          // Add the base theme's theme engine info.
-          $lists['theme'][$key]->info['engine'] = $lists['theme'][$base_key]->info['engine'];
-        }
-        else {
-          // A plain theme is its own base theme.
-          $base_key = $key;
-        }
-        // Set the theme engine prefix.
-        $lists['theme'][$key]->prefix = ($lists['theme'][$key]->info['engine'] == 'theme') ? $base_key : $lists['theme'][$key]->info['engine'];
+
+      $config_themes = config('system.themes');
+      $lists['theme'] = $config_themes->get('enabled');
+      uasort($lists['theme'], 'drupal_sort_weight');
+      // @todo Fix calling code to not rely on a duplicated $name within $record.
+      // @todo Fix calling code to not assume that system_list() would ever return
+      //   something disabled [status].
+      // @todo Adjust calling code to use arrays instead of objects.
+      foreach ($lists['theme'] as $name => $record) {
+        $record['name'] = $name;
+        $record['status'] = 1;
+        $lists['theme'][$name] = (object) $record;
+
+        $lists['filepaths'][] = array('type' => 'theme', 'name' => $name, 'filepath' => $record['filename']);
       }
+
       cache('bootstrap')->set('system_list', $lists);
     }
     // To avoid a separate database lookup for the filepath, prime the
     // drupal_get_filename() static cache with all enabled modules and themes.
+    // @todo A separate cache is nuts for this. Can happy walk through 'module'
+    //   and 'theme' keys instead.
     foreach ($lists['filepaths'] as $item) {
       drupal_get_filename($item['type'], $item['name'], $item['filepath']);
       drupal_classloader_register($item['name'], dirname($item['filepath']));
@@ -243,6 +241,7 @@ function system_list_reset() {
   drupal_static_reset('system_rebuild_module_data');
   drupal_static_reset('list_themes');
   cache('bootstrap')->deleteMultiple(array('bootstrap_modules', 'system_list'));
+  cache('bootstrap')->deletePrefix('system_info:');
 }
 
 /**
@@ -455,11 +454,12 @@ function module_enable($module_list, $enable_dependencies = TRUE) {
       // needs to be done first so that the module's hook implementations,
       // hook_schema() in particular, can be called while it is being
       // installed.
-      db_update('system')
-        ->fields(array('status' => 1))
-        ->condition('type', 'module')
-        ->condition('name', $module)
-        ->execute();
+      config('system.modules')->set('enabled.' . $module, array(
+        'filename' => drupal_get_filename('module', $module),
+        // @todo Need actual weight.
+        'weight' => 0,
+      ))->save();
+
       // Refresh the module list to include it.
       system_list_reset();
       module_list(TRUE);
@@ -572,11 +572,9 @@ function module_disable($module_list, $disable_dependents = TRUE) {
     if (module_exists($module)) {
       module_load_install($module);
       module_invoke($module, 'disable');
-      db_update('system')
-        ->fields(array('status' => 0))
-        ->condition('type', 'module')
-        ->condition('name', $module)
-        ->execute();
+
+      config('system.modules')->clear('enabled.' . $module)->save();
+
       $invoke_modules[] = $module;
       watchdog('system', '%module module disabled.', array('%module' => $module), WATCHDOG_INFO);
     }
diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 7d638f6..89de188 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -768,6 +768,33 @@ function list_themes($refresh = FALSE) {
     if (!defined('MAINTENANCE_MODE')) {
       try {
         $themes = system_list('theme');
+        foreach ($themes as $name => $theme) {
+          $theme->info = system_get_info('theme', $name);
+        }
+        foreach ($themes as $name => $theme) {
+          if (!empty($theme->info['base theme'])) {
+            // Make a list of the theme's base themes.
+            $theme->base_themes = drupal_find_base_themes($themes, $name);
+            // Don't proceed if there was a problem with the root base theme.
+            if (!current($theme->base_themes)) {
+              continue;
+            }
+            // Determine the root base theme.
+            $base_key = key($theme->base_themes);
+            // Add to the list of sub-themes for each of the theme's base themes.
+            foreach (array_keys($theme->base_themes) as $base_theme) {
+              $themes[$base_theme]->sub_themes[$name] = $name;
+            }
+            // Add the base theme's theme engine info.
+            $theme->info['engine'] = $themes[$base_key]->info['engine'];
+          }
+          else {
+            // A plain theme is its own base theme.
+            $base_key = $name;
+          }
+          // Set the theme engine prefix.
+          $theme->prefix = ($theme->info['engine'] == 'theme') ? $base_key : $theme->info['engine'];
+        }
       }
       catch (Exception $e) {
         // If the database is not available, rebuild the theme data.
@@ -1478,14 +1505,25 @@ function theme_render_template($template_file, $variables) {
  *   An array of theme names.
  */
 function theme_enable($theme_list) {
+  // @todo Why on earth is module_enable/_disable() not simply system_enable/_disable() ??!
+  //   Lazy workaround to make system_theme_enable() happy.
+  $theme_data = system_rebuild_theme_data();
+  foreach ($theme_list as $name) {
+    if (!isset($theme_data[$name])) {
+      // This theme is not found in the filesystem, abort.
+      return FALSE;
+    }
+  }
+
   drupal_clear_css_cache();
 
-  foreach ($theme_list as $key) {
-    db_update('system')
-      ->fields(array('status' => 1))
-      ->condition('type', 'theme')
-      ->condition('name', $key)
-      ->execute();
+  foreach ($theme_list as $name) {
+    config('system.themes')->set('enabled.' . $name, array(
+      'filename' => drupal_get_filename('theme', $name),
+      'owner' => $theme_data[$name]->owner,
+      // @todo Need actual weight.
+      'weight' => $theme_data[$name]->weight,
+    ))->save();
   }
 
   list_themes(TRUE);
@@ -1494,6 +1532,7 @@ function theme_enable($theme_list) {
 
   // Invoke hook_themes_enabled() after the themes have been enabled.
   module_invoke_all('themes_enabled', $theme_list);
+  return TRUE;
 }
 
 /**
@@ -1507,18 +1546,14 @@ function theme_disable($theme_list) {
   if ($pos = array_search(variable_get('theme_default', 'stark'), $theme_list) !== FALSE) {
     unset($theme_list[$pos]);
     if (empty($theme_list)) {
-      return;
+      return FALSE;
     }
   }
 
   drupal_clear_css_cache();
 
-  foreach ($theme_list as $key) {
-    db_update('system')
-      ->fields(array('status' => 0))
-      ->condition('type', 'theme')
-      ->condition('name', $key)
-      ->execute();
+  foreach ($theme_list as $name) {
+    config('system.themes')->clear('enabled.' . $name)->save();
   }
 
   list_themes(TRUE);
@@ -1527,6 +1562,7 @@ function theme_disable($theme_list) {
 
   // Invoke hook_themes_disabled after the themes have been disabled.
   module_invoke_all('themes_disabled', $theme_list);
+  return TRUE;
 }
 
 /**
diff --git a/core/includes/update.inc b/core/includes/update.inc
index b0d09a7..d58573f 100644
--- a/core/includes/update.inc
+++ b/core/includes/update.inc
@@ -937,6 +937,46 @@ function update_variables_to_config($config_name, array $variable_map = array())
   }
 }
 
+/* Run me with the following from /debug.php or whatever:
+
+require_once DRUPAL_ROOT . '/core/includes/bootstrap.inc';
+require_once DRUPAL_ROOT . '/core/includes/common.inc';
+require_once DRUPAL_ROOT . '/core/includes/update.inc';
+drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE);
+update_system_list_to_config();
+
+*/
+function update_system_list_to_config() {
+  // Migrate enabled modules and list of bootstrap modules.
+  $result = db_query("SELECT * FROM {system} WHERE type = 'module' AND status = 1 ORDER BY weight ASC, name ASC");
+  $config = config('system.modules');
+  $bootstrap = array();
+  foreach ($result as $record) {
+    if ($record->bootstrap) {
+      $bootstrap[] = $record->name;
+    }
+    $config->set('enabled.' . $record->name, array(
+      'filename' => $record->filename,
+      'weight' => $record->weight,
+    ));
+  }
+  $config->set('bootstrap', $bootstrap);
+  $config->save();
+
+  // Migrate themes.
+  // Intentionally leaves out disabled themes.
+  $result = db_query("SELECT * FROM {system} WHERE type = 'theme' AND status = 1 ORDER BY weight ASC, name ASC");
+  $config = config('system.themes');
+  foreach ($result as $record) {
+    $config->set('enabled.' . $record->name, array(
+      'filename' => $record->filename,
+      'owner' => $record->owner,
+      'weight' => $record->weight,
+    ));
+  }
+  $config->save();
+}
+
 /**
  * @defgroup update-api-7.x-to-8.x Update versions of API functions
  * @{
diff --git a/core/lib/Drupal/Core/Config/DrupalConfig.php b/core/lib/Drupal/Core/Config/DrupalConfig.php
index f5a9220..2875d74 100644
--- a/core/lib/Drupal/Core/Config/DrupalConfig.php
+++ b/core/lib/Drupal/Core/Config/DrupalConfig.php
@@ -201,6 +201,7 @@ class DrupalConfig {
     else {
       drupal_array_unset_nested_value($this->data, $parts);
     }
+    return $this;
   }
 
   /**
diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc
index fc0e8bb..27e2cd4 100644
--- a/core/modules/system/system.admin.inc
+++ b/core/modules/system/system.admin.inc
@@ -265,12 +265,9 @@ function system_themes_admin_form_submit($form, &$form_state) {
 function system_theme_enable() {
   if (isset($_REQUEST['theme']) && isset($_REQUEST['token']) && drupal_valid_token($_REQUEST['token'], 'system-theme-operation-link')) {
     $theme = $_REQUEST['theme'];
-    // Get current list of themes.
-    $themes = list_themes();
 
-    // Check if the specified theme is one recognized by the system.
-    if (!empty($themes[$theme])) {
-      theme_enable(array($theme));
+    if (theme_enable(array($theme))) {
+      $themes = list_themes();
       drupal_set_message(t('The %theme theme has been enabled.', array('%theme' => $themes[$theme]->info['name'])));
     }
     else {
@@ -287,19 +284,14 @@ function system_theme_enable() {
 function system_theme_disable() {
   if (isset($_REQUEST['theme']) && isset($_REQUEST['token']) && drupal_valid_token($_REQUEST['token'], 'system-theme-operation-link')) {
     $theme = $_REQUEST['theme'];
-    // Get current list of themes.
     $themes = list_themes();
 
-    // Check if the specified theme is one recognized by the system.
-    if (!empty($themes[$theme])) {
-      if ($theme == variable_get('theme_default', 'stark')) {
-        // Don't disable the default theme.
-        drupal_set_message(t('%theme is the default theme and cannot be disabled.', array('%theme' => $themes[$theme]->info['name'])), 'error');
-      }
-      else {
-        theme_disable(array($theme));
-        drupal_set_message(t('The %theme theme has been disabled.', array('%theme' => $themes[$theme]->info['name'])));
-      }
+    if ($theme == variable_get('theme_default', 'stark')) {
+      // Don't disable the default theme.
+      drupal_set_message(t('%theme is the default theme and cannot be disabled.', array('%theme' => $themes[$theme]->info['name'])), 'error');
+    }
+    elseif (theme_disable(array($theme))) {
+      drupal_set_message(t('The %theme theme has been disabled.', array('%theme' => $themes[$theme]->info['name'])));
     }
     else {
       drupal_set_message(t('The %theme theme was not found.', array('%theme' => $theme)), 'error');
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index 5581d01..a9b95f0 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -1574,7 +1574,7 @@ function system_schema() {
   $schema['system'] = array(
     'description' => "A list of all modules, themes, and theme engines that are or have been installed in Drupal's file system.",
     'fields' => array(
-      'filename' => array(
+      'filename' => array( // obsolete.
         'description' => 'The path of the primary file for this item, relative to the Drupal root; e.g. modules/node/node.module.',
         'type' => 'varchar',
         'length' => 255,
@@ -1588,27 +1588,27 @@ function system_schema() {
         'not null' => TRUE,
         'default' => '',
       ),
-      'type' => array(
+      'type' => array( // obsolete.
         'description' => 'The type of the item, either module, theme, or theme_engine.',
         'type' => 'varchar',
         'length' => 12,
         'not null' => TRUE,
         'default' => '',
       ),
-      'owner' => array(
+      'owner' => array( // obsolete.
         'description' => "A theme's 'parent' . Can be either a theme or an engine.",
         'type' => 'varchar',
         'length' => 255,
         'not null' => TRUE,
         'default' => '',
       ),
-      'status' => array(
+      'status' => array( // obsolete.
         'description' => 'Boolean indicating whether or not this item is enabled.',
         'type' => 'int',
         'not null' => TRUE,
         'default' => 0,
       ),
-      'bootstrap' => array(
+      'bootstrap' => array( // obsolete.
         'description' => "Boolean indicating whether this module is loaded during Drupal's early bootstrapping phase (e.g. even before the page cache is consulted).",
         'type' => 'int',
         'not null' => TRUE,
@@ -1621,7 +1621,7 @@ function system_schema() {
         'default' => -1,
         'size' => 'small',
       ),
-      'weight' => array(
+      'weight' => array( // obsolete.
         'description' => "The order in which this module's hooks should be invoked relative to other modules. Equal-weighted modules are ordered by name.",
         'type' => 'int',
         'not null' => TRUE,
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 6e60da8..e62c0df 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -2276,6 +2276,34 @@ function system_check_directory($form_element) {
  *   The type of the files.
  */
 function system_get_files_database(&$files, $type) {
+  // Handle config.
+  // @todo Rename system.modules/themes into singular.
+  $config = config('system.' . $type . 's')->get('enabled');
+//  foreach ($config as $name => $record) {
+//    $record['name'] = $name;
+//    $record['status'] = 1;
+//
+//    foreach ($record as $key => $value) {
+//      if (!isset($files[$name]->$key)) {
+//        $files[$name]->$key = $value;
+//      }
+//    }
+//  }
+  // Let's reverse it:
+  // Whatever is in config is enabled. Whatever is not in config is disabled.
+  // And for disabled stuff, we don't care. At all.
+  foreach ($files as $name => $file) {
+    if (isset($config[$name])) {
+      $file->status = 1;
+      $file->filename = $file->uri = $config[$name]['filename'];
+      $file->weight = $config[$name]['weight'];
+    }
+    else {
+      $file->status = 0;
+    }
+  }
+
+  // Handle {system}...
   // Extract current files from database.
   $result = db_query("SELECT filename, name, type, status, schema_version, weight FROM {system} WHERE type = :type", array(':type' => $type));
   foreach ($result as $file) {
@@ -2400,20 +2428,39 @@ function system_update_files_database(&$files, $type) {
  * @see system_rebuild_theme_data()
  */
 function system_get_info($type, $name = NULL) {
+  $list = &drupal_static(__FUNCTION__, array());
+
   $info = array();
-  if ($type == 'module') {
-    $type = 'module_enabled';
-  }
-  $list = system_list($type);
-  foreach ($list as $shortname => $item) {
-    if (!empty($item->status)) {
-      $info[$shortname] = $item->info;
+
+  if (!isset($list[$type])) {
+    $system_list_type = ($type == 'module' ? 'module_enabled' : $type);
+    $system_list = system_list($system_list_type);
+    // @todo Remove value.
+    foreach ($system_list as $extension => $whatever_dont_use_me) {
+      $cid = 'system_info:' . $extension;
+      if (0 && $cached = cache('bootstrap')->get($cid)) {
+        $list[$type][$extension] = $cached->data;
+      }
+      else {
+        $info = db_query_range("SELECT info FROM {system} WHERE type = :type AND name = :name", 0, 1, array(
+          ':type' => $type,
+          ':name' => $extension,
+        ))->fetchField();
+        // Account for non-existing {system} record. (shouldn't be possible)
+        $info = ($info ? unserialize($info) : array());
+        // Account for bogus {system}.info data. (shouldn't be possible)
+        $info = ($info ? $info : array());
+
+        cache('bootstrap')->set($cid, $info);
+        $list[$type][$extension] = $info;
+      }
     }
   }
+
   if (isset($name)) {
-    return isset($info[$name]) ? $info[$name] : array();
+    return isset($list[$type][$name]) ? $list[$type][$name] : array();
   }
-  return $info;
+  return $list[$type];
 }
 
 /**
diff --git a/core/modules/system/system.test b/core/modules/system/system.test
index ec1a9a6..59de7b4 100644
--- a/core/modules/system/system.test
+++ b/core/modules/system/system.test
@@ -2195,8 +2195,7 @@ class SystemInfoAlterTestCase extends WebTestBase {
     $this->assertTrue(isset($info['regions']['test_region']), t('Altered theme info was added to {system}.info.'));
     $seven_regions = system_region_list('seven');
     $this->assertTrue(isset($seven_regions['test_region']), t('Altered theme info was returned by system_region_list().'));
-    $system_list_themes = system_list('theme');
-    $info = $system_list_themes['seven']->info;
+    $info = system_get_info('theme', 'seven');
     $this->assertTrue(isset($info['regions']['test_region']), t('Altered theme info was returned by system_list().'));
     $list_themes = list_themes();
     $this->assertTrue(isset($list_themes['seven']->info['regions']['test_region']), t('Altered theme info was returned by list_themes().'));
@@ -2210,8 +2209,7 @@ class SystemInfoAlterTestCase extends WebTestBase {
     $this->assertFalse(isset($info['regions']['test_region']), t('Altered theme info was removed from {system}.info.'));
     $seven_regions = system_region_list('seven');
     $this->assertFalse(isset($seven_regions['test_region']), t('Altered theme info was not returned by system_region_list().'));
-    $system_list_themes = system_list('theme');
-    $info = $system_list_themes['seven']->info;
+    $info = system_get_info('theme', 'seven');
     $this->assertFalse(isset($info['regions']['test_region']), t('Altered theme info was not returned by system_list().'));
     $list_themes = list_themes();
     $this->assertFalse(isset($list_themes['seven']->info['regions']['test_region']), t('Altered theme info was not returned by list_themes().'));
