diff --git a/core/core.services.yml b/core/core.services.yml
index 65882af..018913c 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -409,6 +409,10 @@ services:
     arguments: ['@entity.manager']
     tags:
       - { name: access_check }
+  access_check.theme:
+    class: Drupal\Core\Theme\ThemeAccessCheck
+    tags:
+      - { name: access_check }
   maintenance_mode_subscriber:
     class: Drupal\Core\EventSubscriber\MaintenanceModeSubscriber
     tags:
diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 87b3b18..adaada3 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -70,15 +70,14 @@
  * @return
  *   Boolean TRUE if the theme is enabled or is the site administration theme;
  *   FALSE otherwise.
+ *
+ * @deprecated Use \Drupal::service('access_check.theme')->checkAccess().
  */
 function drupal_theme_access($theme) {
   if (is_object($theme)) {
-    return !empty($theme->status);
-  }
-  else {
-    $themes = list_themes();
-    return !empty($themes[$theme]->status);
+    $theme = $theme->name;
   }
+  return Drupal::service('access_check.theme')->checkAccess($theme);
 }
 
 /**
diff --git a/core/lib/Drupal/Core/Theme/ThemeAccessCheck.php b/core/lib/Drupal/Core/Theme/ThemeAccessCheck.php
new file mode 100644
index 0000000..90e4a79
--- /dev/null
+++ b/core/lib/Drupal/Core/Theme/ThemeAccessCheck.php
@@ -0,0 +1,47 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Theme\ThemeAccessCheck.
+ */
+
+namespace Drupal\Core\Theme;
+
+use Drupal\Core\Access\StaticAccessCheckInterface;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Routing\Route;
+
+/**
+ * Access check for a theme.
+ */
+class ThemeAccessCheck implements StaticAccessCheckInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function appliesTo() {
+    return array('_access_theme');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function access(Route $route, Request $request) {
+    return $this->checkAccess($request->attributes->get('theme')) ? static::ALLOW : static::DENY;
+  }
+
+  /**
+   * Checks access to a theme.
+   *
+   * @param string $theme
+   *   The name of a theme.
+   *
+   * @return bool
+   *   TRUE if the theme is enabled, FALSE otherwise.
+   */
+  public function checkAccess($theme) {
+    $themes = list_themes();
+    return !empty($themes[$theme]->status);
+  }
+
+}
diff --git a/core/modules/block/block.admin.inc b/core/modules/block/block.admin.inc
deleted file mode 100644
index 0f6ea1e..0000000
--- a/core/modules/block/block.admin.inc
+++ /dev/null
@@ -1,25 +0,0 @@
-<?php
-
-/**
- * @file
- * Admin page callbacks for the block module.
- */
-
-use Drupal\block\Entity\Block;
-use Drupal\Core\Template\Attribute;
-
-/**
- * Page callback: Attaches CSS for the block region demo.
- *
- * @see block_menu()
- */
-function block_admin_demo($theme = NULL) {
-  return array(
-    '#attached' => array(
-      'library' => array(
-        array('block', 'drupal.block.admin'),
-      ),
-    ),
-  );
-}
-
diff --git a/core/modules/block/block.module b/core/modules/block/block.module
index 2bfb799..6641134 100644
--- a/core/modules/block/block.module
+++ b/core/modules/block/block.module
@@ -151,16 +151,13 @@ function block_menu() {
       'type' => $key == $default_theme ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
       'route_name' => "block_admin_display.$key",
     );
-    $items["admin/structure/block/demo/$key"] = array(
-      'title' => check_plain($theme->info['name']),
-      'page callback' => 'block_admin_demo',
-      'page arguments' => array($key),
+  }
+  if (isset($theme)) {
+    $items['admin/structure/block/demo/%'] = array(
+      'route_name' => 'block_admin_demo',
       'type' => MENU_CALLBACK,
-      'access callback' => '_block_themes_access',
-      'access arguments' => array($key),
       'theme callback' => '_block_custom_theme',
-      'theme arguments' => array($key),
-      'file' => 'block.admin.inc',
+      'theme arguments' => array(4),
     );
   }
   return $items;
