diff --git a/core/authorize.php b/core/authorize.php
index 1138c92..0f6dcf5 100644
--- a/core/authorize.php
+++ b/core/authorize.php
@@ -126,8 +126,16 @@ function authorize_access_allowed(Request $request) {
     }
     else {
       $links = array_merge($links, array(
-        \Drupal::l(t('Administration pages'), new Url('system.admin')),
-        \Drupal::l(t('Front page'), new Url('<front>')),
+        array(
+          '#type' => 'link',
+          '#url' => new Url('system.admin'),
+          '#title' => t('Administration pages'),
+        ),
+        array(
+          '#type' => 'link',
+          '#url' => new Url('<front>'),
+          '#title' => t('Front page'),
+        ),
       ));
     }
 
diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 7e311d9..4f5c752 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -1747,17 +1747,10 @@ function drupal_common_theme() {
     'maintenance_task_list' => array(
       'variables' => array('items' => NULL, 'active' => NULL,  'variant' => NULL),
     ),
-    'authorize_message' => array(
-      'variables' => array('message' => NULL, 'success' => TRUE),
-      'function' => 'theme_authorize_message',
-      'path' => 'core/includes',
-      'file' => 'theme.maintenance.inc',
-    ),
     'authorize_report' => array(
-      'variables' => array('messages' => array()),
-      'function' => 'theme_authorize_report',
-      'path' => 'core/includes',
-      'file' => 'theme.maintenance.inc',
+      'variables' => ['messages' => [], 'report' => [], 'attributes' => []],
+      'includes' => ['core/includes/theme.maintenance.inc'],
+      'template' => 'authorize-report',
     ),
     // From pager.inc.
     'pager' => array(
diff --git a/core/includes/theme.maintenance.inc b/core/includes/theme.maintenance.inc
index d23addb..68aff41 100644
--- a/core/includes/theme.maintenance.inc
+++ b/core/includes/theme.maintenance.inc
@@ -100,60 +100,36 @@ function _drupal_maintenance_theme() {
 }
 
 /**
- * Returns HTML for a results report of an operation run by authorize.php.
+ * Prepares variables for authorize.php operation report templates.
  *
- * @param $variables
+ * This report displays the results of an operation run via authorize.php.
+ *
+ * Default template: authorize-report.html.twig.
+ *
+ * @param array $variables
  *   An associative array containing:
  *   - messages: An array of result messages.
- *
- * @ingroup themeable
  */
-function theme_authorize_report($variables) {
+function template_preprocess_authorize_report(&$variables) {
   $messages = $variables['messages'];
-  $output = '';
   if (!empty($messages)) {
-    $output .= '<div class="authorize-results">';
     foreach ($messages as $heading => $logs) {
-      $items = array();
+      $items = [];
       foreach ($logs as $number => $log_message) {
         if ($number === '#abort') {
           continue;
         }
-        $authorize_message = array(
-          '#theme' => 'authorize_message',
-          '#message' => $log_message['message'],
-          '#success' => $log_message['success'],
-        );
-        $items[] = array(
-          '#markup' => drupal_render($authorize_message),
-          '#wrapper_attributes' => array('class' => $log_message['success'] ? 'authorize-results__success' : 'authorize-results__failure'),
-        );
+        $class = 'authorize-results__' . ($log_message['success'] ? 'success' : 'failure');
+        $items[] = [
+          '#wrapper_attributes' => ['class' => [$class]],
+          '#markup' => $log_message['message'],
+        ];
       }
-      $item_list = array(
+      $variables['report'][] = [
         '#theme' => 'item_list',
         '#items' => $items,
         '#title' => $heading,
-      );
-      $output .= drupal_render($item_list);
+      ];
     }
-    $output .= '</div>';
   }
-  return $output;
-}
-
-/**
- * Returns HTML for a single log message from the authorize.php batch operation.
- *
- * @param $variables
- *   An associative array containing:
- *   - message: The log message.
- *     It's the caller's responsibility to ensure this string contains no
- *     dangerous HTML such as SCRIPT tags.
- *   - success: A boolean indicating failure or success.
- *
- * @ingroup themeable
- */
-function theme_authorize_message($variables) {
-  $item = array('#markup' => $variables['message']);
-  return drupal_render($item);
 }
diff --git a/core/lib/Drupal/Core/Theme/Registry.php b/core/lib/Drupal/Core/Theme/Registry.php
index bb89707..d24802d 100644
--- a/core/lib/Drupal/Core/Theme/Registry.php
+++ b/core/lib/Drupal/Core/Theme/Registry.php
@@ -442,6 +442,13 @@ protected function processExtension(array &$cache, $name, $type, $theme, $path)
           $result[$hook]['includes'] = $cache[$hook]['includes'];
         }
 
+        // Load the includes, as they may contain preprocess functions.
+        if (isset($info['includes'])) {
+          foreach ($info['includes'] as $include_file) {
+            include_once $this->root . '/' . $include_file;
+          }
+        }
+
         // If the theme implementation defines a file, then also use the path
         // that it defined. Otherwise use the default path. This allows
         // system.module to declare theme functions on behalf of core .include
diff --git a/core/lib/Drupal/Core/Updater/Module.php b/core/lib/Drupal/Core/Updater/Module.php
index c495272..ae7bea8 100644
--- a/core/lib/Drupal/Core/Updater/Module.php
+++ b/core/lib/Drupal/Core/Updater/Module.php
@@ -108,11 +108,31 @@ public function getSchemaUpdates() {
    * Overrides Drupal\Core\Updater\Updater::postInstallTasks().
    */
   public function postInstallTasks() {
-    return array(
-      \Drupal::l(t('Install another module'), new Url('update.module_install')),
-      \Drupal::l(t('Enable newly added modules'), new Url('system.modules_list')),
-      \Drupal::l(t('Administration pages'), new Url('system.admin')),
-    );
+    // Since this is being called outsite of the primary front controller,
+    // the base_url needs to be set explicitly to ensure that links are
+    // relative to the site root.
+    // @todo Simplify with https://www.drupal.org/node/2548095
+    $default_options = [
+      '#type' => 'link',
+      '#options' => [
+        'absolute' => TRUE,
+        'base_url' => $GLOBALS['base_url'],
+      ],
+    ];
+    return [
+      $default_options + [
+        '#url' => new Url('update.module_install'),
+        '#title' => t('Install another module'),
+      ],
+      $default_options + [
+        '#url' => new Url('system.modules_list'),
+        '#title' => t('Enable newly added modules'),
+      ],
+      $default_options + [
+        '#url' => new Url('system.admin'),
+        '#title' => t('Administration pages'),
+      ],
+    ];
   }
 
   /**
diff --git a/core/modules/system/templates/authorize-report.html.twig b/core/modules/system/templates/authorize-report.html.twig
new file mode 100644
index 0000000..95c0809
--- /dev/null
+++ b/core/modules/system/templates/authorize-report.html.twig
@@ -0,0 +1,23 @@
+{#
+/**
+ * @file
+ * Default theme implementation for authorize.php operation report templates.
+ *
+ * This report displays the results of an operation run via authorize.php.
+ *
+ * Available variables:
+ * - report: A list of result messages.
+ * - attributes: HTML attributes for the element.
+ *
+ * @see template_preprocess_authorize_report()
+ *
+ * @ingroup themeable
+ */
+#}
+{% if report %}
+  <div{{ attributes.addClass('authorize-results') }}>
+    {% for messages in report %}
+      {{ messages }}
+    {% endfor %}
+  </div>
+{% endif %}
