diff --git a/core/core.services.yml b/core/core.services.yml
index 70c6441f91e0d8a7a749a6c01c716aaa698aefbc..c63bde7a4136a28b5db686eda7d15bf43b1b7aca 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -1126,7 +1126,7 @@ services:
     arguments: ['@state', '@current_user']
   maintenance_mode_subscriber:
     class: Drupal\Core\EventSubscriber\MaintenanceModeSubscriber
-    arguments: ['@maintenance_mode', '@config.factory', '@string_translation', '@url_generator', '@current_user', '@bare_html_page_renderer']
+    arguments: ['@maintenance_mode', '@config.factory', '@string_translation', '@url_generator', '@current_user', '@bare_html_page_renderer', '@messenger']
     tags:
       - { name: event_subscriber }
   path_subscriber:
@@ -1631,3 +1631,6 @@ services:
     arguments: ['@current_user', '@path.current', '@path.matcher', '@language_manager']
     tags:
       - { name: event_subscriber }
+  messenger:
+    class: Drupal\Core\Messenger\SessionMessenger
+    arguments: ['@page_cache_kill_switch']
diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index ec1209740d766327585d744875275d1e6e7f28a4..4599b2b828e364cc5163d2d3b030530c4c56d49c 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -9,8 +9,6 @@
 use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Logger\RfcLogLevel;
-use Drupal\Core\Render\Markup;
-use Drupal\Component\Render\MarkupInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\Site\Settings;
 use Drupal\Core\Utility\Error;
