diff --git a/core/includes/config.inc b/core/includes/config.inc
index 8d0eea1..2925b99 100644
--- a/core/includes/config.inc
+++ b/core/includes/config.inc
@@ -2,6 +2,7 @@
 
 use Drupal\Core\Config\DatabaseStorage;
 use Drupal\Core\Config\FileStorage;
+use Drupal\Core\Config\ConfigFactory;
 
 /**
  * @file
@@ -38,8 +39,11 @@ 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')) {
+  if (is_dir($module_config_dir)) {
+    $database_storage = new DatabaseStorage();
+    $module_file_storage = new FileStorage(array('directory' => $module_config_dir));
+    $file_storage = new FileStorage();
+
     $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
@@ -47,10 +51,10 @@ function config_install_default_config($module) {
       // needs to be the same as the file name WITHOUT the extension.
       $config_name = basename($file, '.' . FileStorage::getFileExtension());
 
-      $database_storage = new DatabaseStorage($config_name);
-      $file_storage = new FileStorage($config_name);
-      $file_storage->setPath($module_config_dir);
-      $database_storage->write($file_storage->read());
+      $data = $module_file_storage->read($config_name);
+      $database_storage->write($config_name, $data);
+      // @todo Only explicit exports are supposed to write to FileStorage.
+      $file_storage->write($config_name, $data);
     }
   }
 }
@@ -75,14 +79,13 @@ function config_get_storage_names_with_prefix($prefix = '') {
  *   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.
+ *   ConfigObject.
  *
  * @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..
+ * @todo Replace with DI container.
  */
