diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index 4ebe881..f0b4fda 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -2624,6 +2624,8 @@ function drupal_language_initialize() {
     // Allow modules to react on language system initialization in multilingual
     // environments.
     bootstrap_invoke_all('language_init');
+    // @TODO remove after http://drupal.org/node/1859110 is resolved.
+    drupal_container()->get('config.factory')->resetConfigs();
   }
 }
 
diff --git a/core/includes/config.inc b/core/includes/config.inc
index 00c7fa6..0e8a604 100644
--- a/core/includes/config.inc
+++ b/core/includes/config.inc
@@ -102,7 +102,7 @@ function config_get_storage_names_with_prefix($prefix = '') {
  *   A configuration object.
  */
 function config($name) {
-  return drupal_container()->get('config.factory')->get($name)->load();
+  return drupal_container()->get('config.factory')->get($name);
 }
 
 /**
@@ -141,11 +141,11 @@ function config_sync_get_changes(StorageInterface $source_storage, StorageInterf
     'delete' => array(),
   );
 
-  foreach (array_diff_assoc($target_config_data, $source_config_data) as $name => $value) {
+  foreach (array_diff_key($target_config_data, $source_config_data) as $name => $value) {
     $config_changes['delete'][] = $value['name'];
   }
 
-  foreach (array_diff_assoc($source_config_data, $target_config_data) as $name => $value) {
+  foreach (array_diff_key($source_config_data, $target_config_data) as $name => $value) {
     $config_changes['create'][] = $value['name'];
   }
 
@@ -179,6 +179,7 @@ function config_sync_get_changes(StorageInterface $source_storage, StorageInterf
  *   The storage to synchronize configuration to.
  */
 function config_sync_changes(array $config_changes, StorageInterface $source_storage, StorageInterface $target_storage) {
+  $factory = drupal_container()->get('config.factory');
   foreach (array('delete', 'create', 'change') as $op) {
     foreach ($config_changes[$op] as $name) {
       if ($op == 'delete') {
@@ -188,6 +189,7 @@ function config_sync_changes(array $config_changes, StorageInterface $source_sto
         $data = $source_storage->read($name);
         $target_storage->write($name, $data);
       }
+      $factory->resetConfig($name);
     }
   }
 }
diff --git a/core/lib/Drupal/Core/Config/Config.php b/core/lib/Drupal/Core/Config/Config.php
index 6fc2a87..0a8f0be 100644
--- a/core/lib/Drupal/Core/Config/Config.php
+++ b/core/lib/Drupal/Core/Config/Config.php
@@ -65,6 +65,13 @@ class Config {
   protected $eventDispatcher;
 
   /**
+   * Whether the config object has already been loaded.
+   *
+   * @var bool
+   */
+  protected $isLoaded = FALSE;
+
+  /**
    * Constructs a configuration object.
    *
    * @param string $name
@@ -88,6 +95,8 @@ public function __construct($name, StorageInterface $storage, EventDispatcher $e
    *   The configuration object.
    */
   public function init() {
+    $this->isLoaded = FALSE;
+    $this->overrides = array();
     $this->notify('init');
     return $this;
   }
@@ -120,6 +129,9 @@ public function setName($name) {
    *   TRUE if this config object does not exist in storage.
    */
   public function isNew() {
+    if (!$this->isLoaded) {
+      $this->load();
+    }
     return $this->isNew;
   }
 
@@ -151,6 +163,9 @@ public function isNew() {
    *   The data that was requested.
    */
   public function get($key = '') {
+    if (!$this->isLoaded) {
+      $this->load();
+    }
     if (!isset($this->overriddenData)) {
       $this->setOverriddenData();
     }
@@ -179,6 +194,25 @@ public function get($key = '') {
    *   The configuration object.
    */
   public function setData(array $data) {
+    // A load would destroy the data just set (for example on import).
+    $this->isLoaded = TRUE;
+    return $this->setDataReal($data);
+  }
+
+  /**
+   * Replaces the data of this configuration object.
+   *
+   * This function is separate from setData to avoid load() state tracking.
+   *
+   * @param array $data
+   *   The new configuration data.
+   *
+   * @return Drupal\Core\Config\Config
+   *   The configuration object.
+   */
+  protected function setDataReal(array $data) {
+    // A load would destroy the data just set (for example on import). Do not
+    // set when inside load().
     $this->data = $data;
     $this->resetOverriddenData();
     return $this;
@@ -243,6 +277,9 @@ protected function resetOverriddenData() {
    *   The configuration object.
    */
   public function set($key, $value) {
+    if (!$this->isLoaded) {
+      $this->load();
+    }
     // Type-cast value into a string.
     $value = $this->castValue($value);
 
@@ -309,6 +346,9 @@ public function castValue($value) {
    *   The configuration object.
    */
   public function clear($key) {
+    if (!$this->isLoaded) {
+      $this->load();
+    }
     $parts = explode('.', $key);
     if (count($parts) == 1) {
       unset($this->data[$key]);
@@ -327,16 +367,18 @@ public function clear($key) {
    *   The configuration object.
    */
   public function load() {
+    $this->isLoaded = FALSE;
     $data = $this->storage->read($this->name);
     if ($data === FALSE) {
       $this->isNew = TRUE;
-      $this->setData(array());
+      $this->setDataReal(array());
     }
     else {
       $this->isNew = FALSE;
-      $this->setData($data);
+      $this->setDataReal($data);
     }
     $this->notify('load');
+    $this->isLoaded = TRUE;
     return $this;
   }
 
@@ -347,6 +389,9 @@ public function load() {
    *   The configuration object.
    */
   public function save() {
+    if (!$this->isLoaded) {
+      $this->load();
+    }
     $this->storage->write($this->name, $this->data);
     $this->isNew = FALSE;
     $this->notify('save');
@@ -412,8 +457,12 @@ protected function notify($config_event_name) {
    *   The configuration object.
    */
   public function merge(array $data_to_merge) {
+    if (!$this->isLoaded) {
+      $this->load();
+    }
     // Preserve integer keys so that config keys are not changed.
     $this->data = NestedArray::mergeDeepArray(array($this->data, $data_to_merge), TRUE);
+    $this->resetOverriddenData();
     return $this;
   }
 }
diff --git a/core/lib/Drupal/Core/Config/ConfigFactory.php b/core/lib/Drupal/Core/Config/ConfigFactory.php
index ca36ce7..fd3f6bc 100644
--- a/core/lib/Drupal/Core/Config/ConfigFactory.php
+++ b/core/lib/Drupal/Core/Config/ConfigFactory.php
@@ -38,6 +38,8 @@ class ConfigFactory {
    */
   protected $eventDispatcher;
 
+  protected $configs = array();
+
   /**
    * Constructs the Config factory.
    *
@@ -64,26 +66,37 @@ public function __construct(StorageInterface $storage, EventDispatcher $event_di
   public function get($name) {
     global $conf;
 
-    // @todo Caching the instantiated objects per name might cut off a fair
-    //   amount of CPU time and memory. Only the data within the configuration
-    //   object changes, so the additional cost of instantiating duplicate
-    //   objects could possibly be avoided. It is not uncommon for a
-    //   configuration object to be retrieved many times during a single
-    //   request; e.g., 'system.performance' alone is retrieved around 10-20
-    //   times within a single page request. Sub-requests via HttpKernel will
-    //   most likely only increase these counts.
-    // @todo Benchmarks were performed with a script that essentially retained
-    //   all instantiated configuration objects in memory until script execution
-    //   ended. A variant of that script called config() within a helper
-    //   function only, which inherently meant that PHP destroyed all
-    //   configuration objects after leaving the function. Consequently,
-    //   benchmark results looked entirely different. Profiling should probably
-    //   redone under more realistic conditions; e.g., actual HTTP requests.
-    // @todo The decrease of CPU time is interesting, since that means that
-    //   ContainerBuilder involves plenty of function calls (which are known to
-    //   be slow in PHP).
-    $config = new Config($name, $this->storage, $this->eventDispatcher);
-    return $config->init();
+    if (isset($this->configs[$name])) {
+      return $this->configs[$name];
+    }
+
+    $this->configs[$name] = new Config($name, $this->storage, $this->eventDispatcher);
+    return $this->configs[$name]->init();
+  }
+
+  function resetConfigs() {
+    foreach ($this->configs as $config) {
+      $config->init();
+    }
   }
 
+  function resetConfig($name) {
+    if (isset($this->configs[$name])) {
+      $this->configs[$name]->init();
+    }
+  }
+
+  function renameConfig($old_name, $new_name) {
+    // This will likely always be TRUE
+    if (isset($this->configs[$old_name])) {
+      $config = $this->configs[$old_name];
+      // Save a clone of the config object in the old slot
+      $this->configs[$old_name] = clone $config;
+
+      // Update the name and re-init the object
+      // then save it in the slot of the new_name
+      $config->setName($new_name)->init();
+      $this->configs[$new_name] = $config;
+    }
+  }
 }
diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigStorageController.php b/core/lib/Drupal/Core/Config/Entity/ConfigStorageController.php
index fbd6611..adc7ed9 100644
--- a/core/lib/Drupal/Core/Config/Entity/ConfigStorageController.php
+++ b/core/lib/Drupal/Core/Config/Entity/ConfigStorageController.php
@@ -287,9 +287,17 @@ public function save(EntityInterface $entity) {
       $id = $entity->getOriginalID();
     }
     $config = config($prefix . $id);
-    $config->setName($prefix . $entity->id());
+    $is_new = $config->isNew();
+
+    if ($id != $entity->id()) {
+      // We need to keep three things in mind for a rename:
+      // * Storage controller needs to access the original object
+      // * Object should be renamed in ConfigFactory and slot should be updated
+      // * All instances of the Object should be renamed
+      drupal_container()->get('config.factory')->renameConfig($prefix . $id, $prefix . $entity->id());
+    }
 
-    if (!$config->isNew() && !isset($entity->original)) {
+    if (!$is_new && !isset($entity->original)) {
       $this->resetCache(array($id));
       $result = $this->load(array($id));
       $entity->original = reset($result);
@@ -303,7 +311,7 @@ public function save(EntityInterface $entity) {
       $config->set($key, $value);
     }
 
-    if (!$config->isNew()) {
+    if (!$is_new) {
       $return = SAVED_UPDATED;
       $config->save();
       $this->postSave($entity, TRUE);
diff --git a/core/lib/Drupal/Core/CoreBundle.php b/core/lib/Drupal/Core/CoreBundle.php
index e1147ac..447f730 100644
--- a/core/lib/Drupal/Core/CoreBundle.php
+++ b/core/lib/Drupal/Core/CoreBundle.php
@@ -55,7 +55,8 @@ public function build(ContainerBuilder $container) {
       ->addMethodCall('addSubscriber', array(new Reference('config.subscriber.globalconf')));
     $container->register('config.factory', 'Drupal\Core\Config\ConfigFactory')
       ->addArgument(new Reference('config.storage'))
-      ->addArgument(new Reference('dispatcher'));
+      ->addArgument(new Reference('dispatcher'))
+      ->addTag('persist');
 
     // Register staging configuration storage.
     $container
diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php
index f0621fc..b011271 100644
--- a/core/lib/Drupal/Core/DrupalKernel.php
+++ b/core/lib/Drupal/Core/DrupalKernel.php
@@ -160,6 +160,7 @@ public function registerBundles() {
     $bundles = array(
       new CoreBundle(),
     );
+    $this->bundleClasses = array('Drupal\Core\CoreBundle');
 
     // Ensure we know what modules are enabled and that their namespaces are
     // registered.
@@ -259,6 +260,12 @@ protected function getClassName() {
    * Initializes the service container.
    */
   protected function initializeContainer() {
+    $persist = array();
+    if (isset($this->container)) {
+      foreach ($this->container->getParameter('persistIds') as $id) {
+        $persist[$id] = $this->container->get($id);
+      }
+    }
     $this->container = NULL;
     $class = $this->getClassName();
     $cache_file = $class . '.php';
@@ -285,6 +292,9 @@ protected function initializeContainer() {
     // Second, check if some other request -- for example on another web
     // frontend or during the installer -- changed the list of enabled modules.
     if (isset($this->container)) {
+      foreach ($persist as $id => $object) {
+        $this->container->set($id, $object);
+      }
       // All namespaces must be registered before we attempt to use any service
       // from the container.
       $container_modules = $this->container->getParameter('container.modules');
@@ -309,6 +319,9 @@ protected function initializeContainer() {
 
     if (!isset($this->container)) {
       $this->container = $this->buildContainer();
+      foreach ($persist as $id => $object) {
+        $this->container->set($id, $object);
+      }
       if ($this->allowDumping) {
         $this->containerNeedsDumping = TRUE;
       }
@@ -336,6 +349,7 @@ protected function buildContainer() {
     foreach ($this->bundles as $bundle) {
       $bundle->build($container);
     }
+    $container->setParameter('persistIds', array_keys($container->findTaggedServiceIds('persist')));
     $container->compile();
     return $container;
   }
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigOverrideTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigOverrideTest.php
index 8e83a84..e2ddb59 100644
--- a/core/modules/config/lib/Drupal/config/Tests/ConfigOverrideTest.php
+++ b/core/modules/config/lib/Drupal/config/Tests/ConfigOverrideTest.php
@@ -64,7 +64,7 @@ function testConfOverride() {
     $this->assertIdentical($config->get('404'), $expected_original_data['404']);
 
     // Reload the configuration object.
-    $config = config('config_test.system');
+    $config->init();
 
     // Verify that it contains the overridden data from $conf.
     $this->assertIdentical($config->get('foo'), $conf['config_test.system']['foo']);
@@ -97,7 +97,7 @@ function testConfOverride() {
     unset($conf['config_test.system']);
 
     // Reload it and verify that it still contains the original data.
-    $config = config('config_test.system');
+    $config->init();
     $this->assertIdentical($config->get('foo'), $expected_original_data['foo']);
     $this->assertIdentical($config->get('baz'), $expected_original_data['baz']);
     $this->assertIdentical($config->get('404'), $expected_original_data['404']);
diff --git a/core/modules/config/lib/Drupal/config/Tests/LocaleConfigOverride.php b/core/modules/config/lib/Drupal/config/Tests/LocaleConfigOverride.php
index adfe0b9..350a166 100644
--- a/core/modules/config/lib/Drupal/config/Tests/LocaleConfigOverride.php
+++ b/core/modules/config/lib/Drupal/config/Tests/LocaleConfigOverride.php
@@ -37,7 +37,6 @@ function testLocaleConfigOverride() {
     // Spoof multilingual.
     $GLOBALS['conf']['language_count'] = 2;
     drupal_language_initialize();
-    $config = config($name);
     $this->assertIdentical($config->get('foo'), 'en bar');
   }
 }
diff --git a/core/modules/field/tests/modules/field_test/field_test.module b/core/modules/field/tests/modules/field_test/field_test.module
index 903c2f9..f9359f6 100644
--- a/core/modules/field/tests/modules/field_test/field_test.module
+++ b/core/modules/field/tests/modules/field_test/field_test.module
@@ -298,3 +298,16 @@ function field_test_field_extra_fields_alter(&$info) {
   // Remove all extra fields from the 'no_fields' content type;
   unset($info['node']['no_fields']);
 }
+
+/**
+ * Implements hook_module_implements_alter().
+ */
+function field_test_module_implements_alter(&$implementations, $hook) {
+  if ($hook == 'entity_info_alter' && isset($implementations['field_test']) && isset($implementations['rdf'])) {
+    foreach (array('field_test', 'rdf') as $module) {
+      $group = $implementations[$module];
+      unset($implementations[$module]);
+      $implementations[$module] = $group;
+    }
+  }
+}
diff --git a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
index a936558..c9099a1 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
@@ -1227,6 +1227,7 @@ protected function drupalPost($path, $edit, $submit, array $options = array(), a
           $out = $this->curlExec(array(CURLOPT_URL => $action, CURLOPT_POST => TRUE, CURLOPT_POSTFIELDS => $post, CURLOPT_HTTPHEADER => $headers));
           // Ensure that any changes to variables in the other thread are picked up.
           $this->refreshVariables();
+          drupal_container()->get('config.factory')->resetConfigs();
 
           // Replace original page output with new output from redirected page(s).
           if ($new = $this->checkForMetaRefresh()) {
