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 e9962d6..939fe7b 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 array of active translators keyed by priority.
@@ -55,15 +55,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 \Drupal\Core\StringTranslation\TranslationManager
-   *   The called object.
+   * {@inheritdoc}
    */
   public function addTranslator(TranslatorInterface $translator, $priority = 0) {
     $this->translators[$priority][] = $translator;
@@ -151,10 +143,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;
@@ -172,4 +161,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 29603ee..06fcb94 100644
--- a/core/modules/locale/locale.services.yml
+++ b/core/modules/locale/locale.services.yml
@@ -37,3 +37,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 ba5cf84..e3b14ae 100644
--- a/core/modules/locale/src/Tests/LocalePluralFormatTest.php
+++ b/core/modules/locale/src/Tests/LocalePluralFormatTest.php
@@ -64,6 +64,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/simpletest/src/Tests/SimpleTestNoLocaleTest.php b/core/modules/simpletest/src/Tests/SimpleTestNoLocaleTest.php
new file mode 100644
index 0000000..af66a73
--- /dev/null
+++ b/core/modules/simpletest/src/Tests/SimpleTestNoLocaleTest.php
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\simpletest\Tests\SimpleTestNoLocaleTest.
+ */
+
+namespace Drupal\simpletest\Tests;
+
+use Drupal\Component\Utility\Crypt;
+use Drupal\simpletest\WebTestBase;
+
+/**
+ * A helper test that is run in a child site without locale.
+ *
+ * This test is executed by Drupal\simpletest\Tests\SimpleTestWithLocaleTest.
+ *
+ * @group simpletest
+ */
+class SimpleTestNoLocaleTest extends WebTestBase {
+
+  /**
+   * Ensures the tests run well no  language module enabled.
+   */
+  protected function testSimpleTestWithLanguageModule() {
+    if ($this->isInChildSite()) {
+      // Ensure the .htkey file exists since this is only created just before a
+      // request. This allows the stub test to make requests. The event does not
+      // fire here and drupal_generate_test_ua() can not generate a key for a
+      // test in a test since the prefix has changed.
+      // @see \Drupal\Core\Test\HttpClientMiddleware\TestHttpClientMiddleware::onBeforeSendRequest()
+      // @see drupal_generate_test_ua();
+      $key_file = DRUPAL_ROOT . '/sites/simpletest/' . substr($this->databasePrefix, 10) . '/.htkey';
+      $private_key = Crypt::randomBytesBase64(55);
+      file_put_contents($key_file, $private_key);
+    }
+    $this->drupalLogin($this->drupalCreateUser());
+  }
+
+}
diff --git a/core/modules/simpletest/src/Tests/SimpleTestWithLocaleTest.php b/core/modules/simpletest/src/Tests/SimpleTestWithLocaleTest.php
new file mode 100644
index 0000000..7e0aed0
--- /dev/null
+++ b/core/modules/simpletest/src/Tests/SimpleTestWithLocaleTest.php
@@ -0,0 +1,45 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\simpletest\Tests\SimpleTestWithLocaleTest.
+ */
+
+namespace Drupal\simpletest\Tests;
+
+use Drupal\simpletest\WebTestBase;
+
+/**
+ * Tests SimpleTest's when locale module is enabled.
+ *
+ * @group simpletest
+ */
+class SimpleTestWithLocaleTest extends WebTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = [
+    'simpletest',
+    'language',
+    'locale',
+  ];
+
+  /**
+   * Ensures the tests run well with locale enabled.
+   */
+  protected function testSimpleTestWithLanguageModule() {
+    $this->drupalLogin($this->drupalCreateUser(array('administer unit tests')));
+    $edit['tests[Drupal\simpletest\Tests\SimpleTestNoLocaleTest]'] = TRUE;
+    $this->drupalPostForm('admin/config/development/testing', $edit, t('Run tests'));
+    $this->assertRaw('0 exceptions');
+    $this->assertRaw('0 fails');
+    $this->assertText('successfully logged in.');
+    if (isset($this->xpath('//a[normalize-space(text())=:label]', array(':label' => 'the error page'))[0])) {
+      $this->clickLink('the error page');
+    }
+  }
+
+}
diff --git a/core/modules/system/src/Tests/Module/InstallUninstallTest.php b/core/modules/system/src/Tests/Module/InstallUninstallTest.php
index f50c68a..26319a1 100644
--- a/core/modules/system/src/Tests/Module/InstallUninstallTest.php
+++ b/core/modules/system/src/Tests/Module/InstallUninstallTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\system\Tests\Module;
 
+use Drupal\Component\Render\FormattableMarkup;
 use Drupal\Core\Logger\RfcLogLevel;
 
 /**
@@ -78,6 +79,7 @@ public function testInstallUninstall() {
     // Go through each module in the list and try to install and uninstall
     // it with its dependencies.
     while (list($name, $module) = each($all_modules)) {
+      debug("It's going to install: " . $name);
       $was_installed_list = \Drupal::moduleHandler()->getModuleList();
 
       // Start a list of modules that we expect to be installed this time.
@@ -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(('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;
   }
 
