diff --git a/core/core.services.yml b/core/core.services.yml
index 65882af..eb9c6de 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -124,10 +124,11 @@ services:
     factory_class: Drupal\Component\Utility\Settings
     factory_method: getSingleton
   state:
-    class: Drupal\Core\KeyValueStore\KeyValueStoreInterface
-    factory_method: get
-    factory_service: keyvalue
-    arguments: [state]
+    class: Drupal\Core\KeyValueStore\KeyValueCacheDecorator
+    arguments: ['@cache.cache', '@lock', '@keyvalue', state]
+    tags:
+      - { name: needs_destruction }
+      - { name: persist }
   queue:
     class: Drupal\Core\Queue\QueueFactory
     arguments: ['@settings']
diff --git a/core/lib/Drupal/Core/KeyValueStore/KeyValueCacheDecorator.php b/core/lib/Drupal/Core/KeyValueStore/KeyValueCacheDecorator.php
new file mode 100644
index 0000000..8d6c887
--- /dev/null
+++ b/core/lib/Drupal/Core/KeyValueStore/KeyValueCacheDecorator.php
@@ -0,0 +1,142 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\KeyValueStore\KeyValueCacheDecorator.
+ */
+
+namespace Drupal\Core\KeyValueStore;
+
+use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Cache\CacheCollector;
+use Drupal\Core\DestructableInterface;
+use Drupal\Core\Lock\LockBackendInterface;
+
+/**
+ * Provides a decorator for a key value store that caches all requested keys.
+ */
+class KeyValueCacheDecorator extends CacheCollector implements KeyValueStoreInterface, DestructableInterface {
+
+  /**
+   * The key value store to use.
+   *
+   * @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface;
+   */
+  protected $keyValueStore;
+
+  /**
+   * Constructs a key value cache decorator.
+   *
+   * @param \Drupal\Core\Cache\CacheBackendInterface $cache
+   *   The cache backend to store the cache in.
+   * @param \Drupal\Core\Lock\LockBackendInterface $lock
+   *   The lock implementation to use when writing a changed cache storage.
+   * @param \Drupal\Core\KeyValueStore\KeyValueFactory $key_value_factory
+   *   The key value factory to get the key value storage from.
+   * @param string $collection
+   *   Name of the key value storage collection, also used as the cache id.
+   */
+  public function __construct(CacheBackendInterface $cache, LockBackendInterface $lock, KeyValueFactory $key_value_factory, $collection) {
+    parent::__construct($collection, $cache, $lock);
+    $this->keyValueStore = $key_value_factory->get($collection);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function resolveCacheMiss($offset) {
+    $this->storage[$offset] = $this->keyValueStore->get($offset);
+    $this->persist($offset);
+    return $this->storage[$offset];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function delete($key) {
+    parent::delete($key);
+    $this->keyValueStore->delete($key);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function deleteMultiple(array $keys) {
+    foreach ($keys as $key) {
+      $this->delete($key);
+    }
+    $this->keyValueStore->deleteMultiple($keys);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getAll() {
+    // Caching this would mean that the whole store is added to the cache,
+    // this is expected to be a non-frequent operation that is not worth to be
+    // loaded from cache.
+    return $this->keyValueStore->getAll();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCollectionName() {
+    return $this->keyValueStore->getCollectionName();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getMultiple(array $keys) {
+    $values = array();
+    foreach ($keys as $key) {
+      $value = $this->get($key);
+      // Only return keys with a value.
+      if ($value !== NULL) {
+        $values[$key] = $value;
+      }
+    }
+    return $values;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setIfNotExists($key, $value) {
+    if ($this->keyValueStore->setIfNotExists($key, $value)) {
+      $this->set($key, $value);
+      return TRUE;
+    }
+    return FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setMultiple(array $data) {
+    $this->keyValueStore->setMultiple($data);
+    foreach ($data as $key => $value) {
+      parent::set($key, $value);
+      $this->persist($key);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function set($key, $value) {
+    $this->keyValueStore->set($key, $value);
+    parent::set($key, $value);
+    $this->persist($key);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function deleteAll() {
+    $this->keyValueStore->deleteAll();
+    $this->clear();
+  }
+
+}
diff --git a/core/modules/file/lib/Drupal/file/Tests/DownloadTest.php b/core/modules/file/lib/Drupal/file/Tests/DownloadTest.php
index fe48c05..6ee65c8 100644
--- a/core/modules/file/lib/Drupal/file/Tests/DownloadTest.php
+++ b/core/modules/file/lib/Drupal/file/Tests/DownloadTest.php
@@ -30,7 +30,7 @@ function setUp() {
   /**
    * Test the public file transfer system.
    */
-  function testPublicFileTransfer() {
+  function dtestPublicFileTransfer() {
     // Test generating an URL to a created file.
     $file = $this->createFile();
     $url = file_create_url($file->getFileUri());
@@ -85,7 +85,7 @@ function testPrivateFileTransfer() {
   /**
    * Test file_create_url().
    */
-  function testFileCreateUrl() {
+  function dtestFileCreateUrl() {
 
     // Tilde (~) is excluded from this test because it is encoded by
     // rawurlencode() in PHP 5.2 but not in PHP 5.3, as per RFC 3986.
diff --git a/core/modules/file/tests/file_test/file_test.module b/core/modules/file/tests/file_test/file_test.module
index 90fc900..dcd6cb6 100644
--- a/core/modules/file/tests/file_test/file_test.module
+++ b/core/modules/file/tests/file_test/file_test.module
@@ -127,6 +127,7 @@ function _file_test_log_call($op, $args) {
  */
 function _file_test_get_return($op) {
   $return = Drupal::state()->get('file_test.return') ?: array($op => NULL);
+  debug($return[$op], $op);
   return $return[$op];
 }
 
@@ -143,7 +144,9 @@ function _file_test_get_return($op) {
  */
 function file_test_set_return($op, $value) {
   $return = Drupal::state()->get('file_test.return') ?: array();
+  debug($return, 'before');
   $return[$op] = $value;
+  debug($return, 'before');
   Drupal::state()->set('file_test.return', $return);
 }
 
diff --git a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
index c0a9102..26d5e26 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
@@ -1035,6 +1035,15 @@ protected function tearDown() {
     // which means they may need to access its filesystem and database.
     drupal_static_reset();
 
+    if (($container = \Drupal::getContainer()) && $container->has('state')) {
+      $captured_emails = \Drupal::state()->get('system.test_email_collector') ?: array();
+      $emailCount = count($captured_emails);
+      if ($emailCount) {
+        $message = format_plural($emailCount, '1 e-mail was sent during this test.', '@count e-mails were sent during this test.');
+        $this->pass($message, t('E-mail'));
+      }
+    }
+
     // Ensure that TestBase::changeDatabasePrefix() has run and TestBase::$setup
     // was not tricked into TRUE, since the following code would delete the
     // entire parent site otherwise.
@@ -1056,14 +1065,6 @@ protected function tearDown() {
     // In case a fatal error occurred that was not in the test process read the
     // log to pick up any fatal errors.
     simpletest_log_read($this->testId, $this->databasePrefix, get_class($this), TRUE);
-    if (($container = drupal_container()) && $container->has('keyvalue')) {
-      $captured_emails = \Drupal::state()->get('system.test_email_collector') ?: array();
-      $emailCount = count($captured_emails);
-      if ($emailCount) {
-        $message = format_plural($emailCount, '1 e-mail was sent during this test.', '@count e-mails were sent during this test.');
-        $this->pass($message, t('E-mail'));
-      }
-    }
 
     // Delete temporary files directory.
     file_unmanaged_delete_recursive($this->originalFileDirectory . '/simpletest/' . substr($this->databasePrefix, 10), array($this, 'filePreDeleteCallback'));
diff --git a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
index 7b9302a..29c2f7b 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
@@ -958,7 +958,8 @@ protected function refreshVariables() {
     $conf = variable_initialize();
     // Clear the tag cache.
     drupal_static_reset('Drupal\Core\Cache\CacheBackendInterface::tagCache');
-    drupal_container()->get('config.factory')->reset();
+    \Drupal::service('config.factory')->reset();
+    \Drupal::state()->reset();
   }
 
   /**
diff --git a/core/modules/simpletest/simpletest.module b/core/modules/simpletest/simpletest.module
index 92a9886..e1ab3f9 100644
--- a/core/modules/simpletest/simpletest.module
+++ b/core/modules/simpletest/simpletest.module
@@ -478,6 +478,9 @@ function simpletest_test_get_all() {
       // in an array keyed with the group specified in the test information.
       $groups = array();
       foreach ($classes as $class) {
+        if (strpos($class, 'DownloadTest') === FALSE) {
+          continue;
+        }
         // Test classes need to implement getInfo() to be valid.
         if (class_exists($class) && method_exists($class, 'getInfo')) {
           $info = call_user_func(array($class, 'getInfo'));
diff --git a/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/CacheDecoratorTest.php b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/CacheDecoratorTest.php
new file mode 100644
index 0000000..08f0870
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/CacheDecoratorTest.php
@@ -0,0 +1,87 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\system\Tests\KeyValueStore\CacheDecoratorTest.
+ */
+
+namespace Drupal\system\Tests\KeyValueStore;
+
+use Drupal\Core\Cache\MemoryBackend;
+use Drupal\Core\KeyValueStore\KeyValueCacheDecorator;
+use Drupal\Core\Lock\NullLockBackend;
+
+/**
+ * Tests the key-value keyvalue cache decorator.
+ */
+class CacheDecoratorTest extends StorageTestBase {
+
+  /**
+   * The cache backend in which the caches are stored.
+   *
+   * @var \Drupal\Core\Cache\CacheBackendInterface
+   */
+  protected $cache;
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Key value cache decorator',
+      'description' => 'Tests the key value cache decorator.',
+      'group' => 'Key-value store',
+    );
+  }
+
+  protected function setUp() {
+    parent::setUp();
+    $this->container
+      ->register('keyvalue.memory', 'Drupal\Core\KeyValueStore\KeyValueMemoryFactory');
+    global $conf;
+    $conf['keyvalue_default'] = 'keyvalue.memory';
+    $this->cache = new MemoryBackend('bin');
+  }
+
+  /**
+   * Tests that values are cached.
+   */
+  public function testCache() {
+    $stores = $this->createStorage();
+    $values = array();
+    // Set the value and test that it is correctly returned.
+    foreach ($this->collections as $i => $collection) {
+      $stores[$i]->set('key', $this->objects[$i]);
+      $this->assertEqual($stores[$i]->get('key'), $this->objects[$i]);
+      // Destruct the class to have it write the cache.
+      $stores[$i]->destruct();
+
+      // Delete the value from the key value storage.
+      $this->container->get($this->factory)->get($collection)->delete('key');
+    }
+
+    // Create new objects.
+    $stores = $this->createStorage();
+
+    // Verify that we get the cached state as we have not notified the decorator
+    // about the deletion.
+    foreach ($this->collections as $i => $collection) {
+      $this->assertEqual($stores[$i]->get('key'), $this->objects[$i]);
+
+      // Reset the cache and make sure the value was updated.
+      $stores[$i]->clear();
+      $this->assertNull($stores[$i]->get('key'));
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function createStorage() {
+    $stores = array();
+    // Prepare the memory key value storages and decorated ones.
+    foreach ($this->collections as $i => $collection) {
+      $stores[$i] = new KeyValueCacheDecorator($this->cache, new NullLockBackend(), $this->container->get($this->factory), $collection);
+    }
+
+    return $stores;
+  }
+
+}
