diff --git a/core/core.api.php b/core/core.api.php
index 4b2fe62..11fa9d6 100644
--- a/core/core.api.php
+++ b/core/core.api.php
@@ -2236,6 +2236,61 @@ function hook_validation_constraint_alter(array &$definitions) {
 }
 
 /**
+ * Compute the plural variant index.
+ *
+ * Modules are implementing this hook in order to provide a way to compute the
+ * plural variant index for a certain combination of $count and $langcode.
+ * However, only the index provided by the most weighted module returning a
+ * valid value will be used in PluralTranslatableMarkup::getPluralIndex(). The
+ * implementation should return a valid zero-based positive integer or nothing,
+ * if he wants to pass the decision to core or other modules. Returning anything
+ * else than a zero or a positive integer will have the same effect as missing
+ * the return statement. See locale_plural_variant_index() for an example of
+ * using locale_get_plural() function to retrieve the plural variant index. You
+ * can provide your own implementation, in your custom module, when you don't
+ * want to enable the Locale module or you want to override the Locale module
+ * mechanism.
+ *
+ * @param int $count
+ *   The count value for which to retrieve the plural variant index.
+ * @param string|null $langcode
+ *   (optional) The code of the language to be checked. The implementation
+ *   should decide what to do if the language is missed or is invalid. For
+ *   example the Local module implementation locale_plural_variant_index() is
+ *   calling locale_get_plural() and that defaults to the current language.
+ *
+ * @return int|mixed
+ *   The zero-based numeric index of the plural variant to use for this $count
+ *   and $langcode combination. To avoid making a decision for a certain
+ *   combination just return nothing or any value that is not a zero or a
+ *   positive integer.
+ *
+ * @see \Drupal\Core\StringTranslation\PluralTranslatableMarkup::getPluralIndex()
+ * @see locale_plural_variant_index()
+ * @see locale_get_plural()
+ */
+function hook_plural_variant_index($count, $langcode = NULL) {
+  if ($langcode == 'en') {
+    return $count == 1 ? 0 : 1;
+  }
+  // The Romanian language has 3 plural variants.
+  elseif ($langcode == 'ro') {
+    if ($count == 1) {
+      return 0;
+    }
+    if ($count == 0 || ($count % 100 > 0 && $count % 100 < 20)) {
+      return 1;
+    }
+    return 2;
+  }
+  // In this implementation we ignore all other languages. Therefore we can
+  // return nothing or any value that is not a zero or positive integer.
+  // @code return -1; @endcode or @code return FALSE; @endcode or just omitting
+  // the return statement are the same and will pass the decision to core or
+  // other modules.
+}
+
+/**
  * @} End of "addtogroup hooks".
  */
 
