diff --git a/core/core.services.yml b/core/core.services.yml
index c6161ab..657fc1b 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -10,59 +10,59 @@ parameters:
 services:
   # Simple cache contexts, directly derived from the request context.
   cache_context.ip:
-    class: Drupal\Core\Cache\IpCacheContext
+    class: Drupal\Core\Cache\Contexts\IpCacheContext
     arguments: ['@request_stack']
     tags:
       - { name: cache.context }
   cache_context.headers:
-    class: Drupal\Core\Cache\HeadersCacheContext
+    class: Drupal\Core\Cache\Contexts\HeadersCacheContext
     arguments: ['@request_stack']
     tags:
       - { name: cache.context }
   cache_context.cookies:
-    class: Drupal\Core\Cache\CookiesCacheContext
+    class: Drupal\Core\Cache\Contexts\CookiesCacheContext
     arguments: ['@request_stack']
     tags:
       - { name: cache.context }
   cache_context.request_format:
-    class: Drupal\Core\Cache\RequestFormatCacheContext
+    class: Drupal\Core\Cache\Contexts\RequestFormatCacheContext
     arguments: ['@request_stack']
     tags:
       - { name: cache.context }
   cache_context.url:
-    class: Drupal\Core\Cache\UrlCacheContext
+    class: Drupal\Core\Cache\Contexts\UrlCacheContext
     arguments: ['@request_stack']
     tags:
       - { name: cache.context }
   cache_context.url.site:
-    class: Drupal\Core\Cache\SiteCacheContext
+    class: Drupal\Core\Cache\Contexts\SiteCacheContext
     arguments: ['@request_stack']
     tags:
       - { name: cache.context }
   cache_context.url.query_args:
-    class: Drupal\Core\Cache\QueryArgsCacheContext
+    class: Drupal\Core\Cache\Contexts\QueryArgsCacheContext
     arguments: ['@request_stack']
     tags:
       - { name: cache.context }
   cache_context.url.query_args.pagers:
-    class: Drupal\Core\Cache\PagersCacheContext
+    class: Drupal\Core\Cache\Contexts\PagersCacheContext
     arguments: ['@request_stack']
     tags:
       - { name: cache.context }
 
   # Complex cache contexts, that depend on the routing system.
   cache_context.route:
-    class: Drupal\Core\Cache\RouteCacheContext
+    class: Drupal\Core\Cache\Contexts\RouteCacheContext
     arguments: ['@current_route_match']
     tags:
       - { name: cache.context }
   cache_context.route.name:
-    class: Drupal\Core\Cache\RouteNameCacheContext
+    class: Drupal\Core\Cache\Contexts\RouteNameCacheContext
     arguments: ['@current_route_match']
     tags:
       - { name: cache.context }
   cache_context.route.menu_active_trails:
-    class: Drupal\Core\Cache\MenuActiveTrailsCacheContext
+    class: Drupal\Core\Cache\Contexts\MenuActiveTrailsCacheContext
     calls:
       - [setContainer, ['@service_container']]
     tags:
@@ -72,37 +72,37 @@ services:
   # multiple aspects of the request context plus additional logic. Hence they
   # are their own roots.
   cache_context.user:
-    class: Drupal\Core\Cache\UserCacheContext
+    class: Drupal\Core\Cache\Contexts\UserCacheContext
     arguments: ['@current_user']
     tags:
       - { name: cache.context}
   cache_context.user.permissions:
-    class: Drupal\Core\Cache\AccountPermissionsCacheContext
+    class: Drupal\Core\Cache\Contexts\AccountPermissionsCacheContext
     arguments: ['@current_user', '@user_permissions_hash_generator']
     tags:
       - { name: cache.context}
   cache_context.user.roles:
-    class: Drupal\Core\Cache\UserRolesCacheContext
+    class: Drupal\Core\Cache\Contexts\UserRolesCacheContext
     arguments: ['@current_user']
     tags:
       - { name: cache.context}
   cache_context.user.is_super_user:
-    class: Drupal\Core\Cache\IsSuperUserCacheContext
+    class: Drupal\Core\Cache\Contexts\IsSuperUserCacheContext
     arguments: ['@current_user']
     tags:
       - { name: cache.context}
   cache_context.languages:
-    class: Drupal\Core\Cache\LanguagesCacheContext
+    class: Drupal\Core\Cache\Contexts\LanguagesCacheContext
     arguments: ['@language_manager']
     tags:
       - { name: cache.context}
   cache_context.theme:
-    class: Drupal\Core\Cache\ThemeCacheContext
+    class: Drupal\Core\Cache\Contexts\ThemeCacheContext
     arguments: ['@theme.manager']
     tags:
       - { name: cache.context}
   cache_context.timezone:
-    class: Drupal\Core\Cache\TimeZoneCacheContext
+    class: Drupal\Core\Cache\Contexts\TimeZoneCacheContext
     tags:
       - { name: cache.context}
 
@@ -112,7 +112,7 @@ services:
     calls:
       - [setContainer, ['@service_container']]
   cache_contexts_manager:
-    class: Drupal\Core\Cache\CacheContextsManager
+    class: Drupal\Core\Cache\Contexts\CacheContextsManager
     arguments: ['@service_container', '%cache_contexts%' ]
   cache_tags.invalidator:
     parent: container.trait
diff --git a/core/lib/Drupal/Core/Access/AccessResult.php b/core/lib/Drupal/Core/Access/AccessResult.php
index 24d5051..c2dc8e1 100644
--- a/core/lib/Drupal/Core/Access/AccessResult.php
+++ b/core/lib/Drupal/Core/Access/AccessResult.php
@@ -31,8 +31,8 @@
   /**
    * The cache context IDs (to vary a cache item ID based on active contexts).
    *
-   * @see \Drupal\Core\Cache\CacheContextInterface
-   * @see \Drupal\Core\Cache\CacheContextsManager::convertTokensToKeys()
+   * @see \Drupal\Core\Cache\Contexts\CacheContextInterface
+   * @see \Drupal\Core\Cache\Contexts\CacheContextsManager::convertTokensToKeys()
    *
    * @var string[]
    */
