diff --git a/core/lib/Drupal/Core/Cache/CacheBackendInterface.php b/core/lib/Drupal/Core/Cache/CacheBackendInterface.php
index faf2459..41025b3 100644
--- a/core/lib/Drupal/Core/Cache/CacheBackendInterface.php
+++ b/core/lib/Drupal/Core/Cache/CacheBackendInterface.php
@@ -38,7 +38,7 @@
    *   The "valid" property of the returned object indicates whether the item is
    *   valid or not. Defaults to FALSE.
    *
-   * @return object|false
+   * @return \Drupal\Core\Cache\CacheItemInterface|false
    *   The cache item or FALSE on failure.
    *
    * @see \Drupal\Core\Cache\CacheBackendInterface::getMultiple()
@@ -60,7 +60,7 @@ public function get($cid, $allow_invalid = FALSE);
    *   "valid" property of the returned objects indicates whether the items are
    *   valid or not. Defaults to FALSE.
    *
-   * @return array
+   * @return \Drupal\Core\Cache\CacheItemInterface[]
    *   An array of cache item objects indexed by cache ID.
    *
    * @see \Drupal\Core\Cache\CacheBackendInterface::get()
diff --git a/core/lib/Drupal/Core/Cache/CacheItem.php b/core/lib/Drupal/Core/Cache/CacheItem.php
new file mode 100644
index 0000000..699402a
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/CacheItem.php
@@ -0,0 +1,218 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Cache\CacheItem.
+ */
+
+namespace Drupal\Core\Cache;
+
+/**
+ * Provides a default cache item.
+ *
+ */
+class CacheItem implements CacheItemInterface {
+
+  /**
+   * The cache backend of this cache item.
+   *
+   * @var \Drupal\Core\Cache\CacheBackendInterface
+   */
+  protected $cache;
+
+  /**
+   * The key of this cache item.
+   *
+   * @var string
+   */
+  public $cid;
+
+  /**
+   * Whether the cache item was found in persistent storage.
+   *
+   * @var bool
+   */
+  protected $isHit = FALSE;
+
+  /**
+   * The raw value of this cache item.
+   *
+   * @var mixed
+   */
+  public $data;
+
+  /**
+   * The Unix timestamp of when this cache item was created.
+   *
+   * @var int
+   */
+  public $created = 0;
+
+  /**
+   * The Unix timestamp of when this cache item will expire.
+   *
+   * @var int
+   *   Either a Unix timestamp, or
+   *   \Drupal\Core\Cache\CacheBackendInterface::CACHE_PERMANENT when the item
+   *   will never expire automatically.
+   */
+  public $expire = 0;
+
+  /**
+   * Whether the cache item is valid or not.
+   *
+   * @var bool
+   */
+  public $valid = FALSE;
+
+  /**
+   * Cache tags of this cache item.
+   *
+   * @var array[]
+   *   The entry cache tags. First dimension of the array are key value pairs,
+   *   keys being the business name of tag (e.g. "node") and value is an array
+   *   of tag values (e.g. "1" for node 1).
+   */
+  public $tags = array();
+
+  /**
+   * The current checksum.
+   *
+   * @var int
+   */
+  public $checksum = 0;
+
+  /**
+   * Constructs a new class instance.
+   *
+   * @param \Drupal\Core\Cache\CacheBackendInterface $cache
+   *   The cache backend the item is stored in.
+   * @param string $cid
+   *   The item's unique key within the cache bin it was stored.
+   * @param $data
+   * @param int $expire
+   *   Either a Unix timestamp, or
+   *   \Drupal\Core\Cache\CacheBackendInterface::CACHE_PERMANENT when the item
+   *   will never expire automatically.
+   * @param array $tags
+   *   The entry cache tags. First dimension of the array are key value pairs,
+   *   keys being the business name of tag (e.g. "node") and value is an array
+   *   of tag values (e.g. "1" for node 1).
+   * @param int $created
+   *   The Unix timestamp of when this cache item was created.
+   * @param int $checksum
+   *   The checksum.
+   * @param bool $is_hit
+   *   Whether the cache item was found in persistent storage.
+   */
+  public function __construct(CacheBackendInterface $cache, $cid, $data, $expire = CacheBackendInterface::CACHE_PERMANENT, array $tags = array(), $created = 0, $checksum = 0, $is_hit = FALSE) {
+    $this->cache = $cache;
+    $this->cid = $cid;
+    $this->checksum = $checksum;
+    $this->created = $created;
+    $this->data = $data;
+    $this->expire = $expire;
+    $this->isHit = $is_hit;
+    $this->tags = $tags;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getKey() {
+    return $this->cid;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function get() {
+    return $this->data;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isHit() {
+    return $this->isHit;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function set($value, $ttl = NULL) {
+    $this->data = $value;
+    if (!isset($ttl)) {
+      $expire = CacheBackendInterface::CACHE_PERMANENT;
+    }
+    elseif ($ttl >= time()) {
+      $expire = $ttl;
+    }
+    else {
+      $expire = time() + $ttl;
+    }
+
+    return $this->cache->set($this->cid, $value, $expire);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setWithTags($value, array $tags, $ttl = NULL) {
+    $this->data = $value;
+    if (!isset($ttl)) {
+      $expire = CacheBackendInterface::CACHE_PERMANENT;
+    }
+    elseif ($ttl >= time()) {
+      $expire = $ttl;
+    }
+    else {
+      $expire = time() + $ttl;
+    }
+
+    return $this->cache->set($this->cid, $value, $expire, $tags);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function delete() {
+    $this->cache->delete($this->cid);
+
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCreationTimestamp() {
+    return $this->created;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getExpirationTimestamp() {
+    return $this->expire;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isExpired() {
+    if (CacheBackendInterface::CACHE_PERMANENT === $this->expire) {
+      return FALSE;
+    }
+    else {
+      return time() >= $this->expire;
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getTags() {
+    return $this->tags;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Cache/CacheItemInterface.php b/core/lib/Drupal/Core/Cache/CacheItemInterface.php
new file mode 100644
index 0000000..ec62138
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/CacheItemInterface.php
@@ -0,0 +1,151 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Cache\CacheItem.
+ */
+
+namespace Drupal\Core\Cache;
+
+/**
+ * Defines a cache item.
+ */
+interface CacheItemInterface {
+
+  /**
+   * Returns the key for the current cache item.
+   *
+   * The key is loaded by the Implementing Library, but should be available to
+   * the higher level callers when needed.
+   *
+   * @return string
+   *   The key string for this cache item.
+   */
+  public function getKey();
+
+  /**
+   * Retrieves the value of the item from the cache associated with this objects key.
+   *
+   * The value returned must be identical to the value original stored by set().
+   *
+   * If isHit() returns false, this method MUST return null. Note that null
+   * is a legitimate cached value, so the isHit() method SHOULD be used to
+   * differentiate between "null value was found" and "no value was found."
+   *
+   * @return mixed
+   *   The value corresponding to this cache item's key, or NULL if not found.
+   */
+  public function get();
+
+  /**
+   * Stores a value into the cache.
+   *
+   * The $value argument may be any item that can be serialized by PHP,
+   * although the method of serialization is left up to the Implementing
+   * Library.
+   *
+   * Implementing Libraries MAY provide a default TTL if one is not specified.
+   * If no TTL is specified and no default TTL has been set, the TTL MUST
+   * be set to the maximum possible duration of the underlying storage
+   * mechanism, or permanent if possible.
+   *
+   * @param mixed $value
+   *   The serializable value to be stored.
+   * @param int|\Drupal\Core\Datetime\DrupalDateTime $ttl
+   *   - If an integer is passed, it is interpreted as the number of seconds
+   *     after which the item MUST be considered expired.
+   *   - If a DrupalDateTime object is passed, it is interpreted as the point in
+   *     time after which the the item MUST be considered expired.
+   *   - If no value is passed, a default value MAY be used. If none is set,
+   *     the value should be stored permanently or for as long as the
+   *     implementation allows.
+   *
+   * @return bool
+   *   Returns TRUE if the item was successfully saved, or FALSE if there was
+   *   an error.
+   */
+  public function set($value, $ttl = NULL);
+
+  /**
+   * Stores a tagged value into the cache.
+   *
+   * Same as CacheItemInterface::set(), but using cache tag based invalidation
+   * instead of time based invalidation.
+   *
+   * @param mixed $value
+   *   The serializable value to be stored.
+   * @param array[] $tags
+   *   An associative array of cache tags whose keys are the cache tag names and
+   *   whose values are arrays containing the tag values.
+   * @param int|\Drupal\Core\Datetime\DrupalDateTime $ttl
+   *   - If an integer is passed, it is interpreted as the number of seconds
+   *     after which the item MUST be considered expired.
+   *   - If a DrupalDateTime object is passed, it is interpreted as the point in
+   *     time after which the the item MUST be considered expired.
+   *   - If no value is passed, a default value MAY be used. If none is set,
+   *     the value should be stored permanently or for as long as the
+   *     implementation allows.
+   *
+   * @return bool
+   *   Returns true if the item was successfully saved, or false if there was
+   *   an error.
+   */
+  public function setWithTags($value, array $tags, $ttl = NULL);
+
+  /**
+   * Confirms if the cache item lookup resulted in a cache hit.
+   *
+   * Note: This method MUST NOT have a race condition between calling isHit()
+   * and calling get().
+   *
+   * @return bool
+   *   TRUE if the request resulted in a cache hit. FALSE otherwise.
+   */
+  public function isHit();
+
+  /**
+   * Removes the current key from the cache.
+   *
+   * @return $this
+   */
+  public function delete();
+
+  /**
+   * Get cache entry creation Unix timestamp.
+   *
+   * @return int
+   *   The Unix timestamp when the entry was created.
+   */
+  public function getCreationTimestamp();
+
+  /**
+   * Get cache entry expiration Unix timestamp.
+   *
+   * @return int
+   *   The Unix timestamp when the entry expires.
+   */
+  public function getExpirationTimestamp();
+
+  /**
+   * Is this entry expired.
+   *
+   * The computed return is based upon the local site time (depending on the
+   * configured locale) which means that the entry may already have expired
+   * or is still valid in the backend while this tells the opposite.
+   *
+   * @return int
+   *   TRUE if the entry has expired.
+   */
+  public function isExpired();
+
+  /**
+   * Get entry tags.
+   *
+   * @return array[]
+   *   The entry cache tags. First dimension of the array are key value pairs,
+   *   keys being the business name of tag (e.g. "node") and value is an array
+   *   of tag values (e.g. "1" for node 1).
+   */
+  public function getTags();
+
+}
diff --git a/core/lib/Drupal/Core/Cache/DatabaseBackend.php b/core/lib/Drupal/Core/Cache/DatabaseBackend.php
index b1144e4..a1f734d 100644
--- a/core/lib/Drupal/Core/Cache/DatabaseBackend.php
+++ b/core/lib/Drupal/Core/Cache/DatabaseBackend.php
@@ -66,7 +66,10 @@ public function __construct(Connection $connection, CacheTagsChecksumInterface $
   public function get($cid, $allow_invalid = FALSE) {
     $cids = array($cid);
     $cache = $this->getMultiple($cids, $allow_invalid);
-    return reset($cache);
+    if (isset($cache[$cid])) {
+      return $cache[$cid];
+    }
+    return FALSE;
   }
 
   /**
@@ -95,9 +98,8 @@ public function getMultiple(&$cids, $allow_invalid = FALSE) {
     foreach ($result as $item) {
       // Map the cache ID back to the original.
       $item->cid = $cid_mapping[$item->cid];
-      $item = $this->prepareItem($item, $allow_invalid);
-      if ($item) {
-        $cache[$item->cid] = $item;
+      if ($is_hit = $this->prepareItem($item, $allow_invalid)) {
+        $cache[$item->cid] = new CacheItem($this, $item->cid, $item->data, $item->expire, $item->tags, $item->created, $item->checksum, $is_hit);
       }
     }
     $cids = array_diff($cids, array_keys($cache));
@@ -115,9 +117,8 @@ public function getMultiple(&$cids, $allow_invalid = FALSE) {
    * @param bool $allow_invalid
    *   If FALSE, the method returns FALSE if the cache item is not valid.
    *
-   * @return mixed|false
-   *   The item with data unserialized as appropriate and a property indicating
-   *   whether the item is valid, or FALSE if there is no valid item to load.
+   * @return bool
+   *   TRUE if the cached data is valid, FALSE otherwise.
    */
   protected function prepareItem($cache, $allow_invalid) {
     if (!isset($cache->data)) {
@@ -143,7 +144,7 @@ protected function prepareItem($cache, $allow_invalid) {
       $cache->data = unserialize($cache->data);
     }
 
-    return $cache;
+    return TRUE;
   }
 
   /**
