diff --git a/core/lib/Drupal/Component/Utility/Html.php b/core/lib/Drupal/Component/Utility/Html.php
index a775cdb..eaa95fb 100644
--- a/core/lib/Drupal/Component/Utility/Html.php
+++ b/core/lib/Drupal/Component/Utility/Html.php
@@ -47,13 +47,17 @@ class Html {
    * Do not pass one string containing multiple classes as they will be
    * incorrectly concatenated with dashes, i.e. "one two" will become "one-two".
    *
-   * @param string $class
+   * @param string|\Drupal\Component\Utility\SafeStringInterface $class
    *   The class name to clean.
    *
    * @return string
    *   The cleaned class name.
    */
   public static function getClass($class) {
+    // Cast to string in case $class is a TranslationWrapper.
+    if ($class instanceof SafeStringInterface) {
+      $class = (string) $class;
+    }
     if (!isset(static::$classes[$class])) {
       static::$classes[$class] = static::cleanCssIdentifier(Unicode::strtolower($class));
     }
diff --git a/core/lib/Drupal/Core/Entity/EntityManager.php b/core/lib/Drupal/Core/Entity/EntityManager.php
index 351361f..8280ba4 100644
--- a/core/lib/Drupal/Core/Entity/EntityManager.php
+++ b/core/lib/Drupal/Core/Entity/EntityManager.php
@@ -945,7 +945,9 @@ public function getEntityTypeLabels($group = FALSE) {
 
     foreach ($definitions as $entity_type_id => $definition) {
       if ($group) {
-        $options[$definition->getGroupLabel()][$entity_type_id] = $definition->getLabel();
+        // We cast the optgroup label to string as array keys must not be objects
+        // and t() may return a TranslationWrapper once issue #2557113 lands.
+        $options[(string) $definition->getGroupLabel()][$entity_type_id] = $definition->getLabel();
       }
       else {
         $options[$entity_type_id] = $definition->getLabel();
@@ -960,7 +962,9 @@ public function getEntityTypeLabels($group = FALSE) {
 
       // Make sure that the 'Content' group is situated at the top.
       $content = $this->t('Content', array(), array('context' => 'Entity type group'));
-      $options = array($content => $options[$content]) + $options;
+      // We cast the optgroup label to string as array keys must not be objects
+      // and t() may return a TranslationWrapper once issue #2557113 lands.
+      $options = array((string) $content => $options[(string) $content]) + $options;
     }
 
     return $options;
diff --git a/core/modules/block/src/Tests/BlockInterfaceTest.php b/core/modules/block/src/Tests/BlockInterfaceTest.php
index 7215765..79ae864 100644
--- a/core/modules/block/src/Tests/BlockInterfaceTest.php
+++ b/core/modules/block/src/Tests/BlockInterfaceTest.php
@@ -109,16 +109,16 @@ public function testBlockInterface() {
     $actual_form = $display_block->buildConfigurationForm(array(), $form_state);
     // Remove the visibility sections, as that just tests condition plugins.
     unset($actual_form['visibility'], $actual_form['visibility_tabs']);
-    $this->assertIdentical($actual_form, $expected_form, 'Only the expected form elements were present.');
+    $this->assertEqual($actual_form, $expected_form, 'Only the expected form elements were present.');
 
     $expected_build = array(
       '#children' => 'My custom display message.',
     );
     // Ensure the build array is proper.
-    $this->assertIdentical($display_block->build(), $expected_build, 'The plugin returned the appropriate build array.');
+    $this->assertEqual($display_block->build(), $expected_build, 'The plugin returned the appropriate build array.');
 
     // Ensure the machine name suggestion is correct. In truth, this is actually
     // testing BlockBase's implementation, not the interface itself.
-    $this->assertIdentical($display_block->getMachineNameSuggestion(), 'displaymessage', 'The plugin returned the expected machine name suggestion.');
+    $this->assertEqual($display_block->getMachineNameSuggestion(), 'displaymessage', 'The plugin returned the expected machine name suggestion.');
   }
 }
diff --git a/core/modules/block_content/src/Tests/BlockContentListTest.php b/core/modules/block_content/src/Tests/BlockContentListTest.php
index aeed4dc..8b77d1a 100644
--- a/core/modules/block_content/src/Tests/BlockContentListTest.php
+++ b/core/modules/block_content/src/Tests/BlockContentListTest.php
@@ -46,7 +46,7 @@ public function testListing() {
     // Test the contents of each th cell.
     $expected_items = array(t('Block description'), t('Operations'));
     foreach ($elements as $key => $element) {
-      $this->assertIdentical((string) $element[0], $expected_items[$key]);
+      $this->assertEqual($element[0], $expected_items[$key]);
     }
 
     $label = 'Antelope';
diff --git a/core/modules/block_content/src/Tests/BlockContentListViewsTest.php b/core/modules/block_content/src/Tests/BlockContentListViewsTest.php
index ba84f2b..2818760 100644
--- a/core/modules/block_content/src/Tests/BlockContentListViewsTest.php
+++ b/core/modules/block_content/src/Tests/BlockContentListViewsTest.php
@@ -45,10 +45,10 @@ public function testListing() {
     $expected_items = [t('Block description'), t('Block type'), t('Updated'), t('Operations')];
     foreach ($elements as $key => $element) {
       if ($element->xpath('a')) {
-        $this->assertIdentical(trim((string) $element->xpath('a')[0]), $expected_items[$key]);
+        $this->assertEqual(trim((string) $element->xpath('a')[0]), $expected_items[$key]);
       }
       else {
-        $this->assertIdentical(trim((string) $element[0]), $expected_items[$key]);
+        $this->assertEqual(trim((string) $element[0]), $expected_items[$key]);
       }
     }
 
diff --git a/core/modules/breakpoint/src/Tests/BreakpointDiscoveryTest.php b/core/modules/breakpoint/src/Tests/BreakpointDiscoveryTest.php
index 0668c86..5247a7c 100644
--- a/core/modules/breakpoint/src/Tests/BreakpointDiscoveryTest.php
+++ b/core/modules/breakpoint/src/Tests/BreakpointDiscoveryTest.php
@@ -193,6 +193,7 @@ public function testBreakpointGroups() {
     );
     $breakpoint_groups = \Drupal::service('breakpoint.manager')->getGroups();
     // Ensure the order is as expected. Should be sorted by label.
+    $this->castSafeStrings($expected, $breakpoint_groups);
     $this->assertIdentical($expected, $breakpoint_groups);
 
     $expected = array(
diff --git a/core/modules/ckeditor/ckeditor.admin.inc b/core/modules/ckeditor/ckeditor.admin.inc
index 21be21d..d5bb690 100644
--- a/core/modules/ckeditor/ckeditor.admin.inc
+++ b/core/modules/ckeditor/ckeditor.admin.inc
@@ -18,6 +18,10 @@
  *   An associative array containing:
  *   - editor: An editor object.
  *   - plugins: A list of plugins.
+ *   - active_buttons: A list of disabled buttons.
+ *   - disabled_buttons: A list of disabled buttons.
+ *   - multiple_buttons: A list of multiple buttons that may be added multiple
+ *     times.
  */
 function template_preprocess_ckeditor_settings_toolbar(&$variables) {
   $language_interface = \Drupal::languageManager()->getCurrentLanguage();
@@ -113,6 +117,9 @@ function template_preprocess_ckeditor_settings_toolbar(&$variables) {
   $variables['active_buttons'] = array();
   foreach ($active_buttons as $row_number => $button_row) {
     foreach ($button_groups[$row_number] as $group_name) {
+      // We cast the group name to string as array keys must not be objects
+      // and t() may return a TranslationWrapper once issue #2557113 lands.
+      $group_name = (string) $group_name;
       $variables['active_buttons'][$row_number][$group_name] = array(
         'group_name_class' => Html::getClass($group_name),
         'buttons' => array(),
diff --git a/core/modules/ckeditor/src/Tests/CKEditorAdminTest.php b/core/modules/ckeditor/src/Tests/CKEditorAdminTest.php
index ca1954f..72c1864 100644
--- a/core/modules/ckeditor/src/Tests/CKEditorAdminTest.php
+++ b/core/modules/ckeditor/src/Tests/CKEditorAdminTest.php
@@ -111,7 +111,7 @@ function testExistingFormat() {
       ),
       'plugins' => array(),
     );
-    $this->assertIdentical($ckeditor->getDefaultSettings(), $expected_default_settings);
+    $this->assertEqual($ckeditor->getDefaultSettings(), $expected_default_settings);
 
     // Keep the "CKEditor" editor selected and click the "Configure" button.
     $this->drupalPostAjaxForm(NULL, $edit, 'editor_configure');
diff --git a/core/modules/ckeditor/src/Tests/CKEditorTest.php b/core/modules/ckeditor/src/Tests/CKEditorTest.php
index d2a59bc..ba8ed0b 100644
--- a/core/modules/ckeditor/src/Tests/CKEditorTest.php
+++ b/core/modules/ckeditor/src/Tests/CKEditorTest.php
@@ -94,8 +94,9 @@ function testGetJSSettings() {
         'drupallink' => file_create_url('core/modules/ckeditor/js/plugins/drupallink/plugin.js'),
       ),
     );
-    ksort($expected_config);
-    $this->assertIdentical($expected_config, $this->ckeditor->getJSSettings($editor), 'Generated JS settings are correct for default configuration.');
+    $actual_config = $this->ckeditor->getJSSettings($editor);
+    $this->castSafeStrings($expected_config, $actual_config);
+    $this->assertIdentical($expected_config, $actual_config, 'Generated JS settings are correct for default configuration.');
 
     // Customize the configuration: add button, have two contextually enabled
     // buttons, and configure a CKEditor plugin setting.
@@ -216,7 +217,7 @@ function testBuildToolbarJSSetting() {
 
     // Default toolbar.
     $expected = $this->getDefaultToolbarConfig();
-    $this->assertIdentical($expected, $this->ckeditor->buildToolbarJSSetting($editor), '"toolbar" configuration part of JS settings built correctly for default toolbar.');
+    $this->assertEqual($expected, $this->ckeditor->buildToolbarJSSetting($editor), '"toolbar" configuration part of JS settings built correctly for default toolbar.');
 
     // Customize the configuration.
     $settings = $editor->getSettings();
@@ -224,7 +225,7 @@ function testBuildToolbarJSSetting() {
     $editor->setSettings($settings);
     $editor->save();
     $expected[0]['items'][] = 'Strike';
-    $this->assertIdentical($expected, $this->ckeditor->buildToolbarJSSetting($editor), '"toolbar" configuration part of JS settings built correctly for customized toolbar.');
+    $this->assertEqual($expected, $this->ckeditor->buildToolbarJSSetting($editor), '"toolbar" configuration part of JS settings built correctly for customized toolbar.');
 
     // Enable the editor_test module, customize further.
     $this->enableModules(array('ckeditor_test'));
@@ -236,7 +237,7 @@ function testBuildToolbarJSSetting() {
     $editor->save();
     $expected[0]['name'] = 'JunkScience';
     $expected[0]['items'][] = 'Llama';
-    $this->assertIdentical($expected, $this->ckeditor->buildToolbarJSSetting($editor), '"toolbar" configuration part of JS settings built correctly for customized toolbar with contrib module-provided CKEditor plugin.');
+    $this->assertEqual($expected, $this->ckeditor->buildToolbarJSSetting($editor), '"toolbar" configuration part of JS settings built correctly for customized toolbar with contrib module-provided CKEditor plugin.');
   }
 
   /**
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index 4945fe0..596542f 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -299,8 +299,11 @@ function comment_form_field_ui_field_storage_add_form_alter(&$form, FormStateInt
     $form['#title'] = \Drupal::service('comment.manager')->getFieldUIPageTitle($route_match->getParameter('commented_entity_type'), $route_match->getParameter('field_name'));
   }
   if (!_comment_entity_uses_integer_id($form_state->get('entity_type_id'))) {
+    // We cast the optgroup label to string as array keys must not be objects
+    // and t() will return a TranslationWrapper once issue #2557113 lands.
+    $optgroup = (string) t('General');
     // You cannot use comment fields on entity types with non-integer IDs.
-    unset($form['add']['new_storage_type']['#options'][t('General')]['comment']);
+    unset($form['add']['new_storage_type']['#options'][$optgroup]['comment']);
   }
 }
 
diff --git a/core/modules/config/src/Tests/ConfigImportRenameValidationTest.php b/core/modules/config/src/Tests/ConfigImportRenameValidationTest.php
index 7f0d72e..e0b6a70 100644
--- a/core/modules/config/src/Tests/ConfigImportRenameValidationTest.php
+++ b/core/modules/config/src/Tests/ConfigImportRenameValidationTest.php
@@ -112,7 +112,7 @@ public function testRenameValidation() {
       $expected = array(
         SafeMarkup::format('Entity type mismatch on rename. @old_type not equal to @new_type for existing configuration @old_name and staged configuration @new_name.', array('@old_type' => 'node_type', '@new_type' => 'config_test', '@old_name' => 'node.type.' . $content_type->id(), '@new_name' => 'config_test.dynamic.' . $test_entity_id))
       );
-      $this->assertIdentical($expected, $this->configImporter->getErrors());
+      $this->assertEqual($expected, $this->configImporter->getErrors());
     }
   }
 
@@ -155,7 +155,7 @@ public function testRenameSimpleConfigValidation() {
       $expected = array(
         SafeMarkup::format('Rename operation for simple configuration. Existing configuration @old_name and staged configuration @new_name.', array('@old_name' => 'config_test.old', '@new_name' => 'config_test.new'))
       );
-      $this->assertIdentical($expected, $this->configImporter->getErrors());
+      $this->assertEqual($expected, $this->configImporter->getErrors());
     }
   }
 
diff --git a/core/modules/entity_reference/entity_reference.module b/core/modules/entity_reference/entity_reference.module
index e206dee..908e0e5 100644
--- a/core/modules/entity_reference/entity_reference.module
+++ b/core/modules/entity_reference/entity_reference.module
@@ -126,10 +126,13 @@ function entity_reference_field_config_presave(FieldConfigInterface $field) {
  * Implements hook_form_FORM_ID_alter() for 'field_ui_field_storage_add_form'.
  */
 function entity_reference_form_field_ui_field_storage_add_form_alter(array &$form) {
+  // We cast the optgroup label to string as array keys must not be objects
+  // and t() may return a TranslationWrapper once issue #2557113 lands.
+  $optgroup = (string) t('Reference');
   // Move the "Entity reference" option to the end of the list and rename it to
   // "Other".
-  unset($form['add']['new_storage_type']['#options'][t('Reference')]['entity_reference']);
-  $form['add']['new_storage_type']['#options'][t('Reference')]['entity_reference'] = t('Other…');
+  unset($form['add']['new_storage_type']['#options'][$optgroup]['entity_reference']);
+  $form['add']['new_storage_type']['#options'][$optgroup]['entity_reference'] = t('Other…');
 }
 
 /**
diff --git a/core/modules/language/src/Form/NegotiationBrowserForm.php b/core/modules/language/src/Form/NegotiationBrowserForm.php
index bf0ce4e..111f35a 100644
--- a/core/modules/language/src/Form/NegotiationBrowserForm.php
+++ b/core/modules/language/src/Form/NegotiationBrowserForm.php
@@ -82,8 +82,10 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     }
     else {
       $language_options = array(
-        $this->t('Existing languages') => $existing_languages,
-        $this->t('Languages not yet added') => $this->languageManager->getStandardLanguageListWithoutConfigured(),
+        // We cast the optgroup labels to string as array keys must not be objects
+        // and t() may return a TranslationWrapper once issue #2557113 lands.
+        (string) $this->t('Existing languages') => $existing_languages,
+        (string) $this->t('Languages not yet added') => $this->languageManager->getStandardLanguageListWithoutConfigured(),
       );
     }
 
diff --git a/core/modules/locale/src/Form/ImportForm.php b/core/modules/locale/src/Form/ImportForm.php
index 1728879..86aecc3 100644
--- a/core/modules/locale/src/Form/ImportForm.php
+++ b/core/modules/locale/src/Form/ImportForm.php
@@ -94,8 +94,10 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     else {
       $default = key($existing_languages);
       $language_options = array(
-        $this->t('Existing languages') => $existing_languages,
-        $this->t('Languages not yet added') => $this->languageManager->getStandardLanguageListWithoutConfigured(),
+        // We cast the optgroup labels to string as array keys must not be objects
+        // and t() may return a TranslationWrapper once issue #2557113 lands.
+        (string) $this->t('Existing languages') => $existing_languages,
+        (string) $this->t('Languages not yet added') => $this->languageManager->getStandardLanguageListWithoutConfigured(),
       );
     }
 
diff --git a/core/modules/migrate_drupal/src/Tests/dependencies/MigrateDependenciesTest.php b/core/modules/migrate_drupal/src/Tests/dependencies/MigrateDependenciesTest.php
index 59caa80..d3a5574 100644
--- a/core/modules/migrate_drupal/src/Tests/dependencies/MigrateDependenciesTest.php
+++ b/core/modules/migrate_drupal/src/Tests/dependencies/MigrateDependenciesTest.php
@@ -69,7 +69,7 @@ public function testAggregatorMigrateDependencies() {
     $executable = new MigrateExecutable($migration, $this);
     $this->startCollectingMessages();
     $executable->import();
-    $this->assertIdentical($this->migrateMessages['error'], array(SafeMarkup::format('Migration @id did not meet the requirements. Missing migrations d6_aggregator_feed. requirements: d6_aggregator_feed.', array('@id' => $migration->id()))));
+    $this->assertEqual($this->migrateMessages['error'], array(SafeMarkup::format('Migration @id did not meet the requirements. Missing migrations d6_aggregator_feed. requirements: d6_aggregator_feed.', array('@id' => $migration->id()))));
     $this->collectMessages = FALSE;
   }
 
diff --git a/core/modules/shortcut/src/Tests/ShortcutSetsTest.php b/core/modules/shortcut/src/Tests/ShortcutSetsTest.php
index bc3c5f9..47efc0f 100644
--- a/core/modules/shortcut/src/Tests/ShortcutSetsTest.php
+++ b/core/modules/shortcut/src/Tests/ShortcutSetsTest.php
@@ -73,7 +73,7 @@ function testShortcutSetEdit() {
     // Test the contents of each th cell.
     $expected_items = array(t('Name'), t('Weight'), t('Operations'));
     foreach ($elements as $key => $element) {
-      $this->assertIdentical((string) $element[0], $expected_items[$key]);
+      $this->assertEqual((string) $element[0], $expected_items[$key]);
     }
 
     // Look for test shortcuts in the table.
diff --git a/core/modules/system/src/Tests/Common/FormatDateTest.php b/core/modules/system/src/Tests/Common/FormatDateTest.php
index 0ece458..1dcc202 100644
--- a/core/modules/system/src/Tests/Common/FormatDateTest.php
+++ b/core/modules/system/src/Tests/Common/FormatDateTest.php
@@ -87,12 +87,12 @@ function testAdminDefinedFormatDate() {
    */
   function testFormatDate() {
     $timestamp = strtotime('2007-03-26T00:00:00+00:00');
-    $this->assertIdentical(format_date($timestamp, 'custom', 'l, d-M-y H:i:s T', 'America/Los_Angeles', 'en'), 'Sunday, 25-Mar-07 17:00:00 PDT', 'Test all parameters.');
-    $this->assertIdentical(format_date($timestamp, 'custom', 'l, d-M-y H:i:s T', 'America/Los_Angeles', self::LANGCODE), 'domingo, 25-Mar-07 17:00:00 PDT', 'Test translated format.');
-    $this->assertIdentical(format_date($timestamp, 'custom', '\\l, d-M-y H:i:s T', 'America/Los_Angeles', self::LANGCODE), 'l, 25-Mar-07 17:00:00 PDT', 'Test an escaped format string.');
-    $this->assertIdentical(format_date($timestamp, 'custom', '\\\\l, d-M-y H:i:s T', 'America/Los_Angeles', self::LANGCODE), '\\domingo, 25-Mar-07 17:00:00 PDT', 'Test format containing backslash character.');
-    $this->assertIdentical(format_date($timestamp, 'custom', '\\\\\\l, d-M-y H:i:s T', 'America/Los_Angeles', self::LANGCODE), '\\l, 25-Mar-07 17:00:00 PDT', 'Test format containing backslash followed by escaped format string.');
-    $this->assertIdentical(format_date($timestamp, 'custom', 'l, d-M-y H:i:s T', 'Europe/London', 'en'), 'Monday, 26-Mar-07 01:00:00 BST', 'Test a different time zone.');
+    $this->assertEqual(format_date($timestamp, 'custom', 'l, d-M-y H:i:s T', 'America/Los_Angeles', 'en'), 'Sunday, 25-Mar-07 17:00:00 PDT', 'Test all parameters.');
+    $this->assertEqual(format_date($timestamp, 'custom', 'l, d-M-y H:i:s T', 'America/Los_Angeles', self::LANGCODE), 'domingo, 25-Mar-07 17:00:00 PDT', 'Test translated format.');
+    $this->assertEqual(format_date($timestamp, 'custom', '\\l, d-M-y H:i:s T', 'America/Los_Angeles', self::LANGCODE), 'l, 25-Mar-07 17:00:00 PDT', 'Test an escaped format string.');
+    $this->assertEqual(format_date($timestamp, 'custom', '\\\\l, d-M-y H:i:s T', 'America/Los_Angeles', self::LANGCODE), '\\domingo, 25-Mar-07 17:00:00 PDT', 'Test format containing backslash character.');
+    $this->assertEqual(format_date($timestamp, 'custom', '\\\\\\l, d-M-y H:i:s T', 'America/Los_Angeles', self::LANGCODE), '\\l, 25-Mar-07 17:00:00 PDT', 'Test format containing backslash followed by escaped format string.');
+    $this->assertEqual(format_date($timestamp, 'custom', 'l, d-M-y H:i:s T', 'Europe/London', 'en'), 'Monday, 26-Mar-07 01:00:00 BST', 'Test a different time zone.');
 
     // Change the default language and timezone.
     $this->config('system.site')->set('default_langcode', static::LANGCODE)->save();
diff --git a/core/modules/system/src/Tests/Entity/EntityDefinitionUpdateTest.php b/core/modules/system/src/Tests/Entity/EntityDefinitionUpdateTest.php
index 1010b03..f1f33ab 100644
--- a/core/modules/system/src/Tests/Entity/EntityDefinitionUpdateTest.php
+++ b/core/modules/system/src/Tests/Entity/EntityDefinitionUpdateTest.php
@@ -107,7 +107,7 @@ public function testEntityTypeUpdateWithoutData() {
         t('Update the %entity_type entity type.', array('%entity_type' => $this->entityManager->getDefinition('entity_test_update')->getLabel())),
       ),
     );
-    $this->assertIdentical($this->entityDefinitionUpdateManager->getChangeSummary(), $expected); //, 'EntityDefinitionUpdateManager reports the expected change summary.');
+    $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected); //, 'EntityDefinitionUpdateManager reports the expected change summary.');
 
     // Run the update and ensure the revision table is created.
     $this->entityDefinitionUpdateManager->applyUpdates();
@@ -146,7 +146,7 @@ public function testBaseFieldCreateUpdateDeleteWithoutData() {
         t('Create the %field_name field.', array('%field_name' => t('A new base field'))),
       ),
     );
-    $this->assertIdentical($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.');
+    $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.');
     $this->entityDefinitionUpdateManager->applyUpdates();
     $this->assertTrue($this->database->schema()->fieldExists('entity_test_update', 'new_base_field'), 'Column created in shared table for new_base_field.');
 
@@ -159,7 +159,7 @@ public function testBaseFieldCreateUpdateDeleteWithoutData() {
         t('Update the %field_name field.', array('%field_name' => t('A new base field'))),
       ),
     );
-    $this->assertIdentical($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.');
+    $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.');
     $this->entityDefinitionUpdateManager->applyUpdates();
     $this->assertTrue($this->database->schema()->indexExists('entity_test_update', 'entity_test_update_field__new_base_field'), 'Index created.');
 
@@ -220,7 +220,7 @@ public function testBundleFieldCreateUpdateDeleteWithoutData() {
         t('Create the %field_name field.', array('%field_name' => t('A new bundle field'))),
       ),
     );
-    $this->assertIdentical($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.');
+    $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.');
     $this->entityDefinitionUpdateManager->applyUpdates();
     $this->assertTrue($this->database->schema()->tableExists('entity_test_update__new_bundle_field'), 'Dedicated table created for new_bundle_field.');
 
@@ -234,7 +234,7 @@ public function testBundleFieldCreateUpdateDeleteWithoutData() {
         t('Update the %field_name field.', array('%field_name' => t('A new bundle field'))),
       ),
     );
-    $this->assertIdentical($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.');
+    $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.');
     $this->entityDefinitionUpdateManager->applyUpdates();
     $this->assertTrue($this->database->schema()->fieldExists('entity_test_update__new_bundle_field', 'new_bundle_field_format'), 'Format column created in dedicated table for new_base_field.');
 
@@ -489,7 +489,7 @@ public function testEntityIndexCreateDeleteWithoutData() {
         t('Update the %entity_type entity type.', array('%entity_type' => $this->entityManager->getDefinition('entity_test_update')->getLabel())),
       ),
     );
-    $this->assertIdentical($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.');
+    $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.');
 
     // Run the update and ensure the new index is created.
     $this->entityDefinitionUpdateManager->applyUpdates();
@@ -504,7 +504,7 @@ public function testEntityIndexCreateDeleteWithoutData() {
         t('Update the %entity_type entity type.', array('%entity_type' => $this->entityManager->getDefinition('entity_test_update')->getLabel())),
       ),
     );
-    $this->assertIdentical($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.');
+    $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.');
 
     // Run the update and ensure the index is deleted.
     $this->entityDefinitionUpdateManager->applyUpdates();
diff --git a/core/modules/system/src/Tests/Form/ValidationTest.php b/core/modules/system/src/Tests/Form/ValidationTest.php
index 693d0af..0956676 100644
--- a/core/modules/system/src/Tests/Form/ValidationTest.php
+++ b/core/modules/system/src/Tests/Form/ValidationTest.php
@@ -284,7 +284,7 @@ function testCustomRequiredError() {
    */
   protected function assertErrorMessages($messages) {
     $element = $this->xpath('//div[@class = "form-item--error-message"]/strong');
-    $this->assertIdentical(count($messages), count($element));
+    $this->assertEqual(count($messages), count($element));
 
     $error_links = [];
     foreach ($messages as $delta => $message) {
@@ -293,7 +293,7 @@ protected function assertErrorMessages($messages) {
         $this->fail(format_string('The error message for the "@title" element with key "@key" was not found.', ['@title' => $message['title'], '@key' => $message['key']]));
       }
       else {
-        $this->assertIdentical($message['message'], (string) $element[$delta]);
+        $this->assertEqual($message['message'], (string) $element[$delta]);
       }
 
       // Gather the element for checking the jump link section.
diff --git a/core/modules/views/src/Plugin/views/area/TokenizeAreaPluginBase.php b/core/modules/views/src/Plugin/views/area/TokenizeAreaPluginBase.php
index 82bb51d..7c26932 100644
--- a/core/modules/views/src/Plugin/views/area/TokenizeAreaPluginBase.php
+++ b/core/modules/views/src/Plugin/views/area/TokenizeAreaPluginBase.php
@@ -52,14 +52,18 @@ public function tokenForm(&$form, FormStateInterface $form_state) {
 
     // Get a list of the available fields and arguments for token replacement.
     $options = array();
+    // We cast the optgroup labels to string as array keys must not be objects
+    // and t() may return a TranslationWrapper once issue #2557113 lands.
+    $optgroup_arguments = (string) t('Arguments');
+    $optgroup_fields = (string) t('Fields');
     foreach ($this->view->display_handler->getHandlers('field') as $field => $handler) {
-      $options[t('Fields')]["[$field]"] = $handler->adminLabel();
+      $options[$optgroup_fields]["[$field]"] = $handler->adminLabel();
     }
 
     $count = 0; // This lets us prepare the key as we want it printed.
     foreach ($this->view->display_handler->getHandlers('argument') as $handler) {
-      $options[t('Arguments')]['%' . ++$count] = $this->t('@argument title', array('@argument' => $handler->adminLabel()));
-      $options[t('Arguments')]['!' . $count] = $this->t('@argument input', array('@argument' => $handler->adminLabel()));
+      $options[$optgroup_arguments]['%' . ++$count] = $this->t('@argument title', array('@argument' => $handler->adminLabel()));
+      $options[$optgroup_arguments]['!' . $count] = $this->t('@argument input', array('@argument' => $handler->adminLabel()));
     }
 
     if (!empty($options)) {
diff --git a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
index 09fa129..403d935 100644
--- a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
+++ b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
@@ -1726,9 +1726,12 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
 
         $options = array();
         $count = 0; // This lets us prepare the key as we want it printed.
+        // We cast the optgroup label to string as array keys must not be objects
+        // and t() may return a TranslationWrapper once issue #2557113 lands.
+        $optgroup_arguments = (string) t('Arguments');
         foreach ($this->view->display_handler->getHandlers('argument') as $handler) {
-          $options[t('Arguments')]['%' . ++$count] = $this->t('@argument title', array('@argument' => $handler->adminLabel()));
-          $options[t('Arguments')]['!' . $count] = $this->t('@argument input', array('@argument' => $handler->adminLabel()));
+          $options[$optgroup_arguments]['%' . ++$count] = $this->t('@argument title', array('@argument' => $handler->adminLabel()));
+          $options[$optgroup_arguments]['!' . $count] = $this->t('@argument input', array('@argument' => $handler->adminLabel()));
         }
 
         // Default text.
diff --git a/core/modules/views/src/Plugin/views/exposed_form/InputRequired.php b/core/modules/views/src/Plugin/views/exposed_form/InputRequired.php
index 110115a..0d15d97 100644
--- a/core/modules/views/src/Plugin/views/exposed_form/InputRequired.php
+++ b/core/modules/views/src/Plugin/views/exposed_form/InputRequired.php
@@ -73,6 +73,9 @@ protected function exposedFilterApplied() {
   }
 
   public function preRender($values) {
+    // Display the "text on demand" if needed. This is a site builder-defined
+    // text to display instead of results until the user selects and applies
+    // an exposed filter.
     if (!$this->exposedFilterApplied()) {
       $options = array(
         'id' => 'area',
@@ -81,14 +84,22 @@ public function preRender($values) {
         'label' => '',
         'relationship' => 'none',
         'group_type' => 'group',
-        'content' => $this->options['text_input_required'],
-        'format' => $this->options['text_input_required_format'],
+        // We need to set the "Display even if view has no result" option to
+        // TRUE as the input required exposed form plugin will always force an
+        // empty result if no exposed filters are applied.
+        'empty' => TRUE,
+        'content' => [
+          // @see \Drupal\views\Plugin\views\area\Text::render()
+          'value' => $this->options['text_input_required'],
+          'format' => $this->options['text_input_required_format'],
+        ],
       );
       $handler = Views::handlerManager('area')->getHandler($options);
       $handler->init($this->view, $this->displayHandler, $options);
       $this->displayHandler->handlers['empty'] = array(
         'area' => $handler,
       );
+      // Override the existing empty result message (if applicable).
       $this->displayHandler->setOption('empty', array('text' => $options));
     }
   }
diff --git a/core/modules/views/src/Plugin/views/field/FieldPluginBase.php b/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
index 152d4e9..4f65e01 100644
--- a/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
+++ b/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
@@ -862,19 +862,23 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
 
       // Setup the tokens for fields.
       $previous = $this->getPreviousFieldLabels();
+      // We cast the optgroup labels to string as array keys must not be objects.
+      // and t() may return a TranslationWrapper once issue #2557113 lands.
+      $optgroup_arguments = (string) t('Arguments');
+      $optgroup_fields = (string) t('Fields');
       foreach ($previous as $id => $label) {
-        $options[t('Fields')]["{{ $id }}"] = substr(strrchr($label, ":"), 2 );
+        $options[$optgroup_fields]["{{ $id }}"] = substr(strrchr($label, ":"), 2 );
       }
       // Add the field to the list of options.
-      $options[t('Fields')]["{{ {$this->options['id']} }}"] = substr(strrchr($this->adminLabel(), ":"), 2 );
+      $options[$optgroup_fields]["{{ {$this->options['id']} }}"] = substr(strrchr($this->adminLabel(), ":"), 2 );
 
       $count = 0; // This lets us prepare the key as we want it printed.
       foreach ($this->view->display_handler->getHandlers('argument') as $arg => $handler) {
-        $options[t('Arguments')]['%' . ++$count] = $this->t('@argument title', array('@argument' => $handler->adminLabel()));
-        $options[t('Arguments')]['!' . $count] = $this->t('@argument input', array('@argument' => $handler->adminLabel()));
+        $options[$optgroup_arguments]['%' . ++$count] = $this->t('@argument title', array('@argument' => $handler->adminLabel()));
+        $options[$optgroup_arguments]['!' . $count] = $this->t('@argument input', array('@argument' => $handler->adminLabel()));
       }
 
-      $this->documentSelfTokens($options[t('Fields')]);
+      $this->documentSelfTokens($options[$optgroup_fields]);
 
       // Default text.
 
diff --git a/core/modules/views/src/Tests/ModuleTest.php b/core/modules/views/src/Tests/ModuleTest.php
index 7d5a31b..eb19d09 100644
--- a/core/modules/views/src/Tests/ModuleTest.php
+++ b/core/modules/views/src/Tests/ModuleTest.php
@@ -157,40 +157,40 @@ public function testLoadFunctions() {
     $all_views = $storage->loadMultiple();
 
     // Test Views::getAllViews().
-    $this->assertIdentical(array_keys($all_views), array_keys(Views::getAllViews()), 'Views::getAllViews works as expected.');
+    $this->assertEqual(array_keys($all_views), array_keys(Views::getAllViews()), 'Views::getAllViews works as expected.');
 
     // Test Views::getEnabledViews().
     $expected_enabled = array_filter($all_views, function($view) {
       return views_view_is_enabled($view);
     });
-    $this->assertIdentical(array_keys($expected_enabled), array_keys(Views::getEnabledViews()), 'Expected enabled views returned.');
+    $this->assertEqual(array_keys($expected_enabled), array_keys(Views::getEnabledViews()), 'Expected enabled views returned.');
 
     // Test Views::getDisabledViews().
     $expected_disabled = array_filter($all_views, function($view) {
       return views_view_is_disabled($view);
     });
-    $this->assertIdentical(array_keys($expected_disabled), array_keys(Views::getDisabledViews()), 'Expected disabled views returned.');
+    $this->assertEqual(array_keys($expected_disabled), array_keys(Views::getDisabledViews()), 'Expected disabled views returned.');
 
     // Test Views::getViewsAsOptions().
     // Test the $views_only parameter.
-    $this->assertIdentical(array_keys($all_views), array_keys(Views::getViewsAsOptions(TRUE)), 'Expected option keys for all views were returned.');
+    $this->assertEqual(array_keys($all_views), array_keys(Views::getViewsAsOptions(TRUE)), 'Expected option keys for all views were returned.');
     $expected_options = array();
     foreach ($all_views as $id => $view) {
       $expected_options[$id] = $view->label();
     }
-    $this->assertIdentical($expected_options, Views::getViewsAsOptions(TRUE), 'Expected options array was returned.');
+    $this->assertEqual($expected_options, Views::getViewsAsOptions(TRUE), 'Expected options array was returned.');
 
     // Test the default.
-    $this->assertIdentical($this->formatViewOptions($all_views), Views::getViewsAsOptions(), 'Expected options array for all views was returned.');
+    $this->assertEqual($this->formatViewOptions($all_views), Views::getViewsAsOptions(), 'Expected options array for all views was returned.');
     // Test enabled views.
-    $this->assertIdentical($this->formatViewOptions($expected_enabled), Views::getViewsAsOptions(FALSE, 'enabled'), 'Expected enabled options array was returned.');
+    $this->assertEqual($this->formatViewOptions($expected_enabled), Views::getViewsAsOptions(FALSE, 'enabled'), 'Expected enabled options array was returned.');
     // Test disabled views.
-    $this->assertIdentical($this->formatViewOptions($expected_disabled), Views::getViewsAsOptions(FALSE, 'disabled'), 'Expected disabled options array was returned.');
+    $this->assertEqual($this->formatViewOptions($expected_disabled), Views::getViewsAsOptions(FALSE, 'disabled'), 'Expected disabled options array was returned.');
 
     // Test the sort parameter.
     $all_views_sorted = $all_views;
     ksort($all_views_sorted);
-    $this->assertIdentical(array_keys($all_views_sorted), array_keys(Views::getViewsAsOptions(TRUE, 'all', NULL, FALSE, TRUE)), 'All view id keys returned in expected sort order');
+    $this->assertEqual(array_keys($all_views_sorted), array_keys(Views::getViewsAsOptions(TRUE, 'all', NULL, FALSE, TRUE)), 'All view id keys returned in expected sort order');
 
     // Test $exclude_view parameter.
     $this->assertFalse(array_key_exists('archive', Views::getViewsAsOptions(TRUE, 'all', 'archive')), 'View excluded from options based on name');
@@ -204,7 +204,7 @@ public function testLoadFunctions() {
           $expected_opt_groups[$view->id()][$view->id() . ':' . $display['id']] = t('@view : @display', array('@view' => $view->id(), '@display' => $display['id']));
       }
     }
-    $this->assertIdentical($expected_opt_groups, Views::getViewsAsOptions(FALSE, 'all', NULL, TRUE), 'Expected option array for an option group returned.');
+    $this->assertEqual($expected_opt_groups, Views::getViewsAsOptions(FALSE, 'all', NULL, TRUE), 'Expected option array for an option group returned.');
   }
 
   /**
@@ -236,16 +236,16 @@ public function testViewsFetchPluginNames() {
       $expected[$id] = $definition['title'];
     }
     asort($expected);
-    $this->assertIdentical(array_keys($plugins), array_keys($expected));
+    $this->assertEqual(array_keys($plugins), array_keys($expected));
 
     // Test using the 'test' style plugin type only returns the test_style and
     // mapping_test plugins.
     $plugins = Views::fetchPluginNames('style', 'test');
-    $this->assertIdentical(array_keys($plugins), array('mapping_test', 'test_style', 'test_template_style'));
+    $this->assertEqual(array_keys($plugins), array('mapping_test', 'test_style', 'test_template_style'));
 
     // Test a non existent style plugin type returns no plugins.
     $plugins = Views::fetchPluginNames('style', $this->randomString());
-    $this->assertIdentical($plugins, array());
+    $this->assertEqual($plugins, array());
   }
 
   /**
diff --git a/core/modules/views/src/Tests/Plugin/ExposedFormTest.php b/core/modules/views/src/Tests/Plugin/ExposedFormTest.php
index f1ef4c5..5df5465 100644
--- a/core/modules/views/src/Tests/Plugin/ExposedFormTest.php
+++ b/core/modules/views/src/Tests/Plugin/ExposedFormTest.php
@@ -194,6 +194,31 @@ public function testInputRequired() {
   }
 
   /**
+   * Test the "on demand text" for the input required exposed form type.
+   */
+  public function testTextInputRequired() {
+    $view = Views::getView('test_exposed_form_buttons');
+    $display = &$view->storage->getDisplay('default');
+    $display['display_options']['exposed_form']['type'] = 'input_required';
+    // Set up the "on demand text".
+    // @see https://www.drupal.org/node/535868
+    $on_demand_text = 'Select any filter and click Apply to see results.';
+    $display['display_options']['exposed_form']['options']['text_input_required'] = $on_demand_text;
+    $display['display_options']['exposed_form']['options']['text_input_required_format'] = filter_default_format();
+    $view->save();
+
+    // Ensure that the "on demand text" is displayed when no exposed filters are
+    // applied.
+    $this->drupalGet('test_exposed_form_buttons');
+    $this->assertText('Select any filter and click Apply to see results.');
+
+    // Ensure that the "on demand text" is not displayed when an exposed filter
+    // is applied.
+    $this->drupalGet('test_exposed_form_buttons', array('query' => array('type' => 'article')));
+    $this->assertNoText($on_demand_text);
+  }
+
+  /**
    * Tests exposed forms with exposed sort and items per page.
    */
   public function testExposedSortAndItemsPerPage() {
diff --git a/core/modules/views_ui/admin.inc b/core/modules/views_ui/admin.inc
index 78be0fc..cbb0782 100644
--- a/core/modules/views_ui/admin.inc
+++ b/core/modules/views_ui/admin.inc
@@ -92,8 +92,9 @@ function views_ui_add_ajax_trigger(&$wrapping_element, $trigger_key, $refresh_pa
   }
   // For easiest integration with the form API and the testing framework, we
   // always give the button a unique #value, rather than playing around with
-  // #name.
-  $button_title = !empty($triggering_element['#title']) ? $triggering_element['#title'] : $trigger_key;
+  // #name. We also cast the #title to string as we will use it as an array
+  // key and it may be a TranslationWrapper.
+  $button_title = !empty($triggering_element['#title']) ? (string) $triggering_element['#title'] : $trigger_key;
   if (empty($seen_buttons[$button_title])) {
     $wrapping_element[$button_key]['#value'] = t('Update "@title" choice', array(
       '@title' => $button_title,
