diff --git a/core/core.services.yml b/core/core.services.yml
index 7007138..bc84f56 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -316,6 +316,11 @@ services:
     tags:
       - { name: paramconverter }
     arguments: ['@entity.manager']
+  route_subscriber.module:
+    class: Drupal\Core\EventSubscriber\ModuleRouteSubscriber
+    tags:
+      - { name: event_subscriber }
+    arguments: ['@module_handler']
   route_subscriber.entity:
     class: Drupal\Core\EventSubscriber\EntityRouteAlterSubscriber
     tags:
diff --git a/core/lib/Drupal/Core/EventSubscriber/ModuleRouteSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/ModuleRouteSubscriber.php
new file mode 100644
index 0000000..5bb903e
--- /dev/null
+++ b/core/lib/Drupal/Core/EventSubscriber/ModuleRouteSubscriber.php
@@ -0,0 +1,98 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\EventSubscriber\ModuleRouteSubscriber.
+ */
+
+namespace Drupal\Core\EventSubscriber;
+
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Routing\RouteBuildEvent;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Drupal\Core\Routing\RoutingEvents;
+
+/**
+ * A route subscriber to remove routes that depend on modules being enabled.
+ */
+class ModuleRouteSubscriber implements EventSubscriberInterface {
+
+  /**
+   * The module handler.
+   *
+   * @var \Drupal\Core\Extension\ModuleHandlerInterface
+   */
+  protected $moduleHandler;
+
+  /**
+   * Constructs a ModuleRouteSubscriber object.
+   *
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler.
+   */
+  public function __construct(ModuleHandlerInterface $module_handler) {
+    $this->moduleHandler = $module_handler;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getSubscribedEvents() {
+    $events[RoutingEvents::ALTER] = 'removeRoutes';
+    return $events;
+  }
+
+  /**
+   * Removes any routes that have an unmet module dependency.
+   *
+   * @param \Drupal\Core\Routing\RouteBuildEvent $event
+   *   The route building event.
+   */
+  public function removeRoutes(RouteBuildEvent $event) {
+    $collection = $event->getRouteCollection();
+
+    foreach ($collection as $name => $route) {
+      if ($route->hasRequirement('_module_dependencies')) {
+        $modules = $route->getRequirement('_module_dependencies');
+
+        $explode_and = $this->explodeString($modules, '+');
+        if (count($explode_and) > 1) {
+          foreach ($explode_and as $module) {
+            // If any moduleExists() call returns FALSE, remove the route and
+            // move on to the next.
+            if (!$this->moduleHandler->moduleExists($module)) {
+              $collection->remove($name);
+              continue 2;
+            }
+          }
+        }
+        else {
+          // OR condition, exploding on ',' character.
+          foreach ($this->explodeString($modules, ',') as $module) {
+            if ($this->moduleHandler->moduleExists($module)) {
+              continue 2;
+            }
+          }
+          // If no modules are found, and we get this far, remove the route.
+          $collection->remove($name);
+        }
+      }
+    }
+  }
+
+  /**
+   * Explodes a string based on a separator.
+   *
+   * @param string $string
+   *   The string to explode.
+   * @param string $separator
+   *   The string separator to explode with.
+   *
+   * @return array
+   *   An array of exploded (and trimmed) values.
+   */
+  protected function explodeString($string, $separator = ',') {
+    return array_filter(array_map('trim', explode($separator, $string)));
+  }
+
+}
diff --git a/core/modules/dblog/dblog.routing.yml b/core/modules/dblog/dblog.routing.yml
index 31f1b1c..a0deb7c 100644
--- a/core/modules/dblog/dblog.routing.yml
+++ b/core/modules/dblog/dblog.routing.yml
@@ -27,3 +27,12 @@ dblog.access_denied:
     _content: '\Drupal\dblog\Controller\DbLogController::accessDenied'
   requirements:
     _permission: 'access site reports'
+
+dblog.search:
+  path: '/admin/reports/search'
+  defaults:
+    _content: '\Drupal\dblog\Controller\DbLogController::search'
+    _title: 'Top search phrases'
+  requirements:
+    _module_dependencies: 'search'
+    _permission: 'access site reports'
diff --git a/core/modules/dblog/dblog.services.yml b/core/modules/dblog/dblog.services.yml
deleted file mode 100644
index 815734c..0000000
--- a/core/modules/dblog/dblog.services.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-services:
-  dblog.route_subscriber:
-    class: Drupal\dblog\Routing\RouteSubscriber
-    arguments: ['@module_handler']
-    tags:
-      - { name: event_subscriber}
diff --git a/core/modules/dblog/lib/Drupal/dblog/Routing/RouteSubscriber.php b/core/modules/dblog/lib/Drupal/dblog/Routing/RouteSubscriber.php
deleted file mode 100644
index f04492e..0000000
--- a/core/modules/dblog/lib/Drupal/dblog/Routing/RouteSubscriber.php
+++ /dev/null
@@ -1,73 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\dblog\Routing\RouteSubscriber.
- */
-
-namespace Drupal\dblog\Routing;
-
-use Drupal\Core\Extension\ModuleHandlerInterface;
-use Drupal\Core\Routing\RouteBuildEvent;
-use Drupal\Core\Routing\RoutingEvents;
-use Symfony\Component\EventDispatcher\EventSubscriberInterface;
-use Symfony\Component\Routing\Route;
-
-/**
- * Provides dynamic routes for dblog.
- */
-class RouteSubscriber implements EventSubscriberInterface {
-
-  /**
-   * The module handler.
-   *
-   * @var \Drupal\Core\Extension\ModuleHandlerInterface
-   */
-  protected $moduleHandler;
-
-  /**
-   * Creates a new RouteSubscriber.
-   *
-   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
-   *   The module handler.
-   */
-  public function __construct(ModuleHandlerInterface $module_handler) {
-    $this->moduleHandler = $module_handler;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getSubscribedEvents() {
-    $events[RoutingEvents::DYNAMIC] = 'routes';
-    return $events;
-  }
-
-  /**
-   * Generate dynamic routes for various dblog pages.
-   *
-   * @param \Drupal\Core\Routing\RouteBuildEvent $event
-   *   The route building event.
-   *
-   * @return \Symfony\Component\Routing\RouteCollection
-   *   The route collection that contains the new dynamic route.
-   */
-  public function routes(RouteBuildEvent $event) {
-    $collection = $event->getRouteCollection();
-    if ($this->moduleHandler->moduleExists('search')) {
-      // The block entity listing page.
-      $route = new Route(
-        'admin/reports/search',
-        array(
-          '_content' => '\Drupal\dblog\Controller\DbLogController::search',
-          '_title' => 'Top search phrases',
-        ),
-        array(
-          '_permission' => 'access site reports',
-        )
-      );
-      $collection->add('dblog.search', $route);
-    }
-  }
-
-}
diff --git a/core/tests/Drupal/Tests/Core/EventSubscriber/ModuleRouteSubscriberTest.php b/core/tests/Drupal/Tests/Core/EventSubscriber/ModuleRouteSubscriberTest.php
new file mode 100644
index 0000000..aea9434
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/EventSubscriber/ModuleRouteSubscriberTest.php
@@ -0,0 +1,100 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Core\EventSubscriber\ModuleRouteSubscriberTest.
+ */
+
+namespace Drupal\Tests\Core\EventSubscriber;
+
+use Drupal\Core\Routing\RouteBuildEvent;
+use Drupal\Tests\UnitTestCase;
+use Drupal\Core\EventSubscriber\ModuleRouteSubscriber;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\Route;
+
+/**
+ * Tests the ModuleRouteSubscriber class.
+ *
+ * @group Drupal
+ *
+ * @see \Drupal\Core\EventSubscriber\ModuleRouteSubscriber
+ */
+class ModuleRouteSubscriberTest extends UnitTestCase {
+
+  /**
+   * The mock module handler.
+   *
+   * @var Drupal\Core\Extension\ModuleHandlerInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $moduleHandler;
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Module route subscriber',
+      'description' => 'Unit test the \Drupal\Core\EventSubscriber\ModuleRouteSubscriber class.',
+      'group' => 'System'
+    );
+  }
+
+  public function setUp() {
+    $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
+
+    $value_map = array(
+      array('enabled', TRUE),
+      array('disabled', FALSE),
+    );
+
+    $this->moduleHandler->expects($this->any())
+      ->method('moduleExists')
+      ->will($this->returnValueMap($value_map));
+  }
+
+  /**
+   * Tests that removeRoute() removes routes when the module is not enabled.
+   *
+   * @dataProvider testRemoveRouteProvider
+   *
+   * @param string $route_name
+   *   The machine name for the route.
+   * @param array $requirements
+   *   An array of requirements to use for the route.
+   * @param bool $removed
+   *   Whether or not the route is expected to be removed from the collection.
+   */
+  public function testRemoveRoute($route_name, array $requirements, $removed) {
+    $collection = new RouteCollection();
+    $route = new Route('', array(), $requirements);
+    $collection->add($route_name, $route);
+
+    $event = new RouteBuildEvent($collection, 'test');
+    $route_subscriber = new ModuleRouteSubscriber($this->moduleHandler);
+    $route_subscriber->removeRoutes($event);
+
+    if ($removed) {
+      $this->assertNull($collection->get($route_name));
+    }
+    else {
+      $this->assertInstanceOf('Symfony\Component\Routing\Route', $collection->get($route_name));
+    }
+  }
+
+  /**
+   * Data provider for testRemoveRoute().
+   */
+  public function testRemoveRouteProvider() {
+    return array(
+      array('enabled', array('_module_dependencies' => 'enabled'), FALSE),
+      array('disabled', array('_module_dependencies' => 'disabled'), TRUE),
+      array('enabled_or',  array('_module_dependencies' => 'disabled,enabled'), FALSE),
+      array('enabled_or',  array('_module_dependencies' => 'enabled,disabled'), FALSE),
+      array('disabled_or',  array('_module_dependencies' => 'disabled,disabled'), TRUE),
+      array('enabled_and',  array('_module_dependencies' => 'enabled+enabled'), FALSE),
+      array('enabled_and',  array('_module_dependencies' => 'enabled+disabled'), TRUE),
+      array('enabled_and',  array('_module_dependencies' => 'disabled+enabled'), TRUE),
+      array('disabled_and',  array('_module_dependencies' => 'disabled+disabled'), TRUE),
+      array('no_dependencies', array(), FALSE),
+    );
+  }
+
+}
