From 154f2828998659a864349234106ad02bda1479e2 Mon Sep 17 00:00:00 2001
From: Nathaniel Catchpole <catch@35733.no-reply.drupal.org>
Date: Tue, 8 May 2018 17:23:11 +0100
Subject: [PATCH] Issue #2849669 by alexpott, pwolanin, Munavijayalakshmi,
 dawehner: Fix \Drupal\Component\Utility\Unicode() because of the Symfony
 mbstring polyfill

---
 core/includes/common.inc                      |   2 +-
 core/includes/file.inc                        |   3 +-
 core/includes/theme.inc                       |   3 +-
 core/includes/theme.maintenance.inc           |   2 -
 .../Component/Diff/Engine/DiffEngine.php      |   4 +-
 .../Diff/Engine/HWLDFWordAccumulator.php      |   4 +-
 .../Drupal/Component/Diff/WordLevelDiff.php   |   3 +-
 core/lib/Drupal/Component/Diff/composer.json  |   2 +-
 .../Component/Render/FormattableMarkup.php    |   3 +-
 .../Component/Render/HtmlEscapedText.php      |   3 +-
 .../Drupal/Component/Render/MarkupTrait.php   |   4 +-
 core/lib/Drupal/Component/Utility/Color.php   |   2 +-
 core/lib/Drupal/Component/Utility/Html.php    |   4 +-
 core/lib/Drupal/Component/Utility/Unicode.php | 228 +++++-------------
 .../Drupal/Component/Utility/composer.json    |   4 +-
 core/lib/Drupal/Core/Asset/CssOptimizer.php   |   2 +-
 core/lib/Drupal/Core/Asset/JsOptimizer.php    |   2 +-
 core/lib/Drupal/Core/Block/BlockBase.php      |   3 +-
 .../Drupal/Core/Config/ConfigInstaller.php    |   3 +-
 .../Core/Config/Entity/Query/Condition.php    |   7 +-
 .../Core/Database/Driver/mysql/Schema.php     |   2 +-
 .../Core/Database/Driver/pgsql/Schema.php     |   3 +-
 .../Core/Database/Driver/sqlite/Schema.php    |   3 +-
 .../Drupal/Core/Database/Query/Condition.php  |   3 +-
 core/lib/Drupal/Core/DrupalKernel.php         |   6 +-
 core/lib/Drupal/Core/Entity/Entity.php        |   3 +-
 core/lib/Drupal/Core/Entity/EntityType.php    |   5 +-
 .../EntityReferenceSelection/PhpSelection.php |   9 +-
 .../Field/Plugin/Field/FieldType/UriItem.php  |   3 +-
 core/lib/Drupal/Core/Form/FormValidator.php   |   7 +-
 core/lib/Drupal/Core/GeneratedLink.php        |   3 +-
 .../lib/Drupal/Core/Mail/MailFormatHelper.php |   7 +-
 .../Discovery/AnnotatedClassDiscovery.php     |   3 +-
 .../lib/Drupal/Core/Routing/CompiledRoute.php |   3 +-
 .../lib/Drupal/Core/Routing/RouteProvider.php |   3 +-
 .../StringTranslation/TranslatableMarkup.php  |   3 +-
 .../TypedData/Plugin/DataType/ItemList.php    |   2 +-
 .../Core/TypedData/Plugin/DataType/Map.php    |   2 +-
 core/lib/Drupal/Core/Updater/Updater.php      |   3 +-
 .../Constraint/UniqueFieldValueValidator.php  |   3 +-
 .../src/Functional/BlockHookOperationTest.php |   3 +-
 .../src/Functional/BlockLanguageCacheTest.php |   3 +-
 .../Functional/BlockContentCreationTest.php   |   5 +-
 .../BlockContentTranslationUITest.php         |   3 +-
 .../tests/src/Functional/PageEditTest.php     |   3 +-
 core/modules/color/color.module               |   5 +-
 .../src/Functional/CommentInterfaceTest.php   |   3 +-
 .../src/Kernel/CommentIntegrationTest.php     |   5 +-
 .../Functional/ConfigExportImportUITest.php   |   3 +-
 .../ConfigTranslationFieldListBuilder.php     |   3 +-
 .../ConfigTranslationContextualLink.php       |   3 +-
 .../LocalTask/ConfigTranslationLocalTask.php  |   3 +-
 .../ConfigTranslationListUiTest.php           |  21 +-
 .../Functional/ConfigTranslationUiTest.php    |   3 +-
 .../contact/src/ContactFormEditForm.php       |   3 +-
 .../src/Functional/ContactSitewideTest.php    |  15 +-
 .../src/Functional/ContactStorageTest.php     |   3 +-
 .../datetime/src/Tests/DateTestBase.php       |   3 +-
 .../tests/src/Functional/DateTestBase.php     |   4 +-
 .../src/Functional/DateTimeFieldTest.php      |   5 +-
 .../src/Functional/DateRangeFieldTest.php     |   5 +-
 .../tests/src/Kernel/DateRangeItemTest.php    |   3 +-
 .../src/Kernel/SeparatorTranslationTest.php   |   3 +-
 core/modules/dblog/src/Logger/DbLog.php       |   5 +-
 .../dblog/tests/src/Functional/DbLogTest.php  |   2 +-
 .../editor/src/Tests/EditorAdminTest.php      |   3 +-
 .../Kernel/EditorFilterIntegrationTest.php    |   3 +-
 .../field/src/Entity/FieldStorageConfig.php   |   9 +-
 .../Boolean/BooleanFormatterSettingsTest.php  |   5 +-
 .../field/src/Tests/Email/EmailFieldTest.php  |   3 +-
 .../EntityReferenceAdminTest.php              |   3 +-
 .../src/Tests/Number/NumberFieldTest.php      |  17 +-
 .../src/Tests/String/StringFieldTest.php      |   3 +-
 .../Functional/Boolean/BooleanFieldTest.php   |   3 +-
 .../EntityReferenceAutoCreateTest.php         |   5 +-
 .../EntityReferenceFieldDefaultValueTest.php  |   5 +-
 .../src/Functional/TranslationWebTest.php     |   3 +-
 .../Kernel/Boolean/BooleanFormatterTest.php   |   3 +-
 .../EntityReferenceItemTest.php               |   7 +-
 .../EntityReferenceSettingsTest.php           |  11 +-
 .../src/Kernel/FieldAttachStorageTest.php     |   7 +-
 .../field/tests/src/Kernel/FieldCrudTest.php  |   5 +-
 .../tests/src/Kernel/FieldKernelTestBase.php  |   3 +-
 .../Kernel/String/RawStringFormatterTest.php  |   3 +-
 .../src/Kernel/String/StringFormatterTest.php |   3 +-
 .../Timestamp/TimestampFormatterTest.php      |   3 +-
 .../tests/src/Kernel/TranslationTest.php      |   5 +-
 .../tests/src/Kernel/Uri/UriItemTest.php      |   3 +-
 .../field_ui/src/Tests/ManageDisplayTest.php  |   3 +-
 .../tests/src/Kernel/EntityDisplayTest.php    |   5 +-
 .../Plugin/migrate/destination/EntityFile.php |   3 +-
 .../file/src/Tests/FileFieldWidgetTest.php    |   3 +-
 .../Formatter/FileMediaFormatterTestBase.php  |   3 +-
 core/modules/filter/filter.module             |   6 +-
 .../src/Plugin/Filter/FilterCaption.php       |   3 +-
 .../tests/src/Functional/FilterAdminTest.php  |   9 +-
 .../Functional/FilterDefaultFormatTest.php    |   3 +-
 .../src/Functional/FilterFormatAccessTest.php |   3 +-
 .../tests/src/Functional/FilterHooksTest.php  |   3 +-
 core/modules/image/image.field.inc            |   3 +-
 core/modules/image/src/Entity/ImageStyle.php  |   3 +-
 .../Plugin/ImageEffect/ConvertImageEffect.php |   5 +-
 .../ImageFieldDefaultImagesTest.php           |   3 +-
 .../tests/src/Kernel/ImageFormatterTest.php   |   3 +-
 .../src/Form/NegotiationConfigureForm.php     |   5 +-
 .../tests/src/Functional/LinkFieldTest.php    |  10 +-
 .../src/Functional/MenuUiLanguageTest.php     |   3 +-
 .../tests/src/Functional/MenuUiTest.php       |   5 +-
 .../migrate/src/Plugin/migrate/id_map/Sql.php |   9 +-
 .../Plugin/migrate/process/MakeUniqueBase.php |   3 +-
 .../src/Plugin/migrate/process/Substr.php     |   6 +-
 .../tests/src/Unit/process/CallbackTest.php   |  17 +-
 .../src/Unit/process/DedupeEntityTest.php     |   3 +-
 .../process/MakeUniqueEntityFieldTest.php     |   3 +-
 .../node/src/Tests/PagePreviewTest.php        |   3 +-
 .../MultiStepNodeFormBasicOptionsTest.php     |   3 +-
 .../src/Functional/NodeAccessFieldTest.php    |   3 +-
 .../Functional/NodeTypeTranslationTest.php    |   7 +-
 .../tests/src/Kernel/SummaryLengthTest.php    |   4 -
 .../Plugin/Field/FieldType/ListStringItem.php |   3 +-
 .../tests/src/Functional/PathAliasTest.php    |   9 +-
 .../src/Tests/QuickEditLoadingTest.php        |   9 +-
 .../responsive_image/responsive_image.module  |   5 +-
 .../Tests/ResponsiveImageFieldDisplayTest.php |   9 +-
 core/modules/search/search.module             |  27 +--
 core/modules/search/src/SearchQuery.php       |   3 +-
 .../src/Functional/SearchSimplifyTest.php     |   8 +-
 .../src/Functional/SearchTokenizerTest.php    |   4 +-
 .../EntityAutocompleteController.php          |   3 +-
 .../system/src/MachineNameController.php      |   3 +-
 .../src/Plugin/Condition/RequestPath.php      |   5 +-
 .../src/Plugin/ImageToolkit/GDToolkit.php     |   3 +-
 .../src/Plugin/ImageToolkit/TestToolkit.php   |   3 +-
 .../src/Functional/Mail/HtmlToTextTest.php    |  11 +-
 .../Module/PrepareUninstallTest.php           |   5 +-
 .../System/DateFormatsMachineNameTest.php     |   3 +-
 ...ityReferenceSelectionReferenceableTest.php |   9 +-
 .../taxonomy/src/Tests/TaxonomyTestTrait.php  |   3 +-
 .../src/Tests/TermAutocompleteTest.php        |   3 +-
 core/modules/taxonomy/src/Tests/TermTest.php  |   3 +-
 .../src/Functional/TaxonomyTestTrait.php      |   3 +-
 .../tests/src/Functional/TermIndexTest.php    |   5 +-
 .../Functional/Views/TaxonomyTermViewTest.php |   3 +-
 .../src/Functional/VocabularyCrudTest.php     |   3 +-
 .../src/Functional/VocabularyLanguageTest.php |   5 +-
 .../Functional/VocabularyTranslationTest.php  |   4 +-
 .../tests/src/Functional/VocabularyUiTest.php |   6 +-
 core/modules/text/src/Tests/TextFieldTest.php |   7 +-
 core/modules/text/text.module                 |   2 +-
 core/modules/update/update.report.inc         |   3 +-
 .../UserNameConstraintValidator.php           |   3 +-
 .../Plugin/migrate/destination/EntityUser.php |   5 +-
 core/modules/user/user.module                 |   2 +-
 .../views/src/Plugin/views/HandlerBase.php    |   4 +-
 .../Plugin/views/argument/StringArgument.php  |   3 +-
 .../Plugin/views/field/FieldPluginBase.php    |   7 +-
 .../src/Plugin/views/filter/InOperator.php    |   2 +-
 core/modules/views/src/ViewsDataHelper.php    |   9 +-
 .../tests/src/Functional/DefaultViewsTest.php |   5 +-
 .../tests/src/Functional/GlossaryTest.php     |   3 +-
 .../src/Functional/Handler/FieldWebTest.php   |   3 +-
 .../Plugin/ExposedFormCheckboxesTest.php      |   3 +-
 .../Entity/ViewEntityDependenciesTest.php     |   3 +-
 core/modules/views_ui/views_ui.module         |   5 +-
 .../Core/Asset/AttachedAssetsTest.php         |   3 +-
 .../Core/Config/ConfigImportRecreateTest.php  |   3 +-
 .../ConfigImportRenameValidationTest.php      |   3 +-
 .../Core/Entity/EntityLanguageTestBase.php    |   5 +-
 .../Entity/EntityQueryRelationshipTest.php    |   3 +-
 .../Core/Entity/EntityQueryTest.php           |  17 +-
 .../Core/Entity/FieldSqlStorageTest.php       |   3 +-
 .../KernelTests/Core/Field/FieldItemTest.php  |   3 +-
 .../Core/Field/FieldMissingTypeTest.php       |   3 +-
 .../Core/Routing/RouteProviderTest.php        |   4 +-
 .../Tests/Component/Utility/UnicodeTest.php   | 132 +++-------
 core/tests/bootstrap.php                      |   4 +
 176 files changed, 419 insertions(+), 734 deletions(-)

diff --git a/core/includes/common.inc b/core/includes/common.inc
index 04324f60fcf2..de294dfe394c 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -46,7 +46,7 @@
  *
  * Correct:
  * @code
- *   $my_substring = Unicode::substr($original_string, 0, 5);
+ *   $my_substring = mb_substr($original_string, 0, 5);
  * @endcode
  *
  * @}
diff --git a/core/includes/file.inc b/core/includes/file.inc
index 83df3a2b54b2..5d7837208188 100644
--- a/core/includes/file.inc
+++ b/core/includes/file.inc
@@ -6,7 +6,6 @@
  */
 
 use Drupal\Component\FileSystem\FileSystem as ComponentFileSystem;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Component\Utility\UrlHelper;
 use Drupal\Component\PhpStorage\FileStorage;
 use Drupal\Component\Utility\Bytes;
