diff --git a/core/modules/system/src/Tests/Menu/MenuRouterTest.php b/core/modules/system/src/Tests/Menu/MenuRouterTest.php
index 4089931..d75bd6c 100644
--- a/core/modules/system/src/Tests/Menu/MenuRouterTest.php
+++ b/core/modules/system/src/Tests/Menu/MenuRouterTest.php
@@ -296,19 +296,19 @@ protected function doTestThemeCallbackMaintenanceMode() {
    */
   protected function doTestThemeCallbackOptionalTheme() {
     // Request a theme that is not installed.
-    $this->drupalGet('menu-test/theme-callback/use-stark-theme');
+    $this->drupalGet('menu-test/theme-callback/use-test-theme');
     $this->assertText('Active theme: bartik. Actual theme: bartik.', 'The theme negotiation system falls back on the default theme when a theme that is not installed is requested.');
     $this->assertRaw('bartik/css/base/elements.css', "The default theme's CSS appears on the page.");
 
     // Now install the theme and request it again.
     $theme_handler = $this->container->get('theme_handler');
-    $theme_handler->install(array('stark'));
+    $theme_handler->install(array('test_theme'));
 
-    $this->drupalGet('menu-test/theme-callback/use-stark-theme');
-    $this->assertText('Active theme: stark. Actual theme: stark.', 'The theme negotiation system uses an optional theme once it has been installed.');
-    $this->assertRaw('stark/css/layout.css', "The optional theme's CSS appears on the page.");
+    $this->drupalGet('menu-test/theme-callback/use-test-theme');
+    $this->assertText('Active theme: test_theme. Actual theme: test_theme.', 'The theme negotiation system uses an optional theme once it has been installed.');
+    $this->assertRaw('test_theme/kitten.css', "The optional theme's CSS appears on the page.");
 
-    $theme_handler->uninstall(array('stark'));
+    $theme_handler->uninstall(array('test_theme'));
   }
 
   /**
diff --git a/core/modules/system/src/Tests/Theme/ThemeInfoTest.php b/core/modules/system/src/Tests/Theme/ThemeInfoTest.php
index 3d376ed..55c71e6 100644
--- a/core/modules/system/src/Tests/Theme/ThemeInfoTest.php
+++ b/core/modules/system/src/Tests/Theme/ThemeInfoTest.php
@@ -94,13 +94,13 @@ public function testChanges() {
     $active_theme = $this->themeManager->getActiveTheme();
     // Make sure we are not testing the wrong theme.
     $this->assertEqual('test_theme', $active_theme->getName());
-    $this->assertEqual(['classy/base'], $active_theme->getLibraries());
+    $this->assertEqual(['classy/base', 'test_theme/global-styling'], $active_theme->getLibraries());
 
     // @see theme_test_system_info_alter()
     $this->state->set('theme_test.modify_info_files', TRUE);
     drupal_flush_all_caches();
     $active_theme = $this->themeManager->getActiveTheme();
-    $this->assertEqual(['classy/base', 'core/backbone'], $active_theme->getLibraries());
+    $this->assertEqual(['classy/base', 'test_theme/global-styling', 'core/backbone'], $active_theme->getLibraries());
   }
 
 }
diff --git a/core/modules/system/tests/modules/menu_test/src/Theme/TestThemeNegotiator.php b/core/modules/system/tests/modules/menu_test/src/Theme/TestThemeNegotiator.php
index b4cdd0a..2d8c5f3 100644
--- a/core/modules/system/tests/modules/menu_test/src/Theme/TestThemeNegotiator.php
+++ b/core/modules/system/tests/modules/menu_test/src/Theme/TestThemeNegotiator.php
@@ -35,8 +35,8 @@ public function determineActiveTheme(RouteMatchInterface $route_match) {
       return \Drupal::config('system.theme')->get('admin');
     }
     // Test using a theme that exists, but may or may not be installed.
-    elseif ($argument == 'use-stark-theme') {
-      return 'stark';
+    elseif ($argument == 'use-test-theme') {
+      return 'test_theme';
     }
     // Test using a theme that does not exist.
     elseif ($argument == 'use-fake-theme') {
diff --git a/core/modules/system/tests/themes/test_theme/test_theme.info.yml b/core/modules/system/tests/themes/test_theme/test_theme.info.yml
index 7ddcb2d..e9d6602 100644
--- a/core/modules/system/tests/themes/test_theme/test_theme.info.yml
+++ b/core/modules/system/tests/themes/test_theme/test_theme.info.yml
@@ -16,6 +16,8 @@ base theme: classy
 core: 8.x
 stylesheets-remove:
   - '@system/css/system.module.css'
+libraries:
+  - test_theme/global-styling
 regions:
   content: Content
   left: Left
diff --git a/core/modules/system/tests/themes/test_theme/test_theme.libraries.yml b/core/modules/system/tests/themes/test_theme/test_theme.libraries.yml
new file mode 100644
index 0000000..c1fe4a5
--- /dev/null
+++ b/core/modules/system/tests/themes/test_theme/test_theme.libraries.yml
@@ -0,0 +1,5 @@
+global-styling:
+  version: VERSION
+  css:
+    base:
+      kitten.css: {}
diff --git a/core/modules/toolbar/src/Tests/ToolbarAdminMenuTest.php.orig b/core/modules/toolbar/src/Tests/ToolbarAdminMenuTest.php.orig
new file mode 100644
index 0000000..0f8ad49
--- /dev/null
+++ b/core/modules/toolbar/src/Tests/ToolbarAdminMenuTest.php.orig
@@ -0,0 +1,529 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\toolbar\Tests\ToolbarAdminMenuTest.
+ */
+
+namespace Drupal\toolbar\Tests;
+
+use Drupal\Core\Cache\Cache;
+use Drupal\Core\Language\LanguageInterface;
+use Drupal\language\Entity\ConfigurableLanguage;
+use Drupal\simpletest\WebTestBase;
+use Drupal\user\RoleInterface;
+
+/**
+ * Tests the caching of the admin menu subtree items.
+ *
+ * The cache of the admin menu subtree items will be invalidated if the
+ * following hooks are invoked.
+ *
+ * toolbar_modules_enabled()
+ * toolbar_modules_disabled()
+ * toolbar_menu_link_update()
+ * toolbar_user_update()
+ * toolbar_user_role_update()
+ *
+ * Each hook invocation is simulated and then the previous hash of the admin
+ * menu subtrees is compared to the new hash.
+ *
+ * @group toolbar
+ */
+class ToolbarAdminMenuTest extends WebTestBase {
+
+  /**
+   * A user with permission to access the administrative toolbar.
+   *
+   * @var \Drupal\user\UserInterface
+   */
+  protected $adminUser;
+
+  /**
+   * A second user with permission to access the administrative toolbar.
+   *
+   * @var \Drupal\user\UserInterface
+   */
+  protected $adminUser2;
+
+  /**
+   * The current admin menu subtrees hash for adminUser.
+   *
+   * @var string
+   */
+  protected $hash;
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('node', 'block', 'menu_ui', 'user', 'taxonomy', 'toolbar', 'language', 'test_page_test', 'locale');
+
+  protected function setUp() {
+    parent::setUp();
+
+    $perms = array(
+      'access toolbar',
+      'access administration pages',
+      'administer site configuration',
+      'bypass node access',
+      'administer themes',
+      'administer nodes',
+      'access content overview',
+      'administer blocks',
+      'administer menu',
+      'administer modules',
+      'administer permissions',
+      'administer users',
+      'access user profiles',
+      'administer taxonomy',
+      'administer languages',
+      'translate interface',
+    );
+
+    // Create an administrative user and log it in.
+    $this->adminUser = $this->drupalCreateUser($perms);
+    $this->adminUser2 = $this->drupalCreateUser($perms);
+
+    $this->drupalLogin($this->adminUser);
+
+    $this->drupalGet('test-page');
+    $this->assertResponse(200);
+
+    // Assert that the toolbar is present in the HTML.
+    $this->assertRaw('id="toolbar-administration"');
+
+    // Store the adminUser admin menu subtrees hash for comparison later.
+    $this->hash = $this->getSubtreesHash();
+  }
+
+  /**
+   * Tests the toolbar_modules_installed() and toolbar_modules_uninstalled() hook
+   * implementations.
+   */
+  function testModuleStatusChangeSubtreesHashCacheClear() {
+    // Uninstall a module.
+    $edit = array();
+    $edit['uninstall[taxonomy]'] = TRUE;
+    $this->drupalPostForm('admin/modules/uninstall', $edit, t('Uninstall'));
+    // Confirm the uninstall form.
+    $this->drupalPostForm(NULL, array(), t('Uninstall'));
+    $this->rebuildContainer();
+
+    // Assert that the subtrees hash has been altered because the subtrees
+    // structure changed.
+    $this->assertDifferentHash();
+
+    // Enable a module.
+    $edit = array();
+    $edit['modules[Core][taxonomy][enable]'] = TRUE;
+    $this->drupalPostForm('admin/modules', $edit, t('Save configuration'));
+    $this->rebuildContainer();
+
+    // Assert that the subtrees hash has been altered because the subtrees
+    // structure changed.
+    $this->assertDifferentHash();
+  }
+
+  /**
+   * Tests toolbar cache tags implementation.
+   */
+  function testMenuLinkUpdateSubtreesHashCacheClear() {
+    // The ID of a (any) admin menu link.
+    $admin_menu_link_id = 'system.admin_config_development';
+
+    // Disable the link.
+    $edit = array();
+    $edit['enabled'] = FALSE;
+    $this->drupalPostForm("admin/structure/menu/link/" . $admin_menu_link_id . "/edit", $edit, t('Save'));
+    $this->assertResponse(200);
+    $this->assertText('The menu link has been saved.');
+
+    // Assert that the subtrees hash has been altered because the subtrees
+    // structure changed.
+    $this->assertDifferentHash();
+  }
+
+  /**
+   * Exercises the toolbar_user_role_update() and toolbar_user_update() hook
+   * implementations.
+   */
+  function testUserRoleUpdateSubtreesHashCacheClear() {
+    // Find the new role ID.
+    $all_rids = $this->adminUser->getRoles();
+    unset($all_rids[array_search(RoleInterface::AUTHENTICATED_ID, $all_rids)]);
+    $rid = reset($all_rids);
+
+    $edit = array();
+    $edit[$rid . '[administer taxonomy]'] = FALSE;
+    $this->drupalPostForm('admin/people/permissions', $edit, t('Save permissions'));
+
+    // Assert that the subtrees hash has been altered because the subtrees
+    // structure changed.
+    $this->assertDifferentHash();
+
+    // Test that assigning a user an extra role only affects that single user.
+    // Get the hash for a second user.
+    $this->drupalLogin($this->adminUser2);
+    $this->drupalGet('test-page');
+    $this->assertResponse(200);
+
+    // Assert that the toolbar is present in the HTML.
+    $this->assertRaw('id="toolbar-administration"');
+
+    $admin_user_2_hash = $this->getSubtreesHash();
+
+    // Log in the first admin user again.
+    $this->drupalLogin($this->adminUser);
+    $this->drupalGet('test-page');
+    $this->assertResponse(200);
+
+    // Assert that the toolbar is present in the HTML.
+    $this->assertRaw('id="toolbar-administration"');
+
+    $this->hash = $this->getSubtreesHash();
+
+    $rid = $this->drupalCreateRole(array('administer content types',));
+
+    // Assign the role to the user.
+    $this->drupalPostForm('user/' . $this->adminUser->id() . '/edit', array("roles[$rid]" => $rid), t('Save'));
+    $this->assertText(t('The changes have been saved.'));
+
+    // Assert that the subtrees hash has been altered because the subtrees
+    // structure changed.
+    $this->assertDifferentHash();
+
+    // Log in the second user again and assert that their subtrees hash did not
+    // change.
+    $this->drupalLogin($this->adminUser2);
+
+    // Request a new page to refresh the drupalSettings object.
+    $this->drupalGet('test-page');
+    $this->assertResponse(200);
+    $new_subtree_hash = $this->getSubtreesHash();
+
+    // Assert that the old admin menu subtree hash and the new admin menu
+    // subtree hash are the same.
+    $this->assertTrue($new_subtree_hash, 'A valid hash value for the admin menu subtrees was created.');
+    $this->assertEqual($admin_user_2_hash, $new_subtree_hash, 'The user-specific subtree menu hash has not been updated.');
+  }
+
+  /**
+   * Tests that all toolbar cache entries for a user are cleared with a cache
+   * tag for that user, i.e. cache entries for all languages for that user.
+   */
+  function testCacheClearByCacheTag() {
+    // Test that the toolbar admin menu subtrees cache is invalidated for a user
+    // across multiple languages.
+    $this->drupalLogin($this->adminUser);
+    $toolbarCache = $this->container->get('cache.toolbar');
+    $admin_user_id = $this->adminUser->id();
+    $admin_user_2_id = $this->adminUser2->id();
+
+    // Assert that a cache tag in the toolbar cache under the key "user" exists
+    // for adminUser against the language "en".
+    $cache = $toolbarCache->get('toolbar_' . $admin_user_id . ':' . 'en');
+    $this->assertEqual(in_array('user:' . $admin_user_id, $cache->tags), 'A cache tag in the toolbar cache under the key "user" exists for admin_user against the language "en".');
+
+    // Assert that no toolbar cache exists for adminUser against the
+    // language "fr".
+    $cache = $toolbarCache->get('toolbar_' . $admin_user_id . ':' . 'fr');
+    $this->assertFalse($cache, 'No toolbar cache exists for admin_user against the language "fr".');
+
+    // Install a second language.
+    $edit = array(
+      'predefined_langcode' => 'fr',
+    );
+    $this->drupalPostForm('admin/config/regional/language/add', $edit, 'Add language');
+
+    // Request a page in 'fr' to update the cache.
+    $this->drupalGet('fr/test-page');
+    $this->assertResponse(200);
+
+    // Assert that a cache tag in the toolbar cache under the key "user" exists
+    // for adminUser against the language "fr".
+    $cache = $toolbarCache->get('toolbar_' . $admin_user_id . ':' . 'fr');
+    $this->assertEqual(in_array('user:' . $admin_user_id, $cache->tags), 'A cache tag in the toolbar cache under the key "user" exists for admin_user against the language "fr".');
+
+    // Log in the adminUser2 user. We will use this user as a control to
+    // verify that clearing a cache tag for adminUser does not clear the cache
+    // for adminUser2.
+    $this->drupalLogin($this->adminUser2);
+
+    // Request a page in 'en' to create the cache.
+    $this->drupalGet('test-page');
+    $this->assertResponse(200);
+    // Assert that a cache tag in the toolbar cache under the key "user" exists
+    // for adminUser2 against the language "en".
+    $cache = $toolbarCache->get('toolbar_' . $admin_user_2_id . ':' . 'en');
+    $this->assertEqual(in_array('user:' . $admin_user_2_id, $cache->tags), 'A cache tag in the toolbar cache under the key "user" exists for admin_user_2 against the language "en".');
+
+    // Request a page in 'fr' to create the cache.
+    $this->drupalGet('fr/test-page');
+    $this->assertResponse(200);
+    // Assert that a cache tag in the toolbar cache under the key "user" exists
+    // for adminUser against the language "fr".
+    $cache = $toolbarCache->get('toolbar_' . $admin_user_2_id . ':' . 'fr');
+    $this->assertEqual(in_array('user:' . $admin_user_2_id, $cache->tags), 'A cache tag in the toolbar cache under the key "user" exists for admin_user_2 against the language "fr".');
+
+    // Log in the admin user and clear the caches for this user using a tag.
+    $this->drupalLogin($this->adminUser);
+    Cache::invalidateTags(array('user:' . $admin_user_id));
+
+    // Assert that no toolbar cache exists for adminUser against the
+    // language "en".
+    $cache = $toolbarCache->get($admin_user_id . ':' . 'en');
+    $this->assertFalse($cache, 'No toolbar cache exists for admin_user against the language "en".');
+
+    // Assert that no toolbar cache exists for adminUser against the
+    // language "fr".
+    $cache = $toolbarCache->get($admin_user_id . ':' . 'fr');
+    $this->assertFalse($cache, 'No toolbar cache exists for admin_user against the language "fr".');
+
+    // Log in adminUser2 and verify that this user's caches still exist.
+    $this->drupalLogin($this->adminUser2);
+
+    // Assert that a cache tag in the toolbar cache under the key "user" exists
+    // for adminUser2 against the language "en".
+    $cache = $toolbarCache->get('toolbar_' . $admin_user_2_id . ':' . 'en');
+    $this->assertEqual(in_array('user:' . $admin_user_2_id, $cache->tags), 'A cache tag in the toolbar cache under the key "user" exists for admin_user_2 against the language "en".');
+
+    // Assert that a cache tag in the toolbar cache under the key "user" exists
+    // for adminUser2 against the language "fr".
+    $cache = $toolbarCache->get('toolbar_' . $admin_user_2_id . ':' . 'fr');
+    $this->assertEqual(in_array('user:' . $admin_user_2_id, $cache->tags), 'A cache tag in the toolbar cache under the key "user" exists for admin_user_2 against the language "fr".');
+  }
+
+  /**
+   * Tests that changes to a user account by another user clears the changed
+   * account's toolbar cached, not the user's who took the action.
+   */
+  function testNonCurrentUserAccountUpdates() {
+    $toolbarCache = $this->container->get('cache.toolbar');
+    $admin_user_id = $this->adminUser->id();
+    $admin_user_2_id = $this->adminUser2->id();
+    $this->hash = $this->getSubtreesHash();
+
+    // adminUser2 will add a role to adminUser.
+    $this->drupalLogin($this->adminUser2);
+    $rid = $this->drupalCreateRole(array('administer content types',));
+
+    // Get the subtree hash for adminUser2 to check later that it has not
+    // changed. Request a new page to refresh the drupalSettings object.
+    $this->drupalGet('test-page');
+    $this->assertResponse(200);
+    $admin_user_2_hash = $this->getSubtreesHash();
+
+    // Assign the role to the user.
+    $this->drupalPostForm('user/' . $admin_user_id . '/edit', array("roles[$rid]" => $rid), t('Save'));
+    $this->assertText(t('The changes have been saved.'));
+
+    // Log in adminUser and assert that the subtrees hash has changed.
+    $this->drupalLogin($this->adminUser);
+    $this->assertDifferentHash();
+
+    // Log in adminUser2 to check that its subtrees hash has not changed.
+    $this->drupalLogin($this->adminUser2);
+    $new_subtree_hash = $this->getSubtreesHash();
+
+    // Assert that the old adminUser subtree hash and the new adminUser
+    // subtree hash are the same.
+    $this->assertTrue($new_subtree_hash, 'A valid hash value for the admin menu subtrees was created.');
+    $this->assertEqual($admin_user_2_hash, $new_subtree_hash, 'The user-specific subtree menu hash has not been updated.');
+  }
+
+  /**
+   * Tests that toolbar cache is cleared when string translations are made.
+   */
+  function testLocaleTranslationSubtreesHashCacheClear() {
+    $toolbarCache = $this->container->get('cache.toolbar');
+    $admin_user = $this->adminUser;
+    $admin_user_id = $this->adminUser->id();
+    // User to translate and delete string.
+    $translate_user = $this->drupalCreateUser(array('translate interface', 'access administration pages'));
+
+    // Create a new language with the langcode 'xx'.
+    $langcode = 'xx';
+    // The English name for the language. This will be translated.
+    $name = $this->randomMachineName(16);
+    // This is the language indicator on the translation search screen for
+    // untranslated strings.
+    $language_indicator = "<em class=\"locale-untranslated\">$langcode</em> ";
+    // This will be the translation of $name.
+    $translation = $this->randomMachineName(16);
+    $translation_to_en = $this->randomMachineName(16);
+
+    // Add custom language.
+    $this->drupalLogin($admin_user);
+    $edit = array(
+      'predefined_langcode' => 'custom',
+      'langcode' => $langcode,
+      'label' => $name,
+      'direction' => LanguageInterface::DIRECTION_LTR,
+    );
+    $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language'));
+    t($name, array(), array('langcode' => $langcode));
+    // Reset locale cache.
+    $this->container->get('string_translation')->reset();
+    $this->assertRaw('"edit-languages-' . $langcode .'-weight"', 'Language code found.');
+    $this->assertText(t($name), 'Test language added.');
+
+    // Have the adminUser request a page in the new language.
+    $this->drupalGet($langcode . '/test-page');
+    $this->assertResponse(200);
+
+    // Assert that a cache tag in the toolbar cache under the key "user" exists
+    // for adminUser against the language "xx".
+    $cache = $toolbarCache->get('toolbar_' . $admin_user_id . ':' . $langcode);
+    $this->assertEqual(in_array('user:' . $admin_user_id, $cache->tags), 'A cache tag in the toolbar cache under the key "user" exists for admin_user against the language "xx".');
+
+    // Get a baseline hash for the admin menu subtrees before translating one
+    // of the menu link items.
+    $original_subtree_hash = $this->getSubtreesHash();
+    $this->assertTrue($original_subtree_hash, 'A valid hash value for the admin menu subtrees was created.');
+    $this->drupalLogout();
+
+    // Translate the string 'Menus' in the xx language. This string appears in
+    // a link in the admin menu subtrees. Changing the string should create a
+    // new menu hash if the toolbar subtrees cache is properly cleared.
+    $this->drupalLogin($translate_user);
+    $search = array(
+      'string' => 'Menus',
+      'langcode' => $langcode,
+      'translation' => 'untranslated',
+    );
+    $this->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
+    $this->assertNoText(t('No strings available'));
+    $this->assertText($name, 'Search found the string as untranslated.');
+
+    // Assume this is the only result.
+    // Translate the string to a random string.
+    $textarea = current($this->xpath('//textarea'));
+    $lid = (string) $textarea[0]['name'];
+    $edit = array(
+      $lid => $translation,
+    );
+    $this->drupalPostForm('admin/config/regional/translate', $edit, t('Save translations'));
+    $this->assertText(t('The strings have been saved.'), 'The strings have been saved.');
+    $this->assertUrl(\Drupal::url('locale.translate_page', [], ['absolute' => TRUE]), [], 'Correct page redirection.');
+    $this->drupalLogout();
+
+    // Log in the adminUser. Check the admin menu subtrees hash now that one
+    // of the link items in the Structure tree (Menus) has had its text
+    // translated.
+    $this->drupalLogin($admin_user);
+    // Have the adminUser request a page in the new language.
+    $this->drupalGet($langcode . '/test-page');
+    $this->assertResponse(200);
+    $new_subtree_hash = $this->getSubtreesHash();
+
+    // Assert that the old admin menu subtrees hash and the new admin menu
+    // subtrees hash are different.
+    $this->assertTrue($new_subtree_hash, 'A valid hash value for the admin menu subtrees was created.');
+    $this->assertNotEqual($original_subtree_hash, $new_subtree_hash, 'The user-specific subtree menu hash has been updated.');
+  }
+
+  /**
+   * Tests that the 'toolbar/subtrees/{hash}' is reachable.
+   */
+  function testSubtreesJsonRequest() {
+    $admin_user = $this->adminUser;
+    $this->drupalLogin($admin_user);
+    // Request a new page to refresh the drupalSettings object.
+    $subtrees_hash = $this->getSubtreesHash();
+
+    $this->drupalGetJSON('toolbar/subtrees/' . $subtrees_hash);
+    $this->assertResponse('200');
+
+    // Test that the subtrees hash changes with a different language code and
+    // that JSON is returned when a language code is specified.
+    // Create a new language with the langcode 'xx'.
+    $langcode = 'xx';
+    // The English name for the language. This will be translated.
+    $name = $this->randomMachineName(16);
+    $edit = array(
+      'predefined_langcode' => 'custom',
+      'langcode' => $langcode,
+      'label' => $name,
+      'direction' => LanguageInterface::DIRECTION_LTR,
+    );
+    $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language'));
+
+    // Get a page with the new language langcode in the URL.
+    $this->drupalGet('xx/test-page');
+    // Request a new page to refresh the drupalSettings object.
+    $subtrees_hash = $this->getSubtreesHash();
+
+    $this->drupalGetJSON('toolbar/subtrees/' . $subtrees_hash . '/' . $langcode);
+    $this->assertResponse('200');
+  }
+
+  /**
+   *  Test that subtrees hashes vary by the language of the page.
+   */
+  function testLanguageSwitching() {
+    // Create a new language with the langcode 'xx'.
+    $langcode = 'xx';
+    $language = ConfigurableLanguage::createFromLangcode($langcode);
+    $language->save();
+    // The language path processor is just registered for more than one
+    // configured language, so rebuild the container now that we are
+    // multilingual.
+    $this->rebuildContainer();
+
+    // Get a page with the new language langcode in the URL.
+    $this->drupalGet('test-page', array('language' => $language));
+    // Assert different hash.
+    $new_subtree_hash = $this->getSubtreesHash();
+
+    // Assert that the old admin menu subtree hash and the new admin menu
+    // subtree hash are different.
+    $this->assertTrue($new_subtree_hash, 'A valid hash value for the admin menu subtrees was created.');
+    $this->assertNotEqual($this->hash, $new_subtree_hash, 'The user-specific subtree menu hash has been updated.');
+  }
+
+  /**
+   * Test that back to site link exists on admin pages, not on content pages.
+   */
+  public function testBackToSiteLink() {
+    // Back to site link should exist in the markup.
+    $this->drupalGet('test-page');
+    $back_link = $this->cssSelect('.home-toolbar-tab');
+    $this->assertTrue($back_link);
+  }
+
+  /**
+   * Get the hash value from the admin menu subtrees route path.
+   *
+   * @return string
+   *   The hash value from the admin menu subtrees route path.
+   */
+  private function getSubtreesHash() {
+    $settings = $this->getDrupalSettings();
+    // The toolbar module defines a route '/toolbar/subtrees/{hash}' that
+    // returns JSON for the rendered subtrees. This hash is provided to the
+    // client in drupalSettings.
+    return $settings['toolbar']['subtreesHash'];
+  }
+
+  /**
+   * Asserts the subtrees hash on a fresh page GET is different from the hash
+   * from the previous page GET.
+   */
+  private function assertDifferentHash() {
+    // Request a new page to refresh the drupalSettings object.
+    $this->drupalGet('test-page');
+    $this->assertResponse(200);
+    $new_subtree_hash = $this->getSubtreesHash();
+
+    // Assert that the old admin menu subtree hash and the new admin menu
+    // subtree hash are different.
+    $this->assertTrue($new_subtree_hash, 'A valid hash value for the admin menu subtrees was created.');
+    $this->assertNotEqual($this->hash, $new_subtree_hash, 'The user-specific subtree menu hash has been updated.');
+
+    // Save the new subtree hash as the original.
+    $this->hash = $new_subtree_hash;
+  }
+
+}
diff --git a/core/themes/stark/README.txt b/core/themes/stark/README.txt
index 141a3d0..552261a 100644
--- a/core/themes/stark/README.txt
+++ b/core/themes/stark/README.txt
@@ -10,9 +10,7 @@ default markup without the interference of changes commonly made by more
 complex themes.
 
 To avoid obscuring CSS added to the page by Drupal or a contrib module, the
-Stark theme itself has no styling, except just enough CSS to arrange the page
-in a traditional "Header, sidebars, content, and footer" layout. See the
-layout.css file for more information.
+Stark theme itself has no styling.
 
 
 ABOUT DRUPAL THEMING
diff --git a/core/themes/stark/config/schema/stark.schema.yml b/core/themes/stark/config/schema/stark.schema.yml
deleted file mode 100644
index 2b7f958..0000000
--- a/core/themes/stark/config/schema/stark.schema.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-# Schema for the configuration files of the Stark theme.
-
-stark.settings:
-  type: theme_settings
-  label: 'Stark settings'
diff --git a/core/themes/stark/css/layout.css b/core/themes/stark/css/layout.css
index 486014b..e69de29 100644
--- a/core/themes/stark/css/layout.css
+++ b/core/themes/stark/css/layout.css
@@ -1,123 +0,0 @@
-/**
- * @file
- * Stark layout method
- *
- * To avoid obscuring CSS added to the page by Drupal or a contrib module, the
- * Stark theme itself has no styling, except just enough CSS to arrange the page
- * in a traditional "Header, sidebars, content, and footer" layout.
- *
- * This layout method works reasonably well, but shouldn't be used on a
- * production site because it can break. For example, if an over-large image
- * (one that is wider than 20% of the viewport) is in the left sidebar, the
- * image will overlap with the .layout-content to the right.
- */
-img {
-  height: auto;
-  max-width: 100%;
-}
-main:after {
-  content: "";
-  display: table;
-  clear: both;
-}
-
-.layout-content,
-.layout-sidebar-first,
-.layout-sidebar-second {
-  display: inline;
-  position: relative;
-}
-
-details,
-summary {
-  display: block;
-}
-
-@media all and (min-width: 480px) and (max-width: 959px) {
-  .layout-content {
-    width: 67%;
-    float: right; /* LTR */
-  }
-  [dir="rtl"] .layout-content {
-    float: left;
-  }
-
-  .layout-sidebar-first {
-    width: 33%;
-    float: left; /* LTR */
-  }
-  [dir="rtl"] .layout-sidebar-first {
-    float: right;
-  }
-
-  .layout-sidebar-second {
-    float: right; /* LTR */
-    clear: both;
-    width: 100%;
-  }
-  [dir="rtl"] .layout-sidebar-second {
-    float: right;
-    clear: right;
-  }
-
-  .layout-sidebar-second .block {
-    float: left; /* LTR */
-    width: 33%;
-  }
-  [dir="rtl"] .layout-sidebar-second .block {
-    float: right;
-  }
-  .layout-sidebar-second .block:nth-child(3n+1) {
-    clear: both;
-  }
-}
-
-@media all and (min-width: 960px) {
-  .layout-content {
-    width: 60%;
-    float: left; /* LTR */
-    left: 20%; /* LTR */
-  }
-  [dir="rtl"] .layout-content {
-    float: right;
-    left: 0;
-    right: 20%;
-  }
-
-  .layout-sidebar-first {
-    width: 20%;
-    float: left; /* LTR */
-    left: -60%; /* LTR */
-  }
-  [dir="rtl"] .layout-sidebar-first {
-    float: right;
-    left: 0;
-    right: -60%;
-  }
-
-  .layout-sidebar-second {
-    float: right; /* LTR */
-    width: 20%;
-  }
-  [dir="rtl"] .layout-sidebar-second {
-    float: left;
-  }
-}
-
-/**
- * Responsive tables.
- */
-@media screen and (max-width:28.125em) { /* 450px */
-  th.priority-low,
-  td.priority-low,
-  th.priority-medium,
-  td.priority-medium {
-    display: none;
-  }
-}
-@media screen and (max-width:45em) { /* 720px */
-  th.priority-low,
-  td.priority-low {
-    display: none;
-  }
-}
diff --git a/core/themes/stark/stark.breakpoints.yml b/core/themes/stark/stark.breakpoints.yml
deleted file mode 100644
index 92d33b2..0000000
--- a/core/themes/stark/stark.breakpoints.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-stark.mobile:
-  label: mobile
-  mediaQuery: '(min-width: 0px)'
-  weight: 2
-  multipliers:
-   - 1x
-stark.narrow:
-  label: narrow
-  mediaQuery: 'all and (min-width: 480px) and (max-width: 959px)'
-  weight: 1
-  multipliers:
-    - 1x
-stark.wide:
-  label: wide
-  mediaQuery: 'all and (min-width: 960px)'
-  weight: 0
-  multipliers:
-    - 1x
diff --git a/core/themes/stark/stark.info.yml b/core/themes/stark/stark.info.yml
index 69337d5..e513ca8 100644
--- a/core/themes/stark/stark.info.yml
+++ b/core/themes/stark/stark.info.yml
@@ -4,7 +4,3 @@ description: 'An intentionally plain theme with almost no styling to demonstrate
 package: Core
 version: VERSION
 core: 8.x
-libraries:
-  - stark/global-styling
-stylesheets-remove:
-  - core/assets/vendor/normalize-css/normalize.css
diff --git a/core/themes/stark/stark.libraries.yml b/core/themes/stark/stark.libraries.yml
deleted file mode 100644
index 7655147..0000000
--- a/core/themes/stark/stark.libraries.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-global-styling:
-  version: VERSION
-  css:
-    base:
-      css/layout.css: {}
