diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index d11e608..1ad23e3 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -18,6 +18,7 @@
 use Symfony\Component\ClassLoader\ApcClassLoader;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\Response;
+use Drupal\Component\Utility\StaticStorage;
 use Drupal\Core\Language\LanguageInterface;
 
 /**
@@ -884,98 +885,6 @@ function drupal_classloader_register($name, $path) {
 /**
  * Provides central static variable storage.
  *
- * All functions requiring a static variable to persist or cache data within
- * a single page request are encouraged to use this function unless it is
- * absolutely certain that the static variable will not need to be reset during
- * the page request. By centralizing static variable storage through this
- * function, other functions can rely on a consistent API for resetting any
- * other function's static variables.
- *
- * Example:
- * @code
- * function example_list($field = 'default') {
- *   $examples = &drupal_static(__FUNCTION__);
- *   if (!isset($examples)) {
- *     // If this function is being called for the first time after a reset,
- *     // query the database and execute any other code needed to retrieve
- *     // information.
- *     ...
- *   }
- *   if (!isset($examples[$field])) {
- *     // If this function is being called for the first time for a particular
- *     // index field, then execute code needed to index the information already
- *     // available in $examples by the desired field.
- *     ...
- *   }
- *   // Subsequent invocations of this function for a particular index field
- *   // skip the above two code blocks and quickly return the already indexed
- *   // information.
- *   return $examples[$field];
- * }
- * function examples_admin_overview() {
- *   // When building the content for the overview page, make sure to get
- *   // completely fresh information.
- *   drupal_static_reset('example_list');
- *   ...
- * }
- * @endcode
- *
- * In a few cases, a function can have certainty that there is no legitimate
- * use-case for resetting that function's static variable. This is rare,
- * because when writing a function, it's hard to forecast all the situations in
- * which it will be used. A guideline is that if a function's static variable
- * does not depend on any information outside of the function that might change
- * during a single page request, then it's ok to use the "static" keyword
- * instead of the drupal_static() function.
- *
- * Example:
- * @code
- * function mymodule_log_stream_handle($new_handle = NULL) {
- *   static $handle;
- *   if (isset($new_handle)) {
- *     $handle = $new_handle;
- *   }
- *   return $handle;
- * }
- * @endcode
- *
- * In a few cases, a function needs a resettable static variable, but the
- * function is called many times (100+) during a single page request, so
- * every microsecond of execution time that can be removed from the function
- * counts. These functions can use a more cumbersome, but faster variant of
- * calling drupal_static(). It works by storing the reference returned by
- * drupal_static() in the calling function's own static variable, thereby
- * removing the need to call drupal_static() for each iteration of the function.
- * Conceptually, it replaces:
- * @code
- * $foo = &drupal_static(__FUNCTION__);
- * @endcode
- * with:
- * @code
- * // Unfortunately, this does not work.
- * static $foo = &drupal_static(__FUNCTION__);
- * @endcode
- * However, the above line of code does not work, because PHP only allows static
- * variables to be initialized by literal values, and does not allow static
- * variables to be assigned to references.
- * - http://php.net/manual/language.variables.scope.php#language.variables.scope.static
- * - http://php.net/manual/language.variables.scope.php#language.variables.scope.references
- * The example below shows the syntax needed to work around both limitations.
- * For benchmarks and more information, see https://www.drupal.org/node/619666.
- *
- * Example:
- * @code
- * function example_default_format_type() {
- *   // Use the advanced drupal_static() pattern, since this is called very often.
- *   static $drupal_static_fast;
- *   if (!isset($drupal_static_fast)) {
- *     $drupal_static_fast['format_type'] = &drupal_static(__FUNCTION__);
- *   }
- *   $format_type = &$drupal_static_fast['format_type'];
- *   ...
- * }
- * @endcode
- *
  * @param $name
  *   Globally unique name for the variable. For a function with only one static,
  *   variable, the function name (e.g. via the PHP magic __FUNCTION__ constant)
@@ -983,47 +892,18 @@ function drupal_classloader_register($name, $path) {
  *   distinguishing suffix to the function name for each one.
  * @param $default_value
  *   Optional default value.
- * @param $reset
- *   TRUE to reset one or all variables(s). This parameter is only used
- *   internally and should not be passed in; use drupal_static_reset() instead.
- *   (This function's return value should not be used when TRUE is passed in.)
  *
  * @return
  *   Returns a variable by reference.
  *
  * @see drupal_static_reset()
+ *
+ * @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
+ *   Use \Drupal\Component\Utility\StaticStorage::get().
  */
