diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index fa1335b..4c28ced 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -288,8 +288,6 @@ const REGISTRY_WRITE_LOOKUP_CACHE = 2;
  */
 const DRUPAL_PHP_FUNCTION_PATTERN = '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*';
 
-require_once DRUPAL_ROOT . '/core/includes/config.inc';
-
 /**
  * Starts the timer with the specified name.
  *
@@ -480,6 +478,25 @@ function find_conf_path($http_host, $script_name, $require_settings = TRUE) {
 }
 
 /**
+ * Returns the path of the configuration directory.
+ *
+ * @return string
+ *   The configuration directory path.
+ */
+function config_get_config_directory() {
+  global $config_directory_name;
+
+  if ($test_prefix = drupal_valid_test_ua()) {
+    // @see Drupal\simpletest\WebTestBase::setUp()
+    $path = conf_path() . '/files/simpletest/' . substr($test_prefix, 10) . '/config';
+  }
+  else {
+    $path = conf_path() . '/files/' . $config_directory_name;
+  }
+  return $path;
+}
+
+/**
  * Sets appropriate server variables needed for command line scripts to work.
  *
  * This function can be called by command line scripts before bootstrapping
@@ -2265,6 +2282,9 @@ function _drupal_bootstrap_configuration() {
 
   // Activate the class loader.
   drupal_classloader();
+
+  // Load the procedural configuration system helper functions.
+  require_once DRUPAL_ROOT . '/core/includes/config.inc';
 }
 
 /**
diff --git a/core/includes/config.inc b/core/includes/config.inc
index 8d0eea1..c6435b3 100644
--- a/core/includes/config.inc
+++ b/core/includes/config.inc
@@ -9,25 +9,6 @@ use Drupal\Core\Config\FileStorage;
  */
 
 /**
- * Gets the randomly generated config directory name.
- *
- * @return
- *   The directory name.
- */
-function config_get_config_directory() {
-  global $config_directory_name;
-
-  if ($test_prefix = drupal_valid_test_ua()) {
-    // @see Drupal\simpletest\WebTestBase::setUp()
-    $path = conf_path() . '/files/simpletest/' . substr($test_prefix, 10) . '/config';
-  }
-  else {
-    $path = conf_path() . '/files/' . $config_directory_name;
-  }
-  return $path;
-}
-
-/**
  * Installs the default configuration of a given module.
  *
  * @param
@@ -38,28 +19,23 @@ function config_get_config_directory() {
  */
 function config_install_default_config($module) {
   $module_config_dir = drupal_get_path('module', $module) . '/config';
-  $drupal_config_dir = config_get_config_directory();
-  if (is_dir(drupal_get_path('module', $module) . '/config')) {
-    $files = glob($module_config_dir . '/*.' . FileStorage::getFileExtension());
-    foreach ($files as $key => $file) {
-      // Load config data into the active store and write it out to the
-      // file system in the drupal config directory. Note the config name
-      // needs to be the same as the file name WITHOUT the extension.
-      $config_name = basename($file, '.' . FileStorage::getFileExtension());
+  if (is_dir($module_config_dir)) {
+    $database_storage = new DatabaseStorage();
+    $module_file_storage = new FileStorage(array('directory' => $module_config_dir));
 
-      $database_storage = new DatabaseStorage($config_name);
-      $file_storage = new FileStorage($config_name);
-      $file_storage->setPath($module_config_dir);
-      $database_storage->write($file_storage->read());
+    foreach ($module_file_storage->listAll() as $config_name) {
+      $data = $module_file_storage->read($config_name);
+      $database_storage->write($config_name, $data);
     }
   }
 }
 
 /**
- * @todo http://drupal.org/node/1552396 renames this into config_load_all().
+ * @todo Modules need a way to access the active store, whatever it is.
  */
 function config_get_storage_names_with_prefix($prefix = '') {
-  return DatabaseStorage::getNamesWithPrefix($prefix);
+  $storage = new DatabaseStorage();
+  return $storage->listAll($prefix);
 }
 
 /**
@@ -73,16 +49,11 @@ function config_get_storage_names_with_prefix($prefix = '') {
  *   The name of the configuration object to retrieve. The name corresponds to
  *   a configuration file. For @code config(book.admin) @endcode, the config
  *   object returned will contain the contents of book.admin configuration file.
- * @param $class
- *   The class name of the config object to be returned. Defaults to
- *   DrupalConfig.
  *
- * @return
- *   An instance of the class specified in the $class parameter.
- *
- * @todo Replace this with an appropriate factory / ability to inject in
- *   alternate storage engines..
+ * @return Drupal\Core\Config\Config
+ *   A configuration object.
  */
-function config($name, $class = 'Drupal\Core\Config\DrupalConfig') {
-  return new $class(new DatabaseStorage($name));
+function config($name) {
+  return drupal_container()->get('config.factory')->get($name)->load();
 }
+
diff --git a/core/includes/install.inc b/core/includes/install.inc
index 96e84b3..cd67257 100644
--- a/core/includes/install.inc
+++ b/core/includes/install.inc
@@ -1,7 +1,7 @@
 <?php
 
 use Drupal\Core\Database\Database;
-use Drupal\Core\Config\FileStorage;
+use Drupal\Core\Config\DatabaseStorage;
 
 /**
  * Indicates that a module has not been installed yet.
@@ -376,24 +376,17 @@ function drupal_uninstall_modules($module_list = array(), $uninstall_dependents
     $module_list = array_keys($module_list);
   }
 
+  $storage = new DatabaseStorage();
   foreach ($module_list as $module) {
     // Uninstall the module.
     module_load_install($module);
     module_invoke($module, 'uninstall');
     drupal_uninstall_schema($module);
 
-    // Remove any stray configuration settings.
-    // Get the names of default configurations provided by this module
-    // by scanning its config directory.
-    $module_config_dir = drupal_get_path('module', $module) . '/config';
-    if (is_dir($module_config_dir)) {
-      $files = glob($module_config_dir . '/*.' . FileStorage::getFileExtension());
-      foreach ($files as $file) {
-        $config_name = basename($file, '.' . FileStorage::getFileExtension());
-        $file_storage = new FileStorage($config_name);
-        // Delete the configuration from storage.
-        $file_storage->delete();
-      }
+    // Remove all configuration belonging to the module.
+    $config_names = $storage->listAll($module . '.');
+    foreach ($config_names as $config_name) {
+      config($config_name)->delete();
     }
 
     watchdog('system', '%module module uninstalled.', array('%module' => $module), WATCHDOG_INFO);
diff --git a/core/includes/module.inc b/core/includes/module.inc
index a71cb18..e15cd95 100644
--- a/core/includes/module.inc
+++ b/core/includes/module.inc
@@ -487,7 +487,7 @@ function module_enable($module_list, $enable_dependencies = TRUE) {
         $versions = drupal_get_schema_versions($module);
         $version = $versions ? max($versions) : SCHEMA_INSTALLED;
 
-        // Copy any default configuration data to the system config directory/
+        // Install default configuration of the module.
         config_install_default_config($module);
 
         // If the module has no current updates, but has some that were
diff --git a/core/includes/update.inc b/core/includes/update.inc
index 49df15b..ab373cd 100644
--- a/core/includes/update.inc
+++ b/core/includes/update.inc
@@ -10,6 +10,7 @@
 
 use Drupal\Component\Graph\Graph;
 use Drupal\Core\Config\FileStorage;
+use Drupal\Core\Config\ConfigException;
 
 /**
  * Minimum schema version of Drupal 7 required for upgrade to Drupal 8.
@@ -942,11 +943,11 @@ function update_variables_to_config($config_name, array $variable_map) {
   $module = strtok($config_name, '.');
 
   // Load and set default configuration values.
-  // Throws a FileStorageReadException if there is no default configuration
-  // file, which is required to exist.
-  $file = new FileStorage($config_name);
-  $file->setPath(drupal_get_path('module', $module) . '/config');
-  $default_data = $file->read();
+  $file = new FileStorage(array('directory' => drupal_get_path('module', $module) . '/config'));
+  if (!$file->exists($config_name)) {
+    throw new ConfigException("Default configuration file $config_name for $module extension not found but is required to exist.");
+  }
+  $default_data = $file->read($config_name);
 
   // Merge any possibly existing original data into default values.
   // Only relevant when being called repetitively on the same config object.
diff --git a/core/lib/Drupal/Core/Config/ConfigException.php b/core/lib/Drupal/Core/Config/ConfigException.php
index c60a449..5e7daed 100644
--- a/core/lib/Drupal/Core/Config/ConfigException.php
+++ b/core/lib/Drupal/Core/Config/ConfigException.php
@@ -1,8 +1,15 @@
 <?php
 
+/**
+ * @file
+ * Definition of Drupal\Core\Config\ConfigException.
+ */
+
 namespace Drupal\Core\Config;
 
+use RuntimeException;
+
 /**
- * @todo
+ * A base exception thrown in any configuration system operations.
  */
-class ConfigException extends \Exception {}
+class ConfigException extends RuntimeException {}
diff --git a/core/lib/Drupal/Core/Config/ConfigFactory.php b/core/lib/Drupal/Core/Config/ConfigFactory.php
new file mode 100644
index 0000000..5d6535a
--- /dev/null
+++ b/core/lib/Drupal/Core/Config/ConfigFactory.php
@@ -0,0 +1,65 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\Core\Config\ConfigFactory.
+ */
+
+namespace Drupal\Core\Config;
+
+/**
+ * Defines the configuration object factory.
+ *
+ * The configuration object factory instantiates a Config object for each
+ * configuration object name that is accessed and returns it to callers.
+ *
+ * Each configuration object gets a storage dispatcher object injected, which
+ * determines the storage controller to use for reading and writing the
+ * configuration data.
+ *
+ * @see Drupal\Core\Config\Config
+ */
+class ConfigFactory {
+  /**
+   * Instantiated storage object.
+   *
+   * @var StorageInterface
+   */
+  protected $storage;
+
+  /**
+   * Instantiated configuration objects.
+   *
+   * @todo Implement ConfigCacheArray to cache and preload config objects per
+   *   request.
+   *
+   * @var array
+   */
+  protected $configObjects = array();
+
+  public function __construct(StorageInterface $storage) {
+    $this->storage = $storage;
+  }
+
+  /**
+   * Returns a configuration object for a given name.
+   *
+   * Configuration objects are instantiated once only.
+   *
+   * @param string $name
+   *   The name of the configuration object to construct.
+   * @param string $class
+   *   (optional) The name of the class to use for the configuration object.
+   *   Defaults to Drupal\Core\Config\ConfigObject.
+   * @param string $manager_class
+   *   (optional) The name of the storage manager class to use. Defaults to
+   *   Drupal\Core\Config\StorageManager.
+   *
+   * @return Drupal\Core\Config\ConfigObject
+   *   A configuration object with the given $name.
+   */
+  public function get($name) {
+    // Instantiate the configuration object
+    return $this->configObjects[$name];
+  }
+}
diff --git a/core/lib/Drupal/Core/Config/DatabaseStorage.php b/core/lib/Drupal/Core/Config/DatabaseStorage.php
index c736245..1dd8507 100644
--- a/core/lib/Drupal/Core/Config/DatabaseStorage.php
+++ b/core/lib/Drupal/Core/Config/DatabaseStorage.php
@@ -1,26 +1,65 @@
 <?php
 
+/**
+ * @file
+ * Definition of Drupal\Core\Config\DatabaseStorage.
+ */
+
 namespace Drupal\Core\Config;
 
-use Drupal\Core\Config\StorageBase;
+use Drupal\Core\Database\Database;
 use Exception;
 
 /**
- * Represents an SQL-based configuration storage object.
+ * Defines the Database storage controller.
  */
-class DatabaseStorage extends StorageBase {
+class DatabaseStorage implements StorageInterface {
+
+  /**
+   * Database connection options for this storage controller.
+   *
+   * - connection: The connection key to use.
+   * - target: The target on the connection to use.
+   *
+   * @var array
+   */
+  protected $options;
+
+  /**
+   * Implements Drupal\Core\Config\StorageInterface::__construct().
+   */
+  public function __construct(array $options = array()) {
+    $options += array(
+      'connection' => 'default',
+      'target' => 'default',
+    );
+    $this->options = $options;
+  }
+
+  /**
+   * Returns the database connection to use.
+   */
+  protected function getConnection() {
+    return Database::getConnection($this->options['target'], $this->options['connection']);
+  }
 
   /**
-   * Implements StorageInterface::read().
+   * Implements Drupal\Core\Config\StorageInterface::read().
+   *
+   * @throws PDOException
+   * @throws Drupal\Core\Database\DatabaseExceptionWrapper
+   *   Only thrown in case $this->options['throw_exception'] is TRUE.
    */
-  public function read() {
+  public function read($name) {
+    $data = array();
     // There are situations, like in the installer, where we may attempt a
     // read without actually having the database available. In this case,
     // catch the exception and just return an empty array so the caller can
     // handle it if need be.
-    $data = array();
+    // @todo Remove this and use appropriate StorageDispatcher configuration in
+    //   the installer instead.
     try {
-      $raw = db_query('SELECT data FROM {config} WHERE name = :name', array(':name' => $this->name))->fetchField();
+      $raw = $this->getConnection()->query('SELECT data FROM {config} WHERE name = :name', array(':name' => $name), $this->options)->fetchField();
       if ($raw !== FALSE) {
         $data = $this->decode($raw);
       }
@@ -31,43 +70,63 @@ class DatabaseStorage extends StorageBase {
   }
 
   /**
-   * Implements StorageInterface::writeToActive().
+   * Implements Drupal\Core\Config\StorageInterface::write().
+   *
+   * @throws PDOException
+   *
+   * @todo Ignore slave targets for data manipulation operations.
    */
-  public function writeToActive($data) {
+  public function write($name, array $data) {
     $data = $this->encode($data);
-    return db_merge('config')
-      ->key(array('name' => $this->name))
+    $options = array('return' => Database::RETURN_AFFECTED) + $this->options;
+    return (bool) $this->getConnection()->merge('config', $options)
+      ->key(array('name' => $name))
       ->fields(array('data' => $data))
       ->execute();
   }
 
   /**
-   * @todo
+   * Implements Drupal\Core\Config\StorageInterface::delete().
+   *
+   * @throws PDOException
+   *
+   * @todo Ignore slave targets for data manipulation operations.
    */
-  public function deleteFromActive() {
-    db_delete('config')
-      ->condition('name', $this->name)
+  public function delete($name) {
+    $options = array('return' => Database::RETURN_AFFECTED) + $this->options;
+    return (bool) $this->getConnection()->delete('config', $options)
+      ->condition('name', $name)
       ->execute();
   }
 
   /**
-   * Implements StorageInterface::encode().
+   * Implements Drupal\Core\Config\StorageInterface::encode().
    */
   public static function encode($data) {
     return serialize($data);
   }
 
   /**
-   * Implements StorageInterface::decode().
+   * Implements Drupal\Core\Config\StorageInterface::decode().
+   *
+   * @throws ErrorException
+   *   unserialize() triggers E_NOTICE if the string cannot be unserialized.
    */
   public static function decode($raw) {
-    return unserialize($raw);
+    $data = @unserialize($raw);
+    return $data !== FALSE ? $data : array();
   }
 
   /**
-   * Implements StorageInterface::getNamesWithPrefix().
+   * Implements Drupal\Core\Config\StorageInterface::listAll().
+   *
+   * @throws PDOException
+   * @throws Drupal\Core\Database\DatabaseExceptionWrapper
+   *   Only thrown in case $this->options['throw_exception'] is TRUE.
    */
-  static public function getNamesWithPrefix($prefix = '') {
-    return db_query('SELECT name FROM {config} WHERE name LIKE :name', array(':name' => db_like($prefix) . '%'))->fetchCol();
+  public function listAll($prefix = '') {
+    return $this->getConnection()->query('SELECT name FROM {config} WHERE name LIKE :name', array(
+      ':name' => db_like($prefix) . '%',
+    ), $this->options)->fetchCol();
   }
 }
diff --git a/core/lib/Drupal/Core/Config/DrupalConfig.php b/core/lib/Drupal/Core/Config/DrupalConfig.php
index f5a9220..bdf91be 100644
--- a/core/lib/Drupal/Core/Config/DrupalConfig.php
+++ b/core/lib/Drupal/Core/Config/DrupalConfig.php
@@ -1,21 +1,23 @@
 <?php
 
-namespace Drupal\Core\Config;
+/**
+ * @file
+ * Definition of Drupal\Core\Config\DrupalConfig.
+ */
 
-use Drupal\Core\Config\StorageInterface;
-use Drupal\Core\Config\ConfigException;
+namespace Drupal\Core\Config;
 
 /**
- * Represents the default configuration storage object.
+ * Defines the default configuration object.
  */
 class DrupalConfig {
 
   /**
-   * The storage engine to save this config object to.
+   * The name of the configuration object.
    *
-   * @var StorageInterface
+   * @var string
    */
-  protected $storage;
+  protected $name;
 
   /**
    * The data of the configuration object.
@@ -25,38 +27,37 @@ class DrupalConfig {
   protected $data = array();
 
   /**
-   * Constructs a DrupalConfig object.
+   * The injected storage object.
    *
-   * @param StorageInterface $storage
-   *   The storage engine where this config object should be saved.
+   * @var Drupal\Core\Config\StorageInterface
+   */
+  protected $storage;
+
+  /**
+   * Constructs a configuration object.
    *
-   * @todo $this should really know about $name and make it publicly accessible.
+   * @param Drupal\Core\Config\StorageDispatcher $storageDispatcher
+   *   A storage dispatcher object to use for reading and writing the
+   *   configuration data.
    */
-  public function __construct(StorageInterface $storage) {
+  public function __construct($name, StorageInterface $storage) {
+    $this->name = $name;
     $this->storage = $storage;
-    $this->read();
   }
 
   /**
-   * Reads config data from the active store into our object.
+   * Returns the name of this configuration object.
    */
-  public function read() {
-    $data = $this->storage->read();
-    $this->setData($data !== FALSE ? $data : array());
-    return $this;
+  public function getName() {
+    return $this->name;
   }
 
   /**
-   * Checks whether a particular value is overridden.
-   *
-   * @param $key
-   *   @todo
-   *
-   * @return
-   *   @todo
+   * Sets the name of this configuration object.
    */
-  public function isOverridden($key) {
-    return isset($this->_overrides[$key]);
+  public function setName($name) {
+    $this->name = $name;
+    return $this;
   }
 
   /**
@@ -89,7 +90,7 @@ class DrupalConfig {
   public function get($key = '') {
     global $conf;
 
-    $name = $this->storage->getName();
+    $name = $this->getName();
     if (isset($conf[$name])) {
       $merged_data = drupal_array_merge_deep($this->data, $conf[$name]);
     }
@@ -201,13 +202,48 @@ class DrupalConfig {
     else {
       drupal_array_unset_nested_value($this->data, $parts);
     }
+    return $this;
+  }
+
+  /**
+   * Loads configuration data into this object.
+   */
+  public function load() {
+    $this->setData(array());
+    $data = $this->storage->read($this->name);
+    if ($data !== FALSE) {
+      $this->setData($data);
+    }
+    return $this;
   }
 
   /**
    * Saves the configuration object.
    */
   public function save() {
-    $this->storage->write($this->data);
+    $this->sortByKey($this->data);
+    $this->storage->write($this->name, $this->data);
+    return $this;
+  }
+
+  /**
+   * Sorts all keys in configuration data.
+   *
+   * Ensures that re-inserted keys appear in the same location as before, in
+   * order to ensure an identical order regardless of storage controller.
+   * A consistent order is important for any storage that allows any kind of
+   * diff operation.
+   *
+   * @param array $data
+   *   An associative array to sort recursively by key name.
+   */
+  public function sortByKey(array &$data) {
+    ksort($data);
+    foreach ($data as &$value) {
+      if (is_array($value)) {
+        $this->sortByKey($value);
+      }
+    }
   }
 
   /**
@@ -215,6 +251,7 @@ class DrupalConfig {
    */
   public function delete() {
     $this->data = array();
-    $this->storage->delete();
+    $this->storage->delete($this->name);
+    return $this;
   }
 }
diff --git a/core/lib/Drupal/Core/Config/FileStorage.php b/core/lib/Drupal/Core/Config/FileStorage.php
index 2a6d448..7827dc0 100644
--- a/core/lib/Drupal/Core/Config/FileStorage.php
+++ b/core/lib/Drupal/Core/Config/FileStorage.php
@@ -1,59 +1,36 @@
 <?php
 
+/**
+ * @file
+ * Definition of Drupal\Core\Config\FileStorage.
+ */
+
 namespace Drupal\Core\Config;
 
 use Symfony\Component\Yaml\Yaml;
 
 /**
- * Represents the file storage controller.
- *
- * @todo Implement StorageInterface after removing DrupalConfig methods.
- * @todo Consider to extend StorageBase.
+ * Defines the file storage controller.
  */
-class FileStorage {
+class FileStorage implements StorageInterface {
 
   /**
-   * The name of the configuration object.
+   * Configuration options for this storage controller.
    *
-   * @var string
-   */
-  protected $name;
-
-  /**
-   * The filesystem path containing the configuration object.
+   * - directory: The filesystem path for configuration objects.
    *
-   * @var string
+   * @var array
    */
-  protected $path;
+  protected $options;
 
   /**
-   * Implements StorageInterface::__construct().
-   */
-  public function __construct($name = NULL) {
-    $this->name = $name;
-  }
-
-  /**
-   * Returns the path containing the configuration file.
-   *
-   * @return string
-   *   The relative path to the configuration object.
+   * Implements Drupal\Core\Config\StorageInterface::__construct().
    */
-  public function getPath() {
-    // If the path has not been set yet, retrieve and assign the default path
-    // for configuration files.
-    if (!isset($this->path)) {
-      $this->setPath(config_get_config_directory());
+  public function __construct(array $options = array()) {
+    if (!isset($options['directory'])) {
+      $options['directory'] = config_get_config_directory();
     }
-    return $this->path;
-  }
-
-  /**
-   * Sets the path containing the configuration file.
-   */
-  public function setPath($directory) {
-    $this->path = $directory;
-    return $this;
+    $this->options = $options;
   }
 
   /**
@@ -62,8 +39,8 @@ class FileStorage {
    * @return string
    *   The path to the configuration file.
    */
-  public function getFilePath() {
-    return $this->getPath() . '/' . $this->getName() . '.' . self::getFileExtension();
+  public function getFilePath($name) {
+    return $this->options['directory'] . '/' . $name . '.' . self::getFileExtension();
   }
 
   /**
@@ -82,50 +59,65 @@ class FileStorage {
    * @return bool
    *   TRUE if the configuration file exists, FALSE otherwise.
    */
-  protected function exists() {
-    return file_exists($this->getFilePath());
+  public function exists($name) {
+    return file_exists($this->getFilePath($name));
   }
 
   /**
-   * Implements StorageInterface::write().
+   * Implements Drupal\Core\Config\StorageInterface::read().
    *
-   * @throws FileStorageException
+   * @throws Symfony\Component\Yaml\Exception\ParseException
    */
-  public function write($data) {
-    $data = $this->encode($data);
-    if (!file_put_contents($this->getFilePath(), $data)) {
-      throw new FileStorageException('Failed to write configuration file: ' . $this->getFilePath());
+  public function read($name) {
+    if (!$this->exists($name)) {
+      return array();
+    }
+    $data = file_get_contents($this->getFilePath($name));
+    // @todo Yaml throws a ParseException on invalid data. Is it expected to be
+    //   caught or not?
+    $data = $this->decode($data);
+    if ($data === FALSE) {
+      return array();
     }
+    // A simple string is valid YAML for any reason.
+    if (!is_array($data)) {
+      return array();
+    }
+    return $data;
   }
 
   /**
-   * Implements StorageInterface::read().
+   * Implements Drupal\Core\Config\StorageInterface::write().
    *
-   * @throws FileStorageReadException
+   * @throws Symfony\Component\Yaml\Exception\DumpException
+   * @throws Drupal\Core\Config\StorageException
    */
-  public function read() {
-    if (!$this->exists()) {
-      throw new FileStorageReadException("Configuration file '$this->name' does not exist.");
-    }
-
-    $data = file_get_contents($this->getFilePath());
-    $data = $this->decode($data);
-    if ($data === FALSE) {
-      throw new FileStorageReadException("Failed to decode configuration file '$this->name'.");
+  public function write($name, array $data) {
+    $data = $this->encode($data);
+    $status = @file_put_contents($this->getFilePath($name), $data);
+    if ($status === FALSE) {
+      throw new StorageException('Failed to write configuration file: ' . $this->getFilePath($name));
     }
-    return $data;
+    return TRUE;
   }
 
   /**
-   * Deletes a configuration file.
+   * Implements Drupal\Core\Config\StorageInterface::delete().
    */
-  public function delete() {
-    // Needs error handling and etc.
-    @drupal_unlink($this->getFilePath());
+  public function delete($name) {
+    if (!$this->exists($name)) {
+      if (!file_exists($this->options['directory'])) {
+        throw new StorageException($this->options['directory'] . '/ not found.');
+      }
+      return FALSE;
+    }
+    return drupal_unlink($this->getFilePath($name));
   }
 
   /**
-   * Implements StorageInterface::encode().
+   * Implements Drupal\Core\Config\StorageInterface::encode().
+   *
+   * @throws Symfony\Component\Yaml\Exception\DumpException
    */
   public static function encode($data) {
     // The level where you switch to inline YAML is set to PHP_INT_MAX to ensure
@@ -134,7 +126,9 @@ class FileStorage {
   }
 
   /**
-   * Implements StorageInterface::decode().
+   * Implements Drupal\Core\Config\StorageInterface::decode().
+   *
+   * @throws Symfony\Component\Yaml\Exception\ParseException
    */
   public static function decode($raw) {
     if (empty($raw)) {
@@ -144,28 +138,18 @@ class FileStorage {
   }
 
   /**
-   * Implements StorageInterface::getName().
-   */
-  public function getName() {
-    return $this->name;
-  }
-
-  /**
-   * Implements StorageInterface::setName().
+   * Implements Drupal\Core\Config\StorageInterface::listAll().
    */
-  public function setName($name) {
-    $this->name = $name;
-  }
-
-  /**
-   * Implements StorageInterface::getNamesWithPrefix().
-   */
-  public static function getNamesWithPrefix($prefix = '') {
-    // @todo Use $this->getPath() to allow for contextual search of files in
-    //   custom paths.
-    $files = glob(config_get_config_directory() . '/' . $prefix . '*.' . FileStorage::getFileExtension());
-    $clean_name = function ($value) {
-      return basename($value, '.' . FileStorage::getFileExtension());
+  public function listAll($prefix = '') {
+    // glob() silently ignores the error of a non-existing search directory,
+    // even with the GLOB_ERR flag.
+    if (!file_exists($this->options['directory'])) {
+      throw new StorageException($this->options['directory'] . '/ not found.');
+    }
+    $extension = '.' . self::getFileExtension();
+    $files = glob($this->options['directory'] . '/' . $prefix . '*' . $extension);
+    $clean_name = function ($value) use ($extension) {
+      return basename($value, $extension);
     };
     return array_map($clean_name, $files);
   }
diff --git a/core/lib/Drupal/Core/Config/FileStorageException.php b/core/lib/Drupal/Core/Config/FileStorageException.php
deleted file mode 100644
index bf3ae5f..0000000
--- a/core/lib/Drupal/Core/Config/FileStorageException.php
+++ /dev/null
@@ -1,10 +0,0 @@
-<?php
-
-namespace Drupal\Core\Config;
-
-use Drupal\Core\Config\ConfigException;
-
-/**
- * @todo
- */
-class FileStorageException extends ConfigException {}
diff --git a/core/lib/Drupal/Core/Config/FileStorageReadException.php b/core/lib/Drupal/Core/Config/FileStorageReadException.php
deleted file mode 100644
index d613666..0000000
--- a/core/lib/Drupal/Core/Config/FileStorageReadException.php
+++ /dev/null
@@ -1,10 +0,0 @@
-<?php
-
-namespace Drupal\Core\Config;
-
-use Drupal\Core\Config\FileStorageException;
-
-/**
- * @todo
- */
-class FileStorageReadException extends FileStorageException {}
diff --git a/core/lib/Drupal/Core/Config/StorageBase.php b/core/lib/Drupal/Core/Config/StorageBase.php
deleted file mode 100644
index b03ff27..0000000
--- a/core/lib/Drupal/Core/Config/StorageBase.php
+++ /dev/null
@@ -1,121 +0,0 @@
-<?php
-
-namespace Drupal\Core\Config;
-
-use Drupal\Core\Config\StorageInterface;
-use Drupal\Core\Config\FileStorage;
-
-/**
- * Base class for configuration storage controllers.
- */
-abstract class StorageBase implements StorageInterface {
-
-  /**
-   * The name of the configuration object.
-   *
-   * @var string
-   */
-  protected $name;
-
-  /**
-   * The local file object to read from and write to.
-   *
-   * @var Drupal\Core\Config\FileStorage
-   */
-  protected $fileStorage;
-
-  /**
-   * Implements StorageInterface::__construct().
-   */
-  function __construct($name = NULL) {
-    $this->name = $name;
-  }
-
-  /**
-   * Instantiates a new file storage object or returns the existing one.
-   *
-   * @return Drupal\Core\Config\FileStorage
-   *   The file object for this configuration object.
-   */
-  protected function fileStorage() {
-    if (!isset($this->fileStorage)) {
-      $this->fileStorage = new FileStorage($this->name);
-    }
-    return $this->fileStorage;
-  }
-
-  /**
-   * Implements StorageInterface::copyToFile().
-   */
-  public function copyToFile() {
-    return $this->writeToFile($this->read());
-  }
-
-  /**
-   * Implements StorageInterface::deleteFile().
-   */
-  public function deleteFile() {
-    return $this->fileStorage()->delete();
-  }
-
-  /**
-   * Implements StorageInterface::copyFromFile().
-   */
-  public function copyFromFile() {
-    return $this->writeToActive($this->readFromFile());
-  }
-
-  /**
-   * @todo
-   *
-   * @return
-   *   @todo
-   */
-  public function readFromFile() {
-    return $this->fileStorage()->read($this->name);
-  }
-
-  /**
-   * Implements StorageInterface::isOutOfSync().
-   */
-  public function isOutOfSync() {
-    return $this->read() !== $this->readFromFile();
-  }
-
-  /**
-   * Implements StorageInterface::write().
-   */
-  public function write($data) {
-    $this->writeToActive($data);
-    $this->writeToFile($data);
-  }
-
-  /**
-   * Implements StorageInterface::writeToFile().
-   */
-  public function writeToFile($data) {
-    return $this->fileStorage()->write($data);
-  }
-
-  /**
-   * Implements StorageInterface::delete().
-   */
-  public function delete() {
-    $this->deleteFromActive();
-    $this->deleteFile();
-  }
-
-  /**
-   * Implements StorageInterface::getName().
-   */
-  public function getName() {
-    return $this->name;
-  }
-
-  /**
-   * Implements StorageInterface::setName().
-   */
-  public function setName($name) {
-    $this->name = $name;
-  }
-}
diff --git a/core/lib/Drupal/Core/Config/StorageException.php b/core/lib/Drupal/Core/Config/StorageException.php
new file mode 100644
index 0000000..b1e99a1
--- /dev/null
+++ b/core/lib/Drupal/Core/Config/StorageException.php
@@ -0,0 +1,13 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\Core\Config\StorageException.
+ */
+
+namespace Drupal\Core\Config;
+
+/**
+ * An exception thrown in case of storage controller operation errors.
+ */
+class StorageException extends ConfigException {}
diff --git a/core/lib/Drupal/Core/Config/StorageInterface.php b/core/lib/Drupal/Core/Config/StorageInterface.php
index 43141a5..907e884 100644
--- a/core/lib/Drupal/Core/Config/StorageInterface.php
+++ b/core/lib/Drupal/Core/Config/StorageInterface.php
@@ -1,80 +1,64 @@
 <?php
 
+/**
+ * @file
+ * Definition of Drupal\Core\Config\StorageInterface.
+ */
+
 namespace Drupal\Core\Config;
 
 /**
- * Defines an interface for configuration storage manipulation.
+ * Defines an interface for configuration storage controllers.
  *
  * Classes implementing this interface allow reading and writing configuration
  * data from and to the storage.
- *
- * @todo Remove all active/file methods. They belong onto DrupalConfig only.
  */
 interface StorageInterface {
 
   /**
-   * Constructs a storage manipulation class.
+   * Constructs the storage controller.
    *
-   * @param string $name
-   *   (optional) The name of a configuration object to load.
-   */
-  function __construct($name = NULL);
-
-  /**
-   * Reads the configuration data from the storage.
-   */
-  function read();
-
-  /**
-   * Copies the configuration data from the storage into a file.
-   */
-  function copyToFile();
-
-  /**
-   * Copies the configuration data from the file into the storage.
-   */
-  function copyFromFile();
-
-  /**
-   * Deletes the configuration data file.
+   * @param array $options
+   *   An associative array containing configuration options specific to the
+   *   storage controller.
    */
-  function deleteFile();
+  public function __construct(array $options = array());
 
   /**
-   * Checks whether the file and the storage is in sync.
+   * Reads configuration data from the storage.
    *
-   * @return
-   *   TRUE if the file and the storage contains the same data, FALSE
-   *   if not.
-   */
-  function isOutOfSync();
-
-  /**
-   * Writes the configuration data into the active storage and the file.
+   * @param string $name
+   *   The name of a configuration object to load.
    *
-   * @param $data
-   *   The configuration data to write.
+   * @return array
+   *   The configuration data stored for the configuration object name. If no
+   *   configuration data exists for the given name, an empty array is returned.
    */
-  function write($data);
+  public function read($name);
 
   /**
-   * Writes the configuration data into the active storage but not the file.
+   * Writes configuration data to the storage.
    *
-   * Use this function if you need to make temporary changes to your
-   * configuration.
+   * @param string $name
+   *   The name of a configuration object to save.
+   * @param array $data
+   *   The configuration data to write.
    *
-   * @param $data
-   *   The configuration data to write into active storage.
+   * @return bool
+   *   TRUE on success, FALSE in case of an error.
    */
-  function writeToActive($data);
+  public function write($name, array $data);
 
   /**
-   * Writes the configuration data into the file.
+   * Deletes a configuration object from the storage.
    *
-   * @param $data
-   *   The configuration data to write into the file.
+   * @param string $name
+   *   The name of a configuration object to delete.
+   *
+   * @return bool
+   *   TRUE on success, FALSE otherwise.
    */
-  function writeToFile($data);
+  public function delete($name);
 
   /**
    * Encodes configuration data into the storage-specific format.
@@ -105,23 +89,13 @@ interface StorageInterface {
   public static function decode($raw);
 
   /**
-   * Gets the name of this object.
-   */
-  public function getName();
-
-  /**
-   * Sets the name of this object.
-   */
-  public function setName($name);
-
-  /**
    * Gets configuration object names starting with a given prefix.
    *
    * Given the following configuration objects:
    * - node.type.article
    * - node.type.page
    *
-   * Passing the prefix 'node.type' will return an array containing the above
+   * Passing the prefix 'node.type.' will return an array containing the above
    * names.
    *
    * @param string $prefix
@@ -131,5 +105,5 @@ interface StorageInterface {
    * @return array
    *   An array containing matching configuration object names.
    */
-  static function getNamesWithPrefix($prefix = '');
+  public function listAll($prefix = '');
 }
diff --git a/core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php b/core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php
index aa73ace..85fb1b3 100644
--- a/core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php
+++ b/core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php
@@ -8,6 +8,8 @@
 namespace Drupal\Core\DependencyInjection;
 
 use Symfony\Component\DependencyInjection\ContainerBuilder as BaseContainerBuilder;
+use Symfony\Component\DependencyInjection\Reference;
+
 
 /**
  * Drupal's dependency injection container.
@@ -27,5 +29,12 @@ class ContainerBuilder extends BaseContainerBuilder {
 
     // Register the default language content.
     $this->register(LANGUAGE_TYPE_CONTENT, 'Drupal\\Core\\Language\\Language');
+
+    // Register configuration storage.
+    $this->register('config.storage', 'Drupal\Core\Config\DatabaseStorage');
+
+    // Register configuration factory.
+    $this->register('config.factory', 'Drupal\Core\Config\ConfigFactory')
+      ->addArgument(new Reference('config.storage'));
   }
 }
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigCRUDTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigCRUDTest.php
new file mode 100644
index 0000000..aeca024
--- /dev/null
+++ b/core/modules/config/lib/Drupal/config/Tests/ConfigCRUDTest.php
@@ -0,0 +1,106 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\config\Tests\ConfigCRUDTest.
+ */
+
+namespace Drupal\config\Tests;
+
+use Drupal\Core\Config\DatabaseStorage;
+use Drupal\simpletest\WebTestBase;
+
+/**
+ * Tests CRUD operations on configuration objects.
+ */
+class ConfigCRUDTest extends WebTestBase {
+  public static function getInfo() {
+    return array(
+      'name' => 'CRUD operations',
+      'description' => 'Tests CRUD operations on configuration objects.',
+      'group' => 'Configuration',
+    );
+  }
+
+  /**
+   * Tests CRUD operations.
+   */
+  function testCRUD() {
+    $storage = new DatabaseStorage();
+    $name = 'config_test.crud';
+
+    // Create a new configuration object.
+    $config = config($name);
+    $config->set('value', 'initial');
+    $config->save();
+
+    // Verify the active store contains the saved value.
+    $actual_data = $storage->read($name);
+    $this->assertIdentical($actual_data, array('value' => 'initial'));
+
+    // Update the configuration object instance.
+    $config->set('value', 'instance-update');
+    $config->save();
+
+    // Verify the active store contains the updated value.
+    $actual_data = $storage->read($name);
+    $this->assertIdentical($actual_data, array('value' => 'instance-update'));
+
+    // Verify a call to config() immediately returns the updated value.
+    $new_config = config($name);
+    $this->assertIdentical($new_config->get(), $config->get());
+
+    // Delete the configuration object.
+    $config->delete();
+
+    // Verify the configuration object is empty.
+    $this->assertIdentical($config->get(), array());
+
+    // Verify the active store contains no value.
+    $actual_data = $storage->read($name);
+    $this->assertIdentical($actual_data, array());
+
+    // Verify config() returns no data.
+    $new_config = config($name);
+    $this->assertIdentical($new_config->get(), $config->get());
+
+    // Re-create the configuration object.
+    $config->set('value', 're-created');
+    $config->save();
+
+    // Verify the active store contains the updated value.
+    $actual_data = $storage->read($name);
+    $this->assertIdentical($actual_data, array('value' => 're-created'));
+
+    // Verify a call to config() immediately returns the updated value.
+    $new_config = config($name);
+    $this->assertIdentical($new_config->get(), $config->get());
+  }
+
+  /**
+   * Tests Drupal\Core\Config\Config::sortByKey().
+   */
+  function testDataKeySort() {
+    $config = config('config_test.keysort');
+    $config->set('new', 'Value to be replaced');
+    $config->set('static', 'static');
+    $config->save();
+    // Clone this Config, so this test does not rely on any particular
+    // architecture.
+    $config = clone $config;
+
+    // Load the configuration data into a new object.
+    $new_config = config('config_test.keysort');
+    // Clear the 'new' key that came first.
+    $new_config->clear('new');
+    // Add a new 'new' key and save.
+    $new_config->set('new', 'Value to be replaced');
+    $new_config->save();
+
+    // Verify that the data of both objects is in the identical order.
+    // assertIdentical() is the required essence of this test; it performs a
+    // strict comparison, which means that keys and values must be identical and
+    // their order must be identical.
+    $this->assertIdentical($new_config->get(), $config->get());
+  }
+}
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigFileContentTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigFileContentTest.php
index bfd27ac..3add6d8 100644
--- a/core/modules/config/lib/Drupal/config/Tests/ConfigFileContentTest.php
+++ b/core/modules/config/lib/Drupal/config/Tests/ConfigFileContentTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\config\Tests;
 
+use Drupal\Core\Config\DatabaseStorage;
 use Drupal\Core\Config\FileStorage;
 use Drupal\simpletest\WebTestBase;
 
@@ -14,8 +15,6 @@ use Drupal\simpletest\WebTestBase;
  * Tests reading and writing file contents.
  */
 class ConfigFileContentTest extends WebTestBase {
-  protected $fileExtension;
-
   public static function getInfo() {
     return array(
       'name' => 'File content',
@@ -26,15 +25,14 @@ class ConfigFileContentTest extends WebTestBase {
 
   function setUp() {
     parent::setUp();
-
-    $this->fileExtension = FileStorage::getFileExtension();
   }
 
   /**
    * Tests setting, writing, and reading of a configuration setting.
    */
   function testReadWriteConfig() {
-    $config_dir = config_get_config_directory();
+    $database_storage = new DatabaseStorage();
+
     $name = 'foo.bar';
     $key = 'foo';
     $value = 'bar';
@@ -62,16 +60,15 @@ class ConfigFileContentTest extends WebTestBase {
     $config = config($name);
 
     // Verify an configuration object is returned.
-//    $this->assertEqual($config->name, $name);
+    $this->assertEqual($config->getName(), $name);
     $this->assertTrue($config, t('Config object created.'));
 
     // Verify the configuration object is empty.
     $this->assertEqual($config->get(), array(), t('New config object is empty.'));
 
     // Verify nothing was saved.
-    $db_config = db_query('SELECT * FROM {config} WHERE name = :name', array(':name' => $name))->fetch();
-    $this->assertIdentical($db_config, FALSE, t('Active store does not have a record for %name', array('%name' => $name)));
-    $this->assertFalse(file_exists($config_dir . '/' . $name . '.' . $this->fileExtension), 'Configuration file does not exist.');
+    $db_data = $database_storage->read($name);
+    $this->assertIdentical($db_data, array());
 
     // Add a top level value
     $config = config($name);
@@ -97,15 +94,12 @@ class ConfigFileContentTest extends WebTestBase {
     $config->save();
 
     // Verify the database entry exists.
-    $db_config = db_query('SELECT * FROM {config} WHERE name = :name', array(':name' => $name))->fetch();
-    $this->assertEqual($db_config->name, $name, t('After saving configuration, active store has a record for %name', array('%name' => $name)));
-
-    // Verify the file exists.
-    $this->assertTrue(file_exists($config_dir . '/' . $name . '.' . $this->fileExtension), t('After saving configuration, config file exists.'));
+    $db_data = $database_storage->read($name);
+    $this->assertTrue($db_data);
 
     // Read top level value
     $config = config($name);
-//    $this->assertEqual($config->name, $name);
+    $this->assertEqual($config->getName(), $name);
     $this->assertTrue($config, 'Config object created.');
     $this->assertEqual($config->get($key), 'bar', t('Top level configuration value found.'));
 
@@ -158,30 +152,27 @@ class ConfigFileContentTest extends WebTestBase {
     $config->set($key, $value)->save();
 
     // Verify the database entry exists from a chained save.
-    $db_config = db_query('SELECT * FROM {config} WHERE name = :name', array(':name' => $chained_name))->fetch();
-    $this->assertEqual($db_config->name, $chained_name, t('After saving configuration by chaining through set(), active store has a record for %name', array('%name' => $chained_name)));
-
-    // Verify the file exists from a chained save.
-    $this->assertTrue(file_exists($config_dir . '/' . $chained_name . '.' . $this->fileExtension), t('After saving configuration by chaining through set(), config file exists.'));
+    $db_data = $database_storage->read($chained_name);
+    $this->assertEqual($db_data, $config->get());
 
     // Get file listing for all files starting with 'foo'. Should return
     // two elements.
-    $files = FileStorage::getNamesWithPrefix('foo');
+    $files = $database_storage->listAll('foo');
     $this->assertEqual(count($files), 2, 'Two files listed with the prefix \'foo\'.');
 
     // Get file listing for all files starting with 'biff'. Should return
     // one element.
-    $files = FileStorage::getNamesWithPrefix('biff');
+    $files = $database_storage->listAll('biff');
     $this->assertEqual(count($files), 1, 'One file listed with the prefix \'biff\'.');
 
     // Get file listing for all files starting with 'foo.bar'. Should return
     // one element.
-    $files = FileStorage::getNamesWithPrefix('foo.bar');
+    $files = $database_storage->listAll('foo.bar');
     $this->assertEqual(count($files), 1, 'One file listed with the prefix \'foo.bar\'.');
 
     // Get file listing for all files starting with 'bar'. Should return
     // an empty array.
-    $files = FileStorage::getNamesWithPrefix('bar');
+    $files = $database_storage->listAll('bar');
     $this->assertEqual($files, array(), 'No files listed with the prefix \'bar\'.');
 
     // Delete the configuration.
@@ -189,17 +180,14 @@ class ConfigFileContentTest extends WebTestBase {
     $config->delete();
 
     // Verify the database entry no longer exists.
-    $db_config = db_query('SELECT * FROM {config} WHERE name = :name', array(':name' => $name))->fetch();
-    $this->assertIdentical($db_config, FALSE);
-    $this->assertFalse(file_exists($config_dir . '/' . $name . $this->fileExtension));
-
-    // Attempt to delete non-existing configuration.
+    $db_data = $database_storage->read($name);
+    $this->assertIdentical($db_data, array());
   }
 
   /**
    * Tests serialization of configuration to file.
    */
-  function testConfigSerialization() {
+  function testSerialization() {
     $name = $this->randomName(10) . '.' . $this->randomName(10);
     $config_data = array(
       // Indexed arrays; the order of elements is essential.
@@ -216,17 +204,10 @@ class ConfigFileContentTest extends WebTestBase {
       'invalid xml' => '</title><script type="text/javascript">alert("Title XSS!");</script> & < > " \' ',
     );
 
-    // Attempt to read non-existing configuration.
-    $config = config($name);
-
-    foreach ($config_data as $key => $value) {
-      $config->set($key, $value);
-    }
-
-    $config->save();
-
-    $config_filestorage = new FileStorage($name);
-    $config_parsed = $config_filestorage->read();
+    // Encode and write, and reload and decode the configuration data.
+    $filestorage = new FileStorage();
+    $filestorage->write($name, $config_data);
+    $config_parsed = $filestorage->read($name);
 
     $key = 'numeric keys';
     $this->assertIdentical($config_data[$key], $config_parsed[$key]);
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigFileSecurityTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigFileSecurityTest.php
deleted file mode 100644
index 5f9ec07..0000000
--- a/core/modules/config/lib/Drupal/config/Tests/ConfigFileSecurityTest.php
+++ /dev/null
@@ -1,51 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\config\Tests\ConfigFileSecurityTest.
- */
-
-namespace Drupal\config\Tests;
-
-use Drupal\Core\Config\FileStorage;
-use Drupal\simpletest\WebTestBase;
-
-/**
- * Tests the secure file writer.
- */
-class ConfigFileSecurityTest extends WebTestBase {
-  protected $filename = 'foo.bar';
-
-  protected $testContent = array('greeting' => 'Good morning, Denver!');
-
-  public static function getInfo() {
-    return array(
-      'name' => 'File security',
-      'description' => 'Tests security of saved configuration files.',
-      'group' => 'Configuration',
-    );
-  }
-
-  /**
-   * Tests that a file written by this system can be successfully read back.
-   */
-  function testFilePersist() {
-    $file = new FileStorage($this->filename);
-    $file->write($this->testContent);
-
-    unset($file);
-
-    // Reading should throw an exception in case of bad validation.
-    // Note that if any other exception is thrown, we let the test system
-    // handle catching and reporting it.
-    try {
-      $file = new FileStorage($this->filename);
-      $saved_content = $file->read();
-
-      $this->assertEqual($saved_content, $this->testContent);
-    }
-    catch (Exception $e) {
-      $this->fail('File failed verification when being read.');
-    }
-  }
-}
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigUpgradeTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigUpgradeTest.php
index b2286da..0b43de4 100644
--- a/core/modules/config/lib/Drupal/config/Tests/ConfigUpgradeTest.php
+++ b/core/modules/config/lib/Drupal/config/Tests/ConfigUpgradeTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\config\Tests;
 
+use Drupal\Core\Config\ConfigException;
 use Drupal\simpletest\WebTestBase;
 
 /**
@@ -80,5 +81,14 @@ class ConfigUpgradeTest extends WebTestBase {
     // Verify that variables have been deleted.
     $variables = db_query('SELECT name FROM {variable} WHERE name IN (:names)', array(':names' => array('config_upgrade_additional')))->fetchCol();
     $this->assertFalse($variables);
+
+    // Verify that a default module configuration file is required to exist.
+    try {
+      update_variables_to_config('config_upgrade.missing.default.config', array());
+      $this->fail('Exception was not thrown on missing default module configuration file.');
+    }
+    catch (ConfigException $e) {
+      $this->pass('Exception was thrown on missing default module configuration file.');
+    }
   }
 }
diff --git a/core/modules/config/lib/Drupal/config/Tests/Storage/ConfigStorageTestBase.php b/core/modules/config/lib/Drupal/config/Tests/Storage/ConfigStorageTestBase.php
new file mode 100644
index 0000000..3e6b254
--- /dev/null
+++ b/core/modules/config/lib/Drupal/config/Tests/Storage/ConfigStorageTestBase.php
@@ -0,0 +1,121 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\config\Tests\Storage\ConfigStorageTestBase.
+ */
+
+namespace Drupal\config\Tests\Storage;
+
+use Drupal\simpletest\WebTestBase;
+
+/**
+ * Base class for testing storage controller operations.
+ *
+ * All configuration storage controllers are expected to behave identically in
+ * terms of reading, writing, listing, deleting, as well as error handling.
+ *
+ * Therefore, storage controller tests use a uncommon test case class structure;
+ * the base class defines the test method(s) to execute, which are identical for
+ * all storage controllers. The storage controller specific test case classes
+ * supply the necessary helper methods to interact with the raw/native storage
+ * directly.
+ */
+abstract class ConfigStorageTestBase extends WebTestBase {
+
+  /**
+   * Tests storage controller CRUD operations.
+   *
+   * @todo Coverage: Trigger PDOExceptions / Database exceptions.
+   * @todo Coverage: Trigger Yaml's ParseException and DumpException.
+   */
+  function testCRUD() {
+    $name = 'config_test.storage';
+
+    // Reading a non-existing name returns an empty data array.
+    $data = $this->storage->read($name);
+    $this->assertIdentical($data, array());
+
+    // Reading a name containing non-decodeable data returns an empty array.
+    $this->insert($name, '');
+    $data = $this->storage->read($name);
+    $this->assertIdentical($data, array());
+
+    $this->update($name, 'foo');
+    $data = $this->storage->read($name);
+    $this->assertIdentical($data, array());
+
+    $this->delete($name);
+
+    // Writing data returns TRUE and the data has been written.
+    $data = array('foo' => 'bar');
+    $result = $this->storage->write($name, $data);
+    $this->assertIdentical($result, TRUE);
+    $raw_data = $this->read($name);
+    $this->assertIdentical($raw_data, $data);
+
+    // Writing the identical data again still returns TRUE.
+    $result = $this->storage->write($name, $data);
+    $this->assertIdentical($result, TRUE);
+
+    // Listing all names returns all.
+    $names = $this->storage->listAll();
+    $this->assertTrue(in_array('system.performance', $names));
+    $this->assertTrue(in_array($name, $names));
+
+    // Listing all names with prefix returns names with that prefix only.
+    $names = $this->storage->listAll('config_test.');
+    $this->assertFalse(in_array('system.performance', $names));
+    $this->assertTrue(in_array($name, $names));
+
+    // Deleting an existing name returns TRUE.
+    $result = $this->storage->delete($name);
+    $this->assertIdentical($result, TRUE);
+
+    // Deleting a non-existing name returns FALSE.
+    $result = $this->storage->delete($name);
+    $this->assertIdentical($result, FALSE);
+
+    // Reading from a non-existing storage bin returns an empty data array.
+    $data = $this->invalidStorage->read($name);
+    $this->assertIdentical($data, array());
+
+    // Writing to a non-existing storage bin throws an exception.
+    try {
+      $this->invalidStorage->write($name, array('foo' => 'bar'));
+      $this->fail('Exception not thrown upon writing to a non-existing storage bin.');
+    }
+    catch (\Exception $e) {
+      $class = get_class($e);
+      $this->pass($class . ' thrown upon writing to a non-existing storage bin.');
+    }
+
+    // Deleting from a non-existing storage bin throws an exception.
+    try {
+      $this->invalidStorage->delete($name);
+      $this->fail('Exception not thrown upon deleting from a non-existing storage bin.');
+    }
+    catch (\Exception $e) {
+      $class = get_class($e);
+      $this->pass($class . ' thrown upon deleting from a non-existing storage bin.');
+    }
+
+    // Listing on a non-existing storage bin throws an exception.
+    try {
+      $this->invalidStorage->listAll();
+      $this->fail('Exception not thrown upon listing from a non-existing storage bin.');
+    }
+    catch (\Exception $e) {
+      $class = get_class($e);
+      $this->pass($class . ' thrown upon listing from a non-existing storage bin.');
+    }
+  }
+
+  abstract protected function read($name);
+
+  abstract protected function insert($name, $data);
+
+  abstract protected function update($name, $data);
+
+  abstract protected function delete($name);
+}
diff --git a/core/modules/config/lib/Drupal/config/Tests/Storage/DatabaseStorageTest.php b/core/modules/config/lib/Drupal/config/Tests/Storage/DatabaseStorageTest.php
new file mode 100644
index 0000000..2e1599f
--- /dev/null
+++ b/core/modules/config/lib/Drupal/config/Tests/Storage/DatabaseStorageTest.php
@@ -0,0 +1,46 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\config\Tests\Storage\DatabaseStorageTest.
+ */
+
+namespace Drupal\config\Tests\Storage;
+
+use Drupal\Core\Config\DatabaseStorage;
+
+/**
+ * Tests DatabaseStorage controller operations.
+ */
+class DatabaseStorageTest extends ConfigStorageTestBase {
+  public static function getInfo() {
+    return array(
+      'name' => 'DatabaseStorage controller operations',
+      'description' => 'Tests DatabaseStorage controller operations.',
+      'group' => 'Configuration',
+    );
+  }
+
+  function setUp() {
+    parent::setUp();
+    $this->storage = new DatabaseStorage();
+    $this->invalidStorage = new DatabaseStorage(array('connection' => 'invalid'));
+  }
+
+  protected function read($name) {
+    $data = db_query('SELECT data FROM {config} WHERE name = :name', array(':name' => $name))->fetchField();
+    return unserialize($data);
+  }
+
+  protected function insert($name, $data) {
+    db_insert('config')->fields(array('name' => $name, 'data' => $data))->execute();
+  }
+
+  protected function update($name, $data) {
+    db_update('config')->fields(array('data' => $data))->condition('name', $name)->execute();
+  }
+
+  protected function delete($name) {
+    db_delete('config')->condition('name', $name)->execute();
+  }
+}
diff --git a/core/modules/config/lib/Drupal/config/Tests/Storage/FileStorageTest.php b/core/modules/config/lib/Drupal/config/Tests/Storage/FileStorageTest.php
new file mode 100644
index 0000000..092687f
--- /dev/null
+++ b/core/modules/config/lib/Drupal/config/Tests/Storage/FileStorageTest.php
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\config\Tests\Storage\FileStorageTest.
+ */
+
+namespace Drupal\config\Tests\Storage;
+
+use Drupal\Core\Config\FileStorage;
+use Symfony\Component\Yaml\Yaml;
+
+/**
+ * Tests FileStorage controller operations.
+ */
+class FileStorageTest extends ConfigStorageTestBase {
+  public static function getInfo() {
+    return array(
+      'name' => 'FileStorage controller operations',
+      'description' => 'Tests FileStorage controller operations.',
+      'group' => 'Configuration',
+    );
+  }
+
+  function setUp() {
+    parent::setUp();
+    $this->storage = new FileStorage();
+    $this->invalidStorage = new FileStorage(array('directory' => $this->configFileDirectory . '/nonexisting'));
+
+    // FileStorage::listAll() requires other configuration data to exist.
+    $this->storage->write('system.performance', config('system.performance')->get());
+  }
+
+  protected function read($name) {
+    $data = file_get_contents($this->storage->getFilePath($name));
+    return Yaml::parse($data);
+  }
+
+  protected function insert($name, $data) {
+    file_put_contents($this->storage->getFilePath($name), $data);
+  }
+
+  protected function update($name, $data) {
+    file_put_contents($this->storage->getFilePath($name), $data);
+  }
+
+  protected function delete($name) {
+    unlink($this->storage->getFilePath($name));
+  }
+}
diff --git a/core/modules/system/lib/Drupal/system/Tests/Module/EnableDisableTest.php b/core/modules/system/lib/Drupal/system/Tests/Module/EnableDisableTest.php
index 6319572..8afe33b 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Module/EnableDisableTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Module/EnableDisableTest.php
@@ -106,7 +106,7 @@ class EnableDisableTest extends ModuleTestBase {
           $this->assertText(t('hook_modules_enabled fired for @module', array('@module' => $module_to_enable)));
           $this->assertModules(array($module_to_enable), TRUE);
           $this->assertModuleTablesExist($module_to_enable);
-          $this->assertModuleConfigFilesExist($module_to_enable);
+          $this->assertModuleConfig($module_to_enable);
           $this->assertLogMessage('system', "%module module installed.", array('%module' => $module_to_enable), WATCHDOG_INFO);
           $this->assertLogMessage('system', "%module module enabled.", array('%module' => $module_to_enable), WATCHDOG_INFO);
         }
@@ -187,7 +187,7 @@ class EnableDisableTest extends ModuleTestBase {
     //  Check that the module's database tables still exist.
     $this->assertModuleTablesExist($module);
     //  Check that the module's config files still exist.
-    $this->assertModuleConfigFilesExist($module);
+    $this->assertModuleConfig($module);
 
     // Uninstall the module.
     $edit = array();
@@ -209,6 +209,6 @@ class EnableDisableTest extends ModuleTestBase {
     // Check that the module's database tables no longer exist.
     $this->assertModuleTablesDoNotExist($module);
     // Check that the module's config files no longer exist.
-    $this->assertModuleConfigFilesDoNotExist($module);
+    $this->assertNoModuleConfig($module);
   }
 }
diff --git a/core/modules/system/lib/Drupal/system/Tests/Module/ModuleTestBase.php b/core/modules/system/lib/Drupal/system/Tests/Module/ModuleTestBase.php
index 3b2ed5c..8f372ca 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Module/ModuleTestBase.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Module/ModuleTestBase.php
@@ -8,6 +8,7 @@
 namespace Drupal\system\Tests\Module;
 
 use Drupal\Core\Database\Database;
+use Drupal\Core\Config\DatabaseStorage;
 use Drupal\Core\Config\FileStorage;
 use Drupal\simpletest\WebTestBase;
 
@@ -77,65 +78,49 @@ class ModuleTestBase extends WebTestBase {
   }
 
   /**
-   * Assert that a module's config files have been loaded.
+   * Asserts that the default configuration of a module has been installed.
    *
    * @param string $module
    *   The name of the module.
    *
    * @return bool
-   *   TRUE if the module's config files exist, FALSE otherwise.
+   *   TRUE if configuration has been installed, FALSE otherwise.
    */
-  function assertModuleConfigFilesExist($module) {
-    // Define test variable.
-    $files_exist = TRUE;
-    // Get the path to the module's config dir.
+  function assertModuleConfig($module) {
     $module_config_dir = drupal_get_path('module', $module) . '/config';
-    if (is_dir($module_config_dir)) {
-      $files = glob($module_config_dir . '/*.' . FileStorage::getFileExtension());
-      $this->assertTrue($files);
-      $config_dir = config_get_config_directory();
-      // Get the filename of each config file.
-      foreach ($files as $file) {
-        $parts = explode('/', $file);
-        $filename = array_pop($parts);
-        if (!file_exists($config_dir . '/' . $filename)) {
-          $files_exist = FALSE;
-        }
-      }
+    if (!is_dir($module_config_dir)) {
+      return;
     }
+    $module_file_storage = new FileStorage(array('directory' => $module_config_dir));
+    $names = $module_file_storage->listAll();
+
+    // Verify that the config directory is not empty.
+    $this->assertTrue($names);
 
-    return $this->assertTrue($files_exist, t('All config files defined by the @module module have been copied to the live config directory.', array('@module' => $module)));
+    // Look up each default configuration object name in the active store, and
+    // if it exists, remove it from the stack.
+    foreach ($names as $key => $name) {
+      if (config($name)->get()) {
+        unset($names[$key]);
+      }
+    }
+    // Verify that all configuration has been installed (which means that $names
+    // is empty).
+    return $this->assertFalse($names, format_string('All default configuration of @module module found.', array('@module' => $module)));
   }
 
   /**
-   * Assert that none of a module's default config files are loaded.
+   * Asserts that no configuration exists for a given module.
    *
    * @param string $module
    *   The name of the module.
    *
    * @return bool
-   *   TRUE if the module's config files do not exist, FALSE otherwise.
+   *   TRUE if no configuration was found, FALSE otherwise.
    */
-  function assertModuleConfigFilesDoNotExist($module) {
-    // Define test variable.
-    $files_exist = FALSE;
-    // Get the path to the module's config dir.
-    $module_config_dir = drupal_get_path('module', $module) . '/config';
-    if (is_dir($module_config_dir)) {
-      $files = glob($module_config_dir . '/*.' . FileStorage::getFileExtension());
-      $this->assertTrue($files);
-      $config_dir = config_get_config_directory();
-      // Get the filename of each config file.
-      foreach ($files as $file) {
-        $parts = explode('/', $file);
-        $filename = array_pop($parts);
-        if (file_exists($config_dir . '/' . $filename)) {
-          $files_exist = TRUE;
-        }
-      }
-    }
-
-    return $this->assertFalse($files_exist, t('All config files defined by the @module module have been deleted from the live config directory.', array('@module' => $module)));
+  function assertNoModuleConfig($module) {
+    $names = config_get_storage_names_with_prefix($module . '.');
+    return $this->assertFalse($names, format_string('No configuration found for @module module.', array('@module' => $module)));
   }
 
   /**
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index b9558e5..32cfb75 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -379,7 +379,8 @@ function system_element_info() {
   $types['email'] = array(
     '#input' => TRUE,
     '#size' => 60,
-    '#maxlength' => EMAIL_MAX_LENGTH,
+    // user.module is not loaded in case of early bootstrap errors.
+    '#maxlength' => defined('EMAIL_MAX_LENGTH') ? EMAIL_MAX_LENGTH : 255,
     '#autocomplete_path' => FALSE,
     '#process' => array('form_process_autocomplete', 'ajax_process_form', 'form_process_pattern'),
     '#element_validate' => array('form_validate_email'),