-function config($name, $class = 'Drupal\Core\Config\DrupalConfig') {
-  return new $class(new DatabaseStorage($name));
+function config($name, $class = 'Drupal\Core\Config\ConfigObject') {
+  return ConfigFactory::get($name, $class)->load();
 }
diff --git a/core/includes/install.inc b/core/includes/install.inc
index 1ebfb21..49bc272 100644
--- a/core/includes/install.inc
+++ b/core/includes/install.inc
@@ -387,6 +387,7 @@ function drupal_uninstall_modules($module_list = array(), $uninstall_dependents
     $module_list = array_keys($module_list);
   }
 
+  $file_storage = new FileStorage();
   foreach ($module_list as $module) {
     // Uninstall the module.
     module_load_install($module);
@@ -401,9 +402,8 @@ function drupal_uninstall_modules($module_list = array(), $uninstall_dependents
       $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();
+        $file_storage->delete($config_name);
       }
     }
 
diff --git a/core/includes/update.inc b/core/includes/update.inc
index f711507..a46f125 100644
--- a/core/includes/update.inc
+++ b/core/includes/update.inc
@@ -902,9 +902,8 @@ function update_variables_to_config($config_name, array $variable_map) {
   // 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'));
+  $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/ConfigFactory.php b/core/lib/Drupal/Core/Config/ConfigFactory.php
new file mode 100644
index 0000000..71f5b27
--- /dev/null
+++ b/core/lib/Drupal/Core/Config/ConfigFactory.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace Drupal\Core\Config;
+
+class ConfigFactory {
+  protected static $arbiters;
+
+  static function get($name, $class = 'Drupal\Core\Config\ConfigObject', $arbiter_class = 'Drupal\Core\Config\StorageArbiter') {
+    if (!isset(self::$arbiters[$arbiter_class])) {
+      self::$arbiters[$class] = new $arbiter_class();
+    }
+    return new $class($name, self::$arbiters[$class]);
+  }
+}
diff --git a/core/lib/Drupal/Core/Config/ConfigObject.php b/core/lib/Drupal/Core/Config/ConfigObject.php
new file mode 100644
index 0000000..3ba7ed0
--- /dev/null
+++ b/core/lib/Drupal/Core/Config/ConfigObject.php
@@ -0,0 +1,222 @@
+<?php
+
+namespace Drupal\Core\Config;
+
+/**
+ * Defines the default configuration object.
+ */
+class ConfigObject {
+
+  /**
+   * The name of the configuration object.
+   *
+   * @var string
+   */
+  protected $name;
+
+  /**
+   * The data of the configuration object.
+   *
+   * @var array
+   */
+  protected $data = array();
+
+  /**
+   * Constructs a configuration object.
+   *
+   * @param string $name
+   *   The name of the configuration object.
+   * @param Drupal\Core\Config\StorageArbiter $arbiter
+   *   The wrapping configuration manager object.
+   */
+  public function __construct($name, StorageArbiter $arbiter) {
+    $this->setName($name);
+    $this->storageArbiter = $arbiter;
+  }
+
+  /**
+   * Returns the name of this configuration object.
+   */
+  public function getName() {
+    return $this->name;
+  }
+
+  /**
+   * Sets the name of this configuration object.
+   */
+  public function setName($name) {
+    $this->name = $name;
+    return $this;
+  }
+
+  /**
+   * Gets data from this config object.
+   *
+   * @param $key
+   *   A string that maps to a key within the configuration data.
+   *   For instance in the following configuation array:
+   *   @code
+   *   array(
+   *     'foo' => array(
+   *       'bar' => 'baz',
+   *     ),
+   *   );
+   *   @endcode
+   *   A key of 'foo.bar' would return the string 'baz'. However, a key of 'foo'
+   *   would return array('bar' => 'baz').
+   *   If no key is specified, then the entire data array is returned.
+   *
+   * The configuration system does not retain data types. Every saved value is
+   * casted to a string. In most cases this is not an issue; however, it can
+   * cause issues with Booleans, which are casted to "1" (TRUE) or "0" (FALSE).
+   * In particular, code relying on === or !== will no longer function properly.
+   *
+   * @see http://php.net/manual/language.operators.comparison.php.
+   *
+   * @return
+   *   The data that was requested.
+   */
+  public function get($key = '') {
+    global $conf;
+
+    $name = $this->getName();
+    if (isset($conf[$name])) {
+      $merged_data = drupal_array_merge_deep($this->data, $conf[$name]);
+    }
+    else {
+      $merged_data = $this->data;
+    }
+
+    if (empty($key)) {
+      return $merged_data;
+    }
+    else {
+      $parts = explode('.', $key);
+      if (count($parts) == 1) {
+        return isset($merged_data[$key]) ? $merged_data[$key] : NULL;
+      }
+      else {
+        $key_exists = NULL;
+        $value = drupal_array_get_nested_value($merged_data, $parts, $key_exists);
+        return $key_exists ? $value : NULL;
+      }
+    }
+  }
+
+  /**
+   * Replaces the data of this configuration object.
+   *
+   * @param array $data
+   *   The new configuration data.
+   */
+  public function setData(array $data) {
+    $this->data = $data;
+    return $this;
+  }
+
+  /**
+   * Sets value in this config object.
+   *
+   * @param $key
+   *   @todo
+   * @param $value
+   *   @todo
+   */
+  public function set($key, $value) {
+    // Type-cast value into a string.
+    $value = $this->castValue($value);
+
+    // The dot/period is a reserved character; it may appear between keys, but
+    // not within keys.
+    $parts = explode('.', $key);
+    if (count($parts) == 1) {
+      $this->data[$key] = $value;
+    }
+    else {
+      drupal_array_set_nested_value($this->data, $parts, $value);
+    }
+    return $this;
+  }
+
+  /**
+   * Casts a saved value to a string.
+   *
+   * The configuration system only saves strings or arrays. Any scalar
+   * non-string value is cast to a string. The one exception is boolean FALSE
+   * which would normally become '' when cast to a string, but is manually
+   * cast to '0' here for convenience and consistency.
+   *
+   * Any non-scalar value that is not an array (aka objects) gets cast
+   * to an array.
+   *
+   * @param $value
+   *   A value being saved into the configuration system.
+   * @param $value
+   *   The value cast to a string or array.
+   */
+  public function castValue($value) {
+    if (is_scalar($value)) {
+      // Handle special case of FALSE, which should be '0' instead of ''.
+      if ($value === FALSE) {
+        $value = '0';
+      }
+      else {
+        $value = (string) $value;
+      }
+    }
+    else {
+      // Any non-scalar value must be an array.
+      if (!is_array($value)) {
+        $value = (array) $value;
+      }
+      // Recurse into any nested keys.
+      foreach ($value as $key => $nested_value) {
+        $value[$key] = $this->castValue($nested_value);
+      }
+    }
+    return $value;
+  }
+
+  /**
+   * Unsets value in this config object.
+   *
+   * @param $key
+   *   Name of the key whose value should be unset.
+   */
+  public function clear($key) {
+    $parts = explode('.', $key);
+    if (count($parts) == 1) {
+      unset($this->data[$key]);
+    }
+    else {
+      drupal_array_unset_nested_value($this->data, $parts);
+    }
+    return $this;
+  }
+
+  /**
+   * Loads configuration data into this object.
+   */
+  public function load() {
+    $data = $this->storageArbiter->selectStorage('read', $this->name)->read($this->name);
+    $this->setData($data !== FALSE ? $data : array());
+    return $this;
+  }
+
+  /**
+   * Saves the configuration object.
+   */
+  public function save() {
+    $this->storageArbiter->selectStorage('write', $this->name)->write($this->name, $this->data);
+    return $this;
+  }
+
+  /**
+   * Deletes the configuration object.
+   */
+  public function delete() {
+    $this->data = array();
+    $this->storageArbiter->selectStorage('write', $this->name)->delete($this->name);
+    return $this;
+  }
+}
diff --git a/core/lib/Drupal/Core/Config/DatabaseStorage.php b/core/lib/Drupal/Core/Config/DatabaseStorage.php
index c736245..27f5814 100644
--- a/core/lib/Drupal/Core/Config/DatabaseStorage.php
+++ b/core/lib/Drupal/Core/Config/DatabaseStorage.php
@@ -2,25 +2,52 @@
 
 namespace Drupal\Core\Config;
 
-use Drupal\Core\Config\StorageBase;
+use Drupal\Core\Config\StorageInterface;
+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.
+   *
+   * - target: The connection to use for storage operations.
+   *
+   * @var array
+   */
+  protected $options;
+
+  /**
+   * Implements StorageInterface::__construct().
+   */
+  public function __construct(array $info = array()) {
+    $info += array(
+      'target' => 'default',
+    );
+    $this->options = $info;
+  }
+
+  /**
+   * Returns the database connection to use.
+   */
+  protected function getConnection() {
+    return Database::getConnection($this->options['target']);
+  }
 
   /**
    * Implements StorageInterface::read().
    */
-  public function read() {
+  public function read($name) {
     // 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();
     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,22 +58,22 @@ class DatabaseStorage extends StorageBase {
   }
 
   /**
-   * Implements StorageInterface::writeToActive().
+   * Implements StorageInterface::write().
    */
-  public function writeToActive($data) {
+  public function write($name, array $data) {
     $data = $this->encode($data);
-    return db_merge('config')
-      ->key(array('name' => $this->name))
+    return $this->getConnection()->merge('config', $this->options)
+      ->key(array('name' => $name))
       ->fields(array('data' => $data))
       ->execute();
   }
 
   /**
-   * @todo
+   * Implements StorageInterface::delete().
    */
-  public function deleteFromActive() {
-    db_delete('config')
-      ->condition('name', $this->name)
+  public function delete($name) {
+    $this->getConnection()->delete('config', $this->options)
+      ->condition('name', $name)
       ->execute();
   }
 
diff --git a/core/lib/Drupal/Core/Config/DrupalConfig.php b/core/lib/Drupal/Core/Config/DrupalConfig.php
deleted file mode 100644
index f5a9220..0000000
--- a/core/lib/Drupal/Core/Config/DrupalConfig.php
+++ /dev/null
@@ -1,220 +0,0 @@
-<?php
-
-namespace Drupal\Core\Config;
-
-use Drupal\Core\Config\StorageInterface;
-use Drupal\Core\Config\ConfigException;
-
-/**
- * Represents the default configuration storage object.
- */
-class DrupalConfig {
-
-  /**
-   * The storage engine to save this config object to.
-   *
-   * @var StorageInterface
-   */
-  protected $storage;
-
-  /**
-   * The data of the configuration object.
-   *
-   * @var array
-   */
-  protected $data = array();
-
-  /**
-   * Constructs a DrupalConfig object.
-   *
-   * @param StorageInterface $storage
-   *   The storage engine where this config object should be saved.
-   *
-   * @todo $this should really know about $name and make it publicly accessible.
-   */
-  public function __construct(StorageInterface $storage) {
-    $this->storage = $storage;
-    $this->read();
-  }
-
-  /**
-   * Reads config data from the active store into our object.
-   */
-  public function read() {
-    $data = $this->storage->read();
-    $this->setData($data !== FALSE ? $data : array());
-    return $this;
-  }
-
-  /**
-   * Checks whether a particular value is overridden.
-   *
-   * @param $key
-   *   @todo
-   *
-   * @return
-   *   @todo
-   */
-  public function isOverridden($key) {
-    return isset($this->_overrides[$key]);
-  }
-
-  /**
-   * Gets data from this config object.
-   *
-   * @param $key
-   *   A string that maps to a key within the configuration data.
-   *   For instance in the following configuation array:
-   *   @code
-   *   array(
-   *     'foo' => array(
-   *       'bar' => 'baz',
-   *     ),
-   *   );
-   *   @endcode
-   *   A key of 'foo.bar' would return the string 'baz'. However, a key of 'foo'
-   *   would return array('bar' => 'baz').
-   *   If no key is specified, then the entire data array is returned.
-   *
-   * The configuration system does not retain data types. Every saved value is
-   * casted to a string. In most cases this is not an issue; however, it can
-   * cause issues with Booleans, which are casted to "1" (TRUE) or "0" (FALSE).
-   * In particular, code relying on === or !== will no longer function properly.
-   *
-   * @see http://php.net/manual/language.operators.comparison.php.
-   *
-   * @return
-   *   The data that was requested.
-   */
-  public function get($key = '') {
-    global $conf;
-
-    $name = $this->storage->getName();
-    if (isset($conf[$name])) {
-      $merged_data = drupal_array_merge_deep($this->data, $conf[$name]);
-    }
-    else {
-      $merged_data = $this->data;
-    }
-
-    if (empty($key)) {
-      return $merged_data;
-    }
-    else {
-      $parts = explode('.', $key);
-      if (count($parts) == 1) {
-        return isset($merged_data[$key]) ? $merged_data[$key] : NULL;
-      }
-      else {
-        $key_exists = NULL;
-        $value = drupal_array_get_nested_value($merged_data, $parts, $key_exists);
-        return $key_exists ? $value : NULL;
-      }
-    }
-  }
-
-  /**
-   * Replaces the data of this configuration object.
-   *
-   * @param array $data
-   *   The new configuration data.
-   */
-  public function setData(array $data) {
-    $this->data = $data;
-    return $this;
-  }
-
-  /**
-   * Sets value in this config object.
-   *
-   * @param $key
-   *   @todo
-   * @param $value
-   *   @todo
-   */
-  public function set($key, $value) {
-    // Type-cast value into a string.
-    $value = $this->castValue($value);
-
-    // The dot/period is a reserved character; it may appear between keys, but
-    // not within keys.
-    $parts = explode('.', $key);
-    if (count($parts) == 1) {
-      $this->data[$key] = $value;
-    }
-    else {
-      drupal_array_set_nested_value($this->data, $parts, $value);
-    }
-    return $this;
-  }
-
-  /**
-   * Casts a saved value to a string.
-   *
-   * The configuration system only saves strings or arrays. Any scalar
-   * non-string value is cast to a string. The one exception is boolean FALSE
-   * which would normally become '' when cast to a string, but is manually
-   * cast to '0' here for convenience and consistency.
-   *
-   * Any non-scalar value that is not an array (aka objects) gets cast
-   * to an array.
-   *
-   * @param $value
-   *   A value being saved into the configuration system.
-   * @param $value
-   *   The value cast to a string or array.
-   */
-  public function castValue($value) {
-    if (is_scalar($value)) {
-      // Handle special case of FALSE, which should be '0' instead of ''.
-      if ($value === FALSE) {
-        $value = '0';
-      }
-      else {
-        $value = (string) $value;
-      }
-    }
-    else {
-      // Any non-scalar value must be an array.
-      if (!is_array($value)) {
-        $value = (array) $value;
-      }
-      // Recurse into any nested keys.
-      foreach ($value as $key => $nested_value) {
-        $value[$key] = $this->castValue($nested_value);
-      }
-    }
-    return $value;
-  }
-
-  /**
-   * Unsets value in this config object.
-   *
-   * @param $key
-   *   Name of the key whose value should be unset.
-   */
-  public function clear($key) {
-    $parts = explode('.', $key);
-    if (count($parts) == 1) {
-      unset($this->data[$key]);
-    }
-    else {
-      drupal_array_unset_nested_value($this->data, $parts);
-    }
-  }
-
-  /**
-   * Saves the configuration object.
-   */
-  public function save() {
-    $this->storage->write($this->data);
-  }
-
-  /**
-   * Deletes the configuration object.
-   */
-  public function delete() {
-    $this->data = array();
-    $this->storage->delete();
-  }
-}
diff --git a/core/lib/Drupal/Core/Config/FileStorage.php b/core/lib/Drupal/Core/Config/FileStorage.php
index 2a6d448..9c1fc07 100644
--- a/core/lib/Drupal/Core/Config/FileStorage.php
+++ b/core/lib/Drupal/Core/Config/FileStorage.php
@@ -2,58 +2,31 @@
 
 namespace Drupal\Core\Config;
 
+use Drupal\Core\Config\StorageInterface;
 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 $info;
 
   /**
    * 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.
-   */
-  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 $info = array()) {
+    if (!isset($info['directory'])) {
+      $info['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->info = $info;
   }
 
   /**
@@ -62,8 +35,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->info['directory'] . '/' . $name . '.' . self::getFileExtension();
   }
 
   /**
@@ -82,8 +55,8 @@ 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));
   }
 
   /**
@@ -91,10 +64,10 @@ class FileStorage {
    *
    * @throws FileStorageException
    */
-  public function write($data) {
+  public function write($name, array $data) {
     $data = $this->encode($data);
-    if (!file_put_contents($this->getFilePath(), $data)) {
-      throw new FileStorageException('Failed to write configuration file: ' . $this->getFilePath());
+    if (!file_put_contents($this->getFilePath($name), $data)) {
+      throw new FileStorageException('Failed to write configuration file: ' . $this->getFilePath($name));
     }
   }
 
@@ -103,15 +76,15 @@ class FileStorage {
    *
    * @throws FileStorageReadException
    */
-  public function read() {
-    if (!$this->exists()) {
-      throw new FileStorageReadException("Configuration file '$this->name' does not exist.");
+  public function read($name) {
+    if (!$this->exists($name)) {
+      throw new FileStorageReadException("Configuration file '$name' does not exist.");
     }
 
-    $data = file_get_contents($this->getFilePath());
+    $data = file_get_contents($this->getFilePath($name));
     $data = $this->decode($data);
     if ($data === FALSE) {
-      throw new FileStorageReadException("Failed to decode configuration file '$this->name'.");
+      throw new FileStorageReadException("Failed to decode configuration file '$name'.");
     }
     return $data;
   }
@@ -119,9 +92,9 @@ class FileStorage {
   /**
    * Deletes a configuration file.
    */
-  public function delete() {
+  public function delete($name) {
     // Needs error handling and etc.
-    @drupal_unlink($this->getFilePath());
+    @drupal_unlink($this->getFilePath($name));
   }
 
   /**
@@ -144,25 +117,11 @@ class FileStorage {
   }
 
   /**
-   * Implements StorageInterface::getName().
-   */
-  public function getName() {
-    return $this->name;
-  }
-
-  /**
-   * Implements StorageInterface::setName().
-   */
-  public function setName($name) {
-    $this->name = $name;
-  }
-
-  /**
    * Implements StorageInterface::getNamesWithPrefix().
+   *
+   * @todo Allow to search for files in custom paths.
    */
   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());
diff --git a/core/lib/Drupal/Core/Config/StorageArbiter.php b/core/lib/Drupal/Core/Config/StorageArbiter.php
new file mode 100644
index 0000000..f169bd4
--- /dev/null
+++ b/core/lib/Drupal/Core/Config/StorageArbiter.php
@@ -0,0 +1,114 @@
+<?php
+
+namespace Drupal\Core\Config;
+
+/**
+ * Arbiters configuration storage engines.
+ *
+ * A high-level storage manager that determines which storage out of multiple
+ * is configured and allowed to handle a particular configuration object,
+ * depending on the read/write operation being performed.
+ *
+ * The information about available storage controllers and their configuration
+ * options is passed once into the constructor and normally should not change
+ * within a single request or context. Special use-cases, such as import and
+ * export operations, should instantiate a custom configuration manager tailored
+ * to their application needs.
+ *
+ * The configuration manager instantiates storage controllers on demand, and
+ * only once per storage.
+ *
+ * @see Drupal\Core\Config\StorageInterface
+ */
+class StorageArbiter {
+
+  /**
+   * Information about available storage controllers.
+   *
+   * @var array
+   */
+  protected $storageInfo;
+
+  /**
+   * Instantiated storage controller objects.
+   *
+   * @see Drupal\Core\Config\StorageInterface
+   *
+   * @var array
+   */
+  protected $storageInstances;
+
+  /**
+   * Constructs a StorageArbiter object.
+   *
+   * @param array $storage_info
+   *   An associative array defining the storage controllers to use and any
+   *   required configuration for them; e.g.:
+   *   @code
+   *   array(
+   *     'Drupal\Core\Config\DatabaseStorage' => array(
+   *       'target' => 'default',
+   *       'read' => TRUE,
+   *       'write' => TRUE,
+   *     ),
+   *     'Drupal\Core\Config\FileStorage' => array(
+   *       'directory' => 'sites/default/files/config',
+   *       'read' => TRUE,
+   *       'write' => FALSE,
+   *     ),
+   *   )
+   *   @endcode
+   */
+  public function __construct($storage_info = NULL) {
+    if (isset($storage_info)) {
+      $this->storageInfo = $storage_info;
+    }
+    else {
+      $this->storageInfo = array(
+        'Drupal\Core\Config\DatabaseStorage' => array(
+         'target' => 'default',
+         'read' => TRUE,
+         'write' => TRUE,
+        ),
+        'Drupal\Core\Config\FileStorage' => array(
+         'directory' => config_get_config_directory(),
+         'read' => TRUE,
+         'write' => TRUE,
+        ),
+      );
+    }
+  }
+
+  /**
+   * Returns a storage controller to use for a given operation.
+   *
+   * Handles the core functionality of the configuration manager by determining
+   * which storage can handle a particular configuration object, depending on
+   * the operation being performed.
+   *
+   * @param string $access_operation
+   *   The operation access level; either 'read' or 'write'. Use 'write' both
+   *   for saving and deleting configuration.
+   * @param string $name
+   *   The name of the configuration object that is operated on.
+   */
+  public function selectStorage($access_operation, $name) {
+    // Determine the appropriate storage controller to use.
+    // Take the first defined storage that allows $op.
+    foreach ($this->storageInfo as $class => $storage_config) {
+      if (!empty($storage_config[$access_operation])) {
+        $storage_class = $class;
+        break;
+      }
+    }
+    if (!isset($storage_class)) {
+      throw new ConfigException("Failed to find storage controller that allows $access_operation access for $name.");
+    }
+
+    // Instantiate a new storage controller object, if there is none yet.
+    if (!isset($this->storageInstances[$storage_class])) {
+      $this->storageInstances[$storage_class] = new $storage_class($this->storageInfo[$storage_class]);
+    }
+    return $this->storageInstances[$storage_class];
+  }
+}
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/StorageInterface.php b/core/lib/Drupal/Core/Config/StorageInterface.php
index 43141a5..e3ed848 100644
--- a/core/lib/Drupal/Core/Config/StorageInterface.php
+++ b/core/lib/Drupal/Core/Config/StorageInterface.php
@@ -7,74 +7,43 @@ namespace Drupal\Core\Config;
  *
  * 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.
+   * @param array $info
+   *   An associative array containing configuration options specific to the
+   *   storage controller.
    */
-  function copyToFile();
+  public function __construct(array $info = array());
 
   /**
-   * Copies the configuration data from the file into the storage.
-   */
-  function copyFromFile();
-
-  /**
-   * Deletes the configuration data file.
-   */
-  function deleteFile();
-
-  /**
-   * 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.
+   * @param string $name
+   *   The name of a configuration object to load.
    */
-  function isOutOfSync();
+  public function read($name);
 
   /**
-   * Writes the configuration data into the active storage and the file.
+   * Writes configuration data to the storage.
    *
-   * @param $data
+   * @param string $name
+   *   The name of a configuration object to save.
+   * @param array $data
    *   The configuration data to write.
    */
-  function write($data);
-
-  /**
-   * Writes the configuration data into the active storage but not the file.
-   *
-   * Use this function if you need to make temporary changes to your
-   * configuration.
-   *
-   * @param $data
-   *   The configuration data to write into active storage.
-   */
-  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.
    */
-  function writeToFile($data);
+  public function delete($name);
 
   /**
    * Encodes configuration data into the storage-specific format.
@@ -105,16 +74,6 @@ 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:
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigFileContentTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigFileContentTest.php
index bfd27ac..36ab251 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;
 
@@ -34,7 +35,6 @@ class ConfigFileContentTest extends WebTestBase {
    * Tests setting, writing, and reading of a configuration setting.
    */
   function testReadWriteConfig() {
-    $config_dir = config_get_config_directory();
     $name = 'foo.bar';
     $key = 'foo';
     $value = 'bar';
@@ -71,7 +71,6 @@ class ConfigFileContentTest extends WebTestBase {
     // 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.');
 
     // Add a top level value
     $config = config($name);
@@ -100,9 +99,6 @@ class ConfigFileContentTest extends WebTestBase {
     $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.'));
-
     // Read top level value
     $config = config($name);
 //    $this->assertEqual($config->name, $name);
@@ -161,27 +157,24 @@ class ConfigFileContentTest extends WebTestBase {
     $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.'));
-
     // Get file listing for all files starting with 'foo'. Should return
     // two elements.
-    $files = FileStorage::getNamesWithPrefix('foo');
+    $files = DatabaseStorage::getNamesWithPrefix('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 = DatabaseStorage::getNamesWithPrefix('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 = DatabaseStorage::getNamesWithPrefix('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 = DatabaseStorage::getNamesWithPrefix('bar');
     $this->assertEqual($files, array(), 'No files listed with the prefix \'bar\'.');
 
     // Delete the configuration.
@@ -191,9 +184,6 @@ class ConfigFileContentTest extends WebTestBase {
     // 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.
   }
 
   /**
@@ -216,17 +206,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
index 5f9ec07..ae80fb2 100644
--- a/core/modules/config/lib/Drupal/config/Tests/ConfigFileSecurityTest.php
+++ b/core/modules/config/lib/Drupal/config/Tests/ConfigFileSecurityTest.php
@@ -30,17 +30,14 @@ class ConfigFileSecurityTest extends WebTestBase {
    * 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);
+    $file = new FileStorage();
+    $file->write($this->filename, $this->testContent);
 
     // 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();
+      $saved_content = $file->read($this->filename);
 
       $this->assertEqual($saved_content, $this->testContent);
     }
