diff --git a/core/includes/entity.inc b/core/includes/entity.inc
index 8071a0d..937ce3f 100644
--- a/core/includes/entity.inc
+++ b/core/includes/entity.inc
@@ -186,7 +186,7 @@ function entity_get_view_modes($entity_type = NULL) {
  *
  * @param string $entity_type
  *   The entity type to load, e.g. node or user.
- * @param int $id
+ * @param mixed $id
  *   The id of the entity to load.
  * @param bool $reset
  *   Whether to reset the internal cache for the requested entity type.
diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc
index 050cdd7..995dbe2 100644
--- a/core/modules/system/system.admin.inc
+++ b/core/modules/system/system.admin.inc
@@ -147,7 +147,10 @@ function system_themes_page() {
         $theme->operations[] = array(
           'title' => t('Settings'),
           'href' => 'admin/appearance/settings/' . $theme->name,
-          'attributes' => array('title' => t('Settings for !theme theme', array('!theme' => $theme->info['name']))),
+          'attributes' => array(
+            'title' => t('Settings for !theme theme', array('!theme' => $theme->info['name'])),
+            'class' => array('theme-settings'),
+          ),
         );
       }
       if (!empty($theme->status)) {
@@ -157,14 +160,20 @@ function system_themes_page() {
               'title' => t('Disable'),
               'href' => 'admin/appearance/disable',
               'query' => $query,
-              'attributes' => array('title' => t('Disable !theme theme', array('!theme' => $theme->info['name']))),
+              'attributes' => array(
+                'title' => t('Disable !theme theme', array('!theme' => $theme->info['name'])),
+                'class' => array('disable-theme'),
+              ),
             );
           }
           $theme->operations[] = array(
             'title' => t('Set default'),
             'href' => 'admin/appearance/default',
             'query' => $query,
-            'attributes' => array('title' => t('Set !theme as default theme', array('!theme' => $theme->info['name']))),
+            'attributes' => array(
+              'title' => t('Set !theme as default theme', array('!theme' => $theme->info['name'])),
+              'class' => array('set-default-theme'),
+            ),
           );
         }
         $admin_theme_options[$theme->name] = $theme->info['name'];
@@ -174,13 +183,19 @@ function system_themes_page() {
           'title' => t('Enable'),
           'href' => 'admin/appearance/enable',
           'query' => $query,
-          'attributes' => array('title' => t('Enable !theme theme', array('!theme' => $theme->info['name']))),
+          'attributes' => array(
+            'title' => t('Enable !theme theme', array('!theme' => $theme->info['name'])),
+            'class' => array('enable-theme'),
+          ),
         );
         $theme->operations[] = array(
           'title' => t('Enable and set default'),
           'href' => 'admin/appearance/default',
           'query' => $query,
-          'attributes' => array('title' => t('Enable !theme as default theme', array('!theme' => $theme->info['name']))),
+          'attributes' => array(
+            'title' => t('Enable !theme as default theme', array('!theme' => $theme->info['name'])),
+            'class' => array('enable-theme-default'),
+          ),
         );
       }
     }
diff --git a/core/modules/tour/tour.module b/core/modules/tour/tour.module
index affdc49..4f29414 100644
--- a/core/modules/tour/tour.module
+++ b/core/modules/tour/tour.module
@@ -1,147 +1,167 @@
-<?php
-
-/**
- * @file
- * Main functions of the module.
- */
-use Drupal\Core\Cache\CacheBackendInterface;
-
-/**
- * Implements hook_permission().
- */
-function tour_permission() {
-  return array(
-    'access tour' => array(
-      'title' => t('Access tour'),
-      'description' => t('View tour tips.'),
-    ),
-  );
-}
-
-/**
- * Implements hook_library_info().
- */
-function tour_library_info() {
-  $path = drupal_get_path('module', 'tour');
-
-  $libraries['tour'] = array(
-    'title' => 'Tour',
-    'version' => VERSION,
-    'js' => array(
-      // Add the JavaScript, with a group and weight such that it will run
-      // before modules/overlay/overlay-parent.js.
-      $path . '/js/tour.js' => array('group' => JS_LIBRARY, 'weight' => -1),
-    ),
-    'dependencies' => array(
-      array('system', 'jquery'),
-      array('system', 'drupal'),
-      array('system', 'backbone'),
-      array('system', 'jquery.bbq'),
-      array('tour', 'jquery.joyride'),
-      array('tour', 'tour-styling'),
-    ),
-  );
-
-  $libraries['tour-styling'] = array(
-    'title' => 'Tour',
-    'version' => VERSION,
-    'css' => array(
-      $path . '/css/tour.module.css' => array('media' => 'screen'),
-    )
-  );
-
-  $libraries['jquery.joyride'] = array(
-    'title' => 'Joyride',
-    'website' => 'https://github.com/zurb/joyride',
-    'version' => '2.0.3',
-    'js' => array(
-      $path . '/js/jquery.joyride-2.0.3.js' => array(),
-    ),
-    'css' => array(
-      $path . '/css/joyride-2.0.3.css' => array('media' => 'screen'),
-    ),
-    'dependencies' => array(
-      array('system', 'jquery'),
-      array('system', 'jquery.cookie'),
-    ),
-  );
-
-  return $libraries;
-}
-
-/**
- * Implements hook_toolbar().
- */
-function tour_toolbar() {
-  if (!user_access('access tour')) {
-    return;
+  <?php
+
+  /**
+   * @file
+   * Main functions of the module.
+   */
+  use Drupal\Core\Cache\CacheBackendInterface;
+
+  /**
+   * Implements hook_permission().
+   */
+  function tour_permission() {
+    return array(
+      'access tour' => array(
+        'title' => t('Access tour'),
+        'description' => t('View tour tips.'),
+      ),
+    );
+  }
+
+  /**
+   * Implements hook_library_info().
+   */
+  function tour_library_info() {
+    $path = drupal_get_path('module', 'tour');
+
+    $libraries['tour'] = array(
+      'title' => 'Tour',
+      'version' => VERSION,
+      'js' => array(
+        // Add the JavaScript, with a group and weight such that it will run
+        // before modules/overlay/overlay-parent.js.
+        $path . '/js/tour.js' => array('group' => JS_LIBRARY, 'weight' => -1),
+      ),
+      'dependencies' => array(
+        array('system', 'jquery'),
+        array('system', 'drupal'),
+        array('system', 'backbone'),
+        array('system', 'jquery.bbq'),
+        array('tour', 'jquery.joyride'),
+        array('tour', 'tour-styling'),
+      ),
+    );
+
+    $libraries['tour-styling'] = array(
+      'title' => 'Tour',
+      'version' => VERSION,
+      'css' => array(
+        $path . '/css/tour.module.css' => array('media' => 'screen'),
+      )
+    );
+
+    $libraries['jquery.joyride'] = array(
+      'title' => 'Joyride',
+      'website' => 'https://github.com/zurb/joyride',
+      'version' => '2.0.3',
+      'js' => array(
+        $path . '/js/jquery.joyride-2.0.3.js' => array(),
+      ),
+      'css' => array(
+        $path . '/css/joyride-2.0.3.css' => array('media' => 'screen'),
+      ),
+      'dependencies' => array(
+        array('system', 'jquery'),
+        array('system', 'jquery.cookie'),
+      ),
+    );
+
+    return $libraries;
   }
 
-  $tab['tour'] = array(
-    '#type' => 'toolbar_item',
-    'tab' => array(
-      '#type' => 'html_tag',
-      '#tag' => 'button',
-      '#value' => t('Tour'),
-      '#attributes' => array(
-        'class' => array('toolbar-icon', 'toolbar-icon-help'),
-        'role' => 'button',
-        'aria-pressed' => 'false',
+  /**
+   * Implements hook_toolbar().
+   */
+  function tour_toolbar() {
+    if (!user_access('access tour')) {
+      return;
+    }
+
+    $tab['tour'] = array(
+      '#type' => 'toolbar_item',
+      'tab' => array(
+        '#type' => 'html_tag',
+        '#tag' => 'button',
+        '#value' => t('Tour'),
+        '#attributes' => array(
+          'class' => array('toolbar-icon', 'toolbar-icon-help'),
+          'role' => 'button',
+          'aria-pressed' => 'false',
+        ),
       ),
-    ),
-    '#wrapper_attributes' => array(
-      'class' => array('tour-toolbar-tab', 'hidden'),
-      'id' => 'toolbar-tab-tour',
-    ),
-    '#attached' => array(
-      'library' => array(
-        array('tour', 'tour'),
+      '#wrapper_attributes' => array(
+        'class' => array('tour-toolbar-tab', 'hidden'),
+        'id' => 'toolbar-tab-tour',
       ),
-    ),
-  );
-
-  return $tab;
-}
-
-/**
- * Implements hook_preprocess_HOOK() for page.tpl.php.
- */
-function tour_preprocess_page(&$variables) {
-  if (!user_access('access tour')) {
-    return;
+      '#attached' => array(
+        'library' => array(
+          array('tour', 'tour'),
+        ),
+      ),
+    );
+
+    return $tab;
   }
 
-  // @todo replace this with http://drupal.org/node/1918768 once it is committed.
-  $path = current_path();
-  $tour_items = array();
-  // Load all of the items and match on path.
-  $tours = entity_load_multiple('tour');
-
-  $path_alias = drupal_strtolower(Drupal::service('path.alias_manager')->getPathAlias($path));
-  foreach ($tours as $tour_id => $tour) {
-    // @todo Replace this with an entity query that does path matching when
-    // http://drupal.org/node/1918768 lands.
-    $pages = implode("\n", $tour->getPaths());
-    if (!drupal_match_path($path_alias, $pages) && (($path == $path_alias) || drupal_match_path($path, $pages))) {
-      unset($tours[$tour_id]);
+  /**
+   * Implements hook_preprocess_HOOK() for page.tpl.php.
+   */
+  function tour_preprocess_page(&$variables) {
+    if (!user_access('access tour')) {
+      return;
     }
+
+    // @todo replace this with http://drupal.org/node/1918768 once committed.
+    $path = current_path();
+
+
+
+    $path_alias = drupal_strtolower(Drupal::service('path.alias_manager')->getPathAlias($path));
+
+    $tour_id = Drupal::request()->query->get('tour-id');
+
+    // If a tour_id is supplied, do not load any other tours. This option would
+    // usually be used with 'tour=1' to ensure the tour is triggered.
+
+    if (!empty($tour_id)) {
+      if (Drupal::entityQuery('tour')->condition('id', $tour_id)->execute()) {
+        $tours = array(
+          $tour_id => $tours[$tour_id],
+        );
+      }
+    }
+    else {
+      // Load all of the items and match on path.
+      $all_tours = entity_load_multiple('tour');
+
+      foreach ($all_tours as $tour_id => $tour) {
+        // @todo Replace this with an entity query that does path matching when
+        // http://drupal.org/node/1918768 lands.
+        $pages = implode("\n", $tour->getPaths());
+        if (!drupal_match_path($path_alias, $pages) && (($path == $path_alias) || drupal_match_path($path, $pages))) {
+          unset($all_tours[$tour_id]);
+        }
+      }
+    }
+
+    // Allow modules to change which tours are to be loaded, for this path.
+    Drupal::moduleHandler()->alter('tour_list', $all_tours, $path_alias);
+
+    if ($all_tours) {
+      $variables['page']['help']['tour'] = entity_view_multiple($all_tours, 'full');
+    }
+  }
+
+  /**
+   * Implements hook_tour_insert().
+   */
+  function tour_tour_insert($entity) {
+    Drupal::service('plugin.manager.tour.tip')->clearCachedDefinitions();
   }
 
-  if ($tours) {
-    $variables['page']['help']['tour'] = entity_view_multiple($tours, 'full');
+  /**
+   * Implements hook_tour_update().
+   */
+  function tour_tour_update($entity) {
+    Drupal::service('plugin.manager.tour.tip')->clearCachedDefinitions();
   }
-}
-
-/**
- * Implements hook_tour_insert().
- */
-function tour_tour_insert($entity) {
-  Drupal::service('plugin.manager.tour.tip')->clearCachedDefinitions();
-}
-
-/**
- * Implements hook_tour_update().
- */
-function tour_tour_update($entity) {
-  Drupal::service('plugin.manager.tour.tip')->clearCachedDefinitions();
-}
