diff --git a/core/lib/Drupal/Core/Cache/CacheableMetadata.php b/core/lib/Drupal/Core/Cache/CacheableMetadata.php
new file mode 100644
index 0000000..3278a1f
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/CacheableMetadata.php
@@ -0,0 +1,105 @@
+<?php
+/**
+ * @file
+ * Contains \Drupal\Core\CacheableMetadata
+ */
+
+namespace Drupal\Core\Cache;
+
+/**
+ * Defines an interface for objects which may be used by other cached objects.
+ *
+ * This extended interface defines setters so that the object may have cache
+ * metadata added by multiple actors.
+ *
+ * @ingroup cache
+ */
+class CacheableMetadata implements CacheableMetadataInterface {
+
+  /**
+   * Cache contexts.
+   *
+   * @var string[]
+   */
+  protected $contexts = [];
+
+  /**
+   * Cache tags.
+   *
+   * @var string[]
+   */
+  protected $tags = [];
+
+  /**
+   * Cache max-age.
+   *
+   * @var int
+   */
+  protected $maxAge = Cache::PERMANENT;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheTags() {
+    return $this->tags;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function addCacheTags(array $cache_tags) {
+    $this->tags = Cache::mergeTags($this->tags, $cache_tags);
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setCacheTags(array $cache_tags) {
+    $this->tags = $cache_tags;
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheContexts() {
+    return $this->contexts;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function addCacheContexts(array $cache_contexts) {
+    $this->contexts = Cache::mergeContexts($this->contexts, $cache_contexts);
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setCacheContexts(array $cache_contexts) {
+    $this->contexts = $cache_contexts;
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheMaxAge() {
+    return $this->maxAge;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setCacheMaxAge($max_age) {
+    if (!is_int($max_age)) {
+      throw new \InvalidArgumentException('$max_age must be an integer');
+    }
+
+    $this->maxAge = $max_age;
+    return $this;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Cache/CacheableMetadataInterface.php b/core/lib/Drupal/Core/Cache/CacheableMetadataInterface.php
new file mode 100644
index 0000000..dff1b02
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/CacheableMetadataInterface.php
@@ -0,0 +1,73 @@
+<?php
+/**
+ * @file
+ * Contains \Drupal\Core\CacheableMetadataInterface
+ */
+
+namespace Drupal\Core\Cache;
+
+/**
+ * Defines an interface for objects which may be used by other cached objects.
+ *
+ * This extended interface defines setters so that the object may have cache
+ * metadata added by multiple actors.
+ *
+ * @ingroup cache
+ */
+interface CacheableMetadataInterface extends CacheableDependencyInterface {
+
+  /**
+   * Adds cache tags.
+   *
+   * @param string[] $cache_tags
+   *   The cache tags to be added.
+   *
+   * @return $this
+   */
+  public function addCacheTags(array $cache_tags);
+
+  /**
+   * Sets cache tags.
+   *
+   * @param string[] $cache_tags
+   *   The cache tags to be associated.
+   *
+   * @return $this
+   */
+  public function setCacheTags(array $cache_tags);
+
+  /**
+   * Adds cache contexts.
+   *
+   * @param string[] $cache_contexts
+   *   The cache contexts to be added.
+   *
+   * @return $this
+   */
+  public function addCacheContexts(array $cache_contexts);
+
+  /**
+   * Sets cache contexts.
+   *
+   * @param string[] $cache_contexts
+   *   The cache contexts to be associated.
+   *
+   * @return $this
+   */
+  public function setCacheContexts(array $cache_contexts);
+
+  /**
+   * Sets the maximum age (in seconds).
+   *
+   * Defaults to Cache::PERMANENT
+   *
+   * @param int $max_age
+   *   The max age to associate.
+   *
+   * @return $this
+   *
+   * @throws \InvalidArgumentException
+   */
+  public function setCacheMaxAge($max_age);
+
+}
diff --git a/core/lib/Drupal/Core/Render/BubbleableMetadata.php b/core/lib/Drupal/Core/Render/BubbleableMetadata.php
index bf7812e..b51c055 100644
--- a/core/lib/Drupal/Core/Render/BubbleableMetadata.php
+++ b/core/lib/Drupal/Core/Render/BubbleableMetadata.php
@@ -10,13 +10,14 @@
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Cache\CacheableDependencyInterface;
+use Drupal\Core\Cache\CacheableMetadata;
 
 /**
  * Value object used for bubbleable rendering metadata.
  *
  * @see \Drupal\Core\Render\RendererInterface::render()
  */
-class BubbleableMetadata implements CacheableDependencyInterface {
+class BubbleableMetadata extends CacheableMetadata {
 
   /**
    * Cache contexts.
@@ -133,106 +134,6 @@ public static function createFromObject($object) {
   }
 
   /**
-   * Gets cache tags.
-   *
-   * @return string[]
-   */
-  public function getCacheTags() {
-    return $this->tags;
-  }
-
-  /**
-   * Adds cache tags.
-   *
-   * @param string[] $cache_tags
-   *   The cache tags to be added.
-   *
-   * @return $this
-   */
-  public function addCacheTags(array $cache_tags) {
-    $this->tags = Cache::mergeTags($this->tags, $cache_tags);
-    return $this;
-  }
-
-  /**
-   * Sets cache tags.
-   *
-   * @param string[] $cache_tags
-   *   The cache tags to be associated.
-   *
-   * @return $this
-   */
-  public function setCacheTags(array $cache_tags) {
-    $this->tags = $cache_tags;
-    return $this;
-  }
-
-  /**
-   * Gets cache contexts.
-   *
-   * @return string[]
-   */
-  public function getCacheContexts() {
-    return $this->contexts;
-  }
-
-  /**
-   * Adds cache contexts.
-   *
-   * @param string[] $cache_contexts
-   *   The cache contexts to be added.
-   *
-   * @return $this
-   */
-  public function addCacheContexts(array $cache_contexts) {
-    $this->contexts = Cache::mergeContexts($this->contexts, $cache_contexts);
-    return $this;
-  }
-
-  /**
-   * Sets cache contexts.
-   *
-   * @param string[] $cache_contexts
-   *   The cache contexts to be associated.
-   *
-   * @return $this
-   */
-  public function setCacheContexts(array $cache_contexts) {
-    $this->contexts = $cache_contexts;
-    return $this;
-  }
-
-  /**
-   * Gets the maximum age (in seconds).
-   *
-   * @return int
-   */
-  public function getCacheMaxAge() {
-    return $this->maxAge;
-  }
-
-  /**
-   * Sets the maximum age (in seconds).
-   *
-   * Defaults to Cache::PERMANENT
-   *
-   * @param int $max_age
-   *   The max age to associate.
-   *
-   * @return $this
-   *
-   * @throws \InvalidArgumentException
-   */
-  public function setCacheMaxAge($max_age) {
-    if (!is_int($max_age)) {
-      throw new \InvalidArgumentException('$max_age must be an integer');
-    }
-
-    $this->maxAge = $max_age;
-    return $this;
-  }
-
-  /**
    * Gets assets.
    *
    * @return array
