diff --git a/core/core.services.yml b/core/core.services.yml
index 951c458..5a5cb8c 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -358,6 +358,10 @@ services:
     arguments: ['@state']
     tags:
       - { name: event_subscriber }
+  drupal_static.reset_subscriber:
+    class: Drupal\Core\DrupalStatic\DrupalStatic
+    tags:
+      - { name: event_subscriber }
   entity.query:
     class: Drupal\Core\Entity\Query\QueryFactory
     arguments: ['@entity.manager']
diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index d00f819..9fdd6a1 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -14,6 +14,8 @@
 use Drupal\Core\Database\Database;
 use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Core\Extension\ExtensionDiscovery;
+use Drupal\Core\DrupalStatic\DrupalStatic;
+use Drupal\Core\DrupalStatic\StaticResetEvent;
 use Drupal\Core\Site\Settings;
 use Drupal\Core\Utility\Title;
 use Drupal\Core\Utility\Error;
@@ -2133,148 +2135,12 @@ 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 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
- *
- * @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)
- *   is recommended. For a function with multiple static variables add a
- *   distinguishing suffix to the function name for each one.
- * @param $default_value
- *   Optional default value.
- * @param $reset
- *   TRUE to reset a specific named variable, or all variables if $name is NULL.
- *   Resetting every variable should only be used, for example, for running
- *   unit tests with a clean environment. Should be used only though via
- *   function drupal_static_reset() and the return value should not be used in
- *   this case.
- *
- * @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\Core\DrupalStatic\DrupalStatic::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 = &DrupalStatic::get($name, $default_value);
+  return $value;
 }
 
 /**
@@ -2282,9 +2148,12 @@ function &drupal_static($name, $default_value = NULL, $reset = FALSE) {
  *
  * @param $name
  *   Name of the static variable to reset. Omit to reset all variables.
+ *
+ * @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
+ *   Use the event dispatcher to dispatch the 'drupal_static_reset' event.
  */
 function drupal_static_reset($name = NULL) {
-  drupal_static($name, NULL, TRUE);
+  \Drupal::service('event_dispatcher')->dispatch('drupal_static_reset', new StaticResetEvent($name));
 }
 
 /**
diff --git a/core/lib/Drupal/Core/DrupalStatic/DrupalStatic.php b/core/lib/Drupal/Core/DrupalStatic/DrupalStatic.php
new file mode 100644
index 0000000..f406f65
--- /dev/null
+++ b/core/lib/Drupal/Core/DrupalStatic/DrupalStatic.php
@@ -0,0 +1,184 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\DrupalStatic\DrupalStatic.
+ */
+
+namespace Drupal\Core\DrupalStatic;
+
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+/**
+ * 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 DrupalStatic implements EventSubscriberInterface {
+
+  /**
+   * 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_static_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];
+    }
+    // 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;
+    }
+    // As the function returns a reference, the return should always be a
+    // variable.
+    return static::$data;
+  }
+
+  /**
+   * @param \Drupal\Core\DrupalStatic\StaticResetEvent $event
+   */
+  public function onStaticReset(StaticResetEvent $event) {
+    $name = $event->getName();
+    if (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];
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getSubscribedEvents() {
+    $events['drupal_static_reset'][] = 'onStaticReset';
+    return $events;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/DrupalStatic/StaticResetEvent.php b/core/lib/Drupal/Core/DrupalStatic/StaticResetEvent.php
new file mode 100644
index 0000000..f39e727
--- /dev/null
+++ b/core/lib/Drupal/Core/DrupalStatic/StaticResetEvent.php
@@ -0,0 +1,43 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\DrupalStatic\StaticResetEvent.
+ */
+
+namespace Drupal\Core\DrupalStatic;
+
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Event object for resetting a static variable.
+ */
+class StaticResetEvent extends Event {
+
+  /**
+   * The name of the variable to reset.
+   *
+   * @var string
+   */
+  protected $name;
+
+  /**
+   * Constructs a new StaticResetEvent object.
+   *
+   * @param string $name
+   *   The name of the variable to reset.
+   */
+  public function __construct($name) {
+    $this->name = $name;
+  }
+
+  /**
+   * Gets the name of the variable to reset.
+   *
+   * @return string
+   */
+  public function getName() {
+    return $this->name;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Form/FormBuilder.php b/core/lib/Drupal/Core/Form/FormBuilder.php
index 3efa1f2..26fe63d 100644
--- a/core/lib/Drupal/Core/Form/FormBuilder.php
+++ b/core/lib/Drupal/Core/Form/FormBuilder.php
@@ -17,6 +17,7 @@
 use Drupal\Core\Render\Element;
 use Drupal\Core\Routing\UrlGeneratorInterface;
 use Drupal\Core\Site\Settings;
+use Drupal\Core\DrupalStatic\StaticResetEvent;
 use Drupal\Core\Url;
 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 use Symfony\Component\HttpFoundation\RedirectResponse;
@@ -1409,7 +1410,7 @@ protected function drupalHtmlId($id) {
    * Wraps drupal_static_reset().
    */
   protected function drupalStaticReset($name = NULL) {
-    drupal_static_reset($name);
+    $this->eventDispatcher->dispatch('drupal_static_reset', new StaticResetEvent($name));
   }
 
   /**
