diff --git a/core/lib/Drupal/Core/Config/Schema/core.data_types.schema.yml b/core/config/schema/core.data_types.schema.yml
similarity index 100%
rename from core/lib/Drupal/Core/Config/Schema/core.data_types.schema.yml
rename to core/config/schema/core.data_types.schema.yml
diff --git a/core/core.services.yml b/core/core.services.yml
index 0c038ec..fefb50b 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -64,18 +64,9 @@ services:
     factory_method: get
     factory_service: cache_factory
     arguments: [path]
-  config.cachedstorage.storage:
-    class: Drupal\Core\Config\FileStorage
-    factory_class: Drupal\Core\Config\FileStorageFactory
-    factory_method: getActive
   config.manager:
     class: Drupal\Core\Config\ConfigManager
     arguments: ['@entity.manager', '@config.factory', '@config.typed', '@string_translation']
-  config.storage:
-    class: Drupal\Core\Config\CachedStorage
-    arguments: ['@config.cachedstorage.storage', '@cache.config']
-    tags:
-      - { name: persist }
   config.factory:
     class: Drupal\Core\Config\ConfigFactory
     tags:
@@ -85,6 +76,15 @@ services:
   config.installer:
     class: Drupal\Core\Config\ConfigInstaller
     arguments: ['@config.factory', '@config.storage', '@config.typed', '@config.manager', '@event_dispatcher']
+  config.storage:
+    class: Drupal\Core\Config\CachedStorage
+    arguments: ['@config.storage.active', '@cache.config']
+    tags:
+      - { name: persist }
+  config.storage.active:
+    class: Drupal\Core\Config\FileStorage
+    factory_class: Drupal\Core\Config\FileStorageFactory
+    factory_method: getActive
   config.storage.staging:
     class: Drupal\Core\Config\FileStorage
     factory_class: Drupal\Core\Config\FileStorageFactory
@@ -118,7 +118,7 @@ services:
     arguments: ['@service_container', '@settings']
   keyvalue.database:
     class: Drupal\Core\KeyValueStore\KeyValueDatabaseFactory
-    arguments: ['@database']
+    arguments: ['@database', '@serialization.phpserialize']
   keyvalue.expirable:
     class: Drupal\Core\KeyValueStore\KeyValueExpirableFactory
     arguments: ['@service_container', '@settings']
@@ -127,6 +127,16 @@ services:
     tags:
       - { name: needs_destruction }
     arguments: ['@database']
+
+  serialization.json:
+    class: Drupal\Core\Serialization\Json
+  serialization.phpserialize:
+    class: Drupal\Core\Serialization\PhpSerialize
+  serialization.xml:
+    class: Drupal\Core\Serialization\Xml
+  serialization.yaml:
+    class: Drupal\Core\Serialization\Yaml
+
   settings:
     class: Drupal\Component\Utility\Settings
     factory_class: Drupal\Component\Utility\Settings
diff --git a/core/lib/Drupal/Core/Config/BootstrapConfigStorageFactory.php b/core/lib/Drupal/Core/Config/BootstrapConfigStorageFactory.php
index 054e690..8688ed6 100644
--- a/core/lib/Drupal/Core/Config/BootstrapConfigStorageFactory.php
+++ b/core/lib/Drupal/Core/Config/BootstrapConfigStorageFactory.php
@@ -26,7 +26,7 @@ public static function get() {
       return call_user_func($drupal_bootstrap_config_storage);
     }
     else {
-      return new FileStorage(config_get_config_directory(CONFIG_ACTIVE_DIRECTORY));
+      return FileStorageFactory::getActive();
     }
   }
 
diff --git a/core/lib/Drupal/Core/Config/Config.php b/core/lib/Drupal/Core/Config/Config.php
index e000200..95f724c 100644
--- a/core/lib/Drupal/Core/Config/Config.php
+++ b/core/lib/Drupal/Core/Config/Config.php
@@ -12,6 +12,7 @@
 use Drupal\Core\Config\ConfigNameException;
 use Drupal\Core\Config\Schema\SchemaIncompleteException;
 use Drupal\Core\DependencyInjection\DependencySerialization;
+use Drupal\Core\Serialization\Exception\InvalidDataTypeException;
 use Drupal\Core\TypedData\PrimitiveInterface;
 use Drupal\Core\TypedData\Type\FloatInterface;
 use Drupal\Core\TypedData\Type\IntegerInterface;