diff --git a/core/lib/Drupal/Core/Cache/AccountPermissionsCacheContext.php b/core/lib/Drupal/Core/Cache/AccountPermissionsCacheContext.php
deleted file mode 100644
index 3352eca..0000000
--- a/core/lib/Drupal/Core/Cache/AccountPermissionsCacheContext.php
+++ /dev/null
@@ -1,52 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Cache\UserRolesCacheContext.
- */
-
-namespace Drupal\Core\Cache;
-
-use Drupal\Core\Session\AccountInterface;
-use Drupal\Core\Session\PermissionsHashGeneratorInterface;
-
-/**
- * Defines the AccountPermissionsCacheContext service, for "per permission" caching.
- */
-class AccountPermissionsCacheContext extends UserCacheContext {
-
-  /**
-   * The permissions hash generator.
-   *
-   * @var \Drupal\user\PermissionsHashInterface
-   */
-  protected $permissionsHashGenerator;
-
-  /**
-   * Constructs a new UserCacheContext service.
-   *
-   * @param \Drupal\Core\Session\AccountInterface $user
-   *   The current user.
-   * @param \Drupal\user\PermissionsHashInterface $permissions_hash_generator
-   *   The permissions hash generator.
-   */
-  public function __construct(AccountInterface $user, PermissionsHashGeneratorInterface $permissions_hash_generator) {
-    $this->user = $user;
-    $this->permissionsHashGenerator = $permissions_hash_generator;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getLabel() {
-    return t("Account's permissions");
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getContext() {
-    return 'ph.' . $this->permissionsHashGenerator->generate($this->user);
-  }
-
-}
diff --git a/core/lib/Drupal/Core/Cache/CacheContextInterface.php b/core/lib/Drupal/Core/Cache/CacheContextInterface.php
deleted file mode 100644
index fd9783a..0000000
--- a/core/lib/Drupal/Core/Cache/CacheContextInterface.php
+++ /dev/null
@@ -1,34 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Cache\CacheContextInterface.
- */
-
-namespace Drupal\Core\Cache;
-
-/**
- * Provides an interface for defining a cache context service.
- */
-interface CacheContextInterface {
-
-  /**
-   * Returns the label of the cache context.
-   *
-   * @return string
-   *   The label of the cache context.
-   */
-  public static function getLabel();
-
-  /**
-   * Returns the string representation of the cache context.
-   *
-   * A cache context service's name is used as a token (placeholder) cache key,
-   * and is then replaced with the string returned by this method.
-   *
-   * @return string
-   *   The string representation of the cache context.
-   */
-  public function getContext();
-
-}
diff --git a/core/lib/Drupal/Core/Cache/CacheContextsManager.php b/core/lib/Drupal/Core/Cache/CacheContextsManager.php
deleted file mode 100644
index 67857cb..0000000
--- a/core/lib/Drupal/Core/Cache/CacheContextsManager.php
+++ /dev/null
@@ -1,274 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Cache\CacheContextsManager.
- */
-
-namespace Drupal\Core\Cache;
-
-use Drupal\Component\Utility\SafeMarkup;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Converts cache context tokens into cache keys.
- *
- * Uses cache context services (services tagged with 'cache.context', and whose
- * service ID has the 'cache_context.' prefix) to dynamically generate cache
- * keys based on the request context, thus allowing developers to express the
- * state by which should varied (the current URL, language, and so on).
- *
- * Note that this maps exactly to HTTP's Vary header semantics:
- * @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.44
- *
- * @see \Drupal\Core\Cache\CacheContextInterface
- * @see \Drupal\Core\Cache\CalculatedCacheContextInterface
- * @see \Drupal\Core\Cache\CacheContextsPass
- */
-class CacheContextsManager {
-
-  /**
-   * The service container.
-   *
-   * @var \Symfony\Component\DependencyInjection\ContainerInterface
-   */
-  protected $container;
-
-  /**
-   * Available cache context IDs and corresponding labels.
-   *
-   * @var string[]
-   */
-  protected $contexts;
-
-  /**
-   * Constructs a CacheContextsManager object.
-   *
-   * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
-   *   The current service container.
-   * @param string[] $contexts
-   *   An array of the available cache context IDs.
-   */
-  public function __construct(ContainerInterface $container, array $contexts) {
-    $this->container = $container;
-    $this->contexts = $contexts;
-  }
-
-  /**
-   * Provides an array of available cache contexts.
-   *
-   * @return string[]
-   *   An array of available cache context IDs.
-   */
-  public function getAll() {
-    return $this->contexts;
-  }
-
-  /**
-   * Provides an array of available cache context labels.
-   *
-   * To be used in cache configuration forms.
-   *
-   * @param bool $include_calculated_cache_contexts
-   *   Whether to also return calculated cache contexts. Default to FALSE.
-   *
-   * @return array
-   *   An array of available cache contexts and corresponding labels.
-   */
-  public function getLabels($include_calculated_cache_contexts = FALSE) {
-    $with_labels = array();
-    foreach ($this->contexts as $context) {
-      $service = $this->getService($context);
-      if (!$include_calculated_cache_contexts && $service instanceof CalculatedCacheContextInterface) {
-        continue;
-      }
-      $with_labels[$context] = $service->getLabel();
-    }
-    return $with_labels;
-  }
-
-  /**
-   * Converts cache context tokens to cache keys.
-   *
-   * A cache context token is either:
-   * - a cache context ID (if the service ID is 'cache_context.foo', then 'foo'
-   *   is a cache context ID), e.g. 'foo'
-   * - a calculated cache context ID, followed by a double colon, followed by
-   *   the parameter for the calculated cache context, e.g. 'bar:some_parameter'
-   *
-   * @param string[] $context_tokens
-   *   An array of cache context tokens.
-   *
-   * @return string[]
-   *   The array of corresponding cache keys.
-   *
-   * @throws \InvalidArgumentException
-   */
-  public function convertTokensToKeys(array $context_tokens) {
-    $context_tokens = $this->optimizeTokens($context_tokens);
-    sort($context_tokens);
-    $keys = [];
-    foreach (static::parseTokens($context_tokens) as $context) {
-      list($context_id, $parameter) = $context;
-      if (!in_array($context_id, $this->contexts)) {
-        throw new \InvalidArgumentException(SafeMarkup::format('"@context" is not a valid cache context ID.', ['@context' => $context_id]));
-      }
-      $keys[] = $this->getService($context_id)->getContext($parameter);
-    }
-    return $keys;
-  }
-
-  /**
-   * Optimizes cache context tokens (the minimal representative subset).
-   *
-   * A minimal representative subset means that any cache context token in the
-   * given set of cache context tokens that is a property of another cache
-   * context cache context token in the set, is removed.
-   *
-   * Hence a minimal representative subset is the most compact representation
-   * possible of a set of cache context tokens, that still captures the entire
-   * universe of variations.
-   *
-   * E.g. when caching per user ('user'), also caching per role ('user.roles')
-   * is meaningless because "per role" is implied by "per user".
-   *
-   * Examples — remember that the period indicates hierarchy and the colon can
-   * be used to get a specific value of a calculated cache context:
-   * - ['a', 'a.b'] -> ['a']
-   * - ['a', 'a.b.c'] -> ['a']
-   * - ['a.b', 'a.b.c'] -> ['a.b']
-   * - ['a', 'a.b', 'a.b.c'] -> ['a']
-   * - ['x', 'x:foo'] -> ['x']
-   * - ['a', 'a.b.c:bar'] -> ['a']
-   *
-   * @param string[] $context_tokens
-   *   A set of cache context tokens.
-   *
-   * @return string[]
-   *   A representative subset of the given set of cache context tokens..
-   */
-  public function optimizeTokens(array $context_tokens) {
-    $optimized_content_tokens = [];
-    foreach ($context_tokens as $context_token) {
-      // Context tokens without:
-      // - a period means they don't have a parent
-      // - a colon means they're not a specific value of a cache context
-      // hence no optimizations are possible.
-      if (strpos($context_token, '.') === FALSE && strpos($context_token, ':') === FALSE) {
-        $optimized_content_tokens[] = $context_token;
-      }
-      // The context token has a period or a colon. Iterate over all ancestor
-      // cache contexts. If one exists, omit the context token.
-      else {
-        $ancestor_found = FALSE;
-        // Treat a colon like a period, that allows us to consider 'a' the
-        // ancestor of 'a:foo', without any additional code for the colon.
-        $ancestor = str_replace(':', '.', $context_token);
-        do {
-          $ancestor = substr($ancestor, 0, strrpos($ancestor, '.'));
-          if (in_array($ancestor, $context_tokens)) {
-            // An ancestor cache context is in $context_tokens, hence this cache
-            // context is implied.
-            $ancestor_found = TRUE;
-          }
-
-        } while(!$ancestor_found && strpos($ancestor, '.') !== FALSE);
-        if (!$ancestor_found) {
-          $optimized_content_tokens[] = $context_token;
-        }
-      }
-    }
-    return $optimized_content_tokens;
-  }
-
-  /**
-   * Retrieves a cache context service from the container.
-   *
-   * @param string $context_id
-   *   The context ID, which together with the service ID prefix allows the
-   *   corresponding cache context service to be retrieved.
-   *
-   * @return \Drupal\Core\Cache\CacheContextInterface
-   *   The requested cache context service.
-   */
-  protected function getService($context_id) {
-    return $this->container->get('cache_context.' . $context_id);
-  }
-
-  /**
-   * Parses cache context tokens into context IDs and optional parameters.
-   *
-   * @param string[] $context_tokens
-   *   An array of cache context tokens.
-   *
-   * @return array
-   *   An array with the parsed results, with each result being an array
-   *   containing:
-   *   - The cache context ID.
-   *   - The associated parameter (for a calculated cache context), or NULL if
-   *     there is no parameter.
-   */
-  public static function parseTokens(array $context_tokens) {
-    $contexts_with_parameters = [];
-    foreach ($context_tokens as $context) {
-      $context_id = $context;
-      $parameter = NULL;
-      if (strpos($context, ':') !== FALSE) {
-        list($context_id, $parameter) = explode(':', $context, 2);
-      }
-      $contexts_with_parameters[] = [$context_id, $parameter];
-    }
-    return $contexts_with_parameters;
-  }
-
-  /**
-   * Validates an array of cache context tokens.
-   *
-   * Can be called before using cache contexts in operations, to check validity.
-   *
-   * @param string[] $context_tokens
-   *   An array of cache context tokens.
-   *
-   * @throws \LogicException
-   *
-   * @see \Drupal\Core\Cache\CacheContextsManager::parseTokens()
-   */
-  public function validateTokens(array $context_tokens = []) {
-    if (empty($context_tokens)) {
-      return;
-    }
-
-    // Initialize the set of valid context tokens with the container's contexts.
-    if (!isset($this->validContextTokens)) {
-      $this->validContextTokens = array_flip($this->contexts);
-    }
-
-    foreach ($context_tokens as $context_token) {
-      if (!is_string($context_token)) {
-        throw new \LogicException(sprintf('Cache contexts must be strings, %s given.', gettype($context_token)));
-      }
-
-      if (isset($this->validContextTokens[$context_token])) {
-        continue;
-      }
-
-      // If it's a valid context token, then the ID must be stored in the set
-      // of valid context tokens (since we initialized it with the list of cache
-      // context IDs using the container). In case of an invalid context token,
-      // throw an exception, otherwise cache it, including the parameter, to
-      // minimize the amount of work in future ::validateContexts() calls.
-      $context_id = $context_token;
-      $colon_pos = strpos($context_id, ':');
-      if ($colon_pos !== FALSE) {
-        $context_id = substr($context_id, 0, $colon_pos);
-      }
-      if (isset($this->validContextTokens[$context_id])) {
-        $this->validContextTokens[$context_token] = TRUE;
-      }
-      else {
-        throw new \LogicException(sprintf('"%s" is not a valid cache context ID.', $context_id));
-      }
-    }
-  }
-
-}
diff --git a/core/lib/Drupal/Core/Cache/CacheContextsPass.php b/core/lib/Drupal/Core/Cache/CacheContextsPass.php
deleted file mode 100644
index 576b2b5..0000000
--- a/core/lib/Drupal/Core/Cache/CacheContextsPass.php
+++ /dev/null
@@ -1,48 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Cache\CacheContextsPass.
- */
-
-namespace Drupal\Core\Cache;
-
-use Symfony\Component\DependencyInjection\ContainerBuilder;
-use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
-
-/**
- * Adds cache_contexts parameter to the container.
- */
-class CacheContextsPass implements CompilerPassInterface {
-
-  /**
-   * Implements CompilerPassInterface::process().
-   *
-   * Collects the cache contexts into the cache_contexts parameter.
-   */
-  public function process(ContainerBuilder $container) {
-    $cache_contexts = [];
-    foreach (array_keys($container->findTaggedServiceIds('cache.context')) as $id) {
-      if (strpos($id, 'cache_context.') !== 0) {
-        throw new \InvalidArgumentException(sprintf('The service "%s" has an invalid service ID: cache context service IDs must use the "cache_context." prefix. (The suffix is the cache context ID developers may use.)', $id));
-      }
-      $cache_contexts[] = substr($id, 14);
-    }
-
-    // Validate.
-    sort($cache_contexts);
-    foreach ($cache_contexts as $id) {
-      // Validate the hierarchy of non-root-level cache contexts.
-      if (strpos($id, '.') !== FALSE) {
-        $parent = substr($id, 0, strrpos($id, '.'));
-        if (!in_array($parent, $cache_contexts)) {
-          throw new \InvalidArgumentException(sprintf('The service "%s" has an invalid service ID: the period indicates the hierarchy of cache contexts, therefore "%s" is considered the parent cache context, but no cache context service with that name was found.', $id, $parent));
-        }
-      }
-    }
-
-
-    $container->setParameter('cache_contexts', $cache_contexts);
-  }
-
-}
diff --git a/core/lib/Drupal/Core/Cache/CalculatedCacheContextInterface.php b/core/lib/Drupal/Core/Cache/CalculatedCacheContextInterface.php
deleted file mode 100644
index 38114c3..0000000
--- a/core/lib/Drupal/Core/Cache/CalculatedCacheContextInterface.php
+++ /dev/null
@@ -1,40 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Cache\CacheContextInterface.
- */
-
-namespace Drupal\Core\Cache;
-
-/**
- * Provides an interface for defining a calculated cache context service.
- */
-interface CalculatedCacheContextInterface {
-
-  /**
-   * Returns the label of the cache context.
-   *
-   * @return string
-   *   The label of the cache context.
-   *
-   * @see Cache
-   */
-  public static function getLabel();
-
-  /**
-   * Returns the string representation of the cache context.
-   *
-   * A cache context service's name is used as a token (placeholder) cache key,
-   * and is then replaced with the string returned by this method.
-   *
-   * @param string|null $parameter
-   *   The parameter, or NULL to indicate all possible parameter values.
-   *
-   * @return string
-   *   The string representation of the cache context. When $parameter is NULL,
-   *   a value representing all possible parameters must be generated.
-   */
-  public function getContext($parameter = NULL);
-
-}
diff --git a/core/lib/Drupal/Core/Cache/Contexts/AccountPermissionsCacheContext.php b/core/lib/Drupal/Core/Cache/Contexts/AccountPermissionsCacheContext.php
new file mode 100644
index 0000000..9ebc858
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/Contexts/AccountPermissionsCacheContext.php
@@ -0,0 +1,52 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Cache\Contexts\UserRolesCacheContext.
+ */
+
+namespace Drupal\Core\Cache\Contexts;
+
+use Drupal\Core\Session\AccountInterface;
+use Drupal\Core\Session\PermissionsHashGeneratorInterface;
+
+/**
+ * Defines the AccountPermissionsCacheContext service, for "per permission" caching.
+ */
+class AccountPermissionsCacheContext extends UserCacheContext {
+
+  /**
+   * The permissions hash generator.
+   *
+   * @var \Drupal\user\PermissionsHashInterface
+   */
+  protected $permissionsHashGenerator;
+
+  /**
+   * Constructs a new UserCacheContext service.
+   *
+   * @param \Drupal\Core\Session\AccountInterface $user
+   *   The current user.
+   * @param \Drupal\user\PermissionsHashInterface $permissions_hash_generator
+   *   The permissions hash generator.
+   */
+  public function __construct(AccountInterface $user, PermissionsHashGeneratorInterface $permissions_hash_generator) {
+    $this->user = $user;
+    $this->permissionsHashGenerator = $permissions_hash_generator;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getLabel() {
+    return t("Account's permissions");
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getContext() {
+    return 'ph.' . $this->permissionsHashGenerator->generate($this->user);
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Cache/Contexts/CacheContextInterface.php b/core/lib/Drupal/Core/Cache/Contexts/CacheContextInterface.php
new file mode 100644
index 0000000..ce36a5e
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/Contexts/CacheContextInterface.php
@@ -0,0 +1,34 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Cache\Contexts\CacheContextInterface.
+ */
+
+namespace Drupal\Core\Cache\Contexts;
+
+/**
+ * Provides an interface for defining a cache context service.
+ */
+interface CacheContextInterface {
+
+  /**
+   * Returns the label of the cache context.
+   *
+   * @return string
+   *   The label of the cache context.
+   */
+  public static function getLabel();
+
+  /**
+   * Returns the string representation of the cache context.
+   *
+   * A cache context service's name is used as a token (placeholder) cache key,
+   * and is then replaced with the string returned by this method.
+   *
+   * @return string
+   *   The string representation of the cache context.
+   */
+  public function getContext();
+
+}
diff --git a/core/lib/Drupal/Core/Cache/Contexts/CacheContextsManager.php b/core/lib/Drupal/Core/Cache/Contexts/CacheContextsManager.php
new file mode 100644
index 0000000..af68c3b
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/Contexts/CacheContextsManager.php
@@ -0,0 +1,274 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Cache\Contexts\CacheContextsManager.
+ */
+
+namespace Drupal\Core\Cache\Contexts;
+
+use Drupal\Component\Utility\SafeMarkup;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Converts cache context tokens into cache keys.
+ *
+ * Uses cache context services (services tagged with 'cache.context', and whose
+ * service ID has the 'cache_context.' prefix) to dynamically generate cache
+ * keys based on the request context, thus allowing developers to express the
+ * state by which should varied (the current URL, language, and so on).
+ *
+ * Note that this maps exactly to HTTP's Vary header semantics:
+ * @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.44
+ *
+ * @see \Drupal\Core\Cache\Contexts\CacheContextInterface
+ * @see \Drupal\Core\Cache\Contexts\CalculatedCacheContextInterface
+ * @see \Drupal\Core\Cache\Contexts\CacheContextsPass
+ */
+class CacheContextsManager {
+
+  /**
+   * The service container.
+   *
+   * @var \Symfony\Component\DependencyInjection\ContainerInterface
+   */
+  protected $container;
+
+  /**
+   * Available cache context IDs and corresponding labels.
+   *
+   * @var string[]
+   */
+  protected $contexts;
+
+  /**
+   * Constructs a CacheContextsManager object.
+   *
+   * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
+   *   The current service container.
+   * @param string[] $contexts
+   *   An array of the available cache context IDs.
+   */
+  public function __construct(ContainerInterface $container, array $contexts) {
+    $this->container = $container;
+    $this->contexts = $contexts;
+  }
+
+  /**
+   * Provides an array of available cache contexts.
+   *
+   * @return string[]
+   *   An array of available cache context IDs.
+   */
+  public function getAll() {
+    return $this->contexts;
+  }
+
+  /**
+   * Provides an array of available cache context labels.
+   *
+   * To be used in cache configuration forms.
+   *
+   * @param bool $include_calculated_cache_contexts
+   *   Whether to also return calculated cache contexts. Default to FALSE.
+   *
+   * @return array
+   *   An array of available cache contexts and corresponding labels.
+   */
+  public function getLabels($include_calculated_cache_contexts = FALSE) {
+    $with_labels = array();
+    foreach ($this->contexts as $context) {
+      $service = $this->getService($context);
+      if (!$include_calculated_cache_contexts && $service instanceof CalculatedCacheContextInterface) {
+        continue;
+      }
+      $with_labels[$context] = $service->getLabel();
+    }
+    return $with_labels;
+  }
+
+  /**
+   * Converts cache context tokens to cache keys.
+   *
+   * A cache context token is either:
+   * - a cache context ID (if the service ID is 'cache_context.foo', then 'foo'
+   *   is a cache context ID), e.g. 'foo'
+   * - a calculated cache context ID, followed by a double colon, followed by
+   *   the parameter for the calculated cache context, e.g. 'bar:some_parameter'
+   *
+   * @param string[] $context_tokens
+   *   An array of cache context tokens.
+   *
+   * @return string[]
+   *   The array of corresponding cache keys.
+   *
+   * @throws \InvalidArgumentException
+   */
+  public function convertTokensToKeys(array $context_tokens) {
+    $context_tokens = $this->optimizeTokens($context_tokens);
+    sort($context_tokens);
+    $keys = [];
+    foreach (static::parseTokens($context_tokens) as $context) {
+      list($context_id, $parameter) = $context;
+      if (!in_array($context_id, $this->contexts)) {
+        throw new \InvalidArgumentException(SafeMarkup::format('"@context" is not a valid cache context ID.', ['@context' => $context_id]));
+      }
+      $keys[] = $this->getService($context_id)->getContext($parameter);
+    }
+    return $keys;
+  }
+
+  /**
+   * Optimizes cache context tokens (the minimal representative subset).
+   *
+   * A minimal representative subset means that any cache context token in the
+   * given set of cache context tokens that is a property of another cache
+   * context cache context token in the set, is removed.
+   *
+   * Hence a minimal representative subset is the most compact representation
+   * possible of a set of cache context tokens, that still captures the entire
+   * universe of variations.
+   *
+   * E.g. when caching per user ('user'), also caching per role ('user.roles')
+   * is meaningless because "per role" is implied by "per user".
+   *
+   * Examples — remember that the period indicates hierarchy and the colon can
+   * be used to get a specific value of a calculated cache context:
+   * - ['a', 'a.b'] -> ['a']
+   * - ['a', 'a.b.c'] -> ['a']
+   * - ['a.b', 'a.b.c'] -> ['a.b']
+   * - ['a', 'a.b', 'a.b.c'] -> ['a']
+   * - ['x', 'x:foo'] -> ['x']
+   * - ['a', 'a.b.c:bar'] -> ['a']
+   *
+   * @param string[] $context_tokens
+   *   A set of cache context tokens.
+   *
+   * @return string[]
+   *   A representative subset of the given set of cache context tokens..
+   */
+  public function optimizeTokens(array $context_tokens) {
+    $optimized_content_tokens = [];
+    foreach ($context_tokens as $context_token) {
+      // Context tokens without:
+      // - a period means they don't have a parent
+      // - a colon means they're not a specific value of a cache context
+      // hence no optimizations are possible.
+      if (strpos($context_token, '.') === FALSE && strpos($context_token, ':') === FALSE) {
+        $optimized_content_tokens[] = $context_token;
+      }
+      // The context token has a period or a colon. Iterate over all ancestor
+      // cache contexts. If one exists, omit the context token.
+      else {
+        $ancestor_found = FALSE;
+        // Treat a colon like a period, that allows us to consider 'a' the
+        // ancestor of 'a:foo', without any additional code for the colon.
+        $ancestor = str_replace(':', '.', $context_token);
+        do {
+          $ancestor = substr($ancestor, 0, strrpos($ancestor, '.'));
+          if (in_array($ancestor, $context_tokens)) {
+            // An ancestor cache context is in $context_tokens, hence this cache
+            // context is implied.
+            $ancestor_found = TRUE;
+          }
+
+        } while(!$ancestor_found && strpos($ancestor, '.') !== FALSE);
+        if (!$ancestor_found) {
+          $optimized_content_tokens[] = $context_token;
+        }
+      }
+    }
+    return $optimized_content_tokens;
+  }
+
+  /**
+   * Retrieves a cache context service from the container.
+   *
+   * @param string $context_id
+   *   The context ID, which together with the service ID prefix allows the
+   *   corresponding cache context service to be retrieved.
+   *
+   * @return \Drupal\Core\Cache\Contexts\CacheContextInterface
+   *   The requested cache context service.
+   */
+  protected function getService($context_id) {
+    return $this->container->get('cache_context.' . $context_id);
+  }
+
+  /**
+   * Parses cache context tokens into context IDs and optional parameters.
+   *
+   * @param string[] $context_tokens
+   *   An array of cache context tokens.
+   *
+   * @return array
+   *   An array with the parsed results, with each result being an array
+   *   containing:
+   *   - The cache context ID.
+   *   - The associated parameter (for a calculated cache context), or NULL if
+   *     there is no parameter.
+   */
+  public static function parseTokens(array $context_tokens) {
+    $contexts_with_parameters = [];
+    foreach ($context_tokens as $context) {
+      $context_id = $context;
+      $parameter = NULL;
+      if (strpos($context, ':') !== FALSE) {
+        list($context_id, $parameter) = explode(':', $context, 2);
+      }
+      $contexts_with_parameters[] = [$context_id, $parameter];
+    }
+    return $contexts_with_parameters;
+  }
+
+  /**
+   * Validates an array of cache context tokens.
+   *
+   * Can be called before using cache contexts in operations, to check validity.
+   *
+   * @param string[] $context_tokens
+   *   An array of cache context tokens.
+   *
+   * @throws \LogicException
+   *
+   * @see \Drupal\Core\Cache\Contexts\CacheContextsManager::parseTokens()
+   */
+  public function validateTokens(array $context_tokens = []) {
+    if (empty($context_tokens)) {
+      return;
+    }
+
+    // Initialize the set of valid context tokens with the container's contexts.
+    if (!isset($this->validContextTokens)) {
+      $this->validContextTokens = array_flip($this->contexts);
+    }
+
+    foreach ($context_tokens as $context_token) {
+      if (!is_string($context_token)) {
+        throw new \LogicException(sprintf('Cache contexts must be strings, %s given.', gettype($context_token)));
+      }
+
+      if (isset($this->validContextTokens[$context_token])) {
+        continue;
+      }
+
+      // If it's a valid context token, then the ID must be stored in the set
+      // of valid context tokens (since we initialized it with the list of cache
+      // context IDs using the container). In case of an invalid context token,
+      // throw an exception, otherwise cache it, including the parameter, to
+      // minimize the amount of work in future ::validateContexts() calls.
+      $context_id = $context_token;
+      $colon_pos = strpos($context_id, ':');
+      if ($colon_pos !== FALSE) {
+        $context_id = substr($context_id, 0, $colon_pos);
+      }
+      if (isset($this->validContextTokens[$context_id])) {
+        $this->validContextTokens[$context_token] = TRUE;
+      }
+      else {
+        throw new \LogicException(sprintf('"%s" is not a valid cache context ID.', $context_id));
+      }
+    }
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Cache/Contexts/CacheContextsPass.php b/core/lib/Drupal/Core/Cache/Contexts/CacheContextsPass.php
new file mode 100644
index 0000000..9e1bc48
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/Contexts/CacheContextsPass.php
@@ -0,0 +1,48 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Cache\Contexts\CacheContextsPass.
+ */
+
+namespace Drupal\Core\Cache\Contexts;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+
+/**
+ * Adds cache_contexts parameter to the container.
+ */
+class CacheContextsPass implements CompilerPassInterface {
+
+  /**
+   * Implements CompilerPassInterface::process().
+   *
+   * Collects the cache contexts into the cache_contexts parameter.
+   */
+  public function process(ContainerBuilder $container) {
+    $cache_contexts = [];
+    foreach (array_keys($container->findTaggedServiceIds('cache.context')) as $id) {
+      if (strpos($id, 'cache_context.') !== 0) {
+        throw new \InvalidArgumentException(sprintf('The service "%s" has an invalid service ID: cache context service IDs must use the "cache_context." prefix. (The suffix is the cache context ID developers may use.)', $id));
+      }
+      $cache_contexts[] = substr($id, 14);
+    }
+
+    // Validate.
+    sort($cache_contexts);
+    foreach ($cache_contexts as $id) {
+      // Validate the hierarchy of non-root-level cache contexts.
+      if (strpos($id, '.') !== FALSE) {
+        $parent = substr($id, 0, strrpos($id, '.'));
+        if (!in_array($parent, $cache_contexts)) {
+          throw new \InvalidArgumentException(sprintf('The service "%s" has an invalid service ID: the period indicates the hierarchy of cache contexts, therefore "%s" is considered the parent cache context, but no cache context service with that name was found.', $id, $parent));
+        }
+      }
+    }
+
+
+    $container->setParameter('cache_contexts', $cache_contexts);
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Cache/Contexts/CalculatedCacheContextInterface.php b/core/lib/Drupal/Core/Cache/Contexts/CalculatedCacheContextInterface.php
new file mode 100644
index 0000000..a3b82f1
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/Contexts/CalculatedCacheContextInterface.php
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Cache\Contexts\CacheContextInterface.
+ */
+
+namespace Drupal\Core\Cache\Contexts;
+
+/**
+ * Provides an interface for defining a calculated cache context service.
+ */
+interface CalculatedCacheContextInterface {
+
+  /**
+   * Returns the label of the cache context.
+   *
+   * @return string
+   *   The label of the cache context.
+   *
+   * @see Cache
+   */
+  public static function getLabel();
+
+  /**
+   * Returns the string representation of the cache context.
+   *
+   * A cache context service's name is used as a token (placeholder) cache key,
+   * and is then replaced with the string returned by this method.
+   *
+   * @param string|null $parameter
+   *   The parameter, or NULL to indicate all possible parameter values.
+   *
+   * @return string
+   *   The string representation of the cache context. When $parameter is NULL,
+   *   a value representing all possible parameters must be generated.
+   */
+  public function getContext($parameter = NULL);
+
+}
diff --git a/core/lib/Drupal/Core/Cache/Contexts/CookiesCacheContext.php b/core/lib/Drupal/Core/Cache/Contexts/CookiesCacheContext.php
new file mode 100644
index 0000000..f64c923
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/Contexts/CookiesCacheContext.php
@@ -0,0 +1,34 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Cache\Contexts\CookiesCacheContext.
+ */
+
+namespace Drupal\Core\Cache\Contexts;
+
+/**
+ * Defines the CookiesCacheContext service, for "per cookie" caching.
+ */
+class CookiesCacheContext extends RequestStackCacheContextBase implements CalculatedCacheContextInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getLabel() {
+    return t('HTTP cookies');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getContext($cookie = NULL) {
+    if ($cookie === NULL) {
+      return $this->requestStack->getCurrentRequest()->cookies->all();
+    }
+    else {
+      return $this->requestStack->getCurrentRequest()->cookies->get($cookie);
+    }
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Cache/Contexts/HeadersCacheContext.php b/core/lib/Drupal/Core/Cache/Contexts/HeadersCacheContext.php
new file mode 100644
index 0000000..e19aab6
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/Contexts/HeadersCacheContext.php
@@ -0,0 +1,34 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Cache\Contexts\HeadersCacheContext.
+ */
+
+namespace Drupal\Core\Cache\Contexts;
+
+/**
+ * Defines the HeadersCacheContext service, for "per header" caching.
+ */
+class HeadersCacheContext extends RequestStackCacheContextBase implements CalculatedCacheContextInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getLabel() {
+    return t('HTTP headers');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getContext($header = NULL) {
+    if ($header === NULL) {
+      return $this->requestStack->getCurrentRequest()->headers->all();
+    }
+    else {
+      return $this->requestStack->getCurrentRequest()->headers->get($header);
+    }
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Cache/Contexts/IpCacheContext.php b/core/lib/Drupal/Core/Cache/Contexts/IpCacheContext.php
new file mode 100644
index 0000000..6b31802
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/Contexts/IpCacheContext.php
@@ -0,0 +1,29 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Cache\Contexts\IpCacheContext.
+ */
+
+namespace Drupal\Core\Cache\Contexts;
+
+/**
+ * Defines the IpCacheContext service, for "per IP address" caching.
+ */
+class IpCacheContext extends RequestStackCacheContextBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getLabel() {
+    return t('IP address');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getContext() {
+    return $this->requestStack->getCurrentRequest()->getClientIp();
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Cache/Contexts/IsSuperUserCacheContext.php b/core/lib/Drupal/Core/Cache/Contexts/IsSuperUserCacheContext.php
new file mode 100644
index 0000000..3c2a3f4
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/Contexts/IsSuperUserCacheContext.php
@@ -0,0 +1,29 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Cache\Contexts\IsSuperUserCacheContext.
+ */
+
+namespace Drupal\Core\Cache\Contexts;
+
+/**
+ * Defines the IsSuperUserCacheContext service, for "super user or not" caching.
+ */
+class IsSuperUserCacheContext extends UserCacheContext {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getLabel() {
+    return t('Is super user');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getContext() {
+    return ((int) $this->user->id()) === 1 ? '1' : '0';
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Cache/Contexts/LanguagesCacheContext.php b/core/lib/Drupal/Core/Cache/Contexts/LanguagesCacheContext.php
new file mode 100644
index 0000000..050371d
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/Contexts/LanguagesCacheContext.php
@@ -0,0 +1,77 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Cache\Contexts\LanguagesCacheContext.
+ */
+
+namespace Drupal\Core\Cache\Contexts;
+
+use Drupal\Core\Language\LanguageManagerInterface;
+
+/**
+ * Defines the LanguagesCacheContext service, for "per language" caching.
+ */
+class LanguagesCacheContext implements CalculatedCacheContextInterface  {
+
+  /**
+   * The language manager.
+   *
+   * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
+   */
+  protected $languageManager;
+
+  /**
+   * Constructs a new LanguagesCacheContext service.
+   *
+   * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
+   *   The language manager.
+   */
+  public function __construct(LanguageManagerInterface $language_manager) {
+    $this->languageManager = $language_manager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getLabel() {
+    return t('Language');
+  }
+
+  /**
+   * {@inheritdoc}
+   *
+   * $type can be NULL, or one of the language types supported by the language
+   * manager, typically:
+   * - LanguageInterface::TYPE_INTERFACE
+   * - LanguageInterface::TYPE_CONTENT
+   * - LanguageInterface::TYPE_URL
+   *
+   * @see \Drupal\Core\Language\LanguageManagerInterface::getLanguageTypes()
+   *
+   * @throws \RuntimeException
+   *   In case an invalid language type is specified.
+   */
+  public function getContext($type = NULL) {
+    if ($type === NULL) {
+      $context_parts = array();
+      if ($this->languageManager->isMultilingual()) {
+        foreach ($this->languageManager->getLanguageTypes() as $type) {
+          $context_parts[] = $this->languageManager->getCurrentLanguage($type)->getId();
+        }
+      }
+      else {
+        $context_parts[] = $this->languageManager->getCurrentLanguage()->getId();
+      }
+      return implode(',', $context_parts);
+    }
+    else {
+      $language_types = $this->languageManager->getDefinedLanguageTypesInfo();
+      if (!isset($language_types[$type])) {
+        throw new \RuntimeException(sprintf('The language type "%s" is invalid.', $type));
+      }
+      return $this->languageManager->getCurrentLanguage($type)->getId();
+    }
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Cache/Contexts/MenuActiveTrailsCacheContext.php b/core/lib/Drupal/Core/Cache/Contexts/MenuActiveTrailsCacheContext.php
new file mode 100644
index 0000000..1549ebd
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/Contexts/MenuActiveTrailsCacheContext.php
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Cache\Contexts\MenuActiveTrailsCacheContext.
+ */
+
+namespace Drupal\Core\Cache\Contexts;
+
+use Symfony\Component\DependencyInjection\ContainerAware;
+
+/**
+ * Defines the MenuActiveTrailsCacheContext service.
+ *
+ * This class is container-aware to avoid initializing the 'menu.active_trail'
+ * service (and its dependencies) when it is not necessary.
+ */
+class MenuActiveTrailsCacheContext extends ContainerAware implements CalculatedCacheContextInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getLabel() {
+    return t("Active menu trail");
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getContext($menu_name = NULL) {
+    $active_trail = $this->container->get('menu.active_trail')
+      ->getActiveTrailIds($menu_name);
+    return 'menu_trail.' . $menu_name . '|' . implode('|', $active_trail);
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Cache/Contexts/PagersCacheContext.php b/core/lib/Drupal/Core/Cache/Contexts/PagersCacheContext.php
new file mode 100644
index 0000000..dee5cf3
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/Contexts/PagersCacheContext.php
@@ -0,0 +1,37 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Cache\Contexts\PagersCacheContext.
+ */
+
+namespace Drupal\Core\Cache\Contexts;
+
+/**
+ * Defines a cache context for "per page in a pager" caching.
+ */
+class PagersCacheContext extends RequestStackCacheContextBase implements CalculatedCacheContextInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getLabel() {
+    return t('Pager');
+  }
+
+  /**
+   * {@inheritdoc}
+   *
+   * @see pager_find_page()
+   */
+  public function getContext($pager_id = NULL) {
+    // The value of the 'page' query argument contains the information that
+    // controls *all* pagers.
+    if ($pager_id === NULL) {
+      return 'pager' . $this->requestStack->getCurrentRequest()->query->get('page', '');
+    }
+
+    return 'pager.' . $pager_id . '.' . pager_find_page($pager_id);
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Cache/Contexts/QueryArgsCacheContext.php b/core/lib/Drupal/Core/Cache/Contexts/QueryArgsCacheContext.php
new file mode 100644
index 0000000..10952be
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/Contexts/QueryArgsCacheContext.php
@@ -0,0 +1,38 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Cache\Contexts\QueryArgsCacheContext.
+ */
+
+namespace Drupal\Core\Cache\Contexts;
+
+/**
+ * Defines the QueryArgsCacheContext service, for "per query args" caching.
+ *
+ * A "host" is defined as the combination of URI scheme, domain name and port.
+ *
+ * @see Symfony\Component\HttpFoundation::getSchemeAndHttpHost()
+ */
+class QueryArgsCacheContext extends RequestStackCacheContextBase implements CalculatedCacheContextInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getLabel() {
+    return t('Query arguments');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getContext($query_arg = NULL) {
+    if ($query_arg === NULL) {
+      return $this->requestStack->getCurrentRequest()->getQueryString();
+    }
+    else {
+      return $this->requestStack->getCurrentRequest()->query->get($query_arg);
+    }
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Cache/Contexts/RequestFormatCacheContext.php b/core/lib/Drupal/Core/Cache/Contexts/RequestFormatCacheContext.php
new file mode 100644
index 0000000..35ce30b
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/Contexts/RequestFormatCacheContext.php
@@ -0,0 +1,29 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Cache\Contexts\RequestFormatCacheContext.
+ */
+
+namespace Drupal\Core\Cache\Contexts;
+
+/**
+ * Defines the RequestFormatCacheContext service, for "per format" caching.
+ */
+class RequestFormatCacheContext extends RequestStackCacheContextBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getLabel() {
+    return t('Request format');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getContext() {
+    return $this->requestStack->getCurrentRequest()->getRequestFormat();
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Cache/Contexts/RequestStackCacheContextBase.php b/core/lib/Drupal/Core/Cache/Contexts/RequestStackCacheContextBase.php
new file mode 100644
index 0000000..d48d84a
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/Contexts/RequestStackCacheContextBase.php
@@ -0,0 +1,34 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Cache\Contexts\RequestStackCacheContextBase.
+ */
+
+namespace Drupal\Core\Cache\Contexts;
+
+use Symfony\Component\HttpFoundation\RequestStack;
+
+/**
+ * Defines a base class for cache contexts depending only on the request stack.
+ */
+abstract class RequestStackCacheContextBase implements CacheContextInterface {
+
+  /**
+   * The request stack.
+   *
+   * @var \Symfony\Component\HttpFoundation\RequestStack
+   */
+  protected $requestStack;
+
+  /**
+   * Constructs a new RequestStackCacheContextBase class.
+   *
+   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
+   *   The request stack.
+   */
+  public function __construct(RequestStack $request_stack) {
+    $this->requestStack = $request_stack;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Cache/Contexts/RouteCacheContext.php b/core/lib/Drupal/Core/Cache/Contexts/RouteCacheContext.php
new file mode 100644
index 0000000..aac751e
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/Contexts/RouteCacheContext.php
@@ -0,0 +1,48 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Cache\Contexts\RouteCacheContext.
+ */
+
+namespace Drupal\Core\Cache\Contexts;
+
+use Drupal\Core\Routing\RouteMatchInterface;
+
+/**
+ * Defines the RouteCacheContext service, for "per route" caching.
+ */
+class RouteCacheContext implements CacheContextInterface {
+
+  /**
+   * The route match.
+   *
+   * @var \Drupal\Core\Routing\RouteMatchInterface
+   */
+  protected $routeMatch;
+
+  /**
+   * Constructs a new RouteCacheContext class.
+   *
+   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
+   *   The route match.
+   */
+  public function __construct(RouteMatchInterface $route_match) {
+    $this->routeMatch = $route_match;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getLabel() {
+    return t('Route');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getContext() {
+    return $this->routeMatch->getRouteName() . hash('sha256', serialize($this->routeMatch->getRawParameters()->all()));
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Cache/Contexts/RouteNameCacheContext.php b/core/lib/Drupal/Core/Cache/Contexts/RouteNameCacheContext.php
new file mode 100644
index 0000000..e288620
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/Contexts/RouteNameCacheContext.php
@@ -0,0 +1,29 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Cache\Contexts\RouteNameCacheContext.
+ */
+
+namespace Drupal\Core\Cache\Contexts;
+
+/**
+ * Defines the RouteCacheContext service, for "per route name" caching.
+ */
+class RouteNameCacheContext extends RouteCacheContext {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getLabel() {
+    return t('Route name');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getContext() {
+    return $this->routeMatch->getRouteName();
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Cache/Contexts/SiteCacheContext.php b/core/lib/Drupal/Core/Cache/Contexts/SiteCacheContext.php
new file mode 100644
index 0000000..73f9f15
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/Contexts/SiteCacheContext.php
@@ -0,0 +1,38 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Cache\Contexts\SiteCacheContext.
+ */
+
+namespace Drupal\Core\Cache\Contexts;
+
+/**
+ * Defines the SiteCacheContext service, for "per site" caching.
+ *
+ * A "site" is defined as the combination of URI scheme, domain name, port and
+ * base path. It allows for varying between the *same* site being accessed via
+ * different entry points. (Different sites in a multisite setup have separate
+ * databases.) For example: http://example.com and http://www.example.com.
+ *
+ * @see \Symfony\Component\HttpFoundation\Request::getSchemeAndHttpHost()
+ * @see \Symfony\Component\HttpFoundation\Request::getBaseUrl()
+ */
+class SiteCacheContext extends RequestStackCacheContextBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getLabel() {
+    return t('Site');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getContext() {
+    $request = $this->requestStack->getCurrentRequest();
+    return $request->getSchemeAndHttpHost() . $request->getBaseUrl();
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Cache/Contexts/ThemeCacheContext.php b/core/lib/Drupal/Core/Cache/Contexts/ThemeCacheContext.php
new file mode 100644
index 0000000..f24ef19
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/Contexts/ThemeCacheContext.php
@@ -0,0 +1,49 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Cache\Contexts\LanguageCacheContext.
+ */
+
+namespace Drupal\Core\Cache\Contexts;
+
+use Drupal\Core\Routing\RouteMatchInterface;
+use Drupal\Core\Theme\ThemeManagerInterface;
+
+/**
+ * Defines the ThemeCacheContext service, for "per theme" caching.
+ */
+class ThemeCacheContext implements CacheContextInterface {
+
+  /**
+   * The theme manager.
+   *
+   * @var \Drupal\Core\Theme\ThemeManagerInterface
+   */
+  protected $themeManager;
+
+  /**
+   * Constructs a new ThemeCacheContext service.
+   *
+   * @param \Drupal\Core\Theme\ThemeManagerInterface $theme_manager
+   *   The theme manager.
+   */
+  public function __construct(ThemeManagerInterface $theme_manager) {
+    $this->themeManager = $theme_manager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getLabel() {
+    return t('Theme');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getContext() {
+    return $this->themeManager->getActiveTheme()->getName() ?: 'stark';
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Cache/Contexts/TimeZoneCacheContext.php b/core/lib/Drupal/Core/Cache/Contexts/TimeZoneCacheContext.php
new file mode 100644
index 0000000..cbbc7cc
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/Contexts/TimeZoneCacheContext.php
@@ -0,0 +1,33 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Cache\Contexts\TimeZoneCacheContext.
+ */
+
+namespace Drupal\Core\Cache\Contexts;
+
+/**
+ * Defines the TimeZoneCacheContext service, for "per time zone" caching.
+ *
+ * @see \Drupal\Core\Session\AccountProxy::setAccount()
+ */
+class TimeZoneCacheContext implements CacheContextInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getLabel() {
+    return t("Time zone");
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getContext() {
+    // date_default_timezone_set() is called in AccountProxy::setAccount(), so
+    // we can safely retrieve the timezone.
+    return date_default_timezone_get();
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Cache/Contexts/UrlCacheContext.php b/core/lib/Drupal/Core/Cache/Contexts/UrlCacheContext.php
new file mode 100644
index 0000000..fedcc34
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/Contexts/UrlCacheContext.php
@@ -0,0 +1,29 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Cache\Contexts\UrlCacheContext.
+ */
+
+namespace Drupal\Core\Cache\Contexts;
+
+/**
+ * Defines the UrlCacheContext service, for "per page" caching.
+ */
+class UrlCacheContext extends RequestStackCacheContextBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getLabel() {
+    return t('URL');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getContext() {
+    return $this->requestStack->getCurrentRequest()->getUri();
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Cache/Contexts/UserCacheContext.php b/core/lib/Drupal/Core/Cache/Contexts/UserCacheContext.php
new file mode 100644
index 0000000..849e417
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/Contexts/UserCacheContext.php
@@ -0,0 +1,41 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Cache\Contexts\UserCacheContext.
+ */
+
+namespace Drupal\Core\Cache\Contexts;
+
+use Drupal\Core\Session\AccountInterface;
+
+/**
+ * Defines the UserCacheContext service, for "per user" caching.
+ */
+class UserCacheContext implements CacheContextInterface {
+
+  /**
+   * Constructs a new UserCacheContext service.
+   *
+   * @param \Drupal\Core\Session\AccountInterface $user
+   *   The current user.
+   */
+  public function __construct(AccountInterface $user) {
+    $this->user = $user;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getLabel() {
+    return t('User');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getContext() {
+    return "u." . $this->user->id();
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Cache/Contexts/UserRolesCacheContext.php b/core/lib/Drupal/Core/Cache/Contexts/UserRolesCacheContext.php
new file mode 100644
index 0000000..6b78626
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/Contexts/UserRolesCacheContext.php
@@ -0,0 +1,34 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Cache\Contexts\UserRolesCacheContext.
+ */
+
+namespace Drupal\Core\Cache\Contexts;
+
+/**
+ * Defines the UserRolesCacheContext service, for "per role" caching.
+ */
+class UserRolesCacheContext extends UserCacheContext implements CalculatedCacheContextInterface{
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getLabel() {
+    return t("User's roles");
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getContext($role = NULL) {
+    if ($role === NULL) {
+      return 'r.' . implode(',', $this->user->getRoles());
+    }
+    else {
+      return 'r.' . $role . '.' . (in_array($role, $this->user->getRoles()) ? '0' : '1');
+    }
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Cache/CookiesCacheContext.php b/core/lib/Drupal/Core/Cache/CookiesCacheContext.php
deleted file mode 100644
index 6760b1b..0000000
--- a/core/lib/Drupal/Core/Cache/CookiesCacheContext.php
+++ /dev/null
@@ -1,34 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Cache\CookiesCacheContext.
- */
-
-namespace Drupal\Core\Cache;
-
-/**
- * Defines the CookiesCacheContext service, for "per cookie" caching.
- */
-class CookiesCacheContext extends RequestStackCacheContextBase implements CalculatedCacheContextInterface {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getLabel() {
-    return t('HTTP cookies');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getContext($cookie = NULL) {
-    if ($cookie === NULL) {
-      return $this->requestStack->getCurrentRequest()->cookies->all();
-    }
-    else {
-      return $this->requestStack->getCurrentRequest()->cookies->get($cookie);
-    }
-  }
-
-}
diff --git a/core/lib/Drupal/Core/Cache/HeadersCacheContext.php b/core/lib/Drupal/Core/Cache/HeadersCacheContext.php
deleted file mode 100644
index e2b8932..0000000
--- a/core/lib/Drupal/Core/Cache/HeadersCacheContext.php
+++ /dev/null
@@ -1,34 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Cache\HeadersCacheContext.
- */
-
-namespace Drupal\Core\Cache;
-
-/**
- * Defines the HeadersCacheContext service, for "per header" caching.
- */
-class HeadersCacheContext extends RequestStackCacheContextBase implements CalculatedCacheContextInterface {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getLabel() {
-    return t('HTTP headers');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getContext($header = NULL) {
-    if ($header === NULL) {
-      return $this->requestStack->getCurrentRequest()->headers->all();
-    }
-    else {
-      return $this->requestStack->getCurrentRequest()->headers->get($header);
-    }
-  }
-
-}
diff --git a/core/lib/Drupal/Core/Cache/IpCacheContext.php b/core/lib/Drupal/Core/Cache/IpCacheContext.php
deleted file mode 100644
index c0c2e08..0000000
--- a/core/lib/Drupal/Core/Cache/IpCacheContext.php
+++ /dev/null
@@ -1,29 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Cache\IpCacheContext.
- */
-
-namespace Drupal\Core\Cache;
-
-/**
- * Defines the IpCacheContext service, for "per IP address" caching.
- */
-class IpCacheContext extends RequestStackCacheContextBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getLabel() {
-    return t('IP address');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getContext() {
-    return $this->requestStack->getCurrentRequest()->getClientIp();
-  }
-
-}
diff --git a/core/lib/Drupal/Core/Cache/IsSuperUserCacheContext.php b/core/lib/Drupal/Core/Cache/IsSuperUserCacheContext.php
deleted file mode 100644
index 6569715..0000000
--- a/core/lib/Drupal/Core/Cache/IsSuperUserCacheContext.php
+++ /dev/null
@@ -1,29 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Cache\IsSuperUserCacheContext.
- */
-
-namespace Drupal\Core\Cache;
-
-/**
- * Defines the IsSuperUserCacheContext service, for "super user or not" caching.
- */
-class IsSuperUserCacheContext extends UserCacheContext {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getLabel() {
-    return t('Is super user');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getContext() {
-    return ((int) $this->user->id()) === 1 ? '1' : '0';
-  }
-
-}
diff --git a/core/lib/Drupal/Core/Cache/LanguagesCacheContext.php b/core/lib/Drupal/Core/Cache/LanguagesCacheContext.php
deleted file mode 100644
index b9b8883..0000000
--- a/core/lib/Drupal/Core/Cache/LanguagesCacheContext.php
+++ /dev/null
@@ -1,77 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Cache\LanguagesCacheContext.
- */
-
-namespace Drupal\Core\Cache;
-
-use Drupal\Core\Language\LanguageManagerInterface;
-
-/**
- * Defines the LanguagesCacheContext service, for "per language" caching.
- */
-class LanguagesCacheContext implements CalculatedCacheContextInterface  {
-
-  /**
-   * The language manager.
-   *
-   * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
-   */
-  protected $languageManager;
-
-  /**
-   * Constructs a new LanguagesCacheContext service.
-   *
-   * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
-   *   The language manager.
-   */
-  public function __construct(LanguageManagerInterface $language_manager) {
-    $this->languageManager = $language_manager;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getLabel() {
-    return t('Language');
-  }
-
-  /**
-   * {@inheritdoc}
-   *
-   * $type can be NULL, or one of the language types supported by the language
-   * manager, typically:
-   * - LanguageInterface::TYPE_INTERFACE
-   * - LanguageInterface::TYPE_CONTENT
-   * - LanguageInterface::TYPE_URL
-   *
-   * @see \Drupal\Core\Language\LanguageManagerInterface::getLanguageTypes()
-   *
-   * @throws \RuntimeException
-   *   In case an invalid language type is specified.
-   */
-  public function getContext($type = NULL) {
-    if ($type === NULL) {
-      $context_parts = array();
-      if ($this->languageManager->isMultilingual()) {
-        foreach ($this->languageManager->getLanguageTypes() as $type) {
-          $context_parts[] = $this->languageManager->getCurrentLanguage($type)->getId();
-        }
-      }
-      else {
-        $context_parts[] = $this->languageManager->getCurrentLanguage()->getId();
-      }
-      return implode(',', $context_parts);
-    }
-    else {
-      $language_types = $this->languageManager->getDefinedLanguageTypesInfo();
-      if (!isset($language_types[$type])) {
-        throw new \RuntimeException(sprintf('The language type "%s" is invalid.', $type));
-      }
-      return $this->languageManager->getCurrentLanguage($type)->getId();
-    }
-  }
-
-}
diff --git a/core/lib/Drupal/Core/Cache/MenuActiveTrailsCacheContext.php b/core/lib/Drupal/Core/Cache/MenuActiveTrailsCacheContext.php
deleted file mode 100644
index 3b43178..0000000
--- a/core/lib/Drupal/Core/Cache/MenuActiveTrailsCacheContext.php
+++ /dev/null
@@ -1,36 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Cache\MenuActiveTrailsCacheContext.
- */
-
-namespace Drupal\Core\Cache;
-
-use Symfony\Component\DependencyInjection\ContainerAware;
-
-/**
- * Defines the MenuActiveTrailsCacheContext service.
- *
- * This class is container-aware to avoid initializing the 'menu.active_trail'
- * service (and its dependencies) when it is not necessary.
- */
-class MenuActiveTrailsCacheContext extends ContainerAware implements CalculatedCacheContextInterface {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getLabel() {
-    return t("Active menu trail");
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getContext($menu_name = NULL) {
-    $active_trail = $this->container->get('menu.active_trail')
-      ->getActiveTrailIds($menu_name);
-    return 'menu_trail.' . $menu_name . '|' . implode('|', $active_trail);
-  }
-
-}
diff --git a/core/lib/Drupal/Core/Cache/PagersCacheContext.php b/core/lib/Drupal/Core/Cache/PagersCacheContext.php
deleted file mode 100644
index cd9bb98..0000000
--- a/core/lib/Drupal/Core/Cache/PagersCacheContext.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Cache\PagersCacheContext.
- */
-
-namespace Drupal\Core\Cache;
-
-/**
- * Defines a cache context for "per page in a pager" caching.
- */
-class PagersCacheContext extends RequestStackCacheContextBase implements CalculatedCacheContextInterface {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getLabel() {
-    return t('Pager');
-  }
-
-  /**
-   * {@inheritdoc}
-   *
-   * @see pager_find_page()
-   */
-  public function getContext($pager_id = NULL) {
-    // The value of the 'page' query argument contains the information that
-    // controls *all* pagers.
-    if ($pager_id === NULL) {
-      return 'pager' . $this->requestStack->getCurrentRequest()->query->get('page', '');
-    }
-
-    return 'pager.' . $pager_id . '.' . pager_find_page($pager_id);
-  }
-
-}
diff --git a/core/lib/Drupal/Core/Cache/QueryArgsCacheContext.php b/core/lib/Drupal/Core/Cache/QueryArgsCacheContext.php
deleted file mode 100644
index 4c34721..0000000
--- a/core/lib/Drupal/Core/Cache/QueryArgsCacheContext.php
+++ /dev/null
@@ -1,38 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Cache\QueryArgsCacheContext.
- */
-
-namespace Drupal\Core\Cache;
-
-/**
- * Defines the QueryArgsCacheContext service, for "per query args" caching.
- *
- * A "host" is defined as the combination of URI scheme, domain name and port.
- *
- * @see Symfony\Component\HttpFoundation::getSchemeAndHttpHost()
- */
-class QueryArgsCacheContext extends RequestStackCacheContextBase implements CalculatedCacheContextInterface {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getLabel() {
-    return t('Query arguments');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getContext($query_arg = NULL) {
-    if ($query_arg === NULL) {
-      return $this->requestStack->getCurrentRequest()->getQueryString();
-    }
-    else {
-      return $this->requestStack->getCurrentRequest()->query->get($query_arg);
-    }
-  }
-
-}
diff --git a/core/lib/Drupal/Core/Cache/RequestFormatCacheContext.php b/core/lib/Drupal/Core/Cache/RequestFormatCacheContext.php
deleted file mode 100644
index 397384f..0000000
--- a/core/lib/Drupal/Core/Cache/RequestFormatCacheContext.php
+++ /dev/null
@@ -1,29 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Cache\RequestFormatCacheContext.
- */
-
-namespace Drupal\Core\Cache;
-
-/**
- * Defines the RequestFormatCacheContext service, for "per format" caching.
- */
-class RequestFormatCacheContext extends RequestStackCacheContextBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getLabel() {
-    return t('Request format');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getContext() {
-    return $this->requestStack->getCurrentRequest()->getRequestFormat();
-  }
-
-}
diff --git a/core/lib/Drupal/Core/Cache/RequestStackCacheContextBase.php b/core/lib/Drupal/Core/Cache/RequestStackCacheContextBase.php
deleted file mode 100644
index 34e3560..0000000
--- a/core/lib/Drupal/Core/Cache/RequestStackCacheContextBase.php
+++ /dev/null
@@ -1,34 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Cache\RequestStackCacheContextBase.
- */
-
-namespace Drupal\Core\Cache;
-
-use Symfony\Component\HttpFoundation\RequestStack;
-
-/**
- * Defines a base class for cache contexts depending only on the request stack.
- */
-abstract class RequestStackCacheContextBase implements CacheContextInterface {
-
-  /**
-   * The request stack.
-   *
-   * @var \Symfony\Component\HttpFoundation\RequestStack
-   */
-  protected $requestStack;
-
-  /**
-   * Constructs a new RequestStackCacheContextBase class.
-   *
-   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
-   *   The request stack.
-   */
-  public function __construct(RequestStack $request_stack) {
-    $this->requestStack = $request_stack;
-  }
-
-}
diff --git a/core/lib/Drupal/Core/Cache/RouteCacheContext.php b/core/lib/Drupal/Core/Cache/RouteCacheContext.php
deleted file mode 100644
index 486cdef..0000000
--- a/core/lib/Drupal/Core/Cache/RouteCacheContext.php
+++ /dev/null
@@ -1,48 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Cache\RouteCacheContext.
- */
-
-namespace Drupal\Core\Cache;
-
-use Drupal\Core\Routing\RouteMatchInterface;
-
-/**
- * Defines the RouteCacheContext service, for "per route" caching.
- */
-class RouteCacheContext implements CacheContextInterface {
-
-  /**
-   * The route match.
-   *
-   * @var \Drupal\Core\Routing\RouteMatchInterface
-   */
-  protected $routeMatch;
-
-  /**
-   * Constructs a new RouteCacheContext class.
-   *
-   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
-   *   The route match.
-   */
-  public function __construct(RouteMatchInterface $route_match) {
-    $this->routeMatch = $route_match;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getLabel() {
-    return t('Route');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getContext() {
-    return $this->routeMatch->getRouteName() . hash('sha256', serialize($this->routeMatch->getRawParameters()->all()));
-  }
-
-}
diff --git a/core/lib/Drupal/Core/Cache/RouteNameCacheContext.php b/core/lib/Drupal/Core/Cache/RouteNameCacheContext.php
deleted file mode 100644
index f0bd937..0000000
--- a/core/lib/Drupal/Core/Cache/RouteNameCacheContext.php
+++ /dev/null
@@ -1,29 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Cache\RouteNameCacheContext.
- */
-
-namespace Drupal\Core\Cache;
-
-/**
- * Defines the RouteCacheContext service, for "per route name" caching.
- */
-class RouteNameCacheContext extends RouteCacheContext {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getLabel() {
-    return t('Route name');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getContext() {
-    return $this->routeMatch->getRouteName();
-  }
-
-}
diff --git a/core/lib/Drupal/Core/Cache/SiteCacheContext.php b/core/lib/Drupal/Core/Cache/SiteCacheContext.php
deleted file mode 100644
index febbc0e..0000000
--- a/core/lib/Drupal/Core/Cache/SiteCacheContext.php
+++ /dev/null
@@ -1,38 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Cache\SiteCacheContext.
- */
-
-namespace Drupal\Core\Cache;
-
-/**
- * Defines the SiteCacheContext service, for "per site" caching.
- *
- * A "site" is defined as the combination of URI scheme, domain name, port and
- * base path. It allows for varying between the *same* site being accessed via
- * different entry points. (Different sites in a multisite setup have separate
- * databases.) For example: http://example.com and http://www.example.com.
- *
- * @see \Symfony\Component\HttpFoundation\Request::getSchemeAndHttpHost()
- * @see \Symfony\Component\HttpFoundation\Request::getBaseUrl()
- */
-class SiteCacheContext extends RequestStackCacheContextBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getLabel() {
-    return t('Site');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getContext() {
-    $request = $this->requestStack->getCurrentRequest();
-    return $request->getSchemeAndHttpHost() . $request->getBaseUrl();
-  }
-
-}
diff --git a/core/lib/Drupal/Core/Cache/ThemeCacheContext.php b/core/lib/Drupal/Core/Cache/ThemeCacheContext.php
deleted file mode 100644
index ad0249a..0000000
--- a/core/lib/Drupal/Core/Cache/ThemeCacheContext.php
+++ /dev/null
@@ -1,49 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Cache\LanguageCacheContext.
- */
-
-namespace Drupal\Core\Cache;
-
-use Drupal\Core\Routing\RouteMatchInterface;
-use Drupal\Core\Theme\ThemeManagerInterface;
-
-/**
- * Defines the ThemeCacheContext service, for "per theme" caching.
- */
-class ThemeCacheContext implements CacheContextInterface {
-
-  /**
-   * The theme manager.
-   *
-   * @var \Drupal\Core\Theme\ThemeManagerInterface
-   */
-  protected $themeManager;
-
-  /**
-   * Constructs a new ThemeCacheContext service.
-   *
-   * @param \Drupal\Core\Theme\ThemeManagerInterface $theme_manager
-   *   The theme manager.
-   */
-  public function __construct(ThemeManagerInterface $theme_manager) {
-    $this->themeManager = $theme_manager;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getLabel() {
-    return t('Theme');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getContext() {
-    return $this->themeManager->getActiveTheme()->getName() ?: 'stark';
-  }
-
-}
diff --git a/core/lib/Drupal/Core/Cache/TimeZoneCacheContext.php b/core/lib/Drupal/Core/Cache/TimeZoneCacheContext.php
deleted file mode 100644
index ae0621c..0000000
--- a/core/lib/Drupal/Core/Cache/TimeZoneCacheContext.php
+++ /dev/null
@@ -1,33 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Cache\TimeZoneCacheContext.
- */
-
-namespace Drupal\Core\Cache;
-
-/**
- * Defines the TimeZoneCacheContext service, for "per time zone" caching.
- *
- * @see \Drupal\Core\Session\AccountProxy::setAccount()
- */
-class TimeZoneCacheContext implements CacheContextInterface {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getLabel() {
-    return t("Time zone");
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getContext() {
-    // date_default_timezone_set() is called in AccountProxy::setAccount(), so
-    // we can safely retrieve the timezone.
-    return date_default_timezone_get();
-  }
-
-}
diff --git a/core/lib/Drupal/Core/Cache/UrlCacheContext.php b/core/lib/Drupal/Core/Cache/UrlCacheContext.php
deleted file mode 100644
index 1381093..0000000
--- a/core/lib/Drupal/Core/Cache/UrlCacheContext.php
+++ /dev/null
@@ -1,29 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Cache\UrlCacheContext.
- */
-
-namespace Drupal\Core\Cache;
-
-/**
- * Defines the UrlCacheContext service, for "per page" caching.
- */
-class UrlCacheContext extends RequestStackCacheContextBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getLabel() {
-    return t('URL');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getContext() {
-    return $this->requestStack->getCurrentRequest()->getUri();
-  }
-
-}
diff --git a/core/lib/Drupal/Core/Cache/UserCacheContext.php b/core/lib/Drupal/Core/Cache/UserCacheContext.php
deleted file mode 100644
index d5e2825..0000000
--- a/core/lib/Drupal/Core/Cache/UserCacheContext.php
+++ /dev/null
@@ -1,41 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Cache\UserCacheContext.
- */
-
-namespace Drupal\Core\Cache;
-
-use Drupal\Core\Session\AccountInterface;
-
-/**
- * Defines the UserCacheContext service, for "per user" caching.
- */
-class UserCacheContext implements CacheContextInterface {
-
-  /**
-   * Constructs a new UserCacheContext service.
-   *
-   * @param \Drupal\Core\Session\AccountInterface $user
-   *   The current user.
-   */
-  public function __construct(AccountInterface $user) {
-    $this->user = $user;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getLabel() {
-    return t('User');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getContext() {
-    return "u." . $this->user->id();
-  }
-
-}
diff --git a/core/lib/Drupal/Core/Cache/UserRolesCacheContext.php b/core/lib/Drupal/Core/Cache/UserRolesCacheContext.php
deleted file mode 100644
index cf7b450..0000000
--- a/core/lib/Drupal/Core/Cache/UserRolesCacheContext.php
+++ /dev/null
@@ -1,34 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Cache\UserRolesCacheContext.
- */
-
-namespace Drupal\Core\Cache;
-
-/**
- * Defines the UserRolesCacheContext service, for "per role" caching.
- */
-class UserRolesCacheContext extends UserCacheContext implements CalculatedCacheContextInterface{
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getLabel() {
-    return t("User's roles");
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getContext($role = NULL) {
-    if ($role === NULL) {
-      return 'r.' . implode(',', $this->user->getRoles());
-    }
-    else {
-      return 'r.' . $role . '.' . (in_array($role, $this->user->getRoles()) ? '0' : '1');
-    }
-  }
-
-}
diff --git a/core/lib/Drupal/Core/CoreServiceProvider.php b/core/lib/Drupal/Core/CoreServiceProvider.php
index 75d8ec5..656851c 100644
--- a/core/lib/Drupal/Core/CoreServiceProvider.php
+++ b/core/lib/Drupal/Core/CoreServiceProvider.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\Core;
 
-use Drupal\Core\Cache\CacheContextsPass;
+use Drupal\Core\Cache\Contexts\CacheContextsPass;
 use Drupal\Core\Cache\ListCacheBinsPass;
 use Drupal\Core\DependencyInjection\Compiler\BackendCompilerPass;
 use Drupal\Core\DependencyInjection\Compiler\RegisterLazyRouteEnhancers;
diff --git a/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php
index bee69a1..09132e5 100644
--- a/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php
@@ -9,7 +9,7 @@
 
 use Drupal\Component\Datetime\DateTimePlus;
 use Drupal\Core\Cache\CacheableResponseInterface;
-use Drupal\Core\Cache\CacheContextsManager;
+use Drupal\Core\Cache\Contexts\CacheContextsManager;
 use Drupal\Core\Config\Config;
 use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Language\LanguageManagerInterface;
@@ -61,7 +61,7 @@ class FinishResponseSubscriber implements EventSubscriberInterface {
   /**
    * The cache contexts manager service.
    *
-   * @var \Drupal\Core\Cache\CacheContextsManager
+   * @var \Drupal\Core\Cache\Contexts\CacheContextsManager
    */
   protected $cacheContexts;
 
@@ -76,7 +76,7 @@ class FinishResponseSubscriber implements EventSubscriberInterface {
    *   A policy rule determining the cacheability of a request.
    * @param \Drupal\Core\PageCache\ResponsePolicyInterface $response_policy
    *   A policy rule determining the cacheability of a response.
-   * @param \Drupal\Core\Cache\CacheContextsManager $cache_contexts_manager
+   * @param \Drupal\Core\Cache\Contexts\CacheContextsManager $cache_contexts_manager
    *   The cache contexts manager service.
    */
   public function __construct(LanguageManagerInterface $language_manager, ConfigFactoryInterface $config_factory, RequestPolicyInterface $request_policy, ResponsePolicyInterface $response_policy, CacheContextsManager $cache_contexts_manager) {
diff --git a/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php b/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php
index e5cdd87..df9587e 100644
--- a/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php
+++ b/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php
@@ -11,7 +11,7 @@
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Cache\CacheableMetadata;
 use Drupal\Core\Cache\CacheableResponse;
-use Drupal\Core\Cache\CacheContextsManager;
+use Drupal\Core\Cache\Contexts\CacheContextsManager;
 use Drupal\Core\Controller\TitleResolverInterface;
 use Drupal\Core\Display\PageVariantInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
@@ -82,7 +82,7 @@ class HtmlRenderer implements MainContentRendererInterface {
   /**
    * The cache contexts manager service.
    *
-   * @var \Drupal\Core\Cache\CacheContextsManager
+   * @var \Drupal\Core\Cache\Contexts\CacheContextsManager
    */
   protected $cacheContexts;
 
@@ -103,7 +103,7 @@ class HtmlRenderer implements MainContentRendererInterface {
    *   The renderer service.
    * @param \Drupal\Core\Render\RenderCacheInterface $render_cache
    *   The render cache service.
-   * @param \Drupal\Core\Cache\CacheContextsManager $cache_contexts_manager
+   * @param \Drupal\Core\Cache\Contexts\CacheContextsManager $cache_contexts_manager
    *   The cache contexts manager service.
    */
   public function __construct(TitleResolverInterface $title_resolver, PluginManagerInterface $display_variant_manager, EventDispatcherInterface $event_dispatcher, ElementInfoManagerInterface $element_info_manager, ModuleHandlerInterface $module_handler, RendererInterface $renderer, RenderCacheInterface $render_cache, CacheContextsManager $cache_contexts_manager) {
diff --git a/core/lib/Drupal/Core/Render/RenderCache.php b/core/lib/Drupal/Core/Render/RenderCache.php
index aa071cc..a960078 100644
--- a/core/lib/Drupal/Core/Render/RenderCache.php
+++ b/core/lib/Drupal/Core/Render/RenderCache.php
@@ -8,7 +8,7 @@
 namespace Drupal\Core\Render;
 
 use Drupal\Core\Cache\Cache;
-use Drupal\Core\Cache\CacheContextsManager;
+use Drupal\Core\Cache\Contexts\CacheContextsManager;
 use Drupal\Core\Cache\CacheFactoryInterface;
 use Symfony\Component\HttpFoundation\RequestStack;
 
@@ -34,7 +34,7 @@ class RenderCache implements RenderCacheInterface {
   /**
    * The cache contexts manager.
    *
-   * @var \Drupal\Core\Cache\CacheContextsManager
+   * @var \Drupal\Core\Cache\Contexts\CacheContextsManager
    */
   protected $cacheContextsManager;
 
diff --git a/core/modules/block/src/Tests/BlockViewBuilderTest.php b/core/modules/block/src/Tests/BlockViewBuilderTest.php
index 02fec0f..a58c9f4 100644
--- a/core/modules/block/src/Tests/BlockViewBuilderTest.php
+++ b/core/modules/block/src/Tests/BlockViewBuilderTest.php
@@ -9,7 +9,7 @@
 
 use Drupal\Component\Utility\Html;
 use Drupal\Core\Cache\Cache;
-use Drupal\Core\Cache\UrlCacheContext;
+use Drupal\Core\Cache\Contexts\UrlCacheContext;
 use Drupal\simpletest\KernelTestBase;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\RequestStack;
diff --git a/core/modules/book/src/Cache/BookNavigationCacheContext.php b/core/modules/book/src/Cache/BookNavigationCacheContext.php
index 531611f..23719c2 100644
--- a/core/modules/book/src/Cache/BookNavigationCacheContext.php
+++ b/core/modules/book/src/Cache/BookNavigationCacheContext.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\book\Cache;
 
-use Drupal\Core\Cache\CacheContextInterface;
+use Drupal\Core\Cache\Contexts\CacheContextInterface;
 use Symfony\Component\DependencyInjection\ContainerAware;
 use Symfony\Component\HttpFoundation\RequestStack;
 
diff --git a/core/modules/node/src/Cache/NodeAccessGrantsCacheContext.php b/core/modules/node/src/Cache/NodeAccessGrantsCacheContext.php
index e892212..7c82963 100644
--- a/core/modules/node/src/Cache/NodeAccessGrantsCacheContext.php
+++ b/core/modules/node/src/Cache/NodeAccessGrantsCacheContext.php
@@ -7,8 +7,8 @@
 
 namespace Drupal\node\Cache;
 
-use Drupal\Core\Cache\CalculatedCacheContextInterface;
-use Drupal\Core\Cache\UserCacheContext;
+use Drupal\Core\Cache\Contexts\CalculatedCacheContextInterface;
+use Drupal\Core\Cache\Contexts\UserCacheContext;
 
 /**
  * Defines the node access view cache context service.
diff --git a/core/modules/system/tests/modules/entity_test/src/Cache/EntityTestViewGrantsCacheContext.php b/core/modules/system/tests/modules/entity_test/src/Cache/EntityTestViewGrantsCacheContext.php
index ede6410..eee4dd3 100644
--- a/core/modules/system/tests/modules/entity_test/src/Cache/EntityTestViewGrantsCacheContext.php
+++ b/core/modules/system/tests/modules/entity_test/src/Cache/EntityTestViewGrantsCacheContext.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\entity_test\Cache;
 
-use Drupal\Core\Cache\CacheContextInterface;
+use Drupal\Core\Cache\Contexts\CacheContextInterface;
 
 /**
  * Defines the entity_test view grants cache context service.