diff --git a/core/lib/Drupal/Core/StringTranslation/PluralTranslatableMarkup.php b/core/lib/Drupal/Core/StringTranslation/PluralTranslatableMarkup.php
index 89e602f..df96fb3 100644
--- a/core/lib/Drupal/Core/StringTranslation/PluralTranslatableMarkup.php
+++ b/core/lib/Drupal/Core/StringTranslation/PluralTranslatableMarkup.php
@@ -145,15 +145,18 @@ public function render() {
    * @return int
    */
   protected function getPluralIndex() {
-    // We have to test both if the function and the service exist since in
-    // certain situations it is possible that locale code might be loaded but
-    // the service does not exist. For example, where the parent test site has
-    // locale installed but the child site does not.
-    // @todo Refactor in https://www.drupal.org/node/2660338 so this code does
-    // not depend on knowing that the Locale module exists.
-    if (function_exists('locale_get_plural') && \Drupal::hasService('locale.plural.formula')) {
-      return locale_get_plural($this->count, $this->getOption('langcode'));
+    $indexes = \Drupal::moduleHandler()
+      ->invokeAll('plural_variant_index', [$this->count, $this->getOption('langcode')]);
+
+    // Pickup index provided by the most weighted module returning a valid
+    // value.
+    while ($indexes) {
+      $index = array_pop($indexes);
+      if (is_integer($index) && $index >= 0) {
+        return $index;
+      }
     }
+    // Return -1 if no module has implemented valid plural formulas.
     return -1;
   }
 
diff --git a/core/modules/inline_form_errors/tests/src/Unit/FormErrorHandlerTest.php b/core/modules/inline_form_errors/tests/src/Unit/FormErrorHandlerTest.php
index 773b778..d489cbc 100644
--- a/core/modules/inline_form_errors/tests/src/Unit/FormErrorHandlerTest.php
+++ b/core/modules/inline_form_errors/tests/src/Unit/FormErrorHandlerTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\inline_form_errors\Unit;
 
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Form\FormState;
 use Drupal\Core\Render\RendererInterface;
 use Drupal\Core\Utility\LinkGeneratorInterface;
@@ -15,6 +17,16 @@
 class FormErrorHandlerTest extends UnitTestCase {
 
   /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $container = new ContainerBuilder();
+    $container->set('module_handler', $this->getMock(ModuleHandlerInterface::class));
+    \Drupal::setContainer($container);
+  }
+
+  /**
    * @covers ::handleFormErrors
    * @covers ::displayErrorMessages
    */
diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module
index aecad6c..d568959 100644
--- a/core/modules/locale/locale.module
+++ b/core/modules/locale/locale.module
@@ -308,6 +308,12 @@ function locale_get_plural($count, $langcode = NULL) {
   return $plural_indexes[$langcode][$count];
 }
 
+/**
+ * Implements hook_plural_variant_index().
+ */
+function locale_plural_variant_index($count, $langcode = NULL) {
+  return locale_get_plural($count, $langcode);
+}
 
 /**
  * Implements hook_modules_installed().
diff --git a/core/tests/Drupal/Tests/Core/Datetime/DateTest.php b/core/tests/Drupal/Tests/Core/Datetime/DateTest.php
index 238b5c8..8592da0 100644
--- a/core/tests/Drupal/Tests/Core/Datetime/DateTest.php
+++ b/core/tests/Drupal/Tests/Core/Datetime/DateTest.php
@@ -5,6 +5,7 @@
 use Drupal\Core\Datetime\DateFormatter;
 use Drupal\Core\Datetime\FormattedDateDiff;
 use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Tests\UnitTestCase;
 use Symfony\Component\HttpFoundation\Request;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
@@ -73,6 +74,7 @@ protected function setUp() {
     $container = new ContainerBuilder();
     $container->set('config.factory', $config_factory);
     $container->set('string_translation', $this->getStringTranslationStub());
+    $container->set('module_handler', $this->getMock(ModuleHandlerInterface::class));
     \Drupal::setContainer($container);
 
     $this->dateFormatter = new DateFormatter($this->entityManager, $this->languageManager, $this->stringTranslation, $this->getConfigFactoryStub(), $this->requestStack);
diff --git a/core/tests/Drupal/Tests/Core/Entity/EntityTypeTest.php b/core/tests/Drupal/Tests/Core/Entity/EntityTypeTest.php
index 8ee7478..c96eb20 100644
--- a/core/tests/Drupal/Tests/Core/Entity/EntityTypeTest.php
+++ b/core/tests/Drupal/Tests/Core/Entity/EntityTypeTest.php
@@ -2,8 +2,10 @@
 
 namespace Drupal\Tests\Core\Entity;
 
+use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Core\Entity\EntityType;
 use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\Tests\UnitTestCase;
 
@@ -14,6 +16,16 @@
 class EntityTypeTest extends UnitTestCase {
 
   /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $container = new ContainerBuilder();
+    $container->set('module_handler', $this->getMock(ModuleHandlerInterface::class));
+    \Drupal::setContainer($container);
+  }
+
+  /**
    * Sets up an EntityType object for a given set of values.
    *
    * @param array $definition
diff --git a/core/tests/Drupal/Tests/Core/StringTranslation/StringTranslationTraitTest.php b/core/tests/Drupal/Tests/Core/StringTranslation/StringTranslationTraitTest.php
index 560675e..47f1bba 100644
--- a/core/tests/Drupal/Tests/Core/StringTranslation/StringTranslationTraitTest.php
+++ b/core/tests/Drupal/Tests/Core/StringTranslation/StringTranslationTraitTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\Core\StringTranslation;
 
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\StringTranslation\PluralTranslatableMarkup;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\Core\StringTranslation\TranslationInterface;
@@ -42,6 +44,10 @@ protected function setUp() {
     });
     $this->translation->setStringTranslation($mock->reveal());
     $this->reflection = new \ReflectionClass(get_class($this->translation));
+
+    $container = new ContainerBuilder();
+    $container->set('module_handler', $this->getMock(ModuleHandlerInterface::class));
+    \Drupal::setContainer($container);
   }
 
   /**
diff --git a/core/tests/Drupal/Tests/Core/StringTranslation/TranslationManagerTest.php b/core/tests/Drupal/Tests/Core/StringTranslation/TranslationManagerTest.php
index 8ab6874..619447b 100644
--- a/core/tests/Drupal/Tests/Core/StringTranslation/TranslationManagerTest.php
+++ b/core/tests/Drupal/Tests/Core/StringTranslation/TranslationManagerTest.php
@@ -8,6 +8,8 @@
 namespace Drupal\Tests\Core\StringTranslation;
 
 use Drupal\Component\Render\MarkupInterface;
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\StringTranslation\TranslationManager;
 use Drupal\Tests\UnitTestCase;
 
@@ -28,7 +30,11 @@ class TranslationManagerTest extends UnitTestCase {
    * {@inheritdoc}
    */
   protected function setUp() {
+    parent::setUp();
     $this->translationManager = new TestTranslationManager();
+    $container = new ContainerBuilder();
+    $container->set('module_handler', $this->getMock(ModuleHandlerInterface::class));
+    \Drupal::setContainer($container);
   }
 
   /**
diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php
old mode 100644
new mode 100755
