diff --git a/esi.pages.inc b/esi.pages.inc
index 56c4ecd..60f4893 100644
--- a/esi.pages.inc
+++ b/esi.pages.inc
@@ -7,9 +7,15 @@
 /**
  * Menu callback to handle an ESI component.
  *
- * @see esi_component_load().
+ * @see esi_component_load()
  */
 function esi_handle_component($component) {
+  // Anyone running ESI should have object caching disabled for the page cache.
+  // Disable it just in case. This is especially important since $_GET['q']
+  // gets set synthetically in COMPONENT__restore_context(), and it would be
+  // very easy to end up with an ESI fragment in the cache for "/node/1".
+  drupal_page_is_cacheable(FALSE);
+
   // The menu wildcard loader will return NULL for invalid components, so that
   // the menu-handler will delegate 404 delivery here.
   if (empty($component)) {
@@ -17,13 +23,13 @@ function esi_handle_component($component) {
   }
 
   // Remove the component from the arguments.
-  $args = array_slice(func_get_args(),1);
+  $args = array_slice(func_get_args(), 1);
 
   // Load in the include file if provided.
   if (!empty($component['file'])) {
     $filepath = $component['filepath'] . '/' . $component['file'];
     if (file_exists($filepath)) {
-      include_once($filepath);
+      include_once $filepath;
     }
   }
 
@@ -85,7 +91,7 @@ function esi_fast_404() {
   watchdog('page not found', check_plain($_GET['q']), NULL, WATCHDOG_WARNING);
 
   // Unlike drupal_fast_404(), the HTML furniture (html tag, head tag, etc) are
-  // not delivered 
+  // not delivered.
   echo "<!-- esi_fast_404 -->\n";
 
   // Unlike normal page-views, invoking hook_exit() is unneccessary overhead.
diff --git a/modules/esi_panels/esi_panels.esi.inc b/modules/esi_panels/esi_panels.esi.inc
index 2195911..355f757 100644
--- a/modules/esi_panels/esi_panels.esi.inc
+++ b/modules/esi_panels/esi_panels.esi.inc
@@ -1,58 +1,50 @@
 <?php
 /**
+ * @file
  * ESI prepare, render and flush hooks.
  */
 
-
 /**
  * Prepare an ESI panels pane for rendering.
  * Defined in hook_esi_component_info().
  *
- * @see esi_panels_esi_component_info().
+ * @see esi_panels_esi_component_info()
  */
 function esi_panels__esi_pane_prepare($component_key) {
-  // Use the parameters to reconstruct:
-  // - Display
-  // - Pane
-  // - Contexts
-  list($theme, $did, $pid) = explode(':', $component_key);
+  // If the component key contains "::", it has addressable content in it.
+  if (strpos($component_key, "::") === FALSE) {
+    return FALSE;
+  }
+  else {
+    $matches = array();
+    if (preg_match("/(.*?):(.*)/", $component_key, $matches)) {
+      list($component_key, $theme, $address) = $matches;
+    }
+  }
 
-  // Check for optional args.
   $args = array_slice(func_get_args(), 1);
 
+  // Grab additional info if it is needed.
   $url = array_pop($args);
 
-  // Task-name and context identifier are next in the URL, if context is used
-  // by the pane.
-  $display = panels_load_display($did);
-  $pane = $display->content[$pid];
-
+  $pane = new stdClass();
   $pane->esi_meta = array(
-    'display_contexts' => array(),
-  );
-
-  if (!empty($pane->configuration['context'])) {
-    $task_name = array_shift($args);
-    list($task, $subtask) = _esi_panels__get_task_identifier($task_name);
-
-    $pane->esi_meta['task'] = $task;
-    $pane->esi_meta['subtask'] = $subtask;
-  }
-
-  $pane->esi_meta += array(
-    'display' => $display,
+    'address' => $address,
     'theme' => $theme,
-    'display_args' => $args,
     'url' => base64_decode($url),
   );
 
+  // Allow other modules to alter the context information here.
+  // A certain implementation might adjust the addressable string to add extra
+  // args or do something similar.
+  // @see hook_esi_block_context_alter()
+  drupal_alter('esi_panels_pane_context', $pane);
+
   esi_panels__restore_context($pane);
 
   return $pane;
 }
 
-
-
 /**
  * Restore the original context that was used when a block was displayed.
  */
@@ -65,100 +57,36 @@ function esi_panels__restore_context(&$pane) {
   $_SERVER['REQUEST_URI'] = $pane->esi_meta['url'];
   drupal_static_reset('drupal_get_destination');
 
-  // Load up contexts. Owch.
-  if (!empty($pane->configuration['context'])) {
-    ctools_include('context');
-    ctools_include('context-task-handler');
-
-    // Load the task/subtask plugins.
-    $task = page_manager_get_task($pane->esi_meta['task']);
-    $subtask = (empty($pane->esi_meta['subtask'])) ? '' : page_manager_get_subtask($task, $pane->esi_meta['subtask']);
-
-    // Use the task-name and the original display arguments to generate the
-    // arguments that were passed to the context constructor.
-    // E.g. The node_view task takes "1" and returns node_load(1).
-    $base_context_arguments = esi_panels__get_base_context_arguments($pane->esi_meta['task'], $pane->esi_meta['subtask'], $pane->esi_meta['display_args']);
-    $base_contexts = ctools_context_handler_get_task_contexts($task, $subtask, $base_context_arguments);
-
-
-    // The base contexts are then typically used in the task plugin as render
-    // information:
-    // $output = ctools_context_handler_render($task, '', $contexts, array($node->nid));
-
-    // Other contexts are usually loaded by the panel_context task_handler
-    // plugin in the render function panels_panel_context_render():
-    // $contexts = ctools_context_handler_get_handler_contexts($base_contexts, $handler);
-
-    // Load the relevant handler
-    $handlers = page_manager_load_sorted_handlers($task, $subtask ? $subtask['name'] : '', TRUE);
-    $id = ctools_context_handler_get_render_handler($task, $subtask, $handlers, $base_contexts, $pane->esi_meta['display_args']);
-    if ($id) {
-      $handler = $handlers[$id];
-      $contexts = ctools_context_handler_get_handler_contexts($base_contexts, $handler);
-    }
-
-    $pane->esi_meta['display_contexts'] = $contexts;
+  // Load the actual pane info through the addressable content system.
+  $pane_meta = $pane->esi_meta;
+  ctools_include('content');
+  if ($pane = ctools_get_addressable_content($pane_meta['address'], 'pane')) {
+    $pane->esi_meta = $pane_meta;
   }
 }
 
 /**
- * Render the HTML for a single block.
+ * Render the HTML for a single pane.
  * Defined in hook_esi_component_info().
  *
  * @see esi_panels_esi_component_info()
  */
 function esi_panels__esi_pane_render($pane) {
-  // Much of this is from the "standard" display renderer:
-  // see panels_renderer_standard::prepare().
-  ctools_include('content');
-  $content_type = ctools_get_content_type($pane->type);
-
-  // Check access control; if the user doesn't have access, simply return an
-  // empty string.
-  // ctools_include('context');
-  // if ($pane->access && !empty($pane->display_contexts) && ctools_access($pane->access, $pane->display_contexts)) {
-  //   return '';
-  // }
-  $content = ctools_content_render($pane->type, $pane->subtype, $pane->configuration, array(), $pane->esi_meta['display_args'], $pane->esi_meta['display_contexts']);
-
-  if (empty($content)) {
-    return '';
-  }
-
-  foreach (module_implements('panels_pane_content_alter') as $module) {
-    $function = $module . '_panels_pane_content_alter';
-    $function($content, $pane, $pane->esi_meta['display_args'], $pane->esi_meta['display_contexts']);
-  }
-
+  // Set HTTP headers.
   esi_panels_set_http_headers($pane);
 
-  // Pass long the css_id that is usually available.
-  if (!empty($pane->css['css_id'])) {
-    $content->css_id = check_plain($pane->css['css_id']);
+  // Use addressable content exclusively.
+  if ($address = $pane->esi_meta['address']) {
+    ctools_include('content');
+    $content = ctools_get_addressable_content($address);
   }
 
-  // Pass long the css_class that is usually available.
-  if (!empty($pane->css['css_class'])) {
-    $content->css_class = check_plain($pane->css['css_class']);
+  // CTools will return an empty string if any of a number of errors occur.
+  if (empty($content)) {
+    return '';
   }
 
-  if (!empty($content->content)) {
-    if (!empty($pane->style['style'])) {
-      $style = panels_get_style($pane->style['style']);
-
-      if (isset($style) && isset($style['render pane'])) {
-        $output = theme($style['render pane'], array('content' => $content, 'pane' => $pane, 'display' => $this->display, 'style' => $style, 'settings' => $pane->style['settings']));
-
-        // This could be null if no theme function existed.
-        if (isset($output)) {
-          return $output;
-        }
-      }
-    }
-
-    // fallback
-    return theme('panels_pane', array('content' => $content, 'pane' => $pane, 'display' => $pane->esi_meta['display']));
-  }
+  return $content;
 }
 
 /**
@@ -174,7 +102,7 @@ function esi_panels_set_http_headers($pane) {
   // @see hook_esi_block_cache_headers_alter().
   drupal_alter('esi_panels_cache_headers', $headers);
 
-  foreach($headers as $header) {
+  foreach ($headers as $header) {
     drupal_add_http_header($header[0], $header[1]);
   }
 }
@@ -187,5 +115,4 @@ function esi_panels_set_http_headers($pane) {
  */
 function esi_panels__esi_pane_flush() {
   // @TODO.
-
 }
diff --git a/modules/esi_panels/esi_panels.module b/modules/esi_panels/esi_panels.module
index 835a232..3e9d318 100644
--- a/modules/esi_panels/esi_panels.module
+++ b/modules/esi_panels/esi_panels.module
@@ -87,7 +87,7 @@ function esi_panels_form_panels_panel_context_edit_settings_alter(&$form, &$form
 }
 
 /**
- * Implementation of hook_ctools_plugin_directory().
+ * Implements hook_ctools_plugin_directory().
  */
 function esi_panels_ctools_plugin_directory($module, $plugin) {
   // Safety: go away if CTools is not at an appropriate version.
@@ -99,7 +99,7 @@ function esi_panels_ctools_plugin_directory($module, $plugin) {
   // errors when they're in use.
   if ($module == 'ctools' && $plugin == 'cache') {
     return;
-    // if we did we'd make a plugin/ctools_cache or something.
+    // If we did we'd make a plugin/ctools_cache or something.
   }
 
   if ($module == 'page_manager' || $module == 'panels' || $module == 'ctools') {
@@ -121,7 +121,7 @@ function esi_panels_ctools_plugin_type() {
 }
 
 /**
- * Implementation of hook_ctools_plugin_api().
+ * Implements hook_ctools_plugin_api().
  *
  * Inform CTools about version information for various plugins implemented by
  * Panels.
@@ -157,45 +157,41 @@ function esi_panels_ctools_plugin_post_alter(&$plugin, &$info) {
 /**
  * Build the URL to use for this ESI component.
  *
- * @return String
- * The internal URL. Generate a fully-qualified path by running through url().
+ * @return string
+ *   The internal URL. Generate a fully-qualified path by running through url().
  */
 function esi_panels_url($pane, $display) {
-  // ESI 6.x-1.x and 6.x-2.x used the URL patterns:
-  // Default:                esi/panels_pane/theme:display_id:pane_id
-  // With context:           esi/panels_pane/theme:display_id:pane_id/[base64($_GET['q'])]/task_name/context
-
-  $url = "esi/panels_pane/";
-
+  // ESI 7 takes advantage of addressable content URLs.
+  // Addressable content URLs contain context and args.
+  // Default:              esi/panels_pane/theme:addressable_url
+  // Cache per-role:       esi/panels_pane/theme:addressable_url/CACHE=ROLE
+  // Cache per-user:       esi/panels_pane/theme:addressable_url/CACHE=USER
+  // Cache per-page:       esi/panels_pane/theme:addressable_url/[base64($_GET['q'])]
+  // Cache per-role-page:  esi/panels_pane/theme:addressable_url/[base64($_GET['q'])]/CACHE=ROLE
+  // Cache per-user-page:  esi/panels_pane/theme:addressable_url/[base64($_GET['q'])]/CACHE=ROLE
   global $theme;
-  $url .= implode(':', array(
-    $theme,
-    $pane->did,
-    $pane->pid,
-  ));
-
-  // The did and pid are used to identify which pane content_type to load.
-
-  // Other available data to pass into the URL:
-  // - $display->args       Are *always* passed.
-  // - $display->context    A pane can only accept a single context.
-  // - $display->cache_key  The cache key provides the name of the task/subtask.
-
-  if (!empty($pane->configuration['context'])) {
-    // If the context originates from the *TASK* plugin (which is typical), the
-    // task name is required in order to generate the task contexts
-    // ($base_context in panels_panel_context_render()).
-    // Additional contexts may be supplied directly by the display.
-    $task_name = _esi_panels__get_taskname($display->cache_key);
-
-    $url .= "/{$task_name}";
+  $url = "esi/panels_pane/" . $theme . ":";
+
+  // If the display reports that it has addressable content, make use of that.
+  if ($display->renderer_handler && $address = $display->renderer_handler->address) {
+    $url .= implode('::', array(
+      $address,
+      $pane->pid,
+    ));
   }
 
-  // Add all the display arguments to the end of the URL.
-  $url .= '/' . implode('/', $display->args);
+  if ($pane->cache['settings']['override_context']['esi_overridden_context__page']) {
+    $url .= '/' . base64_encode($_GET['q']);
+  }
 
-  // Always add the current page URL.
-  $url .= '/' . base64_encode($_GET['q']);
+  switch ($pane->cache['settings']['override_context']['esi_overridden_context__user']) {
+    case 1:
+      $url .= '/CACHE=ROLE';
+      break;
+    case 2:
+      $url .= '/CACHE=USER';
+      break;
+  }
 
   // Allow other modules to alter the ESI URL (or respond to it).
   // @see hook_esi_block_url_alter().
@@ -206,7 +202,7 @@ function esi_panels_url($pane, $display) {
 
 /**
  * Save the configuration of a panel page.
- * @see panels_panel_context_save().
+ * @see panels_panel_context_save()
  */
 function esi_panels__panel_context_save(&$handler, $update) {
   // Override the rendering pipeline if any pane uses ESI.
@@ -221,87 +217,23 @@ function esi_panels__panel_context_save(&$handler, $update) {
 }
 
 /**
- * Load the arguments which are used to populate the base context of a ctools
- * task plugin.
- *
- * @example
- * $args = esi_panels__get_base_context_arguments('node_view', array(1));
- * Returns array(node_load(1));
- *
- * @param String $task
- * The ctools task.
- * @param String $subtask
- * The subtask of the ctools task (if applicable).
- * @param Array $args
- * Arguments to pass to the argument constructor (if applicable).
- *
- * @return Array
- * Array of arguments to pass to the ctools context constructor.
- */
-function esi_panels__get_base_context_arguments($task, $subtask = '', $args = array()) {
-  // A core bug is preventing module_invoke_all() from lazy-loading according
-  // to the hook_hook_info() definitions.
-  foreach (module_list(FALSE, FALSE, TRUE) as $module) {
-    module_load_include('inc', $module, $module . '.esi_panels');
-  }
-
-  return module_invoke_all('esi_panels_context_arguments', $task, $subtask, $args);
-}
-
-
-/**
  * Check if any panes are configured to use ESI.
  *
- * @param Object $display
- * A panels_display object.
+ * @param ibject $display
+ *   A panels_display object.
  *
- * @return Boolean
+ * @return boolean
+ *   Whether any panes use the ESI cache.
  */
 function _esi_panels__display_uses_esi(panels_display $display) {
   // Iterate each pane.
   foreach ($display->content as $pid => $pane) {
     // Any single pane implementing ESI is enough to return TRUE.
-    if (!empty($pane->cache) && $pane->cache['method'] == 'esi') {
+    // Allow other cache plugins whose names start with "esi".
+    if (!empty($pane->cache) && strpos($pane->cache['method'], 'esi') === 0) {
       return TRUE;
     }
   }
 
   return FALSE;
 }
-
-/**
- * Reverse the $display->cache_key encoding to get the task name.
- *
- * @param String $cache_key
- * The cache key used on a display.
- *
- * @return String
- * The task name of the task handler.
- */
-function _esi_panels__get_taskname($cache_key) {
-  // $display->cache_key = 'panel_context:' . $task_name . ':' . $handler->name;
-  if (preg_match('/^panel_context:([^:]+):.*$/', $cache_key, $matches)) {
-    return $matches[1];
-  }
-}
-
-/**
- * Reverse the $display->cache_key encoding to get the task name (and sub-task
- * if used).
- *
- * @param String $task_name
- * The task key, as used by a display cache_key.
- *
- * @return Array
- * - 0 => Name of the task.
- * - 1 => Name of the subtask (or '' if not set).
- */
-function _esi_panels__get_task_identifier($task_name) {
-  if (strpos('-', $task_name)) {
-    list ($task, $subtask) = explode('-', $task_name, 2);
-    return array($task, $subtask);
-  }
-  else {
-    return array($task_name, '');
-  }
-}
diff --git a/modules/esi_panels/plugins/cache/esi.inc b/modules/esi_panels/plugins/cache/esi.inc
index 839e703..d5d7bed 100644
--- a/modules/esi_panels/plugins/cache/esi.inc
+++ b/modules/esi_panels/plugins/cache/esi.inc
@@ -1,10 +1,11 @@
 <?php
+
 /**
  * @file
  * ESI cache plugin.  Substitutes esi-tags for a panel-pane's content.
  */
 
-// Plugin definition
+// Plugin definition.
 $plugin = array(
   'title' => t("ESI"),
   'description' => t('ESI caching is a proxy-based cache. Panes are replaced by <esi> tags and requested separately by the proxy.'),
@@ -26,89 +27,68 @@ $plugin = array(
  * Set cached content.
  */
 function esi_panels_esi_cache_set_cache($conf, $content, $display, $args, $contexts, $pane = NULL) {
-  // $content will be a panels_cache_object; $content->content is the actual
-  // content.
-  // DO NOTHING!
+  if (!$conf['use_object_cache']) {
+    return FALSE;
+  }
+
+  $cid = esi_panels_esi_cache_get_id($conf, $display, $args, $contexts, $pane);
+  cache_set($cid, $content);
 }
 
 /**
  * Get cached content.
  */
 function esi_panels_esi_cache_get_cache($conf, $display, $args, $contexts, $pane = NULL) {
-  // If this 'cache get' function returns FALSE, panels will invoke and render
-  // the pane in the normal way.
-  return FALSE;
-
-
-  // @TODO: is this necessary now?
-  // // Check that the pane is indeed meant to be served by ESI.
-  // if (empty($pane) || empty($pane->cache['method']) || $pane->cache['method'] != 'esi') {
-  //   return FALSE;
-  // }
-  // 
-  // // Panels expects a cache-handler to return an object similar to the object
-  // // returned by cache_get().  Faking a cached object allows us to return a
-  // // simple ESI tag instead.
-  // 
-  // // Fake the cached object.
-  // $cache = new stdClass;
-  // $cache->data = new panels_cache_object();
-  // $cache->data->content = new stdClass;
-  // $cache->data->head = NULL;
-  // $cache->data->css = array();
-  // $cache->data->js = array();
-  // $cache->data->tokens = array();
-  // $cache->data->ready = TRUE;
-  // 
-  // // Fill in the content with the ESI code
-  // $cache->data->content->content = 'This is my content, tell me yours.';
-  // 
-  // // Add in extras if missing.
-  // if (!isset($cache->data->content->module)) {
-  //   $cache->data->content->module = isset($pane->type) ? $pane->type : 'esi_panels';
-  // }
-  // if (!isset($cache->data->content->delta)) {
-  //   $cache->data->content->delta = isset($pane->subtype) ? $pane->subtype : 'esi';
-  // }
-  // 
-  // // Return the cache object.
-  // return $cache->data;
-}
+  if (!$conf['use_object_cache']) {
+    return FALSE;
+  }
+  $cid = esi_panels_esi_cache_get_id($conf, $display, $args, $contexts, $pane);
+  $cache = cache_get($cid, 'cache');
+  if (!$cache) {
+    return FALSE;
+  }
 
+  if ((time() - $cache->created) > $conf['esi_ttl']) {
+    return FALSE;
+  }
+
+  return $cache->data;
+}
 
 /**
  * Admin-settings form for configuring the ESI cache on panel panes.
  */
 function esi_panels_esi_cache_settings_form($conf, $display, $pid) {
-  // drupal_set_message(print_r($display,true));
-
   // Use the TTL from the config if provided, or a suitable default.
-  $esi_ttl = isset($conf['esi_ttl']) ? $conf['esi_ttl'] : (int)variable_get('esi_panels_esi_default_ttl', ESI_DEFAULT_TTL);
+  $esi_ttl = isset($conf['esi_ttl']) ? $conf['esi_ttl'] : (int) variable_get('esi_panels_esi_default_ttl', ESI_DEFAULT_TTL);
 
   $pane = (isset($display->content[$pid])) ? $display->content[$pid] : FALSE;
-  // Load up the pane information to examine the context.
-
 
+  // Load up the pane information to examine the context.
   $form['esi_ttl'] = array(
-    '#title' => t('Cache Maximum Age (TTL)'),
+    '#title' => t('Cache maximum age (TTL)'),
     '#type' => 'select',
     '#options' => esi_max_age_options($esi_ttl),
     '#default_value' => $esi_ttl,
     '#description' => t('External page caches (proxy/browser) will not deliver cached paged older than this setting; time to live in short.'),
   );
 
-
-
+  // Load up the pane information to examine the context.
+  $form['use_object_cache'] = array(
+    '#title' => t('Use object caching'),
+    '#type' => 'checkbox',
+    '#default_value' => !empty($conf['use_object_cache']),
+    '#description' => t('Also use object caching for the content of ESI panes. (Be careful - this may cause cache coherency problems.)'),
+  );
 
   $form['override_context'] = array(
     '#title' => t('Override cache context'),
     '#type' => 'fieldset',
     '#description' => t('The context requested by the pane (and provided by the parent panel) will be used by default to create separate versions of the pane for each context.'),
     '#collapsible' => TRUE,
-    '#collapsed' => empty($conf['esi_override_context']),
+    '#collapsed' => empty($conf['override_context']['esi_override_context']),
   );
 
-
   // Describe the current panels context: placeholder if there is no context.
   $form['override_context']['pane_context'] = array(
     '#type' => 'item',
@@ -117,6 +97,7 @@ function esi_panels_esi_cache_settings_form($conf, $display, $pid) {
     '#suffix' => '</div>',
     '#markup' => t("This pane doesn't use panels context."),
   );
+
   // If there is context, add to the placeholder.
   if (!empty($pane->configuration['context'])) {
     // The context is a simple identifier - e.g. "argument_entity_id:node_1".
@@ -127,34 +108,17 @@ function esi_panels_esi_cache_settings_form($conf, $display, $pid) {
     $form['override_context']['pane_context']['#markup'] = t($context->identifier);
   }
 
-
-
   $form['override_context']['esi_override_context'] = array(
     '#title' => t('Override cache context'),
     '#type' => 'checkbox',
-    '#default_value' => !empty($conf['esi_override_context']),
+    '#default_value' => !empty($conf['override_context']['esi_override_context']),
   );
 
-  $form['override_context']['esi_overridden_context__pane_context'] = array(
-    '#title' => t('Cache per pane-context'),
-    '#description' => t("The contents of this pane changes depending on the pane context provided by the panel."),
-    '#type' => 'checkbox',
-    '#default_value' => !empty($conf['esi_overridden_context__pane_context']),
-    // If this pane doesn't provide context, this option isn't applicable.
-    '#disabled' => empty($pane->configuration['context']),
-
-    // @TODO: use states (once control of radios through states is patched).
-    // '#states' => array(
-    //   'disabled' => array(   // override_context to take.
-    //     ':input[name="settings[override_context][esi_override_context]"]' => array('unchecked' => TRUE),
-    //   ),
-    // ),
-  );
   $form['override_context']['esi_overridden_context__page'] = array(
     '#title' => t('Cache per page'),
     '#description' => t("The contents of this pane changes depending on the page on which it's displayed."),
     '#type' => 'checkbox',
-    '#default_value' => !empty($conf['esi_overridden_context__page']),
+    '#default_value' => !empty($conf['override_context']['esi_overridden_context__page']),
 
     // @TODO: use states (once control of radios through states is patched).
     // '#states' => array(
@@ -163,6 +127,7 @@ function esi_panels_esi_cache_settings_form($conf, $display, $pid) {
     //   ),
     // ),
   );
+
   $form['override_context']['esi_overridden_context__user'] = array(
     '#title' => t('User context'),
     '#description' => t("How a user or their roles affect the pane."),
@@ -172,7 +137,7 @@ function esi_panels_esi_cache_settings_form($conf, $display, $pid) {
       DRUPAL_CACHE_PER_ROLE => t("Pane changes according to the current user's roles"),
       DRUPAL_CACHE_PER_USER => ('Pane changes according to the current user'),
     ),
-    '#default_value' => isset($conf['esi_overridden_context__user']) ? $conf['esi_overridden_context__user'] : DRUPAL_CACHE_PER_ROLE,
+    '#default_value' => isset($conf['override_context']['esi_overridden_context__user']) ? $conf['override_context']['esi_overridden_context__user'] : DRUPAL_CACHE_PER_ROLE,
 
     // @TODO: use states (once control of radios through states is patched).
     // '#states' => array(
@@ -181,6 +146,56 @@ function esi_panels_esi_cache_settings_form($conf, $display, $pid) {
     //   ),
     // ),
   );
-  
+
   return $form;
 }
+
+/**
+ * Figure out an id for object caching based upon input and settings.
+ */
+function esi_panels_esi_cache_get_id($conf, $display, $args, $contexts, $pane) {
+  $id = 'esi_panels_esi_cache';
+
+  // This is used in case this is an in-code display, which means did will be something like 'new-1'.
+  if (isset($display->owner) && isset($display->owner->id)) {
+    $id .= ':' . $display->owner->id;
+  }
+  $id .= ':' . $display->did;
+
+  if ($pane) {
+    $id .= ':' . $pane->pid;
+  }
+
+  if (user_access('view pane admin links')) {
+    $id .= ':admin';
+  }
+
+  // @TODO: Fix this to align with how ESI.module works.
+  switch ($conf['granularity']) {
+    case 'args':
+      foreach ($args as $arg) {
+        $id .= ':' . $arg;
+      }
+      break;
+
+    case 'context':
+      if (!is_array($contexts)) {
+        $contexts = array($contexts);
+      }
+      foreach ($contexts as $context) {
+        if (isset($context->argument)) {
+          $id .= ':' . $context->argument;
+        }
+      }
+  }
+  if (module_exists('locale')) {
+    global $language;
+    $id .= ':' . $language->language;
+  }
+
+  if (!empty($pane->configuration['use_pager'])) {
+    $id .= ':p' . check_plain($_GET['page']);
+  }
+
+  return $id;
+}
diff --git a/modules/esi_panels/plugins/display_renderers/esi_panels_renderer_esi.class.php b/modules/esi_panels/plugins/display_renderers/esi_panels_renderer_esi.class.php
index 27b1f9e..098108f 100644
--- a/modules/esi_panels/plugins/display_renderers/esi_panels_renderer_esi.class.php
+++ b/modules/esi_panels/plugins/display_renderers/esi_panels_renderer_esi.class.php
@@ -7,7 +7,6 @@
  * they're bundled together into regions.
  */
 class esi_panels_renderer_esi extends panels_renderer_standard {
-  
   /**
    * Prepare the list of panes to be rendered, accounting for visibility/access
    * settings and rendering order.
@@ -132,7 +131,7 @@ class esi_panels_renderer_esi extends panels_renderer_standard {
    */
   function handle_esi_pane($pane) {
     $url = url(esi_panels_url($pane, $this->display), array('absolute' => TRUE));
-    $render =array(
+    $render = array(
       '#type' => 'esi',
       '#url' => $url,
     );
