diff --git a/core/CHANGELOG.txt b/core/CHANGELOG.txt
index 5ef8eaf..5833d63 100644
--- a/core/CHANGELOG.txt
+++ b/core/CHANGELOG.txt
@@ -520,7 +520,7 @@ Drupal 5.0, 2007-01-15
 - Removed the archive module.
 - Upgrade system:
     * Created space for update branches.
-- Forms API:
+- Form API:
     * Made it possible to programmatically submit forms.
     * Improved api for multistep forms.
 - Theme system:
diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index 906a7c1..d3f2a2b 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -876,9 +876,11 @@ function drupal_get_filename($type, $name, $filename = NULL) {
   else {
     try {
       if (function_exists('db_query')) {
-        $file = db_query("SELECT filename FROM {system} WHERE name = :name AND type = :type", array(':name' => $name, ':type' => $type))->fetchField();
-        if ($file && file_exists(DRUPAL_ROOT . '/' . $file)) {
-          $files[$type][$name] = $file;
+        if ($config = config("system.$type")->get($name)) {
+          $file = $config['filename'];
+          if (file_exists(DRUPAL_ROOT . '/' . $file)) {
+            $files[$type][$name] = $file;
+          }
         }
       }
     }
@@ -2499,11 +2501,23 @@ function drupal_container(Container $new_container = NULL, $rebuild = FALSE) {
     $container
       ->register('config.storage.staging', 'Drupal\Core\Config\FileStorage')
       ->addArgument(config_get_config_directory(CONFIG_STAGING_DIRECTORY));
+    $container
+      ->register('state.storage', 'Drupal\Core\KeyValueStore\DatabaseStorage')
+      ->addArgument('state');
   }
   return $container;
 }
 
 /**
+ * Returns the state storage service.
+ *
+ * @return Drupal\Core\KeyValueStore\KeyValueStoreInterface
+ */
+function state() {
+  return drupal_container()->get('state.storage');
+}
+
+/**
  * Returns the test prefix if this is an internal request from SimpleTest.
  *
  * @return
diff --git a/core/includes/common.inc b/core/includes/common.inc
index c9913a2..ebd6637 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -3168,7 +3168,7 @@ function drupal_pre_render_styles($elements) {
 function drupal_build_css_cache($css) {
   $data = '';
   $uri = '';
-  $map = variable_get('drupal_css_cache_files', array());
+  $map = state()->get('drupal_css_cache_files') ?: array();
   // Create a new array so that only the file names are used to create the hash.
   // This prevents new aggregates from being created unnecessarily.
   $css_data = array();
@@ -3236,7 +3236,7 @@ function drupal_build_css_cache($css) {
     }
     // Save the updated map.
     $map[$key] = $uri;
-    variable_set('drupal_css_cache_files', $map);
+    state()->set('drupal_css_cache_files', $map);
   }
   return $uri;
 }
@@ -3401,7 +3401,7 @@ function _drupal_load_stylesheet($matches) {
  * Deletes old cached CSS files.
  */
 function drupal_clear_css_cache() {
-  variable_del('drupal_css_cache_files');
+  state()->delete('drupal_css_cache_files');
   file_scan_directory('public://css', '/.*/', array('callback' => 'drupal_delete_file_if_stale'));
 }
 
@@ -4711,7 +4711,7 @@ function drupal_add_tabledrag($table_id, $action, $relationship, $group, $subgro
 function drupal_build_js_cache($files) {
   $contents = '';
   $uri = '';
-  $map = variable_get('drupal_js_cache_files', array());
+  $map = state()->get('drupal_js_cache_files') ?: array();
   // Create a new array so that only the file names are used to create the hash.
   // This prevents new aggregates from being created unnecessarily.
   $js_data = array();
@@ -4756,7 +4756,7 @@ function drupal_build_js_cache($files) {
       }
     }
     $map[$key] = $uri;
-    variable_set('drupal_js_cache_files', $map);
+    state()->set('drupal_js_cache_files', $map);
   }
   return $uri;
 }
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index 3b69ce3..4e1dd7f 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -310,7 +310,9 @@ function install_begin_request(&$install_state) {
     $container->register('config.factory', 'Drupal\Core\Config\ConfigFactory')
       ->addArgument(new Reference('config.storage'))
       ->addArgument(new Reference('dispatcher'));
-
+    $container
+      ->register('state.storage', 'Drupal\Core\KeyValueStore\DatabaseStorage')
+      ->addArgument('state');
     drupal_container($container);
   }
 
@@ -1644,15 +1646,12 @@ function install_import_translations_remaining(&$install_state) {
  *   A message informing the user that the installation is complete.
  */
 function install_finished(&$install_state) {
+  $profile = drupal_get_profile();
   // Remember the profile which was used.
-  variable_set('install_profile', drupal_get_profile());
+  variable_set('install_profile', $profile);
 
   // Install profiles are always loaded last.
-  db_update('system')
-    ->fields(array('weight' => 1000))
-    ->condition('type', 'module')
-    ->condition('name', drupal_get_profile())
-    ->execute();
+  module_set_weight($profile, 1000);
 
   // Flush all caches to ensure that any full bootstraps during the installer
   // do not leave stale cached data, and that any content types or other items
@@ -1820,7 +1819,7 @@ function install_check_requirements($install_state) {
 }
 
 /**
- * Returns a Forms API array definition for site configuration.
+ * Returns a Form API array definition for site configuration.
  *
  * @see install_configure_form()
  * @see install_configure_form_validate()
diff --git a/core/includes/install.inc b/core/includes/install.inc
index 330fc0e..c121fa3 100644
--- a/core/includes/install.inc
+++ b/core/includes/install.inc
@@ -6,6 +6,7 @@
  */
 
 use Drupal\Core\Database\Database;
+use Drupal\Core\KeyValueStore\KeyValueFactory;
 use Drupal\locale\Gettext;
 
 /**
@@ -416,18 +417,15 @@ function drupal_install_system() {
   require_once DRUPAL_ROOT . '/' . $system_path . '/system.install';
   $system_versions = drupal_get_schema_versions('system');
   $system_version = $system_versions ? max($system_versions) : SCHEMA_INSTALLED;
-  db_insert('system')
-    ->fields(array('filename', 'name', 'type', 'owner', 'status', 'schema_version', 'bootstrap'))
-    ->values(array(
-        'filename' => $system_path . '/system.module',
-        'name' => 'system',
-        'type' => 'module',
-        'owner' => '',
-        'status' => 1,
-        'schema_version' => $system_version,
-        'bootstrap' => 0,
-      ))
-    ->execute();
+  $module_store = KeyValueFactory::get('system.module');
+  $module_store
+    ->set('system', (object) array(
+      'filename' => $system_path . '/system.module',
+      'schema_version' => $system_version,
+      'bootstrap' => 0,
+      'info' => '',
+    ));
+  module_config()->set('system', 0)->save();
 
   // Clear out module list and hook implementation statics before calling
   // system_rebuild_theme_data().
diff --git a/core/includes/menu.inc b/core/includes/menu.inc
index 8574dbe..4aeda61 100644
--- a/core/includes/menu.inc
+++ b/core/includes/menu.inc
@@ -451,7 +451,7 @@ function menu_get_item($path = NULL, $router_item = NULL) {
   if (!isset($router_items[$path])) {
     // Rebuild if we know it's needed, or if the menu masks are missing which
     // occurs rarely, likely due to a race condition of multiple rebuilds.
-    if (variable_get('menu_rebuild_needed', FALSE) || !variable_get('menu_masks', array())) {
+    if (state()->get('menu_rebuild_needed') || !variable_get('menu_masks', array())) {
       menu_router_rebuild();
     }
     $original_map = arg(NULL, $path);
@@ -2666,7 +2666,7 @@ function menu_router_rebuild() {
     menu_cache_clear_all();
     _menu_clear_page_cache();
     // Indicate that the menu has been successfully rebuilt.
-    variable_del('menu_rebuild_needed');
+    state()->delete('menu_rebuild_needed');
   }
   catch (Exception $e) {
     $transaction->rollback();
diff --git a/core/includes/module.inc b/core/includes/module.inc
index cbdbeaf..a5b79db 100644
--- a/core/includes/module.inc
+++ b/core/includes/module.inc
@@ -6,6 +6,7 @@
  */
 
 use Drupal\Component\Graph\Graph;
+use Drupal\Core\KeyValueStore\KeyValueFactory;
 
 /**
  * Loads all the modules that have been enabled in the system table.
@@ -128,15 +129,24 @@ function system_list($type) {
       $bootstrap_list = $cached->data;
     }
     else {
-      $bootstrap_list = db_query("SELECT name, filename FROM {system} WHERE status = 1 AND bootstrap = 1 AND type = 'module' ORDER BY weight ASC, name ASC")->fetchAllAssoc('name');
+      $store = KeyValueFactory::get('system.module');
+      $enabled_modules = module_config()->get();
+      $modules = $store->getMultiple(array_keys($enabled_modules));
+      $bootstrap_list = array();
+      foreach ($enabled_modules as $name => $weight) {
+        $record = $modules[$name];
+        if ($record->bootstrap) {
+          $bootstrap_list[$name] = $record;
+        }
+      }
       cache('bootstrap')->set('bootstrap_modules', $bootstrap_list);
     }
     // To avoid a separate database lookup for the filepath, prime the
     // drupal_get_filename() static cache for bootstrap modules only.
     // The rest is stored separately to keep the bootstrap module cache small.
-    foreach ($bootstrap_list as $module) {
-      drupal_classloader_register($module->name, dirname($module->filename));
-      drupal_get_filename('module', $module->name, $module->filename);
+    foreach ($bootstrap_list as $name => $module) {
+      drupal_classloader_register($name, dirname($module->filename));
+      drupal_get_filename('module', $name, $module->filename);
     }
     // We only return the module names here since module_list() doesn't need
     // the filename itself.
@@ -158,22 +168,31 @@ function system_list($type) {
       // 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) {
-        // Build a list of all enabled modules.
-        if ($record->type == 'module') {
-          $lists['module_enabled'][$record->name] = $record->name;
-        }
-        // Build a list of themes.
-        if ($record->type == 'theme') {
-          $record->info = unserialize($record->info);
-          $lists['theme'][$record->name] = $record;
-        }
+      $theme_config = config('system.theme')->get();
+      $store = KeyValueFactory::get('system.theme');
+      foreach ($store->getAll() as $name => $record) {
+        $lists['theme'][$name] = $store->get($name);
+        $status = isset($theme_config[$name]);
+        $lists['theme'][$name]->status = $status;
+        $lists['theme'][$name]->name = $name;
         // 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);
+        if ($status) {
+          $lists['filepaths'][] = array('type' => 'theme', 'name' => $name, 'filepath' => $record->filename);
         }
       }
+      $store = KeyValueFactory::get('system.module');
+      $enabled_modules = module_config()->get();
+      $modules = $store->getMultiple(array_keys($enabled_modules));
+      foreach ($enabled_modules as $name => $weight) {
+        // Build a list of all enabled modules.
+        $lists['module_enabled'][$name] = $name;
+        // Build a list of filenames so drupal_get_filename can use it.
+        $lists['filepaths'][] = array(
+          'type' => 'module',
+          'name' => $name,
+          'filepath' => $modules[$name]->filename,
+        );
+      }
       foreach ($lists['theme'] as $key => $theme) {
         if (!empty($theme->info['base theme'])) {
           // Make a list of the theme's base themes.
@@ -375,27 +394,28 @@ function module_load_all_includes($type, $name = NULL) {
  * @see hook_modules_enabled()
  */
 function module_enable($module_list, $enable_dependencies = TRUE) {
+  // Get all module data so we can find dependencies, sort and copy to the
+  // installed modules config.
+  $all_modules = system_rebuild_module_data();
   if ($enable_dependencies) {
-    // Get all module data so we can find dependencies and sort.
-    $module_data = system_rebuild_module_data();
     // Create an associative array with weights as values.
     $module_list = array_flip(array_values($module_list));
 
     while (list($module) = each($module_list)) {
-      if (!isset($module_data[$module])) {
+      if (!isset($all_modules[$module])) {
         // This module is not found in the filesystem, abort.
         return FALSE;
       }
-      if ($module_data[$module]->status) {
+      if ($all_modules[$module]->status) {
         // Skip already enabled modules.
         unset($module_list[$module]);
         continue;
       }
-      $module_list[$module] = $module_data[$module]->sort;
+      $module_list[$module] = $all_modules[$module]->sort;
 
       // Add dependencies to the list, with a placeholder weight.
       // The new modules will be processed as the while loop continues.
-      foreach (array_keys($module_data[$module]->requires) as $dependency) {
+      foreach (array_keys($all_modules[$module]->requires) as $dependency) {
         if (!isset($module_list[$dependency])) {
           $module_list[$dependency] = 0;
         }
@@ -418,25 +438,33 @@ function module_enable($module_list, $enable_dependencies = TRUE) {
   $modules_installed = array();
   $modules_enabled = array();
   foreach ($module_list as $module) {
+    $config = module_config();
     // Only process modules that are not already enabled.
-    $existing = db_query("SELECT status FROM {system} WHERE type = :type AND name = :name", array(
-      ':type' => 'module',
-      ':name' => $module))
-      ->fetchObject();
-    if ($existing->status == 0) {
+    $module_store = KeyValueFactory::get('system.module');
+    $module_data = $module_store->get($module);
+    $enabled = TRUE;
+    if (!$module_data) {
+      $enabled = FALSE;
+      $file = $all_modules[$module];
+      $module_store
+        ->set($module, (object) array(
+          'filename' => $file->uri,
+          'schema_version' => SCHEMA_UNINSTALLED,
+          'bootstrap' => 0,
+          'info' => $file->info,
+        ));
+      $config->set($module, 0);
+    }
+    elseif (!$config->get($module)) {
+      $enabled = FALSE;
+      $config->set($module, isset($module_data->weight) ? $module_data->weight : 0);
+    }
+    if (!$enabled) {
+      $config->save();
       // Load the module's code.
       drupal_load('module', $module);
       module_load_install($module);
 
-      // Update the database and module list to reflect the new module. This
-      // 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();
       // Refresh the module list to include it.
       system_list_reset();
       module_implements_reset();
@@ -542,15 +570,16 @@ function module_disable($module_list, $disable_dependents = TRUE) {
 
   $invoke_modules = array();
 
+  $store = KeyValueFactory::get('system.module');
   foreach ($module_list as $module) {
     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();
+      if ($weight = module_config()->get($module)) {
+        $module_data = $store->get($module);
+        $module_data->weight = $weight;
+        $store->set($module, $module_data);
+      }
       $invoke_modules[] = $module;
       watchdog('system', '%module module disabled.', array('%module' => $module), WATCHDOG_INFO);
     }
@@ -618,6 +647,7 @@ function module_uninstall($module_list = array(), $uninstall_dependents = TRUE)
   }
 
   $storage = drupal_container()->get('config.storage');
+  $config = module_config();
   foreach ($module_list as $module) {
     // Uninstall the module.
     module_load_install($module);
@@ -631,8 +661,10 @@ function module_uninstall($module_list = array(), $uninstall_dependents = TRUE)
     }
 
     watchdog('system', '%module module uninstalled.', array('%module' => $module), WATCHDOG_INFO);
-    drupal_set_installed_schema_version($module, SCHEMA_UNINSTALLED);
+    $config->clear($module);
   }
+  $config->save();
+  drupal_get_installed_schema_version(NULL, TRUE);
 
   if (!empty($module_list)) {
     // Call hook_module_uninstall to let other modules act
@@ -1100,3 +1132,28 @@ function drupal_alter($type, &$data, &$context1 = NULL, &$context2 = NULL) {
     $function($data, $context1, $context2);
   }
 }
+
+/**
+ * Retrieves the module list configuration object.
+ *
+ * @return Drupal\Core\Config\ModuleConfig
+ *   A configuration object.
+ */
+function module_config() {
+  return drupal_container()->get('config.factory')->get('system.module', 'Drupal\Core\Config\ModuleConfig')->load();
+}
+
+function module_set_weight($module, $weight) {
+  $config = module_config();
+  if ($config->get($module)) {
+    $config
+      ->set($module, $weight)
+      ->save();
+  }
+  else {
+    $store = KeyValueFactory::get('system.module');
+    $module_data = $store->get($module);
+    $module_data->weight = $weight;
+    $store->set($module, $module_data);
+  }
+}
\ No newline at end of file
diff --git a/core/includes/path.inc b/core/includes/path.inc
index 07aeee5..71c10a3 100644
--- a/core/includes/path.inc
+++ b/core/includes/path.inc
@@ -72,7 +72,7 @@ function drupal_lookup_path($action, $path = '', $langcode = NULL) {
 
   // Retrieve the path alias whitelist.
   if (!isset($cache['whitelist'])) {
-    $cache['whitelist'] = variable_get('path_alias_whitelist', NULL);
+    $cache['whitelist'] = state()->get('path_alias_whitelist');
     if (!isset($cache['whitelist'])) {
       $cache['whitelist'] = drupal_path_alias_whitelist_rebuild();
     }
@@ -391,7 +391,7 @@ function drupal_path_alias_whitelist_rebuild($source = NULL) {
   // When paths are inserted, only rebuild the whitelist if the system path
   // has a top level component which is not already in the whitelist.
   if (!empty($source)) {
-    $whitelist = variable_get('path_alias_whitelist', NULL);
+    $whitelist = state()->get('path_alias_whitelist');
     if (isset($whitelist[strtok($source, '/')])) {
       return $whitelist;
     }
@@ -404,7 +404,7 @@ function drupal_path_alias_whitelist_rebuild($source = NULL) {
   foreach ($result as $row) {
     $whitelist[$row->path] = TRUE;
   }
-  variable_set('path_alias_whitelist', $whitelist);
+  state()->set('path_alias_whitelist', $whitelist);
   return $whitelist;
 }
 
diff --git a/core/includes/schema.inc b/core/includes/schema.inc
index 7b0c690..022474d 100644
--- a/core/includes/schema.inc
+++ b/core/includes/schema.inc
@@ -6,6 +6,7 @@
  */
 
 use Drupal\Core\Database\Database;
+use Drupal\Core\KeyValueStore\KeyValueFactory;
 use Drupal\Core\Utility\SchemaCache;
 
 /**
@@ -173,9 +174,9 @@ function drupal_get_installed_schema_version($module, $reset = FALSE, $array = F
 
   if (!$versions) {
     $versions = array();
-    $result = db_query("SELECT name, schema_version FROM {system} WHERE type = :type", array(':type' => 'module'));
-    foreach ($result as $row) {
-      $versions[$row->name] = $row->schema_version;
+    $store = KeyValueFactory::get('system.module');
+    foreach ($store->getMultiple(array_keys(module_config()->get())) as $name => $data) {
+      $versions[$name] = $data->schema_version;
     }
   }
 
@@ -196,11 +197,10 @@ function drupal_get_installed_schema_version($module, $reset = FALSE, $array = F
  *   The new schema version.
  */
 function drupal_set_installed_schema_version($module, $version) {
-  db_update('system')
-    ->fields(array('schema_version' => $version))
-    ->condition('name', $module)
-    ->execute();
-
+  $store = KeyValueFactory::get('system.module');
+  $module_data = $store->get($module);
+  $module_data->schema_version = $version;
+  $store->set($module, $module_data);
   // Reset the static cache of module schema versions.
   drupal_get_installed_schema_version(NULL, TRUE);
 }
diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 2d1d375..bffab46 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -9,6 +9,7 @@
  */
 
 use Drupal\Core\Utility\ThemeRegistry;
+use Drupal\Core\KeyValueStore\KeyValueFactory;
 use Drupal\Core\Template\Attribute;
 
 /**
@@ -1392,17 +1393,16 @@ function theme_render_template($template_file, $variables) {
  */
 function theme_enable($theme_list) {
   drupal_clear_css_cache();
-
+  $config = config('system.theme');
   foreach ($theme_list as $key) {
-    db_update('system')
-      ->fields(array('status' => 1))
-      ->condition('type', 'theme')
-      ->condition('name', $key)
-      ->execute();
-
+    // The value is not used, it needs to be consisent with
+    // config('system.module') which uses the value for weight so set all of
+    // them to the same value. 1 looks like 'enabled' so let's use that.
+    $config->set($key, 1);
     // Install default configuration of the theme.
     config_install_default_config('theme', $key);
   }
+  $config->save();
 
   list_themes(TRUE);
   menu_router_rebuild();
@@ -1429,13 +1429,11 @@ function theme_disable($theme_list) {
 
   drupal_clear_css_cache();
 
+  $config = config('system.theme');
   foreach ($theme_list as $key) {
-    db_update('system')
-      ->fields(array('status' => 0))
-      ->condition('type', 'theme')
-      ->condition('name', $key)
-      ->execute();
+    $config->clear($key);
   }
+  $config->save();
 
   list_themes(TRUE);
   menu_router_rebuild();
diff --git a/core/includes/update.inc b/core/includes/update.inc
index 9dd8456..6f67ef6 100644
--- a/core/includes/update.inc
+++ b/core/includes/update.inc
@@ -27,17 +27,18 @@ const REQUIRED_D7_SCHEMA_VERSION = '7069';
  */
 function update_fix_compatibility() {
   $incompatible = array();
-  $result = db_query("SELECT name, type, status FROM {system} WHERE status = 1 AND type IN ('module','theme')");
-  foreach ($result as $row) {
-    if (update_check_incompatibility($row->name, $row->type)) {
-      $incompatible[] = $row->name;
+  foreach (array('module', 'theme') as $type) {
+    $config = $type == 'module' ? config("system.module", 'ModuleConfig') : config('system.theme');
+    $save = FALSE;
+    foreach ($config->get() as $name => $data) {
+      if ($data['status'] && update_check_incompatibility($name, $type)) {
+        $config->set("$name.status", 0);
+        $save = TRUE;
+      }
+    }
+    if ($save) {
+      $config->save();
     }
-  }
-  if (!empty($incompatible)) {
-    db_update('system')
-      ->fields(array('status' => 0))
-      ->condition('name', $incompatible, 'IN')
-      ->execute();
   }
 }
 
@@ -118,6 +119,7 @@ function update_prepare_d8_bootstrap() {
   // drupal_get_installed_schema_version().
   $system_schema = drupal_get_installed_schema_version('system');
   if ($system_schema < 8000) {
+    $system_schema = db_query('SELECT schema_version FROM {system} WHERE name = :system', array(':system'  => 'system'))->fetchField();
     $has_required_schema = $system_schema >= REQUIRED_D7_SCHEMA_VERSION;
     $requirements = array(
       'drupal 7 version' => array(
@@ -130,14 +132,39 @@ function update_prepare_d8_bootstrap() {
     update_extra_requirements($requirements);
 
     if ($has_required_schema) {
+      if (!db_table_exists('keyvalue')) {
+        $specs = array(
+          'description' => 'Generic key-value storage table.',
+          'fields' => array(
+            'name' => array(
+              'description' => 'The key.',
+              'type' => 'varchar',
+              'length' => 128,
+              'not null' => TRUE,
+              'default' => '',
+            ),
+            'collection' => array(
+              'description' => 'The collection of the variable.',
+              'type' => 'varchar',
+              'length' => 128,
+              'not null' => TRUE,
+              'default' => '',
+            ),
+            'value' => array(
+              'description' => 'The value.',
+              'type' => 'blob',
+              'not null' => TRUE,
+              'size' => 'big',
+              'translatable' => TRUE,
+            ),
+          ),
+          'primary key' => array('collection', 'name'),
+        );
+        db_create_table('keyvalue', $specs);
+      }
       // Bootstrap variables so we can update theme while preparing the update
       // process.
       drupal_bootstrap(DRUPAL_BOOTSTRAP_VARIABLES);
-      // Update the dynamic include paths that might be used before running the
-      // proper update functions.
-      update_prepare_stored_includes();
-      // Update the environment for the language bootstrap if needed.
-      update_prepare_d8_language();
 
       // Ensure the configuration directories exist and are writable, or create
       // them. If the directories have not been specified in settings.php and
@@ -145,6 +172,43 @@ function update_prepare_d8_bootstrap() {
       // web server, an exception will be thrown, halting the update.
       drupal_install_config_directories();
 
+      $result = db_query('SELECT * FROM {system} WHERE type = :theme OR (type = :module AND schema_version <> :schema_uninstalled)', array(
+        ':theme' => 'theme',
+        ':module' => 'module',
+        ':schema_uninstalled' => SCHEMA_UNINSTALLED,
+      ));
+      $config['module'] = module_config();
+      $config['theme'] = config('system.theme');
+      foreach ($result as $file) {
+        $file->filename = preg_replace('#^' . $file->type . 's/#', 'core/$0', $file->filename);
+        $data = array(
+          'filename' => $file->filename,
+          'name' => $file->name,
+          'status' => $file->status,
+          'info' => unserialize($file->info),
+        );
+        if ($file->type == 'theme') {
+          $data['owner'] = $file->owner;
+        }
+        else {
+          $data['bootstrap'] = $file->bootstrap;
+          $data['schema_version'] = $file->schema_version;
+          $data['weight'] = $file->weight;
+        }
+        $config[$file->type]->set($file->name, $data);
+      }
+      foreach ($config as $config_object) {
+        $config_object->save();
+      }
+      // Prime the classloader.
+      system_list('module_enabled');
+
+      // Update the dynamic include paths that might be used before running the
+      // proper update functions.
+      update_prepare_stored_includes();
+      // Update the environment for the language bootstrap if needed.
+      update_prepare_d8_language();
+
       // Change language column to langcode in url_alias.
       if (db_table_exists('url_alias') && db_field_exists('url_alias', 'language')) {
         db_drop_index('url_alias', 'alias_language_pid');
@@ -318,21 +382,21 @@ function update_module_add_to_system($modules = array()) {
     'files' => array(),
     'bootstrap' => 0,
   );
+  $config = module_config();
   foreach ($modules as $module) {
     $module_info = drupal_parse_info_file('core/modules/' . $module . '/' . $module . '.info');
-    db_insert('system')
-      ->fields(array(
-        'filename' => 'core/modules/' . $module . '/' . $module . '.module',
-        'name' => $module,
-        'type' => 'module',
-        'status' => 0,
-        'bootstrap' => 0,
-        'schema_version' => -1,
-        'weight' => 0,
-        'info' => serialize($module_info + $info_defaults),
-      ))
-      ->execute();
+    $config->set($module, array(
+      'filename' => 'core/modules/' . $module . '/' . $module . '.module',
+      'name' => $module,
+      'type' => 'module',
+      'status' => 0,
+      'bootstrap' => 0,
+      'schema_version' => SCHEMA_UNINSTALLED,
+      'weight' => 0,
+      'info' => $module_info + $info_defaults,
+    ));
   }
+  $config->save();
 }
 
 /**
@@ -357,6 +421,7 @@ function update_fix_d8_requirements() {
  * Helper function to install a new module in Drupal 8 via hook_update_N().
  */
 function update_module_enable(array $modules) {
+  $config = module_config();
   foreach ($modules as $module) {
     // Check for initial schema and install it. The schema version of a newly
     // installed module is always 0. Using 8000 here would be inconsistent
@@ -371,11 +436,10 @@ function update_module_enable(array $modules) {
     }
     // Change the schema version from SCHEMA_UNINSTALLED to 0, so any module
     // updates since the module's inception are executed in a core upgrade.
-    db_update('system')
-      ->condition('type', 'module')
-      ->condition('name', $module)
-      ->fields(array('schema_version' => 0, 'status' => 1))
-      ->execute();
+    $data = $config->get($module);
+    $data['schema_version'] = 0;
+    $data['status'] = 1;
+    $config->set($module, $data);
 
     // system_list_reset() is in module.inc but that would only be available
     // once the variable bootstrap is done.
@@ -383,6 +447,7 @@ function update_module_enable(array $modules) {
     system_list_reset();
     //  @todo: figure out what to do about hook_install() and hook_enable().
   }
+  $config->save();
 }
 
 /**
@@ -910,8 +975,7 @@ function update_retrieve_dependencies() {
   $return = array();
   // Get a list of installed modules, arranged so that we invoke their hooks in
   // the same order that module_invoke_all() does.
-  $modules = db_query("SELECT name FROM {system} WHERE type = 'module' AND schema_version <> :schema ORDER BY weight ASC, name ASC", array(':schema' => SCHEMA_UNINSTALLED))->fetchCol();
-  foreach ($modules as $module) {
+  foreach (config('system.module')->get() as $module => $data) {
     $function = $module . '_update_dependencies';
     if (function_exists($function)) {
       $result = $function();
diff --git a/core/lib/Drupal/Core/Config/Config.php b/core/lib/Drupal/Core/Config/Config.php
index 538ab6d..adf74fa 100644
--- a/core/lib/Drupal/Core/Config/Config.php
+++ b/core/lib/Drupal/Core/Config/Config.php
@@ -64,6 +64,9 @@ class Config {
    */
   protected $eventDispatcher;
 
+
+  protected $sorted = FALSE;
+
   /**
    * Constructs a configuration object.
    *
@@ -310,13 +313,19 @@ class Config {
    * Saves the configuration object.
    */
   public function save() {
-    $this->sortByKey($this->data);
+    if (!$this->sorted) {
+      $this->sortByKey($this->data);
+    }
     $this->storage->write($this->name, $this->data);
     $this->isNew = FALSE;
     $this->notify('save');
     return $this;
   }
 
+  public function sorted() {
+    $this->sorted = TRUE;
+  }
+
   /*
    * Renames the configuration object.
    *
diff --git a/core/lib/Drupal/Core/Config/ConfigFactory.php b/core/lib/Drupal/Core/Config/ConfigFactory.php
index ca36ce7..318deda 100644
--- a/core/lib/Drupal/Core/Config/ConfigFactory.php
+++ b/core/lib/Drupal/Core/Config/ConfigFactory.php
@@ -57,11 +57,13 @@ class ConfigFactory {
    *
    * @param string $name
    *   The name of the configuration object to construct.
+   * @param $class_name
+   *   Optional. The name of the class handling this configuration object.
    *
    * @return Drupal\Core\Config\Config
    *   A configuration object with the given $name.
    */
-  public function get($name) {
+  public function get($name, $class_name = 'Drupal\Core\Config\Config') {
     global $conf;
 
     // @todo Caching the instantiated objects per name might cut off a fair
@@ -82,7 +84,7 @@ class ConfigFactory {
     // @todo The decrease of CPU time is interesting, since that means that
     //   ContainerBuilder involves plenty of function calls (which are known to
     //   be slow in PHP).
-    $config = new Config($name, $this->storage, $this->eventDispatcher);
+    $config = new $class_name($name, $this->storage, $this->eventDispatcher);
     return $config->init();
   }
 
diff --git a/core/lib/Drupal/Core/Config/ModuleConfig.php b/core/lib/Drupal/Core/Config/ModuleConfig.php
new file mode 100644
index 0000000..e326af4
--- /dev/null
+++ b/core/lib/Drupal/Core/Config/ModuleConfig.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * @file
+ * Definition of Drupal\Core\Config\ModuleConfig.
+ */
+
+namespace Drupal\Core\Config;
+
+/**
+ * Defines the module configuration object.
+ */
+class ModuleConfig extends Config {
+
+  public function save() {
+    asort($this->data);
+    $this->storage->write($this->name, $this->data);
+    $this->isNew = FALSE;
+    $this->notify('save');
+    return $this;
+  }
+}
diff --git a/core/lib/Drupal/Core/KeyValueStore/AbstractStorage.php b/core/lib/Drupal/Core/KeyValueStore/AbstractStorage.php
new file mode 100644
index 0000000..408b9a8
--- /dev/null
+++ b/core/lib/Drupal/Core/KeyValueStore/AbstractStorage.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * @file
+ * Contains KeyValueStore\Storage\AbstracteBackend.
+ */
+
+namespace Drupal\Core\KeyValueStore;
+
+abstract class AbstractStorage implements KeyValueStoreInterface {
+
+  /**
+   * @var string
+   */
+  protected $collection;
+
+  /**
+   * Implements KeyValueStore\Storage\StorageInterface::__construct().
+   */
+  public function __construct($collection, array $options = array()) {
+    $this->collection = $collection;
+  }
+
+  /**
+   * Implements KeyValueStore\Storage\StorageInterface::getCollectionName().
+   */
+  public function getCollectionName() {
+    return $this->collection;
+  }
+
+  /**
+   * Implements KeyValueStore\Storage\StorageInterface::get().
+   */
+  public function get($key) {
+    $values = $this->getMultiple(array($key));
+    return reset($values);
+  }
+
+  /**
+   * Implements KeyValueStore\Storage\StorageInterface::setMultiple().
+   */
+  public function setMultiple(array $data) {
+    foreach ($data as $key => $value) {
+      $this->set($key, $value);
+    }
+  }
+
+  /**
+   * Implements KeyValueStore\Storage\StorageInterface::delete().
+   */
+  public function delete($key) {
+    $this->deleteMultiple(array($key));
+  }
+
+}
diff --git a/core/lib/Drupal/Core/KeyValueStore/DatabaseStorage.php b/core/lib/Drupal/Core/KeyValueStore/DatabaseStorage.php
new file mode 100644
index 0000000..de49f78
--- /dev/null
+++ b/core/lib/Drupal/Core/KeyValueStore/DatabaseStorage.php
@@ -0,0 +1,89 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\KeyValueStore\DatabaseBackend.
+ */
+
+namespace Drupal\Core\KeyValueStore;
+
+/**
+ * Defines a default key/value store implementation.
+ *
+ * This is Drupal's default key/value store implementation. It uses the database to store
+ * key/value data.
+ */
+class DatabaseStorage extends AbstractStorage {
+
+  /**
+   * Overrides KeyValueStore\Storage\AbstractStorage::__construct().
+   */
+  public function __construct($collection, array $options = array()) {
+    parent::__construct($collection, $options);
+    $this->table = isset($options['table']) ? $options['table'] : 'keyvalue';
+  }
+
+  /**
+   * Implements KeyValueStore\Storage\StorageInterface::getMultiple().
+   */
+  public function getMultiple(array $keys) {
+    try {
+      $result = db_query('SELECT name, value FROM {' . db_escape_table($this->table) . '} WHERE name IN (:keys) AND collection = :collection', array(':keys' => $keys, ':collection' => $this->collection))->fetchAllAssoc('name');
+      $values = array();
+      foreach ($keys as $key) {
+        if (isset($result[$key]) && ($value = unserialize($result[$key]->value))) {
+          $values[$key] = $value;
+        }
+      }
+      return $values;
+    }
+    catch (\Exception $e) {
+      // If the database is never going to be available, key/value requests should
+      // return FALSE in order to allow exception handling to occur.
+      return array();
+    }
+  }
+
+  /**
+   * Implements KeyValueStore\Storage\StorageInterface::getAll().
+   */
+  public function getAll() {
+    $result = db_query('SELECT name, value FROM {' . db_escape_table($this->table) . '} WHERE collection = :collection', array(':collection' => $this->collection));
+    $values = array();
+
+    foreach ($result as $item) {
+      if ($item) {
+        $values[$item->name] = unserialize($item->value);
+      }
+    }
+    return $values;
+  }
+
+  /**
+   * Implements KeyValueStore\Storage\StorageInterface::set().
+   */
+  public function set($key, $value) {
+    db_merge($this->table)
+      ->key(array('name' => $key))
+      ->fields(array(
+        'collection' => $this->collection,
+        'value' => serialize($value),
+      ))
+      ->execute();
+  }
+
+  /**
+   * Implements KeyValueStore\Storage\StorageInterface::deleteMultiple().
+   */
+  public function deleteMultiple(array $keys) {
+    // Delete in chunks when a large array is passed.
+    do {
+      db_delete($this->table)
+        ->condition('name', array_splice($keys, 0, 1000))
+        ->condition('collection', $this->collection)
+        ->execute();
+    }
+    while (count($keys));
+  }
+
+}
diff --git a/core/lib/Drupal/Core/KeyValueStore/KeyValueFactory.php b/core/lib/Drupal/Core/KeyValueStore/KeyValueFactory.php
new file mode 100644
index 0000000..9536c97
--- /dev/null
+++ b/core/lib/Drupal/Core/KeyValueStore/KeyValueFactory.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Contains Drupal\Core\KeyValueStore\KeyValueFactory
+ */
+
+namespace Drupal\Core\KeyValueStore;
+
+class KeyValueFactory {
+
+  /**
+   * @param string $collection
+   * @param string $class_name
+   * @return Drupal\Core\KeyValueStore\KeyValueStoreInterface
+   */
+  static function get($collection, $class_name = 'Drupal\Core\KeyValueStore\DatabaseStorage') {
+    return new $class_name($collection);
+  }
+}
diff --git a/core/lib/Drupal/Core/KeyValueStore/KeyValueStoreInterface.php b/core/lib/Drupal/Core/KeyValueStore/KeyValueStoreInterface.php
new file mode 100644
index 0000000..d4d7b6c
--- /dev/null
+++ b/core/lib/Drupal/Core/KeyValueStore/KeyValueStoreInterface.php
@@ -0,0 +1,98 @@
+<?php
+
+/**
+ * @file
+ * Contains KeyValueStore\Storage\StorageInterface.
+ */
+
+namespace Drupal\Core\KeyValueStore;
+
+
+/**
+ * Defines the interface for key/value store implementations.
+ */
+interface KeyValueStoreInterface {
+  /**
+   * Constructs a new key/value collection.
+   *
+   * @param string $collection
+   *   The collection for which the object is created.
+   * @param array $options
+   *   An associative array of options for the key/value storage collection.
+   */
+  public function __construct($collection, array $options = array());
+
+  /**
+   * Returns the name of this collection.
+   *
+   * @return string
+   *   The name of this collection.
+   */
+  public function getCollectionName();
+
+  /**
+   * Returns the stored value for a given key.
+   *
+   * @param $key
+   *   The key of the data to retrieve.
+   *
+   * @return mixed
+   *   The stored value, or FALSE if no value exists.
+   */
+  public function get($key);
+
+  /**
+   * Returns the stored key/value pairs for a given set of keys.
+   *
+   * @param array $keys
+   *   A list of keys to retrieve.
+   *
+   * @return array
+   *   An associative array of items successfully returned, indexed by key.
+   *   @todo What's returned for non-existing keys?
+   */
+  public function getMultiple(array $keys);
+
+  /**
+   * Returns all stored key/value pairs in the collection.
+   *
+   * @return array
+   *   An associative array containing all stored items in the collection.
+   */
+  public function getAll();
+
+  /**
+   * Saves a value for a given key.
+   *
+   * @param string $key
+   *   The key of the data to store.
+   * @param mixed $value
+   *   The data to store.
+   */
+  public function set($key, $value);
+
+  /**
+   * Saves key/value pairs.
+   *
+   * @param array $data
+   *   An associative array of key/value pairs.
+   */
+  public function setMultiple(array $data);
+
+  /**
+   * Deletes an item from the key/value store.
+   *
+   * @param string $key
+   *   The item name to delete.
+   */
+  public function delete($key);
+
+  /**
+   * Deletes multiple items from the key/value store.
+   *
+   * @param array $keys
+   *   A list of item names to delete.
+   */
+  public function deleteMultiple(array $keys);
+
+}
diff --git a/core/lib/Drupal/Core/KeyValueStore/MemoryStorage.php b/core/lib/Drupal/Core/KeyValueStore/MemoryStorage.php
new file mode 100644
index 0000000..b53722b
--- /dev/null
+++ b/core/lib/Drupal/Core/KeyValueStore/MemoryStorage.php
@@ -0,0 +1,97 @@
+<?php
+
+/**
+ * @file
+ * Contains KeyValueStore\Storage\MemoryStorage.
+ */
+
+namespace Drupal\Core\KeyValueStore;
+
+/**
+ * Defines a default key/value store implementation.
+ *
+ * For speed reasons, this class does not use the AbstractStorage generic
+ * implementation.
+ */
+class MemoryStorage implements KeyValueStoreInterface {
+
+  /**
+   * @var array
+   */
+  protected $data = array();
+
+  /**
+   * Implements KeyValueStore\Storage\StorageInterface::__construct().
+   */
+  public function __construct($collection, array $options = array()) {
+    $this->collection = $collection;
+  }
+
+  /**
+   * Implements KeyValueStore\Storage\StorageInterface::getCollectionName().
+   */
+  public function getCollectionName() {
+    return $this->collection;
+  }
+
+  /**
+   * Implements KeyValueStore\Storage\StorageInterface::get().
+   */
+  public function get($key) {
+    return isset($this->data[$key]) ? $this->data[$key] : FALSE;
+  }
+
+  /**
+   * Implements KeyValueStore\Storage\StorageInterface::getMultiple().
+   */
+  public function getMultiple(array $keys) {
+    $results = array();
+    // Foreach only needs to traverse $keys once, the PHP implementation
+    // array_intersect_key(array_flip(array_values($keys)), $this->data);
+    // would be slower.
+    foreach ($keys as $key) {
+      if (isset($this->data[$key])) {
+        $results[$key] = $this->data[$key];
+      }
+    }
+    return $results;
+  }
+
+  /**
+   * Implements KeyValueStore\Storage\StorageInterface::getAll().
+   */
+  public function getAll() {
+    return $this->data;
+  }
+
+  /**
+   * Implements KeyValueStore\Storage\StorageInterface::set().
+   */
+  public function set($key, $value) {
+    $this->data[$key] = $value;
+  }
+
+  /**
+   * Implements KeyValueStore\Storage\StorageInterface::setMultiple().
+   */
+  public function setMultiple(array $data) {
+    $this->data = $data + $this->data;
+  }
+
+  /**
+   * Implements KeyValueStore\Storage\StorageInterface::delete().
+   */
+  public function delete($key) {
+    unset($this->data[$key]);
+  }
+
+  /**
+   * Implements KeyValueStore\Storage\StorageInterface::deleteMultiple().
+   */
+  public function deleteMultiple(array $keys) {
+    foreach ($keys as $key) {
+      unset($this->data[$key]);
+    }
+  }
+
+}
diff --git a/core/modules/block/block.install b/core/modules/block/block.install
index 4c5149b..36854ea 100644
--- a/core/modules/block/block.install
+++ b/core/modules/block/block.install
@@ -213,14 +213,10 @@ function block_schema() {
  * Implements hook_install().
  */
 function block_install() {
-
   // Block should go first so that other modules can alter its output
   // during hook_page_alter(). Almost everything on the page is a block,
   // so before block module runs, there will not be much to alter.
-  db_update('system')
-    ->fields(array('weight' => -5))
-    ->condition('name', 'block')
-    ->execute();
+  module_set_weight('block', -5);
 }
 
 /**
diff --git a/core/modules/block/block.module b/core/modules/block/block.module
index 0626c08..7b67116 100644
--- a/core/modules/block/block.module
+++ b/core/modules/block/block.module
@@ -961,9 +961,8 @@ function block_rebuild() {
   // Rehash blocks for active themes. We don't use list_themes() here,
   // because if MAINTENANCE_MODE is defined it skips reading the database,
   // and we can't tell which themes are active.
-  $themes = db_query("SELECT name FROM {system} WHERE type = 'theme' AND status = 1");
-  foreach ($themes as $theme) {
-    _block_rehash($theme->name);
+  foreach (config('system.theme')->get() as $name => $weight) {
+    _block_rehash($name);
   }
 }
 
diff --git a/core/modules/color/lib/Drupal/color/Tests/ColorTest.php b/core/modules/color/lib/Drupal/color/Tests/ColorTest.php
index 8902d4c..0c8c2a2 100644
--- a/core/modules/color/lib/Drupal/color/Tests/ColorTest.php
+++ b/core/modules/color/lib/Drupal/color/Tests/ColorTest.php
@@ -108,7 +108,7 @@ class ColorTest extends WebTestBase {
     $config->set('preprocess.css', 1);
     $config->save();
     $this->drupalGet('<front>');
-    $stylesheets = variable_get('drupal_css_cache_files', array());
+    $stylesheets = state()->get('drupal_css_cache_files') ?: array();
     $stylesheet_content = '';
     foreach ($stylesheets as $key => $uri) {
       $stylesheet_content .= join("\n", file(drupal_realpath($uri)));
diff --git a/core/modules/contact/contact.pages.inc b/core/modules/contact/contact.pages.inc
index 92d73bc..08c1d12 100644
--- a/core/modules/contact/contact.pages.inc
+++ b/core/modules/contact/contact.pages.inc
@@ -79,22 +79,21 @@ function contact_site_form($form, &$form_state) {
     '#required' => TRUE,
   );
 
-  // Do not allow authenticated usrs to alter the name or e-mail values to
+  // Do not allow authenticated users to alter the name or e-mail values to
   // prevent the impersonation of other users.
-  if ($user->uid){
-    // Change form elements to values.
-    $form['name']['#type'] = $form['mail']['#type'] = 'value';
-
-    // Display read-only name and e-mail address to the user.
+  if ($user->uid) {
+    // Hide the original name and e-mail address fields and display read-only
+    // versions in their place.
+    $form['name']['#access'] = $form['mail']['#access'] = FALSE;
     $form['name_display'] = array(
       '#type' => 'item',
       '#title' => t('Your name'),
-      '#markup' => user_format_name($user),
+      '#markup' => $form['name']['#default_value'],
     );
     $form['mail_display'] = array(
       '#type' => 'item',
       '#title' => t('Your e-mail address'),
-      '#markup' => $user->mail,
+      '#markup' => $form['mail']['#default_value'],
     );
   }
   $form['subject'] = array(
@@ -158,9 +157,9 @@ function contact_site_form_submit($form, &$form_state) {
   $values['sender']->mail = $values['mail'];
   $values['category'] = contact_load($values['cid']);
 
-  // Save the anonymous user information to a cookie for reuse.
   if (!$user->uid) {
-    $values['sender']->name .= ' (' . t('Unverified') . ')';
+    $values['sender']->name .= ' (' . t('not verified') . ')';
+    // Save the anonymous user information to a cookie for reuse.
     user_cookie_save(array_intersect_key($values, array_flip(array('name', 'mail'))));
   }
 
@@ -237,20 +236,19 @@ function contact_personal_form($form, &$form_state, $recipient) {
   );
   // Do not allow authenticated users to alter the name or e-mail values to
   // prevent the impersonation of other users.
-  if ($user->uid){
-    // Change form elements to values.
-    $form['name']['#type'] = $form['mail']['#type'] = 'value';
-
-    // Display read-only name and e-mail address to the user.
+  if ($user->uid) {
+    // Hide the original name and e-mail address fields and display read-only
+    // versions in their place.
+    $form['name']['#access'] = $form['mail']['#access'] = FALSE;
     $form['name_display'] = array(
       '#type' => 'item',
       '#title' => t('Your name'),
-      '#markup' => user_format_name($user),
+      '#markup' => $form['name']['#default_value'],
     );
     $form['mail_display'] = array(
       '#type' => 'item',
       '#title' => t('Your e-mail address'),
-      '#markup' => $user->mail,
+      '#markup' => $form['mail']['#default_value'],
     );
   }
   $form['to'] = array(
@@ -299,9 +297,9 @@ function contact_personal_form_submit($form, &$form_state) {
   $values['sender']->name = $values['name'];
   $values['sender']->mail = $values['mail'];
 
-  // Save the anonymous user information to a cookie for reuse.
   if (!$user->uid) {
-    $values['sender']->name .= ' (' . t('Unverified') . ')';
+    $values['sender']->name .= ' (' . t('not verified') . ')';
+    // Save the anonymous user information to a cookie for reuse.
     user_cookie_save(array_intersect_key($values, array_flip(array('name', 'mail'))));
   }
 
diff --git a/core/modules/field/field.api.php b/core/modules/field/field.api.php
index 1f76def..7364d4f 100644
--- a/core/modules/field/field.api.php
+++ b/core/modules/field/field.api.php
@@ -1551,7 +1551,7 @@ function hook_field_available_languages_alter(&$langcodes, $context) {
 function hook_field_attach_create_bundle($entity_type, $bundle) {
   // When a new bundle is created, the menu needs to be rebuilt to add the
   // Field UI menu item tabs.
-  variable_set('menu_rebuild_needed', TRUE);
+  state()->set('menu_rebuild_needed', TRUE);
 }
 
 /**
diff --git a/core/modules/field/tests/modules/field_test/field_test.install b/core/modules/field/tests/modules/field_test/field_test.install
index 5957561..eacc0d8 100644
--- a/core/modules/field/tests/modules/field_test/field_test.install
+++ b/core/modules/field/tests/modules/field_test/field_test.install
@@ -10,10 +10,7 @@
  */
 function field_test_install() {
   // hook_entity_info_alter() needs to be executed as last.
-  db_update('system')
-    ->fields(array('weight' => 1))
-    ->condition('name', 'field_test')
-    ->execute();
+  module_set_weight('field_test.weight', 1);
 }
 
 /**
diff --git a/core/modules/field_ui/field_ui.admin.inc b/core/modules/field_ui/field_ui.admin.inc
index 29d586e..bb99234 100644
--- a/core/modules/field_ui/field_ui.admin.inc
+++ b/core/modules/field_ui/field_ui.admin.inc
@@ -1175,31 +1175,34 @@ function field_ui_display_overview_form($form, &$form_state, $entity_type, $bund
 
   // Custom display settings.
   if ($view_mode == 'default') {
-    $form['modes'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('Custom display settings'),
-      '#collapsible' => TRUE,
-      '#collapsed' => TRUE,
-    );
-    // Collect options and default values for the 'Custom display settings'
-    // checkboxes.
-    $options = array();
-    $default = array();
     $entity_info = entity_get_info($entity_type);
     $view_modes = $entity_info['view modes'];
-    $view_mode_settings = field_view_mode_settings($entity_type, $bundle);
-    foreach ($view_modes as $view_mode_name => $view_mode_info) {
-      $options[$view_mode_name] = $view_mode_info['label'];
-      if (!empty($view_mode_settings[$view_mode_name]['custom_settings'])) {
-        $default[] = $view_mode_name;
+    // Only show the settings if there is more than one view mode.
+    if (count($view_modes) > 1) {
+      $form['modes'] = array(
+        '#type' => 'fieldset',
+        '#title' => t('Custom display settings'),
+        '#collapsible' => TRUE,
+        '#collapsed' => TRUE,
+      );
+      // Collect options and default values for the 'Custom display settings'
+      // checkboxes.
+      $options = array();
+      $default = array();
+      $view_mode_settings = field_view_mode_settings($entity_type, $bundle);
+      foreach ($view_modes as $view_mode_name => $view_mode_info) {
+        $options[$view_mode_name] = $view_mode_info['label'];
+        if (!empty($view_mode_settings[$view_mode_name]['custom_settings'])) {
+          $default[] = $view_mode_name;
+        }
       }
+      $form['modes']['view_modes_custom'] = array(
+        '#type' => 'checkboxes',
+        '#title' => t('Use custom display settings for the following view modes'),
+        '#options' => $options,
+        '#default_value' => $default,
+      );
     }
-    $form['modes']['view_modes_custom'] = array(
-      '#type' => 'checkboxes',
-      '#title' => t('Use custom display settings for the following view modes'),
-      '#options' => $options,
-      '#default_value' => $default,
-    );
   }
 
   // In overviews involving nested rows from contributed modules (i.e
diff --git a/core/modules/field_ui/field_ui.module b/core/modules/field_ui/field_ui.module
index bde3f35..63cf18b 100644
--- a/core/modules/field_ui/field_ui.module
+++ b/core/modules/field_ui/field_ui.module
@@ -309,7 +309,7 @@ function field_ui_element_info() {
 function field_ui_field_attach_create_bundle($entity_type, $bundle) {
   // When a new bundle is created, the menu needs to be rebuilt to add our
   // menu item tabs.
-  variable_set('menu_rebuild_needed', TRUE);
+  state()->set('menu_rebuild_needed', TRUE);
 }
 
 /**
diff --git a/core/modules/forum/forum.install b/core/modules/forum/forum.install
index 8e6fddf..5db4e63 100644
--- a/core/modules/forum/forum.install
+++ b/core/modules/forum/forum.install
@@ -10,10 +10,7 @@
  */
 function forum_install() {
   // Set the weight of the forum.module to 1 so it is loaded after the taxonomy.module.
-  db_update('system')
-    ->fields(array('weight' => 1))
-    ->condition('name', 'forum')
-    ->execute();
+  module_set_weight('forum.weight', 1);
   // Forum topics are published by default, but do not have any other default
   // options set (for example, they are not promoted to the front page).
   // @todo Convert to default module configuration, once Node module's content
diff --git a/core/modules/help/lib/Drupal/help/Tests/HelpTest.php b/core/modules/help/lib/Drupal/help/Tests/HelpTest.php
index 8404d85..72af556 100644
--- a/core/modules/help/lib/Drupal/help/Tests/HelpTest.php
+++ b/core/modules/help/lib/Drupal/help/Tests/HelpTest.php
@@ -8,6 +8,7 @@
 namespace Drupal\help\Tests;
 
 use Drupal\simpletest\WebTestBase;
+use Drupal\Component\ArraySelect;
 
 /**
  * Tests help display and user access for all modules implementing help.
@@ -107,11 +108,12 @@ class HelpTest extends WebTestBase {
    */
   protected function getModuleList() {
     $modules = array();
-    $result = db_query("SELECT name, filename, info FROM {system} WHERE type = 'module' AND status = 1 ORDER BY weight ASC, filename ASC");
-    foreach ($result as $module) {
-      if (file_exists($module->filename) && function_exists($module->name . '_help')) {
-        $fullname = unserialize($module->info);
-        $modules[$module->name] = $fullname['name'];
+    $result = ArraySelect::select(config('system.module')->get())
+      ->condition('status', 1)
+      ->execute();
+    foreach ($result as $module => $data) {
+      if (file_exists($data->filename) && function_exists($module . '_help')) {
+        $modules[$module] = $data->info['name'];
       }
     }
     return $modules;
diff --git a/core/modules/image/image.module b/core/modules/image/image.module
index ccdc879..491c100 100644
--- a/core/modules/image/image.module
+++ b/core/modules/image/image.module
@@ -253,7 +253,7 @@ function image_form_system_file_system_settings_alter(&$form, &$form_state) {
  */
 function image_system_file_system_settings_submit($form, &$form_state) {
   if ($form['file_public_path']['#default_value'] !== $form_state['values']['file_public_path']) {
-    variable_set('menu_rebuild_needed', TRUE);
+    state()->set('menu_rebuild_needed', TRUE);
   }
 }
 
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 7add837..adb2003 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -2745,7 +2745,7 @@ function node_search_validate($form, &$form_state) {
 
   // Insert extra restrictions into the search keywords string.
   if (isset($form_state['values']['type']) && is_array($form_state['values']['type'])) {
-    // Retrieve selected types - Forms API sets the value of unselected
+    // Retrieve selected types - Form API sets the value of unselected
     // checkboxes to 0.
     $form_state['values']['type'] = array_filter($form_state['values']['type']);
     if (count($form_state['values']['type'])) {
diff --git a/core/modules/search/search.admin.inc b/core/modules/search/search.admin.inc
index 9168510..57e5d6b 100644
--- a/core/modules/search/search.admin.inc
+++ b/core/modules/search/search.admin.inc
@@ -175,7 +175,7 @@ function search_admin_settings_submit($form, &$form_state) {
   if ($config->get('active_modules') != $new_modules) {
     $config->set('active_modules', $new_modules);
     drupal_set_message(t('The active search modules have been changed.'));
-    variable_set('menu_rebuild_needed', TRUE);
+    state()->set('menu_rebuild_needed', TRUE);
   }
   $config->save();
 }
diff --git a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
index 10501d0..27048ee 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
@@ -661,12 +661,7 @@ abstract class WebTestBase extends TestBase {
     }
 
     // Run the profile tasks.
-    $install_profile_module_exists = db_query("SELECT 1 FROM {system} WHERE type = 'module' AND name = :name", array(
-      ':name' => $this->profile,
-    ))->fetchField();
-    if ($install_profile_module_exists) {
-      module_enable(array($this->profile), FALSE);
-    }
+    module_enable(array($this->profile), FALSE);
 
     // Create a new DrupalKernel for testing purposes, now that all required
     // modules have been enabled. This also stores a new dependency injection
diff --git a/core/modules/simpletest/simpletest.module b/core/modules/simpletest/simpletest.module
index f216339..49b1e9f 100644
--- a/core/modules/simpletest/simpletest.module
+++ b/core/modules/simpletest/simpletest.module
@@ -1,6 +1,7 @@
 <?php
 
 use Drupal\Core\Database\Database;
+use Drupal\Component\ArraySelect;
 use Drupal\simpletest\TestBase;
 
 /**
@@ -313,7 +314,8 @@ function simpletest_test_get_all() {
   if (!$groups) {
     // Make sure that namespaces for disabled modules are registered so that the
     // checks below will find them.
-    simpletest_classloader_register();
+    $module_data = system_rebuild_module_data();
+    simpletest_classloader_register($module_data);
 
     // Load test information from cache if available, otherwise retrieve the
     // information from each tests getInfo() method.
@@ -323,16 +325,16 @@ function simpletest_test_get_all() {
     else {
       // Select all PSR-0 classes in the Tests namespace of all modules.
       $classes = array();
-      $system_list = db_query("SELECT name, filename FROM {system}")->fetchAllKeyed();
 
-      foreach ($system_list as $name => $filename) {
+      foreach ($module_data as $name => $data) {
+        $dirname = dirname($data->filename);
         // Build directory in which the test files would reside.
-        $tests_dir = DRUPAL_ROOT . '/' . dirname($filename) . '/lib/Drupal/' . $name . '/Tests';
+        $tests_dir = DRUPAL_ROOT . '/' . $dirname . '/lib/Drupal/' . $name . '/Tests';
         // Scan it for test files if it exists.
         if (is_dir($tests_dir)) {
           $files = file_scan_directory($tests_dir, '/.*\.php/');
           if (!empty($files)) {
-            $basedir = DRUPAL_ROOT . '/' . dirname($filename) . '/lib/';
+            $basedir = DRUPAL_ROOT . '/' . $dirname . '/lib/';
             foreach ($files as $file) {
               // Convert the file name into the namespaced class name.
               $replacements = array(
@@ -357,7 +359,7 @@ function simpletest_test_get_all() {
           // If this test class requires a non-existing module, skip it.
           if (!empty($info['dependencies'])) {
             foreach ($info['dependencies'] as $module) {
-              if (!drupal_get_filename('module', $module)) {
+              if (!isset($module_data[$module])) {
                 continue 2;
               }
             }
@@ -384,12 +386,13 @@ function simpletest_test_get_all() {
 /**
  * Registers namespaces for disabled modules.
  */
-function simpletest_classloader_register() {
-  // Get the cached test modules list and register a test namespace for each.
-  $disabled_modules = db_query("SELECT name, filename FROM {system} WHERE status = 0")->fetchAllKeyed();
-  if ($disabled_modules) {
-    foreach ($disabled_modules as $name => $filename) {
-      drupal_classloader_register($name, dirname($filename));
+function simpletest_classloader_register($module_data = NULL) {
+  if (!$module_data) {
+    $module_data = system_rebuild_module_data();
+  }
+  foreach ($module_data as $name => $data) {
+    if (!$data->status) {
+      drupal_classloader_register($name, dirname($data->filename));
     }
   }
 }
diff --git a/core/modules/system/lib/Drupal/system/Tests/Actions/LoopTest.php b/core/modules/system/lib/Drupal/system/Tests/Actions/LoopTest.php
index 86d99f9..8bfd9bb 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Actions/LoopTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Actions/LoopTest.php
@@ -67,7 +67,6 @@ class LoopTest extends WebTestBase {
     $expected[] = 'Stack overflow: too many calls to actions_do(). Aborting to prevent infinite recursion.';
 
     $result = db_query("SELECT message FROM {watchdog} WHERE type = 'actions_loop_test' OR type = 'actions' ORDER BY wid");
-    $loop_started = FALSE;
     foreach ($result as $row) {
       $expected_message = array_shift($expected);
       $this->assertEqual($row->message, $expected_message, t('Expected message %expected, got %message.', array('%expected' => $expected_message, '%message' => $row->message)));
diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php
index ba7a48b..f72d384 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php
@@ -346,11 +346,11 @@ class JavaScriptTest extends WebTestBase {
     ));
 
     // Store the expected key for the first item in the cache.
-    $cache = array_keys(variable_get('drupal_js_cache_files', array()));
+    $cache = array_keys(state()->get('drupal_js_cache_files') ?: array());
     $expected_key = $cache[0];
 
     // Reset variables and add a file in a different scope first.
-    variable_del('drupal_js_cache_files');
+    state()->delete('drupal_js_cache_files');
     drupal_static_reset('drupal_add_js');
     drupal_add_library('system', 'drupal');
     drupal_add_js('some/custom/javascript_file.js', array('scope' => 'footer'));
@@ -365,7 +365,7 @@ class JavaScriptTest extends WebTestBase {
     ));
 
     // Compare the expected key for the first file to the current one.
-    $cache = array_keys(variable_get('drupal_js_cache_files', array()));
+    $cache = array_keys(state()->get('drupal_js_cache_files') ?: array());
     $key = $cache[0];
     $this->assertEqual($key, $expected_key, 'JavaScript aggregation is not affected by ordering in different scopes.');
   }
diff --git a/core/modules/system/lib/Drupal/system/Tests/Database/RangeQueryTest.php b/core/modules/system/lib/Drupal/system/Tests/Database/RangeQueryTest.php
index 91d6c97..b92e5ce 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Database/RangeQueryTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Database/RangeQueryTest.php
@@ -34,11 +34,11 @@ class RangeQueryTest extends WebTestBase {
    */
   function testRangeQuery() {
     // Test if return correct number of rows.
-    $range_rows = db_query_range("SELECT name FROM {system} ORDER BY name", 2, 3)->fetchAll();
+    $range_rows = db_query_range("SELECT name FROM {variable} ORDER BY name", 2, 3)->fetchAll();
     $this->assertEqual(count($range_rows), 3, t('Range query work and return correct number of rows.'));
 
     // Test if return target data.
-    $raw_rows = db_query('SELECT name FROM {system} ORDER BY name')->fetchAll();
+    $raw_rows = db_query('SELECT name FROM {variable} ORDER BY name')->fetchAll();
     $raw_rows = array_slice($raw_rows, 2, 3);
     $this->assertEqual($range_rows, $raw_rows, t('Range query work and return target data.'));
   }
diff --git a/core/modules/system/lib/Drupal/system/Tests/Database/TemporaryQueryTest.php b/core/modules/system/lib/Drupal/system/Tests/Database/TemporaryQueryTest.php
index 24a61fa..42a70c0 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Database/TemporaryQueryTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Database/TemporaryQueryTest.php
@@ -43,7 +43,7 @@ class TemporaryQueryTest extends WebTestBase {
     $this->drupalGet('database_test/db_query_temporary');
     $data = json_decode($this->drupalGetContent());
     if ($data) {
-      $this->assertEqual($this->countTableRows("system"), $data->row_count, t('The temporary table contains the correct amount of rows.'));
+      $this->assertEqual($this->countTableRows("variable"), $data->row_count, t('The temporary table contains the correct amount of rows.'));
       $this->assertFalse(db_table_exists($data->table_name), t('The temporary table is, indeed, temporary.'));
     }
     else {
@@ -51,10 +51,10 @@ class TemporaryQueryTest extends WebTestBase {
     }
 
     // Now try to run two db_query_temporary() in the same request.
-    $table_name_system = db_query_temporary('SELECT status FROM {system}', array());
+    $table_name_system = db_query_temporary('SELECT name FROM {variable}', array());
     $table_name_users = db_query_temporary('SELECT uid FROM {users}', array());
 
-    $this->assertEqual($this->countTableRows($table_name_system), $this->countTableRows("system"), t('A temporary table was created successfully in this request.'));
+    $this->assertEqual($this->countTableRows($table_name_system), $this->countTableRows("variable"), t('A temporary table was created successfully in this request.'));
     $this->assertEqual($this->countTableRows($table_name_users), $this->countTableRows("users"), t('A second temporary table was created successfully in this request.'));
   }
 }
diff --git a/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/DatabaseStorageTest.php b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/DatabaseStorageTest.php
new file mode 100644
index 0000000..c81f8e9
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/DatabaseStorageTest.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace Drupal\system\Tests\KeyValueStore;
+
+class DatabaseStorageTest extends StorageTestBase {
+
+  static function getInfo() {
+    return array(
+      'name' => 'Database Storage',
+      'description' => 'Test the key-value database storage.',
+      'group' => 'Key-value store'
+    );
+  }
+
+  protected function setUp() {
+    parent::setUp();
+    module_load_install('system');
+    $schema = system_schema();
+    db_create_table('keyvalue', $schema['keyvalue']);
+  }
+
+  protected function tearDown() {
+    db_drop_table('keyvalue');
+    parent::tearDown();
+  }
+}
diff --git a/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/MemoryStorageTest.php b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/MemoryStorageTest.php
new file mode 100644
index 0000000..d3db3bc
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/MemoryStorageTest.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace Drupal\system\Tests\KeyValueStore;
+
+class MemoryStorageTest extends StorageTestBase {
+
+  static function getInfo() {
+    return array(
+      'name' => 'Memory Storage',
+      'description' => 'Test the key-value memory storage.',
+      'group' => 'Key-value store'
+    );
+  }
+
+}
diff --git a/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/StorageTestBase.php b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/StorageTestBase.php
new file mode 100644
index 0000000..8fb38a0
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/StorageTestBase.php
@@ -0,0 +1,41 @@
+<?php
+
+namespace Drupal\system\Tests\KeyValueStore;
+
+use Drupal\simpletest\UnitTestBase;
+
+class StorageTestBase extends UnitTestBase {
+  protected function setUp() {
+    parent::setUp();
+    $class = explode('\\', get_class($this));
+    $this->collection = end($class);
+    $storageClass = '\\Drupal\\Core\\KeyValueStore\\' . substr($this->collection, 0, -4);
+    $this->kv = new $storageClass($this->collection);
+  }
+
+  public function testSetGet() {
+    $this->assertEqual($this->kv->getCollectionName(), $this->collection);
+    // get-set test.
+    $this->kv->set('foo', 'bar');
+    $this->assertEqual('bar', $this->kv->get('foo'));
+    $this->kv->delete('foo');
+    $this->assertFalse($this->kv->get('foo'));
+
+    // multiple test.
+    $values = array('foo' => 'bar', 'baz' => 'qux');
+    $this->kv->setMultiple($values);
+    $result = $this->kv->getMultiple(array('foo', 'baz'));
+    $this->assertEqual($values, $result);
+    $result = $this->kv->getAll();
+    // $result might not equal to $values, the order is not defined for
+    // getAll().
+    $this->assertEqual(count($result), count($values));
+    foreach ($result as $key => $value) {
+      $this->assertEqual($values[$key], $value);
+    }
+    $this->kv->deleteMultiple(array_keys($values));
+    $this->assertFalse($this->kv->get('foo'));
+    $this->assertFalse($this->kv->get('bar'));
+    $this->assertFalse($this->kv->getMultiple(array('foo', 'baz')));
+  }
+}
diff --git a/core/modules/system/lib/Drupal/system/Tests/Menu/RebuildTest.php b/core/modules/system/lib/Drupal/system/Tests/Menu/RebuildTest.php
index b6e0ec2..9cf1080 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Menu/RebuildTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Menu/RebuildTest.php
@@ -38,7 +38,7 @@ class RebuildTest extends WebTestBase {
 
     // Now we enable the rebuild variable and send a request to rebuild the menu
     // item. Now 'admin' should exist.
-    variable_set('menu_rebuild_needed', TRUE);
+    state()->set('menu_rebuild_needed', TRUE);
     // The request should trigger the rebuild.
     $this->drupalGet('<front>');
     $admin_exists = db_query('SELECT path from {menu_router} WHERE path = :path', array(':path' => 'admin'))->fetchField();
diff --git a/core/modules/system/lib/Drupal/system/Tests/Module/ModuleApiTest.php b/core/modules/system/lib/Drupal/system/Tests/Module/ModuleApiTest.php
index 8468185..1d7290f 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Module/ModuleApiTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Module/ModuleApiTest.php
@@ -49,11 +49,7 @@ class ModuleApiTest extends WebTestBase {
     $this->assertModuleList($module_list, t('After adding a module'));
 
     // Try to mess with the module weights.
-    db_update('system')
-      ->fields(array('weight' => 20))
-      ->condition('name', 'contact')
-      ->condition('type', 'module')
-      ->execute();
+    module_set_weight('contact.weight', 20);
     // Reset the module list.
     system_list_reset();
     // Move contact to the end of the array.
diff --git a/core/modules/system/lib/Drupal/system/Tests/System/InfoAlterTest.php b/core/modules/system/lib/Drupal/system/Tests/System/InfoAlterTest.php
index 9bdeac4..acabca7 100644
--- a/core/modules/system/lib/Drupal/system/Tests/System/InfoAlterTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/System/InfoAlterTest.php
@@ -71,7 +71,7 @@ class InfoAlterTest extends WebTestBase {
    *   Array of info, or FALSE if the record is not found.
    */
   function getSystemInfo($name, $type) {
-    $raw_info = db_query("SELECT info FROM {system} WHERE name = :name AND type = :type", array(':name' => $name, ':type' => $type))->fetchField();
-    return $raw_info ? unserialize($raw_info) : FALSE;
+    $info = config('system.' . $type)->get("$name.info");
+    return $info ? $info : FALSE;
   }
 }
diff --git a/core/modules/system/lib/Drupal/system/Tests/Update/UpdateScriptTest.php b/core/modules/system/lib/Drupal/system/Tests/Update/UpdateScriptTest.php
index 1231af4..918eb96 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Update/UpdateScriptTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Update/UpdateScriptTest.php
@@ -129,10 +129,10 @@ class UpdateScriptTest extends WebTestBase {
     // Since visiting update.php triggers a rebuild of the theme system from an
     // unusual maintenance mode environment, we check that this rebuild did not
     // put any incorrect information about the themes into the database.
-    $original_theme_data = db_query("SELECT * FROM {system} WHERE type = 'theme' ORDER BY name")->fetchAll();
+    $original_theme_data = config('system.theme')->get();
     $this->drupalLogin($this->update_user);
     $this->drupalGet($this->update_url, array('external' => TRUE));
-    $final_theme_data = db_query("SELECT * FROM {system} WHERE type = 'theme' ORDER BY name")->fetchAll();
+    $final_theme_data = config('system.theme')->get();
     $this->assertEqual($original_theme_data, $final_theme_data, t('Visiting update.php does not alter the information about themes stored in the database.'));
   }
 
diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/BareMinimalUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/BareMinimalUpgradePathTest.php
index 5956394..9aefbe8 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/BareMinimalUpgradePathTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/BareMinimalUpgradePathTest.php
@@ -78,7 +78,7 @@ class BareMinimalUpgradePathTest extends UpgradePathTestBase {
     $this->assertText(t('Configuration'));
     $this->assertText(t('Reports'));
     $this->assertText(t('Structure'));
-    $this->assertText(t('Modules'));
+    $this->assertText(t('Extend'));
 
     // Confirm that no {menu_links} entry exists for user/autocomplete.
     $result = db_query('SELECT COUNT(*) FROM {menu_links} WHERE link_path = :user_autocomplete', array(':user_autocomplete' => 'user/autocomplete'))->fetchField();
diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/BareStandardUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/BareStandardUpgradePathTest.php
index 1ac554c..5de864a 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/BareStandardUpgradePathTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/BareStandardUpgradePathTest.php
@@ -79,7 +79,7 @@ class BareStandardUpgradePathTest extends UpgradePathTestBase {
     $this->assertText(t('Configuration'));
     $this->assertText(t('Reports'));
     $this->assertText(t('Structure'));
-    $this->assertText(t('Modules'));
+    $this->assertText(t('Extend'));
 
     // Confirm that no {menu_links} entry exists for user/autocomplete.
     $result = db_query('SELECT COUNT(*) FROM {menu_links} WHERE link_path = :user_autocomplete', array(':user_autocomplete' => 'user/autocomplete'))->fetchField();
diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/FilledMinimalUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/FilledMinimalUpgradePathTest.php
index bd74caa..7f47a81 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/FilledMinimalUpgradePathTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/FilledMinimalUpgradePathTest.php
@@ -78,7 +78,7 @@ class FilledMinimalUpgradePathTest extends UpgradePathTestBase {
     $this->assertText(t('Configuration'));
     $this->assertText(t('Reports'));
     $this->assertText(t('Structure'));
-    $this->assertText(t('Modules'));
+    $this->assertText(t('Extend'));
 
     // Confirm that no {menu_links} entry exists for user/autocomplete.
     $result = db_query('SELECT COUNT(*) FROM {menu_links} WHERE link_path = :user_autocomplete', array(':user_autocomplete' => 'user/autocomplete'))->fetchField();
diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/FilledStandardUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/FilledStandardUpgradePathTest.php
index 0242830..5f00785 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/FilledStandardUpgradePathTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/FilledStandardUpgradePathTest.php
@@ -79,7 +79,7 @@ class FilledStandardUpgradePathTest extends UpgradePathTestBase {
     $this->assertText(t('Configuration'));
     $this->assertText(t('Reports'));
     $this->assertText(t('Structure'));
-    $this->assertText(t('Modules'));
+    $this->assertText(t('Extend'));
 
     // Confirm that no {menu_links} entry exists for user/autocomplete.
     $result = db_query('SELECT COUNT(*) FROM {menu_links} WHERE link_path = :user_autocomplete', array(':user_autocomplete' => 'user/autocomplete'))->fetchField();
diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/UpgradePathTestBase.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/UpgradePathTestBase.php
index a0f6c59..db8691e 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/UpgradePathTestBase.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/UpgradePathTestBase.php
@@ -273,10 +273,13 @@ abstract class UpgradePathTestBase extends WebTestBase {
 
     $modules = array_merge($required_modules, $modules);
 
-    db_delete('system')
-      ->condition('type', 'module')
-      ->condition('name', $modules, 'NOT IN')
-      ->execute();
+    $config = config('system.module');
+    foreach ($config->get() as $module => $data) {
+      if (!in_array($module, $required_modules)) {
+        $config->clear($module);
+      }
+    }
+    $config->save();
   }
 
 }
diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php
index 14f3630..c7343ba 100644
--- a/core/modules/system/system.api.php
+++ b/core/modules/system/system.api.php
@@ -206,7 +206,7 @@ function hook_queue_info_alter(&$queues) {
 }
 
 /**
- * Allows modules to declare their own Forms API element types and specify their
+ * Allows modules to declare their own Form API element types and specify their
  * default values.
  *
  * This hook allows modules to declare their own form element types and to
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index ac983aa..e3cc614 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -509,11 +509,7 @@ function system_requirements($phase) {
 function system_install() {
   // Enable the default theme.
   variable_set('theme_default', 'stark');
-  db_update('system')
-    ->fields(array('status' => 1))
-    ->condition('type', 'theme')
-    ->condition('name', 'stark')
-    ->execute();
+  config('system.theme')->set('stark.status', 1)->save();
 
   // Populate the cron key variable.
   $cron_key = drupal_hash_base64(drupal_random_bytes(55));
@@ -549,6 +545,60 @@ function system_schema() {
     ),
     'primary key' => array('name'),
   );
+  $schema['keyvalue'] = array(
+    'description' => 'Generic key-value storage table.',
+    'fields' => array(
+      'name' => array(
+        'description' => 'The key.',
+        'type' => 'varchar',
+        'length' => 128,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'collection' => array(
+        'description' => 'The collection of the variable.',
+        'type' => 'varchar',
+        'length' => 128,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'value' => array(
+        'description' => 'The value.',
+        'type' => 'blob',
+        'not null' => TRUE,
+        'size' => 'big',
+        'translatable' => TRUE,
+      ),
+    ),
+    'primary key' => array('collection', 'name'),
+  );
+  $schema['keyvalue'] = array(
+    'description' => 'Generic key-value storage table.',
+    'fields' => array(
+      'name' => array(
+       'description' => 'The key.',
+       'type' => 'varchar',
+       'length' => 128,
+       'not null' => TRUE,
+       'default' => '',
+      ),
+      'collection' => array(
+        'description' => 'The collection of the variable.',
+        'type' => 'varchar',
+        'length' => 128,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'value' => array(
+        'description' => 'The value.',
+        'type' => 'blob',
+        'not null' => TRUE,
+        'size' => 'big',
+        'translatable' => TRUE,
+      ),
+    ),
+    'primary key' => array('collection', 'name'),
+  );
 
   $schema['actions'] = array(
     'description' => 'Stores action information.',
@@ -1362,75 +1412,6 @@ 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(
-        '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,
-        'not null' => TRUE,
-        'default' => '',
-      ),
-      'name' => array(
-        'description' => 'The name of the item; e.g. node.',
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => TRUE,
-        'default' => '',
-      ),
-      'type' => array(
-        'description' => 'The type of the item, either module, theme, or theme_engine.',
-        'type' => 'varchar',
-        'length' => 12,
-        'not null' => TRUE,
-        'default' => '',
-      ),
-      'owner' => array(
-        'description' => "A theme's 'parent' . Can be either a theme or an engine.",
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => TRUE,
-        'default' => '',
-      ),
-      'status' => array(
-        'description' => 'Boolean indicating whether or not this item is enabled.',
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-      'bootstrap' => array(
-        '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,
-        'default' => 0,
-      ),
-      'schema_version' => array(
-        'description' => "The module's database schema version number. -1 if the module is not installed (its tables do not exist); 0 or the largest N of the module's hook_update_N() function that has either been run or existed when the module was first installed.",
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => -1,
-        'size' => 'small',
-      ),
-      'weight' => array(
-        '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,
-        'default' => 0,
-      ),
-      'info' => array(
-        'description' => "A serialized array containing information from the module's .info file; keys can include name, description, package, version, core, dependencies, and php.",
-        'type' => 'blob',
-        'not null' => FALSE,
-      ),
-    ),
-    'primary key' => array('filename'),
-    'indexes' => array(
-      'system_list' => array('status', 'bootstrap', 'type', 'weight', 'name'),
-      'type_name' => array('type', 'name'),
-    ),
-  );
-
   $schema['url_alias'] = array(
     'description' => 'A list of URL aliases for Drupal paths; a user may visit either the source or destination path.',
     'fields' => array(
@@ -1499,7 +1480,9 @@ function system_update_last_removed() {
  * Enable entity module.
  */
 function system_update_8000() {
-  update_module_enable(array('entity'));
+  $modules = array('entity');
+  update_module_add_to_system($modules);
+  update_module_enable($modules);
 }
 
 /**
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 922b8a7..c3ee221c 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -6,6 +6,7 @@
  */
 
 use Drupal\Core\Utility\ModuleInfo;
+use Drupal\Core\KeyValueStore\KeyValueFactory;
 
 use Symfony\Component\HttpFoundation\JsonResponse;
 use Symfony\Component\HttpFoundation\Response;
@@ -718,8 +719,8 @@ function system_menu() {
 
   // Modules.
   $items['admin/modules'] = array(
-    'title' => 'Modules',
-    'description' => 'Extend site functionality.',
+    'title' => 'Extend',
+    'description' => 'Add and enable modules to extend site functionality.',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('system_modules'),
     'access arguments' => array('administer modules'),
@@ -2609,13 +2610,15 @@ function system_check_directory($form_element) {
  */
 function system_get_files_database(&$files, $type) {
   // 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) {
-    if (isset($files[$file->name]) && is_object($files[$file->name])) {
+  $config = config("system.$type")->get();
+  $store = KeyValueFactory::get('system.module');
+  foreach ($store->getAll() as $name => $file) {
+    if (isset($files[$name]) && is_object($files[$name])) {
       $file->uri = $file->filename;
+      $file->status = isset($config[$name]);
       foreach ($file as $key => $value) {
-        if (!isset($files[$file->name]->$key)) {
-          $files[$file->name]->$key = $value;
+        if (!isset($files[$name]->$key)) {
+          $files[$name]->$key = $value;
         }
       }
     }
@@ -2631,77 +2634,61 @@ function system_get_files_database(&$files, $type) {
  *   The type of the files.
  */
 function system_update_files_database(&$files, $type) {
-  $result = db_query("SELECT * FROM {system} WHERE type = :type", array(':type' => $type));
-
-  // Add all files that need to be deleted to a DatabaseCondition.
-  $delete = db_or();
-  foreach ($result as $file) {
-    if (isset($files[$file->name]) && is_object($files[$file->name])) {
-      // Keep the old filename from the database in case the file has moved.
-      $old_filename = $file->filename;
-
-      $updated_fields = array();
+  $store = KeyValueFactory::get("system.$type");
+  foreach ($store->getAll() as $name => $data) {
+    $update = FALSE;
+    if (isset($files[$name]) && is_object($files[$name])) {
 
       // Handle info specially, compare the serialized value.
-      $serialized_info = serialize($files[$file->name]->info);
-      if ($serialized_info != $file->info) {
-        $updated_fields['info'] = $serialized_info;
+      $serialized_info = serialize($files[$name]->info);
+      if ($serialized_info != serialize($data->info)) {
+        $update = TRUE;
+        $data->info = $files[$name]->info;
       }
-      unset($file->info);
 
       // Scan remaining fields to find only the updated values.
-      foreach ($file as $key => $value) {
-        if (isset($files[$file->name]->$key) && $files[$file->name]->$key != $value) {
-          $updated_fields[$key] = $files[$file->name]->$key;
+      foreach ($data as $key => $value) {
+        if ($key != 'info' && isset($files[$name]->$key) && $files[$name]->$key != $value) {
+          $update = TRUE;
+          $data->$key = $files[$name]->$key;
         }
       }
 
       // Update the record.
-      if (count($updated_fields)) {
-        db_update('system')
-          ->fields($updated_fields)
-          ->condition('filename', $old_filename)
-          ->execute();
+      if ($update) {
+        $store->set($name, $data);
       }
 
       // Indicate that the file exists already.
-      $files[$file->name]->exists = TRUE;
+      $files[$name]->exists = TRUE;
     }
-    else {
-      // File is not found in file system, so delete record from the system table.
-      $delete->condition('filename', $file->filename);
+    elseif ($type == 'module' && $data['schema_version'] == SCHEMA_UNINSTALLED) {
+      $store->delete($name);
     }
   }
 
-  if (count($delete) > 0) {
-    // Delete all missing files from the system table, but only if the plugin
-    // has never been installed.
-    db_delete('system')
-      ->condition($delete)
-      ->condition('schema_version', -1)
-      ->execute();
-  }
-
   // All remaining files are not in the system table, so we need to add them.
-  $query = db_insert('system')->fields(array('filename', 'name', 'type', 'owner', 'info'));
+  $config = config("system.$type")->get();
   foreach ($files as &$file) {
+    $file->status = isset($config[$file->name]);
     if (isset($file->exists)) {
       unset($file->exists);
     }
     else {
-      $query->values(array(
-        'filename' => $file->uri,
-        'name' => $file->name,
-        'type' => $type,
-        'owner' => isset($file->owner) ? $file->owner : '',
-        'info' => serialize($file->info),
-      ));
+      if ($type == 'theme') {
+        $data = (object) array(
+          'filename' => $file->uri,
+          'status' => 0,
+          'owner' => isset($file->owner) ? $file->owner : '',
+          'info' => $file->info,
+        );
+        $store->set($file->name, $data);
+      }
       $file->type = $type;
       $file->status = 0;
       $file->schema_version = -1;
     }
   }
-  $query->execute();
 
   // If any module or theme was moved to a new location, we need to reset the
   // system_list() cache or we will continue to load the old copy, look for
@@ -2734,9 +2721,9 @@ function system_update_files_database(&$files, $type) {
 function system_get_info($type, $name = NULL) {
   $info = array();
   if ($type == 'module') {
-    $result = db_query('SELECT name, info FROM {system} WHERE type = :type AND status = 1', array(':type' => 'module'));
-    foreach ($result as $record) {
-      $info[$record->name] = unserialize($record->info);
+    $module_data = KeyValueFactory::get('system.module')->getMultiple(array_keys(config('system.module')->get()));
+    foreach ($module_data as $module => $data) {
+      $info[$module] = $data->info;
     }
   }
   else {
@@ -2891,21 +2878,14 @@ function system_rebuild_module_data() {
  * are loaded earlier to invoke the hooks.
  */
 function _system_update_bootstrap_status() {
-  $bootstrap_modules = array();
+  $store = KeyValueFactory::get('system.module');
   foreach (bootstrap_hooks() as $hook) {
     foreach (module_implements($hook) as $module) {
-      $bootstrap_modules[] = $module;
+      $module_data = $store->get($module);
+      $module_data->bootstrap = 1;
+      $store->set($module, $module_data);
     }
   }
-  $query = db_update('system')->fields(array('bootstrap' => 0));
-  if ($bootstrap_modules) {
-    db_update('system')
-      ->fields(array('bootstrap' => 1))
-      ->condition('name', $bootstrap_modules, 'IN')
-      ->execute();
-    $query->condition('name', $bootstrap_modules, 'NOT IN');
-  }
-  $query->execute();
   // Reset the cached list of bootstrap modules.
   system_list_reset();
 }
@@ -3072,8 +3052,9 @@ function _system_info_add_path($info, $path) {
     // Unset the original value's key and set the new value with prefix, using
     // the original value as key, so original values can still be looked up.
     else {
-      unset($info[$key]);
-      $info[$value] = $path . '/' . $value;
+      // @TODO do something here to not mess up array order!
+      #unset($info[$key]);
+      $info[$key] = $path . '/' . $value;
     }
   }
   return $info;
diff --git a/core/modules/system/tests/modules/actions_loop_test/actions_loop_test.install b/core/modules/system/tests/modules/actions_loop_test/actions_loop_test.install
index b22fd85..614e737 100644
--- a/core/modules/system/tests/modules/actions_loop_test/actions_loop_test.install
+++ b/core/modules/system/tests/modules/actions_loop_test/actions_loop_test.install
@@ -4,8 +4,7 @@
  * Implements hook_install().
  */
 function actions_loop_test_install() {
-   db_update('system')
-    ->fields(array('weight' => 1))
-    ->condition('name', 'actions_loop_test')
-    ->execute();
+  config('system.module')
+    ->set('actions_loop_test.weight', 1)
+    ->save();
 }
diff --git a/core/modules/system/tests/modules/database_test/database_test.module b/core/modules/system/tests/modules/database_test/database_test.module
index 0180b03..93135c9 100644
--- a/core/modules/system/tests/modules/database_test/database_test.module
+++ b/core/modules/system/tests/modules/database_test/database_test.module
@@ -84,7 +84,7 @@ function database_test_menu() {
  * table should automatically dropped.
  */
 function database_test_db_query_temporary() {
-  $table_name = db_query_temporary('SELECT status FROM {system}', array());
+  $table_name = db_query_temporary('SELECT status FROM {filter}', array());
   return new JsonResponse(array(
     'table_name' => $table_name,
     'row_count' => db_select($table_name)->countQuery()->execute()->fetchField(),
diff --git a/core/modules/system/tests/modules/url_alter_test/url_alter_test.install b/core/modules/system/tests/modules/url_alter_test/url_alter_test.install
index 6e09ab5..10a96e4 100644
--- a/core/modules/system/tests/modules/url_alter_test/url_alter_test.install
+++ b/core/modules/system/tests/modules/url_alter_test/url_alter_test.install
@@ -5,8 +5,5 @@
  */
 function url_alter_test_install() {
   // Set the weight of this module to one higher than forum.module.
-  db_update('system')
-    ->fields(array('weight' => 2))
-    ->condition('name', 'url_alter_test')
-    ->execute();
+  module_set_weight('url_alter_test.weight', 2);
 }
diff --git a/core/modules/system/theme.api.php b/core/modules/system/theme.api.php
index b98132e..0001cba 100644
--- a/core/modules/system/theme.api.php
+++ b/core/modules/system/theme.api.php
@@ -70,8 +70,8 @@
  * Allow themes to alter the theme-specific settings form.
  *
  * With this hook, themes can alter the theme-specific settings form in any way
- * allowable by Drupal's Forms API, such as adding form elements, changing
- * default values and removing form elements. See the Forms API documentation on
+ * allowable by Drupal's Form API, such as adding form elements, changing
+ * default values and removing form elements. See the Form API documentation on
  * api.drupal.org for detailed information.
  *
  * Note that the base theme's form alterations will be run before any sub-theme
diff --git a/core/modules/update/lib/Drupal/update/Tests/UpdateContribTest.php b/core/modules/update/lib/Drupal/update/Tests/UpdateContribTest.php
index 27328c0..adbab48 100644
--- a/core/modules/update/lib/Drupal/update/Tests/UpdateContribTest.php
+++ b/core/modules/update/lib/Drupal/update/Tests/UpdateContribTest.php
@@ -166,11 +166,7 @@ class UpdateContribTest extends UpdateTestBase {
    */
   function testUpdateBaseThemeSecurityUpdate() {
     // Only enable the subtheme, not the base theme.
-    db_update('system')
-      ->fields(array('status' => 1))
-      ->condition('type', 'theme')
-      ->condition('name', 'update_test_subtheme')
-      ->execute();
+    theme_enable(array('update_test_subtheme'));
 
     // Define the initial state for core and the subtheme.
     $system_info = array(
@@ -208,11 +204,13 @@ class UpdateContribTest extends UpdateTestBase {
   function testUpdateShowDisabledThemes() {
     $update_settings = config('update.settings');
     // Make sure all the update_test_* themes are disabled.
-    db_update('system')
-      ->fields(array('status' => 0))
-      ->condition('type', 'theme')
-      ->condition('name', 'update_test_%', 'LIKE')
-      ->execute();
+    $config = config('system.theme');
+    foreach ($config->get() as $theme => $data) {
+      if (preg_match('/^update_test_/', $theme)) {
+        $config->clear($theme);
+      }
+    }
+    $config->save();
 
     // Define the initial state for core and the test contrib themes.
     $system_info = array(
diff --git a/core/profiles/standard/standard.install b/core/profiles/standard/standard.install
index f3eaf29..45d5dbf 100644
--- a/core/profiles/standard/standard.install
+++ b/core/profiles/standard/standard.install
@@ -419,11 +419,7 @@ function standard_install() {
   menu_router_rebuild();
 
   // Enable the admin theme.
-  db_update('system')
-    ->fields(array('status' => 1))
-    ->condition('type', 'theme')
-    ->condition('name', 'seven')
-    ->execute();
+  config('system.theme')->set('seven.status', 1)->save();
   variable_set('admin_theme', 'seven');
   variable_set('node_admin_theme', '1');
 }