@@ -171,7 +168,6 @@ function block_menu() {
  *
  * Path:
  * - admin/structure/block/list/% (for each theme)
- * - admin/structure/block/demo/% (for each theme)
  *
  * @param $theme
  *   Either the name of a theme or a full theme object.
@@ -214,9 +210,10 @@ function block_page_build(&$page) {
 
   // Fetch a list of regions for the current theme.
   $all_regions = system_region_list($theme);
-
   $item = menu_get_item();
-  if ($item['path'] != 'admin/structure/block/demo/' . $theme) {
+  // Make sure the blocks are not getting rendered for demo page
+  // or theme specific site building page.
+  if ($item['path'] != 'admin/structure/block/demo/%' || !isset($item['map'][4]) || $item['map'][4] != $theme) {
     // Load all region content assigned via blocks.
     foreach (array_keys($all_regions) as $region) {
       // Assign blocks to region.
diff --git a/core/modules/block/block.routing.yml b/core/modules/block/block.routing.yml
index a2ca6e5..06eff70 100644
--- a/core/modules/block/block.routing.yml
+++ b/core/modules/block/block.routing.yml
@@ -1,3 +1,13 @@
+block_admin_demo:
+  pattern: '/admin/structure/block/demo/{theme}'
+  defaults:
+    _content: '\Drupal\block\Controller\AdminController::demo'
+  options:
+    _access_mode: 'ALL'
+  requirements:
+    _access_theme: 'TRUE'
+    _permission: 'administer blocks'
+
 block_admin_block_delete:
   pattern: '/admin/structure/block/manage/{block}/delete'
   defaults:
diff --git a/core/modules/block/block.services.yml b/core/modules/block/block.services.yml
index b361dba..d02c2af 100644
--- a/core/modules/block/block.services.yml
+++ b/core/modules/block/block.services.yml
@@ -13,7 +13,3 @@ services:
     class: Drupal\block\Routing\RouteSubscriber
     tags:
       - { name: event_subscriber}
-  block.theme_access_check:
-    class: Drupal\block\Access\BlockThemeAccessCheck
-    tags:
-      - { name: access_check}
diff --git a/core/modules/block/lib/Drupal/block/Access/BlockThemeAccessCheck.php b/core/modules/block/lib/Drupal/block/Access/BlockThemeAccessCheck.php
deleted file mode 100644
index 97b53d4..0000000
--- a/core/modules/block/lib/Drupal/block/Access/BlockThemeAccessCheck.php
+++ /dev/null
@@ -1,34 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\block\Access\BlockThemeAccessCheck.
- */
-
-namespace Drupal\block\Access;
-
-use Drupal\Core\Access\StaticAccessCheckInterface;
-use Symfony\Component\Routing\Route;
-use Symfony\Component\HttpFoundation\Request;
-
-/**
- * Checks access for displaying block page.
- */
-class BlockThemeAccessCheck implements StaticAccessCheckInterface {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function appliesTo() {
-    return array('_block_themes_access');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function access(Route $route, Request $request) {
-    $theme = $request->attributes->get('theme');
-    return (user_access('administer blocks') && drupal_theme_access($theme)) ? static::ALLOW : static::DENY;
-  }
-
-}
diff --git a/core/modules/block/lib/Drupal/block/Controller/AdminController.php b/core/modules/block/lib/Drupal/block/Controller/AdminController.php
new file mode 100644
index 0000000..e9ae9e2
--- /dev/null
+++ b/core/modules/block/lib/Drupal/block/Controller/AdminController.php
@@ -0,0 +1,39 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\block\Controller\AdminController.
+ */
+
+namespace Drupal\block\Controller;
+
+use Drupal\Core\Controller\ControllerBase;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Controller routines for admin block routes.
+ */
+class AdminController extends ControllerBase {
+
+  /**
+   * Returns a block theme demo page.
+   *
+   * @param string $theme
+   *   THe name of the theme.
+   *
+   * @return array
+   *   A render array containing the CSS and title for the block region demo.
+   */
+  public function demo($theme) {
+    $themes = list_themes();
+    return array(
+      '#title' => $this->t($themes[$theme]->info['name']),
+      '#attached' => array(
+        'library' => array(
+          array('block', 'drupal.block.admin'),
+        ),
+      ),
+    );
+  }
+
+}
diff --git a/core/modules/block/lib/Drupal/block/Routing/RouteSubscriber.php b/core/modules/block/lib/Drupal/block/Routing/RouteSubscriber.php
index 576ea80..8abc3c4 100644
--- a/core/modules/block/lib/Drupal/block/Routing/RouteSubscriber.php
+++ b/core/modules/block/lib/Drupal/block/Routing/RouteSubscriber.php
@@ -46,7 +46,11 @@ public function routes(RouteBuildEvent $event) {
           'theme' => $key,
         ),
         array(
-          '_block_themes_access' => 'TRUE',
+          '_access_theme' => 'TRUE',
+          '_permission' => 'administer blocks',
+        ),
+        array(
+          '_access_mode' => 'ALL',
         )
       );
       $collection->add("block_admin_display.$key", $route);