@@ -437,30 +435,15 @@ function watchdog_exception($type, Exception $exception, $message = NULL, $varia
  *
  * @see drupal_get_messages()
  * @see status-messages.html.twig
+ *
+ * @deprecated Deprecated as of Drupal 8.2.
+ *   Use \Drupal::service('messenger')->addMessage() instead.
  */
 function drupal_set_message($message = NULL, $type = 'status', $repeat = FALSE) {
-  if (isset($message)) {
-    if (!isset($_SESSION['messages'][$type])) {
-      $_SESSION['messages'][$type] = array();
-    }
-
-    // Convert strings which are safe to the simplest Markup objects.
-    if (!($message instanceof Markup) && $message instanceof MarkupInterface) {
-      $message = Markup::create((string) $message);
-    }
-
-    // Do not use strict type checking so that equivalent string and
-    // MarkupInterface objects are detected.
-    if ($repeat || !in_array($message, $_SESSION['messages'][$type])) {
-      $_SESSION['messages'][$type][] = $message;
-    }
-
-    // Mark this page as being uncacheable.
-    \Drupal::service('page_cache_kill_switch')->trigger();
-  }
-
-  // Messages not set when DB connection fails.
-  return isset($_SESSION['messages']) ? $_SESSION['messages'] : NULL;
+  /* @var \Drupal\Core\Messenger\MessengerInterface $messenger */
+  $messenger = \Drupal::service('messenger');
+  $messenger->addMessage($message, $type, $repeat);
+  return $messenger->getMessages();
 }
 
 /**
@@ -487,12 +470,19 @@ function drupal_set_message($message = NULL, $type = 'status', $repeat = FALSE)
  *
  * @see drupal_set_message()
  * @see status-messages.html.twig
+ *
+ * @deprecated Deprecated as of Drupal 8.2.
+ *   Use \Drupal::service('messenger')->getMessages() or
+ *   \Drupal::service('messenger')->getMessagesByType() instead.
  */
 function drupal_get_messages($type = NULL, $clear_queue = TRUE) {
-  if ($messages = drupal_set_message()) {
+  /** @var \Drupal\Core\Messenger\MessengerInterface $messenger */
+  $messenger = \Drupal::service('messenger');
+
+  if ($messages = $messenger->getMessages()) {
     if ($type) {
       if ($clear_queue) {
-        unset($_SESSION['messages'][$type]);
+        $messenger->deleteMessagesByType($type);
       }
       if (isset($messages[$type])) {
         return array($type => $messages[$type]);
@@ -500,7 +490,7 @@ function drupal_get_messages($type = NULL, $clear_queue = TRUE) {
     }
     else {
       if ($clear_queue) {
-        unset($_SESSION['messages']);
+        $messenger->deleteMessages();
       }
       return $messages;
     }
diff --git a/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php
index 57d43ec0be11109ab209f1dba42686fc14fe9835..2e9f6fd5abc2ce291138f39fcc1b0ccff1b37a4a 100644
--- a/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php
@@ -5,6 +5,7 @@
 use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Render\BareHtmlPageRendererInterface;
+use Drupal\Core\Messenger\MessengerInterface;
 use Drupal\Core\Routing\RouteMatch;
 use Drupal\Core\Routing\UrlGeneratorInterface;
 use Drupal\Core\Session\AccountInterface;
@@ -58,6 +59,13 @@ class MaintenanceModeSubscriber implements EventSubscriberInterface {
    */
   protected $bareHtmlPageRenderer;
 
+  /**
+   * The messenger.
+   *
+   * @var \Drupal\Core\Messenger\MessengerInterface
+   */
+  protected $messenger;
+
   /**
    * Constructs a new MaintenanceModeSubscriber.
    *
@@ -73,14 +81,17 @@ class MaintenanceModeSubscriber implements EventSubscriberInterface {
    *   The current user.
    * @param \Drupal\Core\Render\BareHtmlPageRendererInterface $bare_html_page_renderer
    *   The bare HTML page renderer.
+   * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+   *   The messenger.
    */
-  public function __construct(MaintenanceModeInterface $maintenance_mode, ConfigFactoryInterface $config_factory, TranslationInterface $translation, UrlGeneratorInterface $url_generator, AccountInterface $account, BareHtmlPageRendererInterface $bare_html_page_renderer) {
+  public function __construct(MaintenanceModeInterface $maintenance_mode, ConfigFactoryInterface $config_factory, TranslationInterface $translation, UrlGeneratorInterface $url_generator, AccountInterface $account, BareHtmlPageRendererInterface $bare_html_page_renderer, MessengerInterface $messenger) {
     $this->maintenanceMode = $maintenance_mode;
     $this->config = $config_factory;
     $this->stringTranslation = $translation;
     $this->urlGenerator = $url_generator;
     $this->account = $account;
     $this->bareHtmlPageRenderer = $bare_html_page_renderer;
+    $this->messenger = $messenger;
   }
 
   /**
@@ -118,10 +129,10 @@ public function onKernelRequestMaintenance(GetResponseEvent $event) {
         // settings page.
         if ($route_match->getRouteName() != 'system.site_maintenance_mode') {
           if ($this->account->hasPermission('administer site configuration')) {
-            $this->drupalSetMessage($this->t('Operating in maintenance mode. <a href=":url">Go online.</a>', array(':url' => $this->urlGenerator->generate('system.site_maintenance_mode'))), 'status', FALSE);
+            $this->messenger->addMessage($this->t('Operating in maintenance mode. <a href=":url">Go online.</a>', [':url' => $this->urlGenerator->generate('system.site_maintenance_mode')]), 'status', FALSE);
           }
           else {
-            $this->drupalSetMessage($this->t('Operating in maintenance mode.'), 'status', FALSE);
+            $this->messenger->addMessage($this->t('Operating in maintenance mode.'), 'status', FALSE);
           }
         }
       }
@@ -140,13 +151,6 @@ protected function getSiteMaintenanceMessage() {
     ));
   }
 
-  /**
-   * Wraps the drupal_set_message function.
-   */
-  protected function drupalSetMessage($message = NULL, $type = 'status', $repeat = FALSE) {
-    return drupal_set_message($message, $type, $repeat);
-  }
-
   /**
    * {@inheritdoc}
    */
diff --git a/core/lib/Drupal/Core/Installer/InstallerServiceProvider.php b/core/lib/Drupal/Core/Installer/InstallerServiceProvider.php
index 1ace991de83c30fefb697d384005d277ec29d938..f5fcf786a5a6534156efbcb21a5827eb2dd7f8d3 100644
--- a/core/lib/Drupal/Core/Installer/InstallerServiceProvider.php
+++ b/core/lib/Drupal/Core/Installer/InstallerServiceProvider.php
@@ -5,6 +5,7 @@
 use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Core\DependencyInjection\ServiceProviderInterface;
 use Drupal\Core\DependencyInjection\ServiceModifierInterface;
+use Drupal\Core\Messenger\StaticMessenger;
 use Symfony\Component\DependencyInjection\Reference;
 
 /**
@@ -34,6 +35,9 @@ public function register(ContainerBuilder $container) {
       ->register('keyvalue', 'Drupal\Core\KeyValueStore\KeyValueMemoryFactory');
     $container
       ->register('keyvalue.expirable', 'Drupal\Core\KeyValueStore\KeyValueNullExpirableFactory');
+    $definition = $container->getDefinition('messenger');
+    $definition->setClass(StaticMessenger::class);
+    $definition->setArguments([new Reference('page_cache_kill_switch')]);
 
     // Replace services with no-op implementations.
     $container
diff --git a/core/lib/Drupal/Core/Messenger/MessengerInterface.php b/core/lib/Drupal/Core/Messenger/MessengerInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..da36f04216cda2666c721ce5c60b64029878425c
--- /dev/null
+++ b/core/lib/Drupal/Core/Messenger/MessengerInterface.php
@@ -0,0 +1,84 @@
+<?php
+
+namespace Drupal\Core\Messenger;
+
+/**
+ * Stores runtime messages sent out to individual users on the page.
+ *
+ * An example for these messages is for example: "Content X got saved".
+ */
+interface MessengerInterface {
+
+  /**
+   * A status message.
+   */
+  const TYPE_STATUS = 'status';
+
+  /**
+   * A warning.
+   */
+  const TYPE_WARNING = 'warning';
+
+  /**
+   * An error.
+   */
+  const TYPE_ERROR = 'error';
+
+  /**
+   * Adds a new message to the queue.
+   *
+   * @param string|\Drupal\Component\Render\MarkupInterface $message
+   *   (optional) The translated message to be displayed to the user. For
+   *   consistency with other messages, it should begin with a capital letter
+   *   and end with a period.
+   * @param string $type
+   *   (optional) The message's type. Either self::TYPE_STATUS,
+   *   self::TYPE_WARNING, or self::TYPE_ERROR.
+   * @param bool $repeat
+   *   (optional) If this is FALSE and the message is already set, then the
+   *   message won't be repeated. Defaults to FALSE.
+   *
+   * @return $this
+   */
+  public function addMessage($message, $type = self::TYPE_STATUS, $repeat = FALSE);
+
+  /**
+   * Gets all messages.
+   *
+   * @return string[][]|\Drupal\Component\Render\MarkupInterface[][]
+   *   Keys are message types and values are indexed arrays of messages. Message
+   *   types are either self::TYPE_STATUS, self::TYPE_WARNING, or
+   *   self::TYPE_ERROR.
+   */
+  public function getMessages();
+
+  /**
+   * Gets all messages of a certain type.
+   *
+   * @param string $type
+   *   The messages' type. Either self::TYPE_STATUS, self::TYPE_WARNING,
+   *   or self::TYPE_ERROR.
+   *
+   * @return string[]|\Drupal\Component\Render\MarkupInterface[]
+   */
+  public function getMessagesByType($type);
+
+  /**
+   * Deletes all messages.
+   *
+   * @return $this
+   */
+  public function deleteMessages();
+
+  /**
+   * Deletes all messages of a certain type.
+   *
+   * @param string $type
+   *   The messages' type. Either self::TYPE_STATUS, self::TYPE_WARNING, or
+   *   self::TYPE_ERROR.
+   *
+   * @return $this
+   */
+  public function deleteMessagesByType($type);
+
+}
diff --git a/core/lib/Drupal/Core/Messenger/SessionMessenger.php b/core/lib/Drupal/Core/Messenger/SessionMessenger.php
new file mode 100644
index 0000000000000000000000000000000000000000..fc858fda513f250b2d4ba7a7572374642a5315c7
--- /dev/null
+++ b/core/lib/Drupal/Core/Messenger/SessionMessenger.php
@@ -0,0 +1,94 @@
+<?php
+
+namespace Drupal\Core\Messenger;
+
+use Drupal\Component\Render\MarkupInterface;
+use Drupal\Core\PageCache\ResponsePolicy\KillSwitch;
+use Drupal\Core\Render\Markup;
+
+/**
+ * Provides a session-based messenger.
+ */
+class SessionMessenger implements MessengerInterface {
+
+  /**
+   * The page caching kill switch.
+   *
+   * @var \Drupal\Core\PageCache\ResponsePolicy\KillSwitch
+   */
+  protected $pageCacheKillSwitch;
+
+  /**
+   * Constructs a new instance.
+   *
+   * @param \Drupal\Core\Session\SessionManagerInterface
+   * @param \Drupal\Core\PageCache\ResponsePolicy\KillSwitch $page_cache_kill_switch
+   *   The page caching kill switch.
+   */
+  public function __construct(KillSwitch $page_cache_kill_switch) {
+    $this->pageCacheKillSwitch = $page_cache_kill_switch;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function addMessage($message, $type = self::TYPE_STATUS, $repeat = FALSE) {
+    if (!isset($_SESSION['messages'][$type])) {
+      $_SESSION['messages'][$type] = [];
+    }
+
+    // Convert strings which are safe to the simplest Markup objects.
+    if (!($message instanceof Markup) && $message instanceof MarkupInterface) {
+      $message = Markup::create((string) $message);
+    }
+
+    // Do not use strict type checking so that equivalent string and
+    // \Drupal\Core\Render\Markup objects are detected.
+    if ($repeat || !in_array($message, $_SESSION['messages'][$type])) {
+      $_SESSION['messages'][$type][] = $message;
+      $this->pageCacheKillSwitch->trigger();
+    }
+
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getMessages() {
+    $messages = isset($_SESSION['messages']) ? $_SESSION['messages'] : [];
+    foreach ($messages as $type => $messages_by_type) {
+      $messages[$type] = $messages_by_type;
+    }
+
+    return $messages;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getMessagesByType($type) {
+    $messages = isset($_SESSION['messages']) && isset($_SESSION['messages'][$type]) ? $_SESSION['messages'][$type] : [];
+
+    return $messages;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function deleteMessages() {
+    unset($_SESSION['messages']);
+
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function deleteMessagesByType($type) {
+    unset($_SESSION['messages'][$type]);
+
+    return $this;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Messenger/StaticMessenger.php b/core/lib/Drupal/Core/Messenger/StaticMessenger.php
new file mode 100644
index 0000000000000000000000000000000000000000..f2e0f51101aa3f9b4feb45517e3d6bb3246c738d
--- /dev/null
+++ b/core/lib/Drupal/Core/Messenger/StaticMessenger.php
@@ -0,0 +1,104 @@
+<?php
+
+namespace Drupal\Core\Messenger;
+
+use Drupal\Component\Render\MarkupInterface;
+use Drupal\Core\PageCache\ResponsePolicy\KillSwitch;
+use Drupal\Core\Render\Markup;
+
+/**
+ * Provides a messenger that stores messages for this request only.
+ */
+class StaticMessenger implements MessengerInterface {
+
+  /**
+   * The messages that have been set.
+   *
+   * @var array[]
+   *   Keys are either self::TYPE_STATUS, self::TYPE_WARNING, or
+   *   self::TYPE_ERROR. Values are arrays of arrays with the following keys:
+   *   - message (string): the message.
+   *   - safe (bool): whether the message is marked as safe markup.
+   */
+  protected $messages = [];
+
+  /**
+   * The page caching kill switch.
+   *
+   * @var \Drupal\Core\PageCache\ResponsePolicy\KillSwitch
+   */
+  protected $pageCacheKillSwitch;
+
+  /**
+   * Constructs a new instance.
+   *
+   * @param \Drupal\Core\PageCache\ResponsePolicy\KillSwitch $page_cache_kill_switch
+   *   The page caching kill switch.
+   */
+  public function __construct(KillSwitch $page_cache_kill_switch) {
+    $this->pageCacheKillSwitch = $page_cache_kill_switch;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function addMessage($message, $type = self::TYPE_STATUS, $repeat = FALSE) {
+    if (!isset($this->messages[$type])) {
+      $this->messages[$type] = [];
+    }
+
+    // Convert strings which are safe to the simplest Markup objects.
+    if (!($message instanceof Markup) && $message instanceof MarkupInterface) {
+      $message = Markup::create((string) $message);
+    }
+
+    // Do not use strict type checking so that equivalent string and
+    // MarkupInterface objects are detected.
+    if ($repeat || !in_array($message, $this->messages[$type])) {
+      $this->messages[$type][] = $message;
+      $this->pageCacheKillSwitch->trigger();
+    }
+
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getMessages() {
+    $messages = isset($this->messages) ? $this->messages : [];
+    foreach ($messages as $type => $messages_by_type) {
+      $messages[$type] = $messages_by_type;
+    }
+
+    return $messages;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getMessagesByType($type) {
+    $messages = isset($this->messages) && isset($this->messages[$type]) ? $this->messages[$type] : [];
+
+    return $messages;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function deleteMessages() {
+    unset($this->messages);
+
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function deleteMessagesByType($type) {
+    unset($this->messages[$type]);
+
+    return $this;
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/Messenger/SessionMessengerTest.php b/core/tests/Drupal/Tests/Core/Messenger/SessionMessengerTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..2da979c0a20f4f504b6e62c1488f1e2eb11e20f0
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Messenger/SessionMessengerTest.php
@@ -0,0 +1,100 @@
+<?php
+
+namespace Drupal\Tests\Core\Messenger;
+
+use Drupal\Core\Messenger\SessionMessenger;
+use Drupal\Core\PageCache\ResponsePolicy\KillSwitch;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\Core\Messenger\SessionMessenger
+ * @group messenger
+ */
+class SessionMessengerTest extends UnitTestCase {
+
+  /**
+   * A copy of any existing session data to restore after the test.
+   *
+   * @var array
+   */
+  protected $existingSession;
+
+  /**
+   * The messenger under test.
+   *
+   * @var \Drupal\Core\Messenger\SessionMessenger
+   */
+  protected $messenger;
+
+  /**
+   * The page caching kill switch.
+   *
+   * @var \Drupal\Core\PageCache\ResponsePolicy\KillSwitch|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $pageCacheKillSwitch;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    $this->pageCacheKillSwitch = $this->prophesize(KillSwitch::class);
+
+    $this->existingSession = isset($_SESSION) ? $_SESSION : NULL;
+    $_SESSION = [];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function tearDown() {
+    if ($this->existingSession !== NULL) {
+      $_SESSION = $this->existingSession;
+    }
+    else {
+      unset($_SESSION);
+    }
+  }
+
+  /**
+   * @covers ::addMessage
+   * @covers ::getMessages
+   * @covers ::getMessagesByType
+   * @covers ::deleteMessages
+   * @covers ::deleteMessagesByType
+   */
+  public function testMessenger() {
+    $this->pageCacheKillSwitch->trigger()->shouldBeCalled();
+
+    $this->messenger = new SessionMessenger($this->pageCacheKillSwitch->reveal());
+
+    $message_a = $this->randomMachineName();
+    $type_a = $this->randomMachineName();
+    $message_b = $this->randomMachineName();
+    $type_b = $this->randomMachineName();
+
+    // Test that if there are no messages, the default is an empty array.
+    $this->assertEquals($this->messenger->getMessages(), []);
+
+    // Test that adding a message returns the messenger and that the message can
+    // be retrieved.
+    $this->assertEquals($this->messenger->addMessage($message_a, $type_a), $this->messenger);
+    $this->messenger->addMessage($message_a, $type_a);
+    $this->messenger->addMessage($message_a, $type_a, TRUE);
+    $this->messenger->addMessage($message_b, $type_b, TRUE);
+    $this->assertEquals($this->messenger->getMessages(), [
+      $type_a => [$message_a, $message_a],
+      $type_b => [$message_b],
+    ]);
+
+    // Test deleting messages of a certain type.
+    $this->assertEquals($this->messenger->deleteMessagesByType($type_a), $this->messenger);
+    $this->assertEquals($this->messenger->getMessages(), [
+      $type_b => [$message_b],
+    ]);
+
+    // Test deleting all messages.
+    $this->assertEquals($this->messenger->deleteMessages(), $this->messenger);
+    $this->assertEquals($this->messenger->getMessages(), []);
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/Messenger/StaticMessengerTest.php b/core/tests/Drupal/Tests/Core/Messenger/StaticMessengerTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d3158954497d81d304b1c5b4e24829c96e006692
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Messenger/StaticMessengerTest.php
@@ -0,0 +1,80 @@
+<?php
+
+namespace Drupal\Tests\Core\Messenger;
+
+use Drupal\Core\Messenger\StaticMessenger;
+use Drupal\Core\PageCache\ResponsePolicy\KillSwitch;
+use Drupal\Tests\RandomGeneratorTrait;
+
+/**
+ * @coversDefaultClass \Drupal\Core\Messenger\StaticMessenger
+ * @group messenger
+ */
+class StaticMessengerTest extends \PHPUnit_Framework_TestCase {
+
+  use RandomGeneratorTrait;
+
+  /**
+   * The messenger under test.
+   *
+   * @var \Drupal\Core\Messenger\StaticMessenger
+   */
+  protected $messenger;
+
+  /**
+   * The page caching kill switch.
+   *
+   * @var \Drupal\Core\PageCache\ResponsePolicy\KillSwitch|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $pageCacheKillSwitch;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    $this->pageCacheKillSwitch = $this->prophesize(KillSwitch::class);
+  }
+
+  /**
+   * @covers ::addMessage
+   * @covers ::getMessages
+   * @covers ::getMessagesByType
+   * @covers ::deleteMessages
+   * @covers ::deleteMessagesByType
+   */
+  public function testMessenger() {
+    $message_a = $this->randomMachineName();
+    $type_a = $this->randomMachineName();
+    $message_b = $this->randomMachineName();
+    $type_b = $this->randomMachineName();
+
+    $this->pageCacheKillSwitch->trigger()->shouldBeCalled();
+
+    $this->messenger = new StaticMessenger($this->pageCacheKillSwitch->reveal());
+
+    // Test that if there are no messages, the default is an empty array.
+    $this->assertEquals($this->messenger->getMessages(), []);
+
+    // Test that adding a message returns the messenger and that the message can
+    // be retrieved.
+    $this->assertSame($this->messenger->addMessage($message_a, $type_a), $this->messenger);
+    $this->messenger->addMessage($message_a, $type_a);
+    $this->messenger->addMessage($message_a, $type_a, TRUE);
+    $this->messenger->addMessage($message_b, $type_b, TRUE);
+    $this->assertEquals([
+      $type_a => [$message_a, $message_a],
+      $type_b => [$message_b],
+    ], $this->messenger->getMessages());
+
+    // Test deleting messages of a certain type.
+    $this->assertEquals($this->messenger->deleteMessagesByType($type_a), $this->messenger);
+    $this->assertEquals([
+      $type_b => [$message_b],
+    ], $this->messenger->getMessages());
+
+    // Test deleting all messages.
+    $this->assertEquals($this->messenger->deleteMessages(), $this->messenger);
+    $this->assertEquals([], $this->messenger->getMessages());
+  }
+
+}