diff --git a/core/includes/config.inc b/core/includes/config.inc
index 5e07c54..522abbd 100644
--- a/core/includes/config.inc
+++ b/core/includes/config.inc
@@ -1,6 +1,7 @@
 <?php
 
 use Drupal\Core\Config\Config;
+use Drupal\Core\Config\ConfigFactory;
 use Drupal\Core\Config\FileStorage;
 use Drupal\Core\Config\NullStorage;
 use Drupal\Core\Config\StorageInterface;
@@ -55,7 +56,7 @@ function config_get_storage_names_with_prefix($prefix = '') {
  * @code config('book.admin') @endcode will return a configuration object in
  * which the book module can store its administrative settings.
  *
- * @param $name
+ * @param string $name
  *   The name of the configuration object to retrieve. The name corresponds to
  *   a configuration file. For @code config('book.admin') @endcode, the config
  *   object returned will contain the contents of book.admin configuration file.
@@ -68,6 +69,57 @@ function config($name) {
 }
 
 /**
+ * Retrieves a configuration object for administration.
+ *
+ * This configuration object has a special configuration context (admin = TRUE)
+ * and configuration plug-ins should mostly keep hands off this object and don't
+ * override it.
+ *
+ * @param $name
+ *   The name of the configuration object to retrieve.
+ *
+ * @return Drupal\Core\Config\Config
+ *   A configuration object.
+ */
+function config_admin($name) {
+  static $config_factory;
+  if (!isset($config_factory)) {
+    $config_factory = config_factory(array('config.admin' => TRUE));
+  }
+  return $config_factory->get($name)->load();
+}
+
+/**
+ * Retrieves a configuration factory object for a given context.
+ *
+ * @param array $context
+ *   (optional) Array with contextual data to be used for the configuration
+ *   factory. Defaults to an empty array.
+ * @param Drupal\Core\Config\StorageInterface $storage
+ *   (optional) The storage controller object to use for reading and writing
+ *   configuration data. Defaults to the storage controller object registered
+ *   in the Drupal Container.
+ * @param Symfony\Component\EventDispatcher\EventDispatcher
+ *   (optional) An event dispatcher instance to use for configuration events.
+ *   Defaults to the event dispatcher instance registered in the Drupal
+ *   Container.
+ *
+ * @return Drupal\Core\Config\ConfigFactory
+ *   Configuration factory object.
+ */
+function config_factory(array $context = array(), StorageInterface $storage = NULL, EventDispatcher $event_dispatcher = NULL) {
+  $storage = $storage ? $storage : drupal_container()->get('config.storage');
+  $event_dispatcher = $event_dispatcher ? $event_dispatcher : drupal_container()->get('dispatcher');
+  $factory = new ConfigFactory($storage, $event_dispatcher);
+  foreach ($context as $key => $value) {
+    $factory->setContext($key, $value);
+  }
+  // Notify other modules and allow them to add other context objects.
+  module_invoke_all('config_factory', $factory);
+  return $factory;
+}
+
+/**
  * Returns a list of differences between configuration storages.
  *
  * @param Drupal\Core\Config\StorageInterface $source_storage
diff --git a/core/lib/Drupal/Core/Config/Config.php b/core/lib/Drupal/Core/Config/Config.php
index 3fe9563..be697ce 100644
--- a/core/lib/Drupal/Core/Config/Config.php
+++ b/core/lib/Drupal/Core/Config/Config.php
@@ -9,6 +9,7 @@
 
 use Drupal\Component\Utility\NestedArray;
 use Symfony\Component\EventDispatcher\EventDispatcher;
+use Drupal\Core\Config\ConfigFactory;
 
 /**
  * Defines the default configuration object.
@@ -51,18 +52,18 @@ class Config {
   protected $overriddenData;
 
   /**
-   * The storage used to load and save this configuration object.
+   * The configuration factory that produces this configuration object.
    *
-   * @var Drupal\Core\Config\StorageInterface
+   * @var Drupal\Core\Config\ConfigFactory
    */
-  protected $storage;
+  protected $factory;
 
   /**
-   * The event dispatcher used to notify subscribers.
+   * The storage used to load and save this configuration object.
    *
-   * @var Symfony\Component\EventDispatcher\EventDispatcher
+   * @var Drupal\Core\Config\StorageInterface
    */
-  protected $eventDispatcher;
+  protected $storage;
 
   /**
    * Constructs a configuration object.
@@ -72,13 +73,15 @@ class Config {
    * @param Drupal\Core\Config\StorageInterface $storage
    *   A storage controller object to use for reading and writing the
    *   configuration data.
-   * @param Symfony\Component\EventDispatcher\EventDispatcher $event_dispatcher
-   *   The event dispatcher used to notify subscribers.
+   * @param Drupal\Core\Config\ConfigFactory $factory
+   *   (optional) A configuration factory object that produces this config
+   *   object. Defaults to the storage controller object registered in the
+   *   Drupal Container.
    */
-  public function __construct($name, StorageInterface $storage, EventDispatcher $event_dispatcher = NULL) {
+  public function __construct($name, StorageInterface $storage, ConfigFactory $factory = NULL) {
     $this->name = $name;
     $this->storage = $storage;
-    $this->eventDispatcher = $event_dispatcher ? $event_dispatcher : drupal_container()->get('dispatcher');
+    $this->factory = $factory ? $factory : drupal_container()->get('config.factory');
   }
 
   /**
@@ -396,9 +399,22 @@ public function getStorage() {
   }
 
   /**
-   * Dispatch a config event.
+   * Retrieves the configuration factory that produces this configuration object.
+   *
+   * @return Drupal\Core\Config\ConfigFactory
+   *   A configuration factory that produces this configuration object.
+   */
+  public function getFactory() {
+    return $this->factory;
+  }
+
+  /**
+   * Dispatches a config event.
+   *
+   * @param $config_event_name
+   *   Event name.
    */
   protected function notify($config_event_name) {
-    $this->eventDispatcher->dispatch('config.' . $config_event_name, new ConfigEvent($this));
+    $this->factory->notify($config_event_name, $this);
   }
 }
diff --git a/core/lib/Drupal/Core/Config/ConfigEvent.php b/core/lib/Drupal/Core/Config/ConfigEvent.php
index aabd1d8..710f51f 100644
--- a/core/lib/Drupal/Core/Config/ConfigEvent.php
+++ b/core/lib/Drupal/Core/Config/ConfigEvent.php
@@ -14,10 +14,16 @@ class ConfigEvent extends Event {
   protected $config;
 
   /**
-   * Constructor.
+   * Constructs a configuration event object.
+   *
+   * @param Drupal\Core\Config\Config
+   *   Configuration object.
+   * @param Drupal\Core\Config\ConfigFactory
+   *   Configuration factory object.
    */
-  public function __construct(Config $config) {
+  public function __construct(Config $config, ConfigFactory $factory) {
     $this->config = $config;
+    $this->factory = $factory;
   }
 
   /**
@@ -26,4 +32,14 @@ public function __construct(Config $config) {
   public function getConfig() {
     return $this->config;
   }
+
+  /**
+   * Get configuration factory object.
+   *
+   * @return Drupal\Core\Config\ConfigFactory
+   *   Configuration factory object.
+   */
+  public function getFactory() {
+    return $this->factory;
+  }
 }
diff --git a/core/lib/Drupal/Core/Config/ConfigFactory.php b/core/lib/Drupal/Core/Config/ConfigFactory.php
index ca36ce7..a2b4b51 100644
--- a/core/lib/Drupal/Core/Config/ConfigFactory.php
+++ b/core/lib/Drupal/Core/Config/ConfigFactory.php
@@ -39,6 +39,13 @@ class ConfigFactory {
   protected $eventDispatcher;
 
   /**
+   * The data of the configuration context.
+   *
+   * @var array
+   */
+  protected $context;
+
+  /**
    * Constructs the Config factory.
    *
    * @param Drupal\Core\Config\StorageInterface $storage
@@ -50,6 +57,7 @@ class ConfigFactory {
   public function __construct(StorageInterface $storage, EventDispatcher $event_dispatcher) {
     $this->storage = $storage;
     $this->eventDispatcher = $event_dispatcher;
+    $this->context = array();
   }
 
   /**
@@ -82,8 +90,64 @@ public function get($name) {
     // @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);
+    $config = new Config($name, $this->storage, $this);
     return $config->init();
   }
 
+  /**
+   * Get storage controller.
+   *
+   * @return Drupal\Core\Config\StorageInterface
+   *   A storage controller instance for reading and writing configuration data.
+   */
+  public function getStorage() {
+    return $this->storage;
+  }
+
+  /**
+   * Gets data from this config context.
+   *
+   * @param string $key
+   *   (optional) A string that maps to a key within the context data or empty
+   *   to get all data.
+   *
+   * @return array
+   *   The data that was requested.
+   */
+  public function getContext($key = '') {
+    if ($key) {
+      return isset($this->context[$key]) ? $this->context[$key] : NULL;
+    }
+    else {
+      return $this->context;
+    }
+  }
+
+  /**
+   * Sets data on this config context.
+   *
+   * @param $key
+   *   A string that maps to a key within the configuration context.
+   * @param $value
+   *   Any value to be set for this key.
+   *
+   * @return Drupal\Core\Config\ConfigFactory
+   *   This ConfigFactory instance.
+   */
+  public function setContext($key, $value) {
+    $this->context[$key] = $value;
+    return $this;
+  }
+
+  /**
+   * Dispatches a config event.
+   *
+   * @param string $config_event_name
+   *   Event name.
+   * @param Drupal\Core\Config\Config
+   *   Configuration object.
+   */
+  public function notify($config_event_name, Config $config) {
+    $this->eventDispatcher->dispatch('config.' . $config_event_name, new ConfigEvent($config, $this));
+  }
 }
diff --git a/core/lib/Drupal/Core/EventSubscriber/ConfigGlobalOverrideSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/ConfigGlobalOverrideSubscriber.php
index 6ee6a3d..75c508b 100644
--- a/core/lib/Drupal/Core/EventSubscriber/ConfigGlobalOverrideSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/ConfigGlobalOverrideSubscriber.php
@@ -23,9 +23,12 @@ class ConfigGlobalOverrideSubscriber implements EventSubscriberInterface {
   public function configInit(ConfigEvent $event) {
     global $conf;
 
-    $config = $event->getConfig();
-    if (isset($conf[$config->getName()])) {
-      $config->setOverride($conf[$config->getName()]);
+    // Do not override configuration objects that are intended for administration.
+    if (!$event->getFactory()->getContext('config.admin')) {
+      $config = $event->getConfig();
+      if (isset($conf[$config->getName()])) {
+        $config->setOverride($conf[$config->getName()]);
+      }
     }
   }
 
diff --git a/core/modules/config/config.api.php b/core/modules/config/config.api.php
index 147412d..558ee08 100644
--- a/core/modules/config/config.api.php
+++ b/core/modules/config/config.api.php
@@ -124,3 +124,25 @@ function hook_config_import_delete($name, $new_config, $old_config) {
   return TRUE;
 }
 
+/**
+ * Deletes configuration upon synchronizing configuration changes.
+ *
+ * This callback is invoked when a new configuration factory is created and
+ * allows a module to take over the synchronization of configuration data.
+ *
+ * Modules should implement this callback if they manage configuration data
+ * (such as image styles, node types, or fields) which needs to be prepared and
+ * passed through module API functions to properly handle a configuration
+ * change.
+ *
+ * @param Drupal\Core\Config\ConfigFactory $factory
+ *   A configuration object containing the new configuration data.
+ */
+function hook_config_factory($factory) {
+  if (!$factory->getContext('locale.language')) {
+    // Add user's language when in user's context.
+    if ($account = $factory->getContext('user.account')) {
+      $factory->setContext('locale.language', user_preferred_language($account));
+    }
+  }
+}
diff --git a/core/modules/locale/lib/Drupal/locale/LocaleConfigSubscriber.php b/core/modules/locale/lib/Drupal/locale/LocaleConfigSubscriber.php
index 3d2fd4a..2c0924e 100644
--- a/core/modules/locale/lib/Drupal/locale/LocaleConfigSubscriber.php
+++ b/core/modules/locale/lib/Drupal/locale/LocaleConfigSubscriber.php
@@ -25,11 +25,12 @@ class LocaleConfigSubscriber implements EventSubscriberInterface {
    *   The Event to process.
    */
   public function configLoad(ConfigEvent $event) {
-    $config = $event->getConfig();
-    $language = language(LANGUAGE_TYPE_INTERFACE);
-    $locale_name = $this->getLocaleConfigName($config->getName(), $language);
-    if ($override = $config->getStorage()->read($locale_name)) {
-      $config->setOverride($override);
+    if ($language = $event->getFactory()->getContext('locale.language')) {
+      $config = $event->getConfig();
+      $locale_name = $this->getLocaleConfigName($config->getName(), $language);
+      if ($override = $config->getStorage()->read($locale_name)) {
+        $config->setOverride($override);
+      }
     }
   }
 
diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module
index 3d3ce1f..8637785 100644
--- a/core/modules/locale/locale.module
+++ b/core/modules/locale/locale.module
@@ -10,6 +10,7 @@
  * object files are supported.
  */
 
+use Drupal\Core\Config\ConfigFactory;
 use Drupal\locale\LocaleLookup;
 use Drupal\locale\LocaleConfigSubscriber;
 use Drupal\locale\SourceString;
@@ -1037,6 +1038,20 @@ function _locale_rebuild_js($langcode = NULL) {
  * Implements hook_language_init().
  */
 function locale_language_init() {
+  // Add current language to default configuration factory.
+  drupal_container()->get('config.factory')->setContext('locale.language', language(LANGUAGE_TYPE_INTERFACE));
   // Add locale helper to configuration subscribers.
   drupal_container()->get('dispatcher')->addSubscriber(new LocaleConfigSubscriber());
 }
+
+/**
+ * Implements hook_config_factory().
+ */
+function locale_config_factory(ConfigFactory $factory) {
+  if (!$factory->getContext('locale.language')) {
+    // Add user's language for user context.
+    if ($account = $factory->getContext('user.account')) {
+      $factory->setContext('locale.language', user_preferred_language($account));
+    }
+  }
+}
diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc
index c55289c..f86dec7 100644
--- a/core/modules/system/system.admin.inc
+++ b/core/modules/system/system.admin.inc
@@ -1377,7 +1377,7 @@ function system_modules_uninstall_submit($form, &$form_state) {
  * @see system_settings_form()
  */
 function system_site_information_settings($form, &$form_state) {
-  $site_config = config('system.site');
+  $site_config = config_admin('system.site');
   $site_mail = $site_config->get('mail');
   if (empty($site_mail)) {
     $site_mail = ini_get('sendmail_from');
@@ -1482,7 +1482,7 @@ function system_site_information_settings_validate($form, &$form_state) {
  * Form submission handler for system_site_information_settings().
  */
 function system_site_information_settings_submit($form, &$form_state) {
-  config('system.site')
+  config_admin('system.site')
     ->set('name', $form_state['values']['site_name'])
     ->set('mail', $form_state['values']['site_mail'])
     ->set('slogan', $form_state['values']['site_slogan'])
@@ -1518,7 +1518,7 @@ function system_cron_settings($form, &$form_state) {
   $form['cron']['cron_safe_threshold'] = array(
     '#type' => 'select',
     '#title' => t('Run cron every'),
-    '#default_value' => config('system.cron')->get('threshold.autorun'),
+    '#default_value' => config_admin('system.cron')->get('threshold.autorun'),
     '#options' => array(0 => t('Never')) + drupal_map_assoc(array(3600, 10800, 21600, 43200, 86400, 604800), 'format_interval'),
   );
 
@@ -1531,7 +1531,7 @@ function system_cron_settings($form, &$form_state) {
  * @ingroup forms
  */
 function system_cron_settings_submit($form, &$form_state) {
-  config('system.cron')
+  config_admin('system.cron')
     ->set('threshold.autorun', $form_state['values']['cron_safe_threshold'])
     ->save();
 }
@@ -1563,7 +1563,7 @@ function system_logging_settings($form, &$form_state) {
   $form['error_level'] = array(
     '#type' => 'radios',
     '#title' => t('Error messages to display'),
-    '#default_value' => config('system.logging')->get('error_level'),
+    '#default_value' => config_admin('system.logging')->get('error_level'),
     '#options' => array(
       ERROR_REPORTING_HIDE => t('None'),
       ERROR_REPORTING_DISPLAY_SOME => t('Errors and warnings'),
@@ -1582,7 +1582,7 @@ function system_logging_settings($form, &$form_state) {
  * @ingroup forms
  */
 function system_logging_settings_submit($form, &$form_state) {
-  config('system.logging')
+  config_admin('system.logging')
     ->set('error_level', $form_state['values']['error_level'])
     ->save();
 }
@@ -1595,7 +1595,7 @@ function system_logging_settings_submit($form, &$form_state) {
  */
 function system_performance_settings($form, &$form_state) {
   drupal_add_library('system', 'drupal.system');
-  $config = config('system.performance');
+  $config = config_admin('system.performance');
 
   $form['clear_cache'] = array(
     '#type' => 'fieldset',
@@ -1681,7 +1681,7 @@ function system_performance_settings($form, &$form_state) {
  * @ingroup forms
  */
 function system_performance_settings_submit($form, &$form_state) {
-  $config = config('system.performance');
+  $config = config_admin('system.performance');
   $config->set('cache.page.enabled', $form_state['values']['cache']);
   $config->set('cache.page.max_age', $form_state['values']['page_cache_maximum_age']);
   $config->set('response.gzip', $form_state['values']['page_compression']);
@@ -1806,7 +1806,7 @@ function system_image_toolkit_settings() {
  * @ingroup forms
  */
 function system_rss_feeds_settings($form, &$form_state) {
-  $rss_config = config('system.rss');
+  $rss_config = config_admin('system.rss');
   $form['feed_description'] = array(
     '#type' => 'textarea',
     '#title' => t('Feed description'),
@@ -1841,7 +1841,7 @@ function system_rss_feeds_settings($form, &$form_state) {
  * @ingroup forms
  */
 function system_rss_feeds_settings_submit($form, &$form_state) {
-  config('system.rss')
+  config_admin('system.rss')
     ->set('channel.description', $form_state['values']['feed_description'])
     ->set('items.limit', $form_state['values']['feed_default_items'])
     ->set('items.view_mode', $form_state['values']['feed_item_length'])
@@ -2150,7 +2150,7 @@ function system_date_time_lookup() {
  * @see system_site_maintenance_mode_submit()
  */
 function system_site_maintenance_mode($form, &$form_state) {
-  $config = config('system.maintenance');
+  $config = config_admin('system.maintenance');
   $form['maintenance_mode'] = array(
     '#type' => 'checkbox',
     '#title' => t('Put site into maintenance mode'),
@@ -2172,7 +2172,7 @@ function system_site_maintenance_mode($form, &$form_state) {
  * @ingroup forms
  */
 function system_site_maintenance_mode_submit($form, &$form_state) {
-  config('system.maintenance')
+  config_admin('system.maintenance')
     ->set('enabled', $form_state['values']['maintenance_mode'])
     ->set('message', $form_state['values']['maintenance_mode_message'])
     ->save();
