diff --git a/core/lib/Drupal/Core/StringTranslation/PluralTranslatableMarkup.php b/core/lib/Drupal/Core/StringTranslation/PluralTranslatableMarkup.php
index 583ab18..a073049 100644
--- a/core/lib/Drupal/Core/StringTranslation/PluralTranslatableMarkup.php
+++ b/core/lib/Drupal/Core/StringTranslation/PluralTranslatableMarkup.php
@@ -130,7 +130,7 @@ public function render() {
       return $this->placeholderFormat($translated_array[0], $arguments);
     }
 
-    $index = $this->getPluralIndex();
+    $index = $this->getStringTranslation()->getPluralIndex($this->count, $this->getOption('langcode'));
     if ($index == 0) {
       // Singular form.
       $return = $translated_array[0];
@@ -151,19 +151,4 @@ public function render() {
     return $this->placeholderFormat($return, $arguments);
   }
 
-  /**
-   * Gets the plural index through the gettext formula.
-   *
-   * @return int
-   */
-  protected function getPluralIndex() {
-    if (!isset(static::$localeEnabled)) {
-      static::$localeEnabled = function_exists('locale_get_plural');
-    }
-    if (function_exists('locale_get_plural')) {
-      return locale_get_plural($this->count, $this->getOption('langcode'));
-    }
-    return -1;
-  }
-
 }
diff --git a/core/lib/Drupal/Core/StringTranslation/TranslationInterface.php b/core/lib/Drupal/Core/StringTranslation/TranslationInterface.php
index cbee36f..a22faff 100644
--- a/core/lib/Drupal/Core/StringTranslation/TranslationInterface.php
+++ b/core/lib/Drupal/Core/StringTranslation/TranslationInterface.php
@@ -7,12 +7,14 @@
 
 namespace Drupal\Core\StringTranslation;
 
+use Drupal\Core\StringTranslation\Translator\TranslatorInterface;
+
 /**
  * Interface for the translation.manager translation service.
  *
  * @ingroup i18n
  */
