diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 0a04480eba9cc3bde83bc386133f31a9182c06ec..4ebe08a20daf077d93ef1688af527429213c06cf 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -2350,11 +2350,7 @@ function theme_get_suggestions($args, $base, $delimiter = '__') {
  * @see system_page_build()
  */
 function template_preprocess_maintenance_page(&$variables) {
-  global $theme;
   $language_interface = language(Language::TYPE_INTERFACE);
-  // Retrieve the theme data to list all available regions.
-  $theme_data = list_themes();
-  $regions = $theme_data[$theme]->info['regions'];
 
   // Initializes attributes which are specific to the html element.
   $variables['html_attributes'] = new Attribute;
@@ -2375,11 +2371,14 @@ function template_preprocess_maintenance_page(&$variables) {
     drupal_render($build);
   }
 
-  // Get all region content set with drupal_add_region_content().
-  foreach (array_keys($regions) as $region) {
-    // Assign region to a region variable.
-    $region_content = drupal_get_region_content($region);
-    isset($variables[$region]) ? $variables[$region] .= $region_content : $variables[$region] = $region_content;
+  foreach (system_region_list($GLOBALS['theme']) as $region_key => $region_name) {
+    if (!isset($variables[$region_key])) {
+      $variables[$region_key] = array();
+    }
+    // Append region content set with drupal_add_region_content() as markup.
+    if ($region_content = drupal_get_region_content($region_key)) {
+      $variables[$region_key][]['#markup'] = $region_content;
+    }
   }
 
   // Setup layout variable.
diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/RenderElementTypesTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/RenderElementTypesTest.php
index 9ba4bf4091feb17ce1f2fe91737cc49ed1cbc323..4b22a2929098d8baf325dcbb0b1594afc479acad 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Common/RenderElementTypesTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Common/RenderElementTypesTest.php
@@ -7,6 +7,11 @@
 
 namespace Drupal\system\Tests\Common;
 
+use Drupal\Component\Utility\String;
+use Drupal\Component\Utility\Url;
+use Drupal\Component\Utility\Xss;
+use Drupal\Core\Language\Language;
+use Drupal\Core\Template\Attribute;
 use Drupal\simpletest\WebTestBase;
 
 /**
@@ -34,7 +39,22 @@ public static function getInfo() {
    */
   function assertElements($elements) {
     foreach($elements as $element) {
-      $this->assertIdentical(drupal_render($element['value']), $element['expected'], '"' . $element['name'] . '" input rendered correctly by drupal_render().');
+      // More complicated "expected" strings may contain placeholders.
+      if (!empty($element['placeholders'])) {
+        $element['expected'] = String::format($element['expected'], $element['placeholders']);
+      }
+
+      // We don't care about whitespace for the sake of comparing markup.
+      $value = new \DOMDocument();
+      $value->preserveWhiteSpace = FALSE;
+      $value->loadXML(drupal_render($element['value']));
+
+      $expected = new \DOMDocument();
+      $expected->preserveWhiteSpace = FALSE;
+      $expected->loadXML($element['expected']);
+
+      $message = isset($element['name']) ? '"' . $element['name'] . '" input rendered correctly by drupal_render().' : NULL;
+      $this->assertIdentical($value->saveXML(), $expected->saveXML(), $message);
     }
   }
 
@@ -113,4 +133,125 @@ function testHtmlTag() {
     $this->assertElements($elements);
   }
 
+  /**
+   * Tests common #theme 'maintenance_page'.
+   */
+  function testMaintenancePage() {
+    // We need to simulate a lot of what would happen in the preprocess, or
+    // there's no way to make these tests portable.
+
+    // HTML element attributes.
+    $html_attributes = new Attribute;
+    $language_interface = \Drupal::service('language_manager')->getCurrentLanguage();
+    $html_attributes['lang'] = $language_interface->id;
+    $html_attributes['dir'] = $language_interface->direction ? 'rtl' : 'ltr';
+
+    $site_config = \Drupal::config('system.site');
+    $site_name = $site_config->get('name');
+    $site_slogan = $site_config->get('slogan');
+    if ($title = drupal_get_title()) {
+      $head_title = array(
+        'title' => strip_tags($title),
+        'name' => String::checkPlain($site_config->get('name')),
+      );
+    }
+    else {
+      $head_title = array('name' => String::checkPlain($site_name));
+      if ($site_slogan) {
+        $head_title['slogan'] = strip_tags(Xss::filterAdmin($site_slogan));
+      }
+    }
+    $head_title = implode(' | ', $head_title);
+
+    // Add favicon.
+    $favicon = theme_get_setting('favicon.url');
+    $type = theme_get_setting('favicon.mimetype');
+    drupal_add_html_head_link(array('rel' => 'shortcut icon', 'href' => Url::stripDangerousProtocols($favicon), 'type' => $type));
+
+    // Build CSS links.
+    drupal_static_reset('_drupal_add_css');
+    $path = drupal_get_path('module', 'system');
+    $default_css = array(
+      '#attached' => array(
+        'css' => array(
+          $path . '/css/system.module.css',
+          $path . '/css/system.admin.css',
+          $path . '/css/system.maintenance.css',
+          $path . '/css/system.theme.css',
+        ),
+      ),
+    );
+    drupal_render($default_css);
+    $css = _drupal_add_css();
+
+    // Simulate the expected output of a "vanilla" maintenance page.
+    $expected = <<<EOT
+<!DOCTYPE html>
+<html!html_attributes>
+  <head>
+    !head
+    <title>!head_title</title>
+    !styles
+    !scripts
+  </head>
+  <body class="!attributes.class">
+    <div class="l-container">
+      <header role="banner">
+        <a href="!front_page" title="Home" rel="home">
+          <img src="!logo" alt="Home"/>
+        </a>
+        <div class="name-and-slogan">
+          <h1 class="site-name">
+            <a href="!front_page" title="Home" rel="home">!site_name</a>
+          </h1>
+        </div>
+      </header>
+      <main role="main">
+        !title
+        !content
+      </main>
+    </div>
+  </body>
+</html>
+EOT;
+
+    $placeholders = array(
+      '!html_attributes' => $html_attributes->__toString(),
+      '!head' => drupal_get_html_head(),
+      '!head_title' => $head_title,
+      '!styles' => drupal_get_css($css),
+      '!scripts' => drupal_get_js(),
+      '!attributes.class' => 'maintenance-page in-maintenance no-sidebars',
+      '!front_page' => url(),
+      '!logo' => theme_get_setting('logo.url'),
+      '!site_name' => $site_config->get('name'),
+      '!title' => $title ? '<h1>' . $title . '</h1>' : '',
+      '!content' => '<span>foo</span>',
+    );
+
+    // We have to reset drupal_add_css between each test.
+    drupal_static_reset('_drupal_add_css');
+
+    // Test basic string for maintenance page content.
+    $elements = array(
+      array(
+        'name' => "#theme 'maintenance_page' with content of <span>foo</span>",
+        'value' => array(
+          '#theme' => 'maintenance_page',
+          '#content' => '<span>foo</span>',
+          '#show_messages' => FALSE,
+        ),
+        'expected' => $expected,
+        'placeholders' => $placeholders,
+      ),
+    );
+    $this->assertElements($elements);
+
+    // Test render array for maintenance page content.
+    drupal_static_reset('_drupal_add_css');
+    $elements[0]['name'] = "#theme 'maintenance_page' with content as a render array";
+    $elements[0]['value']['#content'] = array('#markup' => '<span>foo</span>');
+    $this->assertElements($elements);
+  }
+
 }