diff --git a/core/modules/language/src/Tests/LanguageBrowserDetectionUnitTest.php b/core/modules/language/src/Tests/LanguageBrowserDetectionUnitTest.php
index f724338..2719476 100644
--- a/core/modules/language/src/Tests/LanguageBrowserDetectionUnitTest.php
+++ b/core/modules/language/src/Tests/LanguageBrowserDetectionUnitTest.php
@@ -22,141 +22,6 @@ class LanguageBrowserDetectionUnitTest extends WebTestBase {
   public static $modules = array('language');
 
   /**
-   * Unit tests for the language_from_browser() function.
-   *
-   * @see language_from_browser().
-   */
-  function testLanguageFromBrowser() {
-    // The order of the languages is only important if the browser language
-    // codes are having the same qvalue, otherwise the one with the highest
-    // qvalue is preferred. The automatically generated generic tags are always
-    // having a lower qvalue.
-
-    $languages = array(
-      // In our test case, 'en' has priority over 'en-US'.
-      'en' => new Language(array(
-        'id' => 'en',
-      )),
-      'en-US' => new Language(array(
-        'id' => 'en-US',
-      )),
-      // But 'fr-CA' has priority over 'fr'.
-      'fr-CA' => new Language(array(
-        'id' => 'fr-CA',
-      )),
-      'fr' => new Language(array(
-        'id' => 'fr',
-      )),
-      // 'es-MX' is alone.
-      'es-MX' => new Language(array(
-        'id' => 'es-MX',
-      )),
-      // 'pt' is alone.
-      'pt' => new Language(array(
-        'id' => 'pt',
-      )),
-      // Language codes with more then one dash are actually valid.
-      // eh-oh-laa-laa is the official language code of the Teletubbies.
-      'eh-oh-laa-laa' => new Language(array(
-        'id' => 'eh-oh-laa-laa',
-      )),
-      // Chinese languages.
-      'zh-hans' => new Language(array(
-        'id' => 'zh-hans',
-      )),
-      'zh-hant' => new Language(array(
-        'id' => 'zh-hant',
-      )),
-      'zh-hant-tw' => new Language(array(
-        'id' => 'zh-hant',
-      )),
-    );
-
-    $test_cases = array(
-      // Equal qvalue for each language, choose the site preferred one.
-      'en,en-US,fr-CA,fr,es-MX' => 'en',
-      'en-US,en,fr-CA,fr,es-MX' => 'en',
-      'fr,en' => 'en',
-      'en,fr' => 'en',
-      'en-US,fr' => 'en-US',
-      'fr,en-US' => 'en-US',
-      'fr,fr-CA' => 'fr-CA',
-      'fr-CA,fr' => 'fr-CA',
-      'fr' => 'fr-CA',
-      'fr;q=1' => 'fr-CA',
-      'fr,es-MX' => 'fr-CA',
-      'fr,es' => 'fr-CA',
-      'es,fr' => 'fr-CA',
-      'es-MX,de' => 'es-MX',
-      'de,es-MX' => 'es-MX',
-
-      // Different cases and whitespace.
-      'en' => 'en',
-      'En' => 'en',
-      'EN' => 'en',
-      ' en' => 'en',
-      'en ' => 'en',
-      'en, fr' => 'en',
-
-      // A less specific language from the browser matches a more specific one
-      // from the website, and the other way around for compatibility with
-      // some versions of Internet Explorer.
-      'es' => 'es-MX',
-      'es-MX' => 'es-MX',
-      'pt' => 'pt',
-      'pt-PT' => 'pt',
-      'pt-PT;q=0.5,pt-BR;q=1,en;q=0.7' => 'en',
-      'pt-PT;q=1,pt-BR;q=0.5,en;q=0.7' => 'en',
-      'pt-PT;q=0.4,pt-BR;q=0.1,en;q=0.7' => 'en',
-      'pt-PT;q=0.1,pt-BR;q=0.4,en;q=0.7' => 'en',
-
-      // Language code with several dashes are valid. The less specific language
-      // from the browser matches the more specific one from the website.
-      'eh-oh-laa-laa' => 'eh-oh-laa-laa',
-      'eh-oh-laa' => 'eh-oh-laa-laa',
-      'eh-oh' => 'eh-oh-laa-laa',
-      'eh' => 'eh-oh-laa-laa',
-
-      // Different qvalues.
-      'fr,en;q=0.5' => 'fr-CA',
-      'fr,en;q=0.5,fr-CA;q=0.25' => 'fr',
-
-      // Silly wildcards are also valid.
-      '*,fr-CA;q=0.5' => 'en',
-      '*,en;q=0.25' => 'fr-CA',
-      'en,en-US;q=0.5,fr;q=0.25' => 'en',
-      'en-US,en;q=0.5,fr;q=0.25' => 'en-US',
-
-      // Unresolvable cases.
-      '' => FALSE,
-      'de,pl' => FALSE,
-      'iecRswK4eh' => FALSE,
-      $this->randomMachineName(10) => FALSE,
-
-      // Chinese langcodes.
-      'zh-cn, en-us;q=0.90, en;q=0.80, zh;q=0.70' => 'zh-hans',
-      'zh-tw, en-us;q=0.90, en;q=0.80, zh;q=0.70' => 'zh-hant',
-      'zh-hant, en-us;q=0.90, en;q=0.80, zh;q=0.70' => 'zh-hant',
-      'zh-hans, en-us;q=0.90, en;q=0.80, zh;q=0.70' => 'zh-hans',
-      'zh-cn' => 'zh-hans',
-      'zh-sg' => 'zh-hans',
-      'zh-tw' => 'zh-hant',
-      'zh-hk' => 'zh-hant',
-      'zh-mo' => 'zh-hant',
-      'zh-hans' => 'zh-hans',
-      'zh-hant' => 'zh-hant',
-      'zh-chs' => 'zh-hans',
-      'zh-cht' => 'zh-hant',
-    );
-
-    $mappings = $this->container->get('config.factory')->get('language.mappings')->get();
-    foreach ($test_cases as $accept_language => $expected_result) {
-      $result = UserAgent::getBestMatchingLangcode($accept_language, array_keys($languages), $mappings);
-      $this->assertIdentical($result, $expected_result, format_string("Language selection '@accept-language' selects '@result', result = '@actual'", array('@accept-language' => $accept_language, '@result' => $expected_result, '@actual' => isset($result) ? $result : 'none')));
-    }
-  }
-
-  /**
    * Tests for adding, editing and deleting mappings between browser language
    * codes and Drupal language codes.
    */
diff --git a/core/phpunit.xml.dist b/core/phpunit.xml.dist
index aa4acfd..14bdc29 100644
--- a/core/phpunit.xml.dist
+++ b/core/phpunit.xml.dist
@@ -29,6 +29,6 @@
       <directory>./modules</directory>
       <directory>../modules</directory>
       <directory>../sites</directory>
-     </whitelist>
+    </whitelist>
   </filter>
 </phpunit>
diff --git a/core/tests/Drupal/Tests/Component/Utility/BytesTest.php b/core/tests/Drupal/Tests/Component/Utility/BytesTest.php
index bfacd6c..8e72b6c 100644
--- a/core/tests/Drupal/Tests/Component/Utility/BytesTest.php
+++ b/core/tests/Drupal/Tests/Component/Utility/BytesTest.php
@@ -11,8 +11,11 @@
 use Drupal\Tests\UnitTestCase;
 
 /**
- * @coversDefaultClass \Drupal\Component\Utility\Bytes
+ * Tests bytes size parsing helper methods.
+ *
  * @group Utility
+ *
+ * @coversDefaultClass \Drupal\Component\Utility\Bytes
  */
 class BytesTest extends UnitTestCase {
 
@@ -43,6 +46,7 @@ public function testToInt($size, $expected_int) {
    */
   public function providerTestToInt() {
     return array(
+      array('1', 1),
       array('1 byte', 1),
       array('1 KB'  , Bytes::KILOBYTE),
       array('1 MB'  , pow(Bytes::KILOBYTE, 2)),
diff --git a/core/tests/Drupal/Tests/Component/Utility/CryptTest.php b/core/tests/Drupal/Tests/Component/Utility/CryptTest.php
index 94929ee..bf6ca27 100644
--- a/core/tests/Drupal/Tests/Component/Utility/CryptTest.php
+++ b/core/tests/Drupal/Tests/Component/Utility/CryptTest.php
@@ -11,13 +11,18 @@
 use Drupal\Component\Utility\Crypt;
 
 /**
- * @coversDefaultClass \Drupal\Component\Utility\Crypt
+ * Tests random byte generation.
+ *
  * @group Utility
+ *
+ * @coversDefaultClass \Drupal\Component\Utility\Crypt
  */
 class CryptTest extends UnitTestCase {
 
   /**
-   * Tests \Drupal\Component\Utility\Crypt::randomBytes().
+   * Tests random byte generation.
+   *
+   * @covers ::randomBytes
    */
   public function testRandomBytes() {
     for ($i = 1; $i < 10; $i++) {
@@ -30,14 +35,15 @@ public function testRandomBytes() {
   }
 
   /**
-   * Tests \Drupal\Component\Utility\Crypt::hashBase64().
+   * Tests hash generation.
+   *
+   * @dataProvider providerTestHashBase64
+   * @covers ::hashBase64
    *
    * @param string $data
    *   Data to hash.
    * @param string $expected_hash
    *   Expected result from hashing $data.
-   *
-   * @dataProvider providerTestHashBase64
    */
   public function testHashBase64($data, $expected_hash) {
     $hash = Crypt::hashBase64($data);
@@ -45,7 +51,10 @@ public function testHashBase64($data, $expected_hash) {
   }
 
   /**
-   * Tests \Drupal\Component\Utility\Crypt::hmacBase64().
+   * Tests HMAC generation.
+   *
+   * @dataProvider providerTestHmacBase64
+   * @covers ::hmacBase64
    *
    * @param string $data
    *   Data to hash.
@@ -53,8 +62,6 @@ public function testHashBase64($data, $expected_hash) {
    *   Key to use in hashing process.
    * @param string $expected_hmac
    *   Expected result from hashing $data using $key.
-   *
-   * @dataProvider providerTestHmacBase64
    */
   public function testHmacBase64($data, $key, $expected_hmac) {
     $hmac = Crypt::hmacBase64($data, $key);
@@ -64,13 +71,14 @@ public function testHmacBase64($data, $key, $expected_hmac) {
   /**
    * Tests the hmacBase64 method with invalid parameters.
    *
+   * @dataProvider providerTestHmacBase64Invalid
+   * @expectedException InvalidArgumentException
+   * @covers ::hmacBase64
+   *
    * @param string $data
    *   Data to hash.
    * @param string $key
    *   Key to use in hashing process.
-   *
-   * @dataProvider providerTestHmacBase64Invalid
-   * @expectedException InvalidArgumentException
    */
   public function testHmacBase64Invalid($data, $key) {
     Crypt::hmacBase64($data, $key);
diff --git a/core/tests/Drupal/Tests/Component/Utility/EnvironmentTest.php b/core/tests/Drupal/Tests/Component/Utility/EnvironmentTest.php
index d7713e0..72f04f7 100644
--- a/core/tests/Drupal/Tests/Component/Utility/EnvironmentTest.php
+++ b/core/tests/Drupal/Tests/Component/Utility/EnvironmentTest.php
@@ -11,14 +11,20 @@
 use Drupal\Tests\UnitTestCase;
 
 /**
- * @coversDefaultClass \Drupal\Component\Utility\Environment
+ * Test PHP Environment helper methods.
+ *
  * @group Utility
+ *
+ * @coversDefaultClass \Drupal\Component\Utility\Environment
  */
 class EnvironmentTest extends UnitTestCase {
 
   /**
    * Tests \Drupal\Component\Utility\Environment::checkMemoryLimit().
    *
+   * @dataProvider providerTestCheckMemoryLimit
+   * @covers ::checkMemoryLimit
+   *
    * @param string $required
    *   The required memory argument for
    *   \Drupal\Component\Utility\Environment::checkMemoryLimit().
@@ -28,9 +34,6 @@ class EnvironmentTest extends UnitTestCase {
    * @param bool $expected
    *   The expected return value from
    *   \Drupal\Component\Utility\Environment::checkMemoryLimit().
-   *
-   * @dataProvider providerTestCheckMemoryLimit
-   * @covers ::checkMemoryLimit
    */
   public function testCheckMemoryLimit($required, $custom_memory_limit, $expected) {
     $actual = Environment::checkMemoryLimit($required, $custom_memory_limit);
diff --git a/core/tests/Drupal/Tests/Component/Utility/HtmlTest.php b/core/tests/Drupal/Tests/Component/Utility/HtmlTest.php
new file mode 100644
index 0000000..6e15893
--- /dev/null
+++ b/core/tests/Drupal/Tests/Component/Utility/HtmlTest.php
@@ -0,0 +1,89 @@
+<?php
+
+/**
+ * @file
+ * Container Drupal\Tests\Component\Utility\UserAgentTest
+ */
+
+namespace Drupal\Tests\Component\Utility;
+
+use Drupal\Component\Utility\Html;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * Tests the http query methods.
+ *
+ * @group Utility
+ *
+ * @coversDefaultClass \Drupal\Component\Utility\Html
+ */
+class HtmlTest extends UnitTestCase {
+
+  /**
+   * Test HTML document loading.
+   *
+   * @dataProvider providerTestLoad
+   * @covers ::load
+   *
+   * @param string $html
+   *   Original HTML.
+   * @param array $tags
+   *   A list of tags to find. Key is tag, value is number instances.
+   */
+  public function testLoad($html, $tags) {
+    $doc = Html::load($html);
+    // If we have a document we did our job.
+    $this->assertTrue(is_a($doc, '\DOMDocument'));
+
+    foreach ($tags as $tag_name => $length) {
+      $tag = $doc->getElementsByTagName($tag_name);
+      $this->assertEquals($length, $tag->length);
+    }
+  }
+
+  /**
+   * Test HTML document serialization.
+   *
+   * @dataProvider providerTestLoad
+   * @covers ::serialize
+   *
+   * @param string $html
+   *   Original HTML.
+   * @param array $tags
+   *   A list of tags to find. Key is tag, value is number instances.
+   * @param $expected
+   *   Expected serialized value.
+   */
+  public function testSerialize($html, $tags, $expected) {
+    $doc = Html::load($html);
+    $this->assertEquals($expected, Html::serialize($doc));
+  }
+
+  public function providerTestLoad() {
+    return array(
+      array('<a>', array('a' => 1), '<a></a>'),
+      array('<a href>', array('a' => 1), '<a href=""></a>'),
+      // Bad html
+      array('<div><something></something><something></something></some>', array('div' => 1, 'something' => 2), '<div><something></something><something></something></div>'),
+      array('<astring', array('astring' => 1), '<astring></astring>'),
+    );
+  }
+
+  /**
+   * Test HTML normalization.
+   *
+   * @dataProvider providerTestLoad
+   * @covers ::normalize
+   *
+   * @param string $html
+   *   Original HTML.
+   * @param array $tags
+   *   A list of tags to find. Key is tag, value is number instances.
+   * @param $expected
+   *   Expected normalized value.
+   */
+  public function testNormalize($html, $tags, $expected) {
+    $this->assertEquals($expected, Html::normalize($html));
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Component/Utility/NumberAlphadecimalTest.php b/core/tests/Drupal/Tests/Component/Utility/NumberAlphadecimalTest.php
deleted file mode 100644
index 01d2c2b..0000000
--- a/core/tests/Drupal/Tests/Component/Utility/NumberAlphadecimalTest.php
+++ /dev/null
@@ -1,56 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Tests\Component\Utility\NumberAlphadecimalTest.
- */
-
-namespace Drupal\Tests\Component\Utility;
-
-use Drupal\Component\Utility\Number;
-use Drupal\Tests\UnitTestCase;
-
-/**
- * @coversDefaultClass \Drupal\Component\Utility\Number
- * @group Utility
- */
-class NumberAlphadecimalTest extends UnitTestCase {
-
-  /**
-   * Tests the alphadecimal conversion functions.
-   *
-   * @param int $value
-   *   The integer value.
-   * @param string $expected
-   *   The expected alphadecimal value.
-   *
-   * @dataProvider providerTestConversions
-   */
-  public function testConversions($value, $expected) {
-    $this->assertSame(Number::intToAlphadecimal($value), $expected);
-    $this->assertSame($value, Number::alphadecimalToInt($expected));
-  }
-
-  /**
-   * Data provider for testConversions().
-   *
-   * @see testConversions()
-   *
-   * @return array
-   *   An array containing:
-   *     - The integer value.
-   *     - The alphadecimal value.
-   */
-  public function providerTestConversions() {
-    return array(
-      array(0, '00'),
-      array(1, '01'),
-      array(10, '0a'),
-      array(20, '0k'),
-      array(35, '0z'),
-      array(36, '110'),
-      array(100, '12s'),
-    );
-  }
-
-}
diff --git a/core/tests/Drupal/Tests/Component/Utility/NumberTest.php b/core/tests/Drupal/Tests/Component/Utility/NumberTest.php
index 088a0f3..4e6b967 100644
--- a/core/tests/Drupal/Tests/Component/Utility/NumberTest.php
+++ b/core/tests/Drupal/Tests/Component/Utility/NumberTest.php
@@ -13,23 +13,26 @@
 use Drupal\Tests\UnitTestCase;
 
 /**
- * Tests number step validation by Number::validStep().
+ * Tests number manipulation utilities.
  *
  * @group Utility
+ *
+ * @coversDefaultClass \Drupal\Component\Utility\Number
  */
 class NumberTest extends UnitTestCase {
 
   /**
    * Tests Number::validStep() without offset.
    *
+   * @dataProvider providerTestValidStep
+   * @covers ::validStep
+   *
    * @param numeric $value
    *   The value argument for Number::validStep().
    * @param numeric $step
    *   The step argument for Number::validStep().
    * @param boolean $expected
    *   Expected return value from Number::validStep().
-   *
-   * @dataProvider providerTestValidStep
    */
   public function testValidStep($value, $step, $expected) {
     $return = Number::validStep($value, $step);
@@ -39,6 +42,9 @@ public function testValidStep($value, $step, $expected) {
   /**
    * Tests Number::validStep() with offset.
    *
+   * @dataProvider providerTestValidStepOffset
+   * @covers ::validStep
+   *
    * @param numeric $value
    *   The value argument for Number::validStep().
    * @param numeric $step
@@ -47,8 +53,6 @@ public function testValidStep($value, $step, $expected) {
    *   The offset argument for Number::validStep().
    * @param boolean $expected
    *   Expected return value from Number::validStep().
-   *
-   * @dataProvider providerTestValidStepOffset
    */
   public function testValidStepOffset($value, $step, $offset, $expected) {
     $return = Number::validStep($value, $step, $offset);
@@ -117,4 +121,43 @@ public static function providerTestValidStepOffset() {
     );
   }
 
+  /**
+   * Tests the alphadecimal conversion functions.
+   *
+   * @dataProvider providerTestConversions
+   * @covers ::intToAlphadecimal
+   * @covers ::alphadecimalToInt
+   *
+   * @param int $value
+   *   The integer value.
+   * @param string $expected
+   *   The expected alphadecimal value.
+   */
+  public function testConversions($value, $expected) {
+    $this->assertSame(Number::intToAlphadecimal($value), $expected);
+    $this->assertSame($value, Number::alphadecimalToInt($expected));
+  }
+
+  /**
+   * Data provider for testConversions().
+   *
+   * @see testConversions()
+   *
+   * @return array
+   *   An array containing:
+   *     - The integer value.
+   *     - The alphadecimal value.
+   */
+  public function providerTestConversions() {
+    return array(
+      array(0, '00'),
+      array(1, '01'),
+      array(10, '0a'),
+      array(20, '0k'),
+      array(35, '0z'),
+      array(36, '110'),
+      array(100, '12s'),
+    );
+  }
+
 }
diff --git a/core/tests/Drupal/Tests/Component/Utility/RandomTest.php b/core/tests/Drupal/Tests/Component/Utility/RandomTest.php
index cda119e..716059f 100644
--- a/core/tests/Drupal/Tests/Component/Utility/RandomTest.php
+++ b/core/tests/Drupal/Tests/Component/Utility/RandomTest.php
@@ -12,8 +12,11 @@
 use Drupal\Tests\UnitTestCase;
 
 /**
- * @coversDefaultClass \Drupal\Component\Utility\Random
+ * Tests random data generation.
+ *
  * @group Utility
+ *
+ * @coversDefaultClass \Drupal\Component\Utility\Random
  */
 class RandomTest extends UnitTestCase {
 
@@ -29,7 +32,7 @@ class RandomTest extends UnitTestCase {
   /**
    * Tests unique random string generation.
    *
-   * @see \Drupal\Component\Utility\Random::string()
+   * @covers ::string
    */
   public function testRandomStringUniqueness() {
     $strings = array();
@@ -44,7 +47,7 @@ public function testRandomStringUniqueness() {
   /**
    * Tests unique random name generation.
    *
-   * @see \Drupal\Component\Utility\Random::name()
+   * @covers ::name
    */
   public function testRandomNamesUniqueness() {
     $names = array();
@@ -59,9 +62,8 @@ public function testRandomNamesUniqueness() {
   /**
    * Tests infinite loop prevention whilst generating random names.
    *
-   * @see \Drupal\Component\Utility\Random::name()
-   *
-   * @expectedException RuntimeException
+   * @covers ::name
+   * @expectedException \RuntimeException
    */
   public function testRandomNameException() {
     // There are fewer than 100 possibilities so an exception should occur to
@@ -76,9 +78,8 @@ public function testRandomNameException() {
   /**
    * Tests infinite loop prevention whilst generating random strings.
    *
-   * @see \Drupal\Component\Utility\Random::string()
-   *
-   * @expectedException RuntimeException
+   * @covers ::string
+   * @expectedException \RuntimeException
    */
   public function testRandomStringException() {
     // There are fewer than 100 possibilities so an exception should occur to
@@ -93,7 +94,7 @@ public function testRandomStringException() {
   /**
    * Tests random name generation if uniqueness is not enforced.
    *
-   * @see \Drupal\Component\Utility\Random::name()
+   * @covers ::name
    */
   public function testRandomNameNonUnique() {
     // There are fewer than 100 possibilities if we were forcing uniqueness so
@@ -108,7 +109,7 @@ public function testRandomNameNonUnique() {
   /**
    * Tests random string if uniqueness is not enforced.
    *
-   * @see \Drupal\Component\Utility\Random::string()
+   * @covers ::string
    */
   public function testRandomStringNonUnique() {
     // There are fewer than 100 possibilities if we were forcing uniqueness so
@@ -123,7 +124,7 @@ public function testRandomStringNonUnique() {
   /**
    * Tests random object generation to ensure the expected number of properties.
    *
-   * @see \Drupal\Component\Utility\Random::object()
+   * @covers ::object
    */
   public function testRandomObject() {
     // For values of 0 and 1 \Drupal\Component\Utility\Random::object() will
@@ -138,7 +139,7 @@ public function testRandomObject() {
   /**
    * Tests random string validation callbacks.
    *
-   * @see \Drupal\Component\Utility\Random::name()
+   * @covers ::string
    */
   public function testRandomStringValidator() {
     $random = new Random();
diff --git a/core/tests/Drupal/Tests/Component/Utility/SortArrayTest.php b/core/tests/Drupal/Tests/Component/Utility/SortArrayTest.php
index c2804e4..cd8eff7 100644
--- a/core/tests/Drupal/Tests/Component/Utility/SortArrayTest.php
+++ b/core/tests/Drupal/Tests/Component/Utility/SortArrayTest.php
@@ -11,8 +11,11 @@
 use Drupal\Component\Utility\SortArray;
 
 /**
- * @coversDefaultClass \Drupal\Component\Utility\SortArray
+ * Tests the SortArray component.
+ *
  * @group Utility
+ *
+ * @coversDefaultClass \Drupal\Component\Utility\SortArray
  */
 class SortArrayTest extends UnitTestCase {
 
@@ -20,6 +23,8 @@ class SortArrayTest extends UnitTestCase {
    * Tests SortArray::sortByWeightElement() input against expected output.
    *
    * @dataProvider providerSortByWeightElement
+   * @covers ::sortByWeightElement
+   * @covers ::sortByKeyInt
    *
    * @param array $a
    *   The first input array for the SortArray::sortByWeightElement() method.
@@ -27,9 +32,6 @@ class SortArrayTest extends UnitTestCase {
    *   The second input array for the SortArray::sortByWeightElement().
    * @param integer $expected
    *   The expected output from calling the method.
-   *
-   * @see \Drupal\Component\Utility\SortArray::sortByWeightElement()
-   * @see \Drupal\Tests\Component\Utility\SortArrayTest::providersortByWeightElement()
    */
   public function testSortByWeightElement($a, $b, $expected) {
     $result = SortArray::sortByWeightElement($a, $b);
@@ -43,7 +45,6 @@ public function testSortByWeightElement($a, $b, $expected) {
    *   An array of tests, matching the parameter inputs for
    *   testSortByWeightElement.
    *
-   * @see \Drupal\Component\Utility\SortArray::sortByWeightElement()
    * @see \Drupal\Tests\Component\Utility\SortArrayTest::testSortByWeightElement()
    */
   public function providerSortByWeightElement() {
@@ -98,6 +99,8 @@ public function providerSortByWeightElement() {
    * Tests SortArray::sortByWeightProperty() input against expected output.
    *
    * @dataProvider providerSortByWeightProperty
+   * @covers ::sortByWeightProperty
+   * @covers ::sortByKeyInt
    *
    * @param array $a
    *   The first input array for the SortArray::sortByWeightProperty() method.
@@ -105,9 +108,6 @@ public function providerSortByWeightElement() {
    *   The second input array for the SortArray::sortByWeightProperty().
    * @param integer $expected
    *   The expected output from calling the method.
-   *
-   * @see \Drupal\Component\Utility\SortArray::sortByWeightProperty()
-   * @see \Drupal\Tests\Component\Utility\SortArrayTest::SortByWeightProperty()
    */
   public function testSortByWeightProperty($a, $b, $expected) {
     $result = SortArray::sortByWeightProperty($a, $b);
@@ -121,7 +121,6 @@ public function testSortByWeightProperty($a, $b, $expected) {
    *   An array of tests, matching the parameter inputs for
    *   testSortByWeightProperty.
    *
-   * @see \Drupal\Component\Utility\SortArray::sortByWeightProperty()
    * @see \Drupal\Tests\Component\Utility\SortArrayTest::testSortByWeightProperty()
    */
   public function providerSortByWeightProperty() {
@@ -176,6 +175,8 @@ public function providerSortByWeightProperty() {
    * Tests SortArray::sortByTitleElement() input against expected output.
    *
    * @dataProvider providerSortByTitleElement
+   * @covers ::sortByTitleElement
+   * @covers ::sortByKeyString
    *
    * @param array $a
    *   The first input item for comparison.
@@ -183,9 +184,6 @@ public function providerSortByWeightProperty() {
    *   The second item for comparison.
    * @param integer $expected
    *   The expected output from calling the method.
-   *
-   * @see \Drupal\Component\Utility\SortArray::sortByTitleElement()
-   * @see \Drupal\Tests\Component\Utility\SortArrayTest::providerSortByTitleElement()
    */
   public function testSortByTitleElement($a, $b, $expected) {
     $result = SortArray::sortByTitleElement($a, $b);
@@ -199,7 +197,6 @@ public function testSortByTitleElement($a, $b, $expected) {
    *   An array of tests, matching the parameter inputs for
    *   testSortByTitleElement.
    *
-   * @see \Drupal\Component\Utility\SortArray::sortByTitleElement()
    * @see \Drupal\Tests\Component\Utility\SortArrayTest::testSortByTitleElement()
    */
   public function providerSortByTitleElement() {
@@ -247,6 +244,8 @@ public function providerSortByTitleElement() {
    * Tests SortArray::sortByTitleProperty() input against expected output.
    *
    * @dataProvider providerSortByTitleProperty
+   * @covers ::sortByTitleProperty
+   * @covers ::sortByKeyString
    *
    * @param array $a
    *   The first input item for comparison.
@@ -254,9 +253,6 @@ public function providerSortByTitleElement() {
    *   The second item for comparison.
    * @param integer $expected
    *   The expected output from calling the method.
-   *
-   * @see \Drupal\Component\Utility\SortArray::sortByTitleProperty()
-   * @see \Drupal\Tests\Component\Utility\SortArrayTest::SortByTitleProperty()
    */
   public function testSortByTitleProperty($a, $b, $expected) {
     $result = SortArray::sortByTitleProperty($a, $b);
@@ -270,7 +266,6 @@ public function testSortByTitleProperty($a, $b, $expected) {
    *   An array of tests, matching the parameter inputs for
    *   testSortByTitleProperty.
    *
-   * @see \Drupal\Component\Utility\SortArray::sortByTitleProperty()
    * @see \Drupal\Tests\Component\Utility\SortArrayTest::testSortByTitleProperty()
    */
   public function providerSortByTitleProperty() {
diff --git a/core/tests/Drupal/Tests/Component/Utility/StringTest.php b/core/tests/Drupal/Tests/Component/Utility/StringTest.php
index 21127b5..358ee2d 100644
--- a/core/tests/Drupal/Tests/Component/Utility/StringTest.php
+++ b/core/tests/Drupal/Tests/Component/Utility/StringTest.php
@@ -11,8 +11,11 @@
 use Drupal\Component\Utility\String;
 
 /**
- * @coversDefaultClass \Drupal\Component\Utility\String
+ * Tests string filtering.
+ *
  * @group Utility
+ *
+ * @coversDefaultClass \Drupal\Component\Utility\String
  */
 class StringTest extends UnitTestCase {
 
@@ -20,6 +23,7 @@ class StringTest extends UnitTestCase {
    * Tests String::checkPlain().
    *
    * @dataProvider providerCheckPlain
+   * @covers ::checkPlain
    *
    * @param string $text
    *   The text to provide to String::checkPlain().
@@ -57,6 +61,7 @@ function providerCheckPlain() {
    * Tests string formatting with String::format().
    *
    * @dataProvider providerFormat
+   * @covers ::format
    *
    * @param string $string
    *   The string to run through String::format().
@@ -66,8 +71,6 @@ function providerCheckPlain() {
    *   The expected result from calling the function.
    * @param string $message
    *   The message to display as output to the test.
-   *
-   * @see String::format()
    */
   function testFormat($string, $args, $expected, $message) {
     $result = String::format($string, $args);
@@ -91,7 +94,7 @@ function providerFormat() {
   /**
    * Tests String::placeholder().
    *
-   * @see String::placeholder()
+   * @covers ::placeholder
    */
   function testPlaceholder() {
     $this->assertEquals('<em class="placeholder">Some text</em>', String::placeholder('Some text'));
@@ -101,6 +104,7 @@ function testPlaceholder() {
    * Tests String::decodeEntities().
    *
    * @dataProvider providerDecodeEntities
+   * @covers ::decodeEntities
    */
   public function testDecodeEntities($text, $expected) {
     $this->assertEquals($expected, String::decodeEntities($text));
diff --git a/core/tests/Drupal/Tests/Component/Utility/TimerTest.php b/core/tests/Drupal/Tests/Component/Utility/TimerTest.php
index f306896..cfb05dd 100644
--- a/core/tests/Drupal/Tests/Component/Utility/TimerTest.php
+++ b/core/tests/Drupal/Tests/Component/Utility/TimerTest.php
@@ -11,15 +11,20 @@
 use Drupal\Component\Utility\Timer;
 
 /**
- * @coversDefaultClass \Drupal\Component\Utility\Timer
+ * Tests the Timer system.
+ *
  * @group Utility
+ *
+ * @coversDefaultClass \Drupal\Component\Utility\Timer
  */
 class TimerTest extends UnitTestCase {
 
   /**
    * Tests Timer::read() time accumulation accuracy across multiple restarts.
    *
-   * @see \Drupal\Component\Utility\Timer::read()
+   * @covers ::start
+   * @covers ::stop
+   * @covers ::read
    */
   public function testTimer() {
     Timer::start('test');
diff --git a/core/tests/Drupal/Tests/Component/Utility/UnicodeTest.php b/core/tests/Drupal/Tests/Component/Utility/UnicodeTest.php
index 11d3a83..b9861c2 100644
--- a/core/tests/Drupal/Tests/Component/Utility/UnicodeTest.php
+++ b/core/tests/Drupal/Tests/Component/Utility/UnicodeTest.php
@@ -11,20 +11,30 @@
 use Drupal\Component\Utility\Unicode;
 
 /**
- * @coversDefaultClass \Drupal\Component\Utility\Unicode
+ * Test unicode handling features implemented in Unicode component.
+ *
  * @group Utility
+ *
+ * @coversDefaultClass \Drupal\Component\Utility\Unicode
  */
 class UnicodeTest extends UnitTestCase {
 
-  protected function setUp() {
+  /**
+   * {@inheritdoc}
+   *
+   * @covers ::check
+   */
+  public function setUp() {
     // Initialize unicode component.
     Unicode::check();
   }
 
   /**
-   * Tests Unicode::getStatus() and Unicode::setStatus().
+   * Getting and settings the multibyte environment status.
    *
    * @dataProvider providerTestStatus
+   * @covers ::getStatus
+   * @covers ::setStatus
    */
   public function testStatus($value, $expected, $invalid = FALSE) {
     if ($invalid) {
@@ -58,9 +68,11 @@ public function providerTestStatus() {
   }
 
   /**
-   * Tests Unicode::mimeHeaderEncode() and Unicode::mimeHeaderDecode().
+   * Tests multibyte encoding and decoding.
    *
    * @dataProvider providerTestMimeHeader
+   * @covers ::mimeHeaderEncode
+   * @covers ::mimeHeaderDecode
    */
   public function testMimeHeader($value, $encoded) {
     $this->assertEquals($encoded, Unicode::mimeHeaderEncode($value));
@@ -84,9 +96,11 @@ public function providerTestMimeHeader() {
   }
 
   /**
-   * Tests Unicode::strtolower().
+   * Tests multibyte strtolower.
    *
    * @dataProvider providerStrtolower
+   * @covers ::strtolower
+   * @covers ::caseFlip
    */
   public function testStrtolower($text, $expected, $multibyte = FALSE) {
     $status = $multibyte ? Unicode::STATUS_MULTIBYTE : Unicode::STATUS_SINGLEBYTE;
@@ -119,9 +133,11 @@ public function providerStrtolower() {
   }
 
   /**
-   * Tests Unicode::strtoupper().
+   * Tests multibyte strtoupper.
    *
    * @dataProvider providerStrtoupper
+   * @covers ::strtoupper
+   * @covers ::caseFlip
    */
   public function testStrtoupper($text, $expected, $multibyte = FALSE) {
     $status = $multibyte ? Unicode::STATUS_MULTIBYTE : Unicode::STATUS_SINGLEBYTE;
@@ -154,9 +170,10 @@ public function providerStrtoupper() {
   }
 
   /**
-   * Tests Unicode::ucfirst().
+   * Tests multibyte ucfirst.
    *
    * @dataProvider providerUcfirst
+   * @covers ::ucfirst
    */
   public function testUcfirst($text, $expected) {
     $this->assertEquals($expected, Unicode::ucfirst($text));
@@ -182,9 +199,10 @@ public function providerUcfirst() {
   }
 
   /**
-   * Tests Unicode::lcfirst().
+   * Tests multibyte lcfirst.
    *
    * @dataProvider providerLcfirst
+   * @covers ::lcfirst
    */
   public function testLcfirst($text, $expected, $multibyte = FALSE) {
     $status = $multibyte ? Unicode::STATUS_MULTIBYTE : Unicode::STATUS_SINGLEBYTE;
@@ -213,9 +231,10 @@ public function providerLcfirst() {
   }
 
   /**
-   * Tests Unicode::ucwords().
+   * Tests multibyte ucwords.
    *
    * @dataProvider providerUcwords
+   * @covers ::ucwords
    */
   public function testUcwords($text, $expected, $multibyte = FALSE) {
     $status = $multibyte ? Unicode::STATUS_MULTIBYTE : Unicode::STATUS_SINGLEBYTE;
@@ -246,9 +265,10 @@ public function providerUcwords() {
   }
 
   /**
-   * Tests Unicode::strlen().
+   * Tests multibyte strlen.
    *
    * @dataProvider providerStrlen
+   * @covers ::strlen
    */
   public function testStrlen($text, $expected) {
     // Run through multibyte code path.
@@ -275,9 +295,10 @@ public function providerStrlen() {
   }
 
   /**
-   * Tests Unicode::substr().
+   * Tests multibyte substr.
    *
    * @dataProvider providerSubstr
+   * @covers ::substr
    */
   public function testSubstr($text, $start, $length, $expected) {
     // Run through multibyte code path.
@@ -302,6 +323,7 @@ public function testSubstr($text, $start, $length, $expected) {
    */
   public function providerSubstr() {
     return array(
+      array('frànçAIS is über-åwesome', 0, NULL, 'frànçAIS is über-åwesome'),
       array('frànçAIS is über-åwesome', 0, 0, ''),
       array('frànçAIS is über-åwesome', 0, 1, 'f'),
       array('frànçAIS is über-åwesome', 0, 8, 'frànçAIS'),
@@ -330,12 +352,12 @@ public function providerSubstr() {
   }
 
   /**
-   * Tests Unicode::truncate().
+   * Tests multibyte truncate.
    *
    * @dataProvider providerTruncate
+   * @covers ::truncate
    */
   public function testTruncate($text, $max_length, $expected, $wordsafe = FALSE, $add_ellipsis = FALSE) {
-    Unicode::check();
     $this->assertEquals($expected, Unicode::truncate($text, $max_length, $wordsafe, $add_ellipsis));
   }
 
@@ -402,7 +424,10 @@ public function providerTruncate() {
   }
 
   /**
-   * Tests Unicode::truncateBytes().
+   * Tests multibyte truncate bytes.
+   *
+   * @dataProvider providerTestTruncateBytes
+   * @covers ::truncateBytes
    *
    * @param string $text
    *   The string to truncate.
@@ -410,8 +435,6 @@ public function providerTruncate() {
    *   The upper limit on the returned string length.
    * @param string $expected
    *   The expected return from Unicode::truncateBytes().
-   *
-   * @dataProvider providerTestTruncateBytes
    */
   public function testTruncateBytes($text, $max_length, $expected) {
     $this->assertEquals($expected, Unicode::truncateBytes($text, $max_length), 'The string was not correctly truncated.');
@@ -436,7 +459,10 @@ public function providerTestTruncateBytes() {
   }
 
   /**
-   * Tests Unicode::validateUtf8().
+   * Tests UTF-8 validation.
+   *
+   * @dataProvider providerTestValidateUtf8
+   * @covers ::validateUtf8
    *
    * @param string $text
    *   The text to validate.
@@ -444,8 +470,6 @@ public function providerTestTruncateBytes() {
    *   The expected return value from Unicode::validateUtf8().
    * @param string $message
    *   The message to display on failure.
-   *
-   * @dataProvider providerTestValidateUtf8
    */
   public function testValidateUtf8($text, $expected, $message) {
     $this->assertEquals($expected, Unicode::validateUtf8($text), $message);
@@ -474,7 +498,10 @@ public function providerTestValidateUtf8() {
   }
 
   /**
-   * Tests Unicode::convertToUtf8().
+   * Tests UTF-8 conversion.
+   *
+   * @dataProvider providerTestConvertToUtf8
+   * @covers ::convertToUtf8
    *
    * @param string $data
    *   The data to be converted.
@@ -482,8 +509,6 @@ public function providerTestValidateUtf8() {
    *   The encoding the data is in.
    * @param string|bool $expected
    *   The expected result.
-   *
-   * @dataProvider providerTestConvertToUtf8
    */
   public function testConvertToUtf8($data, $encoding, $expected) {
     $this->assertEquals($expected, Unicode::convertToUtf8($data, $encoding));
diff --git a/core/tests/Drupal/Tests/Component/Utility/UrlHelperTest.php b/core/tests/Drupal/Tests/Component/Utility/UrlHelperTest.php
index 12cbad5..0477b7a 100644
--- a/core/tests/Drupal/Tests/Component/Utility/UrlHelperTest.php
+++ b/core/tests/Drupal/Tests/Component/Utility/UrlHelperTest.php
@@ -7,14 +7,14 @@
 
 namespace Drupal\Tests\Component\Utility;
 
-
 use Drupal\Component\Utility\UrlHelper;
 use Drupal\Component\Utility\String;
 use Drupal\Tests\UnitTestCase;
 
 /**
- * @coversDefaultClass \Drupal\Component\Utility\UrlHelper
  * @group Utility
+ *
+ * @coversDefaultClass \Drupal\Component\Utility\UrlHelper
  */
 class UrlHelperTest extends UnitTestCase {
 
@@ -34,7 +34,10 @@ public function providerTestBuildQuery() {
   }
 
   /**
-   * Tests UrlHelper::buildQuery().
+   * Tests query building.
+   *
+   * @dataProvider providerTestBuildQuery
+   * @covers ::buildQuery
    *
    * @param array $query
    *   The array of query parameters.
@@ -42,8 +45,6 @@ public function providerTestBuildQuery() {
    *   The expected query string.
    * @param string $message
    *   The assertion message.
-   *
-   * @dataProvider providerTestBuildQuery
    */
   public function testBuildQuery($query, $expected, $message) {
     $this->assertEquals(UrlHelper::buildQuery($query), $expected, $message);
@@ -82,12 +83,13 @@ public function providerTestValidAbsoluteData() {
   /**
    * Tests valid absolute URLs.
    *
+   * @dataProvider providerTestValidAbsoluteData
+   * @covers ::isValid
+   *
    * @param string $url
    *   The url to test.
    * @param string $scheme
    *   The scheme to test.
-   *
-   * @dataProvider providerTestValidAbsoluteData
    */
   public function testValidAbsolute($url, $scheme) {
     $test_url = $scheme . '://' . $url;
@@ -112,12 +114,13 @@ public function providerTestInvalidAbsolute() {
   /**
    * Tests invalid absolute URLs.
    *
+   * @dataProvider providerTestInvalidAbsolute
+   * @covers ::isValid
+   *
    * @param string $url
    *   The url to test.
    * @param string $scheme
    *   The scheme to test.
-   *
-   * @dataProvider providerTestInvalidAbsolute
    */
   public function testInvalidAbsolute($url, $scheme) {
     $test_url = $scheme . '://' . $url;
@@ -145,12 +148,13 @@ public function providerTestValidRelativeData() {
   /**
    * Tests valid relative URLs.
    *
+   * @dataProvider providerTestValidRelativeData
+   * @covers ::isValid
+   *
    * @param string $url
    *   The url to test.
    * @param string $prefix
    *   The prefix to test.
-   *
-   * @dataProvider providerTestValidRelativeData
    */
   public function testValidRelative($url, $prefix) {
     $test_url = $prefix . $url;
@@ -175,12 +179,13 @@ public function providerTestInvalidRelativeData() {
   /**
    * Tests invalid relative URLs.
    *
+   * @dataProvider providerTestInvalidRelativeData
+   * @covers ::isValid
+   *
    * @param string $url
    *   The url to test.
    * @param string $prefix
    *   The prefix to test.
-   *
-   * @dataProvider providerTestInvalidRelativeData
    */
   public function testInvalidRelative($url, $prefix) {
     $test_url = $prefix . $url;
@@ -191,6 +196,9 @@ public function testInvalidRelative($url, $prefix) {
   /**
    * Tests query filtering.
    *
+   * @dataProvider providerTestFilterQueryParameters
+   * @covers ::filterQueryParameters
+   *
    * @param array $query
    *   The array of query parameters.
    * @param array $exclude
@@ -198,10 +206,6 @@ public function testInvalidRelative($url, $prefix) {
    *   nested items.
    * @param array $expected
    *   An array containing query parameters.
-   *
-   * @dataProvider providerTestFilterQueryParameters
-   *
-   * @see \Drupal\Component\Utility\Url::filterQueryParameters().
    */
   public function testFilterQueryParameters($query, $exclude, $expected) {
     $filtered = UrlHelper::filterQueryParameters($query, $exclude);
@@ -233,14 +237,13 @@ public static function providerTestFilterQueryParameters() {
   /**
    * Tests url parsing.
    *
+   * @dataProvider providerTestParse
+   * @covers ::parse
+   *
    * @param string $url
    *   URL to test.
    * @param array $expected
    *   Associative array with expected parameters.
-   *
-   * @dataProvider providerTestParse
-   *
-   * @see \Drupal\Component\Utility\Url::parse()
    */
   public function testParse($url, $expected) {
     $parsed = UrlHelper::parse($url);
@@ -304,14 +307,13 @@ public static function providerTestParse() {
   /**
    * Tests path encoding.
    *
+   * @dataProvider providerTestEncodePath
+   * @covers ::encodePath
+   *
    * @param string $path
    *   A path to encode.
    * @param string $expected
    *   The expected encoded path.
-   *
-   * @see \Drupal\Component\Utility\Url::encodePath().
-   *
-   * @dataProvider providerTestEncodePath
    */
   public function testEncodePath($path, $expected) {
     $encoded = UrlHelper::encodePath($path);
@@ -333,14 +335,13 @@ public static function providerTestEncodePath() {
   /**
    * Tests external versus internal paths.
    *
+   * @dataProvider providerTestIsExternal
+   * @covers ::isExternal
+   *
    * @param string $path
    *   URL or path to test.
    * @param bool $expected
    *   Expected result.
-   *
-   * @see \Drupal\Component\Utility\Url::isExternal()
-   *
-   * @dataProvider providerTestIsExternal
    */
   public function testIsExternal($path, $expected) {
     $isExternal = UrlHelper::isExternal($path);
@@ -363,14 +364,16 @@ public static function providerTestIsExternal() {
   /**
    * Tests bad protocol filtering and escaping.
    *
+   * @dataProvider providerTestFilterBadProtocol
+   * @covers ::setAllowedProtocols
+   * @covers ::filterBadProtocol
+   *
    * @param string $uri
    *    Protocol URI.
    * @param string $expected
    *    Expected escaped value.
    * @param array $protocols
    *    Protocols to allow.
-   *
-   * @dataProvider providerTestFilterBadProtocol
    */
   public function testFilterBadProtocol($uri, $expected, $protocols) {
     UrlHelper::setAllowedProtocols($protocols);
@@ -398,16 +401,16 @@ public static function providerTestFilterBadProtocol() {
   /**
    * Tests dangerous url protocol filtering.
    *
+   * @dataProvider providerTestStripDangerousProtocols
+   * @covers ::setAllowedProtocols
+   * @covers ::stripDangerousProtocols
+   *
    * @param string $uri
    *    Protocol URI.
    * @param string $expected
    *    Expected escaped value.
    * @param array $protocols
    *    Protocols to allow.
-   *
-   * @see \Drupal\Component\Utility\Url::stripDangerousProtocols()
-   *
-   * @dataProvider providerTestStripDangerousProtocols
    */
   public function testStripDangerousProtocols($uri, $expected, $protocols) {
     UrlHelper::setAllowedProtocols($protocols);
diff --git a/core/tests/Drupal/Tests/Component/Utility/UserAgentTest.php b/core/tests/Drupal/Tests/Component/Utility/UserAgentTest.php
new file mode 100644
index 0000000..0f94f47
--- /dev/null
+++ b/core/tests/Drupal/Tests/Component/Utility/UserAgentTest.php
@@ -0,0 +1,179 @@
+<?php
+
+/**
+ * @file
+ * Container Drupal\Tests\Component\Utility\UserAgentTest
+ */
+
+namespace Drupal\Tests\Component\Utility;
+
+use Drupal\Component\Utility\UserAgent;
+use Drupal\Core\Language\Language;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * Tests bytes size parsing helper methods.
+ *
+ * @group Utility
+ *
+ * @coversDefaultClass \Drupal\Component\Utility\UserAgent
+ */
+class UserAgentTest extends UnitTestCase {
+
+  protected $languages;
+  protected $mappings;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+
+    $this->languages = array(
+      // In our test case, 'en' has priority over 'en-US'.
+      'en' => new Language(array(
+        'id' => 'en',
+      )),
+      'en-US' => new Language(array(
+        'id' => 'en-US',
+      )),
+      // But 'fr-CA' has priority over 'fr'.
+      'fr-CA' => new Language(array(
+        'id' => 'fr-CA',
+      )),
+      'fr' => new Language(array(
+        'id' => 'fr',
+      )),
+      // 'es-MX' is alone.
+      'es-MX' => new Language(array(
+        'id' => 'es-MX',
+      )),
+      // 'pt' is alone.
+      'pt' => new Language(array(
+        'id' => 'pt',
+      )),
+      // Language codes with more then one dash are actually valid.
+      // eh-oh-laa-laa is the official language code of the Teletubbies.
+      'eh-oh-laa-laa' => new Language(array(
+        'id' => 'eh-oh-laa-laa',
+      )),
+      // Chinese languages.
+      'zh-hans' => new Language(array(
+        'id' => 'zh-hans',
+      )),
+      'zh-hant' => new Language(array(
+        'id' => 'zh-hant',
+      )),
+      'zh-hant-tw' => new Language(array(
+        'id' => 'zh-hant',
+      )),
+    );
+    $this->mappings = array(
+      'no' => 'nb',
+      'pt' => 'pt-pt',
+      'zh' => 'zh-hans',
+      'zh-tw' => 'zh-hant',
+      'zh-hk' => 'zh-hant',
+      'zh-mo' => 'zh-hant',
+      'zh-cht' => 'zh-hant',
+      'zh-cn' => 'zh-hans',
+      'zh-sg' => 'zh-hans',
+      'zh-chs' => 'zh-hans',
+    );
+  }
+
+  /**
+   * Test matching language from user agent.
+   *
+   * @dataProvider providerTestGetBestMatchingLangcode
+   * @covers ::getBestMatchingLangcode
+   */
+  public function testGetBestMatchingLangcode($accept_language, $expected) {
+    $result = UserAgent::getBestMatchingLangcode($accept_language, array_keys($this->languages), $this->mappings);
+    $this->assertSame($expected, $result, $accept_language);
+  }
+
+  public function providerTestGetBestMatchingLangcode() {
+    return array(
+      // Equal qvalue for each language, choose the site preferred one.
+      array('en,en-US,fr-CA,fr,es-MX', 'en'),
+      array('en-US,en,fr-CA,fr,es-MX', 'en'),
+      array('fr,en', 'en'),
+      array('en,fr', 'en'),
+      array('en-US,fr', 'en-US'),
+      array('fr,en-US', 'en-US'),
+      array('fr,fr-CA', 'fr-CA'),
+      array('fr-CA,fr', 'fr-CA'),
+      array('fr', 'fr-CA'),
+      array('fr;q=1', 'fr-CA'),
+      array('fr,es-MX', 'fr-CA'),
+      array('fr,es', 'fr-CA'),
+      array('es,fr', 'fr-CA'),
+      array('es-MX,de', 'es-MX'),
+      array('de,es-MX', 'es-MX'),
+
+      // Different cases and whitespace.
+      array('en', 'en'),
+      array('En', 'en'),
+      array('EN', 'en'),
+      array(' en', 'en'),
+      array('en ', 'en'),
+      array('en, fr', 'en'),
+
+      // A less specific language from the browser matches a more specific one
+      // from the website, and the other way around for compatibility with
+      // some versions of Internet Explorer.
+      array('es', 'es-MX'),
+      array('es-MX', 'es-MX'),
+      array('pt', 'pt'),
+      array('pt-PT', 'pt'),
+      array('pt-PT;q=0.5,pt-BR;q=1,en;q=0.7', 'en'),
+      array('pt-PT;q=1,pt-BR;q=0.5,en;q=0.7', 'en'),
+      array('pt-PT;q=0.4,pt-BR;q=0.1,en;q=0.7', 'en'),
+      array('pt-PT;q=0.1,pt-BR;q=0.4,en;q=0.7', 'en'),
+
+      // Language code with several dashes are valid. The less specific language
+      // from the browser matches the more specific one from the website.
+      array('eh-oh-laa-laa', 'eh-oh-laa-laa'),
+      array('eh-oh-laa', 'eh-oh-laa-laa'),
+      array('eh-oh', 'eh-oh-laa-laa'),
+      array('eh', 'eh-oh-laa-laa'),
+
+      // Different qvalues.
+      array('fr,en;q=0.5', 'fr-CA'),
+      array('fr,en;q=0.5,fr-CA;q=0.25', 'fr'),
+
+      // Silly wildcards are also valid.
+      array('*,fr-CA;q=0.5', 'en'),
+      array('*,en;q=0.25', 'fr-CA'),
+      array('en,en-US;q=0.5,fr;q=0.25', 'en'),
+      array('en-US,en;q=0.5,fr;q=0.25', 'en-US'),
+
+      // Unresolvable cases.
+      array('', FALSE),
+      array('de,pl', FALSE),
+      array('iecRswK4eh', FALSE),
+      array($this->randomName(10), FALSE),
+
+      // Chinese langcodes.
+      array('zh-cn, en-us;q=0.90, en;q=0.80, zh;q=0.70', 'zh-hans'),
+      array('zh-tw, en-us;q=0.90, en;q=0.80, zh;q=0.70', 'zh-hant'),
+      array('zh-hant, en-us;q=0.90, en;q=0.80, zh;q=0.70', 'zh-hant'),
+      array('zh-hans, en-us;q=0.90, en;q=0.80, zh;q=0.70', 'zh-hans'),
+      // TODO This is copied from RFC4647 but our regex skips the numbers so they
+      // where removed. Our code should be updated so private1-private2 is valid.
+      // http://tools.ietf.org/html/rfc4647#section-3.4
+      array('zh-hant-CN-x-private-private, en-us;q=0.90, en;q=0.80, zh;q=0.70', 'zh-hant'),
+      array('zh-cn', 'zh-hans'),
+      array('zh-sg', 'zh-hans'),
+      array('zh-tw', 'zh-hant'),
+      array('zh-hk', 'zh-hant'),
+      array('zh-mo', 'zh-hant'),
+      array('zh-hans', 'zh-hans'),
+      array('zh-hant', 'zh-hant'),
+      array('zh-chs', 'zh-hans'),
+      array('zh-cht', 'zh-hant'),
+    );
+
+  }
+}
diff --git a/core/tests/Drupal/Tests/Component/Utility/XssTest.php b/core/tests/Drupal/Tests/Component/Utility/XssTest.php
index 7f45b17..4ce1915 100644
--- a/core/tests/Drupal/Tests/Component/Utility/XssTest.php
+++ b/core/tests/Drupal/Tests/Component/Utility/XssTest.php
@@ -13,9 +13,12 @@
 use Drupal\Tests\UnitTestCase;
 
 /**
- * @coversDefaultClass \Drupal\Component\Utility\Xss
+ * XSS Filtering tests.
+ *
  * @group Utility
  *
+ * @coversDefaultClass \Drupal\Component\Utility\Xss
+ *
  * Script injection vectors mostly adopted from http://ha.ckers.org/xss.html.
  *
  * Relevant CVEs:
