diff --git a/composer.json b/composer.json
index 2a8f07a342e39ee55e3588342737dce8259ca32a..32dac173e4581715e23a006c76a84fcd2d1198ad 100644
--- a/composer.json
+++ b/composer.json
@@ -3,8 +3,7 @@
     "description": "OSU ASC Pantheon custom upstream for Drupal 8",
     "type": "project",
     "license": "None",
-    "repositories": [
-        {
+    "repositories": [{
             "type": "composer",
             "url": "https://packages.drupal.org/8"
         },
@@ -37,14 +36,14 @@
         {
             "type": "package",
             "package": {
-              "name": "gdsmith/jquery.easing",
-              "version": "1.4.1",
-              "type": "drupal-library",
-              "source": {
-                "url": "https://github.com/gdsmith/jquery.easing",
-                "type": "git",
-                "reference": "origin/master"
-              }
+                "name": "gdsmith/jquery.easing",
+                "version": "1.4.1",
+                "type": "drupal-library",
+                "source": {
+                    "url": "https://github.com/gdsmith/jquery.easing",
+                    "type": "git",
+                    "reference": "origin/master"
+                }
             }
         },
         {
@@ -62,19 +61,19 @@
         {
             "type": "package",
             "package": {
-              "name": "ckeditor/indentblock",
-              "version": "4.8.0",
-              "type": "drupal-library",
-              "extra": {
-                "installer-name": "indentblock"
-              },
-              "dist": {
-                "url": "https://download.ckeditor.com/indentblock/releases/indentblock_4.8.0.zip",
-                "type": "zip"
-              },
-              "require": {
-                "composer/installers": "~1.0"
-              }
+                "name": "ckeditor/indentblock",
+                "version": "4.8.0",
+                "type": "drupal-library",
+                "extra": {
+                    "installer-name": "indentblock"
+                },
+                "dist": {
+                    "url": "https://download.ckeditor.com/indentblock/releases/indentblock_4.8.0.zip",
+                    "type": "zip"
+                },
+                "require": {
+                    "composer/installers": "~1.0"
+                }
             }
         }
     ],
@@ -109,7 +108,7 @@
         "drupal/content_access": "1.0-alpha1",
         "drupal/core": "8.7.*",
         "drupal/crop": "2.0-rc1",
-        "drupal/ctools": "3.0",
+        "drupal/ctools": "^3.0",
         "drupal/devel": "2.0",
         "drupal/draggableviews": "1.0",
         "drupal/dropzonejs": "2.0-alpha3",
@@ -195,10 +194,9 @@
         "rvtraveller/qs-composer-installer": "^1.1",
         "zaporylie/composer-drupal-optimizations": "^1.0"
     },
-    "require-dev": {
-    },
+    "require-dev": {},
     "conflict": {
-            "drupal/drupal": "*"
+        "drupal/drupal": "*"
     },
     "minimum-stability": "dev",
     "prefer-stable": true,
@@ -223,14 +221,14 @@
             "DrupalProject\\composer\\ScriptHandler::createRequiredFiles"
         ],
         "post-package-install": [
-          "rm -rf web/modules/smtp/.git"
+            "rm -rf web/modules/smtp/.git"
         ],
         "post-update-cmd": [
-          "rm -rf vendor/simplesamlphp/simplesamlphp/config",
-          "cp -r config/simplesamlphp/config vendor/simplesamlphp/simplesamlphp/config",
-          "rm -f web/simplesaml",
-          "ln -s ../vendor/simplesamlphp/simplesamlphp/www web/simplesaml",
-          "DrupalProject\\composer\\ScriptHandler::createRequiredFiles"
+            "rm -rf vendor/simplesamlphp/simplesamlphp/config",
+            "cp -r config/simplesamlphp/config vendor/simplesamlphp/simplesamlphp/config",
+            "rm -f web/simplesaml",
+            "ln -s ../vendor/simplesamlphp/simplesamlphp/www web/simplesaml",
+            "DrupalProject\\composer\\ScriptHandler::createRequiredFiles"
         ],
         "post-create-project-cmd": [
             "@drupal-scaffold",
@@ -272,37 +270,37 @@
         },
         "patches": {
             "drupal/core": {
-              "2799049": "patches/role_based_email_access-2799049-d87.patch",
-              "2949017": "https://www.drupal.org/files/issues/2018-09-19/allow-uid-1-to-delete-2949017-36-3.patch"
+                "2799049": "patches/role_based_email_access-2799049-d87.patch",
+                "2949017": "https://www.drupal.org/files/issues/2018-09-19/allow-uid-1-to-delete-2949017-36-3.patch"
             },
             "drupal/better_exposed_filters": {
-              "2961022": "https://www.drupal.org/files/issues/2018-09-27/better_exposed_filters-autosubmit-fix-2961022-4.patch"
+                "2961022": "https://www.drupal.org/files/issues/2018-09-27/better_exposed_filters-autosubmit-fix-2961022-4.patch"
             },
             "mehrpadin/superfish": {
-              "Fontawesome Tags": "patches/superfish-fontawesome-tags.patch"
+                "Fontawesome Tags": "patches/superfish-fontawesome-tags.patch"
             },
             "drupal/addtocalendar": {
-              "UTC Time Adjustment": "patches/utc-time-adjustment.patch"
+                "UTC Time Adjustment": "patches/utc-time-adjustment.patch"
             },
             "drupal/block_permissions": {
-              "2962965": "https://www.drupal.org/files/issues/2018-09-01/block-permissions-2962965-4.patch"
+                "2962965": "https://www.drupal.org/files/issues/2018-09-01/block-permissions-2962965-4.patch"
             },
             "drupal/menu_block": {
-              "2809699": "https://www.drupal.org/files/issues/2018-10-26/menu_block-label_configuration-2809699-82.patch",
-              "2811337": "https://www.drupal.org/files/issues/menu_block-2_level_menu_block_not_limited_to_active_parent-2811337-58.patch"
+                "2809699": "https://www.drupal.org/files/issues/2018-10-26/menu_block-label_configuration-2809699-82.patch",
+                "2811337": "https://www.drupal.org/files/issues/menu_block-2_level_menu_block_not_limited_to_active_parent-2811337-58.patch"
             },
             "drupal/entity_embed": {
-              "2881745": "patches/entity_embed_2881745-22.patch",
-              "2511404": "patches/entity-embed-img-link-2511404-68.patch"
+                "2881745": "patches/entity_embed_2881745-22.patch",
+                "2511404": "patches/entity-embed-img-link-2511404-68.patch"
             },
             "drupal/smtp": {
-              "2781157": "https://www.drupal.org/files/issues/2018-11-07/2781157-n10.patch"
+                "2781157": "https://www.drupal.org/files/issues/2018-11-07/2781157-n10.patch"
             },
             "drupal/linkit": {
-              "2712951": "https://www.drupal.org/files/issues/2019-11-27/linkit_for_link_field-2712951-140.patch"
+                "2712951": "https://www.drupal.org/files/issues/2019-11-27/linkit_for_link_field-2712951-140.patch"
             },
             "drupal/entity_clone": {
-              "3060223": "https://www.drupal.org/files/issues/2019-10-17/%20entity_clone-corrupted-paragraph-cloning-3060223-5.patch"
+                "3060223": "https://www.drupal.org/files/issues/2019-10-17/%20entity_clone-corrupted-paragraph-cloning-3060223-5.patch"
             }
         }
     },
@@ -314,4 +312,4 @@
             "php": "7.0.8"
         }
     }