@@ -202,7 +201,7 @@ function file_create_url($uri) {
     //   HTTP and to https://example.com/bar.jpg when viewing a HTTPS page)
     // Both types of relative URIs are characterized by a leading slash, hence
     // we can use a single check.
-    if (Unicode::substr($uri, 0, 1) == '/') {
+    if (mb_substr($uri, 0, 1) == '/') {
       return $uri;
     }
     else {
diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index ac085b4c9768..a6fffa76ae20 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -12,7 +12,6 @@
 use Drupal\Component\Utility\Crypt;
 use Drupal\Component\Utility\Html;
 use Drupal\Component\Render\MarkupInterface;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Cache\CacheableDependencyInterface;
 use Drupal\Core\Config\Config;
 use Drupal\Core\Config\StorageException;
@@ -485,7 +484,7 @@ function theme_settings_convert_to_config(array $theme_settings, Config $config)
       $config->set('favicon.mimetype', $value);
     }
     elseif (substr($key, 0, 7) == 'toggle_') {
-      $config->set('features.' . Unicode::substr($key, 7), $value);
+      $config->set('features.' . mb_substr($key, 7), $value);
     }
     elseif (!in_array($key, ['theme', 'logo_upload'])) {
       $config->set($key, $value);
diff --git a/core/includes/theme.maintenance.inc b/core/includes/theme.maintenance.inc
index 80cc52cb8112..310c9cd858a3 100644
--- a/core/includes/theme.maintenance.inc
+++ b/core/includes/theme.maintenance.inc
@@ -5,7 +5,6 @@
  * Theming for maintenance pages.
  */
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Site\Settings;
 
 /**
@@ -29,7 +28,6 @@ function _drupal_maintenance_theme() {
   require_once __DIR__ . '/file.inc';
   require_once __DIR__ . '/module.inc';
   require_once __DIR__ . '/database.inc';
-  Unicode::check();
 
   // Install and update pages are treated differently to prevent theming overrides.
   if (defined('MAINTENANCE_MODE') && (MAINTENANCE_MODE == 'install' || MAINTENANCE_MODE == 'update')) {
diff --git a/core/lib/Drupal/Component/Diff/Engine/DiffEngine.php b/core/lib/Drupal/Component/Diff/Engine/DiffEngine.php
index 27b0f325724b..34c01f36593d 100644
--- a/core/lib/Drupal/Component/Diff/Engine/DiffEngine.php
+++ b/core/lib/Drupal/Component/Diff/Engine/DiffEngine.php
@@ -2,8 +2,6 @@
 
 namespace Drupal\Component\Diff\Engine;
 
-use Drupal\Component\Utility\Unicode;
-
 /**
  * Class used internally by Diff to actually compute the diffs.
  *
@@ -134,7 +132,7 @@ public function diff($from_lines, $to_lines) {
    * Returns the whole line if it's small enough, or the MD5 hash otherwise.
    */
   protected function _line_hash($line) {
-    if (Unicode::strlen($line) > $this::MAX_XREF_LENGTH) {
+    if (mb_strlen($line) > $this::MAX_XREF_LENGTH) {
       return md5($line);
     }
     else {
diff --git a/core/lib/Drupal/Component/Diff/Engine/HWLDFWordAccumulator.php b/core/lib/Drupal/Component/Diff/Engine/HWLDFWordAccumulator.php
index eb7d9434c963..98d430cfcc5c 100644
--- a/core/lib/Drupal/Component/Diff/Engine/HWLDFWordAccumulator.php
+++ b/core/lib/Drupal/Component/Diff/Engine/HWLDFWordAccumulator.php
@@ -2,8 +2,6 @@
 
 namespace Drupal\Component\Diff\Engine;
 
-use Drupal\Component\Utility\Unicode;
-
 /**
  * Additions by Axel Boldt follow, partly taken from diff.php, phpwiki-1.3.3
  */
@@ -64,7 +62,7 @@ public function addWords($words, $tag = '') {
       }
       if ($word[0] == "\n") {
         $this->_flushLine($tag);
-        $word = Unicode::substr($word, 1);
+        $word = mb_substr($word, 1);
       }
       assert(!strstr($word, "\n"));
       $this->group .= $word;
diff --git a/core/lib/Drupal/Component/Diff/WordLevelDiff.php b/core/lib/Drupal/Component/Diff/WordLevelDiff.php
index a8c2f80f256e..66c6e1a90f2c 100644
--- a/core/lib/Drupal/Component/Diff/WordLevelDiff.php
+++ b/core/lib/Drupal/Component/Diff/WordLevelDiff.php
@@ -3,7 +3,6 @@
 namespace Drupal\Component\Diff;
 
 use Drupal\Component\Diff\Engine\HWLDFWordAccumulator;
-use Drupal\Component\Utility\Unicode;
 
 /**
  * @todo document
@@ -35,7 +34,7 @@ protected function _split($lines) {
         $words[] = "\n";
         $stripped[] = "\n";
       }
-      if (Unicode::strlen($line) > $this::MAX_LINE_LENGTH) {
+      if (mb_strlen($line) > $this::MAX_LINE_LENGTH) {
         $words[] = $line;
         $stripped[] = $line;
       }
diff --git a/core/lib/Drupal/Component/Diff/composer.json b/core/lib/Drupal/Component/Diff/composer.json
index fc9e1cd675ee..b3016084a204 100644
--- a/core/lib/Drupal/Component/Diff/composer.json
+++ b/core/lib/Drupal/Component/Diff/composer.json
@@ -6,7 +6,7 @@
   "license": "GPL-2.0-or-later",
   "require": {
     "php": ">=5.5.9",
-    "drupal/core-utility": "^8.2"
+    "symfony/polyfill-mbstring": "~1.0"
   },
   "autoload": {
     "psr-4": {
diff --git a/core/lib/Drupal/Component/Render/FormattableMarkup.php b/core/lib/Drupal/Component/Render/FormattableMarkup.php
index 1b91b9d93a83..2bad2ec8c511 100644
--- a/core/lib/Drupal/Component/Render/FormattableMarkup.php
+++ b/core/lib/Drupal/Component/Render/FormattableMarkup.php
@@ -3,7 +3,6 @@
 namespace Drupal\Component\Render;
 
 use Drupal\Component\Utility\Html;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Component\Utility\UrlHelper;
 
 /**
@@ -107,7 +106,7 @@ public function __toString() {
    *   The length of the string.
    */
   public function count() {
-    return Unicode::strlen($this->string);
+    return mb_strlen($this->string);
   }
 
   /**
diff --git a/core/lib/Drupal/Component/Render/HtmlEscapedText.php b/core/lib/Drupal/Component/Render/HtmlEscapedText.php
index b286f572e08e..0ddc4fa4c500 100644
--- a/core/lib/Drupal/Component/Render/HtmlEscapedText.php
+++ b/core/lib/Drupal/Component/Render/HtmlEscapedText.php
@@ -3,7 +3,6 @@
 namespace Drupal\Component\Render;
 
 use Drupal\Component\Utility\Html;
-use Drupal\Component\Utility\Unicode;
 
 /**
  * Escapes HTML syntax characters to HTML entities for display in markup.
@@ -43,7 +42,7 @@ public function __toString() {
    * {@inheritdoc}
    */
   public function count() {
-    return Unicode::strlen($this->string);
+    return mb_strlen($this->string);
   }
 
   /**
diff --git a/core/lib/Drupal/Component/Render/MarkupTrait.php b/core/lib/Drupal/Component/Render/MarkupTrait.php
index 59e98c3730ca..c7faa81abae7 100644
--- a/core/lib/Drupal/Component/Render/MarkupTrait.php
+++ b/core/lib/Drupal/Component/Render/MarkupTrait.php
@@ -2,8 +2,6 @@
 
 namespace Drupal\Component\Render;
 
-use Drupal\Component\Utility\Unicode;
-
 /**
  * Implements MarkupInterface and Countable for rendered objects.
  *
@@ -61,7 +59,7 @@ public function __toString() {
    *   The length of the string.
    */
   public function count() {
-    return Unicode::strlen($this->string);
+    return mb_strlen($this->string);
   }
 
   /**
diff --git a/core/lib/Drupal/Component/Utility/Color.php b/core/lib/Drupal/Component/Utility/Color.php
index e3cb56bc9269..ff06f39f4132 100644
--- a/core/lib/Drupal/Component/Utility/Color.php
+++ b/core/lib/Drupal/Component/Utility/Color.php
@@ -23,7 +23,7 @@ public static function validateHex($hex) {
     // Hash prefix is optional.
     $hex = ltrim($hex, '#');
     // Must be either RGB or RRGGBB.
-    $length = Unicode::strlen($hex);
+    $length = mb_strlen($hex);
     $valid = $valid && ($length === 3 || $length === 6);
     // Must be a valid hex value.
     $valid = $valid && ctype_xdigit($hex);
diff --git a/core/lib/Drupal/Component/Utility/Html.php b/core/lib/Drupal/Component/Utility/Html.php
index 353dac280ed5..5beee495b980 100644
--- a/core/lib/Drupal/Component/Utility/Html.php
+++ b/core/lib/Drupal/Component/Utility/Html.php
@@ -71,7 +71,7 @@ class Html {
   public static function getClass($class) {
     $class = (string) $class;
     if (!isset(static::$classes[$class])) {
-      static::$classes[$class] = static::cleanCssIdentifier(Unicode::strtolower($class));
+      static::$classes[$class] = static::cleanCssIdentifier(mb_strtolower($class));
     }
     return static::$classes[$class];
   }
@@ -215,7 +215,7 @@ public static function getUniqueId($id) {
    * @see self::getUniqueId()
    */
   public static function getId($id) {
-    $id = str_replace([' ', '_', '[', ']'], ['-', '-', '-', ''], Unicode::strtolower($id));
+    $id = str_replace([' ', '_', '[', ']'], ['-', '-', '-', ''], mb_strtolower($id));
 
     // As defined in http://www.w3.org/TR/html4/types.html#type-name, HTML IDs can
     // only contain letters, digits ([0-9]), hyphens ("-"), underscores ("_"),
diff --git a/core/lib/Drupal/Component/Utility/Unicode.php b/core/lib/Drupal/Component/Utility/Unicode.php
index e136a8971b7a..7cf2351603d3 100644
--- a/core/lib/Drupal/Component/Utility/Unicode.php
+++ b/core/lib/Drupal/Component/Utility/Unicode.php
@@ -87,13 +87,6 @@ class Unicode {
    */
   const STATUS_ERROR = -1;
 
-  /**
-   * Holds the multibyte capabilities of the current environment.
-   *
-   * @var int
-   */
-  protected static $status = 0;
-
   /**
    * Gets the current status of unicode/multibyte support on this environment.
    *
@@ -107,7 +100,13 @@ class Unicode {
    *     An error occurred. No unicode support.
    */
   public static function getStatus() {
-    return static::$status;
+    switch (static::check()) {
+      case 'mb_strlen':
+        return Unicode::STATUS_SINGLEBYTE;
+      case '':
+        return Unicode::STATUS_MULTIBYTE;
+    }
+    return Unicode::STATUS_ERROR;
   }
 
   /**
@@ -123,12 +122,16 @@ public static function getStatus() {
    *
    * @param int $status
    *   The new status of multibyte support.
+   *
+   * @deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. In
+   *   Drupal 9 there will be no way to set the status and in Drupal 8 this
+   *   ability has been removed because mb_*() functions are supplied using
+   *   Symfony's polyfill.
+   *
+   * @see https://www.drupal.org/node/2850048
    */
   public static function setStatus($status) {
-    if (!in_array($status, [static::STATUS_SINGLEBYTE, static::STATUS_MULTIBYTE, static::STATUS_ERROR])) {
-      throw new \InvalidArgumentException('Invalid status value for unicode support.');
-    }
-    static::$status = $status;
+    @trigger_error('\Drupal\Component\Utility\Unicode::setStatus() is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. In Drupal 9 there will be no way to set the status and in Drupal 8 this ability has been removed because mb_*() functions are supplied using Symfony\'s polyfill. See https://www.drupal.org/node/2850048.', E_USER_DEPRECATED);
   }
 
   /**
@@ -143,38 +146,33 @@ public static function setStatus($status) {
    *   Otherwise, an empty string.
    */
   public static function check() {
+    // Set appropriate configuration.
+    mb_internal_encoding('utf-8');
+    mb_language('uni');
+
     // Check for mbstring extension.
-    if (!function_exists('mb_strlen')) {
-      static::$status = static::STATUS_SINGLEBYTE;
+    if (!extension_loaded('mbstring')) {
       return 'mb_strlen';
     }
 
     // Check mbstring configuration.
     if (ini_get('mbstring.func_overload') != 0) {
-      static::$status = static::STATUS_ERROR;
       return 'mbstring.func_overload';
     }
     if (ini_get('mbstring.encoding_translation') != 0) {
-      static::$status = static::STATUS_ERROR;
       return 'mbstring.encoding_translation';
     }
     // mbstring.http_input and mbstring.http_output are deprecated and empty by
     // default in PHP 5.6.
     if (version_compare(PHP_VERSION, '5.6.0') == -1) {
       if (ini_get('mbstring.http_input') != 'pass') {
-        static::$status = static::STATUS_ERROR;
         return 'mbstring.http_input';
       }
       if (ini_get('mbstring.http_output') != 'pass') {
-        static::$status = static::STATUS_ERROR;
         return 'mbstring.http_output';
       }
     }
 
-    // Set appropriate configuration.
-    mb_internal_encoding('utf-8');
-    mb_language('uni');
-    static::$status = static::STATUS_MULTIBYTE;
     return '';
   }
 
@@ -224,17 +222,7 @@ public static function encodingFromBOM($data) {
    *   Converted data or FALSE.
    */
   public static function convertToUtf8($data, $encoding) {
-    if (function_exists('iconv')) {
-      return @iconv($encoding, 'utf-8', $data);
-    }
-    elseif (function_exists('mb_convert_encoding')) {
-      return @mb_convert_encoding($data, 'utf-8', $encoding);
-    }
-    elseif (function_exists('recode_string')) {
-      return @recode_string($encoding . '..utf-8', $data);
-    }
-    // Cannot convert.
-    return FALSE;
+    return @iconv($encoding, 'utf-8', $data);
   }
 
   /**
@@ -281,15 +269,15 @@ public static function truncateBytes($string, $len) {
    *
    * @return int
    *   The length of the string.
+   *
+   * @deprecated in Drupal 8.6.0, will be removed before Drupal 9.0.0. Use
+   *   mb_strlen() instead.
+   *
+   * @see https://www.drupal.org/node/2850048
    */
   public static function strlen($text) {
-    if (static::getStatus() == static::STATUS_MULTIBYTE) {
-      return mb_strlen($text);
-    }
-    else {
-      // Do not count UTF-8 continuation bytes.
-      return strlen(preg_replace("/[\x80-\xBF]/", '', $text));
-    }
+    @trigger_error('\Drupal\Component\Utility\Unicode::strlen() is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. Use mb_strlen() instead. See https://www.drupal.org/node/2850048.', E_USER_DEPRECATED);
+    return mb_strlen($text);
   }
 
   /**
@@ -300,18 +288,15 @@ public static function strlen($text) {
    *
    * @return string
    *   The string in uppercase.
+   *
+   * @deprecated in Drupal 8.6.0, will be removed before Drupal 9.0.0. Use
+   *   mb_strtoupper() instead.
+   *
+   * @see https://www.drupal.org/node/2850048
    */
   public static function strtoupper($text) {
-    if (static::getStatus() == static::STATUS_MULTIBYTE) {
-      return mb_strtoupper($text);
-    }
-    else {
-      // Use C-locale for ASCII-only uppercase.
-      $text = strtoupper($text);
-      // Case flip Latin-1 accented letters.
-      $text = preg_replace_callback('/\xC3[\xA0-\xB6\xB8-\xBE]/', '\Drupal\Component\Utility\Unicode::caseFlip', $text);
-      return $text;
-    }
+    @trigger_error('\Drupal\Component\Utility\Unicode::strtoupper() is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. Use mb_strtoupper() instead. See https://www.drupal.org/node/2850048.', E_USER_DEPRECATED);
+    return mb_strtoupper($text);
   }
 
   /**
@@ -322,18 +307,15 @@ public static function strtoupper($text) {
    *
    * @return string
    *   The string in lowercase.
+   *
+   * @deprecated in Drupal 8.6.0, will be removed before Drupal 9.0.0. Use
+   *   mb_strtolower() instead.
+   *
+   * @see https://www.drupal.org/node/2850048
    */
   public static function strtolower($text) {
-    if (static::getStatus() == static::STATUS_MULTIBYTE) {
-      return mb_strtolower($text);
-    }
-    else {
-      // Use C-locale for ASCII-only lowercase.
-      $text = strtolower($text);
-      // Case flip Latin-1 accented letters.
-      $text = preg_replace_callback('/\xC3[\x80-\x96\x98-\x9E]/', '\Drupal\Component\Utility\Unicode::caseFlip', $text);
-      return $text;
-    }
+    @trigger_error('\Drupal\Component\Utility\Unicode::strtolower() is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. Use mb_strtolower() instead. See https://www.drupal.org/node/2850048.', E_USER_DEPRECATED);
+    return mb_strtolower($text);
   }
 
   /**
@@ -346,7 +328,7 @@ public static function strtolower($text) {
    *   The string with the first character as uppercase.
    */
   public static function ucfirst($text) {
-    return static::strtoupper(static::substr($text, 0, 1)) . static::substr($text, 1);
+    return mb_strtoupper(mb_substr($text, 0, 1)) . mb_substr($text, 1);
   }
 
   /**
@@ -362,7 +344,7 @@ public static function ucfirst($text) {
    */
   public static function lcfirst($text) {
     // Note: no mbstring equivalent!
-    return static::strtolower(static::substr($text, 0, 1)) . static::substr($text, 1);
+    return mb_strtolower(mb_substr($text, 0, 1)) . mb_substr($text, 1);
   }
 
   /**
@@ -379,7 +361,7 @@ public static function lcfirst($text) {
   public static function ucwords($text) {
     $regex = '/(^|[' . static::PREG_CLASS_WORD_BOUNDARY . '])([^' . static::PREG_CLASS_WORD_BOUNDARY . '])/u';
     return preg_replace_callback($regex, function (array $matches) {
-      return $matches[1] . Unicode::strtoupper($matches[2]);
+      return $matches[1] . mb_strtoupper($matches[2]);
     }, $text);
   }
 
@@ -399,92 +381,15 @@ public static function ucwords($text) {
    *
    * @return string
    *   The shortened string.
+   *
+   * @deprecated in Drupal 8.6.0, will be removed before Drupal 9.0.0. Use
+   *   mb_substr() instead.
+   *
+   * @see https://www.drupal.org/node/2850048
    */
   public static function substr($text, $start, $length = NULL) {
-    if (static::getStatus() == static::STATUS_MULTIBYTE) {
-      return $length === NULL ? mb_substr($text, $start) : mb_substr($text, $start, $length);
-    }
-    else {
-      $strlen = strlen($text);
-      // Find the starting byte offset.
-      $bytes = 0;
-      if ($start > 0) {
-        // Count all the characters except continuation bytes from the start
-        // until we have found $start characters or the end of the string.
-        $bytes = -1; $chars = -1;
-        while ($bytes < $strlen - 1 && $chars < $start) {
-          $bytes++;
-          $c = ord($text[$bytes]);
-          if ($c < 0x80 || $c >= 0xC0) {
-            $chars++;
-          }
-        }
-      }
-      elseif ($start < 0) {
-        // Count all the characters except continuation bytes from the end
-        // until we have found abs($start) characters.
-        $start = abs($start);
-        $bytes = $strlen; $chars = 0;
-        while ($bytes > 0 && $chars < $start) {
-          $bytes--;
-          $c = ord($text[$bytes]);
-          if ($c < 0x80 || $c >= 0xC0) {
-            $chars++;
-          }
-        }
-      }
-      $istart = $bytes;
-
-      // Find the ending byte offset.
-      if ($length === NULL) {
-        $iend = $strlen;
-      }
-      elseif ($length > 0) {
-        // Count all the characters except continuation bytes from the starting
-        // index until we have found $length characters or reached the end of
-        // the string, then backtrace one byte.
-        $iend = $istart - 1;
-        $chars = -1;
-        $last_real = FALSE;
-        while ($iend < $strlen - 1 && $chars < $length) {
-          $iend++;
-          $c = ord($text[$iend]);
-          $last_real = FALSE;
-          if ($c < 0x80 || $c >= 0xC0) {
-            $chars++;
-            $last_real = TRUE;
-          }
-        }
-        // Backtrace one byte if the last character we found was a real
-        // character and we don't need it.
-        if ($last_real && $chars >= $length) {
-          $iend--;
-        }
-      }
-      elseif ($length < 0) {
-        // Count all the characters except continuation bytes from the end
-        // until we have found abs($start) characters, then backtrace one byte.
-        $length = abs($length);
-        $iend = $strlen; $chars = 0;
-        while ($iend > 0 && $chars < $length) {
-          $iend--;
-          $c = ord($text[$iend]);
-          if ($c < 0x80 || $c >= 0xC0) {
-            $chars++;
-          }
-        }
-        // Backtrace one byte if we are not at the beginning of the string.
-        if ($iend > 0) {
-          $iend--;
-        }
-      }
-      else {
-        // $length == 0, return an empty string.
-        return '';
-      }
-
-      return substr($text, $istart, max(0, $iend - $istart + 1));
-    }
+    @trigger_error('\Drupal\Component\Utility\Unicode::substr() is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. Use mb_substr() instead. See https://www.drupal.org/node/2850048.', E_USER_DEPRECATED);
+    return mb_substr($text, $start, $length);
   }
 
   /**
@@ -526,15 +431,15 @@ public static function truncate($string, $max_length, $wordsafe = FALSE, $add_el
     $max_length = max($max_length, 0);
     $min_wordsafe_length = max($min_wordsafe_length, 0);
 
-    if (static::strlen($string) <= $max_length) {
+    if (mb_strlen($string) <= $max_length) {
       // No truncation needed, so don't add ellipsis, just return.
       return $string;
     }
 
     if ($add_ellipsis) {
       // Truncate ellipsis in case $max_length is small.
-      $ellipsis = static::substr('…', 0, $max_length);
-      $max_length -= static::strlen($ellipsis);
+      $ellipsis = mb_substr('…', 0, $max_length);
+      $max_length -= mb_strlen($ellipsis);
       $max_length = max($max_length, 0);
     }
 
@@ -553,11 +458,11 @@ public static function truncate($string, $max_length, $wordsafe = FALSE, $add_el
         $string = $matches[1];
       }
       else {
-        $string = static::substr($string, 0, $max_length);
+        $string = mb_substr($string, 0, $max_length);
       }
     }
     else {
-      $string = static::substr($string, 0, $max_length);
+      $string = mb_substr($string, 0, $max_length);
     }
 
     if ($add_ellipsis) {
@@ -583,7 +488,7 @@ public static function truncate($string, $max_length, $wordsafe = FALSE, $add_el
    *   $str2, and 0 if they are equal.
    */
   public static function strcasecmp($str1, $str2) {
-    return strcmp(static::strtoupper($str1), static::strtoupper($str2));
+    return strcmp(mb_strtoupper($str1), mb_strtoupper($str2));
   }
 
   /**
@@ -715,18 +620,15 @@ public static function validateUtf8($text) {
    *   The position where $needle occurs in $haystack, always relative to the
    *   beginning (independent of $offset), or FALSE if not found. Note that
    *   a return value of 0 is not the same as FALSE.
+   *
+   * @deprecated in Drupal 8.6.0, will be removed before Drupal 9.0.0. Use
+   *   mb_strpos() instead.
+   *
+   * @see https://www.drupal.org/node/2850048
    */
   public static function strpos($haystack, $needle, $offset = 0) {
-    if (static::getStatus() == static::STATUS_MULTIBYTE) {
-      return mb_strpos($haystack, $needle, $offset);
-    }
-    else {
-      // Remove Unicode continuation characters, to be compatible with
-      // Unicode::strlen() and Unicode::substr().
-      $haystack = preg_replace("/[\x80-\xBF]/", '', $haystack);
-      $needle = preg_replace("/[\x80-\xBF]/", '', $needle);
-      return strpos($haystack, $needle, $offset);
-    }
+    @trigger_error('\Drupal\Component\Utility\Unicode::strpos() is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. Use mb_strpos() instead. See https://www.drupal.org/node/2850048.', E_USER_DEPRECATED);
+    return mb_strpos($haystack, $needle, $offset);
   }
 
 }
diff --git a/core/lib/Drupal/Component/Utility/composer.json b/core/lib/Drupal/Component/Utility/composer.json
index 3b8b5de5b872..b89e81390383 100644
--- a/core/lib/Drupal/Component/Utility/composer.json
+++ b/core/lib/Drupal/Component/Utility/composer.json
@@ -7,7 +7,9 @@
   "require": {
     "php": ">=5.5.9",
     "paragonie/random_compat": "^1.0|^2.0",
-    "drupal/core-render": "^8.2"
+    "drupal/core-render": "^8.2",
+    "symfony/polyfill-iconv": "~1.0",
+    "symfony/polyfill-mbstring": "~1.0"
   },
   "autoload": {
     "psr-4": {
diff --git a/core/lib/Drupal/Core/Asset/CssOptimizer.php b/core/lib/Drupal/Core/Asset/CssOptimizer.php
index 4ad7ba134cca..f20078ca0d87 100644
--- a/core/lib/Drupal/Core/Asset/CssOptimizer.php
+++ b/core/lib/Drupal/Core/Asset/CssOptimizer.php
@@ -119,7 +119,7 @@ public function loadFile($file, $optimize = NULL, $reset_basepath = TRUE) {
       // If a BOM is found, convert the file to UTF-8, then use substr() to
       // remove the BOM from the result.
       if ($encoding = (Unicode::encodingFromBOM($contents))) {
-        $contents = Unicode::substr(Unicode::convertToUtf8($contents, $encoding), 1);
+        $contents = mb_substr(Unicode::convertToUtf8($contents, $encoding), 1);
       }
       // If no BOM, check for fallback encoding. Per CSS spec the regex is very strict.
       elseif (preg_match('/^@charset "([^"]+)";/', $contents, $matches)) {
diff --git a/core/lib/Drupal/Core/Asset/JsOptimizer.php b/core/lib/Drupal/Core/Asset/JsOptimizer.php
index 6b8c217fcc57..243b40294c86 100644
--- a/core/lib/Drupal/Core/Asset/JsOptimizer.php
+++ b/core/lib/Drupal/Core/Asset/JsOptimizer.php
@@ -24,7 +24,7 @@ public function optimize(array $js_asset) {
     // remove the BOM from the result.
     $data = file_get_contents($js_asset['data']);
     if ($encoding = (Unicode::encodingFromBOM($data))) {
-      $data = Unicode::substr(Unicode::convertToUtf8($data, $encoding), 1);
+      $data = mb_substr(Unicode::convertToUtf8($data, $encoding), 1);
     }
     // If no BOM is found, check for the charset attribute.
     elseif (isset($js_asset['attributes']['charset'])) {
diff --git a/core/lib/Drupal/Core/Block/BlockBase.php b/core/lib/Drupal/Core/Block/BlockBase.php
index 411c3ef44871..a5f7fa9ed9d6 100644
--- a/core/lib/Drupal/Core/Block/BlockBase.php
+++ b/core/lib/Drupal/Core/Block/BlockBase.php
@@ -7,7 +7,6 @@
 use Drupal\Core\Messenger\MessengerTrait;
 use Drupal\Core\Plugin\ContextAwarePluginAssignmentTrait;
 use Drupal\Core\Plugin\ContextAwarePluginBase;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Plugin\PluginWithFormsInterface;
@@ -246,7 +245,7 @@ public function getMachineNameSuggestion() {
     //   \Drupal\system\MachineNameController::transliterate(), so it might make
     //   sense to provide a common service for the two.
     $transliterated = $this->transliteration()->transliterate($admin_label, LanguageInterface::LANGCODE_DEFAULT, '_');
-    $transliterated = Unicode::strtolower($transliterated);
+    $transliterated = mb_strtolower($transliterated);
 
     $transliterated = preg_replace('@[^a-z0-9_.]+@', '', $transliterated);
 
diff --git a/core/lib/Drupal/Core/Config/ConfigInstaller.php b/core/lib/Drupal/Core/Config/ConfigInstaller.php
index 242d92097e57..d7788161cba6 100644
--- a/core/lib/Drupal/Core/Config/ConfigInstaller.php
+++ b/core/lib/Drupal/Core/Config/ConfigInstaller.php
@@ -3,7 +3,6 @@
 namespace Drupal\Core\Config;
 
 use Drupal\Component\Utility\Crypt;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Config\Entity\ConfigDependencyManager;
 use Drupal\Core\Config\Entity\ConfigEntityDependency;
 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
@@ -344,7 +343,7 @@ public function installCollectionDefaultConfig($collection) {
     // Only install configuration for enabled extensions.
     $enabled_extensions = $this->getEnabledExtensions();
     $config_to_install = array_filter($storage->listAll(), function ($config_name) use ($enabled_extensions) {
-      $provider = Unicode::substr($config_name, 0, strpos($config_name, '.'));
+      $provider = mb_substr($config_name, 0, strpos($config_name, '.'));
       return in_array($provider, $enabled_extensions);
     });
     if (!empty($config_to_install)) {
diff --git a/core/lib/Drupal/Core/Config/Entity/Query/Condition.php b/core/lib/Drupal/Core/Config/Entity/Query/Condition.php
index bd2facd18fe8..3410a6ef53ce 100644
--- a/core/lib/Drupal/Core/Config/Entity/Query/Condition.php
+++ b/core/lib/Drupal/Core/Config/Entity/Query/Condition.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Core\Config\Entity\Query;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Entity\Query\ConditionBase;
 use Drupal\Core\Entity\Query\ConditionInterface;
 use Drupal\Core\Entity\Query\QueryException;
@@ -32,10 +31,10 @@ public function compile($configs) {
 
         // Lowercase condition value(s) for case-insensitive matches.
         if (is_array($condition['value'])) {
-          $condition['value'] = array_map('Drupal\Component\Utility\Unicode::strtolower', $condition['value']);
+          $condition['value'] = array_map('mb_strtolower', $condition['value']);
         }
         elseif (!is_bool($condition['value'])) {
-          $condition['value'] = Unicode::strtolower($condition['value']);
+          $condition['value'] = mb_strtolower($condition['value']);
         }
 
         $single_conditions[] = $condition;
@@ -164,7 +163,7 @@ protected function match(array $condition, $value) {
     if (isset($value)) {
       // We always want a case-insensitive match.
       if (!is_bool($value)) {
-        $value = Unicode::strtolower($value);
+        $value = mb_strtolower($value);
       }
 
       switch ($condition['operator']) {
diff --git a/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php
index 44b560c242cc..ffe670f450c0 100644
--- a/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php
+++ b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php
@@ -212,7 +212,7 @@ protected function processField($field) {
     // Set the correct database-engine specific datatype.
     // In case one is already provided, force it to uppercase.
     if (isset($field['mysql_type'])) {
-      $field['mysql_type'] = Unicode::strtoupper($field['mysql_type']);
+      $field['mysql_type'] = mb_strtoupper($field['mysql_type']);
     }
     else {
       $map = $this->getFieldTypeMap();
diff --git a/core/lib/Drupal/Core/Database/Driver/pgsql/Schema.php b/core/lib/Drupal/Core/Database/Driver/pgsql/Schema.php
index 58c658766138..6e81fbc0b9de 100644
--- a/core/lib/Drupal/Core/Database/Driver/pgsql/Schema.php
+++ b/core/lib/Drupal/Core/Database/Driver/pgsql/Schema.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Core\Database\Driver\pgsql;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Database\SchemaObjectExistsException;
 use Drupal\Core\Database\SchemaObjectDoesNotExistException;
 use Drupal\Core\Database\Schema as DatabaseSchema;
@@ -350,7 +349,7 @@ protected function processField($field) {
     // Set the correct database-engine specific datatype.
     // In case one is already provided, force it to lowercase.
     if (isset($field['pgsql_type'])) {
-      $field['pgsql_type'] = Unicode::strtolower($field['pgsql_type']);
+      $field['pgsql_type'] = mb_strtolower($field['pgsql_type']);
     }
     else {
       $map = $this->getFieldTypeMap();
diff --git a/core/lib/Drupal/Core/Database/Driver/sqlite/Schema.php b/core/lib/Drupal/Core/Database/Driver/sqlite/Schema.php
index 8c0ce54dc4d9..db2e348ef3c9 100644
--- a/core/lib/Drupal/Core/Database/Driver/sqlite/Schema.php
+++ b/core/lib/Drupal/Core/Database/Driver/sqlite/Schema.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Core\Database\Driver\sqlite;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Database\SchemaObjectExistsException;
 use Drupal\Core\Database\SchemaObjectDoesNotExistException;
 use Drupal\Core\Database\Schema as DatabaseSchema;
@@ -131,7 +130,7 @@ protected function processField($field) {
     // Set the correct database-engine specific datatype.
     // In case one is already provided, force it to uppercase.
     if (isset($field['sqlite_type'])) {
-      $field['sqlite_type'] = Unicode::strtoupper($field['sqlite_type']);
+      $field['sqlite_type'] = mb_strtoupper($field['sqlite_type']);
     }
     else {
       $map = $this->getFieldTypeMap();
diff --git a/core/lib/Drupal/Core/Database/Query/Condition.php b/core/lib/Drupal/Core/Database/Query/Condition.php
index 51693576e865..dd9a730f1d55 100644
--- a/core/lib/Drupal/Core/Database/Query/Condition.php
+++ b/core/lib/Drupal/Core/Database/Query/Condition.php
@@ -375,7 +375,8 @@ protected function mapConditionOperator($operator) {
     }
     else {
       // We need to upper case because PHP index matches are case sensitive but
-      // do not need the more expensive Unicode::strtoupper() because SQL statements are ASCII.
+      // do not need the more expensive mb_strtoupper() because SQL statements
+      // are ASCII.
       $operator = strtoupper($operator);
       $return = isset(static::$conditionOperatorMap[$operator]) ? static::$conditionOperatorMap[$operator] : [];
     }
diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php
index 490eebd6e9cd..8de7a460c032 100644
--- a/core/lib/Drupal/Core/DrupalKernel.php
+++ b/core/lib/Drupal/Core/DrupalKernel.php
@@ -5,7 +5,6 @@
 use Composer\Autoload\ClassLoader;
 use Drupal\Component\Assertion\Handle;
 use Drupal\Component\FileCache\FileCacheFactory;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Component\Utility\UrlHelper;
 use Drupal\Core\Cache\DatabaseBackend;
 use Drupal\Core\Config\BootstrapConfigStorageFactory;
@@ -1000,8 +999,9 @@ public static function bootEnvironment($app_root = NULL) {
     // numbers handling.
     setlocale(LC_ALL, 'C');
 
-    // Detect string handling method.
-    Unicode::check();
+    // Set appropriate configuration for multi-byte strings.
+    mb_internal_encoding('utf-8');
+    mb_language('uni');
 
     // Indicate that code is operating in a test child site.
     if (!defined('DRUPAL_TEST_IN_CHILD_SITE')) {
diff --git a/core/lib/Drupal/Core/Entity/Entity.php b/core/lib/Drupal/Core/Entity/Entity.php
index dbf4df389984..84991bc60935 100644
--- a/core/lib/Drupal/Core/Entity/Entity.php
+++ b/core/lib/Drupal/Core/Entity/Entity.php
@@ -5,7 +5,6 @@
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Cache\RefinableCacheableDependencyTrait;
 use Drupal\Core\DependencyInjection\DependencySerializationTrait;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Config\Entity\Exception\ConfigEntityIdLengthException;
 use Drupal\Core\Entity\Exception\UndefinedLinkTemplateException;
 use Drupal\Core\Language\Language;
@@ -431,7 +430,7 @@ public function preSave(EntityStorageInterface $storage) {
     // Check if this is an entity bundle.
     if ($this->getEntityType()->getBundleOf()) {
       // Throw an exception if the bundle ID is longer than 32 characters.
-      if (Unicode::strlen($this->id()) > EntityTypeInterface::BUNDLE_MAX_LENGTH) {
+      if (mb_strlen($this->id()) > EntityTypeInterface::BUNDLE_MAX_LENGTH) {
         throw new ConfigEntityIdLengthException("Attempt to create a bundle with an ID longer than " . EntityTypeInterface::BUNDLE_MAX_LENGTH . " characters: $this->id().");
       }
     }
diff --git a/core/lib/Drupal/Core/Entity/EntityType.php b/core/lib/Drupal/Core/Entity/EntityType.php
index 28f5b4ed753e..2ef984d6623d 100644
--- a/core/lib/Drupal/Core/Entity/EntityType.php
+++ b/core/lib/Drupal/Core/Entity/EntityType.php
@@ -3,7 +3,6 @@
 namespace Drupal\Core\Entity;
 
 use Drupal\Component\Plugin\Definition\PluginDefinition;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Entity\Exception\EntityTypeIdLengthException;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
@@ -295,7 +294,7 @@ class EntityType extends PluginDefinition implements EntityTypeInterface {
    */
   public function __construct($definition) {
     // Throw an exception if the entity type ID is longer than 32 characters.
-    if (Unicode::strlen($definition['id']) > static::ID_MAX_LENGTH) {
+    if (mb_strlen($definition['id']) > static::ID_MAX_LENGTH) {
       throw new EntityTypeIdLengthException('Attempt to create an entity type with an ID longer than ' . static::ID_MAX_LENGTH . " characters: {$definition['id']}.");
     }
 
@@ -768,7 +767,7 @@ public function getLabel() {
    * {@inheritdoc}
    */
   public function getLowercaseLabel() {
-    return Unicode::strtolower($this->getLabel());
+    return mb_strtolower($this->getLabel());
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/PhpSelection.php b/core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/PhpSelection.php
index 4545ebbe866a..52cf33d29d7d 100644
--- a/core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/PhpSelection.php
+++ b/core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/PhpSelection.php
@@ -3,7 +3,6 @@
 namespace Drupal\Core\Entity\Plugin\EntityReferenceSelection;
 
 use Drupal\Component\Utility\Html;
-use Drupal\Component\Utility\Unicode;
 
 /**
  * Defines an alternative to the default Entity Reference Selection plugin.
@@ -35,11 +34,11 @@ public function getReferenceableEntities($match = NULL, $match_operator = 'CONTA
     // possible.
     // @see \Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface::getReferenceableEntities()
     if (is_string($match)) {
-      $match = Html::escape(Unicode::strtolower($match));
+      $match = Html::escape(mb_strtolower($match));
     }
     elseif (is_array($match)) {
       array_walk($match, function (&$item) {
-        $item = Html::escape(Unicode::strtolower($item));
+        $item = Html::escape(mb_strtolower($item));
       });
     }
 
@@ -89,7 +88,7 @@ public function countReferenceableEntities($match = NULL, $match_operator = 'CON
    */
   protected function matchLabel($match, $match_operator, $label) {
     // Always use a case-insensitive value.
-    $label = Unicode::strtolower($label);
+    $label = mb_strtolower($label);
 
     switch ($match_operator) {
       case '=':
@@ -113,7 +112,7 @@ protected function matchLabel($match, $match_operator, $label) {
       case 'CONTAINS':
         return strpos($label, $match) !== FALSE;
       case 'ENDS_WITH':
-        return Unicode::substr($label, -Unicode::strlen($match)) === (string) $match;
+        return mb_substr($label, -mb_strlen($match)) === (string) $match;
       case 'IS NOT NULL':
         return TRUE;
       case 'IS NULL':
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UriItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UriItem.php
index 8d1d6e64949b..cfc7b1d0673c 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UriItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UriItem.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Core\Field\Plugin\Field\FieldType;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
 use Drupal\Core\TypedData\DataDefinition;
@@ -81,7 +80,7 @@ public static function generateSampleValue(FieldDefinitionInterface $field_defin
     $values = parent::generateSampleValue($field_definition);
     $suffix_length = $field_definition->getSetting('max_length') - 7;
     foreach ($values as $key => $value) {
-      $values[$key] = 'http://' . Unicode::substr($value, 0, $suffix_length);
+      $values[$key] = 'http://' . mb_substr($value, 0, $suffix_length);
     }
     return $values;
   }
diff --git a/core/lib/Drupal/Core/Form/FormValidator.php b/core/lib/Drupal/Core/Form/FormValidator.php
index 0d0d12c94405..57d24cc21e70 100644
--- a/core/lib/Drupal/Core/Form/FormValidator.php
+++ b/core/lib/Drupal/Core/Form/FormValidator.php
@@ -3,7 +3,6 @@
 namespace Drupal\Core\Form;
 
 use Drupal\Component\Utility\NestedArray;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Access\CsrfTokenGenerator;
 use Drupal\Core\Render\Element;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
@@ -259,7 +258,7 @@ protected function doValidateForm(&$elements, FormStateInterface &$form_state, $
         // string '0', which could be a valid value.
         $is_countable = is_array($elements['#value']) || $elements['#value'] instanceof \Countable;
         $is_empty_multiple = $is_countable && count($elements['#value']) == 0;
-        $is_empty_string = (is_string($elements['#value']) && Unicode::strlen(trim($elements['#value'])) == 0);
+        $is_empty_string = (is_string($elements['#value']) && mb_strlen(trim($elements['#value'])) == 0);
         $is_empty_value = ($elements['#value'] === 0);
         $is_empty_null = is_null($elements['#value']);
         if ($is_empty_multiple || $is_empty_string || $is_empty_value || $is_empty_null) {
@@ -331,8 +330,8 @@ protected function doValidateForm(&$elements, FormStateInterface &$form_state, $
    */
   protected function performRequiredValidation(&$elements, FormStateInterface &$form_state) {
     // Verify that the value is not longer than #maxlength.
-    if (isset($elements['#maxlength']) && Unicode::strlen($elements['#value']) > $elements['#maxlength']) {
-      $form_state->setError($elements, $this->t('@name cannot be longer than %max characters but is currently %length characters long.', ['@name' => empty($elements['#title']) ? $elements['#parents'][0] : $elements['#title'], '%max' => $elements['#maxlength'], '%length' => Unicode::strlen($elements['#value'])]));
+    if (isset($elements['#maxlength']) && mb_strlen($elements['#value']) > $elements['#maxlength']) {
+      $form_state->setError($elements, $this->t('@name cannot be longer than %max characters but is currently %length characters long.', ['@name' => empty($elements['#title']) ? $elements['#parents'][0] : $elements['#title'], '%max' => $elements['#maxlength'], '%length' => mb_strlen($elements['#value'])]));
     }
 
     if (isset($elements['#options']) && isset($elements['#value'])) {
diff --git a/core/lib/Drupal/Core/GeneratedLink.php b/core/lib/Drupal/Core/GeneratedLink.php
index c2c4900e113e..62f10a5df70b 100644
--- a/core/lib/Drupal/Core/GeneratedLink.php
+++ b/core/lib/Drupal/Core/GeneratedLink.php
@@ -3,7 +3,6 @@
 namespace Drupal\Core;
 
 use Drupal\Component\Render\MarkupInterface;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Render\BubbleableMetadata;
 
 /**
@@ -66,7 +65,7 @@ public function jsonSerialize() {
    * {@inheritdoc}
    */
   public function count() {
-    return Unicode::strlen($this->__toString());
+    return mb_strlen($this->__toString());
   }
 
 }
diff --git a/core/lib/Drupal/Core/Mail/MailFormatHelper.php b/core/lib/Drupal/Core/Mail/MailFormatHelper.php
index ca63ca040e0d..431c846ceec9 100644
--- a/core/lib/Drupal/Core/Mail/MailFormatHelper.php
+++ b/core/lib/Drupal/Core/Mail/MailFormatHelper.php
@@ -3,7 +3,6 @@
 namespace Drupal\Core\Mail;
 
 use Drupal\Component\Utility\Html;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Component\Utility\Xss;
 use Drupal\Core\Site\Settings;
 
@@ -222,12 +221,12 @@ public static function htmlToText($string, $allowed_tags = NULL) {
           // Fancy headers.
           case 'h1':
             $indent[] = '======== ';
-            $casing = '\Drupal\Component\Utility\Unicode::strtoupper';
+            $casing = 'mb_strtoupper';
             break;
 
           case 'h2':
             $indent[] = '-------- ';
-            $casing = '\Drupal\Component\Utility\Unicode::strtoupper';
+            $casing = 'mb_strtoupper';
             break;
 
           case '/h1':
@@ -260,7 +259,7 @@ public static function htmlToText($string, $allowed_tags = NULL) {
         // Convert inline HTML text to plain text; not removing line-breaks or
         // white-space, since that breaks newlines when sanitizing plain-text.
         $value = trim(Html::decodeEntities($value));
-        if (Unicode::strlen($value)) {
+        if (mb_strlen($value)) {
           $chunk = $value;
         }
       }
diff --git a/core/lib/Drupal/Core/Plugin/Discovery/AnnotatedClassDiscovery.php b/core/lib/Drupal/Core/Plugin/Discovery/AnnotatedClassDiscovery.php
index 9ecbaa053754..7e455dccc1d5 100644
--- a/core/lib/Drupal/Core/Plugin/Discovery/AnnotatedClassDiscovery.php
+++ b/core/lib/Drupal/Core/Plugin/Discovery/AnnotatedClassDiscovery.php
@@ -4,7 +4,6 @@
 
 use Drupal\Component\Annotation\AnnotationInterface;
 use Drupal\Component\Annotation\Plugin\Discovery\AnnotatedClassDiscovery as ComponentAnnotatedClassDiscovery;
-use Drupal\Component\Utility\Unicode;
 
 /**
  * Defines a discovery mechanism to find annotated plugins in PSR-0 namespaces.
@@ -103,7 +102,7 @@ protected function getProviderFromNamespace($namespace) {
     preg_match('|^Drupal\\\\(?<provider>[\w]+)\\\\|', $namespace, $matches);
 
     if (isset($matches['provider'])) {
-      return Unicode::strtolower($matches['provider']);
+      return mb_strtolower($matches['provider']);
     }
 
     return NULL;
diff --git a/core/lib/Drupal/Core/Routing/CompiledRoute.php b/core/lib/Drupal/Core/Routing/CompiledRoute.php
index a1366a608492..652acc5bb470 100644
--- a/core/lib/Drupal/Core/Routing/CompiledRoute.php
+++ b/core/lib/Drupal/Core/Routing/CompiledRoute.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Core\Routing;
 
-use Drupal\Component\Utility\Unicode;
 use Symfony\Component\Routing\CompiledRoute as SymfonyCompiledRoute;
 
 /**
@@ -69,7 +68,7 @@ public function __construct($fit, $pattern_outline, $num_parts, $staticPrefix, $
     // Support case-insensitive route matching by ensuring the pattern outline
     // is lowercase.
     // @see \Drupal\Core\Routing\RouteProvider::getRoutesByPath()
-    $this->patternOutline = Unicode::strtolower($pattern_outline);
+    $this->patternOutline = mb_strtolower($pattern_outline);
     $this->numParts = $num_parts;
   }
 
diff --git a/core/lib/Drupal/Core/Routing/RouteProvider.php b/core/lib/Drupal/Core/Routing/RouteProvider.php
index 95cbd6715b71..26df831a9080 100644
--- a/core/lib/Drupal/Core/Routing/RouteProvider.php
+++ b/core/lib/Drupal/Core/Routing/RouteProvider.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Core\Routing;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Cache\CacheTagsInvalidatorInterface;
@@ -345,7 +344,7 @@ protected function getRoutesByPath($path) {
     // have a case-insensitive match from the incoming path to the lower case
     // pattern outlines from \Drupal\Core\Routing\RouteCompiler::compile().
     // @see \Drupal\Core\Routing\CompiledRoute::__construct()
-    $parts = preg_split('@/+@', Unicode::strtolower($path), NULL, PREG_SPLIT_NO_EMPTY);
+    $parts = preg_split('@/+@', mb_strtolower($path), NULL, PREG_SPLIT_NO_EMPTY);
 
     $collection = new RouteCollection();
 
diff --git a/core/lib/Drupal/Core/StringTranslation/TranslatableMarkup.php b/core/lib/Drupal/Core/StringTranslation/TranslatableMarkup.php
index 3e9461accd8b..dcff3fc3b231 100644
--- a/core/lib/Drupal/Core/StringTranslation/TranslatableMarkup.php
+++ b/core/lib/Drupal/Core/StringTranslation/TranslatableMarkup.php
@@ -4,7 +4,6 @@
 
 use Drupal\Component\Render\FormattableMarkup;
 use Drupal\Component\Utility\ToStringTrait;
-use Drupal\Component\Utility\Unicode;
 
 /**
  * Provides translatable markup class.
@@ -226,7 +225,7 @@ protected function getStringTranslation() {
    *   The length of the string.
    */
   public function count() {
-    return Unicode::strlen($this->render());
+    return mb_strlen($this->render());
   }
 
 }
diff --git a/core/lib/Drupal/Core/TypedData/Plugin/DataType/ItemList.php b/core/lib/Drupal/Core/TypedData/Plugin/DataType/ItemList.php
index 0d58b717db06..b84643fc4fc0 100644
--- a/core/lib/Drupal/Core/TypedData/Plugin/DataType/ItemList.php
+++ b/core/lib/Drupal/Core/TypedData/Plugin/DataType/ItemList.php
@@ -87,7 +87,7 @@ public function getString() {
       $strings[] = $item->getString();
     }
     // Remove any empty strings resulting from empty items.
-    return implode(', ', array_filter($strings, '\Drupal\Component\Utility\Unicode::strlen'));
+    return implode(', ', array_filter($strings, 'mb_strlen'));
   }
 
   /**
diff --git a/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php b/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php
index a95c14b30e3b..aee25bc00db1 100644
--- a/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php
+++ b/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php
@@ -100,7 +100,7 @@ public function getString() {
       $strings[] = $property->getString();
     }
     // Remove any empty strings resulting from empty items.
-    return implode(', ', array_filter($strings, '\Drupal\Component\Utility\Unicode::strlen'));
+    return implode(', ', array_filter($strings, 'mb_strlen'));
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Updater/Updater.php b/core/lib/Drupal/Core/Updater/Updater.php
index a1ba10311739..c8b35f8ce9d3 100644
--- a/core/lib/Drupal/Core/Updater/Updater.php
+++ b/core/lib/Drupal/Core/Updater/Updater.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Core\Updater;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\FileTransfer\FileTransferException;
 use Drupal\Core\FileTransfer\FileTransfer;
 
@@ -112,7 +111,7 @@ public static function findInfoFile($directory) {
       return FALSE;
     }
     foreach ($info_files as $info_file) {
-      if (Unicode::substr($info_file->filename, 0, -9) == drupal_basename($directory)) {
+      if (mb_substr($info_file->filename, 0, -9) == drupal_basename($directory)) {
         // Info file Has the same name as the directory, return it.
         return $info_file->uri;
       }
diff --git a/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/UniqueFieldValueValidator.php b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/UniqueFieldValueValidator.php
index 1e63e6d4df71..3b8fd036f95c 100644
--- a/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/UniqueFieldValueValidator.php
+++ b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/UniqueFieldValueValidator.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Core\Validation\Plugin\Validation\Constraint;
 
-use Drupal\Component\Utility\Unicode;
 use Symfony\Component\Validator\Constraint;
 use Symfony\Component\Validator\ConstraintValidator;
 
@@ -36,7 +35,7 @@ public function validate($items, Constraint $constraint) {
       $this->context->addViolation($constraint->message, [
         '%value' => $item->value,
         '@entity_type' => $entity->getEntityType()->getLowercaseLabel(),
-        '@field_name' => Unicode::strtolower($items->getFieldDefinition()->getLabel()),
+        '@field_name' => mb_strtolower($items->getFieldDefinition()->getLabel()),
       ]);
     }
   }
diff --git a/core/modules/block/tests/src/Functional/BlockHookOperationTest.php b/core/modules/block/tests/src/Functional/BlockHookOperationTest.php
index 3a5c1ffbd5c4..23b1f0ce5fd3 100644
--- a/core/modules/block/tests/src/Functional/BlockHookOperationTest.php
+++ b/core/modules/block/tests/src/Functional/BlockHookOperationTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\block\Functional;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Tests\BrowserTestBase;
 
 /**
@@ -37,7 +36,7 @@ protected function setUp() {
   public function testBlockOperationAlter() {
     // Add a test block, any block will do.
     // Set the machine name so the test_operation link can be built later.
-    $block_id = Unicode::strtolower($this->randomMachineName(16));
+    $block_id = mb_strtolower($this->randomMachineName(16));
     $this->drupalPlaceBlock('system_powered_by_block', ['id' => $block_id]);
 
     // Get the Block listing.
diff --git a/core/modules/block/tests/src/Functional/BlockLanguageCacheTest.php b/core/modules/block/tests/src/Functional/BlockLanguageCacheTest.php
index b9c7c909eef1..9ca2b718636d 100644
--- a/core/modules/block/tests/src/Functional/BlockLanguageCacheTest.php
+++ b/core/modules/block/tests/src/Functional/BlockLanguageCacheTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\block\Functional;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\language\Entity\ConfigurableLanguage;
 use Drupal\Tests\BrowserTestBase;
 
@@ -62,7 +61,7 @@ public function testBlockLinks() {
 
     // Create a menu in the default language.
     $edit['label'] = $this->randomMachineName();
-    $edit['id'] = Unicode::strtolower($edit['label']);
+    $edit['id'] = mb_strtolower($edit['label']);
     $this->drupalPostForm('admin/structure/menu/add', $edit, t('Save'));
     $this->assertText(t('Menu @label has been added.', ['@label' => $edit['label']]));
 
diff --git a/core/modules/block_content/tests/src/Functional/BlockContentCreationTest.php b/core/modules/block_content/tests/src/Functional/BlockContentCreationTest.php
index 0f89b86e6a23..7447f33a628e 100644
--- a/core/modules/block_content/tests/src/Functional/BlockContentCreationTest.php
+++ b/core/modules/block_content/tests/src/Functional/BlockContentCreationTest.php
@@ -3,7 +3,6 @@
 namespace Drupal\Tests\block_content\Functional;
 
 use Drupal\block_content\Entity\BlockContent;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Database\Database;
 
 /**
@@ -239,7 +238,7 @@ public function testBlockDelete() {
 
     // Place the block.
     $instance = [
-      'id' => Unicode::strtolower($edit['info[0][value]']),
+      'id' => mb_strtolower($edit['info[0][value]']),
       'settings[label]' => $edit['info[0][value]'],
       'region' => 'sidebar_first',
     ];
@@ -291,7 +290,7 @@ public function testBlockDelete() {
   public function testConfigDependencies() {
     $block = $this->createBlockContent();
     // Place the block.
-    $block_placement_id = Unicode::strtolower($block->label());
+    $block_placement_id = mb_strtolower($block->label());
     $instance = [
       'id' => $block_placement_id,
       'settings[label]' => $block->label(),
diff --git a/core/modules/block_content/tests/src/Functional/BlockContentTranslationUITest.php b/core/modules/block_content/tests/src/Functional/BlockContentTranslationUITest.php
index c200252b813f..ccf5b32cc455 100644
--- a/core/modules/block_content/tests/src/Functional/BlockContentTranslationUITest.php
+++ b/core/modules/block_content/tests/src/Functional/BlockContentTranslationUITest.php
@@ -4,7 +4,6 @@
 
 use Drupal\block_content\Entity\BlockContent;
 use Drupal\block_content\Entity\BlockContentType;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Tests\content_translation\Functional\ContentTranslationUITestBase;
 
 /**
@@ -106,7 +105,7 @@ protected function createBlockContent($title = FALSE, $bundle = FALSE) {
    * {@inheritdoc}
    */
   protected function getNewEntityValues($langcode) {
-    return ['info' => Unicode::strtolower($this->randomMachineName())] + parent::getNewEntityValues($langcode);
+    return ['info' => mb_strtolower($this->randomMachineName())] + parent::getNewEntityValues($langcode);
   }
 
   /**
diff --git a/core/modules/block_content/tests/src/Functional/PageEditTest.php b/core/modules/block_content/tests/src/Functional/PageEditTest.php
index 41638bd2bc21..f623cfa28acb 100644
--- a/core/modules/block_content/tests/src/Functional/PageEditTest.php
+++ b/core/modules/block_content/tests/src/Functional/PageEditTest.php
@@ -3,7 +3,6 @@
 namespace Drupal\Tests\block_content\Functional;
 
 use Drupal\block_content\Entity\BlockContent;
-use Drupal\Component\Utility\Unicode;
 
 /**
  * Create a block and test block edit functionality.
@@ -28,7 +27,7 @@ public function testPageEdit() {
     $body_key = 'body[0][value]';
     // Create block to edit.
     $edit = [];
-    $edit['info[0][value]'] = Unicode::strtolower($this->randomMachineName(8));
+    $edit['info[0][value]'] = mb_strtolower($this->randomMachineName(8));
     $edit[$body_key] = $this->randomMachineName(16);
     $this->drupalPostForm('block/add/basic', $edit, t('Save'));
 
diff --git a/core/modules/color/color.module b/core/modules/color/color.module
index 35552961774d..a25be981d4a1 100644
--- a/core/modules/color/color.module
+++ b/core/modules/color/color.module
@@ -6,7 +6,6 @@
  */
 
 use Drupal\Component\Utility\Color;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Asset\CssOptimizer;
 use Drupal\Component\Utility\Bytes;
 use Drupal\Component\Utility\Environment;
@@ -514,7 +513,7 @@ function _color_rewrite_stylesheet($theme, &$info, &$paths, $palette, $style) {
   // Prepare color conversion table.
   $conversion = $palette;
   foreach ($conversion as $k => $v) {
-    $v = Unicode::strtolower($v);
+    $v = mb_strtolower($v);
     $conversion[$k] = Color::normalizeHexLength($v);
   }
   $default = color_get_palette($theme, TRUE);
@@ -534,7 +533,7 @@ function _color_rewrite_stylesheet($theme, &$info, &$paths, $palette, $style) {
   // Iterate over all the parts.
   foreach ($style as $chunk) {
     if ($is_color) {
-      $chunk = Unicode::strtolower($chunk);
+      $chunk = mb_strtolower($chunk);
       $chunk = Color::normalizeHexLength($chunk);
       // Check if this is one of the colors in the default palette.
       if ($key = array_search($chunk, $default)) {
diff --git a/core/modules/comment/tests/src/Functional/CommentInterfaceTest.php b/core/modules/comment/tests/src/Functional/CommentInterfaceTest.php
index 4b9a12777d36..a2c0d4a55e59 100644
--- a/core/modules/comment/tests/src/Functional/CommentInterfaceTest.php
+++ b/core/modules/comment/tests/src/Functional/CommentInterfaceTest.php
@@ -5,7 +5,6 @@
 use Drupal\comment\CommentManagerInterface;
 use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
 use Drupal\comment\Entity\Comment;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Entity\Entity\EntityViewDisplay;
 use Drupal\Core\Entity\Entity\EntityViewMode;
 use Drupal\user\RoleInterface;
@@ -311,7 +310,7 @@ public function testViewMode() {
     $this->assertRaw('<p>' . $comment_text . '</p>');
 
     // Create a new comment entity view mode.
-    $mode = Unicode::strtolower($this->randomMachineName());
+    $mode = mb_strtolower($this->randomMachineName());
     EntityViewMode::create([
       'targetEntityType' => 'comment',
       'id' => "comment.$mode",
diff --git a/core/modules/comment/tests/src/Kernel/CommentIntegrationTest.php b/core/modules/comment/tests/src/Kernel/CommentIntegrationTest.php
index af730346cbfe..88311994c4d5 100644
--- a/core/modules/comment/tests/src/Kernel/CommentIntegrationTest.php
+++ b/core/modules/comment/tests/src/Kernel/CommentIntegrationTest.php
@@ -3,7 +3,6 @@
 namespace Drupal\Tests\comment\Kernel;
 
 use Drupal\comment\Entity\CommentType;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Database\Database;
 use Drupal\Core\Entity\Entity\EntityViewDisplay;
 use Drupal\Core\Entity\Entity\EntityViewMode;
@@ -47,7 +46,7 @@ protected function setUp() {
    * @see CommentDefaultFormatter::calculateDependencies()
    */
   public function testViewMode() {
-    $mode = Unicode::strtolower($this->randomMachineName());
+    $mode = mb_strtolower($this->randomMachineName());
     // Create a new comment view mode and a view display entity.
     EntityViewMode::create([
       'id' => "comment.$mode",
@@ -64,7 +63,7 @@ public function testViewMode() {
     FieldStorageConfig::create([
       'entity_type' => 'entity_test',
       'type' => 'comment',
-      'field_name' => $field_name = Unicode::strtolower($this->randomMachineName()),
+      'field_name' => $field_name = mb_strtolower($this->randomMachineName()),
       'settings' => [
         'comment_type' => 'comment',
       ],
diff --git a/core/modules/config/tests/src/Functional/ConfigExportImportUITest.php b/core/modules/config/tests/src/Functional/ConfigExportImportUITest.php
index 96a80a606fff..5ef146c8e4c8 100644
--- a/core/modules/config/tests/src/Functional/ConfigExportImportUITest.php
+++ b/core/modules/config/tests/src/Functional/ConfigExportImportUITest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\config\Functional;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Archiver\ArchiveTar;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
@@ -102,7 +101,7 @@ public function testExportImport() {
     $this->contentType = $this->drupalCreateContentType();
 
     // Create a field.
-    $this->fieldName = Unicode::strtolower($this->randomMachineName());
+    $this->fieldName = mb_strtolower($this->randomMachineName());
     $this->fieldStorage = FieldStorageConfig::create([
       'field_name' => $this->fieldName,
       'entity_type' => 'node',
diff --git a/core/modules/config_translation/src/Controller/ConfigTranslationFieldListBuilder.php b/core/modules/config_translation/src/Controller/ConfigTranslationFieldListBuilder.php
index 566afdbb2300..f5b1bdd18f4b 100644
--- a/core/modules/config_translation/src/Controller/ConfigTranslationFieldListBuilder.php
+++ b/core/modules/config_translation/src/Controller/ConfigTranslationFieldListBuilder.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\config_translation\Controller;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Entity\EntityStorageInterface;
@@ -97,7 +96,7 @@ public function load() {
   public function getFilterLabels() {
     $info = parent::getFilterLabels();
     $bundle = $this->baseEntityInfo->getBundleLabel() ?: $this->t('Bundle');
-    $bundle = Unicode::strtolower($bundle);
+    $bundle = mb_strtolower($bundle);
 
     $info['placeholder'] = $this->t('Enter field or @bundle', ['@bundle' => $bundle]);
     $info['description'] = $this->t('Enter a part of the field or @bundle to filter by.', ['@bundle' => $bundle]);
diff --git a/core/modules/config_translation/src/Plugin/Menu/ContextualLink/ConfigTranslationContextualLink.php b/core/modules/config_translation/src/Plugin/Menu/ContextualLink/ConfigTranslationContextualLink.php
index fff82f0c7299..c808ebf56a75 100644
--- a/core/modules/config_translation/src/Plugin/Menu/ContextualLink/ConfigTranslationContextualLink.php
+++ b/core/modules/config_translation/src/Plugin/Menu/ContextualLink/ConfigTranslationContextualLink.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\config_translation\Plugin\Menu\ContextualLink;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Menu\ContextualLinkDefault;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Symfony\Component\HttpFoundation\Request;
@@ -28,7 +27,7 @@ public function getTitle(Request $request = NULL) {
     // retrieve the title. We need to retrieve a runtime title (as opposed to
     // storing the title on the plugin definition for the link) because it
     // contains translated parts that we need in the runtime language.
-    $type_name = Unicode::strtolower($this->mapperManager()->createInstance($this->pluginDefinition['config_translation_plugin_id'])->getTypeLabel());
+    $type_name = mb_strtolower($this->mapperManager()->createInstance($this->pluginDefinition['config_translation_plugin_id'])->getTypeLabel());
     return $this->t('Translate @type_name', ['@type_name' => $type_name]);
   }
 
diff --git a/core/modules/config_translation/src/Plugin/Menu/LocalTask/ConfigTranslationLocalTask.php b/core/modules/config_translation/src/Plugin/Menu/LocalTask/ConfigTranslationLocalTask.php
index 0aa84d224317..e781c9bd9a22 100644
--- a/core/modules/config_translation/src/Plugin/Menu/LocalTask/ConfigTranslationLocalTask.php
+++ b/core/modules/config_translation/src/Plugin/Menu/LocalTask/ConfigTranslationLocalTask.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\config_translation\Plugin\Menu\LocalTask;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Menu\LocalTaskDefault;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Symfony\Component\HttpFoundation\Request;
@@ -28,7 +27,7 @@ public function getTitle(Request $request = NULL) {
     // retrieve title. We need to retrieve a runtime title (as opposed to
     // storing the title on the plugin definition for the link) because
     // it contains translated parts that we need in the runtime language.
-    $type_name = Unicode::strtolower($this->mapperManager()->createInstance($this->pluginDefinition['config_translation_plugin_id'])->getTypeLabel());
+    $type_name = mb_strtolower($this->mapperManager()->createInstance($this->pluginDefinition['config_translation_plugin_id'])->getTypeLabel());
     return $this->t('Translate @type_name', ['@type_name' => $type_name]);
   }
 
diff --git a/core/modules/config_translation/tests/src/Functional/ConfigTranslationListUiTest.php b/core/modules/config_translation/tests/src/Functional/ConfigTranslationListUiTest.php
index 586d1975799c..bbaace29e827 100644
--- a/core/modules/config_translation/tests/src/Functional/ConfigTranslationListUiTest.php
+++ b/core/modules/config_translation/tests/src/Functional/ConfigTranslationListUiTest.php
@@ -3,7 +3,6 @@
 namespace Drupal\Tests\config_translation\Functional;
 
 use Drupal\block_content\Entity\BlockContentType;
-use Drupal\Component\Utility\Unicode;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
 use Drupal\language\Entity\ConfigurableLanguage;
@@ -93,7 +92,7 @@ protected function setUp() {
   protected function doBlockListTest() {
     // Add a test block, any block will do.
     // Set the machine name so the translate link can be built later.
-    $id = Unicode::strtolower($this->randomMachineName(16));
+    $id = mb_strtolower($this->randomMachineName(16));
     $this->drupalPlaceBlock('system_powered_by_block', ['id' => $id]);
 
     // Get the Block listing.
@@ -116,7 +115,7 @@ protected function doMenuListTest() {
     // this does not test more than necessary.
     $this->drupalGet('admin/structure/menu/add');
     // Lowercase the machine name.
-    $menu_name = Unicode::strtolower($this->randomMachineName(16));
+    $menu_name = mb_strtolower($this->randomMachineName(16));
     $label = $this->randomMachineName(16);
     $edit = [
       'id' => $menu_name,
@@ -164,7 +163,7 @@ protected function doVocabularyListTest() {
     $vocabulary = Vocabulary::create([
       'name' => $this->randomMachineName(),
       'description' => $this->randomMachineName(),
-      'vid' => Unicode::strtolower($this->randomMachineName()),
+      'vid' => mb_strtolower($this->randomMachineName()),
     ]);
     $vocabulary->save();
 
@@ -187,7 +186,7 @@ public function doCustomContentTypeListTest() {
     // Create a test custom block type to decouple looking for translate
     // operations link so this does not test more than necessary.
     $block_content_type = BlockContentType::create([
-      'id' => Unicode::strtolower($this->randomMachineName(16)),
+      'id' => mb_strtolower($this->randomMachineName(16)),
       'label' => $this->randomMachineName(),
       'revision' => FALSE
     ]);
@@ -212,7 +211,7 @@ public function doContactFormsListTest() {
     // Create a test contact form to decouple looking for translate operations
     // link so this does not test more than necessary.
     $contact_form = ContactForm::create([
-      'id' => Unicode::strtolower($this->randomMachineName(16)),
+      'id' => mb_strtolower($this->randomMachineName(16)),
       'label' => $this->randomMachineName(),
     ]);
     $contact_form->save();
@@ -236,7 +235,7 @@ public function doContentTypeListTest() {
     // Create a test content type to decouple looking for translate operations
     // link so this does not test more than necessary.
     $content_type = $this->drupalCreateContentType([
-      'type' => Unicode::strtolower($this->randomMachineName(16)),
+      'type' => mb_strtolower($this->randomMachineName(16)),
       'name' => $this->randomMachineName(),
     ]);
 
@@ -259,7 +258,7 @@ public function doFormatsListTest() {
     // Create a test format to decouple looking for translate operations
     // link so this does not test more than necessary.
     $filter_format = FilterFormat::create([
-      'format' => Unicode::strtolower($this->randomMachineName(16)),
+      'format' => mb_strtolower($this->randomMachineName(16)),
       'name' => $this->randomMachineName(),
     ]);
     $filter_format->save();
@@ -283,7 +282,7 @@ public function doShortcutListTest() {
     // Create a test shortcut to decouple looking for translate operations
     // link so this does not test more than necessary.
     $shortcut = ShortcutSet::create([
-      'id' => Unicode::strtolower($this->randomMachineName(16)),
+      'id' => mb_strtolower($this->randomMachineName(16)),
       'label' => $this->randomString(),
     ]);
     $shortcut->save();
@@ -306,7 +305,7 @@ public function doShortcutListTest() {
   public function doUserRoleListTest() {
     // Create a test role to decouple looking for translate operations
     // link so this does not test more than necessary.
-    $role_id = Unicode::strtolower($this->randomMachineName(16));
+    $role_id = mb_strtolower($this->randomMachineName(16));
     $this->drupalCreateRole([], $role_id);
 
     // Get the role listing.
@@ -387,7 +386,7 @@ public function doResponsiveImageListTest() {
   public function doFieldListTest() {
     // Create a base content type.
     $content_type = $this->drupalCreateContentType([
-      'type' => Unicode::strtolower($this->randomMachineName(16)),
+      'type' => mb_strtolower($this->randomMachineName(16)),
       'name' => $this->randomMachineName(),
     ]);
 
diff --git a/core/modules/config_translation/tests/src/Functional/ConfigTranslationUiTest.php b/core/modules/config_translation/tests/src/Functional/ConfigTranslationUiTest.php
index 97ce59cc94e8..82f7e2f1a052 100644
--- a/core/modules/config_translation/tests/src/Functional/ConfigTranslationUiTest.php
+++ b/core/modules/config_translation/tests/src/Functional/ConfigTranslationUiTest.php
@@ -5,7 +5,6 @@
 use Behat\Mink\Element\NodeElement;
 use Drupal\Component\Utility\Html;
 use Drupal\Component\Render\FormattableMarkup;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Language\Language;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Test\AssertMailTrait;
@@ -404,7 +403,7 @@ public function testContactConfigEntityTranslation() {
 
     // Test that delete links work and operations perform properly.
     foreach ($this->langcodes as $langcode) {
-      $replacements = ['%label' => t('@label @entity_type', ['@label' => $label, '@entity_type' => Unicode::strtolower(t('Contact form'))]), '@language' => \Drupal::languageManager()->getLanguage($langcode)->getName()];
+      $replacements = ['%label' => t('@label @entity_type', ['@label' => $label, '@entity_type' => mb_strtolower(t('Contact form'))]), '@language' => \Drupal::languageManager()->getLanguage($langcode)->getName()];
 
       $this->drupalGet("$translation_base_url/$langcode/delete");
       $this->assertRaw(t('Are you sure you want to delete the @language translation of %label?', $replacements));
diff --git a/core/modules/contact/src/ContactFormEditForm.php b/core/modules/contact/src/ContactFormEditForm.php
index 7e78f7835da2..cdf7765a4a87 100644
--- a/core/modules/contact/src/ContactFormEditForm.php
+++ b/core/modules/contact/src/ContactFormEditForm.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\contact;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Drupal\Core\Entity\EntityForm;
@@ -150,7 +149,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
     $form_state->setValue('recipients', $recipients);
     $redirect_url = $form_state->getValue('redirect');
     if ($redirect_url && $this->pathValidator->isValid($redirect_url)) {
-      if (Unicode::substr($redirect_url, 0, 1) !== '/') {
+      if (mb_substr($redirect_url, 0, 1) !== '/') {
         $form_state->setErrorByName('redirect', $this->t('The path should start with /.'));
       }
     }
diff --git a/core/modules/contact/tests/src/Functional/ContactSitewideTest.php b/core/modules/contact/tests/src/Functional/ContactSitewideTest.php
index 178a3ad01d24..b42b96064623 100644
--- a/core/modules/contact/tests/src/Functional/ContactSitewideTest.php
+++ b/core/modules/contact/tests/src/Functional/ContactSitewideTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\contact\Functional;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\contact\Entity\ContactForm;
 use Drupal\Core\Mail\MailFormatHelper;
 use Drupal\Core\Test\AssertMailTrait;
@@ -149,9 +148,9 @@ public function testSiteWideContact() {
     $recipients = ['simpletest&@example.com', 'simpletest2@example.com', 'simpletest3@example.com'];
     $max_length = EntityTypeInterface::BUNDLE_MAX_LENGTH;
     $max_length_exceeded = $max_length + 1;
-    $this->addContactForm($id = Unicode::strtolower($this->randomMachineName($max_length_exceeded)), $label = $this->randomMachineName($max_length_exceeded), implode(',', [$recipients[0]]), '', TRUE);
+    $this->addContactForm($id = mb_strtolower($this->randomMachineName($max_length_exceeded)), $label = $this->randomMachineName($max_length_exceeded), implode(',', [$recipients[0]]), '', TRUE);
     $this->assertText(format_string('Machine-readable name cannot be longer than @max characters but is currently @exceeded characters long.', ['@max' => $max_length, '@exceeded' => $max_length_exceeded]));
-    $this->addContactForm($id = Unicode::strtolower($this->randomMachineName($max_length)), $label = $this->randomMachineName($max_length), implode(',', [$recipients[0]]), '', TRUE);
+    $this->addContactForm($id = mb_strtolower($this->randomMachineName($max_length)), $label = $this->randomMachineName($max_length), implode(',', [$recipients[0]]), '', TRUE);
     $this->assertText(t('Contact form @label has been added.', ['@label' => $label]));
 
     // Verify that the creation message contains a link to a contact form.
@@ -159,7 +158,7 @@ public function testSiteWideContact() {
     $this->assert(isset($view_link), 'The message area contains a link to a contact form.');
 
     // Create first valid form.
-    $this->addContactForm($id = Unicode::strtolower($this->randomMachineName(16)), $label = $this->randomMachineName(16), implode(',', [$recipients[0]]), '', TRUE);
+    $this->addContactForm($id = mb_strtolower($this->randomMachineName(16)), $label = $this->randomMachineName(16), implode(',', [$recipients[0]]), '', TRUE);
     $this->assertText(t('Contact form @label has been added.', ['@label' => $label]));
 
     // Verify that the creation message contains a link to a contact form.
@@ -202,10 +201,10 @@ public function testSiteWideContact() {
     $this->drupalLogin($admin_user);
 
     // Add more forms.
-    $this->addContactForm(Unicode::strtolower($this->randomMachineName(16)), $label = $this->randomMachineName(16), implode(',', [$recipients[0], $recipients[1]]), '', FALSE);
+    $this->addContactForm(mb_strtolower($this->randomMachineName(16)), $label = $this->randomMachineName(16), implode(',', [$recipients[0], $recipients[1]]), '', FALSE);
     $this->assertText(t('Contact form @label has been added.', ['@label' => $label]));
 
-    $this->addContactForm($name = Unicode::strtolower($this->randomMachineName(16)), $label = $this->randomMachineName(16), implode(',', [$recipients[0], $recipients[1], $recipients[2]]), '', FALSE);
+    $this->addContactForm($name = mb_strtolower($this->randomMachineName(16)), $label = $this->randomMachineName(16), implode(',', [$recipients[0], $recipients[1], $recipients[2]]), '', FALSE);
     $this->assertText(t('Contact form @label has been added.', ['@label' => $label]));
 
     // Try adding a form that already exists.
@@ -270,7 +269,7 @@ public function testSiteWideContact() {
 
     $label = $this->randomMachineName(16);
     $recipients = implode(',', [$recipients[0], $recipients[1], $recipients[2]]);
-    $contact_form = Unicode::strtolower($this->randomMachineName(16));
+    $contact_form = mb_strtolower($this->randomMachineName(16));
     $this->addContactForm($contact_form, $label, $recipients, '', FALSE);
     $this->drupalGet('admin/structure/contact');
     $this->clickLink(t('Edit'));
@@ -300,7 +299,7 @@ public function testSiteWideContact() {
     $this->assertResponse(200);
 
     // Create a simple textfield.
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     $field_label = $this->randomMachineName();
     $this->fieldUIAddNewField(NULL, $field_name, $field_label, 'text');
     $field_name = 'field_' . $field_name;
diff --git a/core/modules/contact/tests/src/Functional/ContactStorageTest.php b/core/modules/contact/tests/src/Functional/ContactStorageTest.php
index acacab4182de..fbd938bb8a55 100644
--- a/core/modules/contact/tests/src/Functional/ContactStorageTest.php
+++ b/core/modules/contact/tests/src/Functional/ContactStorageTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\contact\Functional;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\contact\Entity\Message;
 use Drupal\user\RoleInterface;
 
@@ -47,7 +46,7 @@ public function testContactStorage() {
     $this->drupalLogin($admin_user);
     // Create first valid contact form.
     $mail = 'simpletest@example.com';
-    $this->addContactForm($id = Unicode::strtolower($this->randomMachineName(16)), $label = $this->randomMachineName(16), implode(',', [$mail]), '', TRUE, 'Your message has been sent.', [
+    $this->addContactForm($id = mb_strtolower($this->randomMachineName(16)), $label = $this->randomMachineName(16), implode(',', [$mail]), '', TRUE, 'Your message has been sent.', [
       'send_a_pony' => 1,
     ]);
     $this->assertText(t('Contact form @label has been added.', ['@label' => $label]));
diff --git a/core/modules/datetime/src/Tests/DateTestBase.php b/core/modules/datetime/src/Tests/DateTestBase.php
index ca43b8d54674..6a8900390081 100644
--- a/core/modules/datetime/src/Tests/DateTestBase.php
+++ b/core/modules/datetime/src/Tests/DateTestBase.php
@@ -4,7 +4,6 @@
 
 @trigger_error('\Drupal\datetime\Tests\DateTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Use \Drupal\Tests\BrowserTestBase instead. See https://www.drupal.org/node/2780063.', E_USER_DEPRECATED);
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Entity\Entity\EntityFormDisplay;
 use Drupal\Core\Entity\Entity\EntityViewDisplay;
 use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem;
@@ -111,7 +110,7 @@ protected function setUp() {
    * Creates a date test field.
    */
   protected function createField() {
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     $type = $this->getTestFieldType();
     $widget_type = $formatter_type = $type . '_default';
 
diff --git a/core/modules/datetime/tests/src/Functional/DateTestBase.php b/core/modules/datetime/tests/src/Functional/DateTestBase.php
index 21bad50ba02d..46e23ce15032 100644
--- a/core/modules/datetime/tests/src/Functional/DateTestBase.php
+++ b/core/modules/datetime/tests/src/Functional/DateTestBase.php
@@ -106,8 +106,8 @@ protected function setUp() {
    * Creates a date test field.
    */
   protected function createField() {
-    $field_name = Unicode::strtolower($this->randomMachineName());
-    $field_label = Unicode::ucfirst(Unicode::strtolower($this->randomMachineName()));
+    $field_name = mb_strtolower($this->randomMachineName());
+    $field_label = Unicode::ucfirst(mb_strtolower($this->randomMachineName()));
     $type = $this->getTestFieldType();
     $widget_type = $formatter_type = $type . '_default';
 
diff --git a/core/modules/datetime/tests/src/Functional/DateTimeFieldTest.php b/core/modules/datetime/tests/src/Functional/DateTimeFieldTest.php
index 3fcc2ad6a14a..72ef1283198a 100644
--- a/core/modules/datetime/tests/src/Functional/DateTimeFieldTest.php
+++ b/core/modules/datetime/tests/src/Functional/DateTimeFieldTest.php
@@ -3,7 +3,6 @@
 namespace Drupal\Tests\datetime\Functional;
 
 use Drupal\Component\Render\FormattableMarkup;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Datetime\DrupalDateTime;
 use Drupal\Core\Datetime\Entity\DateFormat;
 use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;
@@ -647,7 +646,7 @@ public function testDefaultValue() {
     $this->drupalCreateContentType(['type' => 'date_content']);
 
     // Create a field storage with settings to validate.
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     $field_storage = FieldStorageConfig::create([
       'field_name' => $field_name,
       'entity_type' => 'node',
@@ -854,7 +853,7 @@ public function testDateStorageSettings() {
     $this->drupalCreateContentType(['type' => 'date_content']);
 
     // Create a field storage with settings to validate.
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     $field_storage = FieldStorageConfig::create([
       'field_name' => $field_name,
       'entity_type' => 'node',
diff --git a/core/modules/datetime_range/tests/src/Functional/DateRangeFieldTest.php b/core/modules/datetime_range/tests/src/Functional/DateRangeFieldTest.php
index bd83b980e7eb..9cecd605f0bc 100644
--- a/core/modules/datetime_range/tests/src/Functional/DateRangeFieldTest.php
+++ b/core/modules/datetime_range/tests/src/Functional/DateRangeFieldTest.php
@@ -3,7 +3,6 @@
 namespace Drupal\Tests\datetime_range\Functional;
 
 use Drupal\Component\Render\FormattableMarkup;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Datetime\DrupalDateTime;
 use Drupal\Core\Datetime\Entity\DateFormat;
 use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;
@@ -978,7 +977,7 @@ public function testDefaultValue() {
     $this->drupalCreateContentType(['type' => 'date_content']);
 
     // Create a field storage with settings to validate.
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     $field_storage = FieldStorageConfig::create([
       'field_name' => $field_name,
       'entity_type' => 'node',
@@ -1344,7 +1343,7 @@ public function testDateStorageSettings() {
     $this->drupalCreateContentType(['type' => 'date_content']);
 
     // Create a field storage with settings to validate.
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     $field_storage = FieldStorageConfig::create([
       'field_name' => $field_name,
       'entity_type' => 'node',
diff --git a/core/modules/datetime_range/tests/src/Kernel/DateRangeItemTest.php b/core/modules/datetime_range/tests/src/Kernel/DateRangeItemTest.php
index 54f805ffd33f..658159a8aa3a 100644
--- a/core/modules/datetime_range/tests/src/Kernel/DateRangeItemTest.php
+++ b/core/modules/datetime_range/tests/src/Kernel/DateRangeItemTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\datetime_range\Kernel;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Entity\Entity\EntityViewDisplay;
 use Drupal\datetime_range\Plugin\Field\FieldType\DateRangeItem;
 use Drupal\entity_test\Entity\EntityTest;
@@ -47,7 +46,7 @@ protected function setUp() {
 
     // Add a datetime range field.
     $this->fieldStorage = FieldStorageConfig::create([
-      'field_name' => Unicode::strtolower($this->randomMachineName()),
+      'field_name' => mb_strtolower($this->randomMachineName()),
       'entity_type' => 'entity_test',
       'type' => 'daterange',
       'settings' => ['datetime_type' => DateRangeItem::DATETIME_TYPE_DATE],
diff --git a/core/modules/datetime_range/tests/src/Kernel/SeparatorTranslationTest.php b/core/modules/datetime_range/tests/src/Kernel/SeparatorTranslationTest.php
index 155bb61d10ee..d92a313f39ba 100644
--- a/core/modules/datetime_range/tests/src/Kernel/SeparatorTranslationTest.php
+++ b/core/modules/datetime_range/tests/src/Kernel/SeparatorTranslationTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\datetime_range\Kernel;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Entity\Entity\EntityViewDisplay;
 use Drupal\Core\Language\Language;
 use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem;
@@ -59,7 +58,7 @@ protected function setUp() {
 
     // Add a datetime range field.
     $this->fieldStorage = FieldStorageConfig::create([
-      'field_name' => Unicode::strtolower($this->randomMachineName()),
+      'field_name' => mb_strtolower($this->randomMachineName()),
       'entity_type' => 'entity_test',
       'type' => 'daterange',
       'settings' => ['datetime_type' => DateTimeItem::DATETIME_TYPE_DATE],
diff --git a/core/modules/dblog/src/Logger/DbLog.php b/core/modules/dblog/src/Logger/DbLog.php
index a1621ffcd035..5933e222810c 100644
--- a/core/modules/dblog/src/Logger/DbLog.php
+++ b/core/modules/dblog/src/Logger/DbLog.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\dblog\Logger;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Database\Connection;
 use Drupal\Core\Database\Database;
 use Drupal\Core\Database\DatabaseException;
@@ -66,14 +65,14 @@ public function log($level, $message, array $context = []) {
         ->insert('watchdog')
         ->fields([
           'uid' => $context['uid'],
-          'type' => Unicode::substr($context['channel'], 0, 64),
+          'type' => mb_substr($context['channel'], 0, 64),
           'message' => $message,
           'variables' => serialize($message_placeholders),
           'severity' => $level,
           'link' => $context['link'],
           'location' => $context['request_uri'],
           'referer' => $context['referer'],
-          'hostname' => Unicode::substr($context['ip'], 0, 128),
+          'hostname' => mb_substr($context['ip'], 0, 128),
           'timestamp' => $context['timestamp'],
         ])
         ->execute();
diff --git a/core/modules/dblog/tests/src/Functional/DbLogTest.php b/core/modules/dblog/tests/src/Functional/DbLogTest.php
index 5b82282d6aaa..1f04052913a5 100644
--- a/core/modules/dblog/tests/src/Functional/DbLogTest.php
+++ b/core/modules/dblog/tests/src/Functional/DbLogTest.php
@@ -432,7 +432,7 @@ private function doUser() {
       $value = $links->getAttribute('href');
 
       // Extract link to details page.
-      $link = Unicode::substr($value, strpos($value, 'admin/reports/dblog/event/'));
+      $link = mb_substr($value, strpos($value, 'admin/reports/dblog/event/'));
       $this->drupalGet($link);
       // Check for full message text on the details page.
       $this->assertRaw($message, 'DBLog event details was found: [delete user]');
diff --git a/core/modules/editor/src/Tests/EditorAdminTest.php b/core/modules/editor/src/Tests/EditorAdminTest.php
index 4315a6dabd85..8e993f3000c5 100644
--- a/core/modules/editor/src/Tests/EditorAdminTest.php
+++ b/core/modules/editor/src/Tests/EditorAdminTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\editor\Tests;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\filter\Entity\FilterFormat;
 use Drupal\node\Entity\Node;
 use Drupal\node\Entity\NodeType;
@@ -109,7 +108,7 @@ public function testDisableFormatWithEditor() {
     $this->container->get('module_installer')->install(['node']);
     $this->resetAll();
     // Create a new node type and attach the 'body' field to it.
-    $node_type = NodeType::create(['type' => Unicode::strtolower($this->randomMachineName())]);
+    $node_type = NodeType::create(['type' => mb_strtolower($this->randomMachineName())]);
     $node_type->save();
     node_add_body_field($node_type, $this->randomString());
 
diff --git a/core/modules/editor/tests/src/Kernel/EditorFilterIntegrationTest.php b/core/modules/editor/tests/src/Kernel/EditorFilterIntegrationTest.php
index 30f36e5a7295..c7a9b9ad5ba2 100644
--- a/core/modules/editor/tests/src/Kernel/EditorFilterIntegrationTest.php
+++ b/core/modules/editor/tests/src/Kernel/EditorFilterIntegrationTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\editor\Kernel;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\editor\Entity\Editor;
 use Drupal\filter\Entity\FilterFormat;
 use Drupal\KernelTests\KernelTestBase;
@@ -25,7 +24,7 @@ class EditorFilterIntegrationTest extends KernelTestBase {
   public function testTextFormatIntegration() {
     // Create an arbitrary text format.
     $format = FilterFormat::create([
-      'format' => Unicode::strtolower($this->randomMachineName()),
+      'format' => mb_strtolower($this->randomMachineName()),
       'name' => $this->randomString(),
     ]);
     $format->save();
diff --git a/core/modules/field/src/Entity/FieldStorageConfig.php b/core/modules/field/src/Entity/FieldStorageConfig.php
index 4e8ad9138090..b607f3b086f7 100644
--- a/core/modules/field/src/Entity/FieldStorageConfig.php
+++ b/core/modules/field/src/Entity/FieldStorageConfig.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\field\Entity;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Config\Entity\ConfigEntityBase;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Entity\FieldableEntityInterface;
@@ -317,10 +316,10 @@ protected function preSaveNew(EntityStorageInterface $storage) {
     // Assign the ID.
     $this->id = $this->id();
 
-    // Field name cannot be longer than FieldStorageConfig::NAME_MAX_LENGTH characters.
-    // We use Unicode::strlen() because the DB layer assumes that column widths
-    // are given in characters rather than bytes.
-    if (Unicode::strlen($this->getName()) > static::NAME_MAX_LENGTH) {
+    // Field name cannot be longer than FieldStorageConfig::NAME_MAX_LENGTH
+    // characters. We use mb_strlen() because the DB layer assumes that column
+    // widths are given in characters rather than bytes.
+    if (mb_strlen($this->getName()) > static::NAME_MAX_LENGTH) {
       throw new FieldException('Attempt to create a field storage with an name longer than ' . static::NAME_MAX_LENGTH . ' characters: ' . $this->getName());
     }
 
diff --git a/core/modules/field/src/Tests/Boolean/BooleanFormatterSettingsTest.php b/core/modules/field/src/Tests/Boolean/BooleanFormatterSettingsTest.php
index a9f755d8ba48..c2a156b89562 100644
--- a/core/modules/field/src/Tests/Boolean/BooleanFormatterSettingsTest.php
+++ b/core/modules/field/src/Tests/Boolean/BooleanFormatterSettingsTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\field\Tests\Boolean;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Component\Render\FormattableMarkup;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
@@ -43,14 +42,14 @@ protected function setUp() {
     parent::setUp();
 
     // Create a content type. Use Node because it has Field UI pages that work.
-    $type_name = Unicode::strtolower($this->randomMachineName(8)) . '_test';
+    $type_name = mb_strtolower($this->randomMachineName(8)) . '_test';
     $type = $this->drupalCreateContentType(['name' => $type_name, 'type' => $type_name]);
     $this->bundle = $type->id();
 
     $admin_user = $this->drupalCreateUser(['access content', 'administer content types', 'administer node fields', 'administer node display', 'bypass node access', 'administer nodes']);
     $this->drupalLogin($admin_user);
 
-    $this->fieldName = Unicode::strtolower($this->randomMachineName(8));
+    $this->fieldName = mb_strtolower($this->randomMachineName(8));
 
     $field_storage = FieldStorageConfig::create([
       'field_name' => $this->fieldName,
diff --git a/core/modules/field/src/Tests/Email/EmailFieldTest.php b/core/modules/field/src/Tests/Email/EmailFieldTest.php
index 269d91f65726..bd1a69d5e06f 100644
--- a/core/modules/field/src/Tests/Email/EmailFieldTest.php
+++ b/core/modules/field/src/Tests/Email/EmailFieldTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\field\Tests\Email;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\entity_test\Entity\EntityTest;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\simpletest\WebTestBase;
@@ -51,7 +50,7 @@ protected function setUp() {
    */
   public function testEmailField() {
     // Create a field with settings to validate.
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     $this->fieldStorage = FieldStorageConfig::create([
       'field_name' => $field_name,
       'entity_type' => 'entity_test',
diff --git a/core/modules/field/src/Tests/EntityReference/EntityReferenceAdminTest.php b/core/modules/field/src/Tests/EntityReference/EntityReferenceAdminTest.php
index 9bacb07d9642..369869c0f2d3 100644
--- a/core/modules/field/src/Tests/EntityReference/EntityReferenceAdminTest.php
+++ b/core/modules/field/src/Tests/EntityReference/EntityReferenceAdminTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\field\Tests\EntityReference;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
 use Drupal\field_ui\Tests\FieldUiTestTrait;
@@ -424,7 +423,7 @@ public function testMultipleTargetBundles() {
     /** @var \Drupal\taxonomy\Entity\Vocabulary[] $vocabularies */
     $vocabularies = [];
     for ($i = 0; $i < 2; $i++) {
-      $vid = Unicode::strtolower($this->randomMachineName());
+      $vid = mb_strtolower($this->randomMachineName());
       $vocabularies[$i] = Vocabulary::create([
         'name' => $this->randomString(),
         'vid' => $vid,
diff --git a/core/modules/field/src/Tests/Number/NumberFieldTest.php b/core/modules/field/src/Tests/Number/NumberFieldTest.php
index 64da6c1a00fb..dc082d7153e0 100644
--- a/core/modules/field/src/Tests/Number/NumberFieldTest.php
+++ b/core/modules/field/src/Tests/Number/NumberFieldTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\field\Tests\Number;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\node\Entity\Node;
 use Drupal\simpletest\WebTestBase;
@@ -40,7 +39,7 @@ protected function setUp() {
    */
   public function testNumberDecimalField() {
     // Create a field with settings to validate.
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     FieldStorageConfig::create([
       'field_name' => $field_name,
       'entity_type' => 'entity_test',
@@ -128,7 +127,7 @@ public function testNumberIntegerField() {
     $maximum = rand(2000, 4000);
 
     // Create a field with settings to validate.
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     $storage = FieldStorageConfig::create([
       'field_name' => $field_name,
       'entity_type' => 'entity_test',
@@ -273,7 +272,7 @@ public function testNumberIntegerField() {
   */
   public function testNumberFloatField() {
     // Create a field with settings to validate.
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     FieldStorageConfig::create([
       'field_name' => $field_name,
       'entity_type' => 'entity_test',
@@ -362,9 +361,9 @@ public function testNumberFloatField() {
    * Test default formatter behavior
    */
   public function testNumberFormatter() {
-    $type = Unicode::strtolower($this->randomMachineName());
-    $float_field = Unicode::strtolower($this->randomMachineName());
-    $integer_field = Unicode::strtolower($this->randomMachineName());
+    $type = mb_strtolower($this->randomMachineName());
+    $float_field = mb_strtolower($this->randomMachineName());
+    $integer_field = mb_strtolower($this->randomMachineName());
     $thousand_separators = ['', '.', ',', ' ', chr(8201), "'"];
     $decimal_separators = ['.', ','];
     $prefix = $this->randomMachineName();
@@ -494,7 +493,7 @@ public function testNumberFormatter() {
    */
   public function testCreateNumberFloatField() {
     // Create a float field.
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     FieldStorageConfig::create([
       'field_name' => $field_name,
       'entity_type' => 'entity_test',
@@ -519,7 +518,7 @@ public function testCreateNumberFloatField() {
    */
   public function testCreateNumberDecimalField() {
     // Create a decimal field.
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     FieldStorageConfig::create([
       'field_name' => $field_name,
       'entity_type' => 'entity_test',
diff --git a/core/modules/field/src/Tests/String/StringFieldTest.php b/core/modules/field/src/Tests/String/StringFieldTest.php
index fdedb79907a8..5049280190de 100644
--- a/core/modules/field/src/Tests/String/StringFieldTest.php
+++ b/core/modules/field/src/Tests/String/StringFieldTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\field\Tests\String;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\entity_test\Entity\EntityTest;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\simpletest\WebTestBase;
@@ -51,7 +50,7 @@ public function testTextfieldWidgets() {
    */
   public function _testTextfieldWidgets($field_type, $widget_type) {
     // Create a field.
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     $field_storage = FieldStorageConfig::create([
       'field_name' => $field_name,
       'entity_type' => 'entity_test',
diff --git a/core/modules/field/tests/src/Functional/Boolean/BooleanFieldTest.php b/core/modules/field/tests/src/Functional/Boolean/BooleanFieldTest.php
index af3ffc7d9bef..7a5dc45750c6 100644
--- a/core/modules/field/tests/src/Functional/Boolean/BooleanFieldTest.php
+++ b/core/modules/field/tests/src/Functional/Boolean/BooleanFieldTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\field\Functional\Boolean;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\entity_test\Entity\EntityTest;
 use Drupal\field\Entity\FieldStorageConfig;
 use Drupal\field\Entity\FieldConfig;
@@ -64,7 +63,7 @@ public function testBooleanField() {
     $label = $this->randomMachineName();
 
     // Create a field with settings to validate.
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     $this->fieldStorage = FieldStorageConfig::create([
       'field_name' => $field_name,
       'entity_type' => 'entity_test',
diff --git a/core/modules/field/tests/src/Functional/EntityReference/EntityReferenceAutoCreateTest.php b/core/modules/field/tests/src/Functional/EntityReference/EntityReferenceAutoCreateTest.php
index 1e6511fd68fc..84f2b58a07a1 100644
--- a/core/modules/field/tests/src/Functional/EntityReference/EntityReferenceAutoCreateTest.php
+++ b/core/modules/field/tests/src/Functional/EntityReference/EntityReferenceAutoCreateTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\field\Functional\EntityReference;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\Tests\BrowserTestBase;
@@ -145,7 +144,7 @@ public function testMultipleTargetBundles() {
     /** @var \Drupal\taxonomy\Entity\Vocabulary[] $vocabularies */
     $vocabularies = [];
     for ($i = 0; $i < 2; $i++) {
-      $vid = Unicode::strtolower($this->randomMachineName());
+      $vid = mb_strtolower($this->randomMachineName());
       $vocabularies[$i] = Vocabulary::create([
         'name' => $this->randomMachineName(),
         'vid' => $vid,
@@ -156,7 +155,7 @@ public function testMultipleTargetBundles() {
     // Create a taxonomy term entity reference field that saves the auto-created
     // taxonomy terms in the second vocabulary from the two that were configured
     // as targets.
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     $handler_settings = [
       'target_bundles' => [
         $vocabularies[0]->id() => $vocabularies[0]->id(),
diff --git a/core/modules/field/tests/src/Functional/EntityReference/EntityReferenceFieldDefaultValueTest.php b/core/modules/field/tests/src/Functional/EntityReference/EntityReferenceFieldDefaultValueTest.php
index 4567bd07e9e7..f5d37c2d318c 100644
--- a/core/modules/field/tests/src/Functional/EntityReference/EntityReferenceFieldDefaultValueTest.php
+++ b/core/modules/field/tests/src/Functional/EntityReference/EntityReferenceFieldDefaultValueTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\field\Functional\EntityReference;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Tests\SchemaCheckTestTrait;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
@@ -51,7 +50,7 @@ public function testEntityReferenceDefaultValue() {
     // Create a node to be referenced.
     $referenced_node = $this->drupalCreateNode(['type' => 'referenced_content']);
 
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     $field_storage = FieldStorageConfig::create([
       'field_name' => $field_name,
       'entity_type' => 'node',
@@ -114,7 +113,7 @@ public function testEntityReferenceDefaultConfigValue() {
     $referenced_node_type = $this->drupalCreateContentType(['type' => 'referenced_config_to_delete']);
     $referenced_node_type2 = $this->drupalCreateContentType(['type' => 'referenced_config_to_preserve']);
 
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     $field_storage = FieldStorageConfig::create([
       'field_name' => $field_name,
       'entity_type' => 'node',
diff --git a/core/modules/field/tests/src/Functional/TranslationWebTest.php b/core/modules/field/tests/src/Functional/TranslationWebTest.php
index 19af64d917e6..465add964dff 100644
--- a/core/modules/field/tests/src/Functional/TranslationWebTest.php
+++ b/core/modules/field/tests/src/Functional/TranslationWebTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\field\Functional;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\field\Entity\FieldStorageConfig;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\language\Entity\ConfigurableLanguage;
@@ -52,7 +51,7 @@ class TranslationWebTest extends FieldTestBase {
   protected function setUp() {
     parent::setUp();
 
-    $this->fieldName = Unicode::strtolower($this->randomMachineName() . '_field_name');
+    $this->fieldName = mb_strtolower($this->randomMachineName() . '_field_name');
 
     $field_storage = [
       'field_name' => $this->fieldName,
diff --git a/core/modules/field/tests/src/Kernel/Boolean/BooleanFormatterTest.php b/core/modules/field/tests/src/Kernel/Boolean/BooleanFormatterTest.php
index 94f5bc6c3028..9e4a0edf883d 100644
--- a/core/modules/field/tests/src/Kernel/Boolean/BooleanFormatterTest.php
+++ b/core/modules/field/tests/src/Kernel/Boolean/BooleanFormatterTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\field\Kernel\Boolean;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
 use Drupal\Core\Entity\FieldableEntityInterface;
 use Drupal\entity_test\Entity\EntityTest;
@@ -55,7 +54,7 @@ protected function setUp() {
 
     $this->entityType = 'entity_test';
     $this->bundle = $this->entityType;
-    $this->fieldName = Unicode::strtolower($this->randomMachineName());
+    $this->fieldName = mb_strtolower($this->randomMachineName());
 
     $field_storage = FieldStorageConfig::create([
       'field_name' => $this->fieldName,
diff --git a/core/modules/field/tests/src/Kernel/EntityReference/EntityReferenceItemTest.php b/core/modules/field/tests/src/Kernel/EntityReference/EntityReferenceItemTest.php
index 6b31790c7119..b3042f207804 100644
--- a/core/modules/field/tests/src/Kernel/EntityReference/EntityReferenceItemTest.php
+++ b/core/modules/field/tests/src/Kernel/EntityReference/EntityReferenceItemTest.php
@@ -4,7 +4,6 @@
 
 use Drupal\comment\Entity\Comment;
 use Drupal\Component\Render\FormattableMarkup;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Field\FieldItemListInterface;
 use Drupal\Core\Field\FieldItemInterface;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
@@ -78,7 +77,7 @@ protected function setUp() {
 
     $this->vocabulary = Vocabulary::create([
       'name' => $this->randomMachineName(),
-      'vid' => Unicode::strtolower($this->randomMachineName()),
+      'vid' => mb_strtolower($this->randomMachineName()),
       'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
     ]);
     $this->vocabulary->save();
@@ -259,7 +258,7 @@ public function testConfigEntityReferenceItem() {
     // Make sure the computed term reflects updates to the term id.
     $vocabulary2 = $vocabulary = Vocabulary::create([
       'name' => $this->randomMachineName(),
-      'vid' => Unicode::strtolower($this->randomMachineName()),
+      'vid' => mb_strtolower($this->randomMachineName()),
       'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
     ]);
     $vocabulary2->save();
@@ -330,7 +329,7 @@ public function testEntitySaveOrder() {
    * Tests that the 'handler' field setting stores the proper plugin ID.
    */
   public function testSelectionHandlerSettings() {
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     $field_storage = FieldStorageConfig::create([
       'field_name' => $field_name,
       'entity_type' => 'entity_test',
diff --git a/core/modules/field/tests/src/Kernel/EntityReference/EntityReferenceSettingsTest.php b/core/modules/field/tests/src/Kernel/EntityReference/EntityReferenceSettingsTest.php
index 2f8f13df8db5..93c39257b362 100644
--- a/core/modules/field/tests/src/Kernel/EntityReference/EntityReferenceSettingsTest.php
+++ b/core/modules/field/tests/src/Kernel/EntityReference/EntityReferenceSettingsTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\field\Kernel\EntityReference;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Core\Logger\RfcLogLevel;
 use Drupal\field\Entity\FieldConfig;
@@ -65,13 +64,13 @@ protected function setUp() {
     $this->installEntitySchema('entity_test');
 
     $this->nodeType = NodeType::create([
-      'type' => Unicode::strtolower($this->randomMachineName()),
+      'type' => mb_strtolower($this->randomMachineName()),
       'name' => $this->randomString(),
     ]);
     $this->nodeType->save();
 
     // Create a custom bundle.
-    $this->customBundle = 'test_bundle_' . Unicode::strtolower($this->randomMachineName());
+    $this->customBundle = 'test_bundle_' . mb_strtolower($this->randomMachineName());
     entity_test_create_bundle($this->customBundle, NULL, 'entity_test');
 
     // Prepare the logger for collecting the expected critical error.
@@ -86,7 +85,7 @@ public function testConfigTargetBundleDeletion() {
     /** @var \Drupal\taxonomy\Entity\Vocabulary[] $vocabularies */
     $vocabularies = [];
     for ($i = 0; $i < 2; $i++) {
-      $vid = Unicode::strtolower($this->randomMachineName());
+      $vid = mb_strtolower($this->randomMachineName());
       $vocabularies[$i] = Vocabulary::create([
         'name' => $this->randomString(),
         'vid' => $vid,
@@ -94,7 +93,7 @@ public function testConfigTargetBundleDeletion() {
       $vocabularies[$i]->save();
     }
     // Attach an entity reference field to $this->nodeType.
-    $name = Unicode::strtolower($this->randomMachineName());
+    $name = mb_strtolower($this->randomMachineName());
     $label = $this->randomString();
     $handler_settings = [
       'target_bundles' => [
@@ -143,7 +142,7 @@ public function testConfigTargetBundleDeletion() {
    */
   public function testCustomTargetBundleDeletion() {
     // Attach an entity reference field to $this->nodeType.
-    $name = Unicode::strtolower($this->randomMachineName());
+    $name = mb_strtolower($this->randomMachineName());
     $label = $this->randomString();
     $handler_settings = ['target_bundles' => [$this->customBundle => $this->customBundle]];
     $this->createEntityReferenceField('node', $this->nodeType->id(), $name, $label, 'entity_test', 'default', $handler_settings);
diff --git a/core/modules/field/tests/src/Kernel/FieldAttachStorageTest.php b/core/modules/field/tests/src/Kernel/FieldAttachStorageTest.php
index 04c308315b9a..04d997d77d6f 100644
--- a/core/modules/field/tests/src/Kernel/FieldAttachStorageTest.php
+++ b/core/modules/field/tests/src/Kernel/FieldAttachStorageTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\field\Kernel;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
 
@@ -292,7 +291,7 @@ public function testEntityCreateBundle() {
     $cardinality = $this->fieldTestData->field_storage->getCardinality();
 
     // Create a new bundle.
-    $new_bundle = 'test_bundle_' . Unicode::strtolower($this->randomMachineName());
+    $new_bundle = 'test_bundle_' . mb_strtolower($this->randomMachineName());
     entity_test_create_bundle($new_bundle, NULL, $entity_type);
 
     // Add a field to that bundle.
@@ -319,7 +318,7 @@ public function testEntityDeleteBundle() {
     $this->createFieldWithStorage('', $entity_type);
 
     // Create a new bundle.
-    $new_bundle = 'test_bundle_' . Unicode::strtolower($this->randomMachineName());
+    $new_bundle = 'test_bundle_' . mb_strtolower($this->randomMachineName());
     entity_test_create_bundle($new_bundle, NULL, $entity_type);
 
     // Add a field to that bundle.
@@ -327,7 +326,7 @@ public function testEntityDeleteBundle() {
     FieldConfig::create($this->fieldTestData->field_definition)->save();
 
     // Create a second field for the test bundle
-    $field_name = Unicode::strtolower($this->randomMachineName() . '_field_name');
+    $field_name = mb_strtolower($this->randomMachineName() . '_field_name');
     $field_storage = [
       'field_name' => $field_name,
       'entity_type' => $entity_type,
diff --git a/core/modules/field/tests/src/Kernel/FieldCrudTest.php b/core/modules/field/tests/src/Kernel/FieldCrudTest.php
index 6407be75203b..6068d316fba7 100644
--- a/core/modules/field/tests/src/Kernel/FieldCrudTest.php
+++ b/core/modules/field/tests/src/Kernel/FieldCrudTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\field\Kernel;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Entity\EntityStorageException;
 use Drupal\Core\Field\FieldException;
 use Drupal\entity_test\Entity\EntityTest;
@@ -43,7 +42,7 @@ public function setUp() {
     parent::setUp();
 
     $this->fieldStorageDefinition = [
-      'field_name' => Unicode::strtolower($this->randomMachineName()),
+      'field_name' => mb_strtolower($this->randomMachineName()),
       'entity_type' => 'entity_test',
       'type' => 'test_field',
     ];
@@ -199,7 +198,7 @@ protected function doFieldPropertyConstraintsTests() {
    * Test creating a field with custom storage set.
    */
   public function testCreateFieldCustomStorage() {
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     \Drupal::state()->set('field_test_custom_storage', $field_name);
 
     $field_storage = FieldStorageConfig::create([
diff --git a/core/modules/field/tests/src/Kernel/FieldKernelTestBase.php b/core/modules/field/tests/src/Kernel/FieldKernelTestBase.php
index 96e77cf159c6..7643585e9304 100644
--- a/core/modules/field/tests/src/Kernel/FieldKernelTestBase.php
+++ b/core/modules/field/tests/src/Kernel/FieldKernelTestBase.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\field\Kernel;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\field\Entity\FieldConfig;
@@ -87,7 +86,7 @@ protected function createFieldWithStorage($suffix = '', $entity_type = 'entity_t
     $field = 'field' . $suffix;
     $field_definition = 'field_definition' . $suffix;
 
-    $this->fieldTestData->$field_name = Unicode::strtolower($this->randomMachineName() . '_field_name' . $suffix);
+    $this->fieldTestData->$field_name = mb_strtolower($this->randomMachineName() . '_field_name' . $suffix);
     $this->fieldTestData->$field_storage = FieldStorageConfig::create([
       'field_name' => $this->fieldTestData->$field_name,
       'entity_type' => $entity_type,
diff --git a/core/modules/field/tests/src/Kernel/String/RawStringFormatterTest.php b/core/modules/field/tests/src/Kernel/String/RawStringFormatterTest.php
index 1000d640789f..fba3bda6b547 100644
--- a/core/modules/field/tests/src/Kernel/String/RawStringFormatterTest.php
+++ b/core/modules/field/tests/src/Kernel/String/RawStringFormatterTest.php
@@ -3,7 +3,6 @@
 namespace Drupal\Tests\field\Kernel\String;
 
 use Drupal\Component\Utility\Html;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
 use Drupal\Core\Entity\FieldableEntityInterface;
 use Drupal\entity_test\Entity\EntityTest;
@@ -58,7 +57,7 @@ protected function setUp() {
 
     $this->entityType = 'entity_test';
     $this->bundle = $this->entityType;
-    $this->fieldName = Unicode::strtolower($this->randomMachineName());
+    $this->fieldName = mb_strtolower($this->randomMachineName());
 
     $field_storage = FieldStorageConfig::create([
       'field_name' => $this->fieldName,
diff --git a/core/modules/field/tests/src/Kernel/String/StringFormatterTest.php b/core/modules/field/tests/src/Kernel/String/StringFormatterTest.php
index b09eb58c0913..ae3a371c81d9 100644
--- a/core/modules/field/tests/src/Kernel/String/StringFormatterTest.php
+++ b/core/modules/field/tests/src/Kernel/String/StringFormatterTest.php
@@ -3,7 +3,6 @@
 namespace Drupal\Tests\field\Kernel\String;
 
 use Drupal\Component\Utility\Html;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
 use Drupal\Core\Entity\FieldableEntityInterface;
 use Drupal\entity_test\Entity\EntityTestRev;
@@ -58,7 +57,7 @@ protected function setUp() {
 
     $this->entityType = 'entity_test_rev';
     $this->bundle = $this->entityType;
-    $this->fieldName = Unicode::strtolower($this->randomMachineName());
+    $this->fieldName = mb_strtolower($this->randomMachineName());
 
     $field_storage = FieldStorageConfig::create([
       'field_name' => $this->fieldName,
diff --git a/core/modules/field/tests/src/Kernel/Timestamp/TimestampFormatterTest.php b/core/modules/field/tests/src/Kernel/Timestamp/TimestampFormatterTest.php
index 4384666baf21..9bb1f73acc3e 100644
--- a/core/modules/field/tests/src/Kernel/Timestamp/TimestampFormatterTest.php
+++ b/core/modules/field/tests/src/Kernel/Timestamp/TimestampFormatterTest.php
@@ -3,7 +3,6 @@
 namespace Drupal\Tests\field\Kernel\Timestamp;
 
 use Drupal\Component\Render\FormattableMarkup;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
 use Drupal\Core\Entity\FieldableEntityInterface;
 use Drupal\entity_test\Entity\EntityTest;
@@ -55,7 +54,7 @@ protected function setUp() {
 
     $this->entityType = 'entity_test';
     $this->bundle = $this->entityType;
-    $this->fieldName = Unicode::strtolower($this->randomMachineName());
+    $this->fieldName = mb_strtolower($this->randomMachineName());
 
     $field_storage = FieldStorageConfig::create([
       'field_name' => $this->fieldName,
diff --git a/core/modules/field/tests/src/Kernel/TranslationTest.php b/core/modules/field/tests/src/Kernel/TranslationTest.php
index 124fd94da0c5..17620e8c5dae 100644
--- a/core/modules/field/tests/src/Kernel/TranslationTest.php
+++ b/core/modules/field/tests/src/Kernel/TranslationTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\field\Kernel;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\language\Entity\ConfigurableLanguage;
 use Drupal\field\Entity\FieldStorageConfig;
@@ -75,7 +74,7 @@ protected function setUp() {
 
     $this->installConfig(['language']);
 
-    $this->fieldName = Unicode::strtolower($this->randomMachineName());
+    $this->fieldName = mb_strtolower($this->randomMachineName());
 
     $this->entityType = 'entity_test';
 
@@ -140,7 +139,7 @@ public function testTranslatableFieldSaveLoad() {
     }
 
     // Test default values.
-    $field_name_default = Unicode::strtolower($this->randomMachineName() . '_field_name');
+    $field_name_default = mb_strtolower($this->randomMachineName() . '_field_name');
     $field_storage_definition = $this->fieldStorageDefinition;
     $field_storage_definition['field_name'] = $field_name_default;
     $field_storage = FieldStorageConfig::create($field_storage_definition);
diff --git a/core/modules/field/tests/src/Kernel/Uri/UriItemTest.php b/core/modules/field/tests/src/Kernel/Uri/UriItemTest.php
index 43102ca8cce1..86cc3621091f 100644
--- a/core/modules/field/tests/src/Kernel/Uri/UriItemTest.php
+++ b/core/modules/field/tests/src/Kernel/Uri/UriItemTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\field\Kernel\Uri;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\entity_test\Entity\EntityTest;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
@@ -38,7 +37,7 @@ public function testUriField() {
     $label = $this->randomMachineName();
 
     // Create a field with settings to validate.
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     $this->fieldStorage = FieldStorageConfig::create([
       'field_name' => $field_name,
       'entity_type' => 'entity_test',
diff --git a/core/modules/field_ui/src/Tests/ManageDisplayTest.php b/core/modules/field_ui/src/Tests/ManageDisplayTest.php
index 688b9e9e8471..985c6088164d 100644
--- a/core/modules/field_ui/src/Tests/ManageDisplayTest.php
+++ b/core/modules/field_ui/src/Tests/ManageDisplayTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\field_ui\Tests;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Entity\Entity\EntityFormDisplay;
 use Drupal\Core\Entity\Entity\EntityViewDisplay;
 use Drupal\Core\Entity\EntityInterface;
@@ -48,7 +47,7 @@ protected function setUp() {
     $vocabulary = Vocabulary::create([
       'name' => $this->randomMachineName(),
       'description' => $this->randomMachineName(),
-      'vid' => Unicode::strtolower($this->randomMachineName()),
+      'vid' => mb_strtolower($this->randomMachineName()),
       'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
       'help' => '',
       'nodes' => ['article' => 'article'],
diff --git a/core/modules/field_ui/tests/src/Kernel/EntityDisplayTest.php b/core/modules/field_ui/tests/src/Kernel/EntityDisplayTest.php
index c6a7a3f156c4..4385c2b75329 100644
--- a/core/modules/field_ui/tests/src/Kernel/EntityDisplayTest.php
+++ b/core/modules/field_ui/tests/src/Kernel/EntityDisplayTest.php
@@ -3,7 +3,6 @@
 namespace Drupal\Tests\field_ui\Kernel;
 
 use Drupal\Component\Render\FormattableMarkup;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Database\Database;
 use Drupal\Core\Entity\Display\EntityDisplayInterface;
@@ -523,14 +522,14 @@ public function testComponentDependencies() {
     // Create two arbitrary user roles.
     for ($i = 0; $i < 2; $i++) {
       $roles[$i] = Role::create([
-        'id' => Unicode::strtolower($this->randomMachineName()),
+        'id' => mb_strtolower($this->randomMachineName()),
         'label' => $this->randomString(),
       ]);
       $roles[$i]->save();
     }
 
     // Create a field of type 'test_field' attached to 'entity_test'.
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     FieldStorageConfig::create([
       'field_name' => $field_name,
       'entity_type' => 'entity_test',
diff --git a/core/modules/file/src/Plugin/migrate/destination/EntityFile.php b/core/modules/file/src/Plugin/migrate/destination/EntityFile.php
index d0a1cca83dd7..31740c25961d 100644
--- a/core/modules/file/src/Plugin/migrate/destination/EntityFile.php
+++ b/core/modules/file/src/Plugin/migrate/destination/EntityFile.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\file\Plugin\migrate\destination;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Field\Plugin\Field\FieldType\UriItem;
 use Drupal\migrate\Row;
 use Drupal\migrate\MigrateException;
@@ -58,7 +57,7 @@ protected function processStubRow(Row $row) {
       // Make it into a proper public file uri, stripping off the existing
       // scheme if present.
       $value = 'public://' . preg_replace('|^[a-z]+://|i', '', $value);
-      $value = Unicode::substr($value, 0, $field_definitions['uri']->getSetting('max_length'));
+      $value = mb_substr($value, 0, $field_definitions['uri']->getSetting('max_length'));
       // Create a real file, so File::preSave() can do filesize() on it.
       touch($value);
       $row->setDestinationProperty('uri', $value);
diff --git a/core/modules/file/src/Tests/FileFieldWidgetTest.php b/core/modules/file/src/Tests/FileFieldWidgetTest.php
index 8017ebf1b25d..0f40c4c19b99 100644
--- a/core/modules/file/src/Tests/FileFieldWidgetTest.php
+++ b/core/modules/file/src/Tests/FileFieldWidgetTest.php
@@ -4,7 +4,6 @@
 
 use Drupal\comment\Entity\Comment;
 use Drupal\comment\Tests\CommentTestTrait;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Url;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
@@ -461,7 +460,7 @@ public function testWidgetValidation() {
    * Tests file widget element.
    */
   public function testWidgetElement() {
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     $html_name = str_replace('_', '-', $field_name);
     $this->createFileField($field_name, 'node', 'article', ['cardinality' => FieldStorageConfig::CARDINALITY_UNLIMITED]);
     $file = $this->getTestFile('text');
diff --git a/core/modules/file/tests/src/Functional/Formatter/FileMediaFormatterTestBase.php b/core/modules/file/tests/src/Functional/Formatter/FileMediaFormatterTestBase.php
index 5ff99f4b05ee..228b1d6f050c 100644
--- a/core/modules/file/tests/src/Functional/Formatter/FileMediaFormatterTestBase.php
+++ b/core/modules/file/tests/src/Functional/Formatter/FileMediaFormatterTestBase.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\file\Functional\Formatter;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
@@ -47,7 +46,7 @@ protected function setUp() {
    */
   protected function createMediaField($formatter, $file_extensions, array $formatter_settings = []) {
     $entity_type = $bundle = 'entity_test';
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
 
     FieldStorageConfig::create([
       'entity_type' => $entity_type,
diff --git a/core/modules/filter/filter.module b/core/modules/filter/filter.module
index 1497aba2eee7..2222efce95d6 100644
--- a/core/modules/filter/filter.module
+++ b/core/modules/filter/filter.module
@@ -773,7 +773,7 @@ function _filter_html_escape($text) {
 function _filter_html_image_secure_process($text) {
   // Find the path (e.g. '/') to Drupal root.
   $base_path = base_path();
-  $base_path_length = Unicode::strlen($base_path);
+  $base_path_length = mb_strlen($base_path);
 
   // Find the directory on the server where index.php resides.
   $local_dir = \Drupal::root() . '/';
@@ -789,11 +789,11 @@ function _filter_html_image_secure_process($text) {
     // Verify that $src starts with $base_path.
     // This also ensures that external images cannot be referenced.
     $src = $image->getAttribute('src');
-    if (Unicode::substr($src, 0, $base_path_length) === $base_path) {
+    if (mb_substr($src, 0, $base_path_length) === $base_path) {
       // Remove the $base_path to get the path relative to the Drupal root.
       // Ensure the path refers to an actual image by prefixing the image source
       // with the Drupal root and running getimagesize() on it.
-      $local_image_path = $local_dir . Unicode::substr($src, $base_path_length);
+      $local_image_path = $local_dir . mb_substr($src, $base_path_length);
       $local_image_path = rawurldecode($local_image_path);
       if (@getimagesize($local_image_path)) {
         // The image has the right path. Erroneous images are dealt with below.
diff --git a/core/modules/filter/src/Plugin/Filter/FilterCaption.php b/core/modules/filter/src/Plugin/Filter/FilterCaption.php
index 03cddb790051..a03c95f5c8ca 100644
--- a/core/modules/filter/src/Plugin/Filter/FilterCaption.php
+++ b/core/modules/filter/src/Plugin/Filter/FilterCaption.php
@@ -3,7 +3,6 @@
 namespace Drupal\filter\Plugin\Filter;
 
 use Drupal\Component\Utility\Html;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Component\Utility\Xss;
 use Drupal\filter\FilterProcessResult;
 use Drupal\filter\Plugin\FilterBase;
@@ -43,7 +42,7 @@ public function process($text, $langcode) {
         $caption = FilteredMarkup::create(Xss::filter($caption, ['a', 'em', 'strong', 'cite', 'code', 'br']));
 
         // The caption must be non-empty.
-        if (Unicode::strlen($caption) === 0) {
+        if (mb_strlen($caption) === 0) {
           continue;
         }
 
diff --git a/core/modules/filter/tests/src/Functional/FilterAdminTest.php b/core/modules/filter/tests/src/Functional/FilterAdminTest.php
index a6e429304e91..d6327688ef03 100644
--- a/core/modules/filter/tests/src/Functional/FilterAdminTest.php
+++ b/core/modules/filter/tests/src/Functional/FilterAdminTest.php
@@ -3,7 +3,6 @@
 namespace Drupal\Tests\filter\Functional;
 
 use Drupal\Component\Utility\Html;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Url;
 use Drupal\filter\Entity\FilterFormat;
 use Drupal\node\Entity\Node;
@@ -115,7 +114,7 @@ public function testFormatAdmin() {
     // Add text format.
     $this->drupalGet('admin/config/content/formats');
     $this->clickLink('Add text format');
-    $format_id = Unicode::strtolower($this->randomMachineName());
+    $format_id = mb_strtolower($this->randomMachineName());
     $name = $this->randomMachineName();
     $edit = [
       'format' => $format_id,
@@ -241,7 +240,7 @@ public function testFilterAdmin() {
 
     // Add format.
     $edit = [];
-    $edit['format'] = Unicode::strtolower($this->randomMachineName());
+    $edit['format'] = mb_strtolower($this->randomMachineName());
     $edit['name'] = $this->randomMachineName();
     $edit['roles[' . RoleInterface::AUTHENTICATED_ID . ']'] = 1;
     $edit['filters[' . $second_filter . '][status]'] = TRUE;
@@ -389,14 +388,14 @@ public function testFilterTipHtmlEscape() {
    */
   public function testDisabledFormat() {
     // Create a node type and add a standard body field.
-    $node_type = NodeType::create(['type' => Unicode::strtolower($this->randomMachineName())]);
+    $node_type = NodeType::create(['type' => mb_strtolower($this->randomMachineName())]);
     $node_type->save();
     node_add_body_field($node_type, $this->randomString());
 
     // Create a text format with a filter that returns a static string.
     $format = FilterFormat::create([
       'name' => $this->randomString(),
-      'format' => $format_id = Unicode::strtolower($this->randomMachineName()),
+      'format' => $format_id = mb_strtolower($this->randomMachineName()),
     ]);
     $format->setFilterConfig('filter_static_text', ['status' => TRUE]);
     $format->save();
diff --git a/core/modules/filter/tests/src/Functional/FilterDefaultFormatTest.php b/core/modules/filter/tests/src/Functional/FilterDefaultFormatTest.php
index 45c371171133..e5a57482a530 100644
--- a/core/modules/filter/tests/src/Functional/FilterDefaultFormatTest.php
+++ b/core/modules/filter/tests/src/Functional/FilterDefaultFormatTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\filter\Functional;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\filter\Entity\FilterFormat;
 use Drupal\Tests\BrowserTestBase;
 
@@ -31,7 +30,7 @@ public function testDefaultTextFormats() {
     $formats = [];
     for ($i = 0; $i < 2; $i++) {
       $edit = [
-        'format' => Unicode::strtolower($this->randomMachineName()),
+        'format' => mb_strtolower($this->randomMachineName()),
         'name' => $this->randomMachineName(),
       ];
       $this->drupalPostForm('admin/config/content/formats/add', $edit, t('Save configuration'));
diff --git a/core/modules/filter/tests/src/Functional/FilterFormatAccessTest.php b/core/modules/filter/tests/src/Functional/FilterFormatAccessTest.php
index 8c3394bdbf8a..f82d258ddfc4 100644
--- a/core/modules/filter/tests/src/Functional/FilterFormatAccessTest.php
+++ b/core/modules/filter/tests/src/Functional/FilterFormatAccessTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\filter\Functional;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Access\AccessResult;
 use Drupal\filter\Entity\FilterFormat;
 use Drupal\Tests\BrowserTestBase;
@@ -85,7 +84,7 @@ protected function setUp() {
     $formats = [];
     for ($i = 0; $i < 3; $i++) {
       $edit = [
-        'format' => Unicode::strtolower($this->randomMachineName()),
+        'format' => mb_strtolower($this->randomMachineName()),
         'name' => $this->randomMachineName(),
       ];
       $this->drupalPostForm('admin/config/content/formats/add', $edit, t('Save configuration'));
diff --git a/core/modules/filter/tests/src/Functional/FilterHooksTest.php b/core/modules/filter/tests/src/Functional/FilterHooksTest.php
index 5ff4a8a487d2..420a7b385560 100644
--- a/core/modules/filter/tests/src/Functional/FilterHooksTest.php
+++ b/core/modules/filter/tests/src/Functional/FilterHooksTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\filter\Functional;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Tests\BrowserTestBase;
 use Drupal\user\RoleInterface;
 
@@ -38,7 +37,7 @@ public function testFilterHooks() {
     // Add a text format.
     $name = $this->randomMachineName();
     $edit = [];
-    $edit['format'] = Unicode::strtolower($this->randomMachineName());
+    $edit['format'] = mb_strtolower($this->randomMachineName());
     $edit['name'] = $name;
     $edit['roles[' . RoleInterface::ANONYMOUS_ID . ']'] = 1;
     $this->drupalPostForm('admin/config/content/formats/add', $edit, t('Save configuration'));
diff --git a/core/modules/image/image.field.inc b/core/modules/image/image.field.inc
index 9fcdf69116c5..bf69b90442ec 100644
--- a/core/modules/image/image.field.inc
+++ b/core/modules/image/image.field.inc
@@ -5,7 +5,6 @@
  * Implement an image field, based on the file module's file field.
  */
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Render\Element;
 
 /**
@@ -64,7 +63,7 @@ function template_preprocess_image_formatter(&$variables) {
   $item = $variables['item'];
 
   // Do not output an empty 'title' attribute.
-  if (Unicode::strlen($item->title) != 0) {
+  if (mb_strlen($item->title) != 0) {
     $variables['image']['#title'] = $item->title;
   }
 
diff --git a/core/modules/image/src/Entity/ImageStyle.php b/core/modules/image/src/Entity/ImageStyle.php
index da00c7f7d297..7992aea57af0 100644
--- a/core/modules/image/src/Entity/ImageStyle.php
+++ b/core/modules/image/src/Entity/ImageStyle.php
@@ -14,7 +14,6 @@
 use Drupal\image\ImageStyleInterface;
 use Drupal\Component\Utility\Crypt;
 use Drupal\Component\Utility\UrlHelper;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\StreamWrapper\StreamWrapperInterface;
 use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
 use Drupal\Core\Entity\Entity\EntityViewDisplay;
@@ -355,7 +354,7 @@ public function supportsUri($uri) {
     // Only support the URI if its extension is supported by the current image
     // toolkit.
     return in_array(
-      Unicode::strtolower(pathinfo($uri, PATHINFO_EXTENSION)),
+      mb_strtolower(pathinfo($uri, PATHINFO_EXTENSION)),
       $this->getImageFactory()->getSupportedExtensions()
     );
   }
diff --git a/core/modules/image/src/Plugin/ImageEffect/ConvertImageEffect.php b/core/modules/image/src/Plugin/ImageEffect/ConvertImageEffect.php
index 28d51792c81f..675ef3a4ea26 100644
--- a/core/modules/image/src/Plugin/ImageEffect/ConvertImageEffect.php
+++ b/core/modules/image/src/Plugin/ImageEffect/ConvertImageEffect.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\image\Plugin\ImageEffect;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Image\ImageInterface;
 use Drupal\image\ConfigurableImageEffectBase;
@@ -41,7 +40,7 @@ public function getDerivativeExtension($extension) {
    */
   public function getSummary() {
     $summary = [
-      '#markup' => Unicode::strtoupper($this->configuration['extension']),
+      '#markup' => mb_strtoupper($this->configuration['extension']),
     ];
     $summary += parent::getSummary();
 
@@ -64,7 +63,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
     $extensions = \Drupal::service('image.toolkit.manager')->getDefaultToolkit()->getSupportedExtensions();
     $options = array_combine(
       $extensions,
-      array_map(['\Drupal\Component\Utility\Unicode', 'strtoupper'], $extensions)
+      array_map('mb_strtoupper', $extensions)
     );
     $form['extension'] = [
       '#type' => 'select',
diff --git a/core/modules/image/tests/src/Functional/ImageFieldDefaultImagesTest.php b/core/modules/image/tests/src/Functional/ImageFieldDefaultImagesTest.php
index c4b989a75902..a06e0d7eec66 100644
--- a/core/modules/image/tests/src/Functional/ImageFieldDefaultImagesTest.php
+++ b/core/modules/image/tests/src/Functional/ImageFieldDefaultImagesTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\image\Functional;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Entity\Entity\EntityViewDisplay;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\file\Entity\File;
@@ -369,7 +368,7 @@ public function testDefaultImages() {
    */
   public function testInvalidDefaultImage() {
     $field_storage = FieldStorageConfig::create([
-      'field_name' => Unicode::strtolower($this->randomMachineName()),
+      'field_name' => mb_strtolower($this->randomMachineName()),
       'entity_type' => 'node',
       'type' => 'image',
       'settings' => [
diff --git a/core/modules/image/tests/src/Kernel/ImageFormatterTest.php b/core/modules/image/tests/src/Kernel/ImageFormatterTest.php
index e994f12e279e..1baa83019977 100644
--- a/core/modules/image/tests/src/Kernel/ImageFormatterTest.php
+++ b/core/modules/image/tests/src/Kernel/ImageFormatterTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\image\Kernel;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
 use Drupal\entity_test\Entity\EntityTest;
 use Drupal\field\Entity\FieldConfig;
@@ -58,7 +57,7 @@ protected function setUp() {
 
     $this->entityType = 'entity_test';
     $this->bundle = $this->entityType;
-    $this->fieldName = Unicode::strtolower($this->randomMachineName());
+    $this->fieldName = mb_strtolower($this->randomMachineName());
 
     FieldStorageConfig::create([
       'entity_type' => $this->entityType,
diff --git a/core/modules/language/src/Form/NegotiationConfigureForm.php b/core/modules/language/src/Form/NegotiationConfigureForm.php
index 806123f45919..21c08c92b193 100644
--- a/core/modules/language/src/Form/NegotiationConfigureForm.php
+++ b/core/modules/language/src/Form/NegotiationConfigureForm.php
@@ -3,7 +3,6 @@
 namespace Drupal\language\Form;
 
 use Drupal\Core\Block\BlockManagerInterface;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Extension\ThemeHandlerInterface;
@@ -276,7 +275,7 @@ protected function configureFormTable(array &$form, $type) {
 
         $table_form['weight'][$method_id] = [
           '#type' => 'weight',
-          '#title' => $this->t('Weight for @title language detection method', ['@title' => Unicode::strtolower($method_name)]),
+          '#title' => $this->t('Weight for @title language detection method', ['@title' => mb_strtolower($method_name)]),
           '#title_display' => 'invisible',
           '#default_value' => $weight,
           '#attributes' => ['class' => ["language-method-weight-$type"]],
@@ -287,7 +286,7 @@ protected function configureFormTable(array &$form, $type) {
 
         $table_form['enabled'][$method_id] = [
           '#type' => 'checkbox',
-          '#title' => $this->t('Enable @title language detection method', ['@title' => Unicode::strtolower($method_name)]),
+          '#title' => $this->t('Enable @title language detection method', ['@title' => mb_strtolower($method_name)]),
           '#title_display' => 'invisible',
           '#default_value' => $enabled,
         ];
diff --git a/core/modules/link/tests/src/Functional/LinkFieldTest.php b/core/modules/link/tests/src/Functional/LinkFieldTest.php
index f32bf3c45b82..32ea380a2741 100644
--- a/core/modules/link/tests/src/Functional/LinkFieldTest.php
+++ b/core/modules/link/tests/src/Functional/LinkFieldTest.php
@@ -59,7 +59,7 @@ protected function setUp() {
    * Tests link field URL validation.
    */
   public function testURLValidation() {
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     // Create a field with settings to validate.
     $this->fieldStorage = FieldStorageConfig::create([
       'field_name' => $field_name,
@@ -226,7 +226,7 @@ protected function assertInvalidEntries($field_name, array $invalid_entries) {
    * Tests the link title settings of a link field.
    */
   public function testLinkTitle() {
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     // Create a field with settings to validate.
     $this->fieldStorage = FieldStorageConfig::create([
       'field_name' => $field_name,
@@ -340,7 +340,7 @@ public function testLinkTitle() {
    * Tests the default 'link' formatter.
    */
   public function testLinkFormatter() {
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     // Create a field with settings to validate.
     $this->fieldStorage = FieldStorageConfig::create([
       'field_name' => $field_name,
@@ -495,7 +495,7 @@ public function testLinkFormatter() {
    * merged, since they involve different configuration and output.
    */
   public function testLinkSeparateFormatter() {
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     // Create a field with settings to validate.
     $this->fieldStorage = FieldStorageConfig::create([
       'field_name' => $field_name,
@@ -622,7 +622,7 @@ public function testLinkSeparateFormatter() {
   public function testLinkTypeOnLinkWidget() {
 
     $link_type = LinkItemInterface::LINK_EXTERNAL;
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
 
     // Create a field with settings to validate.
     $this->fieldStorage = FieldStorageConfig::create([
diff --git a/core/modules/menu_ui/tests/src/Functional/MenuUiLanguageTest.php b/core/modules/menu_ui/tests/src/Functional/MenuUiLanguageTest.php
index ee9374141b29..9e0e844aff13 100644
--- a/core/modules/menu_ui/tests/src/Functional/MenuUiLanguageTest.php
+++ b/core/modules/menu_ui/tests/src/Functional/MenuUiLanguageTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\menu_ui\Functional;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\language\Entity\ConfigurableLanguage;
 use Drupal\language\Entity\ContentLanguageSettings;
 use Drupal\Tests\BrowserTestBase;
@@ -51,7 +50,7 @@ protected function setUp() {
   public function testMenuLanguage() {
     // Create a test menu to test the various language-related settings.
     // Machine name has to be lowercase.
-    $menu_name = Unicode::strtolower($this->randomMachineName(16));
+    $menu_name = mb_strtolower($this->randomMachineName(16));
     $label = $this->randomString();
     $edit = [
       'id' => $menu_name,
diff --git a/core/modules/menu_ui/tests/src/Functional/MenuUiTest.php b/core/modules/menu_ui/tests/src/Functional/MenuUiTest.php
index 8f4dc5f1dac0..9cd64c0b0357 100644
--- a/core/modules/menu_ui/tests/src/Functional/MenuUiTest.php
+++ b/core/modules/menu_ui/tests/src/Functional/MenuUiTest.php
@@ -3,7 +3,6 @@
 namespace Drupal\Tests\menu_ui\Functional;
 
 use Drupal\block\Entity\Block;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
 use Drupal\Core\Menu\MenuLinkInterface;
 use Drupal\Core\Url;
@@ -208,7 +207,7 @@ public function addCustomMenu() {
     $this->assertRaw(t('@name cannot be longer than %max characters but is currently %length characters long.', [
       '@name' => t('Menu name'),
       '%max' => MENU_MAX_MENU_NAME_LENGTH_UI,
-      '%length' => Unicode::strlen($menu_name),
+      '%length' => mb_strlen($menu_name),
     ]));
 
     // Change the menu_name so it no longer exceeds the maximum length.
@@ -220,7 +219,7 @@ public function addCustomMenu() {
     $this->assertNoRaw(t('@name cannot be longer than %max characters but is currently %length characters long.', [
       '@name' => t('Menu name'),
       '%max' => MENU_MAX_MENU_NAME_LENGTH_UI,
-      '%length' => Unicode::strlen($menu_name),
+      '%length' => mb_strlen($menu_name),
     ]));
     // Verify that the confirmation message is displayed.
     $this->assertRaw(t('Menu %label has been added.', ['%label' => $label]));
diff --git a/core/modules/migrate/src/Plugin/migrate/id_map/Sql.php b/core/modules/migrate/src/Plugin/migrate/id_map/Sql.php
index b926c52349c1..0de83485ffa9 100644
--- a/core/modules/migrate/src/Plugin/migrate/id_map/Sql.php
+++ b/core/modules/migrate/src/Plugin/migrate/id_map/Sql.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\migrate\Plugin\migrate\id_map;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Database\DatabaseException;
 use Drupal\Core\Field\BaseFieldDefinition;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
@@ -170,10 +169,10 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition
     // Default generated table names, limited to 63 characters.
     $machine_name = str_replace(':', '__', $this->migration->id());
     $prefix_length = strlen($this->database->tablePrefix());
-    $this->mapTableName = 'migrate_map_' . Unicode::strtolower($machine_name);
-    $this->mapTableName = Unicode::substr($this->mapTableName, 0, 63 - $prefix_length);
-    $this->messageTableName = 'migrate_message_' . Unicode::strtolower($machine_name);
-    $this->messageTableName = Unicode::substr($this->messageTableName, 0, 63 - $prefix_length);
+    $this->mapTableName = 'migrate_map_' . mb_strtolower($machine_name);
+    $this->mapTableName = mb_substr($this->mapTableName, 0, 63 - $prefix_length);
+    $this->messageTableName = 'migrate_message_' . mb_strtolower($machine_name);
+    $this->messageTableName = mb_substr($this->messageTableName, 0, 63 - $prefix_length);
   }
 
   /**
diff --git a/core/modules/migrate/src/Plugin/migrate/process/MakeUniqueBase.php b/core/modules/migrate/src/Plugin/migrate/process/MakeUniqueBase.php
index a69fa654b260..861a6b6f8890 100644
--- a/core/modules/migrate/src/Plugin/migrate/process/MakeUniqueBase.php
+++ b/core/modules/migrate/src/Plugin/migrate/process/MakeUniqueBase.php
@@ -6,7 +6,6 @@
 use Drupal\migrate\MigrateExecutableInterface;
 use Drupal\migrate\Row;
 use Drupal\migrate\MigrateException;
-use Drupal\Component\Utility\Unicode;
 
 /**
  * This plugin ensures the source value is unique.
@@ -56,7 +55,7 @@ public function transform($value, MigrateExecutableInterface $migrate_executable
       throw new MigrateException('The character length configuration key should be an integer. Omit this key to capture the entire string.');
     }
     // Use optional start or length to return a portion of the unique value.
-    $value = Unicode::substr($value, $start, $length);
+    $value = mb_substr($value, $start, $length);
     $new_value = $value;
     while ($this->exists($new_value)) {
       $new_value = $value . $postfix . $i++;
diff --git a/core/modules/migrate/src/Plugin/migrate/process/Substr.php b/core/modules/migrate/src/Plugin/migrate/process/Substr.php
index 4d49a3809b70..b8f5f497b8b3 100644
--- a/core/modules/migrate/src/Plugin/migrate/process/Substr.php
+++ b/core/modules/migrate/src/Plugin/migrate/process/Substr.php
@@ -6,14 +6,12 @@
 use Drupal\migrate\MigrateExecutableInterface;
 use Drupal\migrate\Row;
 use Drupal\migrate\MigrateException;
-use Drupal\Component\Utility\Unicode;
 
 /**
  * Returns a substring of the input value.
  *
  * The substr process plugin returns the portion of the input value specified by
- * the start and length parameters. This is a wrapper around
- * \Drupal\Component\Utility\Unicode::substr().
+ * the start and length parameters. This is a wrapper around mb_substr().
  *
  * Available configuration keys:
  * - start: (optional) The returned string will start this many characters after
@@ -85,7 +83,7 @@ public function transform($value, MigrateExecutableInterface $migrate_executable
     }
 
     // Use optional start or length to return a portion of $value.
-    $new_value = Unicode::substr($value, $start, $length);
+    $new_value = mb_substr($value, $start, $length);
     return $new_value;
   }
 
diff --git a/core/modules/migrate/tests/src/Unit/process/CallbackTest.php b/core/modules/migrate/tests/src/Unit/process/CallbackTest.php
index 9f280b81997c..e6722044234f 100644
--- a/core/modules/migrate/tests/src/Unit/process/CallbackTest.php
+++ b/core/modules/migrate/tests/src/Unit/process/CallbackTest.php
@@ -29,7 +29,7 @@ public function testCallback($callable) {
   public function providerCallback() {
     return [
       'function' => ['strtolower'],
-      'class method' => [['\Drupal\Component\Utility\Unicode', 'strtolower']],
+      'class method' => [[self::class, 'strtolower']],
     ];
   }
 
@@ -59,4 +59,19 @@ public function providerCallbackExceptions() {
     ];
   }
 
+  /**
+   * Makes a string lowercase for testing purposes.
+   *
+   * @param string $string
+   *   The input string.
+   *
+   * @return string
+   *   The lowercased string.
+   *
+   * @see \Drupal\Tests\migrate\Unit\process\CallbackTest::providerCallback()
+   */
+  public static function strToLower($string) {
+    return mb_strtolower($string);
+  }
+
 }
diff --git a/core/modules/migrate/tests/src/Unit/process/DedupeEntityTest.php b/core/modules/migrate/tests/src/Unit/process/DedupeEntityTest.php
index 56ec983485f7..2d0157ad3cd6 100644
--- a/core/modules/migrate/tests/src/Unit/process/DedupeEntityTest.php
+++ b/core/modules/migrate/tests/src/Unit/process/DedupeEntityTest.php
@@ -6,7 +6,6 @@
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Entity\Query\QueryInterface;
 use Drupal\migrate\Plugin\migrate\process\DedupeEntity;
-use Drupal\Component\Utility\Unicode;
 
 /**
  * @coversDefaultClass \Drupal\migrate\Plugin\migrate\process\DedupeEntity
@@ -77,7 +76,7 @@ public function testDedupe($count, $postfix = '', $start = NULL, $length = NULL)
     $this->entityQueryExpects($count);
     $value = $this->randomMachineName(32);
     $actual = $plugin->transform($value, $this->migrateExecutable, $this->row, 'testproperty');
-    $expected = Unicode::substr($value, $start, $length);
+    $expected = mb_substr($value, $start, $length);
     $expected .= $count ? $postfix . $count : '';
     $this->assertSame($expected, $actual);
   }
diff --git a/core/modules/migrate/tests/src/Unit/process/MakeUniqueEntityFieldTest.php b/core/modules/migrate/tests/src/Unit/process/MakeUniqueEntityFieldTest.php
index fda25de930a4..0b4ebd5f92c8 100644
--- a/core/modules/migrate/tests/src/Unit/process/MakeUniqueEntityFieldTest.php
+++ b/core/modules/migrate/tests/src/Unit/process/MakeUniqueEntityFieldTest.php
@@ -6,7 +6,6 @@
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Entity\Query\QueryInterface;
 use Drupal\migrate\Plugin\migrate\process\MakeUniqueEntityField;
-use Drupal\Component\Utility\Unicode;
 
 /**
  * @coversDefaultClass \Drupal\migrate\Plugin\migrate\process\MakeUniqueEntityField
@@ -76,7 +75,7 @@ public function testMakeUniqueEntityField($count, $postfix = '', $start = NULL,
     $this->entityQueryExpects($count);
     $value = $this->randomMachineName(32);
     $actual = $plugin->transform($value, $this->migrateExecutable, $this->row, 'testproperty');
-    $expected = Unicode::substr($value, $start, $length);
+    $expected = mb_substr($value, $start, $length);
     $expected .= $count ? $postfix . $count : '';
     $this->assertSame($expected, $actual);
   }
diff --git a/core/modules/node/src/Tests/PagePreviewTest.php b/core/modules/node/src/Tests/PagePreviewTest.php
index 2f4056e4c451..e9f607cf26ea 100644
--- a/core/modules/node/src/Tests/PagePreviewTest.php
+++ b/core/modules/node/src/Tests/PagePreviewTest.php
@@ -4,7 +4,6 @@
 
 use Drupal\comment\Tests\CommentTestTrait;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Url;
 use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
@@ -88,7 +87,7 @@ protected function setUp() {
     $field_config->save();
 
     // Create a field.
-    $this->fieldName = Unicode::strtolower($this->randomMachineName());
+    $this->fieldName = mb_strtolower($this->randomMachineName());
     $handler_settings = [
       'target_bundles' => [
         $this->vocabulary->id() => $this->vocabulary->id(),
diff --git a/core/modules/node/tests/src/Functional/MultiStepNodeFormBasicOptionsTest.php b/core/modules/node/tests/src/Functional/MultiStepNodeFormBasicOptionsTest.php
index fbdb200cc56d..93c225786492 100644
--- a/core/modules/node/tests/src/Functional/MultiStepNodeFormBasicOptionsTest.php
+++ b/core/modules/node/tests/src/Functional/MultiStepNodeFormBasicOptionsTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\node\Functional;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
 
@@ -29,7 +28,7 @@ public function testMultiStepNodeFormBasicOptions() {
     $this->drupalLogin($web_user);
 
     // Create an unlimited cardinality field.
-    $this->fieldName = Unicode::strtolower($this->randomMachineName());
+    $this->fieldName = mb_strtolower($this->randomMachineName());
     FieldStorageConfig::create([
       'field_name' => $this->fieldName,
       'entity_type' => 'node',
diff --git a/core/modules/node/tests/src/Functional/NodeAccessFieldTest.php b/core/modules/node/tests/src/Functional/NodeAccessFieldTest.php
index 8028ec9f976a..aa224824d5dd 100644
--- a/core/modules/node/tests/src/Functional/NodeAccessFieldTest.php
+++ b/core/modules/node/tests/src/Functional/NodeAccessFieldTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\node\Functional;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
 
@@ -51,7 +50,7 @@ protected function setUp() {
     $this->contentAdminUser = $this->drupalCreateUser(['access content', 'administer content types', 'administer node fields']);
 
     // Add a custom field to the page content type.
-    $this->fieldName = Unicode::strtolower($this->randomMachineName() . '_field_name');
+    $this->fieldName = mb_strtolower($this->randomMachineName() . '_field_name');
     FieldStorageConfig::create([
       'field_name' => $this->fieldName,
       'entity_type' => 'node',
diff --git a/core/modules/node/tests/src/Functional/NodeTypeTranslationTest.php b/core/modules/node/tests/src/Functional/NodeTypeTranslationTest.php
index 264bada062f7..973955c5dd97 100644
--- a/core/modules/node/tests/src/Functional/NodeTypeTranslationTest.php
+++ b/core/modules/node/tests/src/Functional/NodeTypeTranslationTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\node\Functional;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\language\Entity\ConfigurableLanguage;
 use Drupal\Tests\BrowserTestBase;
 
@@ -95,7 +94,7 @@ protected function installParameters() {
    * Tests the node type translation.
    */
   public function testNodeTypeTranslation() {
-    $type = Unicode::strtolower($this->randomMachineName(16));
+    $type = mb_strtolower($this->randomMachineName(16));
     $name = $this->randomString();
     $this->drupalLogin($this->adminUser);
     $this->drupalCreateContentType(['type' => $type, 'name' => $name]);
@@ -129,7 +128,7 @@ public function testNodeTypeTranslation() {
    * Tests the node type title label translation.
    */
   public function testNodeTypeTitleLabelTranslation() {
-    $type = Unicode::strtolower($this->randomMachineName(16));
+    $type = mb_strtolower($this->randomMachineName(16));
     $name = $this->randomString();
     $this->drupalLogin($this->adminUser);
     $this->drupalCreateContentType(['type' => $type, 'name' => $name]);
@@ -159,7 +158,7 @@ public function testNodeTypeTitleLabelTranslation() {
     $this->drupalPostForm(NULL, [], 'Save field settings');
     $this->drupalPostForm(NULL, [], 'Save settings');
 
-    $type = Unicode::strtolower($this->randomMachineName(16));
+    $type = mb_strtolower($this->randomMachineName(16));
     $name = $this->randomString();
     $this->drupalCreateContentType(['type' => $type, 'name' => $name]);
 
diff --git a/core/modules/node/tests/src/Kernel/SummaryLengthTest.php b/core/modules/node/tests/src/Kernel/SummaryLengthTest.php
index fa15c0e6ab13..eecb0d018846 100644
--- a/core/modules/node/tests/src/Kernel/SummaryLengthTest.php
+++ b/core/modules/node/tests/src/Kernel/SummaryLengthTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\node\Kernel;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Datetime\Entity\DateFormat;
 use Drupal\KernelTests\KernelTestBase;
 use Drupal\node\Entity\Node;
@@ -72,9 +71,6 @@ protected function setUp() {
       'label' => 'Fallback',
       'pattern' => 'Y-m-d',
     ])->save();
-
-    // Enable multibyte support.
-    Unicode::setStatus(Unicode::STATUS_MULTIBYTE);
   }
 
   /**
diff --git a/core/modules/options/src/Plugin/Field/FieldType/ListStringItem.php b/core/modules/options/src/Plugin/Field/FieldType/ListStringItem.php
index 1f8caeaf3617..16e8878d7abf 100644
--- a/core/modules/options/src/Plugin/Field/FieldType/ListStringItem.php
+++ b/core/modules/options/src/Plugin/Field/FieldType/ListStringItem.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\options\Plugin\Field\FieldType;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
 use Drupal\Core\TypedData\DataDefinition;
 
@@ -65,7 +64,7 @@ protected function allowedValuesDescription() {
    * {@inheritdoc}
    */
   protected static function validateAllowedValue($option) {
-    if (Unicode::strlen($option) > 255) {
+    if (mb_strlen($option) > 255) {
       return t('Allowed values list: each key must be a string at most 255 characters long.');
     }
   }
diff --git a/core/modules/path/tests/src/Functional/PathAliasTest.php b/core/modules/path/tests/src/Functional/PathAliasTest.php
index a12b282d6721..b8ac5968db26 100644
--- a/core/modules/path/tests/src/Functional/PathAliasTest.php
+++ b/core/modules/path/tests/src/Functional/PathAliasTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\path\Functional;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Database\Database;
 
@@ -84,7 +83,7 @@ public function testAdminAlias() {
     $this->drupalGet($edit['alias']);
     $this->assertText($node1->label(), 'Alias works lower case.');
     $this->assertResponse(200);
-    $this->drupalGet(Unicode::strtoupper($edit['alias']));
+    $this->drupalGet(mb_strtoupper($edit['alias']));
     $this->assertText($node1->label(), 'Alias works upper case.');
     $this->assertResponse(200);
 
@@ -111,7 +110,7 @@ public function testAdminAlias() {
     $this->drupalPostForm('admin/config/search/path/edit/' . $pid, $edit, t('Save'));
 
     // Confirm that the alias works.
-    $this->drupalGet(Unicode::strtoupper($edit['alias']));
+    $this->drupalGet(mb_strtoupper($edit['alias']));
     $this->assertText($node1->label(), 'Changed alias works.');
     $this->assertResponse(200);
 
@@ -133,7 +132,7 @@ public function testAdminAlias() {
     $this->assertRaw(t('The alias %alias is already in use in this language.', ['%alias' => $edit['alias']]), 'Attempt to move alias was rejected.');
 
     $edit_upper = $edit;
-    $edit_upper['alias'] = Unicode::strtoupper($edit['alias']);
+    $edit_upper['alias'] = mb_strtoupper($edit['alias']);
     $this->drupalPostForm('admin/config/search/path/add', $edit_upper, t('Save'));
     $this->assertRaw(t('The alias %alias could not be added because it is already in use in this language with different capitalization: %stored_alias.', [
       '%alias' => $edit_upper['alias'],
@@ -266,7 +265,7 @@ public function testNodeAlias() {
     $this->drupalPostForm('node/' . $node1->id() . '/edit', $edit, t('Save'));
 
     // Confirm that the alias works.
-    $this->drupalGet(Unicode::strtoupper($edit['path[0][alias]']));
+    $this->drupalGet(mb_strtoupper($edit['path[0][alias]']));
     $this->assertText($node1->label(), 'Changed alias works.');
     $this->assertResponse(200);
 
diff --git a/core/modules/quickedit/src/Tests/QuickEditLoadingTest.php b/core/modules/quickedit/src/Tests/QuickEditLoadingTest.php
index 6945610db1f6..9957a67ee01b 100644
--- a/core/modules/quickedit/src/Tests/QuickEditLoadingTest.php
+++ b/core/modules/quickedit/src/Tests/QuickEditLoadingTest.php
@@ -3,7 +3,6 @@
 namespace Drupal\quickedit\Tests;
 
 use Drupal\Component\Serialization\Json;
-use Drupal\Component\Utility\Unicode;
 use Drupal\block_content\Entity\BlockContent;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
@@ -216,7 +215,7 @@ public function testUserWithPermission() {
     $ajax_commands = Json::decode($response);
     $this->assertIdentical(1, count($ajax_commands), 'The field form HTTP request results in one AJAX command.');
     $this->assertIdentical('quickeditFieldForm', $ajax_commands[0]['command'], 'The first AJAX command is a quickeditFieldForm command.');
-    $this->assertIdentical('<form ', Unicode::substr($ajax_commands[0]['data'], 0, 6), 'The quickeditFieldForm command contains a form.');
+    $this->assertIdentical('<form ', mb_substr($ajax_commands[0]['data'], 0, 6), 'The quickeditFieldForm command contains a form.');
 
     // Prepare form values for submission. drupalPostAjaxForm() is not suitable
     // for handling pages with JSON responses, so we need our own solution here.
@@ -286,7 +285,7 @@ public function testUserWithPermission() {
       $ajax_commands = Json::decode($response);
       $this->assertIdentical(1, count($ajax_commands), 'The field form HTTP request results in one AJAX command.');
       $this->assertIdentical('quickeditFieldForm', $ajax_commands[0]['command'], 'The first AJAX command is a quickeditFieldForm command.');
-      $this->assertIdentical('<form ', Unicode::substr($ajax_commands[0]['data'], 0, 6), 'The quickeditFieldForm command contains a form.');
+      $this->assertIdentical('<form ', mb_substr($ajax_commands[0]['data'], 0, 6), 'The quickeditFieldForm command contains a form.');
 
       // Submit field form.
       preg_match('/\sname="form_token" value="([^"]+)"/', $ajax_commands[0]['data'], $token_match);
@@ -389,7 +388,7 @@ public function testTitleBaseField() {
     $ajax_commands = Json::decode($response);
     $this->assertIdentical(1, count($ajax_commands), 'The field form HTTP request results in one AJAX command.');
     $this->assertIdentical('quickeditFieldForm', $ajax_commands[0]['command'], 'The first AJAX command is a quickeditFieldForm command.');
-    $this->assertIdentical('<form ', Unicode::substr($ajax_commands[0]['data'], 0, 6), 'The quickeditFieldForm command contains a form.');
+    $this->assertIdentical('<form ', mb_substr($ajax_commands[0]['data'], 0, 6), 'The quickeditFieldForm command contains a form.');
 
     // Prepare form values for submission. drupalPostAjaxForm() is not suitable
     // for handling pages with JSON responses, so we need our own solution
@@ -602,7 +601,7 @@ public function testImageField() {
     $response = $this->drupalPost('quickedit/form/node/1/field_image/en/full', '', ['nocssjs' => 'true'] + $this->getAjaxPageStatePostData(), ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]);
     $this->assertResponse(200);
     $ajax_commands = Json::decode($response);
-    $this->assertIdentical('<form ', Unicode::substr($ajax_commands[0]['data'], 0, 6), 'The quickeditFieldForm command contains a form.');
+    $this->assertIdentical('<form ', mb_substr($ajax_commands[0]['data'], 0, 6), 'The quickeditFieldForm command contains a form.');
   }
 
 }
diff --git a/core/modules/responsive_image/responsive_image.module b/core/modules/responsive_image/responsive_image.module
index 54dc56c8f7a8..4ea413c44cab 100644
--- a/core/modules/responsive_image/responsive_image.module
+++ b/core/modules/responsive_image/responsive_image.module
@@ -7,7 +7,6 @@
 
 use Drupal\Core\Template\Attribute;
 use Drupal\Core\Logger\RfcLogLevel;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\image\Entity\ImageStyle;
 use Drupal\responsive_image\Entity\ResponsiveImageStyle;
@@ -127,7 +126,7 @@ function template_preprocess_responsive_image_formatter(&$variables) {
   $item = $variables['item'];
   $attributes = [];
   // Do not output an empty 'title' attribute.
-  if (Unicode::strlen($item->title) != 0) {
+  if (mb_strlen($item->title) != 0) {
     $attributes['title'] = $item->title;
   }
   $attributes['alt'] = $item->alt;
@@ -449,7 +448,7 @@ function _responsive_image_build_source_attributes(array $variables, BreakpointI
         // be sorted from small to large, since the first matching source will
         // be used. We multiply it by 100 so multipliers with up to two decimals
         // can be used.
-        $srcset[intval(Unicode::substr($multiplier, 0, -1) * 100)] = _responsive_image_image_style_url($image_style_mapping['image_mapping'], $variables['uri']) . ' ' . $multiplier;
+        $srcset[intval(mb_substr($multiplier, 0, -1) * 100)] = _responsive_image_image_style_url($image_style_mapping['image_mapping'], $variables['uri']) . ' ' . $multiplier;
         break;
     }
   }
diff --git a/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php b/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php
index b50d71be651b..9196135afdc9 100644
--- a/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php
+++ b/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\responsive_image\Tests;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\image\Tests\ImageFieldTestBase;
 use Drupal\image\Entity\ImageStyle;
 use Drupal\node\Entity\Node;
@@ -168,7 +167,7 @@ protected function doTestResponsiveImageFieldFormatters($scheme, $empty_styles =
     /** @var \Drupal\Core\Render\RendererInterface $renderer */
     $renderer = $this->container->get('renderer');
     $node_storage = $this->container->get('entity.manager')->getStorage('node');
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     $this->createImageField($field_name, 'article', ['uri_scheme' => $scheme]);
     // Create a new node with an image attached. Make sure we use a large image
     // so the scale effects of the image styles always have an effect.
@@ -366,7 +365,7 @@ public function testResponsiveImageFieldFormattersEmptyMediaQuery() {
       ])
       ->save();
     $node_storage = $this->container->get('entity.manager')->getStorage('node');
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     $this->createImageField($field_name, 'article', ['uri_scheme' => 'public']);
     // Create a new node with an image attached.
     $test_image = current($this->drupalGetTestFiles('image'));
@@ -414,7 +413,7 @@ public function testResponsiveImageFieldFormattersOneSource() {
         ])
       ->save();
     $node_storage = $this->container->get('entity.manager')->getStorage('node');
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     $this->createImageField($field_name, 'article', ['uri_scheme' => 'public']);
     // Create a new node with an image attached.
     $test_image = current($this->drupalGetTestFiles('image'));
@@ -451,7 +450,7 @@ public function testResponsiveImageFieldFormattersOneSource() {
    *   The link type to test. Either 'file' or 'content'.
    */
   private function assertResponsiveImageFieldFormattersLink($link_type) {
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     $field_settings = ['alt_field_required' => 0];
     $this->createImageField($field_name, 'article', ['uri_scheme' => 'public'], $field_settings);
     // Create a new node with an image attached.
diff --git a/core/modules/search/search.module b/core/modules/search/search.module
index 5be9206bc368..d2560dffcc31 100644
--- a/core/modules/search/search.module
+++ b/core/modules/search/search.module
@@ -265,7 +265,7 @@ function search_simplify($text, $langcode = NULL) {
   $text = Html::decodeEntities($text);
 
   // Lowercase
-  $text = Unicode::strtolower($text);
+  $text = mb_strtolower($text);
 
   // Remove diacritics.
   $text = \Drupal::service('transliteration')->removeDiacritics($text);
@@ -330,7 +330,7 @@ function search_simplify($text, $langcode = NULL) {
 function search_expand_cjk($matches) {
   $min = \Drupal::config('search.settings')->get('index.minimum_word_size');
   $str = $matches[0];
-  $length = Unicode::strlen($str);
+  $length = mb_strlen($str);
   // If the text is shorter than the minimum word size, don't tokenize it.
   if ($length <= $min) {
     return ' ' . $str . ' ';
@@ -340,7 +340,7 @@ function search_expand_cjk($matches) {
   $chars = [];
   for ($i = 0; $i < $length; $i++) {
     // Add the next character off the beginning of the string to the queue.
-    $current = Unicode::substr($str, 0, 1);
+    $current = mb_substr($str, 0, 1);
     $str = substr($str, strlen($current));
     $chars[] = $current;
     if ($i >= $min - 1) {
@@ -473,7 +473,7 @@ function search_index($type, $sid, $langcode, $text) {
     if ($tag) {
       // Increase or decrease score per word based on tag
       list($tagname) = explode(' ', $value, 2);
-      $tagname = Unicode::strtolower($tagname);
+      $tagname = mb_strtolower($tagname);
       // Closing or opening tag?
       if ($tagname[0] == '/') {
         $tagname = substr($tagname, 1);
@@ -511,7 +511,7 @@ function search_index($type, $sid, $langcode, $text) {
           // Add word to accumulator
           $accum .= $word . ' ';
           // Check wordlength
-          if (is_numeric($word) || Unicode::strlen($word) >= $minimum_word_size) {
+          if (is_numeric($word) || mb_strlen($word) >= $minimum_word_size) {
             if (!isset($scored_words[$word])) {
               $scored_words[$word] = 0;
             }
@@ -841,13 +841,13 @@ function _search_find_match_with_simplify($key, $text, $boundary, $langcode = NU
 
   // See if there is a match after lower-casing and removing diacritics in
   // both, which should preserve the string length.
-  $new_text = Unicode::strtolower($text);
+  $new_text = mb_strtolower($text);
   $new_text = \Drupal::service('transliteration')->removeDiacritics($new_text);
-  $new_key = Unicode::strtolower($temp);
+  $new_key = mb_strtolower($temp);
   $new_key = \Drupal::service('transliteration')->removeDiacritics($new_key);
   if (preg_match('/' . $preceded_by_boundary . preg_quote($new_key, '/') . $followed_by_boundary . '/u', ' ' . $new_text . ' ')) {
-    $position = Unicode::strpos($new_text, $new_key);
-    return Unicode::substr($text, $position, Unicode::strlen($new_key));
+    $position = mb_strpos($new_text, $new_key);
+    return mb_substr($text, $position, mb_strlen($new_key));
   }
 
   // Run both text and key through search_simplify.
@@ -876,7 +876,7 @@ function _search_find_match_with_simplify($key, $text, $boundary, $langcode = NU
     $proposed_end_index = floor(($max_end_index + $min_end_index) / 2);
     $proposed_end_pos = $words[$proposed_end_index][1];
     // Since the split was done with preg_split(), the positions are byte counts
-    // not character counts, so use substr() not Unicode::substr() here.
+    // not character counts, so use substr() not mb_substr() here.
     $trial_text = trim(search_simplify(substr($text, $start_pos, $proposed_end_pos - $start_pos), $langcode));
     if (strpos($trial_text, $simplified_key) !== FALSE) {
       // The proposed endpoint is fine, text still matches.
@@ -902,7 +902,7 @@ function _search_find_match_with_simplify($key, $text, $boundary, $langcode = NU
     $proposed_start_index = ceil(($max_start_index + $min_start_index) / 2);
     $proposed_start_pos = $words[$proposed_start_index][1];
     // Since the split was done with preg_split(), the positions are byte counts
-    // not character counts, so use substr() not Unicode::substr() here.
+    // not character counts, so use substr() not mb_substr() here.
     $trial_text = trim(search_simplify(substr($text, $proposed_start_pos, $end_pos - $proposed_start_pos), $langcode));
     if (strpos($trial_text, $simplified_key) !== FALSE) {
       // The proposed start point is fine, text still matches.
@@ -917,9 +917,8 @@ function _search_find_match_with_simplify($key, $text, $boundary, $langcode = NU
   $start_index = $max_start_index;
 
   // Return the matching text. We need to use substr() here and not the
-  // Unicode::substr() function, because the indices in $words came from
-  // preg_split(), so they are Unicode-safe byte positions, not character
-  // positions.
+  // mb_substr() function, because the indices in $words came from preg_split(),
+  // so they are Unicode-safe byte positions, not character positions.
   return trim(substr($text, $words[$start_index][1], $words[$end_index][1] - $words[$start_index][1]));
 }
 
diff --git a/core/modules/search/src/SearchQuery.php b/core/modules/search/src/SearchQuery.php
index fca2b23b76f3..6446fa4ed507 100644
--- a/core/modules/search/src/SearchQuery.php
+++ b/core/modules/search/src/SearchQuery.php
@@ -3,7 +3,6 @@
 namespace Drupal\search;
 
 use Drupal\Core\Database\Query\Condition;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Database\Query\SelectExtender;
 use Drupal\Core\Database\Query\SelectInterface;
 
@@ -364,7 +363,7 @@ protected function parseWord($word) {
     $split = explode(' ', $word);
     foreach ($split as $s) {
       $num = is_numeric($s);
-      if ($num || Unicode::strlen($s) >= \Drupal::config('search.settings')->get('index.minimum_word_size')) {
+      if ($num || mb_strlen($s) >= \Drupal::config('search.settings')->get('index.minimum_word_size')) {
         if (!isset($this->words[$s])) {
           $this->words[$s] = $s;
           $num_new_scores++;
diff --git a/core/modules/search/tests/src/Functional/SearchSimplifyTest.php b/core/modules/search/tests/src/Functional/SearchSimplifyTest.php
index c30611991295..1c30c2e3639e 100644
--- a/core/modules/search/tests/src/Functional/SearchSimplifyTest.php
+++ b/core/modules/search/tests/src/Functional/SearchSimplifyTest.php
@@ -2,8 +2,6 @@
 
 namespace Drupal\Tests\search\Functional;
 
-use Drupal\Component\Utility\Unicode;
-
 /**
  * Tests that the search_simply() function works as intended.
  *
@@ -35,8 +33,8 @@ public function testSearchSimplifyUnicode() {
         // Split this into 30-character chunks, so we don't run into limits
         // of truncation in search_simplify().
         $start = 0;
-        while ($start < Unicode::strlen($string)) {
-          $newstr = Unicode::substr($string, $start, 30);
+        while ($start < mb_strlen($string)) {
+          $newstr = mb_substr($string, $start, 30);
           // Special case: leading zeros are removed from numeric strings,
           // and there's one string in this file that is numbers starting with
           // zero, so prepend a 1 on that string.
@@ -50,7 +48,7 @@ public function testSearchSimplifyUnicode() {
     }
     foreach ($strings as $key => $string) {
       $simplified = search_simplify($string);
-      $this->assertTrue(Unicode::strlen($simplified) >= Unicode::strlen($string), "Nothing is removed from string $key.");
+      $this->assertTrue(mb_strlen($simplified) >= mb_strlen($string), "Nothing is removed from string $key.");
     }
 
     // Test the low-numbered ASCII control characters separately. They are not
diff --git a/core/modules/search/tests/src/Functional/SearchTokenizerTest.php b/core/modules/search/tests/src/Functional/SearchTokenizerTest.php
index 218ec185b1d3..7862ea644867 100644
--- a/core/modules/search/tests/src/Functional/SearchTokenizerTest.php
+++ b/core/modules/search/tests/src/Functional/SearchTokenizerTest.php
@@ -2,8 +2,6 @@
 
 namespace Drupal\Tests\search\Functional;
 
-use Drupal\Component\Utility\Unicode;
-
 /**
  * Tests that CJK tokenizer works as intended.
  *
@@ -95,7 +93,7 @@ public function testTokenizer() {
     // Merge into a string and tokenize.
     $string = implode('', $chars);
     $out = trim(search_simplify($string));
-    $expected = Unicode::strtolower(implode(' ', $chars));
+    $expected = mb_strtolower(implode(' ', $chars));
 
     // Verify that the output matches what we expect.
     $this->assertEqual($out, $expected, 'CJK tokenizer worked on all supplied CJK characters');
diff --git a/core/modules/system/src/Controller/EntityAutocompleteController.php b/core/modules/system/src/Controller/EntityAutocompleteController.php
index 974c2ded3374..88c367f2822a 100644
--- a/core/modules/system/src/Controller/EntityAutocompleteController.php
+++ b/core/modules/system/src/Controller/EntityAutocompleteController.php
@@ -4,7 +4,6 @@
 
 use Drupal\Component\Utility\Crypt;
 use Drupal\Component\Utility\Tags;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Controller\ControllerBase;
 use Drupal\Core\Entity\EntityAutocompleteMatcher;
 use Drupal\Core\KeyValueStore\KeyValueStoreInterface;
@@ -81,7 +80,7 @@ public function handleAutocomplete(Request $request, $target_type, $selection_ha
     // Get the typed string from the URL, if it exists.
     if ($input = $request->query->get('q')) {
       $typed_string = Tags::explode($input);
-      $typed_string = Unicode::strtolower(array_pop($typed_string));
+      $typed_string = mb_strtolower(array_pop($typed_string));
 
       // Selection settings are passed in as a hashed key of a serialized array
       // stored in the key/value store.
diff --git a/core/modules/system/src/MachineNameController.php b/core/modules/system/src/MachineNameController.php
index d6310f4599aa..ef8bff2bc319 100644
--- a/core/modules/system/src/MachineNameController.php
+++ b/core/modules/system/src/MachineNameController.php
@@ -3,7 +3,6 @@
 namespace Drupal\system;
 
 use Drupal\Component\Transliteration\TransliterationInterface;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Access\CsrfTokenGenerator;
 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
 use Symfony\Component\HttpFoundation\JsonResponse;
@@ -73,7 +72,7 @@ public function transliterate(Request $request) {
 
     $transliterated = $this->transliteration->transliterate($text, $langcode, '_');
     if ($lowercase) {
-      $transliterated = Unicode::strtolower($transliterated);
+      $transliterated = mb_strtolower($transliterated);
     }
 
     if (isset($replace_pattern) && isset($replace)) {
diff --git a/core/modules/system/src/Plugin/Condition/RequestPath.php b/core/modules/system/src/Plugin/Condition/RequestPath.php
index ae9d77da21a7..1f73624774be 100644
--- a/core/modules/system/src/Plugin/Condition/RequestPath.php
+++ b/core/modules/system/src/Plugin/Condition/RequestPath.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\system\Plugin\Condition;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Condition\ConditionPluginBase;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Path\AliasManagerInterface;
@@ -139,7 +138,7 @@ public function summary() {
   public function evaluate() {
     // Convert path to lowercase. This allows comparison of the same path
     // with different case. Ex: /Page, /page, /PAGE.
-    $pages = Unicode::strtolower($this->configuration['pages']);
+    $pages = mb_strtolower($this->configuration['pages']);
     if (!$pages) {
       return TRUE;
     }
@@ -149,7 +148,7 @@ public function evaluate() {
     $path = $this->currentPath->getPath($request);
     // Do not trim a trailing slash if that is the complete path.
     $path = $path === '/' ? $path : rtrim($path, '/');
-    $path_alias = Unicode::strtolower($this->aliasManager->getAliasByPath($path));
+    $path_alias = mb_strtolower($this->aliasManager->getAliasByPath($path));
 
     return $this->pathMatcher->matchPath($path_alias, $pages) || (($path != $path_alias) && $this->pathMatcher->matchPath($path, $pages));
   }
diff --git a/core/modules/system/src/Plugin/ImageToolkit/GDToolkit.php b/core/modules/system/src/Plugin/ImageToolkit/GDToolkit.php
index 308a8075b51f..eafda1d5a391 100644
--- a/core/modules/system/src/Plugin/ImageToolkit/GDToolkit.php
+++ b/core/modules/system/src/Plugin/ImageToolkit/GDToolkit.php
@@ -3,7 +3,6 @@
 namespace Drupal\system\Plugin\ImageToolkit;
 
 use Drupal\Component\Utility\Color;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\ImageToolkit\ImageToolkitBase;
@@ -395,7 +394,7 @@ public static function getSupportedExtensions() {
     foreach (static::supportedTypes() as $image_type) {
       // @todo Automatically fetch possible extensions for each mime type.
       // @see https://www.drupal.org/node/2311679
-      $extension = Unicode::strtolower(image_type_to_extension($image_type, FALSE));
+      $extension = mb_strtolower(image_type_to_extension($image_type, FALSE));
       $extensions[] = $extension;
       // Add some known similar extensions.
       if ($extension === 'jpeg') {
diff --git a/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/TestToolkit.php b/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/TestToolkit.php
index a0f508041bd7..48e0722402ca 100644
--- a/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/TestToolkit.php
+++ b/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/TestToolkit.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\image_test\Plugin\ImageToolkit;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\ImageToolkit\ImageToolkitBase;
@@ -238,7 +237,7 @@ public static function isAvailable() {
   public static function getSupportedExtensions() {
     $extensions = [];
     foreach (static::supportedTypes() as $image_type) {
-      $extensions[] = Unicode::strtolower(image_type_to_extension($image_type, FALSE));
+      $extensions[] = mb_strtolower(image_type_to_extension($image_type, FALSE));
     }
     return $extensions;
   }
diff --git a/core/modules/system/tests/src/Functional/Mail/HtmlToTextTest.php b/core/modules/system/tests/src/Functional/Mail/HtmlToTextTest.php
index bdbfd749c948..82410fd52a7c 100644
--- a/core/modules/system/tests/src/Functional/Mail/HtmlToTextTest.php
+++ b/core/modules/system/tests/src/Functional/Mail/HtmlToTextTest.php
@@ -3,7 +3,6 @@
 namespace Drupal\Tests\system\Functional\Mail;
 
 use Drupal\Component\Utility\Html;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Mail\MailFormatHelper;
 use Drupal\Core\Site\Settings;
 use Drupal\Tests\BrowserTestBase;
@@ -48,7 +47,7 @@ protected function stringToHtml($text) {
    *   \Drupal\Core\Mail\MailFormatHelper::htmlToText().
    */
   protected function assertHtmlToText($html, $text, $message, $allowed_tags = NULL) {
-    preg_match_all('/<([a-z0-6]+)/', Unicode::strtolower($html), $matches);
+    preg_match_all('/<([a-z0-6]+)/', mb_strtolower($html), $matches);
     $tested_tags = implode(', ', array_unique($matches[1]));
     $message .= ' (' . $tested_tags . ')';
     $result = MailFormatHelper::htmlToText($html, $allowed_tags);
@@ -241,8 +240,8 @@ public function testDrupalHtmlToTextBlockTagToNewline() {
     if (!$pass) {
       $this->verbose($this->stringToHtml($output));
     }
-    $output_upper = Unicode::strtoupper($output);
-    $upper_input = Unicode::strtoupper($input);
+    $output_upper = mb_strtoupper($output);
+    $upper_input = mb_strtoupper($input);
     $upper_output = MailFormatHelper::htmlToText($upper_input);
     $pass = $this->assertEqual(
       $upper_output,
@@ -347,8 +346,8 @@ public function testVeryLongLineWrap() {
 
     $maximum_line_length = 0;
     foreach (explode($eol, $output) as $line) {
-      // We must use strlen() rather than Unicode::strlen() in order to count
-      // octets rather than characters.
+      // We must use strlen() rather than mb_strlen() in order to count octets
+      // rather than characters.
       $maximum_line_length = max($maximum_line_length, strlen($line . $eol));
     }
     $verbose = 'Maximum line length found was ' . $maximum_line_length . ' octets.';
diff --git a/core/modules/system/tests/src/Functional/Module/PrepareUninstallTest.php b/core/modules/system/tests/src/Functional/Module/PrepareUninstallTest.php
index cf577709728e..5edaf42afe50 100644
--- a/core/modules/system/tests/src/Functional/Module/PrepareUninstallTest.php
+++ b/core/modules/system/tests/src/Functional/Module/PrepareUninstallTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\system\Functional\Module;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Tests\BrowserTestBase;
 use Drupal\Tests\taxonomy\Functional\TaxonomyTestTrait;
 
@@ -162,14 +161,14 @@ public function testUninstall() {
     $storage = $this->container->get('entity.manager')
       ->getStorage('entity_test_no_label');
     $storage->create([
-      'id' => Unicode::strtolower($this->randomMachineName()),
+      'id' => mb_strtolower($this->randomMachineName()),
       'name' => $this->randomMachineName(),
     ])->save();
     $this->drupalGet('admin/modules/uninstall/entity/entity_test_no_label');
     $this->assertText('This will delete 1 entity test without label.');
     $this->assertFieldByXPath($button_xpath, NULL, 'Button with value "Delete all entity test without label entities" found');
     $storage->create([
-      'id' => Unicode::strtolower($this->randomMachineName()),
+      'id' => mb_strtolower($this->randomMachineName()),
       'name' => $this->randomMachineName(),
     ])->save();
     $this->drupalGet('admin/modules/uninstall/entity/entity_test_no_label');
diff --git a/core/modules/system/tests/src/Functional/System/DateFormatsMachineNameTest.php b/core/modules/system/tests/src/Functional/System/DateFormatsMachineNameTest.php
index 7ff8af1fa4b8..fd88bdc77fd2 100644
--- a/core/modules/system/tests/src/Functional/System/DateFormatsMachineNameTest.php
+++ b/core/modules/system/tests/src/Functional/System/DateFormatsMachineNameTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\system\Functional\System;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Tests\BrowserTestBase;
 
 /**
@@ -56,7 +55,7 @@ public function testDateFormatsMachineNameAllowedValues() {
     $this->assertText(t('The machine-readable name is already in use. It must be unique.'), 'It is not possible to create a date format with the machine name "fallback". It is a built-in format that already exists.');
 
     // Create a date format with a machine name distinct from the previous two.
-    $id = Unicode::strtolower($this->randomMachineName(16));
+    $id = mb_strtolower($this->randomMachineName(16));
     $edit = [
       'label' => $this->randomMachineName(16),
       'id' => $id,
diff --git a/core/modules/system/tests/src/Kernel/Entity/EntityReferenceSelectionReferenceableTest.php b/core/modules/system/tests/src/Kernel/Entity/EntityReferenceSelectionReferenceableTest.php
index f7fa5d87be46..8ccca7e44f42 100644
--- a/core/modules/system/tests/src/Kernel/Entity/EntityReferenceSelectionReferenceableTest.php
+++ b/core/modules/system/tests/src/Kernel/Entity/EntityReferenceSelectionReferenceableTest.php
@@ -3,7 +3,6 @@
 namespace Drupal\Tests\system\Kernel\Entity;
 
 use Drupal\Component\Utility\Html;
-use Drupal\Component\Utility\Unicode;
 use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\node\Entity\NodeType;
@@ -58,24 +57,24 @@ protected function setUp() {
 
     // Create a new node-type.
     NodeType::create([
-      'type' => $node_type = Unicode::strtolower($this->randomMachineName()),
+      'type' => $node_type = mb_strtolower($this->randomMachineName()),
       'name' => $this->randomString(),
     ])->save();
 
     // Create an entity reference field targeting 'entity_test_no_label'
     // entities.
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     $this->createEntityReferenceField('node', $node_type, $field_name, $this->randomString(), 'entity_test_no_label');
     $field_config = FieldConfig::loadByName('node', $node_type, $field_name);
     $this->selectionHandler = $this->container->get('plugin.manager.entity_reference_selection')->getSelectionHandler($field_config);
 
     // Generate a bundle name to be used with 'entity_test_no_label'.
-    $this->bundle = Unicode::strtolower($this->randomMachineName());
+    $this->bundle = mb_strtolower($this->randomMachineName());
 
     // Create 6 entities to be referenced by the field.
     foreach (static::$labels as $name) {
       $storage->create([
-        'id' => Unicode::strtolower($this->randomMachineName()),
+        'id' => mb_strtolower($this->randomMachineName()),
         'name' => $name,
         'type' => $this->bundle,
       ])->save();
diff --git a/core/modules/taxonomy/src/Tests/TaxonomyTestTrait.php b/core/modules/taxonomy/src/Tests/TaxonomyTestTrait.php
index 8c4a6672703d..a1b4a552144a 100644
--- a/core/modules/taxonomy/src/Tests/TaxonomyTestTrait.php
+++ b/core/modules/taxonomy/src/Tests/TaxonomyTestTrait.php
@@ -4,7 +4,6 @@
 
 @trigger_error(__NAMESPACE__ . '\TaxonomyTestTrait is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\taxonomy\Functional\TaxonomyTestTrait', E_USER_DEPRECATED);
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\taxonomy\Entity\Vocabulary;
 use Drupal\taxonomy\Entity\Term;
@@ -25,7 +24,7 @@ public function createVocabulary() {
     $vocabulary = Vocabulary::create([
       'name' => $this->randomMachineName(),
       'description' => $this->randomMachineName(),
-      'vid' => Unicode::strtolower($this->randomMachineName()),
+      'vid' => mb_strtolower($this->randomMachineName()),
       'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
       'weight' => mt_rand(0, 10),
     ]);
diff --git a/core/modules/taxonomy/src/Tests/TermAutocompleteTest.php b/core/modules/taxonomy/src/Tests/TermAutocompleteTest.php
index 7ff519df9403..00f0ee784b69 100644
--- a/core/modules/taxonomy/src/Tests/TermAutocompleteTest.php
+++ b/core/modules/taxonomy/src/Tests/TermAutocompleteTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\taxonomy\Tests;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Entity\Entity\EntityFormDisplay;
 use Drupal\Core\Entity\Entity\EntityViewDisplay;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
@@ -86,7 +85,7 @@ protected function setUp() {
 
     // Create a taxonomy_term_reference field on the article Content Type that
     // uses a taxonomy_autocomplete widget.
-    $this->fieldName = Unicode::strtolower($this->randomMachineName());
+    $this->fieldName = mb_strtolower($this->randomMachineName());
     FieldStorageConfig::create([
       'field_name' => $this->fieldName,
       'entity_type' => 'node',
diff --git a/core/modules/taxonomy/src/Tests/TermTest.php b/core/modules/taxonomy/src/Tests/TermTest.php
index 42f92b1b4b43..abcde83d3301 100644
--- a/core/modules/taxonomy/src/Tests/TermTest.php
+++ b/core/modules/taxonomy/src/Tests/TermTest.php
@@ -3,7 +3,6 @@
 namespace Drupal\taxonomy\Tests;
 
 use Drupal\Component\Utility\Tags;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\taxonomy\Entity\Term;
@@ -490,7 +489,7 @@ public function testTaxonomyGetTermByName() {
     $this->assertFalse($terms, 'No term loaded with an invalid name.');
 
     // Try to load the term using a substring of the name.
-    $terms = taxonomy_term_load_multiple_by_name(Unicode::substr($term->getName(), 2), 'No term loaded with a substring of the name.');
+    $terms = taxonomy_term_load_multiple_by_name(mb_substr($term->getName(), 2), 'No term loaded with a substring of the name.');
     $this->assertFalse($terms);
 
     // Create a new term in a different vocabulary with the same name.
diff --git a/core/modules/taxonomy/tests/src/Functional/TaxonomyTestTrait.php b/core/modules/taxonomy/tests/src/Functional/TaxonomyTestTrait.php
index db445e962bd5..8dcdf170073f 100644
--- a/core/modules/taxonomy/tests/src/Functional/TaxonomyTestTrait.php
+++ b/core/modules/taxonomy/tests/src/Functional/TaxonomyTestTrait.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\taxonomy\Functional;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\taxonomy\Entity\Vocabulary;
 use Drupal\taxonomy\Entity\Term;
@@ -20,7 +19,7 @@ public function createVocabulary() {
     $vocabulary = Vocabulary::create([
       'name' => $this->randomMachineName(),
       'description' => $this->randomMachineName(),
-      'vid' => Unicode::strtolower($this->randomMachineName()),
+      'vid' => mb_strtolower($this->randomMachineName()),
       'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
       'weight' => mt_rand(0, 10),
     ]);
diff --git a/core/modules/taxonomy/tests/src/Functional/TermIndexTest.php b/core/modules/taxonomy/tests/src/Functional/TermIndexTest.php
index d4fe8f225b6f..83ab04d5e13e 100644
--- a/core/modules/taxonomy/tests/src/Functional/TermIndexTest.php
+++ b/core/modules/taxonomy/tests/src/Functional/TermIndexTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\taxonomy\Functional;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
 
 /**
@@ -49,7 +48,7 @@ protected function setUp() {
     // Create a vocabulary and add two term reference fields to article nodes.
     $this->vocabulary = $this->createVocabulary();
 
-    $this->fieldName1 = Unicode::strtolower($this->randomMachineName());
+    $this->fieldName1 = mb_strtolower($this->randomMachineName());
     $handler_settings = [
       'target_bundles' => [
         $this->vocabulary->id() => $this->vocabulary->id(),
@@ -69,7 +68,7 @@ protected function setUp() {
       ])
       ->save();
 
-    $this->fieldName2 = Unicode::strtolower($this->randomMachineName());
+    $this->fieldName2 = mb_strtolower($this->randomMachineName());
     $this->createEntityReferenceField('node', 'article', $this->fieldName2, NULL, 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
 
     entity_get_form_display('node', 'article', 'default')
diff --git a/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyTermViewTest.php b/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyTermViewTest.php
index f69c49c7147c..fc0cddce484b 100644
--- a/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyTermViewTest.php
+++ b/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyTermViewTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\taxonomy\Functional\Views;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
 use Drupal\language\Entity\ConfigurableLanguage;
 use Drupal\node\Entity\Node;
@@ -50,7 +49,7 @@ protected function setUp($import_test_views = TRUE) {
 
     // Create a vocabulary and add two term reference fields to article nodes.
 
-    $this->fieldName1 = Unicode::strtolower($this->randomMachineName());
+    $this->fieldName1 = mb_strtolower($this->randomMachineName());
 
     $handler_settings = [
       'target_bundles' => [
diff --git a/core/modules/taxonomy/tests/src/Functional/VocabularyCrudTest.php b/core/modules/taxonomy/tests/src/Functional/VocabularyCrudTest.php
index 2ac2d9de6124..f7c2f7c1e23a 100644
--- a/core/modules/taxonomy/tests/src/Functional/VocabularyCrudTest.php
+++ b/core/modules/taxonomy/tests/src/Functional/VocabularyCrudTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\taxonomy\Functional;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\taxonomy\Entity\Vocabulary;
 use Drupal\field\Entity\FieldStorageConfig;
@@ -144,7 +143,7 @@ public function testTaxonomyVocabularyLoadMultiple() {
   public function testUninstallReinstall() {
     // Field storages and fields attached to taxonomy term bundles should be
     // removed when the module is uninstalled.
-    $field_name = Unicode::strtolower($this->randomMachineName() . '_field_name');
+    $field_name = mb_strtolower($this->randomMachineName() . '_field_name');
     $storage_definition = [
       'field_name' => $field_name,
       'entity_type' => 'taxonomy_term',
diff --git a/core/modules/taxonomy/tests/src/Functional/VocabularyLanguageTest.php b/core/modules/taxonomy/tests/src/Functional/VocabularyLanguageTest.php
index f25df8a1fdcf..c94d64e287d8 100644
--- a/core/modules/taxonomy/tests/src/Functional/VocabularyLanguageTest.php
+++ b/core/modules/taxonomy/tests/src/Functional/VocabularyLanguageTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\taxonomy\Functional;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\language\Entity\ConfigurableLanguage;
 use Drupal\language\Entity\ContentLanguageSettings;
 
@@ -43,7 +42,7 @@ public function testVocabularyLanguage() {
     $this->assertField('edit-langcode', 'The language selector field was found on the page.');
 
     // Create the vocabulary.
-    $vid = Unicode::strtolower($this->randomMachineName());
+    $vid = mb_strtolower($this->randomMachineName());
     $edit['name'] = $this->randomMachineName();
     $edit['description'] = $this->randomMachineName();
     $edit['langcode'] = 'aa';
@@ -72,7 +71,7 @@ public function testVocabularyDefaultLanguageForTerms() {
     // the terms are saved.
     $edit = [
       'name' => $this->randomMachineName(),
-      'vid' => Unicode::strtolower($this->randomMachineName()),
+      'vid' => mb_strtolower($this->randomMachineName()),
       'default_language[langcode]' => 'bb',
       'default_language[language_alterable]' => TRUE,
     ];
diff --git a/core/modules/taxonomy/tests/src/Functional/VocabularyTranslationTest.php b/core/modules/taxonomy/tests/src/Functional/VocabularyTranslationTest.php
index 2d312578e755..aa98ac33300b 100644
--- a/core/modules/taxonomy/tests/src/Functional/VocabularyTranslationTest.php
+++ b/core/modules/taxonomy/tests/src/Functional/VocabularyTranslationTest.php
@@ -2,8 +2,6 @@
 
 namespace Drupal\Tests\taxonomy\Functional;
 
-use Drupal\Component\Utility\Unicode;
-
 /**
  * Tests content translation for vocabularies.
  *
@@ -39,7 +37,7 @@ public function testVocabularyLanguage() {
     $this->assertField('edit-default-language-content-translation', 'The content translation checkbox is present on the page.');
 
     // Create the vocabulary.
-    $vid = Unicode::strtolower($this->randomMachineName());
+    $vid = mb_strtolower($this->randomMachineName());
     $edit['name'] = $this->randomMachineName();
     $edit['description'] = $this->randomMachineName();
     $edit['langcode'] = 'en';
diff --git a/core/modules/taxonomy/tests/src/Functional/VocabularyUiTest.php b/core/modules/taxonomy/tests/src/Functional/VocabularyUiTest.php
index e39a0d855540..2620cb8fc479 100644
--- a/core/modules/taxonomy/tests/src/Functional/VocabularyUiTest.php
+++ b/core/modules/taxonomy/tests/src/Functional/VocabularyUiTest.php
@@ -2,8 +2,6 @@
 
 namespace Drupal\Tests\taxonomy\Functional;
 
-use Drupal\Component\Utility\Unicode;
-
 use Drupal\Core\Url;
 use Drupal\taxonomy\Entity\Vocabulary;
 
@@ -39,7 +37,7 @@ public function testVocabularyInterface() {
     // Create a new vocabulary.
     $this->clickLink(t('Add vocabulary'));
     $edit = [];
-    $vid = Unicode::strtolower($this->randomMachineName());
+    $vid = mb_strtolower($this->randomMachineName());
     $edit['name'] = $this->randomMachineName();
     $edit['description'] = $this->randomMachineName();
     $edit['vid'] = $vid;
@@ -131,7 +129,7 @@ public function testTaxonomyAdminNoVocabularies() {
    */
   public function testTaxonomyAdminDeletingVocabulary() {
     // Create a vocabulary.
-    $vid = Unicode::strtolower($this->randomMachineName());
+    $vid = mb_strtolower($this->randomMachineName());
     $edit = [
       'name' => $this->randomMachineName(),
       'vid' => $vid,
diff --git a/core/modules/text/src/Tests/TextFieldTest.php b/core/modules/text/src/Tests/TextFieldTest.php
index f3fb43f2d5b5..52286a63ac95 100644
--- a/core/modules/text/src/Tests/TextFieldTest.php
+++ b/core/modules/text/src/Tests/TextFieldTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\text\Tests;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\entity_test\Entity\EntityTest;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Tests\String\StringFieldTest;
@@ -37,7 +36,7 @@ protected function setUp() {
   public function testTextFieldValidation() {
     // Create a field with settings to validate.
     $max_length = 3;
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     $field_storage = FieldStorageConfig::create([
       'field_name' => $field_name,
       'entity_type' => 'entity_test',
@@ -149,7 +148,7 @@ public function _testTextfieldWidgetsFormatted($field_type, $widget_type) {
     $renderer = $this->container->get('renderer');
 
     // Create a field.
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     $field_storage = FieldStorageConfig::create([
       'field_name' => $field_name,
       'entity_type' => 'entity_test',
@@ -207,7 +206,7 @@ public function _testTextfieldWidgetsFormatted($field_type, $widget_type) {
     // access to it.
     $this->drupalLogin($this->adminUser);
     $edit = [
-      'format' => Unicode::strtolower($this->randomMachineName()),
+      'format' => mb_strtolower($this->randomMachineName()),
       'name' => $this->randomMachineName(),
     ];
     $this->drupalPostForm('admin/config/content/formats/add', $edit, t('Save configuration'));
diff --git a/core/modules/text/text.module b/core/modules/text/text.module
index b88fdc1fd74c..a8c2b847fe42 100644
--- a/core/modules/text/text.module
+++ b/core/modules/text/text.module
@@ -91,7 +91,7 @@ function text_summary($text, $format = NULL, $size = NULL) {
   }
 
   // If we have a short body, the entire body is the summary.
-  if (Unicode::strlen($text) <= $size) {
+  if (mb_strlen($text) <= $size) {
     return $text;
   }
 
diff --git a/core/modules/update/update.report.inc b/core/modules/update/update.report.inc
index 7b14a0585258..91864632dcf8 100644
--- a/core/modules/update/update.report.inc
+++ b/core/modules/update/update.report.inc
@@ -5,7 +5,6 @@
  * Code required only when rendering the available updates report.
  */
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Template\Attribute;
 use Drupal\Core\Url;
 
@@ -54,7 +53,7 @@ function template_preprocess_update_report(&$variables) {
         '#attributes' => ['class' => ['update']],
       ];
     }
-    $row_key = !empty($project['title']) ? Unicode::strtolower($project['title']) : Unicode::strtolower($project['name']);
+    $row_key = !empty($project['title']) ? mb_strtolower($project['title']) : mb_strtolower($project['name']);
 
     // Add the project status row and details.
     $rows[$project['project_type']][$row_key]['status'] = $project_status;
diff --git a/core/modules/user/src/Plugin/Validation/Constraint/UserNameConstraintValidator.php b/core/modules/user/src/Plugin/Validation/Constraint/UserNameConstraintValidator.php
index 9e4776bdcaf8..7e41ed15cd29 100644
--- a/core/modules/user/src/Plugin/Validation/Constraint/UserNameConstraintValidator.php
+++ b/core/modules/user/src/Plugin/Validation/Constraint/UserNameConstraintValidator.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\user\Plugin\Validation\Constraint;
 
-use Drupal\Component\Utility\Unicode;
 use Symfony\Component\Validator\Constraint;
 use Symfony\Component\Validator\ConstraintValidator;
 
@@ -53,7 +52,7 @@ public function validate($items, Constraint $constraint) {
     ) {
       $this->context->addViolation($constraint->illegalMessage);
     }
-    if (Unicode::strlen($name) > USERNAME_MAX_LENGTH) {
+    if (mb_strlen($name) > USERNAME_MAX_LENGTH) {
       $this->context->addViolation($constraint->tooLongMessage, ['%name' => $name, '%max' => USERNAME_MAX_LENGTH]);
     }
   }
diff --git a/core/modules/user/src/Plugin/migrate/destination/EntityUser.php b/core/modules/user/src/Plugin/migrate/destination/EntityUser.php
index 1f2917f5596d..316d063bf742 100644
--- a/core/modules/user/src/Plugin/migrate/destination/EntityUser.php
+++ b/core/modules/user/src/Plugin/migrate/destination/EntityUser.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\user\Plugin\migrate\destination;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Entity\ContentEntityInterface;
 use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Entity\EntityStorageInterface;
@@ -168,8 +167,8 @@ protected function processStubRow(Row $row) {
     if (is_array($name)) {
       $name = reset($name);
     }
-    if (Unicode::strlen($name) > USERNAME_MAX_LENGTH) {
-      $row->setDestinationProperty('name', Unicode::substr($name, 0, USERNAME_MAX_LENGTH));
+    if (mb_strlen($name) > USERNAME_MAX_LENGTH) {
+      $row->setDestinationProperty('name', mb_substr($name, 0, USERNAME_MAX_LENGTH));
     }
   }
 
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 0683e882b7e2..db016a1c3e0c 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -493,7 +493,7 @@ function template_preprocess_username(&$variables) {
   // that $variables['name'] is safe for printing.
   $name  = $account->getDisplayName();
   $variables['name_raw'] = $account->getUsername();
-  if (Unicode::strlen($name) > 20) {
+  if (mb_strlen($name) > 20) {
     $name = Unicode::truncate($name, 15, FALSE, TRUE);
     $variables['truncated'] = TRUE;
   }
diff --git a/core/modules/views/src/Plugin/views/HandlerBase.php b/core/modules/views/src/Plugin/views/HandlerBase.php
index a50f9cdab393..35689ee077dc 100644
--- a/core/modules/views/src/Plugin/views/HandlerBase.php
+++ b/core/modules/views/src/Plugin/views/HandlerBase.php
@@ -230,9 +230,9 @@ protected function caseTransform($string, $option) {
       default:
         return $string;
       case 'upper':
-        return Unicode::strtoupper($string);
+        return mb_strtoupper($string);
       case 'lower':
-        return Unicode::strtolower($string);
+        return mb_strtolower($string);
       case 'ucfirst':
         return Unicode::ucfirst($string);
       case 'ucwords':
diff --git a/core/modules/views/src/Plugin/views/argument/StringArgument.php b/core/modules/views/src/Plugin/views/argument/StringArgument.php
index 6058d6618b6d..7bde8ff5c7c8 100644
--- a/core/modules/views/src/Plugin/views/argument/StringArgument.php
+++ b/core/modules/views/src/Plugin/views/argument/StringArgument.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\views\Plugin\views\argument;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Database\Database;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Plugin\Context\ContextDefinition;
@@ -214,7 +213,7 @@ public function query($group_by = FALSE) {
     // converting the arguments to lowercase.
     if ($this->options['case'] != 'none' && Database::getConnection()->databaseType() == 'pgsql') {
       foreach ($this->value as $key => $value) {
-        $this->value[$key] = Unicode::strtolower($value);
+        $this->value[$key] = mb_strtolower($value);
       }
     }
 
diff --git a/core/modules/views/src/Plugin/views/field/FieldPluginBase.php b/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
index 78c6a1281626..033bda0784c0 100644
--- a/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
+++ b/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
@@ -4,7 +4,6 @@
 
 use Drupal\Component\Utility\Html;
 use Drupal\Component\Render\MarkupInterface;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Component\Utility\UrlHelper;
 use Drupal\Component\Utility\Xss;
 use Drupal\Core\Form\FormStateInterface;
@@ -1288,7 +1287,7 @@ public function renderText($alter) {
         $base_path = base_path();
         // Checks whether the path starts with the base_path.
         if (strpos($more_link_path, $base_path) === 0) {
-          $more_link_path = Unicode::substr($more_link_path, Unicode::strlen($base_path));
+          $more_link_path = mb_substr($more_link_path, mb_strlen($base_path));
         }
 
         // @todo Views should expect and store a leading /. See
@@ -1792,8 +1791,8 @@ public function adminLabel($short = FALSE) {
    *   The trimmed string.
    */
   public static function trimText($alter, $value) {
-    if (Unicode::strlen($value) > $alter['max_length']) {
-      $value = Unicode::substr($value, 0, $alter['max_length']);
+    if (mb_strlen($value) > $alter['max_length']) {
+      $value = mb_substr($value, 0, $alter['max_length']);
       if (!empty($alter['word_boundary'])) {
         $regex = "(.*)\b.+";
         if (function_exists('mb_ereg')) {
diff --git a/core/modules/views/src/Plugin/views/filter/InOperator.php b/core/modules/views/src/Plugin/views/filter/InOperator.php
index 1e6682d69aa2..e0add0fcb1bb 100644
--- a/core/modules/views/src/Plugin/views/filter/InOperator.php
+++ b/core/modules/views/src/Plugin/views/filter/InOperator.php
@@ -369,7 +369,7 @@ public function adminSummary() {
           if ($values !== '') {
             $values .= ', ';
           }
-          if (Unicode::strlen($values) > 8) {
+          if (mb_strlen($values) > 8) {
             $values = Unicode::truncate($values, 8, FALSE, TRUE);
             break;
           }
diff --git a/core/modules/views/src/ViewsDataHelper.php b/core/modules/views/src/ViewsDataHelper.php
index b6364a723427..6a9188bee681 100644
--- a/core/modules/views/src/ViewsDataHelper.php
+++ b/core/modules/views/src/ViewsDataHelper.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\views;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Component\Render\FormattableMarkup;
 
 /**
@@ -174,14 +173,14 @@ public function fetchFields($base, $type, $grouping = FALSE, $sub_type = NULL) {
    *   decided.
    */
   protected static function fetchedFieldSort($a, $b) {
-    $a_group = Unicode::strtolower($a['group']);
-    $b_group = Unicode::strtolower($b['group']);
+    $a_group = mb_strtolower($a['group']);
+    $b_group = mb_strtolower($b['group']);
     if ($a_group != $b_group) {
       return $a_group < $b_group ? -1 : 1;
     }
 
-    $a_title = Unicode::strtolower($a['title']);
-    $b_title = Unicode::strtolower($b['title']);
+    $a_title = mb_strtolower($a['title']);
+    $b_title = mb_strtolower($b['title']);
     if ($a_title != $b_title) {
       return $a_title < $b_title ? -1 : 1;
     }
diff --git a/core/modules/views/tests/src/Functional/DefaultViewsTest.php b/core/modules/views/tests/src/Functional/DefaultViewsTest.php
index 9e4c338ddc74..c3e8f56dbf54 100644
--- a/core/modules/views/tests/src/Functional/DefaultViewsTest.php
+++ b/core/modules/views/tests/src/Functional/DefaultViewsTest.php
@@ -4,7 +4,6 @@
 
 use Drupal\comment\CommentInterface;
 use Drupal\comment\Tests\CommentTestTrait;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Url;
@@ -53,7 +52,7 @@ protected function setUp($import_test_views = TRUE) {
     $vocabulary = Vocabulary::create([
       'name' => $this->randomMachineName(),
       'description' => $this->randomMachineName(),
-      'vid' => Unicode::strtolower($this->randomMachineName()),
+      'vid' => mb_strtolower($this->randomMachineName()),
       'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
       'help' => '',
       'nodes' => ['page' => 'page'],
@@ -62,7 +61,7 @@ protected function setUp($import_test_views = TRUE) {
     $vocabulary->save();
 
     // Create a field.
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
 
     $handler_settings = [
       'target_bundles' => [
diff --git a/core/modules/views/tests/src/Functional/GlossaryTest.php b/core/modules/views/tests/src/Functional/GlossaryTest.php
index d67f70dfd74b..276737f1980c 100644
--- a/core/modules/views/tests/src/Functional/GlossaryTest.php
+++ b/core/modules/views/tests/src/Functional/GlossaryTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\views\Functional;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Url;
 use Drupal\views\Tests\AssertViewsCacheTagsTrait;
@@ -109,7 +108,7 @@ public function testGlossaryView() {
     $this->assertResponse(200);
     foreach ($nodes_per_char as $char => $count) {
       $href = Url::fromRoute('view.glossary.page_1', ['arg_0' => $char])->toString();
-      $label = Unicode::strtoupper($char);
+      $label = mb_strtoupper($char);
       // Get the summary link for a certain character. Filter by label and href
       // to ensure that both of them are correct.
       $result = $this->xpath('//a[contains(@href, :href) and normalize-space(text())=:label]/..', [':href' => $href, ':label' => $label]);
diff --git a/core/modules/views/tests/src/Functional/Handler/FieldWebTest.php b/core/modules/views/tests/src/Functional/Handler/FieldWebTest.php
index a3646f0c0b38..41849b254952 100644
--- a/core/modules/views/tests/src/Functional/Handler/FieldWebTest.php
+++ b/core/modules/views/tests/src/Functional/Handler/FieldWebTest.php
@@ -3,7 +3,6 @@
 namespace Drupal\Tests\views\Functional\Handler;
 
 use Drupal\Component\Utility\Html;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Component\Utility\UrlHelper;
 use Drupal\Core\Render\RenderContext;
 use Drupal\Core\Url;
@@ -556,7 +555,7 @@ public function testTextRendering() {
     // Tests for simple trimming by string length.
     $row->views_test_data_name = $this->randomMachineName(8);
     $name_field->options['alter']['max_length'] = 5;
-    $trimmed_name = Unicode::substr($row->views_test_data_name, 0, 5);
+    $trimmed_name = mb_substr($row->views_test_data_name, 0, 5);
 
     $output = $renderer->executeInRenderContext(new RenderContext(), function () use ($name_field, $row) {
       return $name_field->advancedRender($row);
diff --git a/core/modules/views/tests/src/Functional/Plugin/ExposedFormCheckboxesTest.php b/core/modules/views/tests/src/Functional/Plugin/ExposedFormCheckboxesTest.php
index 80584d796e2b..f5901a080d15 100644
--- a/core/modules/views/tests/src/Functional/Plugin/ExposedFormCheckboxesTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/ExposedFormCheckboxesTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\views\Functional\Plugin;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
 use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
 use Drupal\taxonomy\Entity\Term;
@@ -123,7 +122,7 @@ public function testExposedIsAllOfFilter() {
     }
 
     // Create a field.
-    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_name = mb_strtolower($this->randomMachineName());
     $handler_settings = [
       'target_bundles' => [
         $this->vocabulary->id() => $this->vocabulary->id(),
diff --git a/core/modules/views/tests/src/Kernel/Entity/ViewEntityDependenciesTest.php b/core/modules/views/tests/src/Kernel/Entity/ViewEntityDependenciesTest.php
index 24cd1162c5f6..32aac174c4fe 100644
--- a/core/modules/views/tests/src/Kernel/Entity/ViewEntityDependenciesTest.php
+++ b/core/modules/views/tests/src/Kernel/Entity/ViewEntityDependenciesTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\views\Kernel\Entity;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
 use Drupal\node\Entity\NodeType;
@@ -56,7 +55,7 @@ protected function setUp($import_test_views = TRUE) {
     ]);
     $content_type->save();
     $field_storage = FieldStorageConfig::create([
-      'field_name' => Unicode::strtolower($this->randomMachineName()),
+      'field_name' => mb_strtolower($this->randomMachineName()),
       'entity_type' => 'node',
       'type' => 'comment',
     ]);
diff --git a/core/modules/views_ui/views_ui.module b/core/modules/views_ui/views_ui.module
index bae74a83e76b..0475bce698bc 100644
--- a/core/modules/views_ui/views_ui.module
+++ b/core/modules/views_ui/views_ui.module
@@ -5,7 +5,6 @@
  * Provide structure for the administrative interface to Views.
  */
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\Core\Url;
 use Drupal\views\ViewExecutable;
@@ -341,8 +340,8 @@ function views_ui_views_analyze(ViewExecutable $view) {
  * This is often used in the UI to ensure long strings fit.
  */
 function views_ui_truncate($string, $length) {
-  if (Unicode::strlen($string) > $length) {
-    $string = Unicode::substr($string, 0, $length);
+  if (mb_strlen($string) > $length) {
+    $string = mb_substr($string, 0, $length);
     $string .= '...';
   }
 
diff --git a/core/tests/Drupal/KernelTests/Core/Asset/AttachedAssetsTest.php b/core/tests/Drupal/KernelTests/Core/Asset/AttachedAssetsTest.php
index 1e1c6fd8fa29..14288fee8e00 100644
--- a/core/tests/Drupal/KernelTests/Core/Asset/AttachedAssetsTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Asset/AttachedAssetsTest.php
@@ -3,7 +3,6 @@
 namespace Drupal\KernelTests\Core\Asset;
 
 use Drupal\Component\Serialization\Json;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Asset\AttachedAssets;
 use Drupal\KernelTests\KernelTestBase;
 
@@ -205,7 +204,7 @@ public function testSettings() {
     $end = strrpos($rendered_js, $endToken);
     // Convert to a string, as $renderer_js is a \Drupal\Core\Render\Markup
     // object.
-    $json  = Unicode::substr($rendered_js, $start, $end - $start + 1);
+    $json  = mb_substr($rendered_js, $start, $end - $start + 1);
     $parsed_settings = Json::decode($json);
 
     // Test whether the settings for core/drupalSettings are available.
diff --git a/core/tests/Drupal/KernelTests/Core/Config/ConfigImportRecreateTest.php b/core/tests/Drupal/KernelTests/Core/Config/ConfigImportRecreateTest.php
index c69f9febb4d4..7d9c9ae23f76 100644
--- a/core/tests/Drupal/KernelTests/Core/Config/ConfigImportRecreateTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Config/ConfigImportRecreateTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\KernelTests\Core\Config;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Config\ConfigImporter;
 use Drupal\Core\Config\StorageComparer;
 use Drupal\KernelTests\KernelTestBase;
@@ -57,7 +56,7 @@ protected function setUp() {
   }
 
   public function testRecreateEntity() {
-    $type_name = Unicode::strtolower($this->randomMachineName(16));
+    $type_name = mb_strtolower($this->randomMachineName(16));
     $content_type = NodeType::create([
       'type' => $type_name,
       'name' => 'Node type one',
diff --git a/core/tests/Drupal/KernelTests/Core/Config/ConfigImportRenameValidationTest.php b/core/tests/Drupal/KernelTests/Core/Config/ConfigImportRenameValidationTest.php
index e28e2144662f..01a9746dffe2 100644
--- a/core/tests/Drupal/KernelTests/Core/Config/ConfigImportRenameValidationTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Config/ConfigImportRenameValidationTest.php
@@ -3,7 +3,6 @@
 namespace Drupal\KernelTests\Core\Config;
 
 use Drupal\Component\Render\FormattableMarkup;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Component\Uuid\Php;
 use Drupal\Core\Config\ConfigImporter;
 use Drupal\Core\Config\ConfigImporterException;
@@ -82,7 +81,7 @@ public function testRenameValidation() {
 
     // Create a content type with a matching UUID in the active storage.
     $content_type = NodeType::create([
-      'type' => Unicode::strtolower($this->randomMachineName(16)),
+      'type' => mb_strtolower($this->randomMachineName(16)),
       'name' => $this->randomMachineName(),
       'uuid' => $uuid,
     ]);
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityLanguageTestBase.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityLanguageTestBase.php
index 570aa984465f..d76c3c17f8a0 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/EntityLanguageTestBase.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityLanguageTestBase.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\KernelTests\Core\Entity;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\language\Entity\ConfigurableLanguage;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
@@ -64,10 +63,10 @@ protected function setUp() {
     $this->state->set('entity_test.translation', TRUE);
 
     // Create a translatable test field.
-    $this->fieldName = Unicode::strtolower($this->randomMachineName() . '_field_name');
+    $this->fieldName = mb_strtolower($this->randomMachineName() . '_field_name');
 
     // Create an untranslatable test field.
-    $this->untranslatableFieldName = Unicode::strtolower($this->randomMachineName() . '_field_name');
+    $this->untranslatableFieldName = mb_strtolower($this->randomMachineName() . '_field_name');
 
     // Create field fields in all entity variations.
     foreach (entity_test_entity_types() as $entity_type) {
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryRelationshipTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryRelationshipTest.php
index 0bb5b16c34a6..1f0073e107fb 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryRelationshipTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryRelationshipTest.php
@@ -3,7 +3,6 @@
 namespace Drupal\KernelTests\Core\Entity;
 
 use Drupal\Component\Plugin\Exception\PluginNotFoundException;
-use Drupal\Component\Utility\Unicode;
 use Drupal\entity_test\Entity\EntityTest;
 use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
 use Drupal\taxonomy\Entity\Vocabulary;
@@ -73,7 +72,7 @@ protected function setUp() {
     // We want an entity reference field. It needs a vocabulary, terms, a field
     // storage and a field. First, create the vocabulary.
     $vocabulary = Vocabulary::create([
-      'vid' => Unicode::strtolower($this->randomMachineName()),
+      'vid' => mb_strtolower($this->randomMachineName()),
     ]);
     $vocabulary->save();
 
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryTest.php
index 9edee5cd21a7..f048569707db 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\KernelTests\Core\Entity;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\entity_test\Entity\EntityTest;
 use Drupal\entity_test\Entity\EntityTestMulRev;
 use Drupal\field\Entity\FieldConfig;
@@ -67,8 +66,8 @@ protected function setUp() {
 
     $this->installConfig(['language']);
 
-    $figures = Unicode::strtolower($this->randomMachineName());
-    $greetings = Unicode::strtolower($this->randomMachineName());
+    $figures = mb_strtolower($this->randomMachineName());
+    $greetings = mb_strtolower($this->randomMachineName());
     foreach ([$figures => 'shape', $greetings => 'text'] as $field_name => $field_type) {
       $field_storage = FieldStorageConfig::create([
         'field_name' => $field_name,
@@ -720,8 +719,8 @@ public function testCaseSensitivity() {
       $string = $this->randomMachineName(7) . 'a';
       $fixtures[] = [
         'original' => $string,
-        'uppercase' => Unicode::strtoupper($string),
-        'lowercase' => Unicode::strtolower($string),
+        'uppercase' => mb_strtoupper($string),
+        'lowercase' => mb_strtolower($string),
       ];
     }
 
@@ -844,23 +843,23 @@ public function testCaseSensitivity() {
     // Check the case insensitive field, CONTAINS operator, use the inner 8
     // characters of the uppercase and lowercase strings.
     $result = \Drupal::entityQuery('entity_test_mulrev')->condition(
-      'field_ci', Unicode::substr($fixtures[0]['uppercase'] . $fixtures[1]['lowercase'], 4, 8), 'CONTAINS'
+      'field_ci', mb_substr($fixtures[0]['uppercase'] . $fixtures[1]['lowercase'], 4, 8), 'CONTAINS'
     )->execute();
     $this->assertIdentical(count($result), 1, 'Case sensitive, lowercase.');
 
     $result = \Drupal::entityQuery('entity_test_mulrev')->condition(
-      'field_ci', Unicode::strtolower(Unicode::substr($fixtures[0]['uppercase'] . $fixtures[1]['lowercase'], 4, 8)), 'CONTAINS'
+      'field_ci', mb_strtolower(mb_substr($fixtures[0]['uppercase'] . $fixtures[1]['lowercase'], 4, 8)), 'CONTAINS'
     )->execute();
     $this->assertIdentical(count($result), 1, 'Case sensitive, exact match.');
 
     // Check the case sensitive field, CONTAINS operator.
     $result = \Drupal::entityQuery('entity_test_mulrev')->condition(
-      'field_cs', Unicode::substr($fixtures[0]['uppercase'] . $fixtures[1]['lowercase'], 4, 8), 'CONTAINS'
+      'field_cs', mb_substr($fixtures[0]['uppercase'] . $fixtures[1]['lowercase'], 4, 8), 'CONTAINS'
     )->execute();
     $this->assertIdentical(count($result), 1, 'Case sensitive, lowercase.');
 
     $result = \Drupal::entityQuery('entity_test_mulrev')->condition(
-      'field_cs', Unicode::strtolower(Unicode::substr($fixtures[0]['uppercase'] . $fixtures[1]['lowercase'], 4, 8)), 'CONTAINS'
+      'field_cs', mb_strtolower(mb_substr($fixtures[0]['uppercase'] . $fixtures[1]['lowercase'], 4, 8)), 'CONTAINS'
     )->execute();
     $this->assertIdentical(count($result), 0, 'Case sensitive, exact match.');
 
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/FieldSqlStorageTest.php b/core/tests/Drupal/KernelTests/Core/Entity/FieldSqlStorageTest.php
index 7ff6caf2b121..9c003493f436 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/FieldSqlStorageTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/FieldSqlStorageTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\KernelTests\Core\Entity;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Database\Database;
 use Drupal\Core\Entity\Exception\FieldStorageDefinitionUpdateForbiddenException;
 use Drupal\field\Entity\FieldConfig;
@@ -278,7 +277,7 @@ public function testLongNames() {
     $storage = $this->container->get('entity.manager')->getStorage($entity_type);
 
     // Create two fields and generate random values.
-    $name_base = Unicode::strtolower($this->randomMachineName(FieldStorageConfig::NAME_MAX_LENGTH - 1));
+    $name_base = mb_strtolower($this->randomMachineName(FieldStorageConfig::NAME_MAX_LENGTH - 1));
     $field_names = [];
     $values = [];
     for ($i = 0; $i < 2; $i++) {
diff --git a/core/tests/Drupal/KernelTests/Core/Field/FieldItemTest.php b/core/tests/Drupal/KernelTests/Core/Field/FieldItemTest.php
index e14fc6371158..d1469ef53dc2 100644
--- a/core/tests/Drupal/KernelTests/Core/Field/FieldItemTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Field/FieldItemTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\KernelTests\Core\Field;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\entity_test\Entity\EntityTest;
 use Drupal\entity_test\Entity\EntityTestMulRev;
 use Drupal\field\Entity\FieldConfig;
@@ -33,7 +32,7 @@ protected function setUp() {
     $entity_type_id = 'entity_test_mulrev';
     $this->installEntitySchema($entity_type_id);
 
-    $this->fieldName = Unicode::strtolower($this->randomMachineName());
+    $this->fieldName = mb_strtolower($this->randomMachineName());
 
     /** @var \Drupal\field\Entity\FieldStorageConfig $field_storage */
     FieldStorageConfig::create([
diff --git a/core/tests/Drupal/KernelTests/Core/Field/FieldMissingTypeTest.php b/core/tests/Drupal/KernelTests/Core/Field/FieldMissingTypeTest.php
index b164e1c0b226..02e3939d3f0d 100644
--- a/core/tests/Drupal/KernelTests/Core/Field/FieldMissingTypeTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Field/FieldMissingTypeTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\KernelTests\Core\Field;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\entity_test\Entity\EntityTestMulRev;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
@@ -37,7 +36,7 @@ protected function setUp() {
 
     $entity_type_id = 'entity_test_mulrev';
     $this->installEntitySchema($entity_type_id);
-    $this->fieldName = Unicode::strtolower($this->randomMachineName());
+    $this->fieldName = mb_strtolower($this->randomMachineName());
 
     /** @var \Drupal\field\Entity\FieldStorageConfig $field_storage */
     FieldStorageConfig::create([
diff --git a/core/tests/Drupal/KernelTests/Core/Routing/RouteProviderTest.php b/core/tests/Drupal/KernelTests/Core/Routing/RouteProviderTest.php
index c11b23d20df2..44efa1647976 100644
--- a/core/tests/Drupal/KernelTests/Core/Routing/RouteProviderTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Routing/RouteProviderTest.php
@@ -223,7 +223,7 @@ public function providerMixedCaseRoutePaths() {
    */
   public function testMixedCasePaths($path, $expected_route_name, $method = 'GET') {
     // The case-insensitive behavior for higher UTF-8 characters depends on
-    // \Drupal\Component\Utility\Unicode::strtolower() using mb_strtolower()
+    // mb_strtolower() using mb_strtolower()
     // but kernel tests do not currently run the check that enables it.
     // @todo remove this when https://www.drupal.org/node/2849669 is fixed.
     Unicode::check();
@@ -274,7 +274,7 @@ public function providerDuplicateRoutePaths() {
   public function testDuplicateRoutePaths($path, $number, $expected_route_name = NULL) {
 
     // The case-insensitive behavior for higher UTF-8 characters depends on
-    // \Drupal\Component\Utility\Unicode::strtolower() using mb_strtolower()
+    // mb_strtolower() using mb_strtolower()
     // but kernel tests do not currently run the check that enables it.
     // @todo remove this when https://www.drupal.org/node/2849669 is fixed.
     Unicode::check();
diff --git a/core/tests/Drupal/Tests/Component/Utility/UnicodeTest.php b/core/tests/Drupal/Tests/Component/Utility/UnicodeTest.php
index 960d1812adc5..3dc731ce962e 100644
--- a/core/tests/Drupal/Tests/Component/Utility/UnicodeTest.php
+++ b/core/tests/Drupal/Tests/Component/Utility/UnicodeTest.php
@@ -15,56 +15,11 @@
 class UnicodeTest extends TestCase {
 
   /**
-   * {@inheritdoc}
-   *
-   * @covers ::check
-   */
-  protected function setUp() {
-    // Initialize unicode component.
-    Unicode::check();
-  }
-
-  /**
-   * Getting and settings the multibyte environment status.
-   *
-   * @dataProvider providerTestStatus
-   * @covers ::getStatus
-   * @covers ::setStatus
-   */
-  public function testStatus($value, $expected, $invalid = FALSE) {
-    if ($invalid) {
-      if (method_exists($this, 'expectException')) {
-        $this->expectException('InvalidArgumentException');
-      }
-      else {
-        $this->setExpectedException('InvalidArgumentException');
-      }
-    }
-    Unicode::setStatus($value);
-    $this->assertEquals($expected, Unicode::getStatus());
-  }
-
-  /**
-   * Data provider for testStatus().
-   *
-   * @see testStatus()
-   *
-   * @return array
-   *   An array containing:
-   *     - The status value to set.
-   *     - The status value to expect after setting the new value.
-   *     - (optional) Boolean indicating invalid status. Defaults to FALSE.
+   * @group legacy
+   * @expectedDeprecation \Drupal\Component\Utility\Unicode::setStatus() is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. In Drupal 9 there will be no way to set the status and in Drupal 8 this ability has been removed because mb_*() functions are supplied using Symfony's polyfill. See https://www.drupal.org/node/2850048.
    */
-  public function providerTestStatus() {
-    return [
-      [Unicode::STATUS_SINGLEBYTE, Unicode::STATUS_SINGLEBYTE],
-      [rand(10, 100), Unicode::STATUS_SINGLEBYTE, TRUE],
-      [rand(10, 100), Unicode::STATUS_SINGLEBYTE, TRUE],
-      [Unicode::STATUS_MULTIBYTE, Unicode::STATUS_MULTIBYTE],
-      [rand(10, 100), Unicode::STATUS_MULTIBYTE, TRUE],
-      [Unicode::STATUS_ERROR, Unicode::STATUS_ERROR],
-      [Unicode::STATUS_MULTIBYTE, Unicode::STATUS_MULTIBYTE],
-    ];
+  public function testSetStatus() {
+    Unicode::setStatus(Unicode::STATUS_SINGLEBYTE);
   }
 
   /**
@@ -101,10 +56,10 @@ public function providerTestMimeHeader() {
    * @dataProvider providerStrtolower
    * @covers ::strtolower
    * @covers ::caseFlip
+   * @group legacy
+   * @expectedDeprecation \Drupal\Component\Utility\Unicode::strtolower() is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. Use mb_strtolower() instead. See https://www.drupal.org/node/2850048.
    */
-  public function testStrtolower($text, $expected, $multibyte = FALSE) {
-    $status = $multibyte ? Unicode::STATUS_MULTIBYTE : Unicode::STATUS_SINGLEBYTE;
-    Unicode::setStatus($status);
+  public function testStrtolower($text, $expected) {
     $this->assertEquals($expected, Unicode::strtolower($text));
   }
 
@@ -114,22 +69,14 @@ public function testStrtolower($text, $expected, $multibyte = FALSE) {
    * @see testStrtolower()
    *
    * @return array
-   *   An array containing a string, its lowercase version and whether it should
-   *   be processed as multibyte.
+   *   An array containing a string and its lowercase version.
    */
   public function providerStrtolower() {
-    $cases = [
+    return [
       ['tHe QUIcK bRoWn', 'the quick brown'],
       ['FrançAIS is ÜBER-åwesome', 'français is über-åwesome'],
+      ['ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΣὨ', 'αβγδεζηθικλμνξοσὠ'],
     ];
-    foreach ($cases as $case) {
-      // Test the same string both in multibyte and singlebyte conditions.
-      array_push($case, TRUE);
-      $cases[] = $case;
-    }
-    // Add a multibyte string.
-    $cases[] = ['ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΣὨ', 'αβγδεζηθικλμνξοσὠ', TRUE];
-    return $cases;
   }
 
   /**
@@ -138,10 +85,10 @@ public function providerStrtolower() {
    * @dataProvider providerStrtoupper
    * @covers ::strtoupper
    * @covers ::caseFlip
+   * @group legacy
+   * @expectedDeprecation \Drupal\Component\Utility\Unicode::strtoupper() is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. Use mb_strtoupper() instead. See https://www.drupal.org/node/2850048.
    */
-  public function testStrtoupper($text, $expected, $multibyte = FALSE) {
-    $status = $multibyte ? Unicode::STATUS_MULTIBYTE : Unicode::STATUS_SINGLEBYTE;
-    Unicode::setStatus($status);
+  public function testStrtoupper($text, $expected) {
     $this->assertEquals($expected, Unicode::strtoupper($text));
   }
 
@@ -151,22 +98,14 @@ public function testStrtoupper($text, $expected, $multibyte = FALSE) {
    * @see testStrtoupper()
    *
    * @return array
-   *   An array containing a string, its uppercase version and whether it should
-   *   be processed as multibyte.
+   *   An array containing a string and its uppercase version.
    */
   public function providerStrtoupper() {
-    $cases = [
+    return [
       ['tHe QUIcK bRoWn', 'THE QUICK BROWN'],
       ['FrançAIS is ÜBER-åwesome', 'FRANÇAIS IS ÜBER-ÅWESOME'],
+      ['αβγδεζηθικλμνξοσὠ', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΣὨ'],
     ];
-    foreach ($cases as $case) {
-      // Test the same string both in multibyte and singlebyte conditions.
-      array_push($case, TRUE);
-      $cases[] = $case;
-    }
-    // Add a multibyte string.
-    $cases[] = ['αβγδεζηθικλμνξοσὠ', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΣὨ', TRUE];
-    return $cases;
   }
 
   /**
@@ -204,9 +143,7 @@ public function providerUcfirst() {
    * @dataProvider providerLcfirst
    * @covers ::lcfirst
    */
-  public function testLcfirst($text, $expected, $multibyte = FALSE) {
-    $status = $multibyte ? Unicode::STATUS_MULTIBYTE : Unicode::STATUS_SINGLEBYTE;
-    Unicode::setStatus($status);
+  public function testLcfirst($text, $expected) {
     $this->assertEquals($expected, Unicode::lcfirst($text));
   }
 
@@ -216,8 +153,7 @@ public function testLcfirst($text, $expected, $multibyte = FALSE) {
    * @see testLcfirst()
    *
    * @return array
-   *   An array containing a string, its lowercase version and whether it should
-   *   be processed as multibyte.
+   *   An array containing a string and its lowercase version.
    */
   public function providerLcfirst() {
     return [
@@ -226,7 +162,7 @@ public function providerLcfirst() {
       ['Über', 'über'],
       ['Ã…wesome', 'Ã¥wesome'],
       // Add a multibyte string.
-      ['ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΣὨ', 'αΒΓΔΕΖΗΘΙΚΛΜΝΞΟΣὨ', TRUE],
+      ['ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΣὨ', 'αΒΓΔΕΖΗΘΙΚΛΜΝΞΟΣὨ'],
     ];
   }
 
@@ -236,9 +172,7 @@ public function providerLcfirst() {
    * @dataProvider providerUcwords
    * @covers ::ucwords
    */
-  public function testUcwords($text, $expected, $multibyte = FALSE) {
-    $status = $multibyte ? Unicode::STATUS_MULTIBYTE : Unicode::STATUS_SINGLEBYTE;
-    Unicode::setStatus($status);
+  public function testUcwords($text, $expected) {
     $this->assertEquals($expected, Unicode::ucwords($text));
   }
 
@@ -248,8 +182,7 @@ public function testUcwords($text, $expected, $multibyte = FALSE) {
    * @see testUcwords()
    *
    * @return array
-   *   An array containing a string, its capitalized version and whether it should
-   *   be processed as multibyte.
+   *   An array containing a string and its capitalized version.
    */
   public function providerUcwords() {
     return [
@@ -260,7 +193,7 @@ public function providerUcwords() {
       // Make sure we don't mangle extra spaces.
       ['frànçAIS is  über-åwesome', 'FrànçAIS Is  Über-Åwesome'],
       // Add a multibyte string.
-      ['σion', 'Σion', TRUE],
+      ['σion', 'Σion'],
     ];
   }
 
@@ -269,13 +202,10 @@ public function providerUcwords() {
    *
    * @dataProvider providerStrlen
    * @covers ::strlen
+   * @group legacy
+   * @expectedDeprecation \Drupal\Component\Utility\Unicode::strlen() is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. Use mb_strlen() instead. See https://www.drupal.org/node/2850048.
    */
   public function testStrlen($text, $expected) {
-    // Run through multibyte code path.
-    Unicode::setStatus(Unicode::STATUS_MULTIBYTE);
-    $this->assertEquals($expected, Unicode::strlen($text));
-    // Run through singlebyte code path.
-    Unicode::setStatus(Unicode::STATUS_SINGLEBYTE);
     $this->assertEquals($expected, Unicode::strlen($text));
   }
 
@@ -300,13 +230,10 @@ public function providerStrlen() {
    *
    * @dataProvider providerSubstr
    * @covers ::substr
+   * @group legacy
+   * @expectedDeprecation \Drupal\Component\Utility\Unicode::substr() is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. Use mb_substr() instead. See https://www.drupal.org/node/2850048.
    */
   public function testSubstr($text, $start, $length, $expected) {
-    // Run through multibyte code path.
-    Unicode::setStatus(Unicode::STATUS_MULTIBYTE);
-    $this->assertEquals($expected, Unicode::substr($text, $start, $length));
-    // Run through singlebyte code path.
-    Unicode::setStatus(Unicode::STATUS_SINGLEBYTE);
     $this->assertEquals($expected, Unicode::substr($text, $start, $length));
   }
 
@@ -553,13 +480,10 @@ public function providerTestConvertToUtf8() {
    *
    * @dataProvider providerStrpos
    * @covers ::strpos
+   * @group legacy
+   * @expectedDeprecation \Drupal\Component\Utility\Unicode::strpos() is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. Use mb_strpos() instead. See https://www.drupal.org/node/2850048.
    */
   public function testStrpos($haystack, $needle, $offset, $expected) {
-    // Run through multibyte code path.
-    Unicode::setStatus(Unicode::STATUS_MULTIBYTE);
-    $this->assertEquals($expected, Unicode::strpos($haystack, $needle, $offset));
-    // Run through singlebyte code path.
-    Unicode::setStatus(Unicode::STATUS_SINGLEBYTE);
     $this->assertEquals($expected, Unicode::strpos($haystack, $needle, $offset));
   }
 
diff --git a/core/tests/bootstrap.php b/core/tests/bootstrap.php
index b15645a64c8c..82a1830547b3 100644
--- a/core/tests/bootstrap.php
+++ b/core/tests/bootstrap.php
@@ -170,6 +170,10 @@ function drupal_phpunit_populate_class_loader() {
 // @see \Drupal\Core\DrupalKernel::bootEnvironment()
 setlocale(LC_ALL, 'C');
 
+// Set appropriate configuration for multi-byte strings.
+mb_internal_encoding('utf-8');
+mb_language('uni');
+
 // Set the default timezone. While this doesn't cause any tests to fail, PHP
 // complains if 'date.timezone' is not set in php.ini. The Australia/Sydney
 // timezone is chosen so all tests are run using an edge case scenario (UTC+10
-- 
GitLab