diff --git a/core/core.services.yml b/core/core.services.yml
index f3d2ae6..b602ebc 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -254,8 +254,6 @@ services:
   config.storage.schema:
     class: Drupal\Core\Config\ExtensionInstallStorage
     arguments: ['@config.storage', 'config/schema']
-  config.storage.installer:
-    class: Drupal\Core\Config\InstallStorage
   config.typed:
     class: Drupal\Core\Config\TypedConfigManager
     arguments: ['@config.storage', '@config.storage.schema', '@cache.discovery', '@module_handler']
diff --git a/core/lib/Drupal/Core/Language/LanguageManager.php b/core/lib/Drupal/Core/Language/LanguageManager.php
index 9169031..8803734 100644
--- a/core/lib/Drupal/Core/Language/LanguageManager.php
+++ b/core/lib/Drupal/Core/Language/LanguageManager.php
@@ -233,27 +233,16 @@ public function getLanguageSwitchLinks($type, Url $url) {
   }
 
   /**
-   * Some common languages with their English and native names.
-   *
-   * Language codes are defined by the W3C language tags document for
-   * interoperability. Language codes typically have a language and, optionally,
-   * a script or regional variant name. See:
-   * http://www.w3.org/International/articles/language-tags/ for more
-   * information.
-   *
-   * This list is based on languages available from localize.drupal.org. See
-   * http://localize.drupal.org/issues for information on how to add languages
-   * there.
-   *
-   * The "Left-to-right marker" comments and the enclosed UTF-8 markers are to
-   * make otherwise strange looking PHP syntax natural (to not be displayed in
-   * right to left). See http://drupal.org/node/128866#comment-528929.
-   *
-   * @return array
-   *   An array of language code to language name information.
-   *   Language name information itself is an array of English and native names.
+   * @inheritdoc
    */
   public static function getStandardLanguageList() {
+    // This list is based on languages available from localize.drupal.org. See
+    // http://localize.drupal.org/issues for information on how to add languages
+    // there.
+    //
+    // The "Left-to-right marker" comments and the enclosed UTF-8 markers are to
+    // make otherwise strange looking PHP syntax natural (to not be displayed in
+    // right to left). See http://drupal.org/node/128866#comment-528929.
     return array(
       'af' => array('Afrikaans', 'Afrikaans'),
       'am' => array('Amharic', 'አማርኛ'),
diff --git a/core/lib/Drupal/Core/Language/LanguageManagerInterface.php b/core/lib/Drupal/Core/Language/LanguageManagerInterface.php
index c29dd33..b536a00 100644
--- a/core/lib/Drupal/Core/Language/LanguageManagerInterface.php
+++ b/core/lib/Drupal/Core/Language/LanguageManagerInterface.php
@@ -208,4 +208,19 @@ public function setConfigOverrideLanguage(LanguageInterface $language = NULL);
    */
   public function getConfigOverrideLanguage();
 
+  /**
+   * Some common languages with their English and native names.
+   *
+   * Language codes are defined by the W3C language tags document for
+   * interoperability. Language codes typically have a language and, optionally,
+   * a script or regional variant name. See:
+   * http://www.w3.org/International/articles/language-tags/ for more
+   * information.
+   *
+   * @return array
+   *   An array of language code to language name information. Language name
+   *   information itself is an array of English and native names.
+   */
+  public static function getStandardLanguageList();
+
 }
diff --git a/core/modules/config/src/Tests/ConfigInstallTest.php b/core/modules/config/src/Tests/ConfigInstallTest.php
index 9a903a1..c32922a 100644
--- a/core/modules/config/src/Tests/ConfigInstallTest.php
+++ b/core/modules/config/src/Tests/ConfigInstallTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\config\Tests;
 
+use Drupal\Core\Config\InstallStorage;
 use Drupal\Core\Config\PreExistingConfigException;
 use Drupal\Core\Config\StorageInterface;
 use Drupal\Core\Config\UnmetDependenciesException;
@@ -223,7 +224,8 @@ public function testDependencyChecking() {
   function testLanguage() {
     $this->installModules(['config_test_language']);
     // Test imported configuration with implicit language code.
-    $data = $this->container->get('config.storage.installer')->read('config_test.dynamic.dotted.english');
+    $storage = new InstallStorage();
+    $data = $storage->read('config_test.dynamic.dotted.english');
     $this->assertTrue(!isset($data['langcode']));
     $this->assertEqual(
       $this->config('config_test.dynamic.dotted.english')->get('langcode'),
@@ -231,7 +233,7 @@ function testLanguage() {
     );
 
     // Test imported configuration with explicit language code.
-    $data = $this->container->get('config.storage.installer')->read('config_test.dynamic.dotted.french');
+    $data = $storage->read('config_test.dynamic.dotted.french');
     $this->assertEqual($data['langcode'], 'fr');
     $this->assertEqual(
       $this->config('config_test.dynamic.dotted.french')->get('langcode'),
diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module
index 237ef21..34f2e78 100644
--- a/core/modules/locale/locale.module
+++ b/core/modules/locale/locale.module
@@ -405,23 +405,30 @@ function locale_system_update(array $components) {
   // Skip running the translation imports if in the installer,
   // because it would break out of the installer flow. We have
   // built-in support for translation imports in the installer.
-  if (!drupal_installation_attempted() && locale_translatable_language_list() && \Drupal::config('locale.settings')->get('translation.import_enabled')) {
-    module_load_include('compare.inc', 'locale');
-
-    // Update the list of translatable projects and start the import batch.
-    // Only when new projects are added the update batch will be triggered. Not
-    // each enabled module will introduce a new project. E.g. sub modules.
-    $projects = array_keys(locale_translation_build_projects());
-    if ($list = array_intersect($list, $projects)) {
-      module_load_include('fetch.inc', 'locale');
-      // Get translation status of the projects, download and update
-      // translations.
-      $options = _locale_translation_default_update_options();
-      $batch = locale_translation_batch_update_build($list, array(), $options);
-      batch_set($batch);
+  if (!drupal_installation_attempted() && locale_translatable_language_list()) {
+    if (\Drupal::config('locale.settings')->get('translation.import_enabled')) {
+      module_load_include('compare.inc', 'locale');
+
+      // Update the list of translatable projects and start the import batch.
+      // Only when new projects are added the update batch will be triggered. Not
+      // each enabled module will introduce a new project. E.g. sub modules.
+      $projects = array_keys(locale_translation_build_projects());
+      if ($list = array_intersect($list, $projects)) {
+        module_load_include('fetch.inc', 'locale');
+        // Get translation status of the projects, download and update
+        // translations.
+        $options = _locale_translation_default_update_options();
+        $batch = locale_translation_batch_update_build($list, array(), $options);
+        batch_set($batch);
+      }
     }
+
+    // Construct a batch to update configuration for all components. Installing
+    // this component may have installed configuration from any number of
+    // other components. Do this even if import is not enabled because parsing
+    // new configuration may expose new source strings.
     \Drupal::moduleHandler()->loadInclude('locale', 'bulk.inc');
-    if ($batch = locale_config_batch_update_components(array(), array(), $components)) {
+    if ($batch = locale_config_batch_update_components(array())) {
       batch_set($batch);
     }
   }
diff --git a/core/modules/locale/locale.services.yml b/core/modules/locale/locale.services.yml
index 284878b..0e0dd47 100644
--- a/core/modules/locale/locale.services.yml
+++ b/core/modules/locale/locale.services.yml
@@ -1,7 +1,10 @@
 services:
+  locale.default.config.storage:
+    class: Drupal\locale\LocaleDefaultConfigStorage
+    arguments: ['@config.storage', '@language_manager']
   locale.config_manager:
     class: Drupal\locale\LocaleConfigManager
-    arguments: ['@config.storage', '@config.storage.installer', '@locale.storage', '@config.factory', '@config.typed', '@language_manager']
+    arguments: ['@config.storage', '@locale.storage', '@config.factory', '@config.typed', '@language_manager', '@locale.default.config.storage']
   locale.storage:
     class: Drupal\locale\StringDatabaseStorage
     arguments: ['@database']
diff --git a/core/modules/locale/src/LocaleConfigManager.php b/core/modules/locale/src/LocaleConfigManager.php
index da21bca..2f474f5 100644
--- a/core/modules/locale/src/LocaleConfigManager.php
+++ b/core/modules/locale/src/LocaleConfigManager.php
@@ -9,6 +9,7 @@
 
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Config\InstallStorage;
 use Drupal\Core\Config\StorageInterface;
 use Drupal\Core\Config\TypedConfigManagerInterface;
 use Drupal\Core\StringTranslation\TranslationWrapper;
@@ -45,13 +46,6 @@ class LocaleConfigManager {
   protected $configStorage;
 
   /**
-   * The storage instance for reading default configuration data.
-   *
-   * @var \Drupal\Core\Config\StorageInterface
-   */
-  protected $installStorage;
-
-  /**
    * The string storage for reading and writing translations.
    *
    * @var \Drupal\locale\StringStorageInterface;
@@ -96,13 +90,17 @@ class LocaleConfigManager {
   protected $isUpdatingFromLocale = FALSE;
 
   /**
+   * The locale default config storage instance.
+   *
+   * @var \Drupal\locale\LocaleDefaultConfigStorage
+   */
+  protected $defaultConfigStorage;
+
+  /**
    * Creates a new typed configuration manager.
    *
    * @param \Drupal\Core\Config\StorageInterface $config_storage
    *   The storage object to use for reading configuration data.
-   * @param \Drupal\Core\Config\StorageInterface $install_storage
-   *   The storage object to use for reading default configuration
-   *   data.
    * @param \Drupal\locale\StringStorageInterface $locale_storage
    *   The locale storage to use for reading string translations.
    * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
@@ -112,13 +110,13 @@ class LocaleConfigManager {
    * @param \Drupal\language\ConfigurableLanguageManagerInterface $language_manager
    *   The language manager.
    */
-  public function __construct(StorageInterface $config_storage, StorageInterface $install_storage, StringStorageInterface $locale_storage, ConfigFactoryInterface $config_factory, TypedConfigManagerInterface $typed_config, ConfigurableLanguageManagerInterface $language_manager) {
+  public function __construct(StorageInterface $config_storage, StringStorageInterface $locale_storage, ConfigFactoryInterface $config_factory, TypedConfigManagerInterface $typed_config, ConfigurableLanguageManagerInterface $language_manager, LocaleDefaultConfigStorage $default_config_storage) {
     $this->configStorage = $config_storage;
-    $this->installStorage = $install_storage;
     $this->localeStorage = $locale_storage;
     $this->configFactory = $config_factory;
     $this->typedConfigManager = $typed_config;
     $this->languageManager = $language_manager;
+    $this->defaultConfigStorage = $default_config_storage;
   }
 
   /**
@@ -133,7 +131,7 @@ public function __construct(StorageInterface $config_storage, StorageInterface $
   public function getTranslatableDefaultConfig($name) {
     if ($this->isSupported($name)) {
       // Create typed configuration wrapper based on install storage data.
-      $data = $this->installStorageRead($name);
+      $data = $this->defaultConfigStorage->read($name);
       $type_definition = $this->typedConfigManager->getDefinition($name);
       $data_definition = $this->typedConfigManager->buildDataDefinition($type_definition, $data);
       $typed_config = $this->typedConfigManager->create($data_definition, $data);
@@ -293,12 +291,12 @@ public function getComponentNames(array $components = array()) {
       foreach ($components as $type => $list) {
         // InstallStorage::getComponentNames returns a list of folders keyed by
         // config name.
-        $names = array_merge($names, $this->installStorageComponents($type, $list));
+        $names = array_merge($names, $this->defaultConfigStorage->getComponentNames($type, $list));
       }
       return $names;
     }
     else {
-      return $this->installStorageAll();
+      return $this->defaultConfigStorage->listAll();
     }
   }
 
@@ -474,7 +472,7 @@ public function hasTranslation($name, $langcode) {
    *   configuration exists.
    */
   public function getDefaultConfigLangcode($name) {
-    $shipped = $this->installStorageRead($name);
+    $shipped = $this->defaultConfigStorage->read($name);
     if (!empty($shipped)) {
       return !empty($shipped['langcode']) ? $shipped['langcode'] : 'en';
     }
@@ -635,81 +633,4 @@ protected function filterOverride(array $override_data, array $translatable) {
     return $filtered_data;
   }
 
-  /**
-   * Read a configuration from install storage or default languages.
-   *
-   * @param string $name
-   *   Configuration object name.
-   *
-   * @return array
-   *   Configuration data from install storage or default language.
-   */
-  protected function installStorageRead($name) {
-    if ($this->installStorage->exists($name)) {
-      return $this->installStorage->read($name);
-    }
-    elseif (strpos($name, 'language.entity.') === 0) {
-      // Simulate default languages as if they were shipped as default
-      // configuration.
-      $langcode = str_replace('language.entity.', '', $name);
-      $predefined_languages = $this->languageManager->getStandardLanguageList();
-      if (isset($predefined_languages[$langcode])) {
-        $data = $this->configStorage->read($name);
-        $data['label'] = $predefined_languages[$langcode][0];
-        return $data;
-      }
-    }
-  }
-
-  /**
-   * Return the list of configuration in install storage and current languages.
-   *
-   * @return array
-   *   List of configuration in install storage and current languages.
-   */
-  protected function installStorageAll() {
-    $languages = $this->predefinedConfiguredLanguages();
-    return array_unique(array_merge($this->installStorage->listAll(), $languages));
-  }
-
-  /**
-   * Get all configuration names and folders for a list of modules or themes.
-   *
-   * @param string $type
-   *   Type of components: 'module' | 'theme' | 'profile'
-   * @param array $list
-   *   Array of theme or module names.
-   *
-   * @return array
-   *   Configuration names provided by that component. In case of language
-   *   module this list is extended with configured languages that have
-   *   predefined names as well.
-   */
-  protected function installStorageComponents($type, array $list) {
-    $names = array_keys($this->installStorage->getComponentNames($type, $list));
-    if ($type == 'module' && in_array('language', $list)) {
-      $languages = $this->predefinedConfiguredLanguages();
-      $names = array_unique(array_merge($names, $languages));
-    }
-    return $names;
-  }
-
-  /**
-   * Compute the list of configuration names that match predefined languages.
-   *
-   * @return array
-   *   The list of configuration names that match predefined languages.
-   */
-  protected function predefinedConfiguredLanguages() {
-    $names = $this->configStorage->listAll('language.entity.');
-    $predefined_languages = $this->languageManager->getStandardLanguageList();
-    foreach ($names as $id => $name) {
-      $langcode = str_replace('language.entity.', '', $name);
-      if (!isset($predefined_languages[$langcode])) {
-        unset($names[$id]);
-      }
-    }
-    return array_values($names);
-  }
-
 }
diff --git a/core/modules/locale/src/LocaleDefaultConfigStorage.php b/core/modules/locale/src/LocaleDefaultConfigStorage.php
new file mode 100644
index 0000000..d17ce9a
--- /dev/null
+++ b/core/modules/locale/src/LocaleDefaultConfigStorage.php
@@ -0,0 +1,152 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\locale\LocaleDefaultConfigStorage.
+ */
+
+namespace Drupal\locale;
+
+use Drupal\Core\Config\InstallStorage;
+use Drupal\Core\Config\StorageInterface;
+use Drupal\language\ConfigurableLanguageManagerInterface;
+
+class LocaleDefaultConfigStorage {
+
+  /**
+   * The storage instance for reading configuration data.
+   *
+   * @var \Drupal\Core\Config\StorageInterface
+   */
+  protected $configStorage;
+
+  /**
+   * The language manager.
+   *
+   * @var \Drupal\language\ConfigurableLanguageManagerInterface
+   */
+  protected $languageManager;
+
+  /**
+   * The storage instance for reading required default configuration data.
+   *
+   * @var \Drupal\Core\Config\StorageInterface
+   */
+  protected $requiredInstallStorage;
+
+  /**
+   * The storage instance for reading optional default configuration data.
+   *
+   * @var \Drupal\Core\Config\StorageInterface
+   */
+  protected $optionalInstallStorage;
+
+  /**
+   * Constructs a LocaleDefaultConfigStorage.
+   *
+   * @param \Drupal\Core\Config\StorageInterface $config_storage
+   *   The storage object to use for reading configuration data.
+   * @param \Drupal\language\ConfigurableLanguageManagerInterface $language_manager
+   *   The language manager.
+   */
+  public function __construct(StorageInterface $config_storage, ConfigurableLanguageManagerInterface $language_manager) {
+    $this->configStorage = $config_storage;
+    $this->languageManager = $language_manager;
+
+    $this->requiredInstallStorage = new InstallStorage();
+    $this->optionalInstallStorage = new InstallStorage(InstallStorage::CONFIG_OPTIONAL_DIRECTORY);
+  }
+
+  /**
+   * Read a configuration from install storage or default languages.
+   *
+   * @param string $name
+   *   Configuration object name.
+   *
+   * @return array
+   *   Configuration data from install storage or default language.
+   */
+  public function read($name) {
+    if ($this->requiredInstallStorage->exists($name)) {
+      return $this->requiredInstallStorage->read($name);
+    }
+    elseif ($this->optionalInstallStorage->exists($name)) {
+      return $this->optionalInstallStorage->read($name);
+    }
+    elseif (strpos($name, 'language.entity.') === 0) {
+      // Simulate default languages as if they were shipped as default
+      // configuration.
+      $langcode = str_replace('language.entity.', '', $name);
+      $predefined_languages = $this->languageManager->getStandardLanguageList();
+      if (isset($predefined_languages[$langcode])) {
+        $data = $this->configStorage->read($name);
+        $data['label'] = $predefined_languages[$langcode][0];
+        return $data;
+      }
+    }
+  }
+
+  /**
+   * Return the list of configuration in install storage and current languages.
+   *
+   * @return array
+   *   List of configuration in install storage and current languages.
+   */
+  public function listAll() {
+    $languages = $this->predefinedConfiguredLanguages();
+    return array_unique(
+      array_merge(
+        $this->requiredInstallStorage->listAll(),
+        $this->optionalInstallStorage->listAll(),
+        $languages
+      )
+    );
+  }
+
+  /**
+   * Get all configuration names and folders for a list of modules or themes.
+   *
+   * @param string $type
+   *   Type of components: 'module' | 'theme' | 'profile'
+   * @param array $list
+   *   Array of theme or module names.
+   *
+   * @return array
+   *   Configuration names provided by that component. In case of language
+   *   module this list is extended with configured languages that have
+   *   predefined names as well.
+   */
+  public function getComponentNames($type, array $list) {
+    $names = array_unique(
+      array_merge(
+        array_keys($this->requiredInstallStorage->getComponentNames($type, $list)),
+        array_keys($this->optionalInstallStorage->getComponentNames($type, $list))
+      )
+    );
+    if ($type == 'module' && in_array('language', $list)) {
+      $languages = $this->predefinedConfiguredLanguages();
+      $names = array_unique(array_merge($names, $languages));
+    }
+    return $names;
+  }
+
+  /**
+   * Compute the list of configuration names that match predefined languages.
+   *
+   * @return array
+   *   The list of configuration names that match predefined languages.
+   */
+  protected function predefinedConfiguredLanguages() {
+    $names = $this->configStorage->listAll('language.entity.');
+    $predefined_languages = $this->languageManager->getStandardLanguageList();
+    foreach ($names as $id => $name) {
+      $langcode = str_replace('language.entity.', '', $name);
+      if (!isset($predefined_languages[$langcode])) {
+        unset($names[$id]);
+      }
+    }
+    return array_values($names);
+  }
+
+}
+
diff --git a/core/modules/locale/src/Tests/LocaleConfigTranslationTest.php b/core/modules/locale/src/Tests/LocaleConfigTranslationTest.php
index 4535b9b..3b0700f 100644
--- a/core/modules/locale/src/Tests/LocaleConfigTranslationTest.php
+++ b/core/modules/locale/src/Tests/LocaleConfigTranslationTest.php
@@ -19,6 +19,13 @@
 class LocaleConfigTranslationTest extends WebTestBase {
 
   /**
+   * The language code used.
+   *
+   * @var string
+   */
+  protected $langcode;
+
+  /**
    * Modules to enable.
    *
    * @var array
@@ -38,28 +45,28 @@ protected function setUp() {
     $this->config('locale.settings')
       ->set('translation.import_enabled', TRUE)
       ->save();
-  }
 
-  /**
-   * Tests basic configuration translation.
-   */
-  public function testConfigTranslation() {
     // Add custom language.
-    $langcode = 'xx';
+    $this->langcode = 'xx';
     $admin_user = $this->drupalCreateUser(array('administer languages', 'access administration pages', 'translate interface', 'administer modules', 'access site-wide contact form', 'administer contact forms', 'administer site configuration'));
     $this->drupalLogin($admin_user);
     $name = $this->randomMachineName(16);
     $edit = array(
       'predefined_langcode' => 'custom',
-      'langcode' => $langcode,
+      'langcode' => $this->langcode,
       'label' => $name,
       'direction' => LanguageInterface::DIRECTION_LTR,
     );
     $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language'));
     // Set path prefix.
-    $edit = array("prefix[$langcode]" => $langcode);
+    $edit = array("prefix[$this->langcode]" => $this->langcode);
     $this->drupalPostForm('admin/config/regional/language/detection/url', $edit, t('Save configuration'));
+  }
 
+  /**
+   * Tests basic configuration translation.
+   */
+  public function testConfigTranslation() {
     // Check that the maintenance message exists and create translation for it.
     $source = '@site is currently under maintenance. We should be back shortly. Thank you for your patience.';
     $string = $this->storage->findString(array('source' => $source, 'context' => '', 'type' => 'configuration'));
@@ -69,7 +76,7 @@ public function testConfigTranslation() {
     $message = $this->randomMachineName(20);
     $search = array(
       'string' => $string->source,
-      'langcode' => $langcode,
+      'langcode' => $this->langcode,
       'translation' => 'all',
     );
     $this->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
@@ -82,7 +89,7 @@ public function testConfigTranslation() {
     $this->drupalPostForm('admin/config/regional/translate', $edit, t('Save translations'));
 
     // Get translation and check we've only got the message.
-    $translation = \Drupal::languageManager()->getLanguageConfigOverride($langcode, 'system.maintenance')->get();
+    $translation = \Drupal::languageManager()->getLanguageConfigOverride($this->langcode, 'system.maintenance')->get();
     $this->assertEqual(count($translation), 1, 'Got the right number of properties after translation.');
     $this->assertEqual($translation['message'], $message);
 
@@ -93,7 +100,7 @@ public function testConfigTranslation() {
     // Translate using the UI so configuration is refreshed.
     $search = array(
       'string' => $string->source,
-      'langcode' => $langcode,
+      'langcode' => $this->langcode,
       'translation' => 'all',
     );
     $this->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
@@ -105,12 +112,12 @@ public function testConfigTranslation() {
     );
     $this->drupalPostForm('admin/config/regional/translate', $edit, t('Save translations'));
 
-    $translation = \Drupal::languageManager()->getLanguageConfigOverride($langcode, 'core.date_format.medium')->get();
+    $translation = \Drupal::languageManager()->getLanguageConfigOverride($this->langcode, 'core.date_format.medium')->get();
     $this->assertEqual($translation['pattern'], 'D', 'Got the right date format pattern after translation.');
 
     // Formatting the date 8 / 27 / 1985 @ 13:37 EST with pattern D should
     // display "Tue".
-    $formatted_date = format_date(494015820, $type = 'medium', NULL, NULL, $langcode);
+    $formatted_date = format_date(494015820, $type = 'medium', NULL, NULL, $this->langcode);
     $this->assertEqual($formatted_date, 'Tue', 'Got the right formatted date using the date format translation pattern.');
 
     // Assert strings from image module config are not available.
@@ -127,7 +134,7 @@ public function testConfigTranslation() {
     $this->assertTrue(isset($locations['configuration']) && isset($locations['configuration']['image.style.medium']), 'Configuration string has been created with the right location');
 
     // Check the string is unique and has no translation yet.
-    $translations = $this->storage->getTranslations(array('language' => $langcode, 'type' => 'configuration', 'name' => 'image.style.medium'));
+    $translations = $this->storage->getTranslations(array('language' => $this->langcode, 'type' => 'configuration', 'name' => 'image.style.medium'));
     $this->assertEqual(count($translations), 1);
     $translation = reset($translations);
     $this->assertEqual($translation->source, $string->source);
@@ -137,7 +144,7 @@ public function testConfigTranslation() {
     $image_style_label = $this->randomMachineName(20);
     $search = array(
       'string' => $string->source,
-      'langcode' => $langcode,
+      'langcode' => $this->langcode,
       'translation' => 'all',
     );
     $this->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
@@ -149,12 +156,12 @@ public function testConfigTranslation() {
     $this->drupalPostForm('admin/config/regional/translate', $edit, t('Save translations'));
 
     // Check the right single translation has been created.
-    $translations = $this->storage->getTranslations(array('language' => $langcode, 'type' => 'configuration', 'name' => 'image.style.medium'));
+    $translations = $this->storage->getTranslations(array('language' => $this->langcode, 'type' => 'configuration', 'name' => 'image.style.medium'));
     $translation = reset($translations);
     $this->assertTrue(count($translations) == 1 && $translation->source == $string->source && $translation->translation == $image_style_label, 'Got only one translation for image configuration.');
 
     // Try more complex configuration data.
-    $translation = \Drupal::languageManager()->getLanguageConfigOverride($langcode, 'image.style.medium')->get();
+    $translation = \Drupal::languageManager()->getLanguageConfigOverride($this->langcode, 'image.style.medium')->get();
     $this->assertEqual($translation['label'], $image_style_label, 'Got the right translation for image style name after translation');
 
     // Uninstall the module.
@@ -169,7 +176,7 @@ public function testConfigTranslation() {
     $category_label = $this->randomMachineName(20);
     $search = array(
       'string' => 'Website feedback',
-      'langcode' => $langcode,
+      'langcode' => $this->langcode,
       'translation' => 'all',
     );
     $this->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
@@ -183,7 +190,7 @@ public function testConfigTranslation() {
     // Check if this category displayed in this language will use the
     // translation. This test ensures the entity loaded from the request
     // upcasting will already work.
-    $this->drupalGet($langcode . '/contact/feedback');
+    $this->drupalGet($this->langcode . '/contact/feedback');
     $this->assertText($category_label);
 
     // Check if the UI does not show the translated String.
@@ -191,4 +198,54 @@ public function testConfigTranslation() {
     $this->assertFieldById('edit-label', 'Website feedback', 'Translation is not loaded for Edit Form.');
   }
 
+  /**
+   * Test translatability of optional configuration in locale.
+   */
+  public function testOptionalConfiguration() {
+    $this->checkNodeConfig(FALSE, FALSE);
+    // Enable the node module.
+    $this->drupalPostForm('admin/modules', array('modules[Core][node][enable]' => "1"), t('Save configuration'));
+    $this->drupalPostForm(NULL, array(), t('Continue'));
+    $this->rebuildContainer();
+    $this->checkNodeConfig(TRUE, FALSE);
+    // Enable the views module (which node provides some optional config for).
+    $this->drupalPostForm('admin/modules', array('modules[Core][views][enable]' => "1"), t('Save configuration'));
+    $this->rebuildContainer();
+    $this->checkNodeConfig(TRUE, TRUE);
+  }
+
+  /**
+   * Check that node configuration source strings are made available in locale.
+   *
+   * @param bool $required
+   *   Whether to assume a sample of the required default configuration is
+   *   present.
+   * @param bool $optional
+   *   Whether to assume a sample of the optional default configuration is
+   *   present.
+   */
+  protected function checkNodeConfig($required, $optional) {
+    // Check the required default configuration in node module.
+    $string = $this->storage->findString(array('source' => 'Make content sticky', 'context' => '', 'type' => 'configuration'));
+    if ($required) {
+      $this->assertFalse($this->config('system.action.node_make_sticky_action')->isNew());
+      $this->assertTrue($string, 'Node action text can be found with node module.');
+    }
+    else {
+      $this->assertTrue($this->config('system.action.node_make_sticky_action')->isNew());
+      $this->assertFalse($string, 'Node action text can not be found without node module.');
+    }
+
+    // Check the optional default configuration in node module.
+    $string = $this->storage->findString(array('source' => 'No front page content has been created yet.', 'context' => '', 'type' => 'configuration'));
+    if ($optional) {
+      $this->assertFalse($this->config('views.view.frontpage')->isNew());
+      $this->assertTrue($string, 'Node view text can be found with node and views modules.');
+    }
+    else {
+      $this->assertTrue($this->config('views.view.frontpage')->isNew());
+      $this->assertFalse($string, 'Node view text can not be found without node and/or views modules.');
+    }
+  }
+
 }