-}
+}
\ No newline at end of file
diff --git a/composer.lock b/composer.lock
index 4198cf4a3d5ec6da8ce2f466fc6d7a140d0268b0..93e3412a9a32f524379167a4369c9d5a115afb9f 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "471ffca42dc5858e1856dc4b8da65a8d",
+    "content-hash": "47d3b7ec0db139d69a314901588f15a6",
     "packages": [
         {
             "name": "alchemy/zippy",
@@ -3726,20 +3726,20 @@
         },
         {
             "name": "drupal/ctools",
-            "version": "3.0.0",
+            "version": "3.2.0",
             "source": {
                 "type": "git",
                 "url": "https://git.drupalcode.org/project/ctools.git",
-                "reference": "8.x-3.0"
+                "reference": "8.x-3.2"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://ftp.drupal.org/files/projects/ctools-8.x-3.0.zip",
-                "reference": "8.x-3.0",
-                "shasum": "302e869ecd1e59fe55663673999fee2ccac5daa8"
+                "url": "https://ftp.drupal.org/files/projects/ctools-8.x-3.2.zip",
+                "reference": "8.x-3.2",
+                "shasum": "d6da87239b64ba708a5977e7b33b1e009e36b091"
             },
             "require": {
-                "drupal/core": "~8.0"
+                "drupal/core": "^8.5"
             },
             "type": "drupal-module",
             "extra": {
@@ -3747,8 +3747,8 @@
                     "dev-3.x": "3.x-dev"
                 },
                 "drupal": {
-                    "version": "8.x-3.0",
-                    "datestamp": "1493401742",
+                    "version": "8.x-3.2",
+                    "datestamp": "1550728386",
                     "security-coverage": {
                         "status": "covered",
                         "message": "Covered by Drupal's security advisory policy"
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index 75dd421e592931f3cec6df32f94739292a356872..e5803b8f435b1f9af2c66846fa36699bd65f144d 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -3841,21 +3841,21 @@
     },
     {
         "name": "drupal/ctools",
-        "version": "3.0.0",
-        "version_normalized": "3.0.0.0",
+        "version": "3.2.0",
+        "version_normalized": "3.2.0.0",
         "source": {
             "type": "git",
             "url": "https://git.drupalcode.org/project/ctools.git",
-            "reference": "8.x-3.0"
+            "reference": "8.x-3.2"
         },
         "dist": {
             "type": "zip",
-            "url": "https://ftp.drupal.org/files/projects/ctools-8.x-3.0.zip",
-            "reference": "8.x-3.0",
-            "shasum": "302e869ecd1e59fe55663673999fee2ccac5daa8"
+            "url": "https://ftp.drupal.org/files/projects/ctools-8.x-3.2.zip",
+            "reference": "8.x-3.2",
+            "shasum": "d6da87239b64ba708a5977e7b33b1e009e36b091"
         },
         "require": {
-            "drupal/core": "~8.0"
+            "drupal/core": "^8.5"
         },
         "type": "drupal-module",
         "extra": {
@@ -3863,8 +3863,8 @@
                 "dev-3.x": "3.x-dev"
             },
             "drupal": {
-                "version": "8.x-3.0",
-                "datestamp": "1493401742",
+                "version": "8.x-3.2",
+                "datestamp": "1550728386",
                 "security-coverage": {
                     "status": "covered",
                     "message": "Covered by Drupal's security advisory policy"
diff --git a/web/modules/ctools/ctools.info.yml b/web/modules/ctools/ctools.info.yml
index 3b54b6ab98b6dc4818d28d2974396793f8ec79c9..01f59c94d88e20026719402e647ad843b9c20d70 100644
--- a/web/modules/ctools/ctools.info.yml
+++ b/web/modules/ctools/ctools.info.yml
@@ -1,11 +1,13 @@
-name: Chaos tools
+name: Chaos Tools
 type: module
 description: 'Provides a number of utility and helper APIs for Drupal developers and site builders.'
 package: Chaos tool suite
 # core: 8.x
+dependencies:
+  - drupal:system (>=8.5)
 
-# Information added by Drupal.org packaging script on 2017-04-28
-version: '8.x-3.0'
+# Information added by Drupal.org packaging script on 2019-02-21
+version: '8.x-3.2'
 core: '8.x'
 project: 'ctools'
-datestamp: 1493401747
+datestamp: 1550728390
diff --git a/web/modules/ctools/ctools.services.yml b/web/modules/ctools/ctools.services.yml
index eaa38b81e35290778d6b499afb4df599ffe97daa..59f91f92af3ff74f5e370f07bb4a5c82dd50de26 100644
--- a/web/modules/ctools/ctools.services.yml
+++ b/web/modules/ctools/ctools.services.yml
@@ -4,17 +4,17 @@ services:
     arguments: ['@controller_resolver', '@form_builder', '@ctools.wizard.factory']
   ctools.wizard.entity.form:
     class: Drupal\ctools\Controller\WizardEntityFormController
-    arguments: ['@controller_resolver', '@form_builder', '@ctools.wizard.factory', '@entity.manager']
+    arguments: ['@controller_resolver', '@form_builder', '@ctools.wizard.factory', '@entity_type.manager']
   ctools.wizard_enhancer:
     class: Drupal\ctools\Routing\Enhancer\WizardEnhancer
     tags:
       - { name: route_enhancer }
   ctools.wizard.factory:
     class: Drupal\ctools\Wizard\WizardFactory
-    arguments: ['@form_builder', '@event_dispatcher']
+    arguments: ['@form_builder', '@event_dispatcher', '@renderer']
   ctools.paramconverter.tempstore:
     class: Drupal\ctools\ParamConverter\TempstoreConverter
-    arguments: ['@user.shared_tempstore', '@entity_type.manager']
+    arguments: ['@tempstore.shared', '@entity_type.manager']
     tags:
       - { name: paramconverter }
   ctools.typed_data.resolver:
@@ -22,7 +22,7 @@ services:
     arguments: ['@typed_data_manager', '@string_translation']
   ctools.access:
     class: Drupal\ctools\Access\TempstoreAccess
-    arguments: ['@user.shared_tempstore']
+    arguments: ['@tempstore.shared']
     tags:
       - { name: access_check, applies_to: _ctools_access }
   plugin.manager.ctools.relationship:
@@ -33,6 +33,6 @@ services:
     arguments: ['@entity.repository']
   ctools.serializable.tempstore.factory:
     class: Drupal\ctools\SerializableTempstoreFactory
-    arguments: ['@keyvalue.expirable', '@lock', '@request_stack', '%user.tempstore.expire%']
+    arguments: ['@keyvalue.expirable', '@lock', '@request_stack', '%tempstore.expire%', '@current_user']
     tags:
       - { name: backend_overridable }
diff --git a/web/modules/ctools/modules/ctools_block/ctools_block.info.yml b/web/modules/ctools/modules/ctools_block/ctools_block.info.yml
index e9fdf7c746109f64bfa7372fda66b8cf4d784bd5..e5cb62e95f3a91217da0a08710175206d5df5f62 100644
--- a/web/modules/ctools/modules/ctools_block/ctools_block.info.yml
+++ b/web/modules/ctools/modules/ctools_block/ctools_block.info.yml
@@ -1,14 +1,14 @@
-name: Chaos tools blocks
+name: Chaos Tools Blocks
 type: module
 description: 'Provides improvements to blocks that will one day be added to Drupal core.'
 package: Chaos tool suite (Experimental)
 # version: 3.x
 # core: 8.x
 dependencies:
-  - ctools
+  - ctools:ctools
 
-# Information added by Drupal.org packaging script on 2017-04-28
-version: '8.x-3.0'
+# Information added by Drupal.org packaging script on 2019-02-21
+version: '8.x-3.2'
 core: '8.x'
 project: 'ctools'
-datestamp: 1493401747
+datestamp: 1550728390
diff --git a/web/modules/ctools/modules/ctools_block/ctools_block.module b/web/modules/ctools/modules/ctools_block/ctools_block.module
new file mode 100644
index 0000000000000000000000000000000000000000..12c80348e973c61a884a842a416e8c2def5854c2
--- /dev/null
+++ b/web/modules/ctools/modules/ctools_block/ctools_block.module
@@ -0,0 +1,16 @@
+<?php
+
+/**
+ * Remove ctools block from appearing on viewable block types.
+ * In general, users should be using the core block types instead.
+ */
+function ctools_block_plugin_filter_block_alter(array &$definitions, array $extra, $consumer) {
+  $moduleHandler = \Drupal::service('module_handler');
+  if ($moduleHandler->moduleExists('layout_builder')){
+    foreach ($definitions AS $label => $definition) {
+      if($definition['provider'] == 'ctools_block') {
+        unset($definitions[$label]);
+      }
+    }
+  }
+}
diff --git a/web/modules/ctools/modules/ctools_block/src/Plugin/Block/EntityField.php b/web/modules/ctools/modules/ctools_block/src/Plugin/Block/EntityField.php
index 14cf6ac21738a6e5ba30bd958c72626a048a7660..e86ce0101df61c0a66e5be3528294059ee53779f 100644
--- a/web/modules/ctools/modules/ctools_block/src/Plugin/Block/EntityField.php
+++ b/web/modules/ctools/modules/ctools_block/src/Plugin/Block/EntityField.php
@@ -5,7 +5,6 @@
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Block\BlockBase;
-use Drupal\Core\Cache\CacheableMetadata;
 use Drupal\Core\Entity\EntityFieldManagerInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Entity\FieldableEntityInterface;
@@ -189,7 +188,7 @@ public function defaultConfiguration() {
     return [
       'formatter' => [
         'label' => 'above',
-        'type' => $field_type_definition['default_formatter'] ?: '',
+        'type' => isset($field_type_definition['default_formatter']) ? $field_type_definition['default_formatter'] : '',
         'settings' => [],
         'third_party_settings' => [],
         'weight' => 0,
diff --git a/web/modules/ctools/modules/ctools_block/src/Plugin/Deriver/EntityFieldDeriver.php b/web/modules/ctools/modules/ctools_block/src/Plugin/Deriver/EntityFieldDeriver.php
index ac5b5d176b96f8654a32dfcc3fdc6c9cd7b69edf..7413605fb4137dc2c669d2813a65ba300f9da4a3 100644
--- a/web/modules/ctools/modules/ctools_block/src/Plugin/Deriver/EntityFieldDeriver.php
+++ b/web/modules/ctools/modules/ctools_block/src/Plugin/Deriver/EntityFieldDeriver.php
@@ -14,9 +14,9 @@ class EntityFieldDeriver extends EntityDeriverBase {
    * {@inheritdoc}
    */
   public function getDerivativeDefinitions($base_plugin_definition) {
-    $entity_type_labels = $this->entityManager->getEntityTypeLabels();
-    foreach ($this->entityManager->getFieldMap() as $entity_type_id => $entity_field_map) {
-      foreach ($this->entityManager->getFieldStorageDefinitions($entity_type_id) as $field_storage_definition) {
+    $entity_type_labels = $this->entityTypeRepository->getEntityTypeLabels();
+    foreach ($this->entityFieldManager->getFieldMap() as $entity_type_id => $entity_field_map) {
+      foreach ($this->entityFieldManager->getFieldStorageDefinitions($entity_type_id) as $field_storage_definition) {
         $field_name = $field_storage_definition->getName();
 
         // The blocks are based on fields. However, we are looping through field
@@ -36,7 +36,7 @@ public function getDerivativeDefinitions($base_plugin_definition) {
         else {
           // We take the field label used on the first bundle.
           $first_bundle = reset($field_info['bundles']);
-          $bundle_field_definitions = $this->entityManager->getFieldDefinitions($entity_type_id, $first_bundle);
+          $bundle_field_definitions = $this->entityFieldManager->getFieldDefinitions($entity_type_id, $first_bundle);
 
           // The field storage config may exist, but it's possible that no
           // fields are actually using it. If that's the case, skip to the next
diff --git a/web/modules/ctools/modules/ctools_block/tests/modules/ctools_block_field_test/ctools_block_field_test.info.yml b/web/modules/ctools/modules/ctools_block/tests/modules/ctools_block_field_test/ctools_block_field_test.info.yml
index 17bf6d5139985be4367c75691be96f3b52d3f16f..82daed53d099ab5485c548f8b1198cd7424ae7fb 100644
--- a/web/modules/ctools/modules/ctools_block/tests/modules/ctools_block_field_test/ctools_block_field_test.info.yml
+++ b/web/modules/ctools/modules/ctools_block/tests/modules/ctools_block_field_test/ctools_block_field_test.info.yml
@@ -1,4 +1,4 @@
-name: 'Chaos tools blocks test'
+name: 'Chaos Tools blocks test'
 type: module
 description: 'Support module for Chaos tools blocks tests.'
 # core: 8.x
@@ -13,8 +13,8 @@ dependencies:
   - user
 features: true
 
-# Information added by Drupal.org packaging script on 2017-04-28
-version: '8.x-3.0'
+# Information added by Drupal.org packaging script on 2019-02-21
+version: '8.x-3.2'
 core: '8.x'
 project: 'ctools'
-datestamp: 1493401747
+datestamp: 1550728390
diff --git a/web/modules/ctools/modules/ctools_entity_mask/ctools_entity_mask.info.yml b/web/modules/ctools/modules/ctools_entity_mask/ctools_entity_mask.info.yml
new file mode 100644
index 0000000000000000000000000000000000000000..8e7d0d53dc1177193b5f92f6e4e3e4171ade7cc2
--- /dev/null
+++ b/web/modules/ctools/modules/ctools_entity_mask/ctools_entity_mask.info.yml
@@ -0,0 +1,11 @@
+name: 'Entity Mask'
+# core: 8.x
+type: module
+description: 'Allows an entity type to borrow the fields and display configuration of another entity type.'
+# version: VERSION
+
+# Information added by Drupal.org packaging script on 2019-02-21
+version: '8.x-3.2'
+core: '8.x'
+project: 'ctools'
+datestamp: 1550728390
diff --git a/web/modules/ctools/modules/ctools_entity_mask/ctools_entity_mask.module b/web/modules/ctools/modules/ctools_entity_mask/ctools_entity_mask.module
new file mode 100644
index 0000000000000000000000000000000000000000..063a8d3cc40f3005e7ec173f614bc6f441766942
--- /dev/null
+++ b/web/modules/ctools/modules/ctools_entity_mask/ctools_entity_mask.module
@@ -0,0 +1,189 @@
+<?php
+
+use Drupal\Core\Entity\Display\EntityDisplayInterface;
+use Drupal\Core\Entity\Display\EntityFormDisplayInterface;
+use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
+use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\Core\Entity\Sql\SqlContentEntityStorage;
+use Drupal\ctools_entity_mask\MaskContentEntityStorage;
+
+/**
+ * Ensures that mask entity types have the same display modes as masked ones.
+ *
+ * @param array $display_modes
+ *   The display modes.
+ *
+ * @see hook_entity_view_mode_info_alter()
+ * @see \Drupal\Core\Entity\EntityDisplayRepository::getAllDisplayModesByEntityType()
+ */
+function ctools_entity_mask_copy_display_modes(array &$display_modes) {
+  foreach (\Drupal::entityTypeManager()->getDefinitions() as $id => $entity_type) {
+    $mask = $entity_type->get('mask');
+
+    if ($mask && isset($display_modes[$mask])) {
+      $display_modes[$id] = $display_modes[$mask];
+    }
+  }
+}
+
+/**
+ * Implements hook_entity_view_mode_info_alter().
+ */
+function ctools_entity_mask_entity_view_mode_info_alter(&$view_modes) {
+  ctools_entity_mask_copy_display_modes($view_modes);
+}
+
+/**
+ * Implements hook_entity_form_mode_info_alter().
+ */
+function ctools_entity_mask_entity_form_mode_info_alter(&$form_modes) {
+  ctools_entity_mask_copy_display_modes($form_modes);
+}
+
+/**
+ * Implements hook_entity_type_alter().
+ */
+function ctools_entity_mask_entity_type_alter(array &$entity_types) {
+  /** @var \Drupal\Core\Entity\EntityTypeInterface $entity_type */
+  foreach ($entity_types as $entity_type) {
+    // Mask entities should use our specialized storage handler, which simulates
+    // a save but does not write anything to the database.
+    if ($entity_type->get('mask') && $entity_type->getStorageClass() == SqlContentEntityStorage::class) {
+      $entity_type->setStorageClass(MaskContentEntityStorage::class);
+      // Mask entities should not maintain any tables.
+      $entity_type->set('base_table', NULL);
+      $entity_type->set('revision_table', NULL);
+      $entity_type->set('data_table', NULL);
+      $entity_type->set('revision_data_table', NULL);
+
+      // Nor should they be exposed to Field UI.
+      $entity_type->set('field_ui_base_route', NULL);
+    }
+  }
+}
+
+/**
+ * Copies all components from a display for a masked entity type.
+ *
+ * If the given display is for a mask entity type, the corresponding display for
+ * the masked entity type is loaded and all of its components are copied into
+ * the given display. If no corresponding display exists for the masked entity
+ * type, the default display will be loaded and used.
+ *
+ * @param \Drupal\Core\Entity\Display\EntityDisplayInterface $display
+ *   The display for the mask entity type.
+ */
+function ctools_entity_mask_copy_display(EntityDisplayInterface $display) {
+  $mask = \Drupal::entityTypeManager()
+    ->getDefinition($display->getTargetEntityTypeId())
+    ->get('mask');
+
+  // If the target entity type is not masking another entity type, there is
+  // nothing to do here.
+  if (empty($mask)) {
+    return;
+  }
+
+  // Try to load the corresponding entity display for the masked entity type,
+  // in descending order of preference.
+  $bundle = $display->getTargetBundle();
+  $displays = $display::loadMultiple([
+    $mask . '.' . $bundle . '.' . $display->getMode(),
+    $mask . '.' . $bundle . '.default',
+  ]);
+
+  // Nothing to do if there is no display we can borrow components from.
+  if (empty($displays)) {
+    return;
+  }
+  foreach (reset($displays)->getComponents() as $key => $component) {
+    $display->setComponent($key, $component);
+  }
+}
+
+/**
+ * Implements hook_ENTITY_TYPE_create().
+ */
+function ctools_entity_mask_entity_view_display_create(EntityViewDisplayInterface $display) {
+  ctools_entity_mask_copy_display($display);
+}
+
+/**
+ * Implements hook_ENTITY_TYPE_create().
+ */
+function ctools_entity_mask_entity_form_display_create(EntityFormDisplayInterface $display) {
+  ctools_entity_mask_copy_display($display);
+}
+
+/**
+ * Implements hook_entity_view_display_alter().
+ */
+function ctools_entity_mask_entity_view_display_alter(EntityViewDisplayInterface $display, array $context) {
+  ctools_entity_mask_copy_display($display);
+}
+
+/**
+ * Implements hook_entity_form_display_alter().
+ */
+function ctools_entity_mask_entity_form_display_alter(EntityFormDisplayInterface $form_display, array $context) {
+  ctools_entity_mask_copy_display($form_display);
+}
+
+/**
+ * Implements hook_entity_bundle_field_info().
+ */
+function ctools_entity_mask_entity_bundle_field_info(EntityTypeInterface $entity_type, $bundle) {
+  $info = [];
+
+  $mask = $entity_type->get('mask');
+  // Nothing to do if the entity type is not masking another entity type.
+  if (empty($mask)) {
+    return $info;
+  }
+
+  $storage_info = ctools_entity_mask_entity_field_storage_info($entity_type);
+
+  /** @var \Drupal\field\FieldConfigInterface[] $fields */
+  $fields = \Drupal::entityTypeManager()
+    ->getStorage('field_config')
+    ->loadByProperties([
+      'entity_type' => $mask,
+      'bundle' => $bundle,
+    ]);
+
+  foreach ($fields as $field) {
+    $field_name = $field->getName();
+
+    $info[$field_name] = $field
+      ->createDuplicate()
+      ->set('entity_type', $mask)
+      ->set('fieldStorage', $storage_info[$field_name]);
+  }
+  return $info;
+}
+
+/**
+ * Implements hook_entity_field_storage_info().
+ */
+function ctools_entity_mask_entity_field_storage_info(EntityTypeInterface $entity_type) {
+  $info = [];
+
+  $mask = $entity_type->get('mask');
+  // Nothing to do if the entity type is not masking another entity type.
+  if (empty($mask)) {
+    return $info;
+  }
+
+  /** @var \Drupal\field\FieldStorageConfigInterface[] $fields */
+  $fields = \Drupal::entityTypeManager()
+    ->getStorage('field_storage_config')
+    ->loadByProperties([
+      'entity_type' => $mask,
+    ]);
+
+  foreach ($fields as $field) {
+    $field_name = $field->getName();
+    $info[$field_name] = $field->createDuplicate()->set('entity_type', $mask);
+  }
+  return $info;
+}
diff --git a/web/modules/ctools/modules/ctools_entity_mask/src/MaskContentEntityStorage.php b/web/modules/ctools/modules/ctools_entity_mask/src/MaskContentEntityStorage.php
new file mode 100644
index 0000000000000000000000000000000000000000..0c9151107202269c30b08e5b2c6a8ae9012256e7
--- /dev/null
+++ b/web/modules/ctools/modules/ctools_entity_mask/src/MaskContentEntityStorage.php
@@ -0,0 +1,81 @@
+<?php
+
+namespace Drupal\ctools_entity_mask;
+
+use Drupal\Core\Entity\ContentEntityInterface;
+use Drupal\Core\Entity\ContentEntityStorageBase;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
+
+/**
+ * Storage handler that simulates a full save, without writing to the database.
+ */
+class MaskContentEntityStorage extends ContentEntityStorageBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function readFieldItemsToPurge(FieldDefinitionInterface $field_definition, $batch_size) {
+    return [];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function purgeFieldItems(ContentEntityInterface $entity, FieldDefinitionInterface $field_definition) {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function doLoadRevisionFieldItems($revision_id) {
+    return NULL;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function doSaveFieldItems(ContentEntityInterface $entity, array $names = []) {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function doDeleteFieldItems($entities) {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function doDeleteRevisionFieldItems(ContentEntityInterface $revision) {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function doLoadMultiple(array $ids = NULL) {
+    return [];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function has($id, EntityInterface $entity) {
+    return FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getQueryServiceName() {
+    return 'entity.query.null';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function countFieldData($storage_definition, $as_bool = FALSE) {
+    return $as_bool ? FALSE : 0;
+  }
+
+}
diff --git a/web/modules/ctools/modules/ctools_entity_mask/src/MaskEntityTrait.php b/web/modules/ctools/modules/ctools_entity_mask/src/MaskEntityTrait.php
new file mode 100644
index 0000000000000000000000000000000000000000..4876e106e7544f2cc1b1c32bcfb592302d6531ff
--- /dev/null
+++ b/web/modules/ctools/modules/ctools_entity_mask/src/MaskEntityTrait.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace Drupal\ctools_entity_mask;
+
+/**
+ * Provides common functionality for mask entities.
+ */
+trait MaskEntityTrait {
+
+  /**
+   * Implements \Drupal\Core\Entity\EntityInterface::id().
+   *
+   * Mask entities are generally not saved to the database like standard content
+   * entities, so it cannot be assumed that they will have a serial ID at any
+   * point in their lives. However, Drupal still expects all entities to have an
+   * identifier of some kind, so this dual-purposes the UUID as the canonical
+   * entity ID. (It would be nice if core did this as a rule for all entities
+   * and stopped using serial IDs, but, y'know, baby steps.)
+   *
+   * @return string
+   */
+  public function id() {
+    return $this->uuid();
+  }
+
+}
diff --git a/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/config/install/block_content.type.basic.yml b/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/config/install/block_content.type.basic.yml
new file mode 100644
index 0000000000000000000000000000000000000000..f01ced96bc23d433db37b97ae9fc8ecb08574aec
--- /dev/null
+++ b/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/config/install/block_content.type.basic.yml
@@ -0,0 +1,7 @@
+langcode: en
+status: true
+dependencies: {  }
+id: basic
+label: 'Basic block'
+revision: 0
+description: 'A basic block contains a title and a body.'
diff --git a/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/config/install/core.entity_form_display.block_content.basic.default.yml b/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/config/install/core.entity_form_display.block_content.basic.default.yml
new file mode 100644
index 0000000000000000000000000000000000000000..4baffd4f823f9807c1aa5706ec1e674b04134cb3
--- /dev/null
+++ b/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/config/install/core.entity_form_display.block_content.basic.default.yml
@@ -0,0 +1,52 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - block_content.type.basic
+    - field.field.block_content.basic.body
+    - field.field.block_content.basic.field_image
+    - field.field.block_content.basic.field_link
+    - image.style.thumbnail
+  module:
+    - image
+    - link
+    - text
+id: block_content.basic.default
+targetEntityType: block_content
+bundle: basic
+mode: default
+content:
+  body:
+    type: text_textarea_with_summary
+    weight: 1
+    settings:
+      rows: 9
+      summary_rows: 3
+      placeholder: ''
+    third_party_settings: {  }
+    region: content
+  field_image:
+    type: image_image
+    weight: 3
+    settings:
+      preview_image_style: thumbnail
+      progress_indicator: throbber
+    third_party_settings: {  }
+    region: content
+  field_link:
+    weight: 2
+    settings:
+      placeholder_url: ''
+      placeholder_title: ''
+    third_party_settings: {  }
+    type: link_default
+    region: content
+  info:
+    type: string_textfield
+    weight: 0
+    settings:
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+    region: content
+hidden: {  }
diff --git a/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/config/install/core.entity_view_display.block_content.basic.default.yml b/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/config/install/core.entity_view_display.block_content.basic.default.yml
new file mode 100644
index 0000000000000000000000000000000000000000..6b554554ebd6a774255a15e3b909ca6f3eb48b3f
--- /dev/null
+++ b/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/config/install/core.entity_view_display.block_content.basic.default.yml
@@ -0,0 +1,46 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - block_content.type.basic
+    - field.field.block_content.basic.body
+    - field.field.block_content.basic.field_image
+    - field.field.block_content.basic.field_link
+  module:
+    - image
+    - link
+    - text
+id: block_content.basic.default
+targetEntityType: block_content
+bundle: basic
+mode: default
+content:
+  body:
+    type: text_default
+    weight: 0
+    label: hidden
+    settings: {  }
+    third_party_settings: {  }
+    region: content
+  field_image:
+    weight: 2
+    label: above
+    settings:
+      image_style: ''
+      image_link: ''
+    third_party_settings: {  }
+    type: image
+    region: content
+  field_link:
+    weight: 1
+    label: above
+    settings:
+      trim_length: 80
+      url_only: false
+      url_plain: false
+      rel: ''
+      target: ''
+    third_party_settings: {  }
+    type: link
+    region: content
+hidden: {  }
diff --git a/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/config/install/field.field.block_content.basic.body.yml b/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/config/install/field.field.block_content.basic.body.yml
new file mode 100644
index 0000000000000000000000000000000000000000..89118eff0821d2c675f31171b77a1dc7aab5c8a2
--- /dev/null
+++ b/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/config/install/field.field.block_content.basic.body.yml
@@ -0,0 +1,21 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - block_content.type.basic
+    - field.storage.block_content.body
+  module:
+    - text
+id: block_content.basic.body
+field_name: body
+entity_type: block_content
+bundle: basic
+label: Body
+description: ''
+required: false
+translatable: true
+default_value: {  }
+default_value_callback: ''
+settings:
+  display_summary: false
+field_type: text_with_summary
diff --git a/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/config/install/field.field.block_content.basic.field_image.yml b/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/config/install/field.field.block_content.basic.field_image.yml
new file mode 100644
index 0000000000000000000000000000000000000000..3e11e963944c50c026a3c5d700f52600f65ab3fd
--- /dev/null
+++ b/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/config/install/field.field.block_content.basic.field_image.yml
@@ -0,0 +1,37 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - block_content.type.basic
+    - field.storage.block_content.field_image
+  module:
+    - image
+id: block_content.basic.field_image
+field_name: field_image
+entity_type: block_content
+bundle: basic
+label: Image
+description: ''
+required: false
+translatable: false
+default_value: {  }
+default_value_callback: ''
+settings:
+  file_directory: '[date:custom:Y]-[date:custom:m]'
+  file_extensions: 'png gif jpg jpeg'
+  max_filesize: ''
+  max_resolution: ''
+  min_resolution: ''
+  alt_field: true
+  alt_field_required: true
+  title_field: false
+  title_field_required: false
+  default_image:
+    uuid: ''
+    alt: ''
+    title: ''
+    width: null
+    height: null
+  handler: 'default:file'
+  handler_settings: {  }
+field_type: image
diff --git a/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/config/install/field.field.block_content.basic.field_link.yml b/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/config/install/field.field.block_content.basic.field_link.yml
new file mode 100644
index 0000000000000000000000000000000000000000..d79e9ff02fb3654c3d2743aaae89663a3943c62d
--- /dev/null
+++ b/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/config/install/field.field.block_content.basic.field_link.yml
@@ -0,0 +1,22 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - block_content.type.basic
+    - field.storage.block_content.field_link
+  module:
+    - link
+id: block_content.basic.field_link
+field_name: field_link
+entity_type: block_content
+bundle: basic
+label: Link
+description: ''
+required: false
+translatable: false
+default_value: {  }
+default_value_callback: ''
+settings:
+  link_type: 17
+  title: 1
+field_type: link
diff --git a/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/config/install/field.storage.block_content.field_image.yml b/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/config/install/field.storage.block_content.field_image.yml
new file mode 100644
index 0000000000000000000000000000000000000000..6e0ba246413bf73387d41df07b5b4791dcf11ce9
--- /dev/null
+++ b/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/config/install/field.storage.block_content.field_image.yml
@@ -0,0 +1,29 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - block_content
+    - file
+    - image
+id: block_content.field_image
+field_name: field_image
+entity_type: block_content
+type: image
+settings:
+  uri_scheme: public
+  default_image:
+    uuid: ''
+    alt: ''
+    title: ''
+    width: null
+    height: null
+  target_type: file
+  display_field: false
+  display_default: false
+module: image
+locked: false
+cardinality: 1
+translatable: true
+indexes: {  }
+persist_with_no_fields: false
+custom_storage: false
diff --git a/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/config/install/field.storage.block_content.field_link.yml b/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/config/install/field.storage.block_content.field_link.yml
new file mode 100644
index 0000000000000000000000000000000000000000..bddf13e1c055dcb746104910882d9f3144232d93
--- /dev/null
+++ b/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/config/install/field.storage.block_content.field_link.yml
@@ -0,0 +1,18 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - block_content
+    - link
+id: block_content.field_link
+field_name: field_link
+entity_type: block_content
+type: link
+settings: {  }
+module: link
+locked: false
+cardinality: 1
+translatable: true
+indexes: {  }
+persist_with_no_fields: false
+custom_storage: false
diff --git a/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/entity_mask_test.info.yml b/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/entity_mask_test.info.yml
new file mode 100644
index 0000000000000000000000000000000000000000..46be42c73a67163775e70eacd374eff7edc40cdf
--- /dev/null
+++ b/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/entity_mask_test.info.yml
@@ -0,0 +1,14 @@
+name: 'Entity Mask test'
+# core: 8.x
+type: module
+dependencies:
+  - block_content
+  - ctools_entity_mask
+  - image
+  - text
+
+# Information added by Drupal.org packaging script on 2019-02-21
+version: '8.x-3.2'
+core: '8.x'
+project: 'ctools'
+datestamp: 1550728390
diff --git a/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/entity_mask_test.routing.yml b/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/entity_mask_test.routing.yml
new file mode 100644
index 0000000000000000000000000000000000000000..85d2c8d3b20640e47482405e7884453b0144e849
--- /dev/null
+++ b/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/entity_mask_test.routing.yml
@@ -0,0 +1,9 @@
+fake_block_content.add_form:
+  path: '/fake-block/add/{block_content_type}'
+  defaults:
+    _controller: '\Drupal\block_content\Controller\BlockContentController::addForm'
+    _title_callback: 'Drupal\block_content\Controller\BlockContentController::getAddFormTitle'
+  options:
+    _admin_route: TRUE
+  requirements:
+    _permission: 'administer blocks'
diff --git a/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/src/Entity/BlockContent.php b/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/src/Entity/BlockContent.php
new file mode 100644
index 0000000000000000000000000000000000000000..75446684831701f2e6aab4faafd89721207ce950
--- /dev/null
+++ b/web/modules/ctools/modules/ctools_entity_mask/tests/modules/entity_mask_test/src/Entity/BlockContent.php
@@ -0,0 +1,70 @@
+<?php
+
+namespace Drupal\entity_mask_test\Entity;
+
+use Drupal\block_content\Entity\BlockContent as BaseBlockContent;
+use Drupal\ctools_entity_mask\MaskEntityTrait;
+
+/**
+ * Provides a masked version of BlockContent.
+ *
+ * @todo Investigate a better way to copy the upstream properties instead of
+ *   manually duplicating them.
+ *
+ * @ContentEntityType(
+ *   id = "fake_block_content",
+ *   label = @Translation("Custom block"),
+ *   bundle_label = @Translation("Custom block type"),
+ *   handlers = {
+ *     "storage" = "Drupal\Core\Entity\Sql\SqlContentEntityStorage",
+ *     "access" = "Drupal\block_content\BlockContentAccessControlHandler",
+ *     "list_builder" = "Drupal\block_content\BlockContentListBuilder",
+ *     "view_builder" = "Drupal\block_content\BlockContentViewBuilder",
+ *     "views_data" = "Drupal\block_content\BlockContentViewsData",
+ *     "form" = {
+ *       "add" = "Drupal\block_content\BlockContentForm",
+ *       "edit" = "Drupal\block_content\BlockContentForm",
+ *       "delete" = "Drupal\block_content\Form\BlockContentDeleteForm",
+ *       "default" = "Drupal\block_content\BlockContentForm"
+ *     },
+ *     "translation" = "Drupal\block_content\BlockContentTranslationHandler"
+ *   },
+ *   admin_permission = "administer blocks",
+ *   base_table = "block_content",
+ *   revision_table = "block_content_revision",
+ *   data_table = "block_content_field_data",
+ *   revision_data_table = "block_content_field_revision",
+ *   show_revision_ui = TRUE,
+ *   links = {
+ *     "canonical" = "/block/{block_content}",
+ *     "delete-form" = "/block/{block_content}/delete",
+ *     "edit-form" = "/block/{block_content}",
+ *     "collection" = "/admin/structure/block/block-content",
+ *     "create" = "/block",
+ *   },
+ *   translatable = TRUE,
+ *   entity_keys = {
+ *     "id" = "id",
+ *     "revision" = "revision_id",
+ *     "bundle" = "type",
+ *     "label" = "info",
+ *     "langcode" = "langcode",
+ *     "uuid" = "uuid",
+ *     "published" = "status",
+ *   },
+ *   revision_metadata_keys = {
+ *     "revision_user" = "revision_user",
+ *     "revision_created" = "revision_created",
+ *     "revision_log_message" = "revision_log"
+ *   },
+ *   bundle_entity_type = "block_content_type",
+ *   field_ui_base_route = "entity.block_content_type.edit_form",
+ *   render_cache = FALSE,
+ *   mask = "block_content",
+ * )
+ */
+class BlockContent extends BaseBlockContent {
+
+  use MaskEntityTrait;
+
+}
diff --git a/web/modules/ctools/modules/ctools_entity_mask/tests/src/Functional/DisplayTest.php b/web/modules/ctools/modules/ctools_entity_mask/tests/src/Functional/DisplayTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..9e45a42459b1ea005480ea354fd5ea0673cf2f11
--- /dev/null
+++ b/web/modules/ctools/modules/ctools_entity_mask/tests/src/Functional/DisplayTest.php
@@ -0,0 +1,110 @@
+<?php
+
+namespace Drupal\Tests\ctools_entity_mask\Functional;
+
+use Drupal\entity_mask_test\Entity\BlockContent;
+use Drupal\file\Entity\File;
+use Drupal\Tests\BrowserTestBase;
+
+/**
+ * @group ctools_entity_mask
+ */
+class DisplayTest extends BrowserTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = [
+    'block',
+    'block_content',
+    'ctools_entity_mask',
+    'entity_mask_test',
+    'field',
+    'field_ui',
+    'file',
+    'image',
+    'link',
+    'system',
+    'text',
+    'user',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $account = $this->drupalCreateUser(['administer blocks']);
+    $this->drupalLogin($account);
+  }
+
+  /**
+   * Tests that the form display for a masked entity replicates its source.
+   */
+  public function testFormDisplay() {
+    $assert = $this->assertSession();
+
+    $this->drupalGet('/fake-block/add/basic');
+    $assert->statusCodeEquals(200);
+    $assert->fieldExists('Body');
+    $assert->fieldExists('Link');
+    $assert->fieldExists('Image');
+  }
+
+  /**
+   * Tests that the view display for a masked entity replicates its source.
+   */
+  public function testViewDisplay() {
+    // Generate a random image for the image field, since that can potentially
+    // be tricky.
+    $image_uri = uniqid('public://') . '.png';
+    $image_uri = $this->getRandomGenerator()->image($image_uri, '100x100', '200x200');
+    $image = File::create(['uri' => $image_uri]);
+    $image->save();
+
+    $body = 'Qui animated corpse, cricket bat max brucks terribilem incessu zomby.';
+    $link = 'https://www.drupal.org/project/ctools';
+
+    $block = BlockContent::create([
+      'type' => 'basic',
+      'body' => $body,
+      'field_link' => $link,
+      'field_image' => $image,
+    ]);
+    $block->save();
+
+    // Ensure that the entity is intact after serialization and deserialization,
+    // since that may prove to be a common storage mechanism for mask entities.
+    $block = serialize($block);
+    $block = unserialize($block);
+
+    $this->assertSame($body, $block->body->value);
+    $this->assertSame($link, $block->field_link->uri);
+    $this->assertSame($image_uri, $block->field_image->entity->getFileUri());
+
+    $build = \Drupal::entityTypeManager()
+      ->getViewBuilder('fake_block_content')
+      ->view($block);
+
+    // If the fields are not in the renderable array, something has gone awry.
+    $this->assertArrayHasKey('body', $build);
+    $this->assertArrayHasKey('field_link', $build);
+    $this->assertArrayHasKey('field_image', $build);
+
+    // Render the block and check the output too, just to be sure.
+    $rendered = \Drupal::service('renderer')->renderRoot($build);
+    $rendered = (string) $rendered;
+
+    $this->assertContains($block->body->value, $rendered);
+    $this->assertContains($block->field_link->uri, $rendered);
+
+    $image_url = $block->field_image->entity->getFileUri();
+    $image_url = file_create_url($image_url);
+    // file_create_url() will include the host and port, but the rendered output
+    // won't include those.
+    $image_url = file_url_transform_relative($image_url);
+    $this->assertContains($image_url, $rendered);
+  }
+
+}
diff --git a/web/modules/ctools/modules/ctools_entity_mask/tests/src/Kernel/EntityMaskTest.php b/web/modules/ctools/modules/ctools_entity_mask/tests/src/Kernel/EntityMaskTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..273a1a457670f09ebdde1c7cf42ae28b31e43c92
--- /dev/null
+++ b/web/modules/ctools/modules/ctools_entity_mask/tests/src/Kernel/EntityMaskTest.php
@@ -0,0 +1,216 @@
+<?php
+
+namespace Drupal\Tests\ctools_entity_mask\Kernel;
+
+use Drupal\Core\Entity\Entity\EntityFormMode;
+use Drupal\entity_mask_test\Entity\BlockContent;
+use Drupal\KernelTests\KernelTestBase;
+
+/**
+ * Basic test of entity type masking.
+ *
+ * @group ctools_entity_mask
+ */
+class EntityMaskTest extends KernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = [
+    'block',
+    'block_content',
+    'ctools_entity_mask',
+    'entity_mask_test',
+    'field',
+    'field_ui',
+    'file',
+    'image',
+    'link',
+    'system',
+    'text',
+    'user',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->installConfig(['block_content', 'entity_mask_test']);
+    $this->installEntitySchema('fake_block_content');
+  }
+
+  /**
+   * Tests that fields are correctly masked.
+   */
+  public function testFields() {
+    $block = BlockContent::create([
+      'type' => 'basic',
+    ]);
+
+    $this->assertTrue($block->hasField('body'));
+    $this->assertTrue($block->hasField('field_link'));
+    $this->assertTrue($block->hasField('field_image'));
+  }
+
+  /**
+   * Tests that entity view displays are correctly masked.
+   */
+  public function testViewDisplays() {
+    $view_modes = $this->container
+      ->get('entity_display.repository')
+      ->getAllViewModes();
+    $this->assertSame($view_modes['block_content'], $view_modes['fake_block_content']);
+
+    $display = entity_get_display('fake_block_content', 'basic', 'default');
+    $this->assertTrue($display->isNew());
+
+    $components = $display->getComponents();
+    $this->assertArrayHasKey('body', $components);
+    $this->assertArrayHasKey('field_link', $components);
+    $this->assertArrayHasKey('field_image', $components);
+  }
+
+  /**
+   * Tests that entity form displays are correctly masked.
+   */
+  public function testFormDisplays() {
+    EntityFormMode::create([
+      'id' => 'block_content.foobar',
+      'label' => $this->randomString(),
+      'targetEntityType' => 'block_content',
+    ])->save();
+
+    $form_modes = $this->container
+      ->get('entity_display.repository')
+      ->getAllFormModes();
+    $this->assertSame($form_modes['block_content'], $form_modes['fake_block_content']);
+
+    $display = entity_get_form_display('fake_block_content', 'basic', 'default');
+    $this->assertTrue($display->isNew());
+
+    $components = $display->getComponents();
+    $this->assertArrayHasKey('body', $components);
+    $this->assertArrayHasKey('field_link', $components);
+    $this->assertArrayHasKey('field_image', $components);
+  }
+
+  /**
+   * Tests that mask entity types define no tables.
+   */
+  public function testNoTables() {
+    /** @var \Drupal\Core\Entity\EntityTypeInterface $entity_type */
+    $entity_type = $this->container
+      ->get('entity_type.manager')
+      ->getDefinition('fake_block_content');
+
+    $this->assertNull($entity_type->getBaseTable());
+    $this->assertNull($entity_type->getDataTable());
+    $this->assertNull($entity_type->getRevisionTable());
+    $this->assertNull($entity_type->getRevisionDataTable());
+  }
+
+  /**
+   * Tests that mask entity types are not exposed to Field UI.
+   */
+  public function testNotExposedToFieldUI() {
+    /** @var \Drupal\Core\Entity\EntityTypeInterface $entity_type */
+    $entity_type = $this->container
+      ->get('entity_type.manager')
+      ->getDefinition('fake_block_content');
+
+    $this->assertNull($entity_type->get('field_ui_base_route'));
+  }
+
+  /**
+   * Asserts that a mask entity can be serialized and de-serialized coherently.
+   *
+   * @depends testFields
+   */
+  public function testSerialization() {
+    $body = $this->getRandomGenerator()->paragraphs(2);
+    $link = 'https://www.drupal.org/project/ctools';
+
+    /** @var \Drupal\Core\Entity\EntityInterface $block */
+    $block = BlockContent::create([
+      'type' => 'basic',
+      'body' => $body,
+      'field_link' => $link,
+    ]);
+
+    $block = serialize($block);
+    $block = unserialize($block);
+
+    $this->assertSame($body, $block->body->value);
+    $this->assertSame($link, $block->field_link->uri);
+  }
+
+  /**
+   * Tests that mask entities' isNew() method behaves consistently.
+   */
+  public function testIsNew() {
+    $block = BlockContent::create(['type' => 'basic']);
+    $this->assertTrue($block->isNew());
+    $block->save();
+    $this->assertFalse($block->isNew());
+  }
+
+  /**
+   * Tests that mask entities' id() method returns the UUID.
+   */
+  public function testId() {
+    $block = BlockContent::create(['type' => 'basic']);
+    $this->assertSame($block->id(), $block->uuid());
+    $block->save();
+    $this->assertSame($block->id(), $block->uuid());
+  }
+
+  /**
+   * Tests that mask entities cannot be loaded.
+   *
+   * @depends testId
+   */
+  public function testLoad() {
+    $block = BlockContent::create(['type' => 'basic']);
+    $block->save();
+
+    /** @var \Drupal\Core\Entity\EntityStorageInterface $storage */
+    $storage = $this->container->get('entity_type.manager')->getStorage('fake_block_content');
+
+    $id = $block->id();
+    $this->assertNull($storage->load($id));
+    $this->assertEmpty($storage->loadMultiple([$id]));
+  }
+
+  /**
+   * Tests that deleting a mask entity doesn't throw an exception or anything.
+   */
+  public function testDelete() {
+    $block = BlockContent::create(['type' => 'basic']);
+    $block->save();
+    $block->delete();
+  }
+
+  /**
+   * Tests that mask entities have field data after save.
+   *
+   * @depends testFields
+   * @depends testNoTables
+   */
+  public function testSave() {
+    $body = $this->getRandomGenerator()->paragraphs(2);
+    $link = 'https://www.drupal.org/project/ctools';
+
+    /** @var \Drupal\Core\Entity\EntityInterface $block */
+    $block = BlockContent::create([
+      'type' => 'basic',
+      'body' => $body,
+      'field_link' => $link,
+    ]);
+
+    // Ensure that the field values are preserved after save...
+    $this->assertSame($body, $block->body->value);
+    $this->assertSame($link, $block->field_link->uri);
+  }
+
+}
diff --git a/web/modules/ctools/modules/ctools_views/ctools_views.info.yml b/web/modules/ctools/modules/ctools_views/ctools_views.info.yml
index 2d66b5b53ae8e3f237bed767f5547236a12307fc..9f3898ee1d0b17d65f9f9753c56d737f6b123d05 100644
--- a/web/modules/ctools/modules/ctools_views/ctools_views.info.yml
+++ b/web/modules/ctools/modules/ctools_views/ctools_views.info.yml
@@ -1,15 +1,15 @@
-name: Chaos tools Views
+name: Chaos Tools Views
 type: module
 description: 'A set of improvements to the core Views code that allows for greater control over Blocks.'
 package: Chaos tool suite (Experimental)
 # version: 3.x
 # core: 8.x
 dependencies:
-    - block
-    - views
+  - drupal:block
+  - drupal:views
 
-# Information added by Drupal.org packaging script on 2017-04-28
-version: '8.x-3.0'
+# Information added by Drupal.org packaging script on 2019-02-21
+version: '8.x-3.2'
 core: '8.x'
 project: 'ctools'
-datestamp: 1493401747
+datestamp: 1550728390
diff --git a/web/modules/ctools/modules/ctools_views/src/Plugin/Display/Block.php b/web/modules/ctools/modules/ctools_views/src/Plugin/Display/Block.php
index e2d2a7c4d36aa25473e24d4b84f81933476c67f8..7ebc1b1fd0009cc34e699354be90e0625d77bdd4 100644
--- a/web/modules/ctools/modules/ctools_views/src/Plugin/Display/Block.php
+++ b/web/modules/ctools/modules/ctools_views/src/Plugin/Display/Block.php
@@ -2,11 +2,9 @@
 
 namespace Drupal\ctools_views\Plugin\Display;
 
-use Drupal\Core\Form\FormState;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\views\Plugin\Block\ViewsBlock;
 use Drupal\views\Plugin\views\display\Block as CoreBlock;
-use Drupal\views\Plugin\views\filter\InOperator;
 
 /**
  * Provides a Block display plugin that allows for greater control over Views
@@ -52,10 +50,14 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
     $options['configure_sorts'] = $this->t('Configure sorts');
     $form['allow']['#options'] = $options;
     // Update the items_per_page if set.
-    $defaults = array_filter($form['allow']['#default_value']);
-    if (isset($defaults['items_per_page'])) {
-      $defaults['items_per_page'] = 'items_per_page';
+    $defaults = [];
+    if (!empty($form['allow']['#default_value'])) {
+      $defaults = array_filter($form['allow']['#default_value']);
+      if (!empty($defaults['items_per_page'])) {
+        $defaults['items_per_page'] = 'items_per_page';
+      }
     }
+
     $form['allow']['#default_value'] = $defaults;
   }
 
@@ -157,7 +159,7 @@ public function blockForm(ViewsBlock $block, array &$form, FormStateInterface $f
        if (!empty($allow_settings['sort_fields'])) {
           $form['override']['order_fields'][$field_name]['#attributes']['class'][] = 'draggable';
         }
-        $form['override']['order_fields'][$field_name]['#weight'] = !empty($block_configuration['fields'][$field_name]['weight']) ? $block_configuration['fields'][$field_name]['weight'] : '';
+        $form['override']['order_fields'][$field_name]['#weight'] = !empty($block_configuration['fields'][$field_name]['weight']) ? $block_configuration['fields'][$field_name]['weight'] : 0;
         if (!empty($allow_settings['hide_fields'])) {
           $form['override']['order_fields'][$field_name]['hide'] = [
             '#type' => 'checkbox',
diff --git a/web/modules/ctools/modules/ctools_views/src/Tests/CToolsViewsBasicViewBlockTest.php b/web/modules/ctools/modules/ctools_views/src/Tests/CToolsViewsBasicViewBlockTest.php
index 85201046a09ca5ed3a45ad8cb78c1af4c9d38ef3..559f38ba9287f17a650c1d1dca4f136ac76a957f 100644
--- a/web/modules/ctools/modules/ctools_views/src/Tests/CToolsViewsBasicViewBlockTest.php
+++ b/web/modules/ctools/modules/ctools_views/src/Tests/CToolsViewsBasicViewBlockTest.php
@@ -41,11 +41,11 @@ class CToolsViewsBasicViewBlockTest extends UITestBase {
   /**
    * @inheritdoc
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     ViewTestData::createTestViews(get_class($this), array('ctools_views_test_views'));
-    $this->storage = $this->container->get('entity.manager')->getStorage('block');
+    $this->storage = $this->container->get('entity_type.manager')->getStorage('block');
   }
 
   /**
diff --git a/web/modules/ctools/modules/ctools_views/tests/modules/ctools_views_test_views/ctools_views_test_views.info.yml b/web/modules/ctools/modules/ctools_views/tests/modules/ctools_views_test_views/ctools_views_test_views.info.yml
index 092f98c3781359e39a5e8a1b78e50f563575a3e2..d476c05185efbfff4bc18de4790338beda697acd 100644
--- a/web/modules/ctools/modules/ctools_views/tests/modules/ctools_views_test_views/ctools_views_test_views.info.yml
+++ b/web/modules/ctools/modules/ctools_views/tests/modules/ctools_views_test_views/ctools_views_test_views.info.yml
@@ -13,8 +13,8 @@ dependencies:
     - node
     - taxonomy
 
-# Information added by Drupal.org packaging script on 2017-04-28
-version: '8.x-3.0'
+# Information added by Drupal.org packaging script on 2019-02-21
+version: '8.x-3.2'
 core: '8.x'
 project: 'ctools'
-datestamp: 1493401747
+datestamp: 1550728390
diff --git a/web/modules/ctools/modules/ctools_views/tests/modules/ctools_views_test_views/test_views/views.view.ctools_views_entity_test.yml b/web/modules/ctools/modules/ctools_views/tests/modules/ctools_views_test_views/test_views/views.view.ctools_views_entity_test.yml
index c2ece3c05f353965f87ef87e5b587bd7b44b6bb9..fbdfb3e9c9e939310670836a5f7b21c9841725b6 100644
--- a/web/modules/ctools/modules/ctools_views/tests/modules/ctools_views_test_views/test_views/views.view.ctools_views_entity_test.yml
+++ b/web/modules/ctools/modules/ctools_views/tests/modules/ctools_views_test_views/test_views/views.view.ctools_views_entity_test.yml
@@ -108,7 +108,7 @@ display:
           field_api_classes: false
       filters:
         status:
-          value: true
+          value: '1'
           table: node_field_data
           field: status
           plugin_id: boolean
@@ -173,7 +173,7 @@ display:
         filter_groups: false
       filters:
         status:
-          value: true
+          value: '1'
           table: node_field_data
           field: status
           plugin_id: boolean
@@ -266,7 +266,7 @@ display:
         filter_groups: false
       filters:
         status:
-          value: true
+          value: '1'
           table: node_field_data
           field: status
           plugin_id: boolean
@@ -361,7 +361,7 @@ display:
         filter_groups: false
       filters:
         status:
-          value: true
+          value: '1'
           table: node_field_data
           field: status
           plugin_id: boolean
@@ -463,7 +463,7 @@ display:
         filter_groups: false
       filters:
         status:
-          value: true
+          value: '1'
           table: node_field_data
           field: status
           plugin_id: boolean
diff --git a/web/modules/ctools/plugins/access/node.inc b/web/modules/ctools/plugins/access/node.inc
new file mode 100644
index 0000000000000000000000000000000000000000..07d500025007a62507690a6311d833b10d726956
--- /dev/null
+++ b/web/modules/ctools/plugins/access/node.inc
@@ -0,0 +1,6 @@
+<?php
+
+/**
+ * @file
+ * Plugin to provide access control based on node.
+ */
diff --git a/web/modules/ctools/src/Access/TempstoreAccess.php b/web/modules/ctools/src/Access/TempstoreAccess.php
index 506ade6b482b3399c8e12e8ac3fbcdc6b37a7ce7..34561955f3395a94b8e875d0cdf749990b618dbb 100644
--- a/web/modules/ctools/src/Access/TempstoreAccess.php
+++ b/web/modules/ctools/src/Access/TempstoreAccess.php
@@ -2,13 +2,12 @@
 
 namespace Drupal\ctools\Access;
 
-
 use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Routing\Access\AccessInterface as CoreAccessInterface;
 use Drupal\Core\Routing\RouteMatch;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\ctools\Access\AccessInterface as CToolsAccessInterface;
-use Drupal\user\SharedTempStoreFactory;
+use Drupal\Core\TempStore\SharedTempStoreFactory;
 use Symfony\Component\Routing\Route;
 
 class TempstoreAccess implements CoreAccessInterface {
@@ -16,7 +15,7 @@ class TempstoreAccess implements CoreAccessInterface {
   /**
    * The shared tempstore factory.
    *
-   * @var \Drupal\user\SharedTempStoreFactory
+   * @var \Drupal\Core\TempStore\SharedTempStoreFactory
    */
   protected $tempstore;
 
diff --git a/web/modules/ctools/src/ContextNotFoundException.php b/web/modules/ctools/src/ContextNotFoundException.php
index b9cf15c4a2a7f4be9f8d05d3cd9e4c46e371ca68..a4c45f20f0b71c0e175f703ec9fc2efa88094999 100644
--- a/web/modules/ctools/src/ContextNotFoundException.php
+++ b/web/modules/ctools/src/ContextNotFoundException.php
@@ -2,5 +2,4 @@
 
 namespace Drupal\ctools;
 
-
 class ContextNotFoundException extends \Exception {}
diff --git a/web/modules/ctools/src/Controller/WizardEntityFormController.php b/web/modules/ctools/src/Controller/WizardEntityFormController.php
index 4525764e831041c63f09a50f99b086915fc7572b..3882e273bea7a23a0df0e4f6ac1a51c262c2d694 100644
--- a/web/modules/ctools/src/Controller/WizardEntityFormController.php
+++ b/web/modules/ctools/src/Controller/WizardEntityFormController.php
@@ -3,7 +3,7 @@
 namespace Drupal\ctools\Controller;
 
 use Drupal\Core\Controller\ControllerResolverInterface;
-use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Form\FormBuilderInterface;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\ctools\Wizard\WizardFactoryInterface;
@@ -14,11 +14,11 @@
 class WizardEntityFormController extends WizardFormController {
 
   /**
-   * The entity manager service.
+   * The entity type manager.
    *
-   * @var \Drupal\Core\Entity\EntityManagerInterface
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
    */
-  protected $entityManager;
+  protected $entityTypeManager;
 
   /**
    * @param \Drupal\Core\Controller\ControllerResolverInterface $controller_resolver
@@ -27,12 +27,12 @@ class WizardEntityFormController extends WizardFormController {
    *   The form builder.
    * @param \Drupal\ctools\Wizard\WizardFactoryInterface $wizard_factory
    *   The wizard factory.
-   * @param \Drupal\Core\Entity\EntityManagerInterface $manager
-   *   The entity manager.
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity type manager.
    */
-  public function __construct(ControllerResolverInterface $controller_resolver, FormBuilderInterface $form_builder, WizardFactoryInterface $wizard_factory, EntityManagerInterface $manager) {
+  public function __construct(ControllerResolverInterface $controller_resolver, FormBuilderInterface $form_builder, WizardFactoryInterface $wizard_factory, EntityTypeManagerInterface $entity_type_manager) {
     parent::__construct($controller_resolver, $form_builder, $wizard_factory);
-    $this->entityManager = $manager;
+    $this->entityTypeManager = $entity_type_manager;
   }
 
   /**
@@ -41,7 +41,7 @@ public function __construct(ControllerResolverInterface $controller_resolver, Fo
   protected function getFormArgument(RouteMatchInterface $route_match) {
     $form_arg = $route_match->getRouteObject()->getDefault('_entity_wizard');
     list($entity_type_id, $operation) = explode('.', $form_arg);
-    $definition = $this->entityManager->getDefinition($entity_type_id);
+    $definition = $this->entityTypeManager->getDefinition($entity_type_id);
     $handlers = $definition->getHandlerClasses();
     if (empty($handlers['wizard'][$operation])) {
       throw new \Exception(sprintf('Unsupported wizard operation %s', $operation));
diff --git a/web/modules/ctools/src/Controller/WizardFormController.php b/web/modules/ctools/src/Controller/WizardFormController.php
index e4492a4c91f07f29b28f8c6fbfae42cd4123acf9..d7eb9b85c1cce856ff7c32d0981ccc9a6ce0937d 100644
--- a/web/modules/ctools/src/Controller/WizardFormController.php
+++ b/web/modules/ctools/src/Controller/WizardFormController.php
@@ -6,7 +6,6 @@
 use Drupal\Core\Controller\FormController;
 use Drupal\Core\Form\FormBuilderInterface;
 use Drupal\Core\Routing\RouteMatchInterface;
-use Drupal\ctools\Wizard\FormWizardInterface;
 use Drupal\ctools\Wizard\WizardFactoryInterface;
 use Symfony\Component\HttpFoundation\Request;
 
@@ -25,7 +24,7 @@ class WizardFormController extends FormController {
   /**
    * Tempstore Factory for keeping track of values in each step of the wizard.
    *
-   * @var \Drupal\user\SharedTempStoreFactory
+   * @var \Drupal\Core\TempStore\SharedTempStoreFactory
    */
   protected $tempstore;
 
diff --git a/web/modules/ctools/src/Event/BlockVariantEvent.php b/web/modules/ctools/src/Event/BlockVariantEvent.php
new file mode 100644
index 0000000000000000000000000000000000000000..35df32dd36dc37554551088c78cd939531c1e49c
--- /dev/null
+++ b/web/modules/ctools/src/Event/BlockVariantEvent.php
@@ -0,0 +1,56 @@
+<?php
+
+namespace Drupal\ctools\Event;
+
+use Drupal\Core\Block\BlockPluginInterface;
+use Drupal\ctools\Plugin\BlockVariantInterface;
+use Symfony\Component\EventDispatcher\Event;
+
+class BlockVariantEvent extends Event {
+
+  /**
+   * The block being acted upon.
+   *
+   * @var \Drupal\Core\Block\BlockPluginInterface
+   */
+  protected $block;
+
+  /**
+   * The variant acting on the block.
+   *
+   * @var \Drupal\ctools\Plugin\BlockVariantInterface
+   */
+  protected $variant;
+
+  /**
+   * BlockVariantEvent constructor.
+   *
+   * @param \Drupal\Core\Block\BlockPluginInterface $block
+   *   The block plugin.
+   * @param \Drupal\ctools\Plugin\BlockVariantInterface $variant
+   *   The variant plugin.
+   */
+  public function __construct(BlockPluginInterface $block, BlockVariantInterface $variant) {
+    $this->block = $block;
+    $this->variant = $variant;
+  }
+
+  /**
+   * Gets the block plugin.
+   *
+   * @return \Drupal\Core\Block\BlockPluginInterface
+   */
+  public function getBlock() {
+    return $this->block;
+  }
+
+  /**
+   * Gets the variant plugin.
+   *
+   * @return \Drupal\ctools\Plugin\BlockVariantInterface
+   */
+  public function getVariant() {
+    return $this->variant;
+  }
+
+}
diff --git a/web/modules/ctools/src/Event/BlockVariantEvents.php b/web/modules/ctools/src/Event/BlockVariantEvents.php
new file mode 100644
index 0000000000000000000000000000000000000000..ea4ec364a8b3578e32956c8a4565e1fd425b66e9
--- /dev/null
+++ b/web/modules/ctools/src/Event/BlockVariantEvents.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace Drupal\ctools\Event;
+
+/**
+ * Contains all events dispatched while manipulating blocks in a variant.
+ */
+final class BlockVariantEvents {
+
+  /**
+   * The name of the event triggered when a block is added to a variant.
+   *
+   * This event allows modules to react to a block being added to a variant. The
+   * event listener method receives a \Drupal\ctools\Event\BlockVariantEvent
+   * instance.
+   *
+   * @Event
+   *
+   * @var string
+   */
+  const ADD_BLOCK = 'block.add';
+
+  /**
+   * The name of the event triggered when a block is modified in a variant.
+   *
+   * This event allows modules to react to a block being modified in a variant.
+   * The event listener method receives a \Drupal\ctools\Event\BlockVariantEvent
+   * instance.
+   *
+   * @Event
+   *
+   * @var string
+   */
+  const UPDATE_BLOCK = 'block.update';
+
+  /**
+   * The name of the event triggered when a block is removed from a variant.
+   *
+   * This event allows modules to react to a block being removed from a variant.
+   * The event listener method receives a \Drupal\ctools\Event\BlockVariantEvent
+   * instance.
+   *
+   * @Event
+   *
+   * @var string
+   */
+  const DELETE_BLOCK = 'block.delete';
+
+}
diff --git a/web/modules/ctools/src/Form/ConditionConfigure.php b/web/modules/ctools/src/Form/ConditionConfigure.php
index fd2608e13c25c160d7de1ed00ce3ea317aa95957..7a370df4be7805b7b5a856b58209b02e38b46824 100644
--- a/web/modules/ctools/src/Form/ConditionConfigure.php
+++ b/web/modules/ctools/src/Form/ConditionConfigure.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\ctools\Form;
 
-
 use Drupal\Component\Plugin\PluginManagerInterface;
 use Drupal\Component\Uuid\Uuid;
 use Drupal\Core\Ajax\AjaxResponse;
@@ -12,7 +11,8 @@
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Plugin\ContextAwarePluginInterface;
 use Drupal\ctools\ConstraintConditionInterface;
-use Drupal\user\SharedTempStoreFactory;
+use Drupal\Core\TempStore\SharedTempStoreFactory;
+use Drupal\Core\Url;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -21,7 +21,7 @@
 abstract class ConditionConfigure extends FormBase {
 
   /**
-   * @var \Drupal\user\SharedTempStoreFactory
+   * @var \Drupal\Core\TempStore\SharedTempStoreFactory
    */
   protected $tempstore;
 
@@ -44,7 +44,7 @@ abstract class ConditionConfigure extends FormBase {
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container) {
-    return new static($container->get('user.shared_tempstore'), $container->get('plugin.manager.condition'));
+    return new static($container->get('tempstore.shared'), $container->get('plugin.manager.condition'));
   }
 
   function __construct(SharedTempStoreFactory $tempstore, PluginManagerInterface $manager) {
@@ -132,7 +132,8 @@ public function ajaxSave(array &$form, FormStateInterface $form_state) {
     $response = new AjaxResponse();
     $cached_values = $this->tempstore->get($this->tempstore_id)->get($this->machine_name);
     list($route_name, $route_parameters) = $this->getParentRouteInfo($cached_values);
-    $response->addCommand(new RedirectCommand($this->url($route_name, $route_parameters)));
+    $url = Url::fromRoute($route_name, $route_parameters);
+    $response->addCommand(new RedirectCommand($url->toString()));
     $response->addCommand(new CloseModalDialogCommand());
     return $response;
   }
diff --git a/web/modules/ctools/src/Form/ConditionDelete.php b/web/modules/ctools/src/Form/ConditionDelete.php
index d2303bc8617709d2e179c4a7b989193d53073ce5..0655934d952c8625294df1f1fc9ffe67bb85fd09 100644
--- a/web/modules/ctools/src/Form/ConditionDelete.php
+++ b/web/modules/ctools/src/Form/ConditionDelete.php
@@ -8,13 +8,13 @@
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Url;
 use Drupal\ctools\ConstraintConditionInterface;
-use Drupal\user\SharedTempStoreFactory;
+use Drupal\Core\TempStore\SharedTempStoreFactory;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 abstract class ConditionDelete extends ConfirmFormBase {
 
   /**
-   * @var \Drupal\user\SharedTempStoreFactory
+   * @var \Drupal\Core\TempStore\SharedTempStoreFactory
    */
   protected $tempstore;
 
@@ -42,7 +42,7 @@ abstract class ConditionDelete extends ConfirmFormBase {
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container) {
-    return new static($container->get('user.shared_tempstore'), $container->get('plugin.manager.condition'));
+    return new static($container->get('tempstore.shared'), $container->get('plugin.manager.condition'));
   }
 
   function __construct(SharedTempStoreFactory $tempstore, PluginManagerInterface $manager) {
diff --git a/web/modules/ctools/src/Form/ContextConfigure.php b/web/modules/ctools/src/Form/ContextConfigure.php
index 142f18abb224c656f39fa5767d490a24e5965781..f5f1c57d5644b2947e10b8dfd047d44dff9a927f 100644
--- a/web/modules/ctools/src/Form/ContextConfigure.php
+++ b/web/modules/ctools/src/Form/ContextConfigure.php
@@ -2,11 +2,9 @@
 
 namespace Drupal\ctools\Form;
 
-
 use Drupal\Core\Ajax\AjaxResponse;
 use Drupal\Core\Ajax\CloseModalDialogCommand;
 use Drupal\Core\Ajax\RedirectCommand;
-use Drupal\Core\Entity\Entity;
 use Drupal\Core\Entity\Plugin\DataType\EntityAdapter;
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
@@ -14,23 +12,31 @@
 use Drupal\Core\Plugin\Context\ContextDefinition;
 use Drupal\Core\Plugin\Context\ContextInterface;
 use Drupal\Core\Url;
-use Drupal\user\SharedTempStoreFactory;
+use Drupal\Core\TempStore\SharedTempStoreFactory;
 use Symfony\Component\DependencyInjection\ContainerInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
 
 abstract class ContextConfigure extends FormBase {
 
   /**
-   * @var \Drupal\user\SharedTempStoreFactory
+   * @var \Drupal\Core\TempStore\SharedTempStoreFactory
    */
   protected $tempstore;
 
+  /**
+   * Object EntityTypeManager.
+   *
+   * @var Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected $entityTypeManager;
+
   /**
    * @var string
    */
   protected $tempstore_id;
 
   /**
-   * @var string;
+   * @var string
    */
   protected $machine_name;
 
@@ -38,11 +44,15 @@ abstract class ContextConfigure extends FormBase {
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container) {
-    return new static($container->get('user.shared_tempstore'));
+    return new static(
+      $container->get('tempstore.shared'),
+      $container->get('entity_type.manager')
+    );
   }
 
-  function __construct(SharedTempStoreFactory $tempstore) {
+  function __construct(SharedTempStoreFactory $tempstore, EntityTypeManagerInterface $entity_type_manager) {
     $this->tempstore = $tempstore;
+    $this->entityTypeManager = $entity_type_manager;
   }
 
   /**
@@ -167,7 +177,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     if (strpos($context_definition->getDataType(), 'entity:') === 0) {
       list(, $entity_type) = explode(':', $context_definition->getDataType());
       if (is_numeric($form_state->getValue('context_value'))) {
-        $value = \Drupal::entityTypeManager()->getStorage($entity_type)->load($form_state->getValue('context_value'));
+        $value = $this->entityTypeManager->getStorage($entity_type)->load($form_state->getValue('context_value'));
       }
     }
     // No loading required for non-entity values.
diff --git a/web/modules/ctools/src/Form/ContextDelete.php b/web/modules/ctools/src/Form/ContextDelete.php
index 06e0794a86fb2122fe270591c687b74ae7d6cdef..ec1406b80bedb48d728232e5219c3dab0860b04b 100644
--- a/web/modules/ctools/src/Form/ContextDelete.php
+++ b/web/modules/ctools/src/Form/ContextDelete.php
@@ -2,10 +2,9 @@
 
 namespace Drupal\ctools\Form;
 
-
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Form\ConfirmFormBase;
-use Drupal\user\SharedTempStoreFactory;
+use Drupal\Core\TempStore\SharedTempStoreFactory;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -14,7 +13,7 @@
 abstract class ContextDelete extends ConfirmFormBase {
 
   /**
-   * @var \Drupal\user\SharedTempStoreFactory
+   * @var \Drupal\Core\TempStore\SharedTempStoreFactory
    */
   protected $tempstore;
 
@@ -36,7 +35,7 @@ abstract class ContextDelete extends ConfirmFormBase {
   protected $context_id;
 
   public static function create(ContainerInterface $container) {
-    return new static($container->get('user.shared_tempstore'));
+    return new static($container->get('tempstore.shared'));
   }
 
   public function __construct(SharedTempStoreFactory $tempstore) {
diff --git a/web/modules/ctools/src/Form/ManageConditions.php b/web/modules/ctools/src/Form/ManageConditions.php
index ee506a89db31b68717214a6f5ed7fc2f3005bf35..7e4bcb6483e9ec43993ebb2d4101fbdca3cc33a4 100644
--- a/web/modules/ctools/src/Form/ManageConditions.php
+++ b/web/modules/ctools/src/Form/ManageConditions.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\ctools\Form;
 
-
 use Drupal\Component\Plugin\PluginManagerInterface;
 use Drupal\Component\Serialization\Json;
 use Drupal\Core\Ajax\AjaxResponse;
@@ -12,6 +11,7 @@
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Url;
 use Symfony\Component\DependencyInjection\ContainerInterface;
+use Drupal\Core\Form\FormBuilder;
 
 abstract class ManageConditions extends FormBase {
 
@@ -20,17 +20,28 @@ abstract class ManageConditions extends FormBase {
    */
   protected $manager;
 
+  /**
+   * The builder of form.
+   *
+   * @var \Drupal\Core\Form\FormBuilder
+   */
+  protected $formBuilder;
+
   /**
    * @var string
    */
   protected $machine_name;
 
   public static function create(ContainerInterface $container) {
-    return new static($container->get('plugin.manager.condition'));
+    return new static(
+      $container->get('plugin.manager.condition'),
+      $container->get('form_builder')
+    );
   }
 
-  function __construct(PluginManagerInterface $manager) {
+  function __construct(PluginManagerInterface $manager, FormBuilder $form_builder) {
     $this->manager = $manager;
+    $this->formBuilder = $form_builder;
   }
 
   /**
@@ -91,11 +102,18 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
 
   public function add(array &$form, FormStateInterface $form_state) {
     $condition = $form_state->getValue('conditions');
-    $content = \Drupal::formBuilder()->getForm($this->getConditionClass(), $condition, $this->getTempstoreId(), $this->machine_name);
+    $content = $this->formBuilder->getForm($this->getConditionClass(), $condition, $this->getTempstoreId(), $this->machine_name);
     $content['#attached']['library'][] = 'core/drupal.dialog.ajax';
     $cached_values = $form_state->getTemporaryValue('wizard');
     list(, $route_parameters) = $this->getOperationsRouteInfo($cached_values, $this->machine_name, $form_state->getValue('conditions'));
-    $content['submit']['#attached']['drupalSettings']['ajax'][$content['submit']['#id']]['url'] = $this->url($this->getAddRoute($cached_values), $route_parameters, ['query' => [FormBuilderInterface::AJAX_FORM_REQUEST => TRUE]]);
+    $route_name = $this->getAddRoute($cached_values);
+    $route_options = [
+      'query' => [
+        FormBuilderInterface::AJAX_FORM_REQUEST => TRUE,
+      ],
+    ];
+    $url = Url::fromRoute($route_name, $route_parameters, $route_options);
+    $content['submit']['#attached']['drupalSettings']['ajax'][$content['submit']['#id']]['url'] = $url->toString();
     $response = new AjaxResponse();
     $response->addCommand(new OpenModalDialogCommand($this->t('Configure Required Context'), $content, array('width' => '700')));
     return $response;
@@ -186,7 +204,7 @@ abstract protected function getTempstoreId();
    * Document the route name and parameters for edit/delete context operations.
    *
    * The route name returned from this method is used as a "base" to which
-   * ".edit" and ".delete" are appeneded in the getOperations() method.
+   * ".edit" and ".delete" are appended in the getOperations() method.
    * Subclassing '\Drupal\ctools\Form\ConditionConfigure' and
    * '\Drupal\ctools\Form\ConditionDelete' should set you up for using this
    * approach quite seamlessly.
diff --git a/web/modules/ctools/src/Form/ManageContext.php b/web/modules/ctools/src/Form/ManageContext.php
index 4ac3b8438f821cbc55e2a6634b0e4cfdb8ac2240..9b9d9cf8f4c157b113520af19e34b652884a4333 100644
--- a/web/modules/ctools/src/Form/ManageContext.php
+++ b/web/modules/ctools/src/Form/ManageContext.php
@@ -10,6 +10,7 @@
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\TypedData\TypedDataManagerInterface;
 use Drupal\Core\Url;
+use Drupal\ctools\TypedDataResolver;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 abstract class ManageContext extends FormBase {
@@ -35,6 +36,13 @@ abstract class ManageContext extends FormBase {
    */
   protected $formBuilder;
 
+  /**
+   * The typed data resolver.
+   *
+   * @var \Drupal\ctools\TypedDataResolver
+   */
+  protected $typedDataResolver;
+
   /**
    * An array of property types that are eligible as relationships.
    *
@@ -49,13 +57,6 @@ abstract class ManageContext extends FormBase {
    */
   protected $relationships = TRUE;
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container) {
-    return new static($container->get('typed_data_manager'), $container->get('form_builder'));
-  }
-
   /**
    * ManageContext constructor.
    *
@@ -63,12 +64,25 @@ public static function create(ContainerInterface $container) {
    *   The typed data manager.
    * @param \Drupal\Core\Form\FormBuilderInterface $form_builder
    *   The form builder.
+   * @param \Drupal\ctools\TypedDataResolver $ctools_typed_data_resolver
+   *   The typed data resolver.
    */
-  public function __construct(TypedDataManagerInterface $typed_data_manager, FormBuilderInterface $form_builder) {
+  public function __construct(TypedDataManagerInterface $typed_data_manager, FormBuilderInterface $form_builder, TypedDataResolver $ctools_typed_data_resolver) {
     $this->typedDataManager = $typed_data_manager;
     $this->formBuilder = $form_builder;
+    $this->typedDataResolver = $ctools_typed_data_resolver;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('typed_data_manager'),
+      $container->get('form_builder'),
+      $container->get('ctools.typed_data.resolver')
+    );
+  }
 
   /**
    * {@inheritdoc}
@@ -160,7 +174,14 @@ public function addContext(array &$form, FormStateInterface $form_state) {
     $content['#attached']['library'][] = 'core/drupal.dialog.ajax';
     $cached_values = $form_state->getTemporaryValue('wizard');
     list(, $route_parameters) = $this->getContextOperationsRouteInfo($cached_values, $this->machine_name, $context);
-    $content['submit']['#attached']['drupalSettings']['ajax'][$content['submit']['#id']]['url'] = $this->url($this->getContextAddRoute($cached_values), $route_parameters, ['query' => [FormBuilderInterface::AJAX_FORM_REQUEST => TRUE]]);
+    $route_name = $this->getContextAddRoute($cached_values);
+    $route_options = [
+      'query' => [
+        FormBuilderInterface::AJAX_FORM_REQUEST => TRUE,
+      ],
+    ];
+    $url = Url::fromRoute($route_name, $route_parameters, $route_options);
+    $content['submit']['#attached']['drupalSettings']['ajax'][$content['submit']['#id']]['url'] = $url->toString();
     $response = new AjaxResponse();
     $response->addCommand(new OpenModalDialogCommand($this->t('Add new context'), $content, array('width' => '700')));
     return $response;
@@ -172,7 +193,14 @@ public function addRelationship(array &$form, FormStateInterface $form_state) {
     $content['#attached']['library'][] = 'core/drupal.dialog.ajax';
     $cached_values = $form_state->getTemporaryValue('wizard');
     list(, $route_parameters) = $this->getRelationshipOperationsRouteInfo($cached_values, $this->machine_name, $relationship);
-    $content['submit']['#attached']['drupalSettings']['ajax'][$content['submit']['#id']]['url'] = $this->url($this->getRelationshipAddRoute($cached_values), $route_parameters, ['query' => [FormBuilderInterface::AJAX_FORM_REQUEST => TRUE]]);
+    $route_name = $this->getRelationshipAddRoute($cached_values);
+    $route_options = [
+      'query' => [
+        FormBuilderInterface::AJAX_FORM_REQUEST => TRUE,
+      ],
+    ];
+    $url = Url::fromRoute($route_name, $route_parameters, $route_options);
+    $content['submit']['#attached']['drupalSettings']['ajax'][$content['submit']['#id']]['url'] = $url->toString();
     $response = new AjaxResponse();
     $response->addCommand(new OpenModalDialogCommand($this->t('Configure Relationship'), $content, array('width' => '700')));
     return $response;
@@ -180,7 +208,7 @@ public function addRelationship(array &$form, FormStateInterface $form_state) {
 
   protected function getAvailableRelationships($cached_values) {
     /** @var \Drupal\ctools\TypedDataResolver $resolver */
-    $resolver = \Drupal::service('ctools.typed_data.resolver');
+    $resolver = $this->typedDataResolver;
     return $resolver->getTokensForContexts($this->getContexts($cached_values));
   }
 
diff --git a/web/modules/ctools/src/Form/ManageResolverRelationships.php b/web/modules/ctools/src/Form/ManageResolverRelationships.php
index 7dfff59825b57cfc214e9a8fa9febe0173597874..bb6bcfb2ef215122e808d831a69dd4af7d4473ca 100644
--- a/web/modules/ctools/src/Form/ManageResolverRelationships.php
+++ b/web/modules/ctools/src/Form/ManageResolverRelationships.php
@@ -9,6 +9,8 @@
 use Drupal\Core\Form\FormBuilderInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Url;
+use Drupal\ctools\TypedDataResolver;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 abstract class ManageResolverRelationships extends FormBase {
 
@@ -24,6 +26,43 @@ abstract class ManageResolverRelationships extends FormBase {
    */
   protected $property_types = [];
 
+  /**
+   * The typed data resolver.
+   *
+   * @var \Drupal\ctools\TypedDataResolver
+   */
+  protected $typedDataResolver;
+
+  /**
+   * The form builder.
+   *
+   * @var \Drupal\Core\Form\FormBuilder
+   */
+  protected $formBuilder;
+
+  /**
+   * Constructs a new ManageResolverRelationships object.
+   *
+   * @param \Drupal\ctools\TypedDataResolver $ctools_typed_data_resolver
+   *   The typed data resolver.
+   * @param \Drupal\Core\Form\FormBuilderInterface $form_builder
+   *   The form builder.
+   */
+  public function __construct(TypedDataResolver $ctools_typed_data_resolver, FormBuilderInterface $form_builder) {
+    $this->typedDataResolver = $ctools_typed_data_resolver;
+    $this->formBuilder = $form_builder;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('ctools.typed_data.resolver'),
+      $container->get('form_builder')
+    );
+  }
+
   /**
    * {@inheritdoc}
    */
@@ -80,11 +119,18 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
 
   public function addRelationship(array &$form, FormStateInterface $form_state) {
     $relationship = $form_state->getValue('relationships');
-    $content = \Drupal::formBuilder()->getForm($this->getContextClass(), $relationship, $this->getTempstoreId(), $this->machine_name);
+    $content = $this->formBuilder->getForm($this->getContextClass(), $relationship, $this->getTempstoreId(), $this->machine_name);
     $content['#attached']['library'][] = 'core/drupal.dialog.ajax';
     $cached_values = $form_state->getTemporaryValue('wizard');
     list(, $route_parameters) = $this->getRelationshipOperationsRouteInfo($cached_values, $this->machine_name, $relationship);
-    $content['submit']['#attached']['drupalSettings']['ajax'][$content['submit']['#id']]['url'] = $this->url($this->getAddRoute($cached_values), $route_parameters, ['query' => [FormBuilderInterface::AJAX_FORM_REQUEST => TRUE]]);
+    $route_name = $this->getAddRoute($cached_values);
+    $route_options = [
+      'query' => [
+        FormBuilderInterface::AJAX_FORM_REQUEST => TRUE,
+      ],
+    ];
+    $url = Url::fromRoute($route_name, $route_parameters, $route_options);
+    $content['submit']['#attached']['drupalSettings']['ajax'][$content['submit']['#id']]['url'] = $url->toString();
     $response = new AjaxResponse();
     $response->addCommand(new OpenModalDialogCommand($this->t('Configure Relationship'), $content, array('width' => '700')));
     return $response;
@@ -92,7 +138,7 @@ public function addRelationship(array &$form, FormStateInterface $form_state) {
 
   protected function getAvailableRelationships($cached_values) {
     /** @var \Drupal\ctools\TypedDataResolver $resolver */
-    $resolver = \Drupal::service('ctools.typed_data.resolver');
+    $resolver = $this->typedDataResolver;
     return $resolver->getTokensForContexts($this->getContexts($cached_values));
   }
 
diff --git a/web/modules/ctools/src/Form/RelationshipConfigure.php b/web/modules/ctools/src/Form/RelationshipConfigure.php
index 4f13f46e860a48fe2c9bbaf7cd52562ad5442195..167ee4cc4db93778864446fc4883f5206fcc7a31 100644
--- a/web/modules/ctools/src/Form/RelationshipConfigure.php
+++ b/web/modules/ctools/src/Form/RelationshipConfigure.php
@@ -8,13 +8,14 @@
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\ctools\TypedDataResolver;
-use Drupal\user\SharedTempStoreFactory;
+use Drupal\Core\TempStore\SharedTempStoreFactory;
+use Drupal\Core\Url;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 abstract class RelationshipConfigure extends FormBase {
 
   /**
-   * @var \Drupal\user\SharedTempStoreFactory
+   * @var \Drupal\Core\TempStore\SharedTempStoreFactory
    */
   protected $tempstore;
 
@@ -37,7 +38,7 @@ abstract class RelationshipConfigure extends FormBase {
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container) {
-    return new static($container->get('user.shared_tempstore'), $container->get('ctools.typed_data.resolver'));
+    return new static($container->get('tempstore.shared'), $container->get('ctools.typed_data.resolver'));
   }
 
   public function __construct(SharedTempStoreFactory $tempstore, TypedDataResolver $resolver) {
@@ -111,7 +112,8 @@ public function ajaxSave(array &$form, FormStateInterface $form_state) {
     $cached_values = $this->tempstore->get($this->tempstore_id)->get($this->machine_name);
     list($route_name, $route_parameters) = $this->getParentRouteInfo($cached_values);
     $response = new AjaxResponse();
-    $response->addCommand(new RedirectCommand($this->url($route_name, $route_parameters)));
+    $url = Url::fromRoute($route_name, $route_parameters);
+    $response->addCommand(new RedirectCommand($url->toString()));
     $response->addCommand(new CloseModalDialogCommand());
     return $response;
   }
diff --git a/web/modules/ctools/src/Form/RequiredContext.php b/web/modules/ctools/src/Form/RequiredContext.php
index 76b5ec2da310bb78745410bea7b001ef3d009486..07ae6be6754f2d95dcbe66d467d940b621d458e9 100644
--- a/web/modules/ctools/src/Form/RequiredContext.php
+++ b/web/modules/ctools/src/Form/RequiredContext.php
@@ -9,6 +9,7 @@
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Url;
 use Symfony\Component\DependencyInjection\ContainerInterface;
+use Drupal\Core\Form\FormBuilder;
 
 abstract class RequiredContext extends FormBase {
 
@@ -17,6 +18,13 @@ abstract class RequiredContext extends FormBase {
    */
   protected $typedDataManager;
 
+  /**
+   * The builder of form.
+   *
+   * @var \Drupal\Core\Form\FormBuilder
+   */
+  protected $formBuilder;
+
   /**
    * @var string
    */
@@ -26,11 +34,15 @@ abstract class RequiredContext extends FormBase {
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container) {
-    return new static($container->get('typed_data_manager'));
+    return new static(
+      $container->get('typed_data_manager'),
+      $container->get('form_builder')
+    );
   }
 
-  public function __construct(PluginManagerInterface $typed_data_manager) {
+  public function __construct(PluginManagerInterface $typed_data_manager, FormBuilder $form_builder) {
     $this->typedDataManager = $typed_data_manager;
+    $this->formBuilder = $form_builder;
   }
 
   /**
@@ -98,7 +110,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
    */
   public function add(array &$form, FormStateInterface $form_state) {
     $context = $form_state->getValue('contexts');
-    $content = \Drupal::formBuilder()->getForm($this->getContextClass(), $context, $this->getTempstoreId(), $this->machine_name);
+    $content = $this->formBuilder->getForm($this->getContextClass(), $context, $this->getTempstoreId(), $this->machine_name);
     $content['#attached']['library'][] = 'core/drupal.dialog.ajax';
     $response = new AjaxResponse();
     $response->addCommand(new OpenModalDialogCommand($this->t('Configure Required Context'), $content, array('width' => '700')));
@@ -183,7 +195,7 @@ abstract protected function getTempstoreId();
    * Document the route name and parameters for edit/delete context operations.
    *
    * The route name returned from this method is used as a "base" to which
-   * ".edit" and ".delete" are appeneded in the getOperations() method.
+   * ".edit" and ".delete" are appended in the getOperations() method.
    * Subclassing '\Drupal\ctools\Form\ContextConfigure' and
    * '\Drupal\ctools\Form\RequiredContextDelete' should set you up for using
    * this approach quite seamlessly.
diff --git a/web/modules/ctools/src/Form/RequiredContextDelete.php b/web/modules/ctools/src/Form/RequiredContextDelete.php
index e04429a98ff18a3cd7ef906698557d7ea9ddb496..e65ce80f205edd20b8ed05dbc0572345ea91bf2f 100644
--- a/web/modules/ctools/src/Form/RequiredContextDelete.php
+++ b/web/modules/ctools/src/Form/RequiredContextDelete.php
@@ -6,7 +6,7 @@
 use Drupal\Core\Form\ConfirmFormHelper;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Url;
-use Drupal\user\SharedTempStoreFactory;
+use Drupal\Core\TempStore\SharedTempStoreFactory;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -15,7 +15,7 @@
 abstract class RequiredContextDelete extends ConfirmFormBase {
 
   /**
-   * @var \Drupal\user\SharedTempStoreFactory
+   * @var \Drupal\Core\TempStore\SharedTempStoreFactory
    */
   protected $tempstore;
 
@@ -38,11 +38,11 @@ abstract class RequiredContextDelete extends ConfirmFormBase {
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container) {
-    return new static($container->get('user.shared_tempstore'));
+    return new static($container->get('tempstore.shared'));
   }
 
   /**
-   * @param \Drupal\user\SharedTempStoreFactory $tempstore
+   * @param \Drupal\Core\TempStore\SharedTempStoreFactory $tempstore
    */
   function __construct(SharedTempStoreFactory $tempstore) {
     $this->tempstore = $tempstore;
diff --git a/web/modules/ctools/src/Form/ResolverRelationshipConfigure.php b/web/modules/ctools/src/Form/ResolverRelationshipConfigure.php
index 00234cd9ab500766f9fe11cb7d1def448f0e5edf..5ec43d5f9148f7373719d35bf4d23720f9cfc40b 100644
--- a/web/modules/ctools/src/Form/ResolverRelationshipConfigure.php
+++ b/web/modules/ctools/src/Form/ResolverRelationshipConfigure.php
@@ -2,19 +2,19 @@
 
 namespace Drupal\ctools\Form;
 
-
 use Drupal\Core\Ajax\AjaxResponse;
 use Drupal\Core\Ajax\CloseModalDialogCommand;
 use Drupal\Core\Ajax\RedirectCommand;
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\user\SharedTempStoreFactory;
+use Drupal\Core\TempStore\SharedTempStoreFactory;
+use Drupal\Core\Url;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 abstract class ResolverRelationshipConfigure extends FormBase {
 
   /**
-   * @var \Drupal\user\SharedTempStoreFactory
+   * @var \Drupal\Core\TempStore\SharedTempStoreFactory
    */
   protected $tempstore;
 
@@ -32,7 +32,7 @@ abstract class ResolverRelationshipConfigure extends FormBase {
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container) {
-    return new static($container->get('user.shared_tempstore'));
+    return new static($container->get('tempstore.shared'));
   }
 
   function __construct(SharedTempStoreFactory $tempstore) {
@@ -141,7 +141,8 @@ public function ajaxSave(array &$form, FormStateInterface $form_state) {
     $response = new AjaxResponse();
     $cached_values = $this->tempstore->get($this->tempstore_id)->get($this->machine_name);
     list($route_name, $route_parameters) = $this->getParentRouteInfo($cached_values);
-    $response->addCommand(new RedirectCommand($this->url($route_name, $route_parameters)));
+    $url = Url::fromRoute($route_name, $route_parameters);
+    $response->addCommand(new RedirectCommand($url->toString()));
     $response->addCommand(new CloseModalDialogCommand());
     return $response;
   }
diff --git a/web/modules/ctools/src/Form/ResolverRelationshipDelete.php b/web/modules/ctools/src/Form/ResolverRelationshipDelete.php
index 4dfde28560fd9e4a98fad91a8092702ad1267c0b..7195e3cf8003d199933aadb6864109d392ccabbd 100644
--- a/web/modules/ctools/src/Form/ResolverRelationshipDelete.php
+++ b/web/modules/ctools/src/Form/ResolverRelationshipDelete.php
@@ -2,18 +2,17 @@
 
 namespace Drupal\ctools\Form;
 
-
 use Drupal\Core\Form\ConfirmFormBase;
 use Drupal\Core\Form\ConfirmFormHelper;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\ctools\TypedDataResolver;
-use Drupal\user\SharedTempStoreFactory;
+use Drupal\Core\TempStore\SharedTempStoreFactory;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 abstract class ResolverRelationshipDelete extends ConfirmFormBase {
 
   /**
-   * @var \Drupal\user\SharedTempStoreFactory
+   * @var \Drupal\Core\TempStore\SharedTempStoreFactory
    */
   protected $tempstore;
 
@@ -41,14 +40,14 @@ abstract class ResolverRelationshipDelete extends ConfirmFormBase {
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container) {
-    return new static($container->get('user.shared_tempstore'), $container->get('ctools.typed_data.resolver'));
+    return new static($container->get('tempstore.shared'), $container->get('ctools.typed_data.resolver'));
   }
 
   /**
-   * @param \Drupal\user\SharedTempStoreFactory $tempstore
+   * @param \Drupal\Core\TempStore\SharedTempStoreFactory $tempstore
    *   The shared tempstore.
    * @param \Drupal\ctools\TypedDataResolver $resolver
-   *   The the typed data resolver.
+   *   The typed data resolver.
    */
   public function __construct(SharedTempStoreFactory $tempstore, TypedDataResolver $resolver) {
     $this->tempstore = $tempstore;
diff --git a/web/modules/ctools/src/ParamConverter/TempstoreConverter.php b/web/modules/ctools/src/ParamConverter/TempstoreConverter.php
index 6458d90e2c13f2d517eabdd55f7c4912ae525ea8..939bd87d6177bbe8f52e938b43e5fb7f2ef229c9 100644
--- a/web/modules/ctools/src/ParamConverter/TempstoreConverter.php
+++ b/web/modules/ctools/src/ParamConverter/TempstoreConverter.php
@@ -3,10 +3,9 @@
 namespace Drupal\ctools\ParamConverter;
 
 use Drupal\Component\Utility\NestedArray;
-use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\ParamConverter\ParamConverterInterface;
-use Drupal\user\SharedTempStoreFactory;
+use Drupal\Core\TempStore\SharedTempStoreFactory;
 use Symfony\Component\Routing\Route;
 
 /**
@@ -83,7 +82,7 @@ class TempstoreConverter implements ParamConverterInterface {
   /**
    * The tempstore factory.
    *
-   * @var \Drupal\user\SharedTempStoreFactory
+   * @var \Drupal\Core\TempStore\SharedTempStoreFactory
    */
   protected $tempstore;
 
@@ -97,7 +96,7 @@ class TempstoreConverter implements ParamConverterInterface {
   /**
    * Constructs a TempstoreConverter.
    *
-   * @param \Drupal\user\SharedTempStoreFactory $tempstore
+   * @param \Drupal\Core\TempStore\SharedTempStoreFactory $tempstore
    */
   public function __construct(SharedTempStoreFactory $tempstore, EntityTypeManagerInterface $entity_type_manager) {
     $this->tempstore = $tempstore;
diff --git a/web/modules/ctools/src/Plugin/Block/EntityView.php b/web/modules/ctools/src/Plugin/Block/EntityView.php
index 51342d010c02271d8fa8b3221879c8774190e6c8..3db471cf2204c1e8d45d81831af1345c699ba596 100644
--- a/web/modules/ctools/src/Plugin/Block/EntityView.php
+++ b/web/modules/ctools/src/Plugin/Block/EntityView.php
@@ -4,7 +4,8 @@
 
 use Drupal\Core\Block\BlockBase;
 use Drupal\Core\Cache\CacheableMetadata;
-use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Entity\EntityDisplayRepositoryInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\Core\Plugin\ContextAwarePluginInterface;
@@ -21,11 +22,18 @@
 class EntityView extends BlockBase implements ContextAwarePluginInterface, ContainerFactoryPluginInterface {
 
   /**
-   * The entity manager.
+   * The entity type manager.
    *
-   * @var \Drupal\Core\Entity\EntityManagerInterface
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
    */
-  protected $entityManager;
+  protected $entityTypeManager;
+
+  /**
+   * The entity display repository.
+   *
+   * @var \Drupal\Core\Entity\EntityDisplayRepositoryInterface
+   */
+  protected $entityDisplayRepository;
 
   /**
    * Constructs a new EntityView.
@@ -36,13 +44,16 @@ class EntityView extends BlockBase implements ContextAwarePluginInterface, Conta
    *   The plugin ID for the plugin instance.
    * @param mixed $plugin_definition
    *   The plugin implementation definition.
-   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
-   *   The entity manager.
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity type manager.
+   * @param \Drupal\Core\Entity\EntityDisplayRepositoryInterface $entity_display_repository
+   *   The entity display repository.
    */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $entity_manager) {
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, EntityDisplayRepositoryInterface $entity_display_repository) {
     parent::__construct($configuration, $plugin_id, $plugin_definition);
 
-    $this->entityManager = $entity_manager;
+    $this->entityTypeManager = $entity_type_manager;
+    $this->entityDisplayRepository = $entity_display_repository;
   }
 
   /**
@@ -53,7 +64,8 @@ public static function create(ContainerInterface $container, array $configuratio
       $configuration,
       $plugin_id,
       $plugin_definition,
-      $container->get('entity.manager')
+      $container->get('entity_type.manager'),
+      $container->get('entity_display.repository')
     );
   }
 
@@ -72,7 +84,7 @@ public function defaultConfiguration() {
   public function blockForm($form, FormStateInterface $form_state) {
     $form['view_mode'] = [
       '#type' => 'select',
-      '#options' => $this->entityManager->getViewModeOptions($this->getDerivativeId()),
+      '#options' => $this->entityDisplayRepository->getViewModeOptions($this->getDerivativeId()),
       '#title' => $this->t('View mode'),
       '#default_value' => $this->configuration['view_mode'],
     ];
@@ -93,7 +105,7 @@ public function build() {
     /** @var $entity \Drupal\Core\Entity\EntityInterface */
     $entity = $this->getContextValue('entity');
 
-    $view_builder = $this->entityManager->getViewBuilder($entity->getEntityTypeId());
+    $view_builder = $this->entityTypeManager->getViewBuilder($entity->getEntityTypeId());
     $build = $view_builder->view($entity, $this->configuration['view_mode']);
 
     CacheableMetadata::createFromObject($this->getContext('entity'))
diff --git a/web/modules/ctools/src/Plugin/BlockVariantTrait.php b/web/modules/ctools/src/Plugin/BlockVariantTrait.php
index fa0187073dea75f89973bab1e9049302e0f1bcd5..f368f2c751c20135da5f726855422aecfdfa7994 100644
--- a/web/modules/ctools/src/Plugin/BlockVariantTrait.php
+++ b/web/modules/ctools/src/Plugin/BlockVariantTrait.php
@@ -2,6 +2,9 @@
 
 namespace Drupal\ctools\Plugin;
 
+use Drupal\ctools\Event\BlockVariantEvent;
+use Drupal\ctools\Event\BlockVariantEvents;
+
 /**
  * Provides methods for \Drupal\ctools\Plugin\BlockVariantInterface.
  */
@@ -21,6 +24,13 @@ trait BlockVariantTrait {
    */
   protected $blockPluginCollection;
 
+  /**
+   * The event dispatcher.
+   *
+   * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
+   */
+  protected $eventDispatcher;
+
   /**
    * @see \Drupal\ctools\Plugin\BlockVariantInterface::getRegionNames()
    */
@@ -39,6 +49,12 @@ public function getBlock($block_id) {
   public function addBlock(array $configuration) {
     $configuration['uuid'] = $this->uuidGenerator()->generate();
     $this->getBlockCollection()->addInstanceId($configuration['uuid'], $configuration);
+
+    $block = $this->getBlock($configuration['uuid']);
+    // Allow modules to react to the change.
+    $event = new BlockVariantEvent($block, $this);
+    $this->eventDispatcher()->dispatch(BlockVariantEvents::ADD_BLOCK, $event);
+
     return $configuration['uuid'];
   }
 
@@ -46,7 +62,13 @@ public function addBlock(array $configuration) {
    * @see \Drupal\ctools\Plugin\BlockVariantInterface::removeBlock()
    */
   public function removeBlock($block_id) {
+    $block = $this->getBlock($block_id);
     $this->getBlockCollection()->removeInstanceId($block_id);
+
+    // Allow modules to react to the change.
+    $event = new BlockVariantEvent($block, $this);
+    $this->eventDispatcher()->dispatch(BlockVariantEvents::DELETE_BLOCK, $event);
+
     return $this;
   }
 
@@ -54,8 +76,14 @@ public function removeBlock($block_id) {
    * @see \Drupal\ctools\Plugin\BlockVariantInterface::updateBlock()
    */
   public function updateBlock($block_id, array $configuration) {
-    $existing_configuration = $this->getBlock($block_id)->getConfiguration();
+    $block = $this->getBlock($block_id);
+    $existing_configuration = $block->getConfiguration();
     $this->getBlockCollection()->setInstanceConfiguration($block_id, $configuration + $existing_configuration);
+
+    // Allow modules to react to the change.
+    $event = new BlockVariantEvent($block, $this);
+    $this->eventDispatcher()->dispatch(BlockVariantEvents::UPDATE_BLOCK, $event);
+
     return $this;
   }
 
@@ -112,6 +140,18 @@ protected function getBlockCollection() {
     return $this->blockPluginCollection;
   }
 
+  /**
+   * Gets the event dispatcher.
+   *
+   * @return \Symfony\Component\EventDispatcher\EventDispatcherInterface
+   */
+  protected function eventDispatcher() {
+    if (!$this->eventDispatcher) {
+      $this->eventDispatcher = \Drupal::service('event_dispatcher');
+    }
+    return $this->eventDispatcher;
+  }
+
   /**
    * Returns the UUID generator.
    *
diff --git a/web/modules/ctools/src/Plugin/Deriver/EntityBundle.php b/web/modules/ctools/src/Plugin/Deriver/EntityBundle.php
index 073ab4a897f075a2aeff4ff96de4cf5b7140a7d0..1adf7058077f4e7dd27f8b50220ff49cbd895920 100644
--- a/web/modules/ctools/src/Plugin/Deriver/EntityBundle.php
+++ b/web/modules/ctools/src/Plugin/Deriver/EntityBundle.php
@@ -13,7 +13,7 @@ class EntityBundle extends EntityDeriverBase {
    * {@inheritdoc}
    */
   public function getDerivativeDefinitions($base_plugin_definition) {
-    foreach ($this->entityManager->getDefinitions() as $entity_type_id => $entity_type) {
+    foreach ($this->entityTypeManager->getDefinitions() as $entity_type_id => $entity_type) {
       if ($entity_type->hasKey('bundle')) {
         $this->derivatives[$entity_type_id] = $base_plugin_definition;
         $this->derivatives[$entity_type_id]['label'] = $this->getEntityBundleLabel($entity_type);
@@ -43,7 +43,7 @@ protected function getEntityBundleLabel($entity_type) {
     $fallback = $entity_type->getLabel();
     if ($bundle_entity_type = $entity_type->getBundleEntityType()) {
       // This is a better fallback.
-      $fallback =  $this->entityManager->getDefinition($bundle_entity_type)->getLabel();
+      $fallback =  $this->entityTypeManager->getDefinition($bundle_entity_type)->getLabel();
     }
 
     return $this->t('@label bundle', ['@label' => $fallback]);
diff --git a/web/modules/ctools/src/Plugin/Deriver/EntityDeriverBase.php b/web/modules/ctools/src/Plugin/Deriver/EntityDeriverBase.php
index 1adec996536209eb5f0895784ff09efa91927681..9fc99baa2e69b7068e9802f90924a9107e6d913d 100644
--- a/web/modules/ctools/src/Plugin/Deriver/EntityDeriverBase.php
+++ b/web/modules/ctools/src/Plugin/Deriver/EntityDeriverBase.php
@@ -4,7 +4,9 @@
 
 
 use Drupal\Component\Plugin\Derivative\DeriverBase;
-use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Entity\EntityFieldManagerInterface;
+use Drupal\Core\Entity\EntityTypeRepositoryInterface;
 use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Drupal\Core\StringTranslation\TranslationInterface;
@@ -18,23 +20,43 @@ abstract class EntityDeriverBase extends DeriverBase implements ContainerDeriver
   use StringTranslationTrait;
 
   /**
-   * The entity manager.
+   * The entity type manager.
    *
-   * @var \Drupal\Core\Entity\EntityManagerInterface
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
    */
-  protected $entityManager;
+  protected $entityTypeManager;
+
+  /**
+   * The entity field manager.
+   *
+   * @var \Drupal\Core\Entity\EntityFieldManagerInterface
+   */
+  protected $entityFieldManager;
+
+  /**
+   * The entity type repository.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeRepositoryInterface
+   */
+  protected $entityTypeRepository;
 
   /**
    * Constructs new EntityViewDeriver.
    *
-   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
-   *   The entity manager.
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity type manager.
    * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
    *   The string translation service.
+   * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
+   *   The entity field manager.
+   * @param \Drupal\Core\Entity\EntityTypeRepositoryInterface $entity_type_repository
+   *   The entity type repository.
    */
-  public function __construct(EntityManagerInterface $entity_manager, TranslationInterface $string_translation) {
-    $this->entityManager = $entity_manager;
+  public function __construct(EntityTypeManagerInterface $entity_type_manager, TranslationInterface $string_translation, EntityFieldManagerInterface $entity_field_manager, EntityTypeRepositoryInterface $entity_type_repository) {
+    $this->entityTypeManager = $entity_type_manager;
     $this->stringTranslation = $string_translation;
+    $this->entityFieldManager = $entity_field_manager;
+    $this->entityTypeRepository = $entity_type_repository;
   }
 
   /**
@@ -42,8 +64,10 @@ public function __construct(EntityManagerInterface $entity_manager, TranslationI
    */
   public static function create(ContainerInterface $container, $base_plugin_id) {
     return new static(
-      $container->get('entity.manager'),
-      $container->get('string_translation')
+      $container->get('entity_type.manager'),
+      $container->get('string_translation'),
+      $container->get('entity_field.manager'),
+      $container->get('entity_type.repository')
     );
   }
 
diff --git a/web/modules/ctools/src/Plugin/Deriver/EntityViewDeriver.php b/web/modules/ctools/src/Plugin/Deriver/EntityViewDeriver.php
index f8f189c5fa87ae922463e70fe848a70c0d677cd0..0e2c725e81d5414cfbfb5ed24bbca10c8e8f1292 100644
--- a/web/modules/ctools/src/Plugin/Deriver/EntityViewDeriver.php
+++ b/web/modules/ctools/src/Plugin/Deriver/EntityViewDeriver.php
@@ -13,7 +13,7 @@ class EntityViewDeriver extends EntityDeriverBase {
    * {@inheritdoc}
    */
   public function getDerivativeDefinitions($base_plugin_definition) {
-    foreach ($this->entityManager->getDefinitions() as $entity_type_id => $entity_type) {
+    foreach ($this->entityTypeManager->getDefinitions() as $entity_type_id => $entity_type) {
       if ($entity_type->hasViewBuilderClass()) {
         $this->derivatives[$entity_type_id] = $base_plugin_definition;
         $this->derivatives[$entity_type_id]['admin_label'] = $this->t('Entity view (@label)', ['@label' => $entity_type->getLabel()]);
diff --git a/web/modules/ctools/src/Plugin/DisplayVariant/BlockDisplayVariant.php b/web/modules/ctools/src/Plugin/DisplayVariant/BlockDisplayVariant.php
index 32c6e86fd0f548b332a5d1afdb3caecd8fdda3ee..eb8615da68ecfa6dcfa8cb19de6b0ac65cc9cd0c 100644
--- a/web/modules/ctools/src/Plugin/DisplayVariant/BlockDisplayVariant.php
+++ b/web/modules/ctools/src/Plugin/DisplayVariant/BlockDisplayVariant.php
@@ -4,13 +4,11 @@
 
 use Drupal\Component\Uuid\UuidInterface;
 use Drupal\Core\Block\BlockManager;
-use Drupal\Core\Cache\RefinableCacheableDependencyInterface;
 use Drupal\Core\Condition\ConditionManager;
 use Drupal\Core\Display\VariantBase;
 use Drupal\Core\Display\ContextAwareVariantInterface;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\Core\Plugin\Context\ContextHandlerInterface;
-use Drupal\Core\Render\Element;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\Utility\Token;
 use Drupal\ctools\Form\AjaxFormTrait;
@@ -21,7 +19,7 @@
 /**
  * Provides a base class for a display variant that simply contains blocks.
  */
-abstract class BlockDisplayVariant extends VariantBase implements ContextAwareVariantInterface, ContainerFactoryPluginInterface, BlockVariantInterface, RefinableCacheableDependencyInterface {
+abstract class BlockDisplayVariant extends VariantBase implements ContextAwareVariantInterface, ContainerFactoryPluginInterface, BlockVariantInterface {
 
   use AjaxFormTrait;
   use BlockVariantTrait;
diff --git a/web/modules/ctools/src/Plugin/Relationship/TypedDataEntityRelationship.php b/web/modules/ctools/src/Plugin/Relationship/TypedDataEntityRelationship.php
index ce96841d307a31341117f0d981ecddd0b41e8991..bee44c509d3a9ac98b9ee748e7c8c3ba8b3921b1 100644
--- a/web/modules/ctools/src/Plugin/Relationship/TypedDataEntityRelationship.php
+++ b/web/modules/ctools/src/Plugin/Relationship/TypedDataEntityRelationship.php
@@ -1,6 +1,7 @@
 <?php
 
 namespace Drupal\ctools\Plugin\Relationship;
+
 use Drupal\Core\Plugin\Context\Context;
 use Drupal\Core\Plugin\Context\ContextDefinition;
 
diff --git a/web/modules/ctools/src/Plugin/Relationship/TypedDataLanguageRelationship.php b/web/modules/ctools/src/Plugin/Relationship/TypedDataLanguageRelationship.php
index c198231808cff944876ff81015d81a43f3975beb..17794eb4d1b55a629d5a766177a9441a626dc56a 100644
--- a/web/modules/ctools/src/Plugin/Relationship/TypedDataLanguageRelationship.php
+++ b/web/modules/ctools/src/Plugin/Relationship/TypedDataLanguageRelationship.php
@@ -1,6 +1,7 @@
 <?php
 
 namespace Drupal\ctools\Plugin\Relationship;
+
 use Drupal\Core\Plugin\Context\Context;
 use Drupal\Core\Plugin\Context\ContextDefinition;
 
diff --git a/web/modules/ctools/src/Plugin/Relationship/TypedDataRelationship.php b/web/modules/ctools/src/Plugin/Relationship/TypedDataRelationship.php
index d795f28caef71c45314bec62192ff3d630849350..6c8523b55d8de0da47e245898dcf9d2b01a1631e 100644
--- a/web/modules/ctools/src/Plugin/Relationship/TypedDataRelationship.php
+++ b/web/modules/ctools/src/Plugin/Relationship/TypedDataRelationship.php
@@ -2,9 +2,7 @@
 
 namespace Drupal\ctools\Plugin\Relationship;
 
-
 use Drupal\Core\Field\FieldItemInterface;
-use Drupal\Core\Field\TypedData\FieldItemDataDefinition;
 use Drupal\Core\Plugin\Context\Context;
 use Drupal\Core\Plugin\Context\ContextDefinition;
 use Drupal\Core\Plugin\Context\ContextInterface;
diff --git a/web/modules/ctools/src/Plugin/RelationshipManagerInterface.php b/web/modules/ctools/src/Plugin/RelationshipManagerInterface.php
index a97fa1ffaa099a007982425d80199144d287e1e9..6de2395b5aebfbfc3a8cf01e51f71dff98a1713d 100644
--- a/web/modules/ctools/src/Plugin/RelationshipManagerInterface.php
+++ b/web/modules/ctools/src/Plugin/RelationshipManagerInterface.php
@@ -1,6 +1,7 @@
 <?php
 
 namespace Drupal\ctools\Plugin;
+
 use Drupal\Component\Plugin\Discovery\CachedDiscoveryInterface;
 use Drupal\Core\Plugin\Context\ContextAwarePluginManagerInterface;
 
diff --git a/web/modules/ctools/src/Routing/Enhancer/WizardEnhancer.php b/web/modules/ctools/src/Routing/Enhancer/WizardEnhancer.php
index 3e125eb9e75d4c4989ec9e6a977acd915161dfc6..e16f6d2648f825f290179fbe034e92759f1c6b70 100644
--- a/web/modules/ctools/src/Routing/Enhancer/WizardEnhancer.php
+++ b/web/modules/ctools/src/Routing/Enhancer/WizardEnhancer.php
@@ -2,33 +2,46 @@
 
 namespace Drupal\ctools\Routing\Enhancer;
 
-use Drupal\Core\Routing\Enhancer\RouteEnhancerInterface;
+use Drupal\Core\Routing\EnhancerInterface;
+use Symfony\Cmf\Component\Routing\RouteObjectInterface;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\Routing\Route;
 
 /**
  * Sets the request format onto the request object.
  */
-class WizardEnhancer implements RouteEnhancerInterface {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function applies(Route $route) {
-    return !$route->hasDefault('_controller') && ($route->hasDefault('_wizard') || $route->hasDefault('_entity_wizard'));
-  }
+class WizardEnhancer implements EnhancerInterface {
 
   /**
    * {@inheritdoc}
    */
   public function enhance(array $defaults, Request $request) {
+    $route = $defaults[RouteObjectInterface::ROUTE_OBJECT];
+    if (!$this->isApplicable($route)) {
+      return $defaults;
+    }
+
     if (!empty($defaults['_wizard'])) {
       $defaults['_controller'] = 'ctools.wizard.form:getContentResult';
     }
     if (!empty($defaults['_entity_wizard'])) {
       $defaults['_controller'] = 'ctools.wizard.entity.form:getContentResult';
     }
+
     return $defaults;
   }
 
+  /**
+   * Returns if current route use ctools default parameters.
+   *
+   * @param \Symfony\Component\Routing\Route $route
+   *   The route to check.
+   *
+   * @return bool
+   *   TRUE if the route use one of ctools route default parameters or FALSE.
+   */
+  public function isApplicable(Route $route) {
+    return !$route->hasDefault('_controller') && ($route->hasDefault('_wizard') || $route->hasDefault('_entity_wizard'));
+  }
+
 }
diff --git a/web/modules/ctools/src/SerializableTempstore.php b/web/modules/ctools/src/SerializableTempstore.php
index 65567edc51be5e5e2aad2f1c79f51a2cfac46304..2fbac0b70ce1d834efaafdc6cd3b6812c1acda4d 100644
--- a/web/modules/ctools/src/SerializableTempstore.php
+++ b/web/modules/ctools/src/SerializableTempstore.php
@@ -3,7 +3,7 @@
 namespace Drupal\ctools;
 
 use Drupal\Core\DependencyInjection\DependencySerializationTrait;
-use Drupal\user\SharedTempStore;
+use Drupal\Core\TempStore\SharedTempStore;
 
 /**
  * An extension of the SharedTempStore system for serialized data.
diff --git a/web/modules/ctools/src/SerializableTempstoreFactory.php b/web/modules/ctools/src/SerializableTempstoreFactory.php
index 51cf02b460dd5f018f94c18ab44a9eaa02c6394a..c3e283b9dc813d5c602ef516268fdb966274015f 100644
--- a/web/modules/ctools/src/SerializableTempstoreFactory.php
+++ b/web/modules/ctools/src/SerializableTempstoreFactory.php
@@ -2,25 +2,55 @@
 
 namespace Drupal\ctools;
 
-use Drupal\user\SharedTempStoreFactory;
+use Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface;
+use Drupal\Core\Lock\LockBackendInterface;
+use Drupal\Core\Session\AccountProxyInterface;
+use Drupal\Core\TempStore\SharedTempStoreFactory;
+use Symfony\Component\HttpFoundation\RequestStack;
 
 /**
  * A factory for creating SerializableTempStore objects.
  */
 class SerializableTempstoreFactory extends SharedTempStoreFactory {
 
+  /**
+   * The current logged user.
+   *
+   * @var \Drupal\Core\Session\AccountProxyInterface
+   */
+  protected $currentUser;
+
+  /**
+   * Constructs a Drupal\Core\TempStore\SharedTempStoreFactory object.
+   *
+   * @param \Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface $storage_factory
+   *   The key/value store factory.
+   * @param \Drupal\Core\Lock\LockBackendInterface $lock_backend
+   *   The lock object used for this data.
+   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
+   *   The request stack.
+   * @param int $expire
+   *   The time to live for items, in seconds.
+   * @param \Drupal\Core\Session\AccountProxyInterface|null $current_user
+   *   The current logged user.
+   */
+  public function __construct(KeyValueExpirableFactoryInterface $storage_factory, LockBackendInterface $lock_backend, RequestStack $request_stack, $expire = 604800, AccountProxyInterface $current_user = NULL) {
+    parent::__construct($storage_factory, $lock_backend, $request_stack, $expire);
+    $this->currentUser = $current_user ?: \Drupal::currentUser();
+  }
+
   /**
    * {@inheritdoc}
    */
-  function get($collection, $owner = NULL) {
+  public function get($collection, $owner = NULL) {
     // Use the currently authenticated user ID or the active user ID unless the
     // owner is overridden.
     if (!isset($owner)) {
-      $owner = \Drupal::currentUser()->id() ?: session_id();
+      $owner = $this->currentUser->id() ?: session_id();
     }
 
     // Store the data for this collection in the database.
-    $storage = $this->storageFactory->get("user.shared_tempstore.$collection");
+    $storage = $this->storageFactory->get("tempstore.shared.$collection");
     return new SerializableTempstore($storage, $this->lockBackend, $owner, $this->requestStack, $this->expire);
   }
 
diff --git a/web/modules/ctools/src/Testing/EntityCreationTrait.php b/web/modules/ctools/src/Testing/EntityCreationTrait.php
index 358f8a17a4f821ec8109662f339472a1a974a11f..6de483d60ae0a8d3978e21a8257ee6401cbb7eb6 100644
--- a/web/modules/ctools/src/Testing/EntityCreationTrait.php
+++ b/web/modules/ctools/src/Testing/EntityCreationTrait.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\ctools\Testing;
 
-
 use Drupal\Component\Render\FormattableMarkup;
 
 trait EntityCreationTrait {
diff --git a/web/modules/ctools/src/Tests/Wizard/CToolsWizardTest.php b/web/modules/ctools/src/Tests/Wizard/CToolsWizardTest.php
index c9b91eada8a020fbfc9335c1a691e0be17defd56..d459dfc38314fbb4c99f4e892b1bdba2c9a03fb7 100644
--- a/web/modules/ctools/src/Tests/Wizard/CToolsWizardTest.php
+++ b/web/modules/ctools/src/Tests/Wizard/CToolsWizardTest.php
@@ -1,43 +1,44 @@
 <?php
 
-namespace Drupal\ctools\Tests\Wizard;
+namespace Drupal\Tests\ctools\Functional;
 
-
-use Drupal\simpletest\WebTestBase;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
-
+use Drupal\Tests\BrowserTestBase;
 
 /**
  * Tests basic wizard functionality.
  *
  * @group ctools
  */
-class CToolsWizardTest extends WebTestBase {
+class CToolsWizardTest extends BrowserTestBase {
 
   use StringTranslationTrait;
-  public static $modules = array('ctools', 'ctools_wizard_test');
+  public static $modules = ['ctools', 'ctools_wizard_test'];
 
-  function testWizardSteps() {
+  /**
+   * Test wizard Multistep form.
+   */
+  public function testWizardSteps() {
     $this->drupalGet('ctools/wizard');
-    $this->assertText('Form One');
+    $this->assertSession()->pageTextContains('Form One');
     $this->dumpHeaders = TRUE;
     // Check that $operations['one']['values'] worked.
-    $this->assertText('Xylophone');
+    $this->assertSession()->pageTextContains('Xylophone');
     // Submit first step in the wizard.
     $edit = [
       'one' => 'test',
     ];
     $this->drupalPostForm('ctools/wizard', $edit, $this->t('Next'));
     // Redirected to the second step.
-    $this->assertText('Form Two');
-    $this->assertText('Dynamic value submitted: Xylophone');
+    $this->assertSession()->pageTextContains('Form Two');
+    $this->assertSession()->pageTextContains('Dynamic value submitted: Xylophone');
     // Check that $operations['two']['values'] worked.
-    $this->assertText('Zebra');
+    $this->assertSession()->pageTextContains('Zebra');
     // Hit previous to make sure our form value are preserved.
     $this->drupalPostForm(NULL, [], $this->t('Previous'));
     // Check the known form values.
-    $this->assertFieldByName('one', 'test');
-    $this->assertText('Xylophone');
+    $this->assertSession()->fieldValueEquals('one', 'test');
+    $this->assertSession()->pageTextContains('Xylophone');
     // Goto next step again and finish this wizard.
     $this->drupalPostForm(NULL, [], $this->t('Next'));
     $edit = [
@@ -45,44 +46,50 @@ function testWizardSteps() {
     ];
     $this->drupalPostForm(NULL, $edit, $this->t('Finish'));
     // Check that the wizard finished properly.
-    $this->assertText('Value One: test');
-    $this->assertText('Value Two: Second test');
+    $this->assertSession()->pageTextContains('Value One: test');
+    $this->assertSession()->pageTextContains('Value Two: Second test');
   }
 
-  function testStepValidateAndSubmit() {
+  /**
+   * Test wizard validate and submit.
+   */
+  public function testStepValidateAndSubmit() {
     $this->drupalGet('ctools/wizard');
-    $this->assertText('Form One');
+    $this->assertSession()->pageTextContains('Form One');
     // Submit first step in the wizard.
     $edit = [
       'one' => 'wrong',
     ];
     $this->drupalPostForm('ctools/wizard', $edit, $this->t('Next'));
     // We're still on the first form and the error is present.
-    $this->assertText('Form One');
-    $this->assertText('Cannot set the value to "wrong".');
+    $this->assertSession()->pageTextContains('Form One');
+    $this->assertSession()->pageTextContains('Cannot set the value to "wrong".');
     // Try again with the magic value.
     $edit = [
       'one' => 'magic',
     ];
     $this->drupalPostForm('ctools/wizard', $edit, $this->t('Next'));
     // Redirected to the second step.
-    $this->assertText('Form Two');
+    $this->assertSession()->pageTextContains('Form Two');
     $edit = [
       'two' => 'Second test',
     ];
     $this->drupalPostForm(NULL, $edit, $this->t('Finish'));
     // Check that the magic value triggered our submit callback.
-    $this->assertText('Value One: Abraham');
-    $this->assertText('Value Two: Second test');
+    $this->assertSession()->pageTextContains('Value One: Abraham');
+    $this->assertSession()->pageTextContains('Value Two: Second test');
   }
 
-  function testEntityWizard() {
+  /**
+   * Test wizard entity config update.
+   */
+  public function testEntityWizard() {
     $this->drupalLogin($this->drupalCreateUser(['administer site configuration']));
 
     // Start adding a new config entity.
     $this->drupalGet('admin/structure/ctools_wizard_test_config_entity/add');
-    $this->assertText('Example entity');
-    $this->assertNoText('Existing entity');
+    $this->assertSession()->pageTextContains('Example entity');
+    $this->assertSession()->pageTextNotContains('Existing entity');
 
     // Submit the general step.
     $edit = [
@@ -104,33 +111,32 @@ function testEntityWizard() {
     $this->drupalPostForm(NULL, $edit, $this->t('Finish'));
 
     // Now we should be looking at the list of entities.
-    $this->assertUrl('admin/structure/ctools_wizard_test_config_entity');
-    $this->assertText('Test Config Entity 123');
+    $this->assertSession()->addressEquals('admin/structure/ctools_wizard_test_config_entity');
+    $this->assertSession()->pageTextContains('Test Config Entity 123');
 
     // Edit the entity again and make sure the values are what we expect.
     $this->clickLink(t('Edit'));
-    $this->assertText('Existing entity');
-    $this->assertFieldByName('label', 'Test Config Entity 123');
+    $this->assertSession()->pageTextContains('Existing entity');
+    $this->assertSession()->fieldValueEquals('label', 'Test Config Entity 123');
     $this->clickLink(t('Form One'));
-    $this->assertFieldByName('one', 'The first bit');
+    $this->assertSession()->fieldValueEquals('one', 'The first bit');
     $previous = $this->getUrl();
     $this->clickLink(t('Show on dialog'));
-    $this->assertRaw('Value from one: The first bit');
+    $this->assertSession()->responseContains('Value from one: The first bit');
     $this->drupalGet($previous);
     // Change the value for 'one'.
     $this->drupalPostForm(NULL, ['one' => 'New value'], $this->t('Next'));
-    $this->assertFieldByName('two', 'The second bit');
+    $this->assertSession()->fieldValueEquals('two', 'The second bit');
     $this->drupalPostForm(NULL, [], $this->t('Next'));
     // Make sure we get the additional step because the entity exists.
-    $this->assertText('This step only shows if the entity is already existing!');
+    $this->assertSession()->pageTextContains('This step only shows if the entity is already existing!');
     $this->drupalPostForm(NULL, [], $this->t('Finish'));
 
     // Edit the entity again and make sure the change stuck.
-    $this->assertUrl('admin/structure/ctools_wizard_test_config_entity');
+    $this->assertSession()->addressEquals('admin/structure/ctools_wizard_test_config_entity');
     $this->clickLink(t('Edit'));
-    $this->drupalPostForm(NULL, [], $this->t('Next'));
-    $this->assertFieldByName('one', 'New value');
+    $this->clickLink(t('Form One'));
+    $this->assertSession()->fieldValueEquals('one', 'New value');
   }
 
 }
-
diff --git a/web/modules/ctools/src/TypedDataResolver.php b/web/modules/ctools/src/TypedDataResolver.php
index 737ab3ce10e477da73d1f56319a98515cff32543..f06ec419cb37485090577564852f097eb8f5a534 100644
--- a/web/modules/ctools/src/TypedDataResolver.php
+++ b/web/modules/ctools/src/TypedDataResolver.php
@@ -2,11 +2,8 @@
 
 namespace Drupal\ctools;
 
-
-use Drupal\Core\Field\BaseFieldDefinition;
 use Drupal\Core\Plugin\Context\Context;
 use Drupal\Core\Plugin\Context\ContextDefinition;
-use Drupal\Core\Plugin\Context\ContextDefinitionInterface;
 use Drupal\Core\Plugin\Context\ContextInterface;
 use Drupal\Core\StringTranslation\TranslationInterface;
 use Drupal\Core\TypedData\ComplexDataDefinitionInterface;
diff --git a/web/modules/ctools/src/Wizard/EntityFormWizardBase.php b/web/modules/ctools/src/Wizard/EntityFormWizardBase.php
index 1647f734aca55aea4690bb0c3f24c0da6de922ee..9cac6854b9ec4bf5392f7ceb5ee2a9870ef57f89 100644
--- a/web/modules/ctools/src/Wizard/EntityFormWizardBase.php
+++ b/web/modules/ctools/src/Wizard/EntityFormWizardBase.php
@@ -2,14 +2,13 @@
 
 namespace Drupal\ctools\Wizard;
 
-
 use Drupal\Core\DependencyInjection\ClassResolverInterface;
-use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Form\FormBuilderInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\ctools\Event\WizardEvent;
-use Drupal\user\SharedTempStoreFactory;
+use Drupal\Core\TempStore\SharedTempStoreFactory;
 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 
 /**
@@ -18,14 +17,14 @@
 abstract class EntityFormWizardBase extends FormWizardBase implements EntityFormWizardInterface {
 
   /**
-   * The entity manager.
+   * The entity type manager.
    *
-   * @var \Drupal\Core\Entity\EntityManagerInterface
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
    */
-  protected $entityManager;
+  protected $entityTypeManager;
 
   /**
-   * @param \Drupal\user\SharedTempStoreFactory $tempstore
+   * @param \Drupal\Core\TempStore\SharedTempStoreFactory $tempstore
    *   Tempstore Factory for keeping track of values in each step of the
    *   wizard.
    * @param \Drupal\Core\Form\FormBuilderInterface $builder
@@ -34,8 +33,8 @@ abstract class EntityFormWizardBase extends FormWizardBase implements EntityForm
    *   The class resolver.
    * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
    *   The event dispatcher.
-   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
-   *   The entity manager.
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity type manager.
    * @param $tempstore_id
    *   The shared temp store factory collection name.
    * @param null $machine_name
@@ -43,8 +42,8 @@ abstract class EntityFormWizardBase extends FormWizardBase implements EntityForm
    * @param null $step
    *   The current active step of the wizard.
    */
-  public function __construct(SharedTempStoreFactory $tempstore, FormBuilderInterface $builder, ClassResolverInterface $class_resolver, EventDispatcherInterface $event_dispatcher, EntityManagerInterface $entity_manager, RouteMatchInterface $route_match, $tempstore_id, $machine_name = NULL, $step = NULL) {
-    $this->entityManager = $entity_manager;
+  public function __construct(SharedTempStoreFactory $tempstore, FormBuilderInterface $builder, ClassResolverInterface $class_resolver, EventDispatcherInterface $event_dispatcher, EntityTypeManagerInterface $entity_type_manager, RouteMatchInterface $route_match, $tempstore_id, $machine_name = NULL, $step = NULL) {
+    $this->entityTypeManager = $entity_type_manager;
     parent::__construct($tempstore, $builder, $class_resolver, $event_dispatcher, $route_match, $tempstore_id, $machine_name, $step);
   }
 
@@ -53,11 +52,14 @@ public function __construct(SharedTempStoreFactory $tempstore, FormBuilderInterf
    */
   public static function getParameters() {
     return [
-      'tempstore' => \Drupal::service('user.shared_tempstore'),
+      'tempstore' => \Drupal::service('tempstore.shared'),
       'builder' => \Drupal::service('form_builder'),
       'class_resolver' => \Drupal::service('class_resolver'),
       'event_dispatcher' => \Drupal::service('event_dispatcher'),
+      // Keep the deprecated entity manager service as a parameter as well for
+      // BC, so that subclasses still work.
       'entity_manager' => \Drupal::service('entity.manager'),
+      'entity_type_manager' => \Drupal::service('entity_type.manager'),
     ];
   }
 
@@ -65,7 +67,7 @@ public static function getParameters() {
    * {@inheritdoc}
    */
   public function initValues() {
-    $storage = $this->entityManager->getStorage($this->getEntityType());
+    $storage = $this->entityTypeManager->getStorage($this->getEntityType());
     if ($this->getMachineName()) {
       $values = $this->getTempstore()->get($this->getMachineName());
       if (!$values) {
@@ -89,24 +91,25 @@ public function initValues() {
    */
   public function finish(array &$form, FormStateInterface $form_state) {
     $cached_values = $form_state->getTemporaryValue('wizard');
-    /** @var $entity \Drupal\Core\Entity\EntityInterface */
+    /** @var \Drupal\Core\Entity\EntityInterface $entity */
     $entity = $cached_values[$this->getEntityType()];
     $entity->set('id', $cached_values['id']);
     $entity->set('label', $cached_values['label']);
     $status = $entity->save();
-    $definition = $this->entityManager->getDefinition($this->getEntityType());
-    if ($status) {
-      drupal_set_message($this->t('Saved the %label @entity_type.', array(
-        '%label' => $entity->label(),
-        '@entity_type' => $definition->getLabel(),
-      )));
+
+    $arguments = [
+      '@entity-type' => $entity->getEntityType()->getLowercaseLabel(),
+      '%label' => $entity->label(),
+    ];
+    if ($status === SAVED_UPDATED) {
+      $this->messenger()->addMessage($this->t('The @entity-type %label has been updated.', $arguments));
+      $this->logger($entity->getEntityType()->getProvider())->notice('Updated @entity-type %label.', $arguments);
     }
-    else {
-      drupal_set_message($this->t('The %label @entity_type was not saved.', array(
-        '%label' => $entity->label(),
-        '@entity_type' => $definition->getLabel(),
-      )));
+    elseif ($status === SAVED_NEW) {
+      $this->messenger()->addMessage($this->t('The @entity-type %label has been added.', $arguments));
+      $this->logger($entity->getEntityType()->getProvider())->notice('Added @entity-type %label.', $arguments);
     }
+
     $form_state->setRedirectUrl($entity->toUrl('collection'));
     parent::finish($form, $form_state);
   }
@@ -122,7 +125,7 @@ public function finish(array &$form, FormStateInterface $form_state) {
   protected function customizeForm(array $form, FormStateInterface $form_state) {
     $form = parent::customizeForm($form, $form_state);
     if ($this->machine_name) {
-      $entity = $this->entityManager->getStorage($this->getEntityType())
+      $entity = $this->entityTypeManager->getStorage($this->getEntityType())
         ->load($this->machine_name);
     }
     else {
@@ -145,7 +148,7 @@ protected function customizeForm(array $form, FormStateInterface $form_state) {
     $default_operation = reset($operations);
     if ($operation['form'] == $default_operation['form']) {
       // Get the plugin definition of this entity.
-      $definition = $this->entityManager->getDefinition($this->getEntityType());
+      $definition = $this->entityTypeManager->getDefinition($this->getEntityType());
       // Create id and label form elements.
       $form['name'] = array(
         '#type' => 'fieldset',
diff --git a/web/modules/ctools/src/Wizard/FormWizardBase.php b/web/modules/ctools/src/Wizard/FormWizardBase.php
index e537ef804fe2da27e204eaff39dcb07c88842e9c..df8048e6c9bbcce90d844314640be3e9c13bff8f 100644
--- a/web/modules/ctools/src/Wizard/FormWizardBase.php
+++ b/web/modules/ctools/src/Wizard/FormWizardBase.php
@@ -13,7 +13,8 @@
 use Drupal\Core\Url;
 use Drupal\ctools\Ajax\OpenModalWizardCommand;
 use Drupal\ctools\Event\WizardEvent;
-use Drupal\user\SharedTempStoreFactory;
+use Drupal\Core\TempStore\PrivateTempStoreFactory;
+use Drupal\Core\TempStore\SharedTempStoreFactory;
 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 
 /**
@@ -24,7 +25,7 @@ abstract class FormWizardBase extends FormBase implements FormWizardInterface {
   /**
    * Tempstore Factory for keeping track of values in each step of the wizard.
    *
-   * @var \Drupal\user\SharedTempStoreFactory
+   * @var \Drupal\Core\TempStore\SharedTempStoreFactory
    */
   protected $tempstore;
 
@@ -71,7 +72,7 @@ abstract class FormWizardBase extends FormBase implements FormWizardInterface {
   protected $step;
 
   /**
-   * @param \Drupal\user\SharedTempStoreFactory $tempstore
+   * @param \Drupal\Core\TempStore\SharedTempStoreFactory $tempstore
    *   Tempstore Factory for keeping track of values in each step of the
    *   wizard.
    * @param \Drupal\Core\Form\FormBuilderInterface $builder
@@ -103,7 +104,7 @@ public function __construct(SharedTempStoreFactory $tempstore, FormBuilderInterf
    */
   public static function getParameters() {
     return [
-      'tempstore' => \Drupal::service('user.shared_tempstore'),
+      'tempstore' => \Drupal::service('tempstore.shared'),
       'builder' => \Drupal::service('form_builder'),
       'class_resolver' => \Drupal::service('class_resolver'),
       'event_dispatcher' => \Drupal::service('event_dispatcher'),
@@ -131,7 +132,8 @@ public function getTempstoreId() {
    * {@inheritdoc}
    */
   public function getTempstore() {
-    return $this->tempstore->get($this->getTempstoreId());
+    $tempstore = $this->tempstore->get($this->getTempstoreId());
+    return $tempstore;
   }
 
   /**
@@ -393,7 +395,7 @@ protected function actions(FormInterface $form_object, FormStateInterface $form_
       $actions['submit']['#ajax'] = [
         'callback' => '::ajaxSubmit',
         'url' => Url::fromRoute($this->getRouteName(), $parameters),
-        'options' => ['query' => \Drupal::request()->query->all() + [FormBuilderInterface::AJAX_FORM_REQUEST => TRUE]],
+        'options' => ['query' => $this->getRequest()->query->all() + [FormBuilderInterface::AJAX_FORM_REQUEST => TRUE]],
       ];
     }
 
@@ -419,7 +421,7 @@ protected function actions(FormInterface $form_object, FormStateInterface $form_
         $actions['previous']['#ajax'] = [
           'callback' => '::ajaxPrevious',
           'url' => Url::fromRoute($this->getRouteName(), $parameters),
-          'options' => ['query' => \Drupal::request()->query->all() + [FormBuilderInterface::AJAX_FORM_REQUEST => TRUE]],
+          'options' => ['query' => $this->getRequest()->query->all() + [FormBuilderInterface::AJAX_FORM_REQUEST => TRUE]],
         ];
       }
     }
diff --git a/web/modules/ctools/src/Wizard/FormWizardInterface.php b/web/modules/ctools/src/Wizard/FormWizardInterface.php
index 54043c3ba26945e3109b29354e180fac20c9596b..53ccc48fc58274031bea512e71b4a5391f19571a 100644
--- a/web/modules/ctools/src/Wizard/FormWizardInterface.php
+++ b/web/modules/ctools/src/Wizard/FormWizardInterface.php
@@ -39,7 +39,7 @@ public function getTempstoreId();
   /**
    * The active SharedTempStore for this wizard.
    *
-   * @return \Drupal\user\SharedTempStore
+   * @return \Drupal\Core\TempStore\SharedTempStore
    */
   public function getTempstore();
 
diff --git a/web/modules/ctools/src/Wizard/WizardFactory.php b/web/modules/ctools/src/Wizard/WizardFactory.php
index 27522d066c1f8ed1eda7775089a91dbf5efe7dd4..4edfe8a4df9523635596524feb103621c7332ad3 100644
--- a/web/modules/ctools/src/Wizard/WizardFactory.php
+++ b/web/modules/ctools/src/Wizard/WizardFactory.php
@@ -5,6 +5,7 @@
 use Drupal\Core\Form\FormBuilderInterface;
 use Drupal\Core\Form\FormState;
 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+use Drupal\Core\Render\Renderer;
 
 class WizardFactory implements WizardFactoryInterface {
 
@@ -23,14 +24,26 @@ class WizardFactory implements WizardFactoryInterface {
   protected $dispatcher;
 
   /**
+   * The object renderer.
+   *
+   * @var \Drupal\Core\Render\Renderer
+   */
+  protected $renderer;
+
+  /**
+   * The construct method.
+   *
    * @param \Drupal\Core\Form\FormBuilderInterface $form_builder
    *   The form builder.
    * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
    *   The event dispatcher.
+   * @param \Drupal\Core\Render\Renderer $renderer
+   *   The object renderer.
    */
-  public function __construct(FormBuilderInterface $form_builder, EventDispatcherInterface $event_dispatcher) {
+  public function __construct(FormBuilderInterface $form_builder, EventDispatcherInterface $event_dispatcher, Renderer $renderer) {
     $this->builder = $form_builder;
     $this->dispatcher = $event_dispatcher;
+    $this->renderer = $renderer;
   }
 
   /**
@@ -42,9 +55,8 @@ public function getWizardForm(FormWizardInterface $wizard, array $parameters = [
 
     if ($ajax) {
       $form['#attached']['library'][] = 'core/drupal.dialog.ajax';
-      $status_messages = array('#type' => 'status_messages');
-      // @todo properly inject the renderer. Core should really be doing this work.
-      if ($messages = \Drupal::service('renderer')->renderRoot($status_messages)) {
+      $status_messages = ['#type' => 'status_messages'];
+      if ($messages = $this->renderer->renderRoot($status_messages)) {
         if (!empty($form['#prefix'])) {
           // Form prefix is expected to be a string. Prepend the messages to
           // that string.
diff --git a/web/modules/ctools/src/Wizard/WizardFactoryInterface.php b/web/modules/ctools/src/Wizard/WizardFactoryInterface.php
index 34b00a8f8aebaf34444469df81c1eece9b174c72..d9b3c8e7163156f89d667e506734d4da18f7cc51 100644
--- a/web/modules/ctools/src/Wizard/WizardFactoryInterface.php
+++ b/web/modules/ctools/src/Wizard/WizardFactoryInterface.php
@@ -1,4 +1,5 @@
 <?php
+
 namespace Drupal\ctools\Wizard;
 
 interface WizardFactoryInterface {
diff --git a/web/modules/ctools/tests/modules/ctools_block_display_test/ctools_block_display_test.info.yml b/web/modules/ctools/tests/modules/ctools_block_display_test/ctools_block_display_test.info.yml
new file mode 100644
index 0000000000000000000000000000000000000000..bfc9fb5587eeb1f0ebfbb7fd6f9be2d4a621dc46
--- /dev/null
+++ b/web/modules/ctools/tests/modules/ctools_block_display_test/ctools_block_display_test.info.yml
@@ -0,0 +1,14 @@
+name: Block Display Variant Test
+type: module
+description: 'Testing infrastructure for CTools block display variants.'
+package: Testing
+# version: 3.x
+# core: 8.x
+dependencies:
+  - ctools:ctools
+
+# Information added by Drupal.org packaging script on 2019-02-21
+version: '8.x-3.2'
+core: '8.x'
+project: 'ctools'
+datestamp: 1550728390
diff --git a/web/modules/ctools/tests/modules/ctools_block_display_test/src/Plugin/DisplayVariant/BlockDisplayVariant.php b/web/modules/ctools/tests/modules/ctools_block_display_test/src/Plugin/DisplayVariant/BlockDisplayVariant.php
new file mode 100644
index 0000000000000000000000000000000000000000..2aa254b3541cd36a93a0ff89a2832972b82b7e59
--- /dev/null
+++ b/web/modules/ctools/tests/modules/ctools_block_display_test/src/Plugin/DisplayVariant/BlockDisplayVariant.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace Drupal\ctools_block_display_test\Plugin\DisplayVariant;
+
+use Drupal\ctools\Plugin\DisplayVariant\BlockDisplayVariant as BaseBlockDisplayVariant;
+
+class BlockDisplayVariant extends BaseBlockDisplayVariant {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getRegionNames() {
+    return [];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function build() {
+    return [];
+  }
+
+}
diff --git a/web/modules/ctools/tests/modules/ctools_wizard_test/ctools_wizard_test.info.yml b/web/modules/ctools/tests/modules/ctools_wizard_test/ctools_wizard_test.info.yml
index 76302ba10f20e1b2b7a4c2bfe0b89245d619b4e1..2a351d203331dcfb3c5305ab0827c5d657c48931 100644
--- a/web/modules/ctools/tests/modules/ctools_wizard_test/ctools_wizard_test.info.yml
+++ b/web/modules/ctools/tests/modules/ctools_wizard_test/ctools_wizard_test.info.yml
@@ -5,8 +5,8 @@ package: Testing
 # version: 3.x
 # core: 8.x
 
-# Information added by Drupal.org packaging script on 2017-04-28
-version: '8.x-3.0'
+# Information added by Drupal.org packaging script on 2019-02-21
+version: '8.x-3.2'
 core: '8.x'
 project: 'ctools'
-datestamp: 1493401747
+datestamp: 1550728390
diff --git a/web/modules/ctools/tests/modules/ctools_wizard_test/src/ExampleConfigEntityListBuilder.php b/web/modules/ctools/tests/modules/ctools_wizard_test/src/ExampleConfigEntityListBuilder.php
index 47d3ecf663db11286ca1367c37c0eef0053ad1e9..d99c6b5f1fb57dd9ab49587b6ff8ff8e3baa8eb4 100644
--- a/web/modules/ctools/tests/modules/ctools_wizard_test/src/ExampleConfigEntityListBuilder.php
+++ b/web/modules/ctools/tests/modules/ctools_wizard_test/src/ExampleConfigEntityListBuilder.php
@@ -22,7 +22,7 @@ public function buildHeader() {
    * {@inheritdoc}
    */
   public function buildRow(EntityInterface $entity) {
-    $row['label'] = $this->getLabel($entity);
+    $row['label'] = $entity->label();
     $row['id'] = $entity->id();
     // You probably want a few more properties here...
     return $row + parent::buildRow($entity);
diff --git a/web/modules/ctools/tests/modules/ctools_wizard_test/src/Form/ExampleConfigEntityDeleteForm.php b/web/modules/ctools/tests/modules/ctools_wizard_test/src/Form/ExampleConfigEntityDeleteForm.php
index 487751d92f47f6f921fee70acf56b4f210eff709..035034ca474f8e01b82a669be9e6880d7a6defc8 100644
--- a/web/modules/ctools/tests/modules/ctools_wizard_test/src/Form/ExampleConfigEntityDeleteForm.php
+++ b/web/modules/ctools/tests/modules/ctools_wizard_test/src/Form/ExampleConfigEntityDeleteForm.php
@@ -36,8 +36,7 @@ public function getConfirmText() {
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
     $this->entity->delete();
-
-    drupal_set_message(
+    $this->messenger()->addMessage(
       $this->t('content @type: deleted @label.',
         [
           '@type' => $this->entity->bundle(),
diff --git a/web/modules/ctools/tests/modules/ctools_wizard_test/src/Form/ExampleConfigEntityExternalForm.php b/web/modules/ctools/tests/modules/ctools_wizard_test/src/Form/ExampleConfigEntityExternalForm.php
index 2ba871c283fecb9fdcebbbccd4b2c3b022939e1d..d82b80c4c10e5e74926f055baaf70661df691ad3 100644
--- a/web/modules/ctools/tests/modules/ctools_wizard_test/src/Form/ExampleConfigEntityExternalForm.php
+++ b/web/modules/ctools/tests/modules/ctools_wizard_test/src/Form/ExampleConfigEntityExternalForm.php
@@ -2,18 +2,20 @@
 
 namespace Drupal\ctools_wizard_test\Form;
 
-
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\user\SharedTempStoreFactory;
+use Drupal\Core\TempStore\SharedTempStoreFactory;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
+/**
+ * Example form config entity.
+ */
 class ExampleConfigEntityExternalForm extends FormBase {
 
   /**
    * Tempstore factory.
    *
-   * @var \Drupal\user\SharedTempStoreFactory
+   * @var \Drupal\Core\TempStore\SharedTempStoreFactory
    */
   protected $tempstore;
 
@@ -21,8 +23,9 @@ class ExampleConfigEntityExternalForm extends FormBase {
    * Constructs a new ExampleConfigEntityExternalForm.
    *
    * @param \Drupal\ctools_wizard_test\Form\SharedTempStoreFactory $tempstore
+   *   Creates a shared temporary storage for a collection.
    */
-  function __construct(SharedTempStoreFactory $tempstore) {
+  public function __construct(SharedTempStoreFactory $tempstore) {
     $this->tempstore = $tempstore;
   }
 
@@ -30,7 +33,7 @@ function __construct(SharedTempStoreFactory $tempstore) {
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container) {
-    return new static($container->get('user.shared_tempstore'));
+    return new static($container->get('tempstore.shared'));
   }
 
   /**
@@ -63,4 +66,3 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
   }
 
 }
-
diff --git a/web/modules/ctools/tests/modules/ctools_wizard_test/src/Form/OneForm.php b/web/modules/ctools/tests/modules/ctools_wizard_test/src/Form/OneForm.php
index 037505637dd0be0b4efd653f226c85d9d8610d43..6ee5d67ef4067a208550d8a509e5db77c0c450ca 100644
--- a/web/modules/ctools/tests/modules/ctools_wizard_test/src/Form/OneForm.php
+++ b/web/modules/ctools/tests/modules/ctools_wizard_test/src/Form/OneForm.php
@@ -64,8 +64,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       $cached_values[$key] = $form_state->getValue($key);
     }
     $form_state->setTemporaryValue('wizard', $cached_values);
-
-    drupal_set_message($this->t('Dynamic value submitted: @value', ['@value' => $cached_values['dynamic']]));;
+    $this->messenger()->addMessage($this->t('Dynamic value submitted: @value', ['@value' => $cached_values['dynamic']]));
   }
 
 }
diff --git a/web/modules/ctools/tests/modules/ctools_wizard_test/src/Wizard/WizardTest.php b/web/modules/ctools/tests/modules/ctools_wizard_test/src/Wizard/WizardTest.php
index 539df331d241bd1b5006cacaba970fd7cb2b963c..49a3ce597f5a97ac2cf6cca4f8779a2e8e1e60ff 100644
--- a/web/modules/ctools/tests/modules/ctools_wizard_test/src/Wizard/WizardTest.php
+++ b/web/modules/ctools/tests/modules/ctools_wizard_test/src/Wizard/WizardTest.php
@@ -74,8 +74,8 @@ public function getRouteName() {
    */
   public function finish(array &$form, FormStateInterface $form_state) {
     $cached_values = $form_state->getTemporaryValue('wizard');
-    drupal_set_message($this->t('Value One: @one', ['@one' => $cached_values['one']]));
-    drupal_set_message($this->t('Value Two: @two', ['@two' => $cached_values['two']]));
+    $this->messenger()->addMessage($this->t('Value One: @one', ['@one' => $cached_values['one']]));
+    $this->messenger()->addMessage($this->t('Value Two: @two', ['@two' => $cached_values['two']]));
     parent::finish($form, $form_state);
   }
 
diff --git a/web/modules/ctools/tests/src/Kernel/BlockDisplayVariantTest.php b/web/modules/ctools/tests/src/Kernel/BlockDisplayVariantTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..01e4626650a6f1cb7162e33dea87e95ecd3244d0
--- /dev/null
+++ b/web/modules/ctools/tests/src/Kernel/BlockDisplayVariantTest.php
@@ -0,0 +1,53 @@
+<?php
+
+namespace Drupal\Tests\ctools\Kernel;
+
+use Drupal\ctools\Event\BlockVariantEvent;
+use Drupal\ctools\Event\BlockVariantEvents;
+use Drupal\ctools_block_display_test\Plugin\DisplayVariant\BlockDisplayVariant;
+use Drupal\KernelTests\KernelTestBase;
+use Prophecy\Argument;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+
+/**
+ * @coversDefaultClass \Drupal\ctools\Plugin\DisplayVariant\BlockDisplayVariant
+ * @group CTools
+ */
+class BlockDisplayVariantTest extends KernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['ctools', 'ctools_block_display_test', 'system', 'user'];
+
+  /**
+   * Tests that events are fired when manipulating a block variant.
+   */
+  public function testBlockDisplayVariantEvents() {
+    /** @var \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher */
+    $event_dispatcher = $this->prophesize(EventDispatcherInterface::class);
+    // Swap in a mock event dispatcher so we can spy on method calls.
+    $this->container->set('event_dispatcher', $event_dispatcher->reveal());
+
+    $variant = BlockDisplayVariant::create(
+      $this->container,
+      [],
+      'foobar',
+      []
+    );
+    // Set up the expected calls to the event dispatcher.
+    $event = Argument::type(BlockVariantEvent::class);
+
+    $event_dispatcher->dispatch(BlockVariantEvents::ADD_BLOCK, $event)
+      ->shouldBeCalled();
+    $event_dispatcher->dispatch(BlockVariantEvents::UPDATE_BLOCK, $event)
+      ->shouldBeCalled();
+    $event_dispatcher->dispatch(BlockVariantEvents::DELETE_BLOCK, $event)
+      ->shouldBeCalled();
+
+    $block_id = $variant->addBlock(['id' => 'system_powered_by_block']);
+    $variant->updateBlock($block_id, []);
+    $variant->removeBlock($block_id);
+  }
+
+}
diff --git a/web/modules/ctools/tests/src/Kernel/RelationshipManagerTest.php b/web/modules/ctools/tests/src/Kernel/RelationshipManagerTest.php
index 94ca6d9c062a249a49c43478e96b855d7ed39056..909c52c683f6ccdb6ab73a299cdc6de3d550ba84 100644
--- a/web/modules/ctools/tests/src/Kernel/RelationshipManagerTest.php
+++ b/web/modules/ctools/tests/src/Kernel/RelationshipManagerTest.php
@@ -6,7 +6,7 @@
 use Drupal\Core\Plugin\Context\ContextDefinition;
 
 /**
- * @coversDefaultClass \Drupal\ctools\Plugin\RelationshipManagerInterface
+ * @coversDefaultClass \Drupal\ctools\Plugin\RelationshipManager
  * @group CTools
  */
 class RelationshipManagerTest extends RelationshipsTestBase {
diff --git a/web/modules/ctools/views_content/views_content.admin.inc b/web/modules/ctools/views_content/views_content.admin.inc
new file mode 100644
index 0000000000000000000000000000000000000000..589cf42b67cbcb3e580190c4bc0144a9a794bdf7
--- /dev/null
+++ b/web/modules/ctools/views_content/views_content.admin.inc
@@ -0,0 +1,6 @@
+<?php
+
+/**
+ * @file
+ * File for admin helper functions for views_content module.
+ */