diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index e173a95..148a6c7 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -1021,38 +1021,6 @@ function variable_del($name) {
 }
 
 /**
- * Retrieves the current page from the cache.
- *
- * Note: we do not serve cached pages to authenticated users, or to anonymous
- * users when $_SESSION is non-empty. $_SESSION may contain status messages
- * from a form submission, the contents of a shopping cart, or other user-
- * specific content that should not be cached and displayed to other users.
- *
- * @param $check_only
- *   (optional) Set to TRUE to only return whether a previous call found a
- *   cache entry.
- *
- * @return
- *   The cache object, if the page was found in the cache, NULL otherwise.
- */
-function drupal_page_get_cache($check_only = FALSE) {
-  global $base_root;
-  static $cache_hit = FALSE;
-
-  if ($check_only) {
-    return $cache_hit;
-  }
-
-  if (drupal_page_is_cacheable()) {
-    $cache = cache('page')->get($base_root . request_uri());
-    if ($cache !== FALSE) {
-      $cache_hit = TRUE;
-    }
-    return $cache;
-  }
-}
-
-/**
  * Determines the cacheability of the current page.
  *
  * @param $allow_caching
@@ -1066,7 +1034,7 @@ function drupal_page_is_cacheable($allow_caching = NULL) {
   if (isset($allow_caching)) {
     $allow_caching_static = $allow_caching;
   }
-
+  
   return $allow_caching_static && ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD')
     && !drupal_is_cli();
 }
@@ -1275,111 +1243,6 @@ function drupal_page_header() {
 }
 
 /**
- * Sets HTTP headers in preparation for a cached page response.
- *
- * The headers allow as much as possible in proxies and browsers without any
- * particular knowledge about the pages. Modules can override these headers
- * using drupal_add_http_header().
- *
- * If the request is conditional (using If-Modified-Since and If-None-Match),
- * and the conditions match those currently in the cache, a 304 Not Modified
- * response is sent.
- */
-function drupal_serve_page_from_cache(stdClass $cache) {
-  $config = config('system.performance');
-
-  // Negotiate whether to use compression.
-  $page_compression = $config->get('page_compression') && extension_loaded('zlib');
-  $return_compressed = $page_compression && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE;
-
-  // Get headers set in hook_boot(). Keys are lower-case.
-  $hook_boot_headers = drupal_get_http_header();
-
-  // Headers generated in this function, that may be replaced or unset using
-  // drupal_add_http_headers(). Keys are mixed-case.
-  $default_headers = array();
-
-  foreach ($cache->data['headers'] as $name => $value) {
-    // In the case of a 304 response, certain headers must be sent, and the
-    // remaining may not (see RFC 2616, section 10.3.5). Do not override
-    // headers set in hook_boot().
-    $name_lower = strtolower($name);
-    if (in_array($name_lower, array('content-location', 'expires', 'cache-control', 'vary')) && !isset($hook_boot_headers[$name_lower])) {
-      drupal_add_http_header($name, $value);
-      unset($cache->data['headers'][$name]);
-    }
-  }
-
-  // If the client sent a session cookie, a cached copy will only be served
-  // to that one particular client due to Vary: Cookie. Thus, do not set
-  // max-age > 0, allowing the page to be cached by external proxies, when a
-  // session cookie is present unless the Vary header has been replaced or
-  // unset in hook_boot().
-  $max_age = !isset($_COOKIE[session_name()]) || isset($hook_boot_headers['vary']) ? $config->get('page_cache_maximum_age') : 0;
-  $default_headers['Cache-Control'] = 'public, max-age=' . $max_age;
-
-  // Entity tag should change if the output changes.
-  $etag = '"' . $cache->created . '-' . intval($return_compressed) . '"';
-  header('Etag: ' . $etag);
-
-  // See if the client has provided the required HTTP headers.
-  $if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) : FALSE;
-  $if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH']) ? stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : FALSE;
-
-  if ($if_modified_since && $if_none_match
-      && $if_none_match == $etag // etag must match
-      && $if_modified_since == $cache->created) {  // if-modified-since must match
-    header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified');
-    drupal_send_headers($default_headers);
-    return;
-  }
-
-  // Send the remaining headers.
-  foreach ($cache->data['headers'] as $name => $value) {
-    drupal_add_http_header($name, $value);
-  }
-
-  $default_headers['Last-Modified'] = gmdate(DATE_RFC1123, $cache->created);
-
-  // HTTP/1.0 proxies does not support the Vary header, so prevent any caching
-  // by sending an Expires date in the past. HTTP/1.1 clients ignores the
-  // Expires header if a Cache-Control: max-age= directive is specified (see RFC
-  // 2616, section 14.9.3).
-  $default_headers['Expires'] = 'Sun, 19 Nov 1978 05:00:00 GMT';
-
-  drupal_send_headers($default_headers);
-
-  // Allow HTTP proxies to cache pages for anonymous users without a session
-  // cookie. The Vary header is used to indicates the set of request-header
-  // fields that fully determines whether a cache is permitted to use the
-  // response to reply to a subsequent request for a given URL without
-  // revalidation. If a Vary header has been set in hook_boot(), it is assumed
-  // that the module knows how to cache the page.
-  if (!isset($hook_boot_headers['vary']) && !variable_get('omit_vary_cookie')) {
-    header('Vary: Cookie');
-  }
-
-  if ($page_compression) {
-    header('Vary: Accept-Encoding', FALSE);
-    // If page_compression is enabled, the cache contains gzipped data.
-    if ($return_compressed) {
-      // $cache->data['body'] is already gzip'ed, so make sure
-      // zlib.output_compression does not compress it once more.
-      ini_set('zlib.output_compression', '0');
-      header('Content-Encoding: gzip');
-    }
-    else {
-      // The client does not support compression, so unzip the data in the
-      // cache. Strip the gzip header and run uncompress.
-      $cache->data['body'] = gzinflate(substr(substr($cache->data['body'], 10), 0, -8));
-    }
-  }
-
-  // Print the page.
-  print $cache->data['body'];
-}
-
-/**
  * Defines the critical hooks that force modules to always be loaded.
  */
 function bootstrap_hooks() {
@@ -2274,35 +2137,8 @@ function _drupal_bootstrap_page_cache() {
   // If there is no session cookie and cache is enabled (or forced), try
   // to serve a cached page.
   if (!isset($_COOKIE[session_name()]) && $cache_enabled) {
-    // Make sure there is a user object because its timestamp will be
-    // checked, hook_boot might check for anonymous user etc.
-    $user = drupal_anonymous_user();
-    // Get the page from the cache.
-    $cache = drupal_page_get_cache();
-    // If there is a cached page, display it.
-    if (is_object($cache)) {
-      header('X-Drupal-Cache: HIT');
-      // Restore the metadata cached with the page.
-      _current_path($cache->data['path']);
-      drupal_set_title($cache->data['title'], PASS_THROUGH);
-      date_default_timezone_set(drupal_get_user_timezone());
-      // If the skipping of the bootstrap hooks is not enforced, call
-      // hook_boot.
-      if (variable_get('page_cache_invoke_hooks', TRUE)) {
-        bootstrap_invoke_all('boot');
-      }
-      drupal_serve_page_from_cache($cache);
-      // If the skipping of the bootstrap hooks is not enforced, call
-      // hook_exit.
-      if (variable_get('page_cache_invoke_hooks', TRUE)) {
-        bootstrap_invoke_all('exit');
-      }
-      // We are done.
-      exit;
-    }
-    else {
-      header('X-Drupal-Cache: MISS');
-    }
+    // The cache was first served here. This is now handled by the
+    // kernel after the bootstrap has finished.
   }
 }
 
diff --git a/core/includes/common.inc b/core/includes/common.inc
index 17e1363..d9a48da 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -4952,62 +4952,6 @@ function _drupal_bootstrap_full($skip = FALSE) {
 }
 
 /**
- * Stores the current page in the cache.
- *
- * If page_compression is enabled, a gzipped version of the page is stored in
- * the cache to avoid compressing the output on each request. The cache entry
- * is unzipped in the relatively rare event that the page is requested by a
- * client without gzip support.
- *
- * Page compression requires the PHP zlib extension
- * (http://php.net/manual/ref.zlib.php).
- *
- * @param $body
- *   The response body.
- * @return
- *   The cached object or NULL if the page cache was not set.
- *
- * @see drupal_page_header()
- */
-function drupal_page_set_cache($body) {
-  global $base_root;
-
-  if (drupal_page_is_cacheable()) {
-    $cache = (object) array(
-      'cid' => $base_root . request_uri(),
-      'data' => array(
-        'path' => current_path(),
-        'body' => $body,
-        'title' => drupal_get_title(),
-        'headers' => array(),
-      ),
-      'tags' => array('content' => TRUE),
-      'expire' => CACHE_PERMANENT,
-      'created' => REQUEST_TIME,
-    );
-
-    // Restore preferred header names based on the lower-case names returned
-    // by drupal_get_http_header().
-    $header_names = _drupal_set_preferred_header_name();
-    foreach (drupal_get_http_header() as $name_lower => $value) {
-      $cache->data['headers'][$header_names[$name_lower]] = $value;
-      if ($name_lower == 'expires') {
-        // Use the actual timestamp from an Expires header if available.
-        $cache->expire = strtotime($value);
-      }
-    }
-
-    if ($cache->data['body']) {
-      if (config('system.performance')->get('page_compression') && extension_loaded('zlib')) {
-        $cache->data['body'] = gzencode($cache->data['body'], 9, FORCE_GZIP);
-      }
-      cache('page')->set($cache->cid, $cache->data, $cache->expire, $cache->tags);
-    }
-    return $cache;
-  }
-}
-
-/**
  * Executes a cron run when called.
  *
  * Do not call this function from a test. Use $this->cronRun() instead.
diff --git a/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php
index 8044a5c..61ed5d0 100644
--- a/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php
@@ -71,15 +71,30 @@ class FinishResponseSubscriber implements EventSubscriberInterface {
     //   use partial page caching more extensively.
     // Commit the user session, if needed.
     drupal_session_commit();
-    if (config('system.performance')->get('cache') && ($cache = drupal_page_set_cache($response->getContent()))) {
-      drupal_serve_page_from_cache($cache);
-      // drupal_serve_page_from_cache() already printed the response.
-      $response->setContent('');
-      $response->headers->remove('cache-control');
+
+    // @todo, is this the proper location to add these headers?
+    if (config('system.performance')->get('cache') && drupal_page_is_cacheable()) {
+      $vary = array('Accept-Encoding');
+      if (!variable_get('omit_vary_cookie')) {
+        $vary[] = 'Cookie';
+      }
+      $response->setVary($vary);
+
+      $response->setPublic();
+      $max_age = config('system.performance')->get('page_cache_maximum_age');
+      if (!$max_age) {
+        // @todo, Define a Max Age to use for HttpCache which it expects
+        // to see whether or not TTL has expired.
+        $max_age = 3600;
+      }
+      $response->setMaxAge($max_age);
     }
     else {
       $response->headers->set('Expires', 'Sun, 19 Nov 1978 05:00:00 GMT');
-      $response->headers->set('Cache-Control', 'no-cache, must-revalidate, post-check=0, pre-check=0');
+      $response->headers->addCacheControlDirective('no-cache');
+      $response->headers->addCacheControlDirective('must-revalidate');
+      $response->headers->addCacheControlDirective('post-check', 0);
+      $response->headers->addCacheControlDirective('pre-check', 0);
     }
   }
 
diff --git a/core/lib/Drupal/Core/HttpCache.php b/core/lib/Drupal/Core/HttpCache.php
index e69de29..e152fe3 100644
--- a/core/lib/Drupal/Core/HttpCache.php
+++ b/core/lib/Drupal/Core/HttpCache.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace Drupal\Core;
+
+use Symfony\Component\HttpKernel\HttpCache\HttpCache as SymfonyHttpCache;
+use Symfony\Component\HttpFoundation\Request as Request;
+
+class HttpCache extends SymfonyHttpCache {
+  protected function getOptions() {
+    $config = config('system.performance');
+    return array(
+      'debug'                  => TRUE
+    );
+  }
+
+  protected function lookup(Request $request, $catch = false)
+  {
+    $entry = parent::lookup($request, $catch);
+    
+    if ($entry->headers->has('age')) {
+      $entry->headers->set('X-Drupal-Cache', 'HIT');
+    }
+    else {
+      $entry->headers->set('X-Drupal-Cache', 'MISS');
+    }
+         
+    return $entry;
+  }
+}
diff --git a/index.php b/index.php
index 38177ab..1dff479 100644
--- a/index.php
+++ b/index.php
@@ -13,7 +13,9 @@
 
 use Drupal\Core\DrupalKernel;
 use Symfony\Component\HttpFoundation\Request;
-
+use Drupal\Core\HttpCache;
+use Symfony\Component\HttpKernel\HttpCache\Store;
+  
 /**
  * Root directory of Drupal installation.
  */
@@ -30,6 +32,11 @@ drupal_bootstrap(DRUPAL_BOOTSTRAP_CODE);
 // @todo Figure out how best to handle the Kernel constructor parameters.
 $kernel = new DrupalKernel('prod', FALSE);
 
+// Are we using page caching, if so override the Kernel.
+if (config('system.performance')->get('cache') && drupal_page_is_cacheable()) {
+  $kernel = new HttpCache($kernel, new Store("/tmp/meuk"));
+}
+
 // Create a request object from the HTTPFoundation.
 $request = Request::createFromGlobals();
 $response = $kernel->handle($request)->prepare($request)->send();
