diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index d2c1312de069c76497c3a9982331f5d16cdd1d4d..1ec434db09e6b0aec15ba157695fe2b45dfe6933 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -556,22 +556,28 @@ function install_run_task($task, &$install_state) {
     // already.
     $current_batch = \Drupal::state()->get('install_current_batch');
     if (!$install_state['interactive'] || !$current_batch) {
-      $batch = $function($install_state);
-      if (empty($batch)) {
+      $batches = $function($install_state);
+      if (empty($batches)) {
         // If the task did some processing and decided no batch was necessary,
         // there is nothing more to do here.
         return;
       }
-      batch_set($batch);
-      // For interactive batches, we need to store the fact that this batch
-      // task is currently running. Otherwise, we need to make sure the batch
-      // will complete in one page request.
-      if ($install_state['interactive']) {
-        \Drupal::state()->set('install_current_batch', $function);
+      // Create a one item list of batches if only one batch was provided.
+      if (isset($batches['operations'])) {
+        $batches = array($batches);
       }
-      else {
-        $batch =& batch_get();
-        $batch['progressive'] = FALSE;
+      foreach ($batches as $batch) {
+        batch_set($batch);
+        // For interactive batches, we need to store the fact that this batch
+        // task is currently running. Otherwise, we need to make sure the batch
+        // will complete in one page request.
+        if ($install_state['interactive']) {
+          \Drupal::state()->set('install_current_batch', $function);
+        }
+        else {
+          $batch =& batch_get();
+          $batch['progressive'] = FALSE;
+        }
       }
       // Process the batch. For progressive batches, this will redirect.
       // Otherwise, the batch will complete.
@@ -760,18 +766,12 @@ function install_tasks($install_state) {
 
   // Finish by adding the remaining core tasks.
   $tasks += array(
-    'install_import_translations_remaining' => array(
+    'install_finish_translations' => array(
       'display_name' => t('Finish translations'),
       'display' => $needs_translations,
       'type' => 'batch',
       'run' => $needs_translations ? INSTALL_TASK_RUN_IF_NOT_COMPLETED : INSTALL_TASK_SKIP,
     ),
-    'install_update_configuration_translations' => array(
-      'display_name' => t('Translate configuration'),
-      'display' => $needs_translations,
-      'type' => 'batch',
-      'run' => $needs_translations ? INSTALL_TASK_RUN_IF_NOT_COMPLETED : INSTALL_TASK_SKIP,
-    ),
     'install_finished' => array(
     ),
   );
@@ -1764,41 +1764,30 @@ function _install_prepare_import($langcodes, $server_pattern) {
  * @param $install_state
  *   An array of information about the current installation state.
  *
- * @return
- *   The batch definition, if there are language files to import.
+ * @return array
+ *   An array of batch definitions.
  */
-function install_import_translations_remaining(&$install_state) {
+function install_finish_translations(&$install_state) {
   \Drupal::moduleHandler()->loadInclude('locale', 'fetch.inc');
   \Drupal::moduleHandler()->loadInclude('locale', 'compare.inc');
+  \Drupal::moduleHandler()->loadInclude('locale', 'bulk.inc');
 
   // Build a fresh list of installed projects. When more projects than core are
   // installed, their translations will be downloaded (if required) and imported
   // using a batch.
   $projects = locale_translation_build_projects();
+  $languages = \Drupal::languageManager()->getLanguages();
+  $batches = array();
   if (count($projects) > 1) {
     $options = _locale_translation_default_update_options();
-    $languages = \Drupal::languageManager()->getLanguages();
     if ($batch = locale_translation_batch_update_build(array(), array_keys($languages), $options)) {
-      return $batch;
+      $batches[] = $batch;
     }
   }
-}
 
-/**
- * Creates configuration translations.
- *
- * @param array $install_state
- *   An array of information about the current installation state.
- *
- * @return array
- *   The batch definition, if there are configuration objects to update.
- *
- * @see install_tasks()
- */
-function install_update_configuration_translations(&$install_state) {
-  \Drupal::moduleHandler()->loadInclude('locale', 'bulk.inc');
-  $languages = \Drupal::languageManager()->getLanguages();
-  return locale_config_batch_update_components(array(), array_keys($languages));
+  // Creates configuration translations.
+  $batches[] = locale_config_batch_update_components(array(), array_keys($languages));
+  return $batches;
 }
 
 /**
diff --git a/core/modules/system/module.api.php b/core/modules/system/module.api.php
index 7fc9f1cfea99f2e0b670ead60e510a2b8f2369fc..2c3cbdeec7cef1acd06ceb6798f5142d89a48263 100644
--- a/core/modules/system/module.api.php
+++ b/core/modules/system/module.api.php
@@ -299,8 +299,9 @@ function hook_uninstall() {
  *       regular callback function, which does its processing and optionally
  *       returns HTML output.
  *     - batch: This indicates that the task function will return a batch API
- *       definition suitable for batch_set(). The installer will then take care
- *       of automatically running the task via batch processing.
+ *       definition suitable for batch_set() or an array of batch definitions
+ *       suitable for consecutive batch_set() calls. The installer will then
+ *       take care of automatically running the task via batch processing.
  *     - form: This indicates that the task function will return a standard
  *       form API definition (and separately define validation and submit
  *       handlers, as appropriate). The installer will then take care of
diff --git a/core/modules/system/src/Tests/Installer/InstallerTranslationMultipleLanguageTest.php b/core/modules/system/src/Tests/Installer/InstallerTranslationMultipleLanguageTest.php
index 879b0078e8c421394882b4c78d930e482a7be723..94759e4c812533e870c582d0f4b31e5e067b66df 100644
--- a/core/modules/system/src/Tests/Installer/InstallerTranslationMultipleLanguageTest.php
+++ b/core/modules/system/src/Tests/Installer/InstallerTranslationMultipleLanguageTest.php
@@ -29,8 +29,8 @@ class InstallerTranslationMultipleLanguageTest extends InstallerTestBase {
   protected function setUpLanguage() {
     // Place custom local translations in the translations directory.
     mkdir(DRUPAL_ROOT . '/' . $this->siteDirectory . '/files/translations', 0777, TRUE);
-    file_put_contents(DRUPAL_ROOT . '/' . $this->siteDirectory . '/files/translations/drupal-8.0.0.de.po', "msgid \"\"\nmsgstr \"\"\nmsgid \"Save and continue\"\nmsgstr \"Save and continue German\"");
-    file_put_contents(DRUPAL_ROOT . '/' . $this->siteDirectory . '/files/translations/drupal-8.0.0.es.po', "msgid \"\"\nmsgstr \"\"\nmsgid \"Save and continue\"\nmsgstr \"Save and continue Spanish\"");
+    file_put_contents(DRUPAL_ROOT . '/' . $this->siteDirectory . '/files/translations/drupal-8.0.0.de.po', "msgid \"\"\nmsgstr \"\"\nmsgid \"Save and continue\"\nmsgstr \"Save and continue German\"\nmsgid\"Anonymous\"\nmsgstr\"Anonymous German\"");
+    file_put_contents(DRUPAL_ROOT . '/' . $this->siteDirectory . '/files/translations/drupal-8.0.0.es.po', "msgid \"\"\nmsgstr \"\"\nmsgid \"Save and continue\"\nmsgstr \"Save and continue Spanish\"\nmsgid\"Anonymous\"\nmsgstr\"Anonymous Spanish\"");
 
     parent::setUpLanguage();
   }
@@ -49,18 +49,27 @@ public function testTranslationsLoaded() {
     }
 
     // Verify the strings from the translation files were imported.
-    $edit = array();
-    $edit['langcode'] = 'de';
-    $edit['translation'] = 'translated';
-    $edit['string'] = 'Save and continue';
-    $this->drupalPostForm('admin/config/regional/translate', $edit, t('Filter'));
-    $this->assertText('Save and continue German');
-    $edit = array();
-    $edit['langcode'] = 'es';
-    $edit['translation'] = 'translated';
-    $edit['string'] = 'Save and continue';
-    $this->drupalPostForm('admin/config/regional/translate', $edit, t('Filter'));
-    $this->assertText('Save and continue Spanish');
+    $test_samples = array('Save and continue', 'Anonymous');
+    $languages = array(
+      'de' => 'German',
+      'es' => 'Spanish',
+    );
+
+    foreach($test_samples as $sample) {
+      foreach($languages as $langcode => $name) {
+        $edit = array();
+        $edit['langcode'] = $langcode;
+        $edit['translation'] = 'translated';
+        $edit['string'] = $sample;
+        $this->drupalPostForm('admin/config/regional/translate', $edit, t('Filter'));
+        $this->assertText($sample . ' ' . $name);
+      }
+    }
+
+    $config = \Drupal::languageManager()->getLanguageConfigOverride('de', 'user.settings');
+    $this->assertEqual($config->get('anonymous'), 'Anonymous German');
+    $config = \Drupal::languageManager()->getLanguageConfigOverride('es', 'user.settings');
+    $this->assertEqual($config->get('anonymous'), 'Anonymous Spanish');
   }
 
 }