diff --git a/core/lib/Drupal/Core/Routing/RouteBuildEvent.php b/core/lib/Drupal/Core/Routing/RouteBuildEvent.php
index 502318d..0aa0072 100644
--- a/core/lib/Drupal/Core/Routing/RouteBuildEvent.php
+++ b/core/lib/Drupal/Core/Routing/RouteBuildEvent.php
@@ -30,15 +30,33 @@ class RouteBuildEvent extends Event {
   protected $provider;
 
   /**
+   * The route collection for conditional routes.
+   *
+   * @var \Symfony\Component\Routing\RouteCollection
+   */
+  protected $conditionalRouteCollection;
+
+  /**
    * Constructs a RouteBuildEvent object.
+   *
+   * @param \Symfony\Component\Routing\RouteCollection $route_collection
+   *   The route collection.
+   * @param string $provider
+   *   The provider of this route collection.
+   * @param \Symfony\Component\Routing\RouteCollection $conditional_route_collection
+   *   The route collection for conditional routes.
    */
-  public function __construct(RouteCollection $route_collection, $provider) {
+  public function __construct(RouteCollection $route_collection, $provider, RouteCollection $conditional_route_collection = NULL) {
     $this->routeCollection = $route_collection;
     $this->provider = $provider;
+    $this->conditionalRouteCollection = $conditional_route_collection;
   }
 
   /**
    * Gets the route collection.
+   *
+   * @return \Symfony\Component\Routing\RouteCollection
+   *   The route collection.
    */
   public function getRouteCollection() {
     return $this->routeCollection;
@@ -46,9 +64,22 @@ public function getRouteCollection() {
 
   /**
    * Gets the provider for this route collection.
+   *
+   * @return string
+   *   The provider for this route collection.
    */
   public function getProvider() {
     return $this->provider;
   }
 
+  /**
+   * Gets the route collection for conditional routes.
+   *
+   * @return \Symfony\Component\Routing\RouteCollection
+   *   The route collection for conditional routes.
+   */
+  public function getConditionalRouteCollection() {
+    return $this->conditionalRouteCollection;
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Routing/RouteBuilder.php b/core/lib/Drupal/Core/Routing/RouteBuilder.php
index eebe414..7a19131 100644
--- a/core/lib/Drupal/Core/Routing/RouteBuilder.php
+++ b/core/lib/Drupal/Core/Routing/RouteBuilder.php
@@ -27,6 +27,15 @@
 class RouteBuilder implements RouteBuilderInterface {
 
   /**
+   * The recursion limit for nested conditional routes.
+   *
+   * @see \Drupal\Core\Routing\RouteBuilder::rebuild()
+   *
+   * @var int
+   */
+  const CONDITIONAL_ROUTES_RECURSION_LIMIT = 10;
+
+  /**
    * The dumper to which we should send collected routes.
    *
    * @var \Symfony\Component\Routing\Matcher\Dumper\MatcherDumperInterface
@@ -103,8 +112,10 @@ public function rebuild() {
       return FALSE;
     }
 
-    $yaml_discovery = $this->getYamlDiscovery();
+    // Conditional routes are all collected into a single route collection.
+    $conditional_collection = new RouteCollection();
 
+    $yaml_discovery = $this->getYamlDiscovery();
     foreach ($yaml_discovery->findAll() as $provider => $routes) {
       $collection = new RouteCollection();
 
@@ -144,17 +155,34 @@ public function rebuild() {
         $collection->add($name, $route);
       }
 
+      // Allow route subscribers to alter the given routes and to add additional
+      // routes conditionally based on the given routes.
       $this->dispatcher->dispatch(RoutingEvents::ALTER, new RouteBuildEvent($collection, $provider));
+      $this->dispatcher->dispatch(RoutingEvents::CONDITIONAL, new RouteBuildEvent($collection, $provider, $conditional_collection));
       $this->dumper->addRoutes($collection);
       $this->dumper->dump(array('provider' => $provider));
     }
 
-    // Now allow modules to register additional, dynamic routes.
-    // @todo Either remove this alter or the per-provider alter.
-    $collection = new RouteCollection();
-    $this->dispatcher->dispatch(RoutingEvents::ALTER, new RouteBuildEvent($collection, 'dynamic_routes'));
-    $this->dumper->addRoutes($collection);
-    $this->dumper->dump(array('provider' => 'dynamic_routes'));
+    // The following can only recurse infinitely if, for example, subscriber A
+    // adds conditional routes, then subscriber B adds conditional routes based
+    // on those conditional routes from subscriber A, then subscriber A adds
+    // conditional routes based on the conditional routes from subscriber B,
+    // etc. Because it is difficult to recover the site if route rebuilding
+    // continually fails, we provide a safeguard for that.
+    $iteration = 0;
+    do {
+      ++$iteration;
+      $collection = $conditional_collection;
+      $conditional_collection = new RouteCollection();
+
+      // Allow the conditional routes to be altered as well.
+      $this->dispatcher->dispatch(RoutingEvents::ALTER, new RouteBuildEvent($collection, 'conditional_routes'));
+      // Route subscribers may want to add further conditional routes based on
+      // other conditional routes.
+      $this->dispatcher->dispatch(RoutingEvents::CONDITIONAL, new RouteBuildEvent($collection, 'conditional_routes', $conditional_collection));
+      $this->dumper->addRoutes($collection);
+      $this->dumper->dump(array('provider' => 'conditional_routes'));
+    } while ($conditional_collection->count() && $iteration <= static::CONDITIONAL_ROUTES_RECURSION_LIMIT);
 
     $this->state->delete(static::REBUILD_NEEDED);
     $this->lock->release('router_rebuild');
diff --git a/core/lib/Drupal/Core/Routing/RouteSubscriberBase.php b/core/lib/Drupal/Core/Routing/RouteSubscriberBase.php
index 1172428..2bf8c71 100644
--- a/core/lib/Drupal/Core/Routing/RouteSubscriberBase.php
+++ b/core/lib/Drupal/Core/Routing/RouteSubscriberBase.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\Core\Routing;
 
-use Drupal\Core\Routing\RoutingEvents;
+use Symfony\Component\EventDispatcher\Event;
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 use Symfony\Component\Routing\RouteCollection;
 
@@ -20,19 +20,38 @@
    * Alters existing routes for a specific collection.
    *
    * @param \Symfony\Component\Routing\RouteCollection $collection
-   *   The route collection for adding routes.
+   *   The route collection that contains the routes to alter.
    * @param string $provider
-   *   The provider these routes belong to. For dynamically added routes, the
-   *   provider name will be 'dynamic_routes'.
+   *   The provider these routes belong to. For conditionally added routes, the
+   *   provider will be 'conditional_routes'.
    */
   protected function alterRoutes(RouteCollection $collection, $provider) {
   }
 
   /**
+   * Returns conditional routes that are based on other routes.
+   *
+   * @param \Symfony\Component\Routing\RouteCollection $collection
+   *   The route collection that contains the routes to base the conditional
+   *   routes on.
+   * @param string $provider
+   *   The provider these routes belong to. For conditionally added routes, the
+   *   provider will be 'conditional_routes'.
+   *
+   * @return \Symfony\Component\Routing\RouteCollection|\Symfony\Component\Routing\Route[]
+   *   The conditional routes either as a route collection or as an array of
+   *   routes keyed by route name.
+   */
+  protected function conditionalRoutes(RouteCollection $collection, $provider) {
+  }
+
+  /**
    * {@inheritdoc}
    */
   public static function getSubscribedEvents() {
     $events[RoutingEvents::ALTER] = 'onAlterRoutes';
+    $events[RoutingEvents::CONDITIONAL] = 'onConditionalRoutes';
+    $events[RoutingEvents::FINISHED] = 'onFinishedRebuilding';
     return $events;
   }
 
@@ -44,7 +63,41 @@ public static function getSubscribedEvents() {
    */
   public function onAlterRoutes(RouteBuildEvent $event) {
     $collection = $event->getRouteCollection();
-    $this->alterRoutes($collection, $event->getProvider());
+    $provider = $event->getProvider();
+
+    $this->alterRoutes($collection, $provider);
+  }
+
+  /**
+   * Delegates the conditional route building to self::conditionalRoutes().
+   *
+   * @param \Drupal\Core\Routing\RouteBuildEvent $event
+   *   The route build event.
+   */
+  public function onConditionalRoutes(RouteBuildEvent $event) {
+    $collection = $event->getRouteCollection();
+    $provider = $event->getProvider();
+    $conditional_collection = $event->getConditionalRouteCollection();
+
+    if ($additional_routes = $this->conditionalRoutes($collection, $provider)) {
+      if ($additional_routes instanceof RouteCollection) {
+        $conditional_collection->addCollection($additional_routes);
+      }
+      else {
+        foreach ($additional_routes as $route_name => $route) {
+          $conditional_collection->add($route_name, $route);
+        }
+      }
+    }
+  }
+
+  /**
+   * Provides an opportunity to run code when route rebuilding has finished.
+   *
+   * @param \Symfony\Component\EventDispatcher\Event $event
+   *   The RoutingEvents::FINISHED event.
+   */
+  public function onFinishedRebuilding(Event $event) {
   }
 
 }
diff --git a/core/lib/Drupal/Core/Routing/RoutingEvents.php b/core/lib/Drupal/Core/Routing/RoutingEvents.php
index b5ee212..a2b5ba0 100644
--- a/core/lib/Drupal/Core/Routing/RoutingEvents.php
+++ b/core/lib/Drupal/Core/Routing/RoutingEvents.php
@@ -24,6 +24,19 @@
   const ALTER = 'routing.route_alter';
 
   /**
+   * The CONDITIONAL event is fired when a subscriber adds routes conditionally.
+   *
+   * Specifically, some route subscribers add routes based on the existence or
+   * state of other routes. If these routes were added in the ALTER event they
+   * themselves could not be altered by other modules. The route builder also
+   * makes sure that route subscribers can provide conditional routes based on
+   * other conditional routes.
+   *
+   * @see \Drupal\Core\Routing\RouteBuilder
+   */
+  const CONDITIONAL = 'routing.route_conditional';
+
+  /**
    * The FINISHED event is fired when the route building ended.
    */
   const FINISHED = 'routing.route_finished';
diff --git a/core/modules/config_translation/lib/Drupal/config_translation/ConfigMapperInterface.php b/core/modules/config_translation/lib/Drupal/config_translation/ConfigMapperInterface.php
index b572708..4def427 100644
--- a/core/modules/config_translation/lib/Drupal/config_translation/ConfigMapperInterface.php
+++ b/core/modules/config_translation/lib/Drupal/config_translation/ConfigMapperInterface.php
@@ -9,6 +9,7 @@
 
 use Drupal\Core\Language\Language;
 use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Routing\Route;
 
 /**
  * Defines an interface for configuration mapper.
@@ -47,6 +48,16 @@ public function getBaseRouteParameters();
   public function getBaseRoute();
 
   /**
+   * Sets the base route object.
+   *
+   * @param \Symfony\Component\Routing\Route $route
+   *   The route object used as base route.
+   *
+   * @see \Drupal\config_translation\Routing\RouteSubscriber::alterRoutes()
+   */
+  public function setBaseRoute(Route $route);
+
+  /**
    * Returns a processed path for the base route the mapper is attached to.
    *
    * @return string
diff --git a/core/modules/config_translation/lib/Drupal/config_translation/ConfigNamesMapper.php b/core/modules/config_translation/lib/Drupal/config_translation/ConfigNamesMapper.php
index 7ba5b2a..e182860 100644
--- a/core/modules/config_translation/lib/Drupal/config_translation/ConfigNamesMapper.php
+++ b/core/modules/config_translation/lib/Drupal/config_translation/ConfigNamesMapper.php
@@ -45,6 +45,13 @@ class ConfigNamesMapper extends PluginBase implements ConfigMapperInterface, Con
   protected $configMapperManager;
 
   /**
+   * The route provider.
+   *
+   * @var \Drupal\Core\Routing\RouteProvider
+   */
+  protected $routeProvider;
+
+  /**
    * The base route object that the mapper is attached to.
    *
    * @return \Symfony\Component\Routing\Route
@@ -95,10 +102,9 @@ public function __construct($plugin_id, array $plugin_definition, ConfigFactory
     $this->configFactory = $config_factory;
     $this->localeConfigManager = $locale_config_manager;
     $this->configMapperManager = $config_mapper_manager;
+    $this->routeProvider = $route_provider;
 
     $this->setTranslationManager($translation_manager);
-
-    $this->baseRoute = $route_provider->getRouteByName($this->getBaseRouteName());
   }
 
   /**
@@ -145,12 +151,25 @@ public function getBaseRouteParameters() {
    * {@inheritdoc}
    */
   public function getBaseRoute() {
+    // The base route cannot be set directly in the constructor because during
+    // route rebuilding we need to instantiate the mappers before the respective
+    // routes are available.
+    if (!isset($this->baseRoute)) {
+      $this->baseRoute = $this->routeProvider->getRouteByName($this->getBaseRouteName());
+    }
     return $this->baseRoute;
   }
 
   /**
    * {@inheritdoc}
    */
+  public function setBaseRoute(Route $route) {
+    $this->baseRoute = $route;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function getBasePath() {
     return $this->getPathFromRoute($this->getBaseRoute(), $this->getBaseRouteParameters());
   }
diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Routing/RouteSubscriber.php b/core/modules/config_translation/lib/Drupal/config_translation/Routing/RouteSubscriber.php
index 335faa5..891ecd9 100644
--- a/core/modules/config_translation/lib/Drupal/config_translation/Routing/RouteSubscriber.php
+++ b/core/modules/config_translation/lib/Drupal/config_translation/Routing/RouteSubscriber.php
@@ -9,6 +9,7 @@
 
 use Drupal\Core\Routing\RouteSubscriberBase;
 use Drupal\config_translation\ConfigMapperManagerInterface;
+use Symfony\Component\EventDispatcher\Event;
 use Symfony\Component\Routing\RouteCollection;
 
 /**
@@ -17,11 +18,32 @@
 class RouteSubscriber extends RouteSubscriberBase {
 
   /**
-   * The mapper plugin discovery service.
+   * An array of all configuration mappers, keyed by ID.
    *
-   * @var \Drupal\config_translation\ConfigMapperManagerInterface
+   * @var \Drupal\config_translation\ConfigMapperInterface[]
    */
-  protected $mapperManager;
+  protected $mappers;
+
+  /**
+   * An array of base route names.
+   *
+   * The array is keyed by the respective configuration mapper ID in order to
+   * map the each mapper to the base route it requires.
+   *
+   * @var array
+   */
+  protected $baseRouteNames = array();
+
+  /**
+   * An array of base route names that need to processed.
+   *
+   * At the beginning of each route rebuilding process this is identical to
+   * RouteSubscriber::$baseRouteNames and after route rebuilding this should
+   * be empty.
+   *
+   * @var array
+   */
+  protected $baseRouteNamesToProcess;
 
   /**
    * Constructs a new RouteSubscriber.
@@ -30,26 +52,62 @@ class RouteSubscriber extends RouteSubscriberBase {
    *   The mapper plugin discovery service.
    */
   public function __construct(ConfigMapperManagerInterface $mapper_manager) {
-    $this->mapperManager = $mapper_manager;
+    $this->mappers = $mapper_manager->getMappers();
+
+    // The entire list of base route names is needed so we can check each route
+    // collection for matching routes in RouteSubscriber::alterRoutes(). In
+    // order to pass the route information to the configuration mapper we then
+    // need the respective mapper ID for the base route name.
+    foreach ($this->mappers as $mapper_id => $mapper) {
+      $this->baseRouteNames[$mapper_id] = $mapper->getBaseRouteName();
+    }
   }
 
   /**
    * {@inheritdoc}
    */
-  protected function alterRoutes(RouteCollection $collection, $provider) {
-    // @todo \Drupal\config_translation\ConfigNamesMapper uses the route
-    //   provider directly, which is unsafe during rebuild. This currently only
-    //   works by coincidence; fix in https://drupal.org/node/2158571.
-    if ($provider != 'dynamic_routes') {
-      return;
+  protected function conditionalRoutes(RouteCollection $collection, $provider) {
+    // Reset RouteSubscriber::$baseRouteNamesToProcess at the beginning of the
+    // route rebuilding process.
+    if (!isset($this->baseRouteNamesToProcess)) {
+      $this->baseRouteNamesToProcess = $this->baseRouteNames;
+    }
+
+    // Create an additional route collection for the translation routes.
+    $additional_collection = new RouteCollection();
+
+    foreach ($this->baseRouteNamesToProcess as $mapper_id => $route_name) {
+      if ($route = $collection->get($route_name)) {
+        $mapper = $this->mappers[$mapper_id];
+        $mapper->setBaseRoute($route);
+
+        $additional_collection->add($mapper->getOverviewRouteName(), $mapper->getOverviewRoute());
+        $additional_collection->add($mapper->getAddRouteName(), $mapper->getAddRoute());
+        $additional_collection->add($mapper->getEditRouteName(), $mapper->getEditRoute());
+        $additional_collection->add($mapper->getDeleteRouteName(), $mapper->getDeleteRoute());
+
+        // We do not need to check for the same base route name on the next
+        // invocation.
+        unset($this->baseRouteNamesToProcess[$mapper_id]);
+      }
     }
 
-    $mappers = $this->mapperManager->getMappers();
-    foreach ($mappers as $mapper) {
-      $collection->add($mapper->getOverviewRouteName(), $mapper->getOverviewRoute());
-      $collection->add($mapper->getAddRouteName(), $mapper->getAddRoute());
-      $collection->add($mapper->getEditRouteName(), $mapper->getEditRoute());
-      $collection->add($mapper->getDeleteRouteName(), $mapper->getDeleteRoute());
+    return $additional_collection;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function onFinishedRebuilding(Event $event) {
+    $base_route_names_to_process = $this->baseRouteNamesToProcess;
+    // Unset RouteSubscriber::$baseRouteNamesToProcess so that if route
+    // rebuilding happens again in the same request,
+    // RouteSubscriber::alterRoutes() will re-initialize it.
+    unset($this->baseRouteNamesToProcess);
+    // If there are any routes left after route rebuilding has finished,
+    // something has gone wrong.
+    if (!empty($base_route_names_to_process)) {
+      throw new \RuntimeException(sprintf('The following routes are needed by configuration mappers but were not found: %s', implode(', ', $base_route_names_to_process)));
     }
   }
 
diff --git a/core/modules/config_translation/tests/Drupal/config_translation/Tests/ConfigEntityMapperTest.php b/core/modules/config_translation/tests/Drupal/config_translation/Tests/ConfigEntityMapperTest.php
index b7ed1f5..46911d2 100644
--- a/core/modules/config_translation/tests/Drupal/config_translation/Tests/ConfigEntityMapperTest.php
+++ b/core/modules/config_translation/tests/Drupal/config_translation/Tests/ConfigEntityMapperTest.php
@@ -65,12 +65,6 @@ public function setUp() {
 
     $this->routeProvider = $this->getMock('Drupal\Core\Routing\RouteProviderInterface');
 
-    $this->routeProvider
-      ->expects($this->once())
-      ->method('getRouteByName')
-      ->with('language.edit')
-      ->will($this->returnValue(new Route('/admin/config/regional/language/edit/{language_entity}')));
-
     $definition = array(
       'class' => '\Drupal\config_translation\ConfigEntityMapper',
       'base_route_name' => 'language.edit',
diff --git a/core/modules/config_translation/tests/Drupal/config_translation/Tests/ConfigNamesMapperTest.php b/core/modules/config_translation/tests/Drupal/config_translation/Tests/ConfigNamesMapperTest.php
index ac8a13a..42b4b8a 100644
--- a/core/modules/config_translation/tests/Drupal/config_translation/Tests/ConfigNamesMapperTest.php
+++ b/core/modules/config_translation/tests/Drupal/config_translation/Tests/ConfigNamesMapperTest.php
@@ -96,12 +96,6 @@ public function setUp() {
 
     $this->baseRoute = new Route('/admin/config/system/site-information');
 
-    $this->routeProvider
-      ->expects($this->once())
-      ->method('getRouteByName')
-      ->with('system.site_information_settings')
-      ->will($this->returnValue($this->baseRoute));
-
     $this->configNamesMapper = new TestConfigNamesMapper(
       'system.site_information_settings',
       $this->pluginDefinition,
@@ -138,9 +132,25 @@ public function testGetBaseRouteParameters() {
   }
 
   /**
-   * Tests ConfigNamesMapper::getBaseRoute().
+   * Tests ConfigNamesMapper::getBaseRoute() and setBaseRoute().
    */
-  public function testGetBaseRoute() {
+  public function testBaseRoute() {
+    // Test that the route can be set manually.
+    $this->configNamesMapper->setBaseRoute($this->baseRoute);
+    $result = $this->configNamesMapper->getBaseRoute();
+    $this->assertSame($this->baseRoute, $result);
+
+    // Test that the route is fetched from the route provider if it is not set.
+    $this->configNamesMapper->unsetBaseRoute();
+    $this->routeProvider
+      ->expects($this->once())
+      ->method('getRouteByName')
+      ->with('system.site_information_settings')
+      ->will($this->returnValue($this->baseRoute));
+    $result = $this->configNamesMapper->getBaseRoute();
+    $this->assertSame($this->baseRoute, $result);
+
+    // Test that the base route is stored on the mapper.
     $result = $this->configNamesMapper->getBaseRoute();
     $this->assertSame($this->baseRoute, $result);
   }
@@ -149,6 +159,7 @@ public function testGetBaseRoute() {
    * Tests ConfigNamesMapper::getBasePath().
    */
   public function testGetBasePath() {
+    $this->configNamesMapper->setBaseRoute($this->baseRoute);
     $result = $this->configNamesMapper->getBasePath();
     $this->assertSame('/admin/config/system/site-information', $result);
   }
@@ -174,6 +185,7 @@ public function testGetOverviewRouteParameters() {
    * Tests ConfigNamesMapper::getOverviewRoute().
    */
   public function testGetOverviewRoute() {
+    $this->configNamesMapper->setBaseRoute($this->baseRoute);
     $expected = new Route('/admin/config/system/site-information/translate',
       array(
         '_content' => '\Drupal\config_translation\Controller\ConfigTranslationController::itemPage',
@@ -191,6 +203,7 @@ public function testGetOverviewRoute() {
    * Tests ConfigNamesMapper::getOverviewPath().
    */
   public function testGetOverviewPath() {
+    $this->configNamesMapper->setBaseRoute($this->baseRoute);
     $result = $this->configNamesMapper->getOverviewPath();
     $this->assertSame('/admin/config/system/site-information/translate', $result);
   }
@@ -221,6 +234,7 @@ public function testGetAddRouteParameters() {
    * Tests ConfigNamesMapper::getAddRoute().
    */
   public function testGetAddRoute() {
+    $this->configNamesMapper->setBaseRoute($this->baseRoute);
     $expected = new Route('/admin/config/system/site-information/translate/{langcode}/add',
       array(
         '_form' => '\Drupal\config_translation\Form\ConfigTranslationAddForm',
@@ -260,6 +274,7 @@ public function testGetEditRouteParameters() {
    * Tests ConfigNamesMapper::getEditRoute().
    */
   public function testGetEditRoute() {
+    $this->configNamesMapper->setBaseRoute($this->baseRoute);
     $expected = new Route('/admin/config/system/site-information/translate/{langcode}/edit',
       array(
         '_form' => '\Drupal\config_translation\Form\ConfigTranslationEditForm',
@@ -298,6 +313,7 @@ public function testGetDeleteRouteParameters() {
    * Tests ConfigNamesMapper::getRoute().
    */
   public function testGetDeleteRoute() {
+    $this->configNamesMapper->setBaseRoute($this->baseRoute);
     $expected = new Route('/admin/config/system/site-information/translate/{langcode}/delete',
       array(
         '_form' => '\Drupal\config_translation\Form\ConfigTranslationDeleteForm',
@@ -604,6 +620,7 @@ public function testGetTypeName() {
    * Tests ConfigNamesMapper::hasTranslation().
    */
   public function testGetOperations() {
+    $this->configNamesMapper->setBaseRoute($this->baseRoute);
     $expected = array(
       'translate' => array(
         'title' => 'Translate',
@@ -653,4 +670,11 @@ public function setConfigFactory(ConfigFactory $config_factory) {
     $this->configFactory = $config_factory;
   }
 
+  /**
+   * Unsets the base route that is stored in the mapper.
+   */
+  public function unsetBaseRoute() {
+    unset($this->baseRoute);
+  }
+
 }
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Routing/RouteSubscriber.php b/core/modules/field_ui/lib/Drupal/field_ui/Routing/RouteSubscriber.php
index 2ec7438..153691b 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Routing/RouteSubscriber.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Routing/RouteSubscriber.php
@@ -38,7 +38,10 @@ public function __construct(EntityManagerInterface $manager) {
   /**
    * {@inheritdoc}
    */
-  protected function alterRoutes(RouteCollection $collection, $provider) {
+  protected function conditionalRoutes(RouteCollection $collection, $provider) {
+    // Create an additional route collection for the field UI routes.
+    $conditional_routes = new RouteCollection();
+
     foreach ($this->manager->getDefinitions() as $entity_type => $entity_info) {
       $defaults = array();
       if ($entity_info->isFieldable() && $entity_info->hasLinkTemplate('admin-form')) {
@@ -56,21 +59,21 @@ protected function alterRoutes(RouteCollection $collection, $provider) {
           ),
           array('_permission' => 'administer ' . $entity_type . ' fields')
         );
-        $collection->add("field_ui.instance_edit_$entity_type", $route);
+        $conditional_routes->add("field_ui.instance_edit_$entity_type", $route);
 
         $route = new Route(
           "$path/fields/{field_instance}/field",
           array('_form' => '\Drupal\field_ui\Form\FieldEditForm'),
           array('_permission' => 'administer ' . $entity_type . ' fields')
         );
-        $collection->add("field_ui.field_edit_$entity_type", $route);
+        $conditional_routes->add("field_ui.field_edit_$entity_type", $route);
 
         $route = new Route(
           "$path/fields/{field_instance}/delete",
           array('_entity_form' => 'field_instance.delete'),
           array('_field_ui_field_delete_access' => 'administer ' . $entity_type . ' fields')
         );
-        $collection->add("field_ui.delete_$entity_type", $route);
+        $conditional_routes->add("field_ui.delete_$entity_type", $route);
 
         // If the entity type has no bundles, use the entity type.
         $defaults['entity_type'] = $entity_type;
@@ -85,7 +88,7 @@ protected function alterRoutes(RouteCollection $collection, $provider) {
           ) + $defaults,
           array('_permission' => 'administer ' . $entity_type . ' fields')
         );
-        $collection->add("field_ui.overview_$entity_type", $route);
+        $conditional_routes->add("field_ui.overview_$entity_type", $route);
 
         $route = new Route(
           "$path/form-display",
@@ -95,7 +98,7 @@ protected function alterRoutes(RouteCollection $collection, $provider) {
           ) + $defaults,
           array('_field_ui_form_mode_access' => 'administer ' . $entity_type . ' form display')
         );
-        $collection->add("field_ui.form_display_overview_$entity_type", $route);
+        $conditional_routes->add("field_ui.form_display_overview_$entity_type", $route);
 
         $route = new Route(
           "$path/form-display/{form_mode_name}",
@@ -104,7 +107,7 @@ protected function alterRoutes(RouteCollection $collection, $provider) {
           ) + $defaults,
           array('_field_ui_form_mode_access' => 'administer ' . $entity_type . ' form display')
         );
-        $collection->add("field_ui.form_display_overview_form_mode_$entity_type", $route);
+        $conditional_routes->add("field_ui.form_display_overview_form_mode_$entity_type", $route);
 
         $route = new Route(
           "$path/display",
@@ -114,7 +117,7 @@ protected function alterRoutes(RouteCollection $collection, $provider) {
           ) + $defaults,
           array('_field_ui_view_mode_access' => 'administer ' . $entity_type . ' display')
         );
-        $collection->add("field_ui.display_overview_$entity_type", $route);
+        $conditional_routes->add("field_ui.display_overview_$entity_type", $route);
 
         $route = new Route(
           "$path/display/{view_mode_name}",
@@ -124,9 +127,11 @@ protected function alterRoutes(RouteCollection $collection, $provider) {
           ) + $defaults,
           array('_field_ui_view_mode_access' => 'administer ' . $entity_type . ' display')
         );
-        $collection->add("field_ui.display_overview_view_mode_$entity_type", $route);
+        $conditional_routes->add("field_ui.display_overview_view_mode_$entity_type", $route);
       }
     }
+
+    return $conditional_routes;
   }
 
   /**
diff --git a/core/modules/system/system.local_tasks.yml b/core/modules/system/system.local_tasks.yml
index 4d597ee..dedbf26 100644
--- a/core/modules/system/system.local_tasks.yml
+++ b/core/modules/system/system.local_tasks.yml
@@ -1,3 +1,8 @@
+system.performance_settings_tab:
+  route_name: system.performance_settings
+  title: Settings
+  base_route: system.performance_settings_tab
+
 system.rss_feeds_settings_tab:
   route_name: system.rss_feeds_settings
   title: Settings
diff --git a/core/modules/views/lib/Drupal/views/EventSubscriber/RouteSubscriber.php b/core/modules/views/lib/Drupal/views/EventSubscriber/RouteSubscriber.php
index 4188c47..66c7933 100644
--- a/core/modules/views/lib/Drupal/views/EventSubscriber/RouteSubscriber.php
+++ b/core/modules/views/lib/Drupal/views/EventSubscriber/RouteSubscriber.php
@@ -86,7 +86,6 @@ public function reset() {
   public static function getSubscribedEvents() {
     $events = parent::getSubscribedEvents();
     $events[KernelEvents::VIEW][] = array('onHtmlPage', 75);
-    $events[RoutingEvents::FINISHED] = array('routeRebuildFinished');
     return $events;
   }
 
@@ -180,7 +179,7 @@ protected function alterRoutes(RouteCollection $collection, $provider) {
   /**
    * {@inheritdoc}
    */
-  public function routeRebuildFinished() {
+  public function onFinishedRebuilding() {
     $this->reset();
     $this->state->set('views.view_route_names', $this->viewRouteNames);
   }