@@ -533,7 +534,7 @@ protected function getSchemaWrapper() {
    * @return mixed
    *   The value cast to the type indicated in the schema.
    *
-   * @throws \Drupal\Core\Config\UnsupportedDataTypeConfigException
+   * @throws \Drupal\Core\Serialization\Exception\InvalidDataTypeException
    *   Exception on unsupported/undefined data type deducted.
    */
   protected function castValue($key, $value) {
@@ -572,7 +573,7 @@ protected function castValue($key, $value) {
     else {
       // Throw exception on any non-scalar or non-array value.
       if (!is_array($value)) {
-        throw new UnsupportedDataTypeConfigException(String::format('Invalid data type for config element @name:@key', array(
+        throw new InvalidDataTypeException(String::format('Invalid data type for config element @name:@key', array(
           '@name' => $this->getName(),
           '@key' => $key,
         )));
diff --git a/core/lib/Drupal/Core/Config/ConfigInstaller.php b/core/lib/Drupal/Core/Config/ConfigInstaller.php
index 2bb06b3..abd52b5 100644
--- a/core/lib/Drupal/Core/Config/ConfigInstaller.php
+++ b/core/lib/Drupal/Core/Config/ConfigInstaller.php
@@ -86,7 +86,7 @@ public function installDefaultConfig($type, $name) {
         // extension has a configuration schema directory.
         $this->typedConfig->clearCachedDefinitions();
       }
-      $default_storage = new FileStorage($config_dir);
+      $default_storage = FileStorageFactory::getExtension($config_dir);
       $other_module_config = array_filter($default_storage->listAll(), function ($value) use ($name) {
         return !preg_match('/^' . $name . '\./', $value);
       });
diff --git a/core/lib/Drupal/Core/Config/ExtensionInstallStorage.php b/core/lib/Drupal/Core/Config/ExtensionInstallStorage.php
index 5bedbbe..d43339a 100644
--- a/core/lib/Drupal/Core/Config/ExtensionInstallStorage.php
+++ b/core/lib/Drupal/Core/Config/ExtensionInstallStorage.php
@@ -29,8 +29,9 @@ class ExtensionInstallStorage extends InstallStorage {
    *   The active configuration store where the list of enabled modules and
    *   themes is stored.
    */
-  public function __construct(StorageInterface $config_storage) {
+  public function __construct(StorageInterface $config_storage, $collection = '') {
     $this->configStorage = $config_storage;
+    parent::__construct($collection);
   }
 
   /**
@@ -57,11 +58,15 @@ protected function getAllFolders() {
       $this->folders = array();
       $modules = $this->configStorage->read('system.module');
       if (isset($modules['enabled'])) {
-        $this->folders += $this->getComponentNames('module', array_keys($modules['enabled']));
+        foreach (array_keys($modules['enabled']) as $name) {
+          $this->folders[$name] = drupal_get_path('module', $name);
+        }
       }
       $themes = $this->configStorage->read('system.theme');
       if (isset($themes['enabled'])) {
-        $this->folders += $this->getComponentNames('theme', array_keys($themes['enabled']));
+        foreach (array_keys($themes['enabled']) as $name) {
+          $this->folders[$name] = drupal_get_path('theme', $name);
+        }
       }
     }
     return $this->folders;
diff --git a/core/lib/Drupal/Core/Config/FileStorage.php b/core/lib/Drupal/Core/Config/FileStorage.php
index 2df9fbd..a2f0273 100644
--- a/core/lib/Drupal/Core/Config/FileStorage.php
+++ b/core/lib/Drupal/Core/Config/FileStorage.php
@@ -7,55 +7,18 @@
 
 namespace Drupal\Core\Config;
 
-use Drupal\Component\Utility\String;
-use Symfony\Component\Yaml\Dumper;
-use Symfony\Component\Yaml\Exception\DumpException;
-use Symfony\Component\Yaml\Parser;
+use Drupal\Core\KeyValueStore\FileStorage as KeyValueFileStorage;
 
 /**
  * Defines the file storage controller.
+ *
+ * @todo Remove Boolean return values from write/delete methods.
+ * @todo Change read method return value for missing key from FALSE to NULL.
  */
-class FileStorage implements StorageInterface {
+class FileStorage extends KeyValueFileStorage implements StorageInterface {
 
-  /**
-   * The filesystem path for configuration objects.
-   *
-   * @var string
-   */
-  protected $directory = '';
-
-  /**
-   * A shared YAML dumper instance.
-   *
-   * @var Symfony\Component\Yaml\Dumper
-   */
-  protected $dumper;
-
-  /**
-   * A shared YAML parser instance.
-   *
-   * @var Symfony\Component\Yaml\Parser
-   */
-  protected $parser;
-
-  /**
-   * Constructs a new FileStorage controller.
-   *
-   * @param string $directory
-   *   A directory path to use for reading and writing of configuration files.
-   */
-  public function __construct($directory) {
-    $this->directory = $directory;
-  }
-
-  /**
-   * Returns the path to the configuration file.
-   *
-   * @return string
-   *   The path to the configuration file.
-   */
   public function getFilePath($name) {
-    return $this->directory . '/' . $name . '.' . static::getFileExtension();
+    return $this->getPathname($name);
   }
 
   /**
@@ -68,177 +31,83 @@ public static function getFileExtension() {
     return 'yml';
   }
 
-  /**
-   * Implements Drupal\Core\Config\StorageInterface::exists().
-   */
   public function exists($name) {
-    return file_exists($this->getFilePath($name));
+    return $this->has($name);
   }
 
-  /**
-   * Implements Drupal\Core\Config\StorageInterface::read().
-   *
-   * @throws Symfony\Component\Yaml\Exception\ParseException
-   */
   public function read($name) {
-    if (!$this->exists($name)) {
+    $value = $this->get($name, FALSE);
+    if (!is_array($value)) {
       return FALSE;
     }
-    $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);
-    return $data;
+    return $value;
   }
 
-  /**
-   * {@inheritdoc}
-   */
   public function readMultiple(array $names) {
-    $list = array();
-    foreach ($names as $name) {
-      if ($data = $this->read($name)) {
-        $list[$name] = $data;
+    $values = $this->getMultiple($names);
+    foreach ($values as $key => $value) {
+      if (!is_array($value)) {
+        $values[$key] = FALSE;
       }
     }
-    return $list;
+    return $values;
   }
 
   /**
    * Implements Drupal\Core\Config\StorageInterface::write().
    *
-   * @throws \Drupal\Core\Config\UnsupportedDataTypeConfigException
-   * @throws \Drupal\Core\Config\StorageException
+   * @throws \Drupal\Core\Serialization\Exception\InvalidDataTypeException
    */
   public function write($name, array $data) {
-    try {
-      $data = $this->encode($data);
-    }
-    catch(DumpException $e) {
-      throw new UnsupportedDataTypeConfigException(String::format('Invalid data type for used in config: @name', array('@name' => $name)));
-    }
-
-    $target = $this->getFilePath($name);
-    $status = @file_put_contents($target, $data);
-    if ($status === FALSE) {
-      throw new StorageException('Failed to write configuration file: ' . $this->getFilePath($name));
-    }
-    else {
-      drupal_chmod($target);
-    }
+    $this->set($name, $data);
     return TRUE;
   }
 
-  /**
-   * Implements Drupal\Core\Config\StorageInterface::delete().
-   */
-  public function delete($name) {
-    if (!$this->exists($name)) {
-      if (!file_exists($this->directory)) {
-        throw new StorageException($this->directory . '/ not found.');
-      }
-      return FALSE;
-    }
-    return drupal_unlink($this->getFilePath($name));
-  }
-
-  /**
-   * Implements Drupal\Core\Config\StorageInterface::rename().
-   */
   public function rename($name, $new_name) {
-    $status = @rename($this->getFilePath($name), $this->getFilePath($new_name));
-    if ($status === FALSE) {
-      throw new StorageException('Failed to rename configuration file from: ' . $this->getFilePath($name) . ' to: ' . $this->getFilePath($new_name));
+    if ($this->has($new_name)) {
+      return FALSE;
     }
+    $value = $this->get($name);
+    $this->delete($name);
+    $this->set($new_name, $value);
     return TRUE;
   }
 
-  /**
-   * Gets the YAML dumper instance.
-   *
-   * @return Symfony\Component\Yaml\Dumper
-   */
-  protected function getDumper() {
-    if (!isset($this->dumper)) {
-      $this->dumper = new Dumper();
-      // Set Yaml\Dumper's default indentation for nested nodes/collections to
-      // 2 spaces for consistency with Drupal coding standards.
-      $this->dumper->setIndentation(2);
-    }
-    return $this->dumper;
-  }
-
-  /**
-   * Gets the YAML parser instance.
-   *
-   * @return Symfony\Component\Yaml\Parser
-   */
-  protected function getParser() {
-    if (!isset($this->parser)) {
-      $this->parser = new Parser();
-    }
-    return $this->parser;
-  }
-
-  /**
-   * Implements Drupal\Core\Config\StorageInterface::encode().
-   *
-   * @throws Symfony\Component\Yaml\Exception\DumpException
-   */
   public function encode($data) {
-    // The level where you switch to inline YAML is set to PHP_INT_MAX to ensure
-    // this does not occur. Also set the exceptionOnInvalidType parameter to
-    // TRUE, so exceptions are thrown for an invalid data type.
-    return $this->getDumper()->dump($data, PHP_INT_MAX, 0, TRUE);
+    return $this->format->encode($data);
   }
 
-  /**
-   * Implements Drupal\Core\Config\StorageInterface::decode().
-   *
-   * @throws Symfony\Component\Yaml\Exception\ParseException
-   */
   public function decode($raw) {
-    $data = $this->getParser()->parse($raw);
-    // A simple string is valid YAML for any reason.
-    if (!is_array($data)) {
-      return FALSE;
-    }
-    return $data;
+    return $this->format->decode($raw);
   }
 
-  /**
-   * Implements Drupal\Core\Config\StorageInterface::listAll().
-   */
   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->directory)) {
-      throw new StorageException($this->directory . '/ not found.');
-    }
-    $extension = '.' . static::getFileExtension();
-    // \GlobIterator on Windows requires an absolute path.
-    $files = new \GlobIterator(realpath($this->directory) . '/' . $prefix . '*' . $extension);
-
+    // @todo Add KeyValueStoreInterface::listKeys().
     $names = array();
-    foreach ($files as $file) {
-      $names[] = $file->getBasename($extension);
+    foreach ($this->getIterator($prefix) as $file) {
+      $names[] = $file->getBasename('.' . $this->format->getFileExtension());
     }
-
     return $names;
   }
 
-  /**
-   * Implements Drupal\Core\Config\StorageInterface::deleteAll().
-   */
+  public function delete($key) {
+    parent::delete($key);
+    return TRUE;
+  }
+
+  public function deleteMultiple(array $keys) {
+    parent::deleteMultiple($keys);
+    return TRUE;
+  }
+
   public function deleteAll($prefix = '') {
-    $success = TRUE;
-    $files = $this->listAll($prefix);
-    foreach ($files as $name) {
-      if (!$this->delete($name) && $success) {
-        $success = FALSE;
-      }
+    if ($prefix === '') {
+      parent::deleteAll();
+      return TRUE;
     }
-
-    return $success;
+    foreach ($this->listAll($prefix) as $name) {
+      $this->delete($name);
+    }
+    return TRUE;
   }
 }
diff --git a/core/lib/Drupal/Core/Config/FileStorageFactory.php b/core/lib/Drupal/Core/Config/FileStorageFactory.php
index 1768df4..ea50dfb 100644
--- a/core/lib/Drupal/Core/Config/FileStorageFactory.php
+++ b/core/lib/Drupal/Core/Config/FileStorageFactory.php
@@ -6,6 +6,8 @@
 
 namespace Drupal\Core\Config;
 
+use Drupal\Core\Serialization\Yaml;
+
 /**
  * Provides a factory for creating config file storage objects.
  */
@@ -17,7 +19,7 @@ class FileStorageFactory {
    * @return \Drupal\Core\Config\FileStorage FileStorage
    */
   static function getActive() {
-    return new FileStorage(config_get_config_directory(CONFIG_ACTIVE_DIRECTORY));
+    return new FileStorage('', new Yaml(), config_get_config_directory(CONFIG_ACTIVE_DIRECTORY));
   }
 
   /**
@@ -26,7 +28,19 @@ static function getActive() {
    * @return \Drupal\Core\Config\FileStorage FileStorage
    */
   static function getStaging() {
-    return new FileStorage(config_get_config_directory(CONFIG_STAGING_DIRECTORY));
+    return new FileStorage('', new Yaml(), config_get_config_directory(CONFIG_STAGING_DIRECTORY));
+  }
+
+  /**
+   * Returns a FileStorage object working with an extension's config directory.
+   *
+   * @param string $config_dir
+   *   The filesystem path of the extension's config directory.
+   *
+   * @return \Drupal\Core\Config\FileStorage
+   */
+  static function getExtension($config_dir) {
+    return new FileStorage('', new Yaml(), $config_dir);
   }
 
 }
diff --git a/core/lib/Drupal/Core/Config/InstallStorage.php b/core/lib/Drupal/Core/Config/InstallStorage.php
index 16bcc1c..eaddd78 100644
--- a/core/lib/Drupal/Core/Config/InstallStorage.php
+++ b/core/lib/Drupal/Core/Config/InstallStorage.php
@@ -7,9 +7,20 @@
 
 namespace Drupal\Core\Config;
 
+use Drupal\Core\Serialization\Yaml;
+
 /**
  * Storage controller used by the Drupal installer.
  *
+ * In essence, this is a clustered/sharded key/value store, which reads from
+ * multiple storage bins. Theoretically, each cluster/bin contains the keys for
+ * a certain key namespace only.
+ *
+ * However, since modules can additionally ship with integration configuration
+ * for already installed modules, and those keys need to be discovered in the
+ * cluster/bin namespace of the module to be installed, the otherwise simple
+ * concept of namespaced key clusters is muddied.
+ *
  * @see install_begin_request()
  */
 class InstallStorage extends FileStorage {
@@ -22,38 +33,23 @@ class InstallStorage extends FileStorage {
   protected $folders;
 
   /**
-   * Overrides Drupal\Core\Config\FileStorage::__construct().
+   * The subdirectory name to scan in each extension directory.
+   *
+   * This does not include the collection.
+   *
+   * @var string
    */
-  public function __construct() {
-  }
+  protected $subpath;
 
   /**
-   * Overrides Drupal\Core\Config\FileStorage::getFilePath().
-   *
-   * Returns the path to the configuration file.
-   *
-   * Determines the owner and path to the default configuration file of a
-   * requested config object name located in the installation profile, a module,
-   * or a theme (in this order).
-   *
-   * @return string
-   *   The path to the configuration file.
-   *
-   * @todo Improve this when figuring out how we want to handle configuration in
-   *   installation profiles. E.g., a config object actually has to be searched
-   *   in the profile first (whereas the profile is never the owner), only
-   *   afterwards check for a corresponding module or theme.
+   * Overrides Drupal\Core\Config\FileStorage::__construct().
    */
-  public function getFilePath($name) {
-    $folders = $this->getAllFolders();
-    if (isset($folders[$name])) {
-      return $folders[$name] . '/' . $name . '.' . $this->getFileExtension();
+  public function __construct($collection = '', $subpath = 'config') {
+    parent::__construct($collection, new Yaml(), 'unused');
+    $this->subpath = $subpath;
+    if ($collection !== '') {
+      $this->subpath .= '/' . $collection;
     }
-    // If any code in the early installer requests a configuration object that
-    // does not exist anywhere as default config, then that must be mistake.
-    throw new StorageException(format_string('Missing configuration file: @name', array(
-      '@name' => $name,
-    )));
   }
 
   /**
@@ -62,7 +58,7 @@ public function getFilePath($name) {
    * @throws \Drupal\Core\Config\StorageException
    */
   public function write($name, array $data) {
-    throw new StorageException('Write operation is not allowed during install.');
+    throw new StorageException('Write operation is not allowed.');
   }
 
   /**
@@ -71,7 +67,7 @@ public function write($name, array $data) {
    * @throws \Drupal\Core\Config\StorageException
    */
   public function delete($name) {
-    throw new StorageException('Delete operation is not allowed during install.');
+    throw new StorageException('Delete operation is not allowed.');
   }
 
   /**
@@ -80,82 +76,54 @@ public function delete($name) {
    * @throws \Drupal\Core\Config\StorageException
    */
   public function rename($name, $new_name) {
-    throw new StorageException('Rename operation is not allowed during install.');
+    throw new StorageException('Rename operation is not allowed.');
   }
 
   /**
-   * Implements Drupal\Core\Config\StorageInterface::listAll().
+   * Overrides \Drupal\Core\KeyValueStore\FileStorage::getPathname().
    */
-  public function listAll($prefix = '') {
-    $names = array_keys($this->getAllFolders());
-    if (!$prefix) {
-      return $names;
-    }
-    else {
-      $return = array();
-      foreach ($names as $index => $name) {
-        if (strpos($name, $prefix) === 0 ) {
-          $return[$index] = $names[$index];
-        }
+  protected function getPathname($key) {
+    foreach ($this->getIterator($key) as $file) {
+      if ($file->getBasename('.' . $this->format->getFileExtension()) == $key) {
+        return $file->getPathname();
       }
-      return $return;
     }
   }
 
   /**
-   * Returns a map of all config object names and their folders.
-   *
-   * @return array
-   *   An array mapping config object names with directories.
+   * Overrides \Drupal\Core\KeyValueStore\FileStorage::getIterator().
    */
-  protected function getAllFolders() {
-    if (!isset($this->folders)) {
-      $this->folders = $this->getComponentNames('profile', array(drupal_get_profile()));
-      $this->folders += $this->getComponentNames('module', array_keys(drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules', 'name', 0)));
-      $this->folders += $this->getComponentNames('theme', array_keys(drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info.yml$/', 'themes')));
+  protected function getIterator($prefix = '') {
+    $iterator = new \AppendIterator();
+    foreach ($this->getAllFolders() as $extension_path) {
+      $path = DRUPAL_ROOT . '/' . $extension_path . '/' . $this->subpath;
+      if (is_dir($path)) {
+        $git = new \GlobIterator("$path/$prefix*." . $this->format->getFileExtension());
+        $iterator->append($git);
+      }
     }
-    return $this->folders;
+    return $iterator;
   }
 
   /**
-   * Get all configuration names and folders for a list of modules or themes.
-   *
-   * @param string $type
-   *   Type of components: 'module' | 'theme' | 'profile'
-   * @param array $list
-   *   Array of theme or module names.
+   * Returns a list of all directory paths to be scanned.
    *
    * @return array
-   *   Folders indexed by configuration name.
    */
-  public function getComponentNames($type, array $list) {
-    $extension = '.' . $this->getFileExtension();
-    $folders = array();
-    foreach ($list as $name) {
-      $directory = $this->getComponentFolder($type, $name);
-      if (file_exists($directory)) {
-        $files = new \GlobIterator(DRUPAL_ROOT . '/' . $directory . '/*' . $extension);
-        foreach ($files as $file) {
-          $folders[$file->getBasename($extension)] = $directory;
-        }
-      }
+  protected function getAllFolders() {
+    if (!isset($this->folders)) {
+      $profile = drupal_get_profile();
+      $this->folders = array($profile => drupal_get_path('profile', $profile));
+      $modules = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules');
+      ksort($modules);
+      $themes = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info\.yml$/', 'themes');
+      ksort($themes);
+      $folders = $modules + $themes;
+      $this->folders += array_map(function ($file) {
+        return dirname($file->uri);
+      }, $folders);
     }
-    return $folders;
-  }
-
-  /**
-   * Get folder inside each component that contains the files.
-   *
-   * @param string $type
-   *   Component type: 'module' | 'theme' | 'profile'
-   * @param string $name
-   *   Component name.
-   *
-   * @return string
-   *   The configuration folder name for this component.
-   */
-  protected function getComponentFolder($type, $name) {
-    return drupal_get_path($type, $name) . '/config';
+    return $this->folders;
   }
 
   /**
@@ -164,7 +132,7 @@ protected function getComponentFolder($type, $name) {
    * @throws \Drupal\Core\Config\StorageException
    */
   public function deleteAll($prefix = '') {
-    throw new StorageException('Delete operation is not allowed during install.');
+    throw new StorageException('Delete operation is not allowed.');
   }
 
 }
diff --git a/core/lib/Drupal/Core/Config/Schema/SchemaStorage.php b/core/lib/Drupal/Core/Config/Schema/SchemaStorage.php
index 1b84dec..bce4b6f 100644
--- a/core/lib/Drupal/Core/Config/Schema/SchemaStorage.php
+++ b/core/lib/Drupal/Core/Config/Schema/SchemaStorage.php
@@ -9,51 +9,25 @@
 
 use Drupal\Core\Config\ExtensionInstallStorage;
 use Drupal\Core\Config\StorageException;
+use Drupal\Core\Config\StorageInterface;
 
 /**
  * Defines the file storage controller for metadata files.
  */
 class SchemaStorage extends ExtensionInstallStorage {
 
-  /**
-   * Implements \Drupal\Core\Config\StorageInterface::exists().
-   */
-  public function exists($name) {
-    return array_key_exists($name, $this->getAllFolders());
-  }
-
-  /**
-   * Overrides \Drupal\Core\Config\InstallStorage::getComponentFolder().
-   */
-  protected function getComponentFolder($type, $name) {
-    return drupal_get_path($type, $name) . '/config/schema';
-  }
-
-  /**
-   * Overrides \Drupal\Core\Config\InstallStorage::write().
-   *
-   * @throws \Drupal\Core\Config\StorageException
-   */
-  public function write($name, array $data) {
-    throw new StorageException('Write operation is not allowed for config schema storage.');
-  }
-
-  /**
-   * Overrides \Drupal\Core\Config\InstallStorage::delete().
-   *
-   * @throws \Drupal\Core\Config\StorageException
-   */
-  public function delete($name) {
-    throw new StorageException('Delete operation is not allowed for config schema storage.');
+  public function __construct(StorageInterface $config_storage) {
+    parent::__construct($config_storage, 'schema');
   }
 
-  /**
-   * Overrides \Drupal\Core\Config\InstallStorage::rename().
-   *
-   * @throws \Drupal\Core\Config\StorageException
-   */
-  public function rename($name, $new_name) {
-    throw new StorageException('Rename operation is not allowed for config schema storage.');
+  public function readMultiple(array $names) {
+    $values = parent::readMultiple($names);
+    foreach ($values as $name => $value) {
+      if (empty($value)) {
+        throw new SchemaIncompleteException("Missing configuration schema for $name.");
+      }
+    }
+    return $values;
   }
 
   /**
@@ -67,21 +41,9 @@ public function rename($name, $new_name) {
   protected function getAllFolders() {
     if (!isset($this->folders)) {
       parent::getAllFolders();
-      $this->folders += $this->getBaseDataTypeSchema();
+      $this->folders['core'] = 'core';
     }
     return $this->folders;
   }
 
-  /**
-   * Gets the base data types for configuration schema.
-   *
-   * @return array
-   *   The file containing the base data types for configuration schema.
-   */
-  protected function getBaseDataTypeSchema() {
-    return array(
-      'core.data_types.schema' => 'core/lib/Drupal/Core/Config/Schema'
-    );
-  }
-
 }
diff --git a/core/lib/Drupal/Core/Config/UnsupportedConfigDataTypeException.php b/core/lib/Drupal/Core/Config/UnsupportedConfigDataTypeException.php
deleted file mode 100644
index ac63c26..0000000
--- a/core/lib/Drupal/Core/Config/UnsupportedConfigDataTypeException.php
+++ /dev/null
@@ -1,14 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Config\UnsupportedConfigDataTypeException.
- */
-
-namespace Drupal\Core\Config;
-
-/**
- * Exception thrown when a config data type is invalid.
- */
-class UnsupportedConfigDataTypeException extends ConfigException {
-}
diff --git a/core/lib/Drupal/Core/Config/UnsupportedDataTypeConfigException.php b/core/lib/Drupal/Core/Config/UnsupportedDataTypeConfigException.php
deleted file mode 100644
index 3cc4012..0000000
--- a/core/lib/Drupal/Core/Config/UnsupportedDataTypeConfigException.php
+++ /dev/null
@@ -1,14 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Config\UnsupportedDataTypeConfigException.
- */
-
-namespace Drupal\Core\Config;
-
-/**
- * Exception thrown when a config data type is invalid.
- */
-class UnsupportedDataTypeConfigException extends ConfigException {
-}
diff --git a/core/lib/Drupal/Core/Extension/UpdateModuleHandler.php b/core/lib/Drupal/Core/Extension/UpdateModuleHandler.php
index 1b8a466..de9e0f0 100644
--- a/core/lib/Drupal/Core/Extension/UpdateModuleHandler.php
+++ b/core/lib/Drupal/Core/Extension/UpdateModuleHandler.php
@@ -9,6 +9,7 @@
 
 use Drupal\Core\Config\ConfigException;
 use Drupal\Core\Config\FileStorage;
+use Drupal\Core\Serialization\Yaml;
 
 /**
  * Deals with module enables and throws exception if hooks fired during updates.
@@ -107,7 +108,7 @@ public function install(array $module_list, $enable_dependencies = TRUE) {
       // this is a plain copy operation from one storage to another.
       $module_config_path = drupal_get_path('module', $module) . '/config';
       if (is_dir($module_config_path)) {
-        $module_filestorage = new FileStorage($module_config_path);
+        $module_filestorage = new FileStorage('', new Yaml(), $module_config_path);
         $config_storage = \Drupal::service('config.storage');
         foreach ($module_filestorage->listAll() as $config_name) {
           // If this file already exists, something in the upgrade path went
diff --git a/core/lib/Drupal/Core/KeyValueStore/DatabaseStorage.php b/core/lib/Drupal/Core/KeyValueStore/DatabaseStorage.php
index 4045c48..03fba90 100644
--- a/core/lib/Drupal/Core/KeyValueStore/DatabaseStorage.php
+++ b/core/lib/Drupal/Core/KeyValueStore/DatabaseStorage.php
@@ -9,6 +9,7 @@
 
 use Drupal\Core\Database\Query\Merge;
 use Drupal\Core\Database\Connection;
+use Drupal\Core\Serialization\SerializationInterface;
 
 /**
  * Defines a default key/value store implementation.
@@ -37,16 +38,28 @@ class DatabaseStorage extends StorageBase {
    *
    * @param string $collection
    *   The name of the collection holding key and value pairs.
+   * @param \Drupal\Core\Serialization\SerializationInterface $format
+   *   The serialization format to use.
    * @param string $table
    *   The name of the SQL table to use, defaults to key_value.
    */
-  public function __construct($collection, Connection $connection, $table = 'key_value') {
-    parent::__construct($collection);
+  public function __construct($collection, SerializationInterface $format, Connection $connection, $table = 'key_value') {
+    parent::__construct($collection, $format);
     $this->connection = $connection;
     $this->table = $table;
   }
 
   /**
+   * {@inheritdoc}
+   */
+  public function has($key) {
+    return (bool) $this->connection->query('SELECT 1 FROM {' . $this->connection->escapeTable($this->table) . '} WHERE collection = :collection AND name = :key', array(
+      ':collection' => $this->collection,
+      ':key' => $key,
+    ))->fetchField();
+  }
+
+  /**
    * Implements Drupal\Core\KeyValueStore\KeyValueStoreInterface::getMultiple().
    */
   public function getMultiple(array $keys) {
@@ -55,7 +68,7 @@ public function getMultiple(array $keys) {
       $result = $this->connection->query('SELECT name, value FROM {' . $this->connection->escapeTable($this->table) . '} WHERE name IN (:keys) AND collection = :collection', array(':keys' => $keys, ':collection' => $this->collection))->fetchAllAssoc('name');
       foreach ($keys as $key) {
         if (isset($result[$key])) {
-          $values[$key] = unserialize($result[$key]->value);
+          $values[$key] = $this->format->decode($result[$key]->value);
         }
       }
     }
@@ -76,7 +89,7 @@ public function getAll() {
 
     foreach ($result as $item) {
       if ($item) {
-        $values[$item->name] = unserialize($item->value);
+        $values[$item->name] = $this->format->decode($item->value);
       }
     }
     return $values;
@@ -91,7 +104,7 @@ public function set($key, $value) {
         'name' => $key,
         'collection' => $this->collection,
       ))
-      ->fields(array('value' => serialize($value)))
+      ->fields(array('value' => $this->format->encode($value)))
       ->execute();
   }
 
@@ -103,7 +116,7 @@ public function setIfNotExists($key, $value) {
       ->insertFields(array(
         'collection' => $this->collection,
         'name' => $key,
-        'value' => serialize($value),
+        'value' => $this->format->encode($value),
       ))
       ->condition('collection', $this->collection)
       ->condition('name', $key)
diff --git a/core/lib/Drupal/Core/KeyValueStore/DatabaseStorageExpirable.php b/core/lib/Drupal/Core/KeyValueStore/DatabaseStorageExpirable.php
index 02eec8c..145548f 100644
--- a/core/lib/Drupal/Core/KeyValueStore/DatabaseStorageExpirable.php
+++ b/core/lib/Drupal/Core/KeyValueStore/DatabaseStorageExpirable.php
@@ -10,6 +10,7 @@
 use Drupal\Core\DestructableInterface;
 use Drupal\Core\Database\Connection;
 use Drupal\Core\Database\Query\Merge;
+use Drupal\Core\Serialization\PhpSerialize;
 
 /**
  * Defines a default key/value store implementation for expiring items.
@@ -53,7 +54,18 @@ class DatabaseStorageExpirable extends DatabaseStorage implements KeyValueStoreE
    *     key_value_expire.
    */
   public function __construct($collection, Connection $connection, $table = 'key_value_expire') {
-    parent::__construct($collection, $connection, $table);
+    parent::__construct($collection, new PhpSerialize(), $connection, $table);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function has($key) {
+    return (bool) $this->connection->query('SELECT 1 FROM {' . $this->connection->escapeTable($this->table) . '} WHERE collection = :collection AND name = :key AND expire > :now', array(
+      ':collection' => $this->collection,
+      ':key' => $key,
+      ':now' => REQUEST_TIME,
+    ))->fetchField();
   }
 
   /**
diff --git a/core/lib/Drupal/Core/KeyValueStore/FileStorage.php b/core/lib/Drupal/Core/KeyValueStore/FileStorage.php
new file mode 100644
index 0000000..351027c
--- /dev/null
+++ b/core/lib/Drupal/Core/KeyValueStore/FileStorage.php
@@ -0,0 +1,136 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\KeyValueStore\FileStorage.
+ */
+
+namespace Drupal\Core\KeyValueStore;
+
+use Drupal\Core\Serialization\SerializationInterface;
+
+/**
+ * Defines the default file key/value store implementation.
+ */
+class FileStorage extends StorageBase {
+
+  /**
+   * The filesystem URI/directory to use as base path.
+   *
+   * @var string
+   */
+  protected $path;
+
+  /**
+   * Overrides \Drupal\Core\KeyValueStore\StorageBase::__construct().
+   *
+   * @param string $collection
+   *   The name of the collection holding key and value pairs.
+   * @param \Drupal\Core\Serialization\SerializationInterface $format
+   *   The serialization format to use.
+   * @param string $path
+   *   The filesystem URI/directory to use as base path.
+   */
+  public function __construct($collection, SerializationInterface $format, $path) {
+    parent::__construct($collection, $format);
+    $this->path = $path;
+    if ($this->collection !== '') {
+      $this->path .= '/' . $this->collection;
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function has($key) {
+    return file_exists($this->getPathname($key));
+  }
+
+  public function getMultiple(array $keys) {
+    $values = array();
+    foreach ($keys as $key) {
+      if (file_exists($pathname = $this->getPathname($key))) {
+        $values[$key] = $this->format->decode(file_get_contents($pathname));
+      }
+    }
+    return $values;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getAll() {
+    $values = array();
+    foreach ($this->getIterator() as $pathname => $file) {
+      $key = $file->getBasename('.' . $this->format->getFileExtension());
+      $values[$key] = $this->format->decode(file_get_contents($pathname));
+    }
+    return $values;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function set($key, $value) {
+    file_put_contents($this->getPathname($key), $this->format->encode($value));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setIfNotExists($key, $value) {
+    if (!file_exists($this->getPathname($key))) {
+      $this->set($key, $value);
+      return TRUE;
+    }
+    return FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function deleteMultiple(array $keys) {
+    foreach ($keys as $key) {
+      if (file_exists($pathname = $this->getPathname($key))) {
+        unlink($pathname);
+      }
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function deleteAll() {
+    foreach ($this->getIterator() as $pathname => $file) {
+      unlink($pathname);
+    }
+  }
+
+  /**
+   * Returns an iterator for the file storage.
+   *
+   * @return \FilesystemIterator|array
+   *   The filesystem iterator, or an empty array if the path is not accessible.
+   */
+  protected function getIterator($prefix = '') {
+    // GlobIterator requires absolute paths on Windows, so we use a filtered
+    // FilesystemIterator instead.
+    try {
+      $flags = \FilesystemIterator::KEY_AS_PATHNAME;
+      $flags |= \FilesystemIterator::CURRENT_AS_FILEINFO;
+      $flags |= \FilesystemIterator::SKIP_DOTS;
+      $flags |= \FilesystemIterator::UNIX_PATHS;
+      $iterator = new \FilesystemIterator($this->path, $flags);
+      $filter = new FileStorageFilterIterator($iterator, $this->format->getFileExtension(), $prefix);
+    }
+    catch (\Exception $e) {
+      $filter = array();
+    }
+    return $filter;
+  }
+
+  protected function getPathname($key) {
+    return $this->path . "/$key." . $this->format->getFileExtension();
+  }
+
+}
diff --git a/core/lib/Drupal/Core/KeyValueStore/FileStorageFilterIterator.php b/core/lib/Drupal/Core/KeyValueStore/FileStorageFilterIterator.php
new file mode 100644
index 0000000..0f4a12b
--- /dev/null
+++ b/core/lib/Drupal/Core/KeyValueStore/FileStorageFilterIterator.php
@@ -0,0 +1,62 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\KeyValueStore\FileStorageFilterIterator.
+ */
+
+namespace Drupal\Core\KeyValueStore;
+
+/**
+ * Filters discovered files in the file key/value store.
+ */
+class FileStorageFilterIterator extends \FilterIterator {
+
+  /**
+   * The file extension to accept.
+   *
+   * @var string
+   */
+  protected $extension;
+
+  /**
+   * An optional filename prefix to filter by.
+   *
+   * @var string
+   */
+  protected $prefix;
+
+  /**
+   * Constructs this filter.
+   *
+   * @param \FilesystemIterator $iterator
+   *   The filesystem iterator to filter.
+   * @param string $extension
+   *   The file extension to accept.
+   * @param string $prefix
+   *   (optional) A filename prefix to filter by.
+   */
+  public function __construct(\FilesystemIterator $iterator, $extension, $prefix = '') {
+    parent::__construct($iterator);
+    $this->extension = $extension;
+    $this->prefix = $prefix;
+  }
+
+  /**
+   * Implements \FilterIterator::accept().
+   */
+  public function accept() {
+    $file = $this->current();
+    if (!$file->isFile()) {
+      return FALSE;
+    }
+    if ($file->getExtension() != $this->extension) {
+      return FALSE;
+    }
+    if ($this->prefix !== '' && strpos($file->getFilename(), $this->prefix) !== 0) {
+      return FALSE;
+    }
+    return TRUE;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/KeyValueStore/KeyValueDatabaseFactory.php b/core/lib/Drupal/Core/KeyValueStore/KeyValueDatabaseFactory.php
index 1a840b3..6df46e6 100644
--- a/core/lib/Drupal/Core/KeyValueStore/KeyValueDatabaseFactory.php
+++ b/core/lib/Drupal/Core/KeyValueStore/KeyValueDatabaseFactory.php
@@ -6,8 +6,10 @@
  */
 
 namespace Drupal\Core\KeyValueStore;
+
 use Drupal\Core\Database\Connection;
 use Drupal\Core\Database\Database;
+use Drupal\Core\Serialization\SerializationInterface;
 
 /**
  * Defines the key/value store factory for the database backend.
@@ -15,20 +17,36 @@
 class KeyValueDatabaseFactory implements KeyValueFactoryInterface {
 
   /**
-   * Constructs this factory object.
+   * The database connection to use.
+   *
+   * @var \Drupal\Core\Database\Connection
+   */
+  protected $connection;
+
+  /**
+   * The serialization format to use.
    *
+   * @var \Drupal\Core\Serialization\SerializationInterface
+   */
+  protected $format;
+
+  /**
+   * Constructs this factory object.
    *
    * @param \Drupal\Core\Database\Connection $connection
    *   The Connection object containing the key-value tables.
+   * @param \Drupal\Core\Serialization\SerializationInterface $format
+   *   The serialization format to use.
    */
-  function __construct(Connection $connection) {
+  function __construct(Connection $connection, SerializationInterface $format) {
     $this->connection = $connection;
+    $this->format = $format;
   }
 
   /**
    * {@inheritdoc}
    */
   public function get($collection) {
-    return new DatabaseStorage($collection, $this->connection);
+    return new DatabaseStorage($collection, $this->format, $this->connection);
   }
 }
diff --git a/core/lib/Drupal/Core/KeyValueStore/KeyValueFileFactory.php b/core/lib/Drupal/Core/KeyValueStore/KeyValueFileFactory.php
new file mode 100644
index 0000000..91edf2c
--- /dev/null
+++ b/core/lib/Drupal/Core/KeyValueStore/KeyValueFileFactory.php
@@ -0,0 +1,53 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\KeyValueStore\KeyValueFileFactory.
+ */
+
+namespace Drupal\Core\KeyValueStore;
+
+use Drupal\Component\Utility\Settings;
+use Drupal\Core\Serialization\SerializationInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Defines the key/value store factory for the file backend.
+ */
+class KeyValueFileFactory implements KeyValueFactoryInterface {
+
+  /**
+   * The filesystem URI/directory to use as base path.
+   *
+   * @var string
+   */
+  protected $path;
+
+  /**
+   * The serialization format to use.
+   *
+   * @var \Drupal\Core\Serialization\SerializationInterface
+   */
+  protected $format;
+
+  /**
+   * Constructs this factory object.
+   *
+   * @param string $path
+   *   The filesystem URI/directory to use as base path.
+   * @param \Drupal\Core\Serialization\SerializationInterface $format
+   *   The serialization format to use.
+   */
+  function __construct($path, SerializationInterface $format) {
+    $this->path = $path;
+    $this->format = $format;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function get($collection) {
+    return new FileStorage($collection, $this->format, $this->path);
+  }
+
+}
diff --git a/core/lib/Drupal/Core/KeyValueStore/KeyValueStoreInterface.php b/core/lib/Drupal/Core/KeyValueStore/KeyValueStoreInterface.php
index 60c150c..39d1da0 100644
--- a/core/lib/Drupal/Core/KeyValueStore/KeyValueStoreInterface.php
+++ b/core/lib/Drupal/Core/KeyValueStore/KeyValueStoreInterface.php
@@ -21,6 +21,17 @@
   public function getCollectionName();
 
   /**
+   * Returns whether a given key exists in the store.
+   *
+   * @param string $key
+   *   The key to check.
+   *
+   * @return bool
+   *   TRUE if the key exists, FALSE otherwise.
+   */
+  public function has($key);
+
+  /**
    * Returns the stored value for a given key.
    *
    * @param string $key
diff --git a/core/lib/Drupal/Core/KeyValueStore/MemoryStorage.php b/core/lib/Drupal/Core/KeyValueStore/MemoryStorage.php
index e6e07ef..6e9b0f7 100644
--- a/core/lib/Drupal/Core/KeyValueStore/MemoryStorage.php
+++ b/core/lib/Drupal/Core/KeyValueStore/MemoryStorage.php
@@ -20,6 +20,13 @@ class MemoryStorage extends StorageBase {
   protected $data = array();
 
   /**
+   * {@inheritdoc}
+   */
+  public function has($key) {
+    return array_key_exists($key, $this->data);
+  }
+
+  /**
    * Implements Drupal\Core\KeyValueStore\KeyValueStoreInterface::get().
    */
   public function get($key, $default = NULL) {
diff --git a/core/lib/Drupal/Core/KeyValueStore/NullStorageExpirable.php b/core/lib/Drupal/Core/KeyValueStore/NullStorageExpirable.php
index 29bcde6..a3704eb 100644
--- a/core/lib/Drupal/Core/KeyValueStore/NullStorageExpirable.php
+++ b/core/lib/Drupal/Core/KeyValueStore/NullStorageExpirable.php
@@ -34,6 +34,13 @@ public function __construct($collection) {
   }
 
   /**
+   * {@inheritdoc}
+   */
+  public function has($key) {
+    return FALSE;
+  }
+
+  /**
    * Implements Drupal\Core\KeyValueStore\KeyValueStoreInterface::get().
    */
   public function get($key, $default = NULL) {
diff --git a/core/lib/Drupal/Core/KeyValueStore/StorageBase.php b/core/lib/Drupal/Core/KeyValueStore/StorageBase.php
index 4c54271..8dc54e6 100644
--- a/core/lib/Drupal/Core/KeyValueStore/StorageBase.php
+++ b/core/lib/Drupal/Core/KeyValueStore/StorageBase.php
@@ -7,6 +7,8 @@
 
 namespace Drupal\Core\KeyValueStore;
 
+use Drupal\Core\Serialization\SerializationInterface;
+
 /**
  * Provides a base class for key/value storage implementations.
  */
@@ -20,10 +22,18 @@
   protected $collection;
 
   /**
+   * The serialization format to use.
+   *
+   * @var \Drupal\Core\Serialization\SerializationInterface
+   */
+  protected $format;
+
+  /**
    * Implements Drupal\Core\KeyValueStore\KeyValueStoreInterface::__construct().
    */
-  public function __construct($collection) {
+  public function __construct($collection, SerializationInterface $format = NULL) {
     $this->collection = $collection;
+    $this->format = $format;
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Serialization/Exception/InvalidDataTypeException.php b/core/lib/Drupal/Core/Serialization/Exception/InvalidDataTypeException.php
new file mode 100644
index 0000000..e6b8ce6
--- /dev/null
+++ b/core/lib/Drupal/Core/Serialization/Exception/InvalidDataTypeException.php
@@ -0,0 +1,14 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Serialization\Exception\InvalidDataTypeException.
+ */
+
+namespace Drupal\Core\Serialization\Exception;
+
+/**
+ * Exception thrown when a data type is invalid.
+ */
+class InvalidDataTypeException extends \InvalidArgumentException {
+}
diff --git a/core/lib/Drupal/Core/Serialization/Json.php b/core/lib/Drupal/Core/Serialization/Json.php
new file mode 100644
index 0000000..f185939
--- /dev/null
+++ b/core/lib/Drupal/Core/Serialization/Json.php
@@ -0,0 +1,38 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Serialization\Json.
+ */
+
+namespace Drupal\Core\Serialization;
+
+use Drupal\Component\Utility\Json as JsonHelper;
+
+/**
+ * Default serialization for JSON.
+ */
+class Json implements SerializationInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function encode($data) {
+    return JsonHelper::encode($data);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function decode($raw) {
+    return JsonHelper::decode($raw);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getFileExtension() {
+    return 'json';
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Serialization/PhpSerialize.php b/core/lib/Drupal/Core/Serialization/PhpSerialize.php
new file mode 100644
index 0000000..4b912ba
--- /dev/null
+++ b/core/lib/Drupal/Core/Serialization/PhpSerialize.php
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Serialization\PhpSerialize.
+ */
+
+namespace Drupal\Core\Serialization;
+
+/**
+ * Default serialization for serialized PHP.
+ */
+class PhpSerialize implements SerializationInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function encode($data) {
+    return serialize($data);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function decode($raw) {
+    return unserialize($raw);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getFileExtension() {
+    return 'serialized';
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Serialization/SerializationInterface.php b/core/lib/Drupal/Core/Serialization/SerializationInterface.php
new file mode 100644
index 0000000..7713032
--- /dev/null
+++ b/core/lib/Drupal/Core/Serialization/SerializationInterface.php
@@ -0,0 +1,45 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Serialization\SerializationInterface.
+ */
+
+namespace Drupal\Core\Serialization;
+
+/**
+ * Defines an interface for serialization formats.
+ */
+interface SerializationInterface {
+
+  /**
+   * Encodes data into the serialization format.
+   *
+   * @param mixed $data
+   *   The data to encode.
+   *
+   * @return string
+   *   The encoded data.
+   */
+  public static function encode($data);
+
+  /**
+   * Decodes data from the serialization format.
+   *
+   * @param string $raw
+   *   The raw data string to decode.
+   *
+   * @return mixed
+   *   The decoded data.
+   */
+  public static function decode($raw);
+
+  /**
+   * Returns the file extension for this serialization format.
+   *
+   * @return string
+   *   The file extension, without leading dot.
+   */
+  public static function getFileExtension();
+
+}
diff --git a/core/lib/Drupal/Core/Serialization/Xml.php b/core/lib/Drupal/Core/Serialization/Xml.php
new file mode 100644
index 0000000..38d409f
--- /dev/null
+++ b/core/lib/Drupal/Core/Serialization/Xml.php
@@ -0,0 +1,86 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Serialization\Xml.
+ */
+
+namespace Drupal\Core\Serialization;
+
+/**
+ * Default serialization for XML.
+ */
+class Xml implements SerializationInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function encode($data) {
+    return static::encodeXml(new \SimpleXMLElement('<array></array>'), $data)->asXML();
+  }
+
+  /**
+   * Recursively encodes a value as XML.
+   *
+   * @param \SimpleXMLElement $xml
+   *   The \SimpleXMLElement to add to.
+   * @param mixed $value
+   *   The value to be encoded.
+   * @param string $key
+   *   (optional) The key in the parent array, if any.
+   *
+   * @return \SimpleXMLElement
+   *   The enhanced $xml element.
+   */
+  protected static function encodeXml(\SimpleXMLElement $xml, $value, $key = NULL) {
+    if (isset($key)) {
+      $xml = $xml->addChild(gettype($value), is_array($value) ? '' : htmlspecialchars($value));
+      $xml->addAttribute('key', $key);
+    }
+    if (is_array($value)) {
+      foreach ($value as $new_key => $new_value) {
+        static::encodeXml($xml, $new_value, $new_key);
+      }
+    }
+    return $xml;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function decode($raw) {
+    return static::decodeXml(new \SimpleXMLElement($raw));
+  }
+
+  /**
+   * Decodes the XML produced by encodeXml().
+   *
+   * @param \SimpleXMLElement $xml
+   *   The \SimpleXMLElement to decode.
+   *
+   * @return mixed
+   *   The decoded value.
+   */
+  protected static function decodeXml(\SimpleXMLElement $xml) {
+    $type = $xml->getName();
+    if ($type == 'array') {
+      $value = array();
+      foreach ($xml as $element) {
+        $value[(string) $element['key']] = static::decodeXml($element);
+      }
+    }
+    else {
+      $value = (string) $xml;
+      settype($value, $type);
+    }
+    return $value;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getFileExtension() {
+    return 'xml';
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Serialization/Yaml.php b/core/lib/Drupal/Core/Serialization/Yaml.php
new file mode 100644
index 0000000..25ee001
--- /dev/null
+++ b/core/lib/Drupal/Core/Serialization/Yaml.php
@@ -0,0 +1,49 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Serialization\Yaml.
+ */
+
+namespace Drupal\Core\Serialization;
+
+use Drupal\Core\Serialization\Exception\InvalidDataTypeException;
+use Symfony\Component\Yaml\Yaml as Symfony;
+
+/**
+ * Default serialization for YAML.
+ */
+class Yaml implements SerializationInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function encode($data) {
+    try {
+      return Symfony::dump($data, PHP_INT_MAX, 2, TRUE);
+    }
+    catch (\Exception $e) {
+      throw new InvalidDataTypeException($e->getMessage(), $e->getCode(), $e);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function decode($raw) {
+    try {
+      return Symfony::parse($raw, TRUE);
+    }
+    catch (\Exception $e) {
+      throw new InvalidDataTypeException($e->getMessage(), $e->getCode(), $e);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getFileExtension() {
+    return 'yml';
+  }
+
+}
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigCRUDTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigCRUDTest.php
index 7576163..50c85ea 100644
--- a/core/modules/config/lib/Drupal/config/Tests/ConfigCRUDTest.php
+++ b/core/modules/config/lib/Drupal/config/Tests/ConfigCRUDTest.php
@@ -11,7 +11,8 @@
 use Drupal\Core\Config\ConfigNameException;
 use Drupal\simpletest\DrupalUnitTestBase;
 use Drupal\Core\Config\FileStorage;
-use Drupal\Core\Config\UnsupportedDataTypeConfigException;
+use Drupal\Core\Serialization\Exception\InvalidDataTypeException;
+use Drupal\Core\Serialization\Yaml;
 
 /**
  * Tests CRUD operations on configuration objects.
@@ -192,7 +193,7 @@ function testNameValidation() {
    */
   public function testDataTypes() {
     \Drupal::moduleHandler()->install(array('config_test'));
-    $storage = new FileStorage($this->configDirectories[CONFIG_ACTIVE_DIRECTORY]);
+    $storage = new FileStorage('', new Yaml(), $this->configDirectories[CONFIG_ACTIVE_DIRECTORY]);
     $name = 'config_test.types';
     $config = $this->container->get('config.factory')->get($name);
     $original_content = file_get_contents($storage->getFilePath($name));
@@ -233,7 +234,7 @@ public function testDataTypes() {
       $config->set('stream', fopen(__FILE__, 'r'))->save();
       $this->fail('No Exception thrown upon saving invalid data type.');
     }
-    catch (UnsupportedDataTypeConfigException $e) {
+    catch (InvalidDataTypeException $e) {
       $this->pass(String::format('%class thrown upon saving invalid data type.', array(
         '%class' => get_class($e),
       )));
@@ -250,7 +251,7 @@ public function testDataTypes() {
       $config->set('stream', fopen(__FILE__, 'r'))->save();
       $this->fail('No Exception thrown upon saving invalid data type.');
     }
-    catch (UnsupportedDataTypeConfigException $e) {
+    catch (InvalidDataTypeException $e) {
       $this->pass(String::format('%class thrown upon saving invalid data type.', array(
         '%class' => get_class($e),
       )));
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigFileContentTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigFileContentTest.php
index a73155d..146a97b 100644
--- a/core/modules/config/lib/Drupal/config/Tests/ConfigFileContentTest.php
+++ b/core/modules/config/lib/Drupal/config/Tests/ConfigFileContentTest.php
@@ -8,6 +8,7 @@
 namespace Drupal\config\Tests;
 
 use Drupal\Core\Config\FileStorage;
+use Drupal\Core\Serialization\Yaml;
 use Drupal\simpletest\DrupalUnitTestBase;
 
 /**
@@ -206,7 +207,7 @@ function testSerialization() {
     );
 
     // Encode and write, and reload and decode the configuration data.
-    $filestorage = new FileStorage($this->configDirectories[CONFIG_ACTIVE_DIRECTORY]);
+    $filestorage = new FileStorage('', new Yaml(), $this->configDirectories[CONFIG_ACTIVE_DIRECTORY]);
     $filestorage->write($name, $config_data);
     $config_parsed = $filestorage->read($name);
 
diff --git a/core/modules/config/lib/Drupal/config/Tests/DefaultConfigTest.php b/core/modules/config/lib/Drupal/config/Tests/DefaultConfigTest.php
index b7424f3..f9d56a0 100644
--- a/core/modules/config/lib/Drupal/config/Tests/DefaultConfigTest.php
+++ b/core/modules/config/lib/Drupal/config/Tests/DefaultConfigTest.php
@@ -70,7 +70,7 @@ public function testDefaultConfig() {
     // every module, profile and theme.
     $typed_config = new TypedConfigManager(
       \Drupal::service('config.storage'),
-      new TestSchemaStorage(),
+      new TestSchemaStorage(\Drupal::service('config.storage.active')),
       \Drupal::service('cache.config')
     );
 
diff --git a/core/modules/config/lib/Drupal/config/Tests/Storage/ConfigStorageTestBase.php b/core/modules/config/lib/Drupal/config/Tests/Storage/ConfigStorageTestBase.php
index d986835..8ed254a 100644
--- a/core/modules/config/lib/Drupal/config/Tests/Storage/ConfigStorageTestBase.php
+++ b/core/modules/config/lib/Drupal/config/Tests/Storage/ConfigStorageTestBase.php
@@ -87,10 +87,6 @@ function testCRUD() {
     $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 FALSE.
     $result = $this->invalidStorage->read($name);
     $this->assertIdentical($result, FALSE);
diff --git a/core/modules/config/lib/Drupal/config/Tests/Storage/FileStorageTest.php b/core/modules/config/lib/Drupal/config/Tests/Storage/FileStorageTest.php
index 6a99605..efdbb9a 100644
--- a/core/modules/config/lib/Drupal/config/Tests/Storage/FileStorageTest.php
+++ b/core/modules/config/lib/Drupal/config/Tests/Storage/FileStorageTest.php
@@ -8,7 +8,7 @@
 namespace Drupal\config\Tests\Storage;
 
 use Drupal\Core\Config\FileStorage;
-use Symfony\Component\Yaml\Yaml;
+use Drupal\Core\Serialization\Yaml;
 
 /**
  * Tests FileStorage controller operations.
@@ -24,8 +24,8 @@ public static function getInfo() {
 
   function setUp() {
     parent::setUp();
-    $this->storage = new FileStorage($this->configDirectories[CONFIG_ACTIVE_DIRECTORY]);
-    $this->invalidStorage = new FileStorage($this->configDirectories[CONFIG_ACTIVE_DIRECTORY] . '/nonexisting');
+    $this->storage = new FileStorage('', new Yaml(), $this->configDirectories[CONFIG_ACTIVE_DIRECTORY]);
+    $this->invalidStorage = new FileStorage('', new Yaml(), $this->configDirectories[CONFIG_ACTIVE_DIRECTORY] . '/nonexisting');
 
     // FileStorage::listAll() requires other configuration data to exist.
     $this->storage->write('system.performance', \Drupal::config('system.performance')->get());
@@ -33,7 +33,7 @@ function setUp() {
 
   protected function read($name) {
     $data = file_get_contents($this->storage->getFilePath($name));
-    return Yaml::parse($data);
+    return Yaml::decode($data);
   }
 
   protected function insert($name, $data) {
@@ -62,7 +62,7 @@ protected function testlistAll() {
 
     // Initialize FileStorage with absolute file path.
     $absolute_path = realpath($this->configDirectories[CONFIG_ACTIVE_DIRECTORY]);
-    $storage_absolute_path = new FileStorage($absolute_path);
+    $storage_absolute_path = new FileStorage('', new Yaml(), $absolute_path);
     $config_files = $storage_absolute_path->listAll();
     $this->assertIdentical($config_files, $expected_files, 'Absolute path, two config files found.');
   }
diff --git a/core/modules/config/tests/config_test/lib/Drupal/config_test/TestInstallStorage.php b/core/modules/config/tests/config_test/lib/Drupal/config_test/TestInstallStorage.php
index c940422..d3d6cad 100644
--- a/core/modules/config/tests/config_test/lib/Drupal/config_test/TestInstallStorage.php
+++ b/core/modules/config/tests/config_test/lib/Drupal/config_test/TestInstallStorage.php
@@ -22,9 +22,12 @@ class TestInstallStorage extends InstallStorage {
    */
   protected function getAllFolders() {
     if (!isset($this->folders)) {
-      $this->folders = $this->getComponentNames('profile', array_keys(drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.profile$/', 'profiles')));
-      $this->folders += $this->getComponentNames('module', array_keys(drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules', 'name', 0)));
-      $this->folders += $this->getComponentNames('theme', array_keys(drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info.yml$/', 'themes')));
+      $folders = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.profile$/', 'profiles');
+      $folders += drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules');
+      $folders += drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info\.yml$/', 'themes');
+      $this->folders = array_map(function ($file) {
+        return dirname($file->uri);
+      }, $folders);
     }
     return $this->folders;
   }
diff --git a/core/modules/config/tests/config_test/lib/Drupal/config_test/TestSchemaStorage.php b/core/modules/config/tests/config_test/lib/Drupal/config_test/TestSchemaStorage.php
index 8d240b0..234268e 100644
--- a/core/modules/config/tests/config_test/lib/Drupal/config_test/TestSchemaStorage.php
+++ b/core/modules/config/tests/config_test/lib/Drupal/config_test/TestSchemaStorage.php
@@ -19,20 +19,17 @@
 class TestSchemaStorage extends SchemaStorage {
 
   /**
-   * Overrides Drupal\Core\Config\ExtensionInstallStorage::__construct().
-   */
-  public function __construct() {
-  }
-
-  /**
    * {@inheritdoc}
    */
   protected function getAllFolders() {
     if (!isset($this->folders)) {
-      $this->folders = $this->getBaseDataTypeSchema();
-      $this->folders += $this->getComponentNames('profile', array_keys(drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.profile$/', 'profiles')));
-      $this->folders += $this->getComponentNames('module', array_keys(drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules', 'name', 0)));
-      $this->folders += $this->getComponentNames('theme', array_keys(drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info.yml$/', 'themes')));
+      $this->folders['core'] = 'core';
+      $folders = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.profile$/', 'profiles');
+      $folders += drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules');
+      $folders += drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info\.yml$/', 'themes');
+      $this->folders += array_map(function ($file) {
+        return dirname($file->uri);
+      }, $folders);
     }
     return $this->folders;
   }
diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationUiTest.php b/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationUiTest.php
index ed4b1e2..c46e678 100644
--- a/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationUiTest.php
+++ b/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationUiTest.php
@@ -11,6 +11,7 @@
 use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Config\FileStorage;
 use Drupal\Core\Language\Language;
+use Drupal\Core\Serialization\Yaml;
 use Drupal\simpletest\WebTestBase;
 
 /**
@@ -177,7 +178,7 @@ public function testSourceValueDuplicateSave() {
     $this->drupalPostForm("$translation_base_url/fr/add", $edit, t('Save translation'));
 
     // Read overridden file from active config.
-    $file_storage = new FileStorage($this->configDirectories[CONFIG_ACTIVE_DIRECTORY]);
+    $file_storage = new FileStorage('', new Yaml(), $this->configDirectories[CONFIG_ACTIVE_DIRECTORY]);
     $language_config_name = \Drupal::configFactory()->getLanguageConfigName('fr', 'system.site');
     $config_parsed = $file_storage->read($language_config_name);
 
@@ -240,7 +241,7 @@ public function testSourceValueDuplicateSave() {
   public function testContactConfigEntityTranslation() {
     $this->drupalLogin($this->admin_user);
 
-    $file_storage = new FileStorage($this->configDirectories[CONFIG_ACTIVE_DIRECTORY]);
+    $file_storage = new FileStorage('', new Yaml(), $this->configDirectories[CONFIG_ACTIVE_DIRECTORY]);
 
     $this->drupalGet('admin/structure/contact');
 
@@ -374,7 +375,7 @@ public function testContactConfigEntityTranslation() {
    */
   public function testDateFormatTranslation() {
     $this->drupalLogin($this->admin_user);
-    $file_storage = new FileStorage($this->configDirectories[CONFIG_ACTIVE_DIRECTORY]);
+    $file_storage = new FileStorage('', new Yaml(), $this->configDirectories[CONFIG_ACTIVE_DIRECTORY]);
 
     $this->drupalGet('admin/config/regional/date-time');
 
diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigManagerTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigManagerTest.php
index 16fc30b..014c9e7 100644
--- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigManagerTest.php
+++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigManagerTest.php
@@ -22,7 +22,7 @@ class LocaleConfigManagerTest extends DrupalUnitTestBase {
    *
    * @var array
    */
-  public static $modules = array('locale', 'locale_test');
+  public static $modules = array('language', 'locale', 'locale_test');
 
   /**
    * {@inheritdoc}
@@ -39,27 +39,12 @@ public static function getInfo() {
    * Tests hasTranslation().
    */
   public function testHasTranslation() {
-    $locale_config_manager = new LocaleConfigManager(
-      // In contrast to the actual configuration we use the installer storage
-      // as the config storage. That way, we do not actually have to install
-      // the module and can extend DrupalUnitTestBase.
-      $this->container->get('config.storage.installer'),
-      $this->container->get('config.storage.schema'),
-      $this->container->get('config.storage.installer'),
-      $this->container->get('locale.storage'),
-      $this->container->get('cache.config'),
-      $this->container->get('config.factory')
-    );
+    $this->installConfig(array('locale_test'));
+    $locale_config_manager = $this->container->get('locale.config.typed');
 
     $language = new Language(array('id' => 'de'));
-    // The installer storage throws an expcetion when requesting a non-existing
-    // file.
-    try {
-      $locale_config_manager->hasTranslation('locale_test.no_translation', $language);
-    }
-    catch (StorageException $exception) {
-      $result = FALSE;
-    }
+
+    $result = $locale_config_manager->hasTranslation('locale_test.no_translation', $language);
     $this->assertIdentical(FALSE, $result);
 
     $result = $locale_config_manager->hasTranslation('locale_test.translation', $language);
diff --git a/core/modules/simpletest/lib/Drupal/simpletest/DrupalUnitTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/DrupalUnitTestBase.php
index cab4b9e..bb5ec0b 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/DrupalUnitTestBase.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/DrupalUnitTestBase.php
@@ -226,6 +226,8 @@ public function containerBuild(ContainerBuilder $container) {
 
     $container
       ->register('config.storage', 'Drupal\Core\Config\FileStorage')
+      ->addArgument('')
+      ->addArgument(new Reference('serialization.yaml'))
       ->addArgument($this->configDirectories[CONFIG_ACTIVE_DIRECTORY]);
 
     $this->settingsSet('keyvalue_default', 'keyvalue.memory');
diff --git a/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/DatabaseStorageTest.php b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/DatabaseStorageTest.php
index ad286d6..eddf7e7 100644
--- a/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/DatabaseStorageTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/DatabaseStorageTest.php
@@ -34,7 +34,10 @@ protected function setUp() {
       ->addArgument('default');
     $this->container
       ->register('keyvalue.database', 'Drupal\Core\KeyValueStore\KeyValueDatabaseFactory')
-      ->addArgument(new Reference('database'));
+      ->addArgument(new Reference('database'))
+      ->addArgument(new Reference('serialization.phpserialize'));
+    $this->container
+      ->register('serialization.phpserialize', 'Drupal\Core\Serialization\PhpSerialize');
     $this->settingsSet('keyvalue_default', 'keyvalue.database');
   }
 
diff --git a/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/FileStorageTest.php b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/FileStorageTest.php
new file mode 100644
index 0000000..aaacef9
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/FileStorageTest.php
@@ -0,0 +1,42 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\system\Tests\KeyValueStore\FileStorageTest.
+ */
+
+namespace Drupal\system\Tests\KeyValueStore;
+
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Tests the key-value file storage.
+ */
+class FileStorageTest extends StorageTestBase {
+
+  public static function getInfo() {
+    return array(
+      'name' => 'File storage',
+      'description' => 'Tests the key-value file storage.',
+      'group' => 'Key-value store',
+    );
+  }
+
+  protected function setUp() {
+    parent::setUp();
+
+    foreach ($this->collections as $collection) {
+      $path = $this->public_files_directory . '/' . $collection;
+      file_prepare_directory($path, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);
+    }
+
+    $this->container
+      ->register('keyvalue.file', 'Drupal\Core\KeyValueStore\KeyValueFileFactory')
+      ->addArgument($this->public_files_directory)
+      ->addArgument(new Reference('serialization.phpserialize'));
+    $this->container
+      ->register('serialization.phpserialize', 'Drupal\Core\Serialization\PhpSerialize');
+    $this->settingsSet('keyvalue_default', 'keyvalue.file');
+  }
+
+}
diff --git a/core/modules/views/lib/Drupal/views/Tests/ViewTestData.php b/core/modules/views/lib/Drupal/views/Tests/ViewTestData.php
index 1117bd8..5f2f23a 100644
--- a/core/modules/views/lib/Drupal/views/Tests/ViewTestData.php
+++ b/core/modules/views/lib/Drupal/views/Tests/ViewTestData.php
@@ -8,6 +8,7 @@
 namespace Drupal\views\Tests;
 
 use Drupal\Core\Config\FileStorage;
+use Drupal\Core\Serialization\Yaml;
 
 /**
  * Provides tests view data and the base test schema with sample data records.
@@ -44,7 +45,7 @@ public static function createTestViews($class, array $modules) {
           continue;
         }
 
-        $file_storage = new FileStorage($config_dir);
+        $file_storage = new FileStorage('', new Yaml(), $config_dir);
         foreach ($file_storage->listAll('views.view.') as $config_name) {
           $id = str_replace('views.view.', '', $config_name);
           if (in_array($id, $views)) {