-function &drupal_static($name, $default_value = NULL, $reset = FALSE) {
-  static $data = array(), $default = array();
-  // First check if dealing with a previously defined static variable.
-  if (isset($data[$name]) || array_key_exists($name, $data)) {
-    // Non-NULL $name and both $data[$name] and $default[$name] statics exist.
-    if ($reset) {
-      // Reset pre-existing static variable to its default value.
-      $data[$name] = $default[$name];
-    }
-    return $data[$name];
-  }
-  // Neither $data[$name] nor $default[$name] static variables exist.
-  if (isset($name)) {
-    if ($reset) {
-      // Reset was called before a default is set and yet a variable must be
-      // returned.
-      return $data;
-    }
-    // First call with new non-NULL $name. Initialize a new static variable.
-    $default[$name] = $data[$name] = $default_value;
-    return $data[$name];
-  }
-  // Reset all: ($name == NULL). This needs to be done one at a time so that
-  // references returned by earlier invocations of drupal_static() also get
-  // reset.
-  foreach ($default as $name => $value) {
-    $data[$name] = $value;
-  }
-  // As the function returns a reference, the return should always be a
-  // variable.
-  return $data;
+function &drupal_static($name, $default_value = NULL) {
+  $value = &StaticStorage::get($name, $default_value);
+  return $value;
 }
 
 /**
@@ -1031,11 +911,12 @@ function &drupal_static($name, $default_value = NULL, $reset = FALSE) {
  *
  * @param $name
  *   Name of the static variable to reset. Omit to reset all variables.
- *   Resetting all variables should only be used, for example, for running
- *   unit tests with a clean environment.
+ *
+ * @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
+ *   Use \Drupal\Component\Utility\StaticStorage::reset().
  */
 function drupal_static_reset($name = NULL) {
-  drupal_static($name, NULL, TRUE);
+  StaticStorage::reset($name);
 }
 
 /**
diff --git a/core/lib/Drupal/Component/Utility/StaticStorage.php b/core/lib/Drupal/Component/Utility/StaticStorage.php
new file mode 100644
index 0000000..e88793e
--- /dev/null
+++ b/core/lib/Drupal/Component/Utility/StaticStorage.php
@@ -0,0 +1,179 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Component\Utility\StaticStorage.
+ */
+
+namespace Drupal\Component\Utility;
+
+/**
+ * Provides central static variable storage.
+ *
+ * All functions requiring a static variable to persist or cache data within
+ * a single page request are encouraged to use this function unless it is
+ * absolutely certain that the static variable will not need to be reset during
+ * the page request. By centralizing static variable storage through this
+ * function, other functions can rely on a consistent API for resetting any
+ * other function's static variables.
+ *
+ * Example:
+ * @code
+ * function example_list($field = 'default') {
+ *   $examples = &drupal_static(__FUNCTION__);
+ *   if (!isset($examples)) {
+ *     // If this function is being called for the first time after a reset,
+ *     // query the database and execute any other code needed to retrieve
+ *     // information.
+ *     ...
+ *   }
+ *   if (!isset($examples[$field])) {
+ *     // If this function is being called for the first time for a particular
+ *     // index field, then execute code needed to index the information already
+ *     // available in $examples by the desired field.
+ *     ...
+ *   }
+ *   // Subsequent invocations of this function for a particular index field
+ *   // skip the above two code blocks and quickly return the already indexed
+ *   // information.
+ *   return $examples[$field];
+ * }
+ * function examples_admin_overview() {
+ *   // When building the content for the overview page, make sure to get
+ *   // completely fresh information.
+ *   drupal_static_reset('example_list');
+ *   ...
+ * }
+ * @endcode
+ *
+ * In a few cases, a function can have certainty that there is no legitimate
+ * use-case for resetting that function's static variable. This is rare,
+ * because when writing a function, it's hard to forecast all the situations in
+ * which it will be used. A guideline is that if a function's static variable
+ * does not depend on any information outside of the function that might change
+ * during a single page request, then it's ok to use the "static" keyword
+ * instead of the drupal_static() function.
+ *
+ * Example:
+ * @code
+ * function mymodule_log_stream_handle($new_handle = NULL) {
+ *   static $handle;
+ *   if (isset($new_handle)) {
+ *     $handle = $new_handle;
+ *   }
+ *   return $handle;
+ * }
+ * @endcode
+ *
+ * In a few cases, a function needs a resettable static variable, but the
+ * function is called many times (100+) during a single page request, so
+ * every microsecond of execution time that can be removed from the function
+ * counts. These functions can use a more cumbersome, but faster variant of
+ * calling drupal_static(). It works by storing the reference returned by
+ * drupal_static() in the calling function's own static variable, thereby
+ * removing the need to call drupal_static() for each iteration of the function.
+ * Conceptually, it replaces:
+ * @code
+ * $foo = &drupal_static(__FUNCTION__);
+ * @endcode
+ * with:
+ * @code
+ * // Unfortunately, this does not work.
+ * static $foo = &drupal_static(__FUNCTION__);
+ * @endcode
+ * However, the above line of code does not work, because PHP only allows static
+ * variables to be initializied by literal values, and does not allow static
+ * variables to be assigned to references.
+ * - http://php.net/manual/language.variables.scope.php#language.variables.scope.static
+ * - http://php.net/manual/language.variables.scope.php#language.variables.scope.references
+ * The example below shows the syntax needed to work around both limitations.
+ * For benchmarks and more information, see http://drupal.org/node/619666.
+ *
+ * Example:
+ * @code
+ * function user_access($string, $account = NULL) {
+ *   // Use the advanced drupal_static() pattern, since this is called very often.
+ *   static $drupal_static_fast;
+ *   if (!isset($drupal_static_fast)) {
+ *     $drupal_static_fast['perm'] = &drupal_static(__FUNCTION__);
+ *   }
+ *   $perm = &$drupal_static_fast['perm'];
+ *   ...
+ * }
+ * @endcode
+ */
+class StaticStorage {
+
+  /**
+   * An array keyed by variable name containing the current values for each.
+   * @var array
+   */
+  protected static $data = array();
+
+  /**
+   * An array of known default values, keyed by variable name.
+   *
+   * @var array
+   */
+  protected static $default = array();
+
+  /**
+   * Gets the value for a specified name.
+   *
+   * @param string|null $name
+   *   Globally unique name for the variable. For a function with only one
+   *   static, variable, the function name (e.g. via the PHP magic __FUNCTION__
+   *   constant) is recommended. For a function with multiple static variables
+   *   add a distinguishing suffix to the function name for each one. If NULL is
+   *   passed, the entire contents of self::$data will be replaced with known
+   *   default values and then returned.
+   * @param mixed $default_value
+   *   (optional) A default value, defaults to NULL.
+   *
+   * @return mixed
+   *   Returns a variable by reference.
+   *
+   * @see \Drupal\Component\Utility\StaticStorage::reset()
+   */
+  public static function &get($name, $default_value = NULL) {
+    // First check if dealing with a previously defined static variable.
+    if (isset(static::$data[$name]) || array_key_exists($name, static::$data)) {
+      // Non-NULL $name and both static::$data[$name] and
+      // static::$default[$name] statics exist.
+      return static::$data[$name];
+    }
+    // Neither static::$data[$name] nor static::$default[$name] static variables
+    // exist.
+    if (isset($name)) {
+      // First call with new non-NULL $name. Initialize a new static variable.
+      static::$default[$name] = static::$data[$name] = $default_value;
+      return static::$data[$name];
+    }
+    // As the function returns a reference, the return should always be a
+    // variable.
+    return static::$data;
+  }
+
+  /**
+   * Resets one or all centrally stored static variable(s).
+   *
+   * @param string|null $name
+   *   (optional) The name of the variable to reset. If NULL, all variables will
+   *   be reset.
+   */
+  public static function reset($name = NULL) {
+    if (!isset($name)) {
+      // Reset all: ($name == NULL). This needs to be done one at a time so that
+      // references returned by earlier invocations of drupal_static() also get
+      // reset.
+      foreach (static::$default as $name => $value) {
+        static::$data[$name] = $value;
+      }
+    }
+    elseif (isset(static::$data[$name]) || array_key_exists($name, static::$data)) {
+      // Reset pre-existing static variable to its default value.
+      static::$data[$name] = static::$default[$name];
+    }
+  }
+
+}
diff --git a/core/modules/system/src/Tests/Bootstrap/ResettableStaticUnitTest.php b/core/modules/system/src/Tests/Bootstrap/ResettableStaticUnitTest.php
deleted file mode 100644
index 4dd34c8..0000000
--- a/core/modules/system/src/Tests/Bootstrap/ResettableStaticUnitTest.php
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\system\Tests\Bootstrap\ResettableStaticUnitTest.
- */
-
-namespace Drupal\system\Tests\Bootstrap;
-
-use Drupal\simpletest\KernelTestBase;
-
-/**
- * Tests that drupal_static() and drupal_static_reset() work.
- *
- * @group Bootstrap
- */
-class ResettableStaticUnitTest extends KernelTestBase {
-
-  /**
-   * Tests drupal_static() function.
-   *
-   * Tests that a variable reference returned by drupal_static() gets reset when
-   * drupal_static_reset() is called.
-   */
-  function testDrupalStatic() {
-    $name = __CLASS__ . '_' . __METHOD__;
-    $var = &drupal_static($name, 'foo');
-    $this->assertEqual($var, 'foo', 'Variable returned by drupal_static() was set to its default.');
-
-    // Call the specific reset and the global reset each twice to ensure that
-    // multiple resets can be issued without odd side effects.
-    $var = 'bar';
-    drupal_static_reset($name);
-    $this->assertEqual($var, 'foo', 'Variable was reset after first invocation of name-specific reset.');
-    $var = 'bar';
-    drupal_static_reset($name);
-    $this->assertEqual($var, 'foo', 'Variable was reset after second invocation of name-specific reset.');
-    $var = 'bar';
-    drupal_static_reset();
-    $this->assertEqual($var, 'foo', 'Variable was reset after first invocation of global reset.');
-    $var = 'bar';
-    drupal_static_reset();
-    $this->assertEqual($var, 'foo', 'Variable was reset after second invocation of global reset.');
-  }
-}
diff --git a/core/tests/Drupal/Tests/Component/Utility/StaticStorageTest.php b/core/tests/Drupal/Tests/Component/Utility/StaticStorageTest.php
new file mode 100644
index 0000000..1045fde
--- /dev/null
+++ b/core/tests/Drupal/Tests/Component/Utility/StaticStorageTest.php
@@ -0,0 +1,94 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Component\Utility\StaticStorageTest.
+ */
+
+namespace Drupal\Tests\Component\Utility;
+
+use Drupal\Component\Utility\StaticStorage;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\Component\Utility\StaticStorage
+ *
+ * @group Drupal
+ */
+class StaticStorageTest extends UnitTestCase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getInfo() {
+    return array(
+      'name' => 'Tests \Drupal\Component\Utility\StaticStorage',
+      'description' => '',
+      'group' => 'Bootstrap',
+    );
+  }
+  protected function tearDown() {
+    parent::tearDown();
+    $empty = &StaticStorage::get(NULL);
+    $empty = array();
+  }
+
+  /**
+   * @covers ::get
+   */
+  public function testGet() {
+    $var1 = &StaticStorage::get(__METHOD__, 'foo');
+    $this->assertSame('foo', $var1);
+  }
+
+  /**
+   * @covers ::get
+   */
+  public function testGetRepeated() {
+    $var1 = &StaticStorage::get(__METHOD__, 'foo');
+    $this->assertSame('foo', $var1);
+
+    $var1 = 'bar';
+    $var2 = &StaticStorage::get(__METHOD__, 'foo');
+    $this->assertSame('bar', $var2);
+  }
+
+  /**
+   * @covers ::get
+   */
+  public function testGetNull() {
+    $var1 = &StaticStorage::get(NULL);
+    $this->assertSame(array(), $var1);
+
+    $var2 = &StaticStorage::get(__METHOD__, 'foo');
+    $expected = array(
+      __METHOD__ => $var2,
+    );
+    $this->assertSame($expected, $var1);
+  }
+
+  /**
+   * @covers ::reset
+   */
+  public function testReset() {
+    $var1 = &StaticStorage::get(__METHOD__, 'foo');
+    $this->assertSame('foo', $var1);
+
+    $var1 = 'bar';
+    StaticStorage::reset(__METHOD__);
+    $this->assertSame('foo', $var1);
+  }
+
+  /**
+   * @covers ::reset
+   */
+  public function testResetNull() {
+    $var1 = &StaticStorage::get(__METHOD__, 'foo');
+    $this->assertSame('foo', $var1);
+    $var1 = 'bar';
+
+    StaticStorage::reset();
+    $this->assertSame('foo', $var1);
+  }
+
+}
