diff --git a/core/lib/Drupal/Component/Utility/SafeMarkup.php b/core/lib/Drupal/Component/Utility/SafeMarkup.php
index d20ad6ba08a7a631a04ad5778110342bd7768740..3020bbe5711c3b7fcf85661570db20bf7db8e127 100644
--- a/core/lib/Drupal/Component/Utility/SafeMarkup.php
+++ b/core/lib/Drupal/Component/Utility/SafeMarkup.php
@@ -35,58 +35,29 @@ class SafeMarkup {
   /**
    * The list of safe strings.
    *
+   * Strings in this list are marked as secure for the entire page render, not
+   * just the code or element that set it. Therefore, only valid HTML should be
+   * marked as safe (never partial markup). For example, you should never mark
+   * string such as '<' or '<script>' safe.
+   *
    * @var array
    */
   protected static $safeStrings = array();
 
   /**
-   * Adds a string to a list of strings marked as secure.
-   *
-   * This method is for internal use. Do not use it to prevent escaping of
-   * markup; instead, use the appropriate
-   * @link sanitization sanitization functions @endlink or the
-   * @link theme_render theme and render systems @endlink so that the output
-   * can be themed, escaped, and altered properly.
-   *
-   * This marks strings as secure for the entire page render, not just the code
-   * or element that set it. Therefore, only valid HTML should be
-   * marked as safe (never partial markup). For example, you should never do:
-   * @code
-   *   SafeMarkup::set('<');
-   * @endcode
-   * or:
-   * @code
-   *   SafeMarkup::set('<script>');
-   * @endcode
+   * Checks if a string is safe to output.
    *
-   * @param string $string
-   *   The content to be marked as secure.
+   * @param string|\Drupal\Component\Utility\SafeStringInterface $string
+   *   The content to be checked.
    * @param string $strategy
-   *   The escaping strategy used for this string. Two values are supported
-   *   by default:
+   *   The escaping strategy. Defaults to 'html'. Two escaping strategies are
+   *   supported by default:
    *   - 'html': (default) The string is safe for use in HTML code.
    *   - 'all': The string is safe for all use cases.
    *   See the
    *   @link http://twig.sensiolabs.org/doc/filters/escape.html Twig escape documentation @endlink
    *   for more information on escaping strategies in Twig.
    *
-   * @return string
-   *   The input string that was marked as safe.
-   */
-  public static function set($string, $strategy = 'html') {
-    $string = (string) $string;
-    static::$safeStrings[$string][$strategy] = TRUE;
-    return $string;
-  }
-
-  /**
-   * Checks if a string is safe to output.
-   *
-   * @param string|\Drupal\Component\Utility\SafeStringInterface $string
-   *   The content to be checked.
-   * @param string $strategy
-   *   The escaping strategy. See self::set(). Defaults to 'html'.
-   *
    * @return bool
    *   TRUE if the string has been marked secure, FALSE otherwise.
    */
@@ -100,12 +71,29 @@ public static function isSafe($string, $strategy = 'html') {
   /**
    * Adds previously retrieved known safe strings to the safe string list.
    *
-   * This is useful for the batch and form APIs, where it is important to
-   * preserve the safe markup state across page requests. The strings will be
-   * added to any safe strings already marked for the current request.
+   * This method is for internal use. Do not use it to prevent escaping of
+   * markup; instead, use the appropriate
+   * @link sanitization sanitization functions @endlink or the
+   * @link theme_render theme and render systems @endlink so that the output
+   * can be themed, escaped, and altered properly.
    *
+   * This marks strings as secure for the entire page render, not just the code
+   * or element that set it. Therefore, only valid HTML should be
+   * marked as safe (never partial markup). For example, you should never do:
+   * @code
+   *   SafeMarkup::setMultiple(['<' => ['html' => TRUE]]);
+   * @endcode
+   * or:
+   * @code
+   *   SafeMarkup::setMultiple(['<script>' => ['all' => TRUE]]);
+   * @endcode
+
    * @param array $safe_strings
    *   A list of safe strings as previously retrieved by self::getAll().
+   *   Every string in this list will be represented by a multidimensional
+   *   array in which the keys are the string and the escaping strategy used for
+   *   this string, and in which the value is the boolean TRUE.
+   *   See self::isSafe() for the list of supported escaping strategies.
    *
    * @throws \UnexpectedValueException
    *
diff --git a/core/lib/Drupal/Component/Utility/SafeStringInterface.php b/core/lib/Drupal/Component/Utility/SafeStringInterface.php
index 45d536d15034ed1f4ca0a32f0c05c7a31af4c7be..181d1d67debdbfb806a5cdf0b1d23228f75e833c 100644
--- a/core/lib/Drupal/Component/Utility/SafeStringInterface.php
+++ b/core/lib/Drupal/Component/Utility/SafeStringInterface.php
@@ -29,7 +29,6 @@
  *   and to fast render fields.
  *
  * @see \Drupal\Component\Utility\SafeStringTrait
- * @see \Drupal\Component\Utility\SafeMarkup::set()
  * @see \Drupal\Component\Utility\SafeMarkup::isSafe()
  * @see \Drupal\Core\Template\TwigExtension::escapeFilter()
  */
diff --git a/core/tests/Drupal/Tests/Component/Utility/SafeMarkupTest.php b/core/tests/Drupal/Tests/Component/Utility/SafeMarkupTest.php
index ec83229b887a08adb01cb16bc6d8a5def9796dbf..fae15bb55c07419b9512e8cd8749eb9baca19c48 100644
--- a/core/tests/Drupal/Tests/Component/Utility/SafeMarkupTest.php
+++ b/core/tests/Drupal/Tests/Component/Utility/SafeMarkupTest.php
@@ -21,54 +21,81 @@
 class SafeMarkupTest extends UnitTestCase {
 
   /**
-   * Tests SafeMarkup::set() and SafeMarkup::isSafe().
+   * Helper function to add a string to the safe list for testing.
    *
-   * @dataProvider providerSet
-   *
-   * @param string $text
-   *   The text or object to provide to SafeMarkup::set().
-   * @param string $message
-   *   The message to provide as output for the test.
+   * @param string $string
+   *   The content to be marked as secure.
+   * @param string $strategy
+   *   The escaping strategy used for this string. Two values are supported
+   *   by default:
+   *   - 'html': (default) The string is safe for use in HTML code.
+   *   - 'all': The string is safe for all use cases.
+   *   See the
+   *   @link http://twig.sensiolabs.org/doc/filters/escape.html Twig escape documentation @endlink
+   *   for more information on escaping strategies in Twig.
+   *
+   * @return string
+   *   The input string that was marked as safe.
+   */
+  protected function safeMarkupSet($string, $strategy = 'html') {
+    $reflected_class = new \ReflectionClass('\Drupal\Component\Utility\SafeMarkup');
+    $reflected_property = $reflected_class->getProperty('safeStrings');
+    $reflected_property->setAccessible(true);
+    $current_value = $reflected_property->getValue();
+    $current_value[$string][$strategy] = TRUE;
+    $reflected_property->setValue($current_value);
+    return $string;
+  }
+
+  /**
+   * Tests SafeMarkup::isSafe() with different providers.
    *
-   * @covers ::set
+   * @covers ::isSafe
    */
-  public function testSet($text, $message) {
-    $returned = SafeMarkup::set($text);
-    $this->assertTrue(is_string($returned), 'The return value of SafeMarkup::set() is really a string');
-    $this->assertEquals($returned, $text, 'The passed in value should be equal to the string value according to PHP');
-    $this->assertTrue(SafeMarkup::isSafe($text), $message);
-    $this->assertTrue(SafeMarkup::isSafe($returned), 'The return value has been marked as safe');
+  public function testStrategy() {
+    $returned = $this->safeMarkupSet('string0', 'html');
+    $this->assertTrue(SafeMarkup::isSafe($returned), 'String set with "html" provider is safe for default (html)');
+    $returned = $this->safeMarkupSet('string1', 'all');
+    $this->assertTrue(SafeMarkup::isSafe($returned), 'String set with "all" provider is safe for default (html)');
+    $returned = $this->safeMarkupSet('string2', 'css');
+    $this->assertFalse(SafeMarkup::isSafe($returned), 'String set with "css" provider is not safe for default (html)');
+    $returned = $this->safeMarkupSet('string3');
+    $this->assertFalse(SafeMarkup::isSafe($returned, 'all'), 'String set with "html" provider is not safe for "all"');
   }
 
   /**
    * Data provider for testSet().
-   *
-   * @see testSet()
    */
   public function providerSet() {
     // Checks that invalid multi-byte sequences are escaped.
-    $tests[] = array("Foo\xC0barbaz", 'Foo�barbaz', 'Invalid sequence "Foo\xC0barbaz" is escaped', TRUE);
-    $tests[] = array("Fooÿñ", 'SafeMarkup::set() does not escape valid sequence "Fooÿñ"');
-    $tests[] = array(new TextWrapper("Fooÿñ"), 'SafeMarkup::set() does not escape valid sequence "Fooÿñ" in an object implementing __toString()');
-    $tests[] = array("<div>", 'SafeMarkup::set() does not escape HTML');
+    $tests[] = array(
+      'Foo�barbaz',
+      'SafeMarkup::setMarkup() functions with valid sequence "Foo�barbaz"',
+      TRUE
+    );
+    $tests[] = array(
+      "Fooÿñ",
+      'SafeMarkup::setMarkup() functions with valid sequence "Fooÿñ"'
+    );
+    $tests[] = array("<div>", 'SafeMarkup::setMultiple() does not escape HTML');
 
     return $tests;
   }
 
   /**
-   * Tests SafeMarkup::set() and SafeMarkup::isSafe() with different providers.
+   * Tests SafeMarkup::setMultiple().
+   * @dataProvider providerSet
    *
-   * @covers ::isSafe
+   * @param string $text
+   *   The text or object to provide to SafeMarkup::setMultiple().
+   * @param string $message
+   *   The message to provide as output for the test.
+   *
+   * @covers ::setMultiple
    */
-  public function testStrategy() {
-    $returned = SafeMarkup::set('string0', 'html');
-    $this->assertTrue(SafeMarkup::isSafe($returned), 'String set with "html" provider is safe for default (html)');
-    $returned = SafeMarkup::set('string1', 'all');
-    $this->assertTrue(SafeMarkup::isSafe($returned), 'String set with "all" provider is safe for default (html)');
-    $returned = SafeMarkup::set('string2', 'css');
-    $this->assertFalse(SafeMarkup::isSafe($returned), 'String set with "css" provider is not safe for default (html)');
-    $returned = SafeMarkup::set('string3');
-    $this->assertFalse(SafeMarkup::isSafe($returned, 'all'), 'String set with "html" provider is not safe for "all"');
+  public function testSet($text, $message) {
+    SafeMarkup::setMultiple([$text => ['html' => TRUE]]);
+    $this->assertTrue(SafeMarkup::isSafe($text), $message);
   }
 
   /**
@@ -217,7 +244,7 @@ public function __toString() {
  * Marks text as safe.
  *
  * SafeMarkupTestSafeString is used to mark text as safe because
- * SafeMarkup::set() is a global static that affects all tests.
+ * SafeMarkup::$safeStrings is a global static that affects all tests.
  */
 class SafeMarkupTestSafeString implements SafeStringInterface {
   use SafeStringTrait;