diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index 56e5f43..2359057 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -2245,6 +2245,8 @@ function _drupal_bootstrap_configuration() {
  * Attempts to serve a page from the cache.
  */
 function _drupal_bootstrap_page_cache() {
+  // Not sure what to do with all this yet, but the whole phase most likely
+  // needs to be removed.
   global $user;
 
   // Allow specifying special cache handlers in settings.php, like
@@ -2253,6 +2255,7 @@ function _drupal_bootstrap_page_cache() {
   foreach (variable_get('cache_backends', array()) as $include) {
     require_once DRUPAL_ROOT . '/' . $include;
   }
+  /*
   // Check for a cache mode force from settings.php.
   if (variable_get('page_cache_without_database')) {
     $cache_enabled = TRUE;
@@ -2296,6 +2299,7 @@ function _drupal_bootstrap_page_cache() {
       header('X-Drupal-Cache: MISS');
     }
   }
+*/
 }
 
 /**
diff --git a/core/includes/common.inc b/core/includes/common.inc
index 44fa367..c9ad4ac 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -4959,62 +4959,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' => CacheBackendInterface::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('response.gzip') && 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 8065349..413555d 100644
--- a/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php
@@ -71,11 +71,8 @@ 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.page.enabled') && ($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');
+    if (config('system.performance')->get('cache.page.enabled')) {
+      $this->setCacheHeaders($response, $event);
     }
     else {
       $response->headers->set('Expires', 'Sun, 19 Nov 1978 05:00:00 GMT');
@@ -83,6 +80,21 @@ class FinishResponseSubscriber implements EventSubscriberInterface {
     }
   }
 
+  public function setCacheHeaders($response, $event) {
+    $response->isNotModified($event->getRequest());
+
+    $vary = array('Accept-Encoding');
+    if (!variable_get('omit_vary_cookie', FALSE)) {
+      $vary[] = 'Cookie';
+    }
+    $response->setVary($vary);
+
+    $max_age = (int)config('system.performance')->get('cache.page.max_age');
+    $max_age = !isset($_COOKIE[session_name()]) ? $max_age : 0;
+    $response->setPublic();
+    $response->setMaxAge($max_age);
+  }
+
   /**
    * Registers the methods in this class that should be listeners.
    *
diff --git a/core/lib/Drupal/Core/HttpCache.php b/core/lib/Drupal/Core/HttpCache.php
new file mode 100644
index 0000000..3ee29cc
--- /dev/null
+++ b/core/lib/Drupal/Core/HttpCache.php
@@ -0,0 +1,70 @@
+<?php
+
+namespace Drupal\Core;
+
+use Symfony\Component\HttpKernel\HttpKernelInterface;
+use Symfony\Component\HttpKernel\HttpCache\HttpCache as SymfonyHttpCache;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\HttpCache\Esi;
+use Symfony\Component\HttpKernel\HttpCache\Store;
+use Symfony\Component\HttpKernel\HttpCache\StoreInterface;
+
+class HttpCache extends SymfonyHttpCache {
+
+    /**
+     * Constructor.
+     *
+     * @param HttpKernelInterface $kernel
+     *   An HttpKernelInterface instance
+     * @param string $cacheDir
+     *   The cache directory (default used if null)
+     */
+    public function __construct(HttpKernelInterface $kernel, StoreInterface $store, array $options = array()) {
+      $this->kernel = $kernel;
+      parent::__construct($kernel, $store, $this->createEsi(), array_merge(array('debug' => $kernel->isDebug()), $this->getOptions()));
+    }
+
+    public function cacheEnabled() {
+      return config('system.performance')->get('cache.page.enabled');
+    }
+    public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) {
+      // Probably a better way to do this.
+      if (!$this->cacheEnabled()) {
+        $request->headers->set('expect', TRUE);
+      }
+      return parent::handle($request, $type, $catch);
+    }
+
+    /**
+     * Forwards the Request to the backend and returns the Response.
+     *
+     * @param Request $request
+     *   A Request instance
+     * @param Boolean $raw
+     *   Whether to catch exceptions or not
+     * @param Response $entry
+     *   A Response instance (the stale entry if present, null otherwise)
+     *
+     * @return Response A Response instance
+     */
+    protected function forward(Request $request, $raw = false, Response $entry = null) {
+      $this->getKernel()->boot();
+      $this->getKernel()->getContainer()->set('cache', $this);
+      $this->getKernel()->getContainer()->set('esi', $this->getEsi());
+
+      return parent::forward($request, $raw, $entry);
+    }
+
+
+    protected function createEsi() {
+      return new Esi();
+    }
+
+    protected function getOptions() {
+      return array(
+        'debug' => TRUE
+      );
+  }
+}
+
diff --git a/index.php b/index.php
index 38177ab..a426deb 100644
--- a/index.php
+++ b/index.php
@@ -13,6 +13,8 @@
 
 use Drupal\Core\DrupalKernel;
 use Symfony\Component\HttpFoundation\Request;
+use Drupal\Core\HttpCache;
+use Symfony\Component\HttpKernel\HttpCache\Store;
 
 /**
  * Root directory of Drupal installation.
@@ -28,7 +30,7 @@ require_once DRUPAL_ROOT . '/core/includes/bootstrap.inc';
 drupal_bootstrap(DRUPAL_BOOTSTRAP_CODE);
 
 // @todo Figure out how best to handle the Kernel constructor parameters.
-$kernel = new DrupalKernel('prod', FALSE);
+$kernel = new HttpCache(new DrupalKernel('prod', FALSE), new Store("/tmp"));
 
 // Create a request object from the HTTPFoundation.
 $request = Request::createFromGlobals();