-interface TranslationInterface {
+interface TranslationInterface extends TranslatorInterface {
 
   /**
    * Translates a string to the current language or to a given language.
@@ -112,4 +114,55 @@ public function translateString(TranslatableMarkup $translated_string);
    */
   public function formatPlural($count, $singular, $plural, array $args = array(), array $options = array());
 
+  /**
+   * Returns plural form index for a specific number.
+   *
+   * @param int $count
+   *   Number to return plural for.
+   * @param string $langcode
+   *   (optional) Language code to translate to a language other than what is
+   *   used to display the page.
+   *
+   * @return int
+   *   The default translation manager returns -1 because Locale is not
+   *   installed.
+   */
+  public function getPluralIndex($count, $langcode = NULL);
+
+  /**
+   * Retrieves English string to given language.
+   *
+   * @param string $langcode
+   *   Language code to translate to.
+   * @param string $string
+   *   The source string.
+   * @param string $context
+   *   The string context.
+   *
+   * @return string|FALSE
+   *   Translated string if there is a translation, FALSE if not.
+   */
+  public function getStringTranslation($langcode, $string, $context);
+
+  /**
+   * Sets the default langcode.
+   *
+   * @param string $langcode
+   *   A language code.
+   */
+  public function setDefaultLangcode($langcode);
+
+  /**
+   * Appends a translation system to the translation chain.
+   *
+   * @param \Drupal\Core\StringTranslation\Translator\TranslatorInterface $translator
+   *   The translation interface to be appended to the translation chain.
+   * @param int $priority
+   *   The priority of the logger being added.
+   *
+   * @return \Drupal\Core\StringTranslation\TranslationManager
+   *   The called object.
+   */
+  public function addTranslator(TranslatorInterface $translator, $priority = 0);
+
 }
diff --git a/core/lib/Drupal/Core/StringTranslation/TranslationManager.php b/core/lib/Drupal/Core/StringTranslation/TranslationManager.php
index e7c58d8..9e1bcd0 100644
--- a/core/lib/Drupal/Core/StringTranslation/TranslationManager.php
+++ b/core/lib/Drupal/Core/StringTranslation/TranslationManager.php
@@ -13,7 +13,7 @@
 /**
  * Defines a chained translation implementation combining multiple translators.
  */
-class TranslationManager implements TranslationInterface, TranslatorInterface {
+class TranslationManager implements TranslationInterface {
 
   /**
    * An unsorted array of arrays of active translators.
@@ -59,14 +59,7 @@ public function __construct(LanguageDefault $default_language) {
   }
 
   /**
-   * Appends a translation system to the translation chain.
-   *
-   * @param \Drupal\Core\StringTranslation\Translator\TranslatorInterface $translator
-   *   The translation interface to be appended to the translation chain.
-   * @param int $priority
-   *   The priority of the logger being added.
-   *
-   * @return $this
+   * {@inheritdoc}
    */
   public function addTranslator(TranslatorInterface $translator, $priority = 0) {
     $this->translators[$priority][] = $translator;
@@ -159,10 +152,7 @@ public function formatPlural($count, $singular, $plural, array $args = array(),
   }
 
   /**
-   * Sets the default langcode.
-   *
-   * @param string $langcode
-   *   A language code.
+   * {@inheritdoc}
    */
   public function setDefaultLangcode($langcode) {
     $this->defaultLangcode = $langcode;
@@ -180,4 +170,11 @@ public function reset() {
     }
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getPluralIndex($count, $langcode = NULL) {
+    return -1;
+  }
+
 }
diff --git a/core/modules/locale/locale.services.yml b/core/modules/locale/locale.services.yml
index 1d55460..948eaee 100644
--- a/core/modules/locale/locale.services.yml
+++ b/core/modules/locale/locale.services.yml
@@ -39,3 +39,9 @@ services:
     arguments: ['@cache_tags.invalidator']
     tags:
       - { name: event_subscriber }
+  locale.string_translation:
+    decorates: string_translation
+    class: Drupal\locale\TranslationManager
+    decoration_inner_name: string_translation.inner
+    arguments: ['@string_translation.inner']
+    public: false
diff --git a/core/modules/locale/src/Tests/LocalePluralFormatTest.php b/core/modules/locale/src/Tests/LocalePluralFormatTest.php
index 36868d5..6928ee7 100644
--- a/core/modules/locale/src/Tests/LocalePluralFormatTest.php
+++ b/core/modules/locale/src/Tests/LocalePluralFormatTest.php
@@ -71,6 +71,8 @@ public function testGetPluralFormat() {
     drupal_static_reset('locale_get_plural:plurals');
     drupal_static_reset('locale');
 
+    $this->rebuildContainer();
+
     // Expected plural translation strings for each plural index.
     $plural_strings = array(
       // English is not imported in this case, so we assume built-in text
diff --git a/core/modules/locale/src/TranslationManager.php b/core/modules/locale/src/TranslationManager.php
new file mode 100644
index 0000000..ab7c32e
--- /dev/null
+++ b/core/modules/locale/src/TranslationManager.php
@@ -0,0 +1,106 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\locale\TranslationManager.
+ */
+
+namespace Drupal\locale;
+
+use Drupal\Core\DependencyInjection\DependencySerializationTrait;
+use Drupal\Core\StringTranslation\PluralTranslatableMarkup;
+use Drupal\Core\StringTranslation\TranslatableMarkup;
+use Drupal\Core\StringTranslation\TranslationInterface;
+use Drupal\Core\StringTranslation\Translator\TranslatorInterface;
+
+/**
+ * Defines a translation manager that is Locale aware.
+ *
+ * @see \Drupal\Core\StringTranslation\TranslationManager
+ */
+class TranslationManager implements TranslationInterface {
+  use DependencySerializationTrait;
+
+  /**
+   * Constructs a TranslationManager object.
+   *
+   * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
+   *   The object that implements TranslationInterface.
+   */
+  public function __construct(TranslationInterface $string_translation) {
+    $this->stringTranslation = $string_translation;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function translate($string, array $args = array(), array $options = array()) {
+    $safe = TRUE;
+    $wrapper = new TranslatableMarkup($string, $args, $options, $this);
+    return $safe ? $wrapper : (string) $wrapper;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function translateString(TranslatableMarkup $translated_string) {
+    return $this->stringTranslation->translateString($translated_string);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formatPlural($count, $singular, $plural, array $args = array(), array $options = array()) {
+    $safe = TRUE;
+    $plural = new PluralTranslatableMarkup($count, $singular, $plural, $args, $options, $this);
+    return $safe ? $plural : (string) $plural;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPluralIndex($count, $langcode = NULL) {
+    return locale_get_plural($count, $langcode);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getStringTranslation($langcode, $string, $context) {
+    return $this->stringTranslation->getStringTranslation($langcode, $string, $context);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function reset() {
+    $this->stringTranslation->reset();
+  }
+
+  /**
+   * Sets the default langcode.
+   *
+   * @param string $langcode
+   *   A language code.
+   */
+  public function setDefaultLangcode($langcode) {
+    $this->stringTranslation->setDefaultLangcode($langcode);
+  }
+
+  /**
+   * Appends a translation system to the translation chain.
+   *
+   * @param \Drupal\Core\StringTranslation\Translator\TranslatorInterface $translator
+   *   The translation interface to be appended to the translation chain.
+   * @param int $priority
+   *   The priority of the logger being added.
+   *
+   * @return \Drupal\Core\StringTranslation\TranslationManager
+   *   The called object.
+   */
+  public function addTranslator(TranslatorInterface $translator, $priority = 0) {
+    $this->stringTranslation->addTranslator($translator, $priority);
+    return $this;
+  }
+
+}
diff --git a/core/modules/system/src/Tests/Module/InstallUninstallTest.php b/core/modules/system/src/Tests/Module/InstallUninstallTest.php
index f50c68a..035f811 100644
--- a/core/modules/system/src/Tests/Module/InstallUninstallTest.php
+++ b/core/modules/system/src/Tests/Module/InstallUninstallTest.php
@@ -7,6 +7,8 @@
 
 namespace Drupal\system\Tests\Module;
 
+use Drupal\Component\Render\FormattableMarkup;
+use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\Core\Logger\RfcLogLevel;
 
 /**
@@ -98,12 +100,12 @@ public function testInstallUninstall() {
       $edit = array();
       $package = $module->info['package'];
       $edit["modules[$package][$name][enable]"] = TRUE;
-      $this->drupalPostForm('admin/modules', $edit, t('Install'));
+      $this->drupalPostForm('admin/modules', $edit, 'Install');
 
       // Handle the case where modules were installed along with this one and
       // where we therefore hit a confirmation screen.
       if (count($modules_to_install) > 1) {
-        $this->drupalPostForm(NULL, array(), t('Continue'));
+        $this->drupalPostForm(NULL, array(), 'Continue');
       }
 
       // List the module display names to check the confirmation message.
@@ -111,17 +113,26 @@ public function testInstallUninstall() {
       foreach ($modules_to_install as $module_to_install) {
         $module_names[] = $all_modules[$module_to_install]->info['name'];
       }
-      $expected_text = \Drupal::translation()->formatPlural(count($module_names), 'Module @name has been enabled.', '@count modules have been enabled: @names.', array(
+      // We cannot use \Drupal::translation()->formatPlural() as the service is
+      // changed by the Locale module.
+      $arguments = [
         '@name' => $module_names[0],
         '@names' => implode(', ', $module_names),
-      ));
+        '@count' => count($module_names),
+      ];
+      if (count($module_names) == 1) {
+        $expected_text = new FormattableMarkup('Module @name has been enabled.', $arguments);
+      }
+      else {
+        $expected_text = new FormattableMarkup('@count modules have been enabled: @names.', $arguments);
+      }
       $this->assertText($expected_text, 'Modules status has been updated.');
 
       // Check that hook_modules_installed() was invoked with the expected list
       // of modules, that each module's database tables now exist, and that
       // appropriate messages appear in the logs.
       foreach ($modules_to_install as $module_to_install) {
-        $this->assertText(t('hook_modules_installed fired for @module', array('@module' => $module_to_install)));
+        $this->assertText(new FormattableMarkup('hook_modules_installed fired for @module', array('@module' => $module_to_install)));
         $this->assertLogMessage('system', "%module module installed.", array('%module' => $module_to_install), RfcLogLevel::INFO);
         $this->assertInstallModuleUpdates($module_to_install);
         $this->assertModuleSuccessfullyInstalled($module_to_install);
@@ -181,8 +192,8 @@ public function testInstallUninstall() {
     foreach ($all_modules as $name => $module) {
       $edit['modules[' . $module->info['package'] . '][' . $name . '][enable]'] = TRUE;
     }
-    $this->drupalPostForm('admin/modules', $edit, t('Install'));
-    $this->assertText(t('@count modules have been enabled: ', array('@count' => count($all_modules))), 'Modules status has been updated.');
+    $this->drupalPostForm('admin/modules', $edit, 'Install');
+    $this->assertText(new FormattableMarkup('@count modules have been enabled: ', array('@count' => count($all_modules))), 'Modules status has been updated.');
   }
 
   /**
@@ -220,16 +231,16 @@ protected function assertModuleSuccessfullyInstalled($name) {
   protected function assertSuccessfulUninstall($module, $package = 'Core') {
     $edit = array();
     $edit['uninstall[' . $module . ']'] = TRUE;
-    $this->drupalPostForm('admin/modules/uninstall', $edit, t('Uninstall'));
-    $this->drupalPostForm(NULL, NULL, t('Uninstall'));
-    $this->assertText(t('The selected modules have been uninstalled.'), 'Modules status has been updated.');
+    $this->drupalPostForm('admin/modules/uninstall', $edit, 'Uninstall');
+    $this->drupalPostForm(NULL, NULL, 'Uninstall');
+    $this->assertText(new TranslatableMarkup('The selected modules have been uninstalled.'), 'Modules status has been updated.');
     $this->assertModules(array($module), FALSE);
 
     // Check that the appropriate hook was fired and the appropriate log
     // message appears. (But don't check for the log message if the dblog
     // module was just uninstalled, since the {watchdog} table won't be there
     // anymore.)
-    $this->assertText(t('hook_modules_uninstalled fired for @module', array('@module' => $module)));
+    $this->assertText(new FormattableMarkup('hook_modules_uninstalled fired for @module', array('@module' => $module)));
     $this->assertLogMessage('system', "%module module uninstalled.", array('%module' => $module), RfcLogLevel::INFO);
 
     // Check that the module's database tables no longer exist.
diff --git a/core/tests/Drupal/Tests/UnitTestCase.php b/core/tests/Drupal/Tests/UnitTestCase.php
index f2c6f4c..893a9fa 100644
--- a/core/tests/Drupal/Tests/UnitTestCase.php
+++ b/core/tests/Drupal/Tests/UnitTestCase.php
@@ -224,6 +224,10 @@ public function getStringTranslationStub() {
         $wrapper = new PluralTranslatableMarkup($count, $singular, $plural, $args, $options, $translation);
         return $wrapper;
       });
+    $translation->expects($this->any())
+      ->method('getPluralIndex')
+      ->willReturn(-1);
+
     return $translation;
   }
 
