diff --git a/composer.json b/composer.json
index 7aedba1b5b565cf7e53db5a9add5bd343a8f2afe..76ade6946edbf27e6e3edd58c15efa11b1a06a58 100644
--- a/composer.json
+++ b/composer.json
@@ -76,16 +76,19 @@
         "drupal/administerusersbyrole": "2.0-alpha6",
         "drupal/allowed_formats": "1.1",
         "drupal/better_exposed_filters": "3.0-alpha3",
+        "drupal/block_permissions": "^1.0",
+        "drupal/block_region_permissions": "^1.2",
         "drupal/bootstrap": "3.5",
         "drupal/calendar": "1.x-dev",
         "drupal/cog": "^1.13",
         "drupal/config_direct_save": "^1.0",
+        "drupal/config_ignore": "^2.1",
         "drupal/config_installer": "^1.0",
+        "drupal/config_update": "^1.5",
         "drupal/console": "^1",
         "drupal/content_access": "1.0-alpha1",
         "drupal/core": "8.5.8",
         "drupal/crop": "2.0-rc1",
-        "drupal/css_editor": "1.0",
         "drupal/ctools": "3.0",
         "drupal/ctools_views": "3.0",
         "drupal/devel": "1.0-rc2",
@@ -100,6 +103,7 @@
         "drupal/entity_reference_revisions": "1.3",
         "drupal/eva": "1.1",
         "drupal/externalauth": "1.0",
+        "drupal/features": "3.8",
         "drupal/field_collection": "1.0-alpha1",
         "drupal/field_group": "1.0-rc6",
         "drupal/field_permissions": "1.0-beta1",
@@ -140,6 +144,7 @@
         "drupal/simple_megamenu": "1.0-beta3",
         "drupal/simplesamlphp_auth": "3.0",
         "drupal/smtp": "1.0-beta3",
+        "drupal/social_media_links": "^2.6",
         "drupal/superfish": "1.2",
         "drupal/svg_image": "1.8",
         "drupal/token": "1.0",
diff --git a/composer.lock b/composer.lock
index c4a782c6a157e2f6d1fbedc0bc20f31594b551ad..a05e389d84357da8b11b3b47007c02378021d58e 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "content-hash": "44a4caf7dab80aa7a8dc0bbbbb7da3db",
+    "content-hash": "53e6428e2704352943c0a7ffbac8c34e",
     "packages": [
         {
             "name": "alchemy/zippy",
@@ -1503,7 +1503,8 @@
             "homepage": "https://www.drupal.org/project/adminimal_theme",
             "support": {
                 "source": "http://cgit.drupalcode.org/adminimal_theme"
-            }
+            },
+            "time": "2017-07-08T17:49:05+00:00"
         },
         {
             "name": "drupal/administerusersbyrole",
@@ -1666,6 +1667,104 @@
                 "source": "http://cgit.drupalcode.org/better_exposed_filters"
             }
         },
+        {
+            "name": "drupal/block_permissions",
+            "version": "1.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://git.drupal.org/project/block_permissions",
+                "reference": "8.x-1.0"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://ftp.drupal.org/files/projects/block_permissions-8.x-1.0.zip",
+                "reference": "8.x-1.0",
+                "shasum": "3f1cb219379fc88a80445d494f66dd4fb2a5befa"
+            },
+            "require": {
+                "drupal/core": "~8.0"
+            },
+            "type": "drupal-module",
+            "extra": {
+                "branch-alias": {
+                    "dev-1.x": "1.x-dev"
+                },
+                "drupal": {
+                    "version": "8.x-1.0",
+                    "datestamp": "1478790983",
+                    "security-coverage": {
+                        "status": "covered",
+                        "message": "Covered by Drupal's security advisory policy"
+                    }
+                }
+            },
+            "notification-url": "https://packages.drupal.org/8/downloads",
+            "license": [
+                "GPL-2.0-or-later"
+            ],
+            "authors": [
+                {
+                    "name": "jefuri",
+                    "homepage": "https://www.drupal.org/user/2733365"
+                },
+                {
+                    "name": "michielnugter",
+                    "homepage": "https://www.drupal.org/user/1023784"
+                }
+            ],
+            "description": "Adds specific permissions for administering blocks.",
+            "homepage": "https://www.drupal.org/project/block_permissions",
+            "support": {
+                "source": "http://cgit.drupalcode.org/block_permissions"
+            }
+        },
+        {
+            "name": "drupal/block_region_permissions",
+            "version": "1.2.0",
+            "source": {
+                "type": "git",
+                "url": "https://git.drupal.org/project/block_region_permissions",
+                "reference": "8.x-1.2"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://ftp.drupal.org/files/projects/block_region_permissions-8.x-1.2.zip",
+                "reference": "8.x-1.2",
+                "shasum": "9776b2be5af7b9ebe7777f17487ef31e48f76c78"
+            },
+            "require": {
+                "drupal/core": "~8.0"
+            },
+            "type": "drupal-module",
+            "extra": {
+                "branch-alias": {
+                    "dev-1.x": "1.x-dev"
+                },
+                "drupal": {
+                    "version": "8.x-1.2",
+                    "datestamp": "1507771445",
+                    "security-coverage": {
+                        "status": "not-covered",
+                        "message": "Project has not opted into security advisory coverage!"
+                    }
+                }
+            },
+            "notification-url": "https://packages.drupal.org/8/downloads",
+            "license": [
+                "GPL-2.0-or-later"
+            ],
+            "authors": [
+                {
+                    "name": "joshua.roberson",
+                    "homepage": "https://www.drupal.org/user/2999235"
+                }
+            ],
+            "description": "Adds specific permissions for administering blocks for each theme's regions.",
+            "homepage": "https://www.drupal.org/project/block_region_permissions",
+            "support": {
+                "source": "http://cgit.drupalcode.org/block_region_permissions"
+            }
+        },
         {
             "name": "drupal/bootstrap",
             "version": "3.5.0",
@@ -1966,6 +2065,132 @@
                 "source": "http://cgit.drupalcode.org/config_direct_save"
             }
         },
+        {
+            "name": "drupal/config_filter",
+            "version": "1.3.0",
+            "source": {
+                "type": "git",
+                "url": "https://git.drupal.org/project/config_filter",
+                "reference": "8.x-1.3"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://ftp.drupal.org/files/projects/config_filter-8.x-1.3.zip",
+                "reference": "8.x-1.3",
+                "shasum": "56255a17c45dcbb0af713215885a8d74214d2ebc"
+            },
+            "require": {
+                "drupal/core": "~8.0"
+            },
+            "suggest": {
+                "drupal/config_split": "Split site configuration for different environments."
+            },
+            "type": "drupal-module",
+            "extra": {
+                "branch-alias": {
+                    "dev-1.x": "1.x-dev"
+                },
+                "drupal": {
+                    "version": "8.x-1.3",
+                    "datestamp": "1537978080",
+                    "security-coverage": {
+                        "status": "covered",
+                        "message": "Covered by Drupal's security advisory policy"
+                    }
+                }
+            },
+            "notification-url": "https://packages.drupal.org/8/downloads",
+            "license": [
+                "GPL-2.0+"
+            ],
+            "authors": [
+                {
+                    "name": "Fabian Bircher",
+                    "homepage": "https://www.drupal.org/u/bircher",
+                    "email": "opensource@fabianbircher.com",
+                    "role": "Maintainer"
+                },
+                {
+                    "name": "Nuvole Web",
+                    "homepage": "http://nuvole.org",
+                    "email": "info@nuvole.org",
+                    "role": "Maintainer"
+                },
+                {
+                    "name": "pescetti",
+                    "homepage": "https://www.drupal.org/user/436244"
+                }
+            ],
+            "description": "Config Filter allows other modules to interact with a ConfigStorage through filter plugins.",
+            "homepage": "https://www.drupal.org/project/config_filter",
+            "keywords": [
+                "Drupal",
+                "configuration",
+                "configuration management"
+            ],
+            "support": {
+                "source": "http://cgit.drupalcode.org/config_filter",
+                "issues": "https://www.drupal.org/project/issues/config_filter",
+                "irc": "irc://irc.freenode.org/drupal-contribute"
+            }
+        },
+        {
+            "name": "drupal/config_ignore",
+            "version": "2.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://git.drupal.org/project/config_ignore",
+                "reference": "8.x-2.1"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://ftp.drupal.org/files/projects/config_ignore-8.x-2.1.zip",
+                "reference": "8.x-2.1",
+                "shasum": "07e00684930706632b3f2fc2a7433ffdae57cde7"
+            },
+            "require": {
+                "drupal/config_filter": "1.*",
+                "drupal/core": "~8.0"
+            },
+            "type": "drupal-module",
+            "extra": {
+                "branch-alias": {
+                    "dev-2.x": "2.x-dev"
+                },
+                "drupal": {
+                    "version": "8.x-2.1",
+                    "datestamp": "1507706044",
+                    "security-coverage": {
+                        "status": "covered",
+                        "message": "Covered by Drupal's security advisory policy"
+                    }
+                }
+            },
+            "notification-url": "https://packages.drupal.org/8/downloads",
+            "license": [
+                "GPL-2.0+"
+            ],
+            "authors": [
+                {
+                    "name": "Tommy Lynge Jørgensen",
+                    "homepage": "https://www.drupal.org/u/tlyngej",
+                    "email": "tlyngej@gmail.com",
+                    "role": "Maintainer"
+                },
+                {
+                    "name": "Fabian Bircher",
+                    "homepage": "https://www.drupal.org/u/bircher",
+                    "role": "Maintainer"
+                }
+            ],
+            "description": "Ignore certain configuration during import.",
+            "homepage": "http://drupal.org/project/config_ignore",
+            "support": {
+                "source": "http://cgit.drupalcode.org/config_ignore",
+                "issues": "http://drupal.org/project/config_ignore",
+                "irc": "irc://irc.freenode.org/drupal-contribute"
+            }
+        },
         {
             "name": "drupal/config_installer",
             "version": "1.8.0",
@@ -2012,6 +2237,57 @@
                 "source": "http://cgit.drupalcode.org/config_installer"
             }
         },
+        {
+            "name": "drupal/config_update",
+            "version": "1.5.0",
+            "source": {
+                "type": "git",
+                "url": "https://git.drupal.org/project/config_update",
+                "reference": "8.x-1.5"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://ftp.drupal.org/files/projects/config_update-8.x-1.5.zip",
+                "reference": "8.x-1.5",
+                "shasum": "2f7ae5f90b1c0ab8edf84680d2651e81fab6a126"
+            },
+            "require": {
+                "drupal/core": "*"
+            },
+            "type": "drupal-module",
+            "extra": {
+                "branch-alias": {
+                    "dev-1.x": "1.x-dev"
+                },
+                "drupal": {
+                    "version": "8.x-1.5",
+                    "datestamp": "1512587912",
+                    "security-coverage": {
+                        "status": "covered",
+                        "message": "Covered by Drupal's security advisory policy"
+                    }
+                }
+            },
+            "notification-url": "https://packages.drupal.org/8/downloads",
+            "license": [
+                "GPL-2.0-or-later"
+            ],
+            "authors": [
+                {
+                    "name": "jhodgdon",
+                    "homepage": "https://www.drupal.org/user/155601"
+                },
+                {
+                    "name": "nedjo",
+                    "homepage": "https://www.drupal.org/user/4481"
+                }
+            ],
+            "description": "Provides basic revert and update functionality for other modules",
+            "homepage": "https://www.drupal.org/project/config_update",
+            "support": {
+                "source": "http://cgit.drupalcode.org/config_update"
+            }
+        },
         {
             "name": "drupal/console",
             "version": "1.8.0",
@@ -2618,61 +2894,6 @@
                 "issues": "https://www.drupal.org/project/issues/crop"
             }
         },
-        {
-            "name": "drupal/css_editor",
-            "version": "1.0.0",
-            "source": {
-                "type": "git",
-                "url": "https://git.drupal.org/project/css_editor",
-                "reference": "8.x-1.0"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://ftp.drupal.org/files/projects/css_editor-8.x-1.0.zip",
-                "reference": "8.x-1.0",
-                "shasum": "b8176a0abc3a0695463a79dd8426e115dbea49b8"
-            },
-            "require": {
-                "drupal/core": "~8.0"
-            },
-            "type": "drupal-module",
-            "extra": {
-                "branch-alias": {
-                    "dev-1.x": "1.x-dev"
-                },
-                "drupal": {
-                    "version": "8.x-1.0",
-                    "datestamp": "1507735144",
-                    "security-coverage": {
-                        "status": "covered",
-                        "message": "Covered by Drupal's security advisory policy"
-                    }
-                }
-            },
-            "notification-url": "https://packages.drupal.org/8/downloads",
-            "license": [
-                "GPL-2.0-or-later"
-            ],
-            "authors": [
-                {
-                    "name": "caiosba",
-                    "homepage": "https://www.drupal.org/user/1774198"
-                },
-                {
-                    "name": "encelado",
-                    "homepage": "https://www.drupal.org/user/701446"
-                },
-                {
-                    "name": "infojunkie",
-                    "homepage": "https://www.drupal.org/user/48424"
-                }
-            ],
-            "description": "Customize your CSS directly from the browser.",
-            "homepage": "https://www.drupal.org/project/css_editor",
-            "support": {
-                "source": "http://cgit.drupalcode.org/css_editor"
-            }
-        },
         {
             "name": "drupal/ctools",
             "version": "3.0.0",
@@ -3719,6 +3940,83 @@
                 "source": "http://cgit.drupalcode.org/externalauth"
             }
         },
+        {
+            "name": "drupal/features",
+            "version": "3.8.0",
+            "source": {
+                "type": "git",
+                "url": "https://git.drupal.org/project/features",
+                "reference": "8.x-3.8"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://ftp.drupal.org/files/projects/features-8.x-3.8.zip",
+                "reference": "8.x-3.8",
+                "shasum": "15cebd00e38d63c0d946682e76327a03499c27be"
+            },
+            "require": {
+                "drupal/config_update": "^1.4",
+                "drupal/core": "*"
+            },
+            "type": "drupal-module",
+            "extra": {
+                "branch-alias": {
+                    "dev-3.x": "3.x-dev"
+                },
+                "drupal": {
+                    "version": "8.x-3.8",
+                    "datestamp": "1536512284",
+                    "security-coverage": {
+                        "status": "covered",
+                        "message": "Covered by Drupal's security advisory policy"
+                    }
+                },
+                "drush": {
+                    "services": {
+                        "drush.services.yml": "^9"
+                    }
+                }
+            },
+            "notification-url": "https://packages.drupal.org/8/downloads",
+            "license": [
+                "GPL-2.0+"
+            ],
+            "authors": [
+                {
+                    "name": "dawehner",
+                    "homepage": "https://www.drupal.org/user/99340"
+                },
+                {
+                    "name": "e2thex",
+                    "homepage": "https://www.drupal.org/user/189123"
+                },
+                {
+                    "name": "febbraro",
+                    "homepage": "https://www.drupal.org/user/43670"
+                },
+                {
+                    "name": "jmiccolis",
+                    "homepage": "https://www.drupal.org/user/31731"
+                },
+                {
+                    "name": "mpotter",
+                    "homepage": "https://www.drupal.org/user/616192"
+                },
+                {
+                    "name": "nedjo",
+                    "homepage": "https://www.drupal.org/user/4481"
+                },
+                {
+                    "name": "tim.plunkett",
+                    "homepage": "https://www.drupal.org/user/241634"
+                }
+            ],
+            "description": "Enables administrators to package configuration into modules",
+            "homepage": "https://www.drupal.org/project/features",
+            "support": {
+                "source": "http://cgit.drupalcode.org/features"
+            }
+        },
         {
             "name": "drupal/field_collection",
             "version": "1.0.0-alpha1",
@@ -6101,6 +6399,54 @@
                 "issues": "https://www.drupal.org/project/issues/smtp"
             }
         },
+        {
+            "name": "drupal/social_media_links",
+            "version": "2.6.0",
+            "source": {
+                "type": "git",
+                "url": "https://git.drupal.org/project/social_media_links",
+                "reference": "8.x-2.6"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://ftp.drupal.org/files/projects/social_media_links-8.x-2.6.zip",
+                "reference": "8.x-2.6",
+                "shasum": "53462cb307b104552ae5370b917e55ca50fba526"
+            },
+            "require": {
+                "drupal/core": "~8.0"
+            },
+            "type": "drupal-module",
+            "extra": {
+                "branch-alias": {
+                    "dev-2.x": "2.x-dev"
+                },
+                "drupal": {
+                    "version": "8.x-2.6",
+                    "datestamp": "1510489384",
+                    "security-coverage": {
+                        "status": "covered",
+                        "message": "Covered by Drupal's security advisory policy"
+                    }
+                }
+            },
+            "notification-url": "https://packages.drupal.org/8/downloads",
+            "license": [
+                "GPL-2.0+"
+            ],
+            "authors": [
+                {
+                    "name": "cbeier",
+                    "homepage": "https://www.drupal.org/user/1500710"
+                }
+            ],
+            "description": "The module provides a block that display links (icons) to your profiles on various social networking sites.",
+            "homepage": "https://www.drupal.org/project/social_media_links",
+            "support": {
+                "source": "http://cgit.drupalcode.org/social_media_links",
+                "issues": "https://www.drupal.org/project/issues/social_media_links"
+            }
+        },
         {
             "name": "drupal/superfish",
             "version": "1.2.0",
@@ -6594,7 +6940,8 @@
             ],
             "support": {
                 "source": "http://cgit.drupalcode.org/views_bootstrap"
-            }
+            },
+            "time": "2018-05-17T13:28:26+00:00"
         },
         {
             "name": "drupal/views_bulk_operations",
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index 510874ca5d78d3b51eae878864cd562e240b16c8..e90e4a64b2965aa12a7996ab5c15a9c6e32d88c9 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -1721,6 +1721,108 @@
             "source": "http://cgit.drupalcode.org/better_exposed_filters"
         }
     },
+    {
+        "name": "drupal/block_permissions",
+        "version": "1.0.0",
+        "version_normalized": "1.0.0.0",
+        "source": {
+            "type": "git",
+            "url": "https://git.drupal.org/project/block_permissions",
+            "reference": "8.x-1.0"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://ftp.drupal.org/files/projects/block_permissions-8.x-1.0.zip",
+            "reference": "8.x-1.0",
+            "shasum": "3f1cb219379fc88a80445d494f66dd4fb2a5befa"
+        },
+        "require": {
+            "drupal/core": "~8.0"
+        },
+        "type": "drupal-module",
+        "extra": {
+            "branch-alias": {
+                "dev-1.x": "1.x-dev"
+            },
+            "drupal": {
+                "version": "8.x-1.0",
+                "datestamp": "1478790983",
+                "security-coverage": {
+                    "status": "covered",
+                    "message": "Covered by Drupal's security advisory policy"
+                }
+            }
+        },
+        "installation-source": "dist",
+        "notification-url": "https://packages.drupal.org/8/downloads",
+        "license": [
+            "GPL-2.0-or-later"
+        ],
+        "authors": [
+            {
+                "name": "jefuri",
+                "homepage": "https://www.drupal.org/user/2733365"
+            },
+            {
+                "name": "michielnugter",
+                "homepage": "https://www.drupal.org/user/1023784"
+            }
+        ],
+        "description": "Adds specific permissions for administering blocks.",
+        "homepage": "https://www.drupal.org/project/block_permissions",
+        "support": {
+            "source": "http://cgit.drupalcode.org/block_permissions"
+        }
+    },
+    {
+        "name": "drupal/block_region_permissions",
+        "version": "1.2.0",
+        "version_normalized": "1.2.0.0",
+        "source": {
+            "type": "git",
+            "url": "https://git.drupal.org/project/block_region_permissions",
+            "reference": "8.x-1.2"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://ftp.drupal.org/files/projects/block_region_permissions-8.x-1.2.zip",
+            "reference": "8.x-1.2",
+            "shasum": "9776b2be5af7b9ebe7777f17487ef31e48f76c78"
+        },
+        "require": {
+            "drupal/core": "~8.0"
+        },
+        "type": "drupal-module",
+        "extra": {
+            "branch-alias": {
+                "dev-1.x": "1.x-dev"
+            },
+            "drupal": {
+                "version": "8.x-1.2",
+                "datestamp": "1507771445",
+                "security-coverage": {
+                    "status": "not-covered",
+                    "message": "Project has not opted into security advisory coverage!"
+                }
+            }
+        },
+        "installation-source": "dist",
+        "notification-url": "https://packages.drupal.org/8/downloads",
+        "license": [
+            "GPL-2.0-or-later"
+        ],
+        "authors": [
+            {
+                "name": "joshua.roberson",
+                "homepage": "https://www.drupal.org/user/2999235"
+            }
+        ],
+        "description": "Adds specific permissions for administering blocks for each theme's regions.",
+        "homepage": "https://www.drupal.org/project/block_region_permissions",
+        "support": {
+            "source": "http://cgit.drupalcode.org/block_region_permissions"
+        }
+    },
     {
         "name": "drupal/bootstrap",
         "version": "3.5.0",
@@ -2030,6 +2132,136 @@
             "source": "http://cgit.drupalcode.org/config_direct_save"
         }
     },
+    {
+        "name": "drupal/config_filter",
+        "version": "1.3.0",
+        "version_normalized": "1.3.0.0",
+        "source": {
+            "type": "git",
+            "url": "https://git.drupal.org/project/config_filter",
+            "reference": "8.x-1.3"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://ftp.drupal.org/files/projects/config_filter-8.x-1.3.zip",
+            "reference": "8.x-1.3",
+            "shasum": "56255a17c45dcbb0af713215885a8d74214d2ebc"
+        },
+        "require": {
+            "drupal/core": "~8.0"
+        },
+        "suggest": {
+            "drupal/config_split": "Split site configuration for different environments."
+        },
+        "type": "drupal-module",
+        "extra": {
+            "branch-alias": {
+                "dev-1.x": "1.x-dev"
+            },
+            "drupal": {
+                "version": "8.x-1.3",
+                "datestamp": "1537978080",
+                "security-coverage": {
+                    "status": "covered",
+                    "message": "Covered by Drupal's security advisory policy"
+                }
+            }
+        },
+        "installation-source": "dist",
+        "notification-url": "https://packages.drupal.org/8/downloads",
+        "license": [
+            "GPL-2.0+"
+        ],
+        "authors": [
+            {
+                "name": "Fabian Bircher",
+                "homepage": "https://www.drupal.org/u/bircher",
+                "email": "opensource@fabianbircher.com",
+                "role": "Maintainer"
+            },
+            {
+                "name": "Nuvole Web",
+                "homepage": "http://nuvole.org",
+                "email": "info@nuvole.org",
+                "role": "Maintainer"
+            },
+            {
+                "name": "pescetti",
+                "homepage": "https://www.drupal.org/user/436244"
+            }
+        ],
+        "description": "Config Filter allows other modules to interact with a ConfigStorage through filter plugins.",
+        "homepage": "https://www.drupal.org/project/config_filter",
+        "keywords": [
+            "Drupal",
+            "configuration",
+            "configuration management"
+        ],
+        "support": {
+            "source": "http://cgit.drupalcode.org/config_filter",
+            "issues": "https://www.drupal.org/project/issues/config_filter",
+            "irc": "irc://irc.freenode.org/drupal-contribute"
+        }
+    },
+    {
+        "name": "drupal/config_ignore",
+        "version": "2.1.0",
+        "version_normalized": "2.1.0.0",
+        "source": {
+            "type": "git",
+            "url": "https://git.drupal.org/project/config_ignore",
+            "reference": "8.x-2.1"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://ftp.drupal.org/files/projects/config_ignore-8.x-2.1.zip",
+            "reference": "8.x-2.1",
+            "shasum": "07e00684930706632b3f2fc2a7433ffdae57cde7"
+        },
+        "require": {
+            "drupal/config_filter": "1.*",
+            "drupal/core": "~8.0"
+        },
+        "type": "drupal-module",
+        "extra": {
+            "branch-alias": {
+                "dev-2.x": "2.x-dev"
+            },
+            "drupal": {
+                "version": "8.x-2.1",
+                "datestamp": "1507706044",
+                "security-coverage": {
+                    "status": "covered",
+                    "message": "Covered by Drupal's security advisory policy"
+                }
+            }
+        },
+        "installation-source": "dist",
+        "notification-url": "https://packages.drupal.org/8/downloads",
+        "license": [
+            "GPL-2.0+"
+        ],
+        "authors": [
+            {
+                "name": "Tommy Lynge Jørgensen",
+                "homepage": "https://www.drupal.org/u/tlyngej",
+                "email": "tlyngej@gmail.com",
+                "role": "Maintainer"
+            },
+            {
+                "name": "Fabian Bircher",
+                "homepage": "https://www.drupal.org/u/bircher",
+                "role": "Maintainer"
+            }
+        ],
+        "description": "Ignore certain configuration during import.",
+        "homepage": "http://drupal.org/project/config_ignore",
+        "support": {
+            "source": "http://cgit.drupalcode.org/config_ignore",
+            "issues": "http://drupal.org/project/config_ignore",
+            "irc": "irc://irc.freenode.org/drupal-contribute"
+        }
+    },
     {
         "name": "drupal/config_installer",
         "version": "1.8.0",
@@ -2078,6 +2310,59 @@
             "source": "http://cgit.drupalcode.org/config_installer"
         }
     },
+    {
+        "name": "drupal/config_update",
+        "version": "1.5.0",
+        "version_normalized": "1.5.0.0",
+        "source": {
+            "type": "git",
+            "url": "https://git.drupal.org/project/config_update",
+            "reference": "8.x-1.5"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://ftp.drupal.org/files/projects/config_update-8.x-1.5.zip",
+            "reference": "8.x-1.5",
+            "shasum": "2f7ae5f90b1c0ab8edf84680d2651e81fab6a126"
+        },
+        "require": {
+            "drupal/core": "*"
+        },
+        "type": "drupal-module",
+        "extra": {
+            "branch-alias": {
+                "dev-1.x": "1.x-dev"
+            },
+            "drupal": {
+                "version": "8.x-1.5",
+                "datestamp": "1512587912",
+                "security-coverage": {
+                    "status": "covered",
+                    "message": "Covered by Drupal's security advisory policy"
+                }
+            }
+        },
+        "installation-source": "dist",
+        "notification-url": "https://packages.drupal.org/8/downloads",
+        "license": [
+            "GPL-2.0-or-later"
+        ],
+        "authors": [
+            {
+                "name": "jhodgdon",
+                "homepage": "https://www.drupal.org/user/155601"
+            },
+            {
+                "name": "nedjo",
+                "homepage": "https://www.drupal.org/user/4481"
+            }
+        ],
+        "description": "Provides basic revert and update functionality for other modules",
+        "homepage": "https://www.drupal.org/project/config_update",
+        "support": {
+            "source": "http://cgit.drupalcode.org/config_update"
+        }
+    },
     {
         "name": "drupal/console",
         "version": "1.8.0",
@@ -2698,63 +2983,6 @@
             "issues": "https://www.drupal.org/project/issues/crop"
         }
     },
-    {
-        "name": "drupal/css_editor",
-        "version": "1.0.0",
-        "version_normalized": "1.0.0.0",
-        "source": {
-            "type": "git",
-            "url": "https://git.drupal.org/project/css_editor",
-            "reference": "8.x-1.0"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://ftp.drupal.org/files/projects/css_editor-8.x-1.0.zip",
-            "reference": "8.x-1.0",
-            "shasum": "b8176a0abc3a0695463a79dd8426e115dbea49b8"
-        },
-        "require": {
-            "drupal/core": "~8.0"
-        },
-        "type": "drupal-module",
-        "extra": {
-            "branch-alias": {
-                "dev-1.x": "1.x-dev"
-            },
-            "drupal": {
-                "version": "8.x-1.0",
-                "datestamp": "1507735144",
-                "security-coverage": {
-                    "status": "covered",
-                    "message": "Covered by Drupal's security advisory policy"
-                }
-            }
-        },
-        "installation-source": "dist",
-        "notification-url": "https://packages.drupal.org/8/downloads",
-        "license": [
-            "GPL-2.0-or-later"
-        ],
-        "authors": [
-            {
-                "name": "caiosba",
-                "homepage": "https://www.drupal.org/user/1774198"
-            },
-            {
-                "name": "encelado",
-                "homepage": "https://www.drupal.org/user/701446"
-            },
-            {
-                "name": "infojunkie",
-                "homepage": "https://www.drupal.org/user/48424"
-            }
-        ],
-        "description": "Customize your CSS directly from the browser.",
-        "homepage": "https://www.drupal.org/project/css_editor",
-        "support": {
-            "source": "http://cgit.drupalcode.org/css_editor"
-        }
-    },
     {
         "name": "drupal/ctools",
         "version": "3.0.0",
@@ -3829,6 +4057,85 @@
             "source": "http://cgit.drupalcode.org/externalauth"
         }
     },
+    {
+        "name": "drupal/features",
+        "version": "3.8.0",
+        "version_normalized": "3.8.0.0",
+        "source": {
+            "type": "git",
+            "url": "https://git.drupal.org/project/features",
+            "reference": "8.x-3.8"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://ftp.drupal.org/files/projects/features-8.x-3.8.zip",
+            "reference": "8.x-3.8",
+            "shasum": "15cebd00e38d63c0d946682e76327a03499c27be"
+        },
+        "require": {
+            "drupal/config_update": "^1.4",
+            "drupal/core": "*"
+        },
+        "type": "drupal-module",
+        "extra": {
+            "branch-alias": {
+                "dev-3.x": "3.x-dev"
+            },
+            "drupal": {
+                "version": "8.x-3.8",
+                "datestamp": "1536512284",
+                "security-coverage": {
+                    "status": "covered",
+                    "message": "Covered by Drupal's security advisory policy"
+                }
+            },
+            "drush": {
+                "services": {
+                    "drush.services.yml": "^9"
+                }
+            }
+        },
+        "installation-source": "dist",
+        "notification-url": "https://packages.drupal.org/8/downloads",
+        "license": [
+            "GPL-2.0+"
+        ],
+        "authors": [
+            {
+                "name": "dawehner",
+                "homepage": "https://www.drupal.org/user/99340"
+            },
+            {
+                "name": "e2thex",
+                "homepage": "https://www.drupal.org/user/189123"
+            },
+            {
+                "name": "febbraro",
+                "homepage": "https://www.drupal.org/user/43670"
+            },
+            {
+                "name": "jmiccolis",
+                "homepage": "https://www.drupal.org/user/31731"
+            },
+            {
+                "name": "mpotter",
+                "homepage": "https://www.drupal.org/user/616192"
+            },
+            {
+                "name": "nedjo",
+                "homepage": "https://www.drupal.org/user/4481"
+            },
+            {
+                "name": "tim.plunkett",
+                "homepage": "https://www.drupal.org/user/241634"
+            }
+        ],
+        "description": "Enables administrators to package configuration into modules",
+        "homepage": "https://www.drupal.org/project/features",
+        "support": {
+            "source": "http://cgit.drupalcode.org/features"
+        }
+    },
     {
         "name": "drupal/field_collection",
         "version": "1.0.0-alpha1",
@@ -6292,6 +6599,56 @@
             "issues": "https://www.drupal.org/project/issues/smtp"
         }
     },
+    {
+        "name": "drupal/social_media_links",
+        "version": "2.6.0",
+        "version_normalized": "2.6.0.0",
+        "source": {
+            "type": "git",
+            "url": "https://git.drupal.org/project/social_media_links",
+            "reference": "8.x-2.6"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://ftp.drupal.org/files/projects/social_media_links-8.x-2.6.zip",
+            "reference": "8.x-2.6",
+            "shasum": "53462cb307b104552ae5370b917e55ca50fba526"
+        },
+        "require": {
+            "drupal/core": "~8.0"
+        },
+        "type": "drupal-module",
+        "extra": {
+            "branch-alias": {
+                "dev-2.x": "2.x-dev"
+            },
+            "drupal": {
+                "version": "8.x-2.6",
+                "datestamp": "1510489384",
+                "security-coverage": {
+                    "status": "covered",
+                    "message": "Covered by Drupal's security advisory policy"
+                }
+            }
+        },
+        "installation-source": "dist",
+        "notification-url": "https://packages.drupal.org/8/downloads",
+        "license": [
+            "GPL-2.0+"
+        ],
+        "authors": [
+            {
+                "name": "cbeier",
+                "homepage": "https://www.drupal.org/user/1500710"
+            }
+        ],
+        "description": "The module provides a block that display links (icons) to your profiles on various social networking sites.",
+        "homepage": "https://www.drupal.org/project/social_media_links",
+        "support": {
+            "source": "http://cgit.drupalcode.org/social_media_links",
+            "issues": "https://www.drupal.org/project/issues/social_media_links"
+        }
+    },
     {
         "name": "drupal/superfish",
         "version": "1.2.0",
diff --git a/web/modules/config_filter/.gitignore b/web/modules/config_filter/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..7579f74311d35aae05dd0f0a54537ea7a0034e89
--- /dev/null
+++ b/web/modules/config_filter/.gitignore
@@ -0,0 +1,2 @@
+vendor
+composer.lock
diff --git a/web/modules/config_filter/.travis.yml b/web/modules/config_filter/.travis.yml
new file mode 100644
index 0000000000000000000000000000000000000000..bc434ee3053f648e287c4fbab30d9e9782e0a2d0
--- /dev/null
+++ b/web/modules/config_filter/.travis.yml
@@ -0,0 +1,41 @@
+language: php
+
+php:
+  - 5.6
+  - 7.0
+
+env:
+  global:
+    - PATH=$PATH:/home/travis/.composer/vendor/bin
+
+install:
+  - composer self-update
+
+before_script:
+  # Set sendmail so drush doesn't throw an error during site install.
+  - echo "sendmail_path=`which true`" >> `php --ini | grep "Loaded Configuration" | awk '{print $4}'`
+  # Create database.
+  - mysql -e 'create database drupal'
+  # Install Drupal 8 target site.
+  - cd tests
+  - mkdir -p themes modules profiles
+  - composer install --prefer-dist
+  - ./vendor/bin/drush si standard -y --db-url=mysql://travis:@127.0.0.1/drupal
+  # Test latest commit on current branch.
+  - git clone --branch=$TRAVIS_BRANCH https://github.com/$TRAVIS_REPO_SLUG.git modules/config_filter
+  - ./vendor/bin/drush en config_filter -y
+  # Run Drush web server.
+  - ./vendor/bin/drush --debug runserver :8888 > ~/debug.txt 2>&1 &
+  - sleep 4s
+  - chmod -R ug+w sites
+
+script:
+  - cd $TRAVIS_BUILD_DIR
+  - cd tests
+  - ./vendor/bin/phpcs --config-set installed_paths ../../drupal/coder/coder_sniffer
+  - ./vendor/bin/phpcs --config-set show_progress 1
+  - ./vendor/bin/phpcs --warning-severity=0 --standard=Drupal,DrupalPractice ../src
+  - ./vendor/bin/phpunit
+
+notifications:
+  email: false
diff --git a/web/modules/config_sync/LICENSE.txt b/web/modules/config_filter/LICENSE.txt
similarity index 100%
rename from web/modules/config_sync/LICENSE.txt
rename to web/modules/config_filter/LICENSE.txt
diff --git a/web/modules/config_filter/README.md b/web/modules/config_filter/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..253c90403993fffc825e292a344096510d0e9bdd
--- /dev/null
+++ b/web/modules/config_filter/README.md
@@ -0,0 +1,50 @@
+# Config Filter
+
+[![Build Status](https://travis-ci.org/nuvoleweb/config_filter.svg?branch=8.x-1.x)](https://travis-ci.org/nuvoleweb/config_filter)
+[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/nuvoleweb/config_filter/badges/quality-score.png?b=8.x-1.x)](https://scrutinizer-ci.com/g/nuvoleweb/config_filter/?branch=8.x-1.x)
+
+
+## Introduction
+
+Modules such as Config Split want to modify the configuration when it is
+synchronized between the database and the exported yaml files.
+This module provides the API to do so but does not influence a sites operation.
+
+## How it works
+
+Configuration Filter swaps the config.storage.sync service from Drupal 8 core.
+The new service wraps the file storage and applies filters to it.
+This allows other modules to change the configuration as it gets imported or
+exported both in the Drupal UI and with drush.
+
+## What is a ConfigFilter
+
+A ConfigFilter is a plugin. This module provides the plugin definition, the
+plugin manager and the storage factory.
+A ConfigFilter can have the following annotation:
+
+```php
+/**
+ * @ConfigFilter(
+ *   id = "may_plugin_id",
+ *   label = @Translation("An example configuration filter"),
+ *   weight = 0,
+ *   status = TRUE,
+ *   storages = {"config.storage.sync"},
+ * )
+ */
+```
+See `\Drupal\config_filter\Annotation\ConfigFilter`.
+
+The weight allows the filters to be sorted. The status allows the filter to be
+active or inactive, the `ConfigFilterManagerInterface::getFiltersForStorages`
+will only take active filters into consideration. The weight, status and
+storages are optional and the above values are the default.
+
+## Alternative Config Filter Managers
+
+Plugins are only available from enabled modules. If you want to provide a
+config filter from a php library, all you have to do is implement the
+`\Drupal\config_filter\ConfigFilterManagerInterface` and add it to the
+service container with a `config.filter` tag.
+Services with higher priority will have their filters added first.
diff --git a/web/modules/config_filter/composer.json b/web/modules/config_filter/composer.json
new file mode 100644
index 0000000000000000000000000000000000000000..68bbb961a96975108040f12405c384c080d4e1ad
--- /dev/null
+++ b/web/modules/config_filter/composer.json
@@ -0,0 +1,31 @@
+{
+  "name": "drupal/config_filter",
+  "type": "drupal-module",
+  "description": "Config Filter allows other modules to interact with a ConfigStorage through filter plugins.",
+  "keywords": ["Drupal", "configuration", "configuration management"],
+  "authors": [
+    {
+      "name": "Fabian Bircher",
+      "email": "opensource@fabianbircher.com",
+      "homepage": "https://www.drupal.org/u/bircher",
+      "role": "Maintainer"
+    },
+    {
+      "name": "Nuvole Web",
+      "email": "info@nuvole.org",
+      "homepage": "http://nuvole.org",
+      "role": "Maintainer"
+    }
+  ],
+  "homepage": "https://www.drupal.org/project/config_filter",
+  "support": {
+    "issues": "https://www.drupal.org/project/issues/config_filter",
+    "irc": "irc://irc.freenode.org/drupal-contribute",
+    "source": "http://cgit.drupalcode.org/config_filter"
+  },
+  "license": "GPL-2.0+",
+  "require": {},
+  "suggest": {
+    "drupal/config_split": "Split site configuration for different environments."
+  }
+}
diff --git a/web/modules/config_filter/config_filter.info.yml b/web/modules/config_filter/config_filter.info.yml
new file mode 100644
index 0000000000000000000000000000000000000000..09a4d71c837ee423969170bd086e5191b60ef3f0
--- /dev/null
+++ b/web/modules/config_filter/config_filter.info.yml
@@ -0,0 +1,11 @@
+name: Config Filter
+type: module
+description: Config Filter allows other modules to interact with a ConfigStorage through filter plugins.
+# core: 8.x
+package: Config
+
+# Information added by Drupal.org packaging script on 2018-09-26
+version: '8.x-1.3'
+core: '8.x'
+project: 'config_filter'
+datestamp: 1537978084
diff --git a/web/modules/config_filter/config_filter.services.yml b/web/modules/config_filter/config_filter.services.yml
new file mode 100644
index 0000000000000000000000000000000000000000..5d77008dbe275de7c900fc122ac2b297dc0b9c41
--- /dev/null
+++ b/web/modules/config_filter/config_filter.services.yml
@@ -0,0 +1,16 @@
+services:
+  plugin.manager.config_filter:
+    class: Drupal\config_filter\Plugin\ConfigFilterPluginManager
+    parent: default_plugin_manager
+    tags:
+      - { name: config.filter }
+  config_filter.storage.sync:
+    class: Drupal\config_filter\Config\FilteredStorage
+    factory: config_filter.storage_factory:getSync
+    decorates: config.storage.staging
+    public: false
+  config_filter.storage_factory:
+    class: Drupal\config_filter\ConfigFilterStorageFactory
+    arguments: ['@config_filter.storage.sync.inner']
+    tags:
+      - { name: service_collector, tag: 'config.filter', call: addConfigFilterManager }
diff --git a/web/modules/config_filter/src/Annotation/ConfigFilter.php b/web/modules/config_filter/src/Annotation/ConfigFilter.php
new file mode 100644
index 0000000000000000000000000000000000000000..5d768382aedef6ab3ad2f9cec6d4f6aadbab692b
--- /dev/null
+++ b/web/modules/config_filter/src/Annotation/ConfigFilter.php
@@ -0,0 +1,62 @@
+<?php
+
+namespace Drupal\config_filter\Annotation;
+
+use Drupal\Component\Annotation\Plugin;
+
+/**
+ * Defines a Config filter plugin item annotation object.
+ *
+ * @see \Drupal\config_filter\Plugin\ConfigFilterPluginManager
+ * @see plugin_api
+ *
+ * @Annotation
+ */
+class ConfigFilter extends Plugin {
+
+
+  /**
+   * The plugin ID.
+   *
+   * @var string
+   */
+  public $id;
+
+  /**
+   * The label of the plugin.
+   *
+   * @var \Drupal\Core\Annotation\Translation
+   *
+   * @ingroup plugin_translatable
+   */
+  public $label;
+
+  /**
+   * The plugin weight.
+   *
+   * The higher the weight the later in the filter order the plugin will be.
+   *
+   * @var int
+   */
+  public $weight = 0;
+
+  /**
+   * The status of the plugin.
+   *
+   * This is an easy way to turn off plugins.
+   *
+   * @var bool
+   */
+  public $status = TRUE;
+
+  /**
+   * The storages the plugin filters on.
+   *
+   * If it is left empty ['config.storage.sync'] will be assumed.
+   * The only storage which is currently filtered is 'config.storage.sync'.
+   *
+   * @var string[]
+   */
+  public $storages = [];
+
+}
diff --git a/web/modules/config_filter/src/Config/FilteredStorage.php b/web/modules/config_filter/src/Config/FilteredStorage.php
new file mode 100644
index 0000000000000000000000000000000000000000..fb3678a234772fa24049562d61b6b9f7abfef1df
--- /dev/null
+++ b/web/modules/config_filter/src/Config/FilteredStorage.php
@@ -0,0 +1,243 @@
+<?php
+
+namespace Drupal\config_filter\Config;
+
+use Drupal\config_filter\Exception\InvalidStorageFilterException;
+use Drupal\Core\Config\StorageInterface;
+
+/**
+ * Class FilteredStorage.
+ *
+ * This class wraps another storage.
+ * It filters the arguments before passing them on to the storage for write
+ * operations and filters the result of read operations before returning them.
+ *
+ * @package Drupal\config_filter\Config
+ */
+class FilteredStorage implements FilteredStorageInterface {
+
+  /**
+   * The storage container that we are wrapping.
+   *
+   * @var \Drupal\Core\Config\StorageInterface
+   */
+  protected $storage;
+
+  /**
+   * The storage filters.
+   *
+   * @var \Drupal\config_filter\Config\StorageFilterInterface[]
+   */
+  protected $filters;
+
+  /**
+   * Create a FilteredStorage with some storage and a filter.
+   *
+   * @param \Drupal\Core\Config\StorageInterface $storage
+   *   The decorated storage.
+   * @param \Drupal\config_filter\Config\StorageFilterInterface[] $filters
+   *   The filters to apply in the given order.
+   */
+  public function __construct(StorageInterface $storage, array $filters) {
+    $this->storage = $storage;
+    $this->filters = $filters;
+
+    // Set the storage to all the filters.
+    foreach ($this->filters as $filter) {
+      if (!$filter instanceof StorageFilterInterface) {
+        throw new InvalidStorageFilterException();
+      }
+      $filter->setSourceStorage(new ReadOnlyStorage($storage));
+      $filter->setFilteredStorage($this);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function exists($name) {
+    $exists = $this->storage->exists($name);
+    foreach ($this->filters as $filter) {
+      $exists = $filter->filterExists($name, $exists);
+    }
+
+    return $exists;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function read($name) {
+    $data = $this->storage->read($name);
+    foreach ($this->filters as $filter) {
+      $data = $filter->filterRead($name, $data);
+    }
+
+    return $data;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function readMultiple(array $names) {
+    $data = $this->storage->readMultiple($names);
+    foreach ($this->filters as $filter) {
+      $data = $filter->filterReadMultiple($names, $data);
+    }
+    ksort($data);
+    return array_filter($data);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function write($name, array $data) {
+    foreach ($this->filters as $filter) {
+      if ($data) {
+        $data = $filter->filterWrite($name, $data);
+      }
+      else {
+        // The filterWrite has an array type hint in the interface.
+        $data = $filter->filterWrite($name, []);
+      }
+    }
+
+    if ($data) {
+      return $this->storage->write($name, $data);
+    }
+
+    // The data has been unset, check if it should be deleted.
+    if ($this->storage->exists($name)) {
+      foreach ($this->filters as $filter) {
+        if ($filter->filterWriteEmptyIsDelete($name)) {
+          return $this->storage->delete($name);
+        }
+      }
+    }
+
+    // The data was not written, but it is not an error.
+    return TRUE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function delete($name) {
+    $success = TRUE;
+    foreach ($this->filters as $filter) {
+      $success = $filter->filterDelete($name, $success);
+    }
+
+    if ($success) {
+      $success = $this->storage->delete($name);
+    }
+
+    return $success;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function rename($name, $new_name) {
+    $success = TRUE;
+    foreach ($this->filters as $filter) {
+      $success = $filter->filterRename($name, $new_name, $success);
+    }
+
+    if ($success) {
+      $success = $this->storage->rename($name, $new_name);
+    }
+
+    return $success;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function encode($data) {
+    return $this->storage->encode($data);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function decode($raw) {
+    return $this->storage->decode($raw);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function listAll($prefix = '') {
+    $data = $this->storage->listAll($prefix);
+    foreach ($this->filters as $filter) {
+      $data = $filter->filterListAll($prefix, $data);
+    }
+    sort($data);
+    return $data;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function deleteAll($prefix = '') {
+    $delete = TRUE;
+    foreach ($this->filters as $filter) {
+      $delete = $filter->filterDeleteAll($prefix, $delete);
+    }
+
+    if ($delete) {
+      return $this->storage->deleteAll($prefix);
+    }
+
+    // The filters returned FALSE for $delete, so we delete the names
+    // individually and allow filters to prevent deleting the config.
+    foreach ($this->storage->listAll($prefix) as $name) {
+      $this->delete($name);
+    }
+
+    // The filters wanted to prevent deleting all and were called to delete the
+    // individual config name, is this a success? Let us say it is.
+    return TRUE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function createCollection($collection) {
+    $filters = [];
+    foreach ($this->filters as $key => $filter) {
+      $filter = $filter->filterCreateCollection($collection);
+      if ($filter) {
+        $filters[$key] = $filter;
+      }
+    }
+
+    return new static($this->storage->createCollection($collection), $filters);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getAllCollectionNames() {
+    $collections = $this->storage->getAllCollectionNames();
+    foreach ($this->filters as $filter) {
+      $collections = $filter->filterGetAllCollectionNames($collections);
+    }
+    sort($collections);
+    return $collections;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCollectionName() {
+    $collection = $this->storage->getCollectionName();
+    foreach ($this->filters as $filter) {
+      $collection = $filter->filterGetCollectionName($collection);
+    }
+
+    return $collection;
+  }
+
+}
diff --git a/web/modules/config_filter/src/Config/FilteredStorageInterface.php b/web/modules/config_filter/src/Config/FilteredStorageInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..0da0f131ddcc978dfdacbe4dabe18fc6e5241573
--- /dev/null
+++ b/web/modules/config_filter/src/Config/FilteredStorageInterface.php
@@ -0,0 +1,12 @@
+<?php
+
+namespace Drupal\config_filter\Config;
+
+use Drupal\Core\Config\StorageInterface;
+
+/**
+ * Essentially the StorageInterface, but knowing that config_filter is used.
+ */
+interface FilteredStorageInterface extends StorageInterface {
+
+}
diff --git a/web/modules/config_filter/src/Config/GhostStorage.php b/web/modules/config_filter/src/Config/GhostStorage.php
new file mode 100644
index 0000000000000000000000000000000000000000..afd44f10ebbcf51ce454c562339b6c1c3806d4eb
--- /dev/null
+++ b/web/modules/config_filter/src/Config/GhostStorage.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace Drupal\config_filter\Config;
+
+use Drupal\Core\Config\StorageInterface;
+
+/**
+ * Class GhostStorage.
+ *
+ * A GhostStorage acts like the normal Storage it wraps. All reading operations
+ * return the values of the decorated storage but write operations are silently
+ * ignored and the ghost pretends that the operation was successful.
+ *
+ * @package Drupal\config_filter\Config
+ */
+class GhostStorage extends ReadOnlyStorage implements StorageInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function write($name, array $data) {
+    return TRUE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function delete($name) {
+    return TRUE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function rename($name, $new_name) {
+    return TRUE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function deleteAll($prefix = '') {
+    return TRUE;
+  }
+
+}
diff --git a/web/modules/config_filter/src/Config/ReadOnlyStorage.php b/web/modules/config_filter/src/Config/ReadOnlyStorage.php
new file mode 100644
index 0000000000000000000000000000000000000000..ca9aad655f151b03ac945a20bcfa9d032b24e851
--- /dev/null
+++ b/web/modules/config_filter/src/Config/ReadOnlyStorage.php
@@ -0,0 +1,125 @@
+<?php
+
+namespace Drupal\config_filter\Config;
+
+use Drupal\Core\Config\StorageInterface;
+use Drupal\config_filter\Exception\UnsupportedMethod;
+
+/**
+ * Class ReadOnlyStorage.
+ *
+ * This is like any other StorageInterface, except it does not allow writing.
+ *
+ * @package Drupal\config_filter\Config
+ */
+class ReadOnlyStorage implements StorageInterface {
+
+  /**
+   * The config storage that we are decorating.
+   *
+   * @var \Drupal\Core\Config\StorageInterface
+   */
+  protected $storage;
+
+  /**
+   * Create a ReadOnlyStorage decorating another storage.
+   *
+   * @param \Drupal\Core\Config\StorageInterface $storage
+   *   The decorated storage.
+   */
+  public function __construct(StorageInterface $storage) {
+    $this->storage = $storage;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function exists($name) {
+    return $this->storage->exists($name);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function read($name) {
+    return $this->storage->read($name);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function readMultiple(array $names) {
+    return $this->storage->readMultiple($names);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function write($name, array $data) {
+    throw new UnsupportedMethod(__METHOD__ . ' is not allowed on a ReadOnlyStorage');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function delete($name) {
+    throw new UnsupportedMethod(__METHOD__ . ' is not allowed on a ReadOnlyStorage');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function rename($name, $new_name) {
+    throw new UnsupportedMethod(__METHOD__ . ' is not allowed on a ReadOnlyStorage');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function encode($data) {
+    return $this->storage->encode($data);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function decode($raw) {
+    return $this->storage->decode($raw);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function listAll($prefix = '') {
+    return $this->storage->listAll($prefix);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function deleteAll($prefix = '') {
+    throw new UnsupportedMethod(__METHOD__ . ' is not allowed on a ReadOnlyStorage');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function createCollection($collection) {
+    return new static($this->storage->createCollection($collection));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getAllCollectionNames() {
+    return $this->storage->getAllCollectionNames();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCollectionName() {
+    return $this->storage->getCollectionName();
+  }
+
+}
diff --git a/web/modules/config_filter/src/Config/StorageFilterInterface.php b/web/modules/config_filter/src/Config/StorageFilterInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..ad2c38eb93274adf48aa89c9f357201a0990abd0
--- /dev/null
+++ b/web/modules/config_filter/src/Config/StorageFilterInterface.php
@@ -0,0 +1,223 @@
+<?php
+
+namespace Drupal\config_filter\Config;
+
+use Drupal\Core\Config\StorageInterface;
+
+/**
+ * Interface StorageFilterInterface.
+ *
+ * This interface defines a config storage filter as the FilteredStorage expects
+ * to use when filtering the operations on the storage. The ConfigFilter plugin
+ * interface extends this interface, together with plugin related interfaces.
+ *
+ * A well-behaved filter does not perform any write operation in a read method.
+ *
+ * @package Drupal\config_split\Config
+ */
+interface StorageFilterInterface {
+
+  /**
+   * Sets the source config storage on which the operation is performed.
+   *
+   * The storage is given to the filter when the storage wrapper is set up,
+   * to avoid passing the storage to each of the filters so that they can read
+   * from it before writing filtered config. The storage is read-only, use the
+   * decorated storage to allow all filters to work for write operations.
+   *
+   * @param \Drupal\Core\Config\StorageInterface $storage
+   *   The storage on which the operation is performed.
+   */
+  public function setSourceStorage(StorageInterface $storage);
+
+  /**
+   * Sets the wrapped config storage which is using the filter.
+   *
+   * This storage is available to the filter in order to inspect how the end
+   * result looks like. This is useful for reading configuration from the
+   * storage as drupal will. Beware of recursive calls to the filter.
+   *
+   * @param \Drupal\Core\Config\StorageInterface $storage
+   *   The storage which has the filters applied.
+   */
+  public function setFilteredStorage(StorageInterface $storage);
+
+  /**
+   * Filters configuration data after it is read from the storage.
+   *
+   * @param string $name
+   *   The name of a configuration object to load.
+   * @param array|bool $data
+   *   The configuration data to filter.
+   *
+   * @return array|bool
+   *   The filtered data.
+   */
+  public function filterRead($name, $data);
+
+  /**
+   * Filter configuration data before it is written to the storage.
+   *
+   * @param string $name
+   *   The name of a configuration object to save.
+   * @param array $data
+   *   The configuration data to filter.
+   *
+   * @return array|null
+   *   The filtered data.
+   */
+  public function filterWrite($name, array $data);
+
+  /**
+   * Let the filter decide whether not-writing data should mean delete.
+   *
+   * Filters can return NULL for `filterWrite($name, $data)` which means to
+   * not write the data to the source storage, but it can also mean deleting it.
+   *
+   * @param string $name
+   *   The name of a configuration object to save.
+   *
+   * @return bool|null
+   *   True to delete at the end of a filtered write action.
+   */
+  public function filterWriteEmptyIsDelete($name);
+
+  /**
+   * Filters whether a configuration object exists.
+   *
+   * @param string $name
+   *   The name of a configuration object to test.
+   * @param bool $exists
+   *   The previous result to alter.
+   *
+   * @return bool
+   *   TRUE if the configuration object exists, FALSE otherwise.
+   */
+  public function filterExists($name, $exists);
+
+  /**
+   * Deletes a configuration object from the storage.
+   *
+   * @param string $name
+   *   The name of a configuration object to delete.
+   * @param bool $delete
+   *   Whether the previous filter allows to delete.
+   *
+   * @return bool
+   *   TRUE to allow deletion, FALSE otherwise.
+   */
+  public function filterDelete($name, $delete);
+
+  /**
+   * Filters read configuration data from the storage.
+   *
+   * @param array $names
+   *   List of names of the configuration objects to load.
+   * @param array $data
+   *   A list of the configuration data stored for the configuration object name
+   *   that could be loaded for the passed list of names.
+   *
+   * @return array
+   *   A list of the configuration data stored for the configuration object name
+   *   that could be loaded for the passed list of names.
+   */
+  public function filterReadMultiple(array $names, array $data);
+
+  /**
+   * Filters renaming a configuration object in the storage.
+   *
+   * @param string $name
+   *   The name of a configuration object to rename.
+   * @param string $new_name
+   *   The new name of a configuration object.
+   * @param bool $rename
+   *   Allowing renaming by previous filters.
+   *
+   * @return bool
+   *   TRUE to allow renaming, FALSE otherwise.
+   */
+  public function filterRename($name, $new_name, $rename);
+
+  /**
+   * Filters what listAll should return.
+   *
+   * @param string $prefix
+   *   The prefix to search for. If omitted, all configuration object
+   *   names that exist are returned.
+   * @param array $data
+   *   The data returned by the storage.
+   *
+   * @return array
+   *   The filtered configuration set.
+   */
+  public function filterListAll($prefix, array $data);
+
+  /**
+   * Deletes configuration objects whose names start with a given prefix.
+   *
+   * Given the following configuration object names:
+   * - node.type.article
+   * - node.type.page.
+   *
+   * Passing the prefix 'node.type.' will delete the above configuration
+   * objects.
+   *
+   * @param string $prefix
+   *   The prefix to search for. If omitted, all configuration
+   *   objects that exist will be deleted.
+   * @param bool $delete
+   *   Whether to delete all or not.
+   *
+   * @return bool
+   *   TRUE to allow deleting all, FALSE to trigger individual deletion.
+   */
+  public function filterDeleteAll($prefix, $delete);
+
+  /**
+   * Allows the filter to react on creating a collection on the storage.
+   *
+   * A configuration storage can contain multiple sets of configuration objects
+   * in partitioned collections. The collection name identifies the current
+   * collection used.
+   *
+   * @param string $collection
+   *   The collection name. Valid collection names conform to the following
+   *   regex [a-zA-Z_.]. A storage does not need to have a collection set.
+   *   However, if a collection is set, then the storage should use it to store
+   *   configuration in a way that allows retrieval of configuration for a
+   *   particular collection.
+   *
+   * @return \Drupal\config_filter\Config\StorageFilterInterface|null
+   *   Return a filter that should participate in the collection. This allows
+   *   filters to act on different collections. Note that a new instance of the
+   *   filter should be created rather than returning $this directly.
+   */
+  public function filterCreateCollection($collection);
+
+  /**
+   * Filter getting the existing collections.
+   *
+   * A configuration storage can contain multiple sets of configuration objects
+   * in partitioned collections. The collection key name identifies the current
+   * collection used.
+   *
+   * @param string[] $collections
+   *   The array of existing collection names.
+   *
+   * @return array
+   *   An array of existing collection names.
+   */
+  public function filterGetAllCollectionNames(array $collections);
+
+  /**
+   * Filter the name of the current collection the storage is using.
+   *
+   * @param string $collection
+   *   The collection found by the storage.
+   *
+   * @return string
+   *   The current collection name.
+   */
+  public function filterGetCollectionName($collection);
+
+}
diff --git a/web/modules/config_filter/src/Config/TransparentStorageFilterTrait.php b/web/modules/config_filter/src/Config/TransparentStorageFilterTrait.php
new file mode 100644
index 0000000000000000000000000000000000000000..b4eb7d5cb39324570b40b3445d4c294efd8c0a4b
--- /dev/null
+++ b/web/modules/config_filter/src/Config/TransparentStorageFilterTrait.php
@@ -0,0 +1,151 @@
+<?php
+
+namespace Drupal\config_filter\Config;
+
+use Drupal\Core\Config\StorageInterface;
+
+/**
+ * Trait TransparentStorageFilterTrait.
+ *
+ * Use this trait or ConfigFilterBase to implement a config storage filter.
+ * Filters do not need to be plugins but it is probably the most convenient way
+ * to create them. Use this trait to ensure compatibility in case the interface
+ * ever needs to change for some reason.
+ *
+ * @package Drupal\config_filter\Config
+ */
+trait TransparentStorageFilterTrait {
+
+  /**
+   * The read-only source storage on which the filter operations are performed.
+   *
+   * @var \Drupal\Core\Config\StorageInterface
+   */
+  protected $source;
+
+  /**
+   * The wrapped storage which calls the filter.
+   *
+   * @var \Drupal\Core\Config\StorageInterface
+   */
+  protected $filtered;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setSourceStorage(StorageInterface $storage) {
+    $this->source = $storage;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setFilteredStorage(StorageInterface $storage) {
+    $this->filtered = $storage;
+  }
+
+  /**
+   * Get the read-only source Storage.
+   *
+   * @return \Drupal\Core\Config\StorageInterface
+   *   The source storage.
+   */
+  protected function getSourceStorage() {
+    return $this->source;
+  }
+
+  /**
+   * Get the decorator storage which applies the filters.
+   *
+   * @return \Drupal\Core\Config\StorageInterface
+   *   The filtered decorator storage.
+   */
+  protected function getFilteredStorage() {
+    return $this->filtered;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function filterRead($name, $data) {
+    return $data;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function filterWrite($name, array $data) {
+    return $data;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function filterWriteEmptyIsDelete($name) {
+    return NULL;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function filterExists($name, $exists) {
+    return $exists;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function filterDelete($name, $delete) {
+    return $delete;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function filterReadMultiple(array $names, array $data) {
+    return $data;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function filterRename($name, $new_name, $rename) {
+    return $rename;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function filterListAll($prefix, array $data) {
+    return $data;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function filterDeleteAll($prefix, $delete) {
+    return $delete;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function filterCreateCollection($collection) {
+    return clone $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function filterGetAllCollectionNames(array $collections) {
+    return $collections;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function filterGetCollectionName($collection) {
+    return $collection;
+  }
+
+}
diff --git a/web/modules/config_filter/src/ConfigFilterManagerInterface.php b/web/modules/config_filter/src/ConfigFilterManagerInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..6e7c10254fa25eeb04f69358a449962f22c2fc5c
--- /dev/null
+++ b/web/modules/config_filter/src/ConfigFilterManagerInterface.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace Drupal\config_filter;
+
+/**
+ * Interface ConfigFilterManagerInterface.
+ */
+interface ConfigFilterManagerInterface {
+
+  /**
+   * Get the applicable filters for given storage names.
+   *
+   * @param string[] $storage_names
+   *   The names of the storage plugins apply to.
+   * @param string[] $excluded
+   *   The ids of filters to exclude.
+   *
+   * @return \Drupal\config_filter\Config\StorageFilterInterface[]
+   *   The configured filter instances, keyed by filter id.
+   */
+  public function getFiltersForStorages(array $storage_names, array $excluded = []);
+
+  /**
+   * Get a configured filter instance by (plugin) id.
+   *
+   * @param string $id
+   *   The plugin id of the filter to load.
+   *
+   * @return \Drupal\config_filter\Config\StorageFilterInterface
+   *   The ConfigFilter.
+   */
+  public function getFilterInstance($id);
+
+}
diff --git a/web/modules/config_filter/src/ConfigFilterStorageFactory.php b/web/modules/config_filter/src/ConfigFilterStorageFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..dec320f637629797ff47cb964cb304ba1d012f74
--- /dev/null
+++ b/web/modules/config_filter/src/ConfigFilterStorageFactory.php
@@ -0,0 +1,93 @@
+<?php
+
+namespace Drupal\config_filter;
+
+use Drupal\config_filter\Config\FilteredStorage;
+use Drupal\Core\Config\StorageInterface;
+
+/**
+ * Class ConfigFilterFactory.
+ */
+class ConfigFilterStorageFactory {
+
+  /**
+   * The decorated sync config storage.
+   *
+   * @var \Drupal\Core\Config\StorageInterface
+   */
+  protected $sync;
+
+  /**
+   * The filter managers to load the filters from.
+   *
+   * @var \Drupal\config_filter\ConfigFilterManagerInterface[]
+   */
+  protected $managers = [];
+
+  /**
+   * ConfigFilterFactory constructor.
+   *
+   * @param \Drupal\Core\Config\StorageInterface $sync
+   *   The original sync storage which is decorated by our filtered storage.
+   */
+  public function __construct(StorageInterface $sync) {
+    $this->sync = $sync;
+  }
+
+  /**
+   * Add a config filter manager.
+   *
+   * @param \Drupal\config_filter\ConfigFilterManagerInterface $manager
+   *   The ConfigFilter plugin manager.
+   */
+  public function addConfigFilterManager(ConfigFilterManagerInterface $manager) {
+    $this->managers[] = $manager;
+  }
+
+  /**
+   * Get the sync storage Drupal uses.
+   *
+   * @return \Drupal\config_filter\Config\FilteredStorageInterface
+   *   The decorated sync config storage.
+   */
+  public function getSync() {
+    return $this->getFilteredStorage($this->sync, ['config.storage.sync']);
+  }
+
+  /**
+   * Get the sync storage Drupal uses and exclude some plugins.
+   *
+   * @param string[] $excluded
+   *   The ids of filters to exclude.
+   *
+   * @return \Drupal\config_filter\Config\FilteredStorageInterface
+   *   The decorated sync config storage.
+   */
+  public function getSyncWithoutExcluded(array $excluded) {
+    return $this->getFilteredStorage($this->sync, ['config.storage.sync'], $excluded);
+  }
+
+  /**
+   * Get a decorated storage with filters applied.
+   *
+   * @param \Drupal\Core\Config\StorageInterface $storage
+   *   The storage to decorate.
+   * @param string[] $storage_names
+   *   The names of the storage, so the correct filters can be applied.
+   * @param string[] $excluded
+   *   The ids of filters to exclude.
+   *
+   * @return \Drupal\config_filter\Config\FilteredStorageInterface
+   *   The decorated storage with the filters applied.
+   */
+  public function getFilteredStorage(StorageInterface $storage, array $storage_names, array $excluded = []) {
+    $filters = [];
+    foreach ($this->managers as $manager) {
+      // Filters from managers that come first will not be overwritten by
+      // filters from lower priority managers.
+      $filters = $filters + $manager->getFiltersForStorages($storage_names, $excluded);
+    }
+    return new FilteredStorage($storage, $filters);
+  }
+
+}
diff --git a/web/modules/config_filter/src/Exception/InvalidStorageFilterException.php b/web/modules/config_filter/src/Exception/InvalidStorageFilterException.php
new file mode 100644
index 0000000000000000000000000000000000000000..f3a62fe602ed9da6847f6f1d25a3babe50178e77
--- /dev/null
+++ b/web/modules/config_filter/src/Exception/InvalidStorageFilterException.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace Drupal\config_filter\Exception;
+
+use Drupal\config_filter\Config\StorageFilterInterface;
+
+/**
+ * Thrown when a StorageFilterInterface is expected but not present.
+ */
+class InvalidStorageFilterException extends \InvalidArgumentException {
+
+  /**
+   * InvalidStorageFilterException constructor.
+   */
+  public function __construct() {
+    parent::__construct("An argument does not implement " . StorageFilterInterface::class);
+  }
+
+}
diff --git a/web/modules/config_filter/src/Exception/UnsupportedMethod.php b/web/modules/config_filter/src/Exception/UnsupportedMethod.php
new file mode 100644
index 0000000000000000000000000000000000000000..a6f5a17f89b0a7876ba9e4c0a18383a00b5e9065
--- /dev/null
+++ b/web/modules/config_filter/src/Exception/UnsupportedMethod.php
@@ -0,0 +1,9 @@
+<?php
+
+namespace Drupal\config_filter\Exception;
+
+/**
+ * Thrown when calling an unsupported method on a ConfigStorage object.
+ */
+class UnsupportedMethod extends \BadMethodCallException {
+}
diff --git a/web/modules/config_filter/src/Plugin/ConfigFilterBase.php b/web/modules/config_filter/src/Plugin/ConfigFilterBase.php
new file mode 100644
index 0000000000000000000000000000000000000000..52d3db26ddf8198ef709658dd4f4a2a67cd7dcb5
--- /dev/null
+++ b/web/modules/config_filter/src/Plugin/ConfigFilterBase.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace Drupal\config_filter\Plugin;
+
+use Drupal\Component\Plugin\PluginBase;
+use Drupal\config_filter\Config\TransparentStorageFilterTrait;
+
+/**
+ * Base class for Config filter plugin plugins.
+ */
+abstract class ConfigFilterBase extends PluginBase implements ConfigFilterInterface {
+
+  use TransparentStorageFilterTrait;
+
+}
diff --git a/web/modules/config_filter/src/Plugin/ConfigFilterInterface.php b/web/modules/config_filter/src/Plugin/ConfigFilterInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..66748734a77e9bb34dc9b03012be276f90dc5c9b
--- /dev/null
+++ b/web/modules/config_filter/src/Plugin/ConfigFilterInterface.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace Drupal\config_filter\Plugin;
+
+use Drupal\Component\Plugin\PluginInspectionInterface;
+use Drupal\config_filter\Config\StorageFilterInterface;
+
+/**
+ * Defines an interface for Config filter plugin plugins.
+ */
+interface ConfigFilterInterface extends PluginInspectionInterface, StorageFilterInterface {
+
+}
diff --git a/web/modules/config_filter/src/Plugin/ConfigFilterPluginManager.php b/web/modules/config_filter/src/Plugin/ConfigFilterPluginManager.php
new file mode 100644
index 0000000000000000000000000000000000000000..3f253ef493f5d995ded97fb71de82482601c08c2
--- /dev/null
+++ b/web/modules/config_filter/src/Plugin/ConfigFilterPluginManager.php
@@ -0,0 +1,80 @@
+<?php
+
+namespace Drupal\config_filter\Plugin;
+
+use Drupal\config_filter\ConfigFilterManagerInterface;
+use Drupal\Core\Plugin\DefaultPluginManager;
+use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+
+/**
+ * Provides the Config filter plugin plugin manager.
+ */
+class ConfigFilterPluginManager extends DefaultPluginManager implements ConfigFilterManagerInterface {
+
+  /**
+   * Constructor for ConfigFilterPluginManager objects.
+   *
+   * @param \Traversable $namespaces
+   *   An object that implements \Traversable which contains the root paths
+   *   keyed by the corresponding namespace to look for plugin implementations.
+   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
+   *   Cache backend instance to use.
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler to invoke the alter hook with.
+   */
+  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
+    parent::__construct('Plugin/ConfigFilter', $namespaces, $module_handler, 'Drupal\config_filter\Plugin\ConfigFilterInterface', 'Drupal\config_filter\Annotation\ConfigFilter');
+
+    $this->alterInfo('config_filter_info');
+    $this->setCacheBackend($cache_backend, 'config_filter_plugins');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFiltersForStorages(array $storage_names, array $excluded = []) {
+    $definitions = $this->getDefinitions();
+    $filters = [];
+    foreach ($definitions as $id => $definition) {
+      if ($definition['status'] && array_intersect($storage_names, $definition['storages']) && !in_array($id, $excluded)) {
+        $filters[$id] = $this->createInstance($id, $definition);
+      }
+    }
+
+    return $filters;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFilterInstance($id) {
+    $definitions = $this->getDefinitions();
+    if (array_key_exists($id, $definitions)) {
+      return $this->createInstance($id, $definitions[$id]);
+    }
+
+    return NULL;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function findDefinitions() {
+    $definitions = array_map(function ($definition) {
+      if (empty($definition['storages'])) {
+        // The sync storage is the default.
+        $definition['storages'] = ['config.storage.sync'];
+      }
+      return $definition;
+    }, parent::findDefinitions());
+
+    // Sort the definitions by weight.
+    uasort($definitions, function ($a, $b) {
+      return strcmp($a['weight'], $b['weight']);
+    });
+
+    return $definitions;
+  }
+
+}
diff --git a/web/modules/config_filter/src/Tests/FilteredStorageTest.php b/web/modules/config_filter/src/Tests/FilteredStorageTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..8f7fe97b7d517712a8420be77697f407b8b2d7aa
--- /dev/null
+++ b/web/modules/config_filter/src/Tests/FilteredStorageTest.php
@@ -0,0 +1,414 @@
+<?php
+
+namespace Drupal\config_filter\Tests;
+
+use Drupal\config_filter\Config\FilteredStorage;
+use Drupal\config_filter\Config\FilteredStorageInterface;
+use Drupal\config_filter\Config\ReadOnlyStorage;
+use Drupal\config_filter\Config\StorageFilterInterface;
+use Drupal\config_filter\Exception\InvalidStorageFilterException;
+use Drupal\Core\Config\CachedStorage;
+use Drupal\Core\Config\StorageInterface;
+use Drupal\KernelTests\Core\Config\Storage\CachedStorageTest;
+use Prophecy\Argument;
+
+/**
+ * Tests StorageWrapper operations using the CachedStorage.
+ *
+ * @group config_filter
+ */
+class FilteredStorageTest extends CachedStorageTest {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    // The storage is a wrapper with a transparent filter.
+    // So all inherited tests should still pass.
+    $this->storage = new FilteredStorage($this->storage, [new TransparentFilter()]);
+  }
+
+  /**
+   * Test that the storage is set on the filters.
+   */
+  public function testSettingStorages() {
+    /** @var \Drupal\config_filter\Tests\TransparentFilter[] $filters */
+    $filters = static::getProtectedFilters($this->storage);
+    foreach ($filters as $filter) {
+      // Test that the source storage is a ReadonlyStorage and wraps the cached
+      // storage from the inherited test.
+      $readonly = $filter->getPrivateSourceStorage();
+      $this->assertInstanceOf(ReadOnlyStorage::class, $readonly);
+      $readonlyReflection = new \ReflectionClass(ReadOnlyStorage::class);
+      $storageProperty = $readonlyReflection->getProperty('storage');
+      $storageProperty->setAccessible(TRUE);
+      $source = $storageProperty->getValue($readonly);
+      $this->assertInstanceOf(CachedStorage::class, $source);
+
+      // Assert that the filter gets the storage.
+      $this->assertEquals($this->storage, $filter->getPrivateFilteredStorage());
+    }
+  }
+
+  /**
+   * Test that creating collections keeps filters set to the correct storages.
+   */
+  public function testCollectionStorages() {
+    $collection = $this->randomString();
+
+    // The storage is in its default state.
+    $this->assertEquals(StorageInterface::DEFAULT_COLLECTION, $this->storage->getCollectionName());
+
+    /** @var \Drupal\config_filter\Tests\TransparentFilter[] $filters */
+    $filters = static::getProtectedFilters($this->storage);
+    foreach ($filters as $filter) {
+      // Test that the filters have the correct storage set.
+      $this->assertEquals($this->storage, $filter->getPrivateFilteredStorage());
+      $this->assertEquals(StorageInterface::DEFAULT_COLLECTION, $filter->getPrivateSourceStorage()->getCollectionName());
+    }
+
+    // Create a collection which creates a clone of the storage and filters.
+    $collectionStorage = $this->storage->createCollection($collection);
+    $this->assertInstanceOf(FilteredStorageInterface::class, $collectionStorage);
+
+    /** @var \Drupal\config_filter\Tests\TransparentFilter[] $collectionFilters */
+    $collectionFilters = static::getProtectedFilters($collectionStorage);
+    foreach ($collectionFilters as $filter) {
+      // Test that the cloned filter has the correct storage set.
+      $this->assertEquals($collectionStorage, $filter->getPrivateFilteredStorage());
+      $this->assertEquals($collection, $filter->getPrivateSourceStorage()->getCollectionName());
+    }
+
+    /** @var \Drupal\config_filter\Tests\TransparentFilter[] $filters */
+    $filters = static::getProtectedFilters($this->storage);
+    foreach ($filters as $filter) {
+      // Test that the filters on the original storage are still correctly set.
+      $this->assertEquals($this->storage, $filter->getPrivateFilteredStorage());
+      $this->assertEquals(StorageInterface::DEFAULT_COLLECTION, $filter->getPrivateSourceStorage()->getCollectionName());
+    }
+  }
+
+  /**
+   * Test setting up filters in FilteredStorage::createCollection().
+   */
+  public function testCreateCollectionFilter() {
+    $collection = $this->randomString();
+    $filteredCollection = $this->randomString();
+
+    $filter = $this->prophesizeFilter();
+    $filterC = $this->prophesizeFilter();
+    $filterC->filterGetCollectionName($collection)->willReturn($filteredCollection);
+    $filter->filterCreateCollection($collection)->willReturn($filterC->reveal());
+
+    $source = $this->prophesize(StorageInterface::class);
+    $sourceC = $this->prophesize(StorageInterface::class);
+    $sourceC->getCollectionName()->willReturn($collection);
+    $source->createCollection($collection)->willReturn($sourceC->reveal());
+
+    $storage = new FilteredStorage($source->reveal(), [$filter->reveal()]);
+    // Creating a collection makes sure the filters were correctly set up.
+    $storageC = $storage->createCollection($collection);
+
+    // Test that the collection is filtered in the collection storage.
+    $this->assertEquals($filteredCollection, $storageC->getCollectionName());
+  }
+
+  /**
+   * Test the read methods invokes the correct filter methods.
+   *
+   * @dataProvider readFilterProvider
+   */
+  public function testReadFilter($name, $storageMethod, $filterMethod, $data, $expected) {
+    $source = $this->prophesize(StorageInterface::class);
+    $filterA = $this->prophesizeFilter();
+    $filterB = $this->prophesizeFilter();
+
+    $source->$storageMethod($name)->willReturn($data);
+    $interim = $this->randomArray();
+    $filterA->$filterMethod($name, $data)->willReturn($interim);
+    $filterB->$filterMethod($name, $interim)->willReturn($expected);
+
+    $storage = new FilteredStorage($source->reveal(), [$filterA->reveal(), $filterB->reveal()]);
+    $this->assertEquals($expected, $storage->$storageMethod($name));
+  }
+
+  /**
+   * Data provider for testReadFilter.
+   */
+  public function readFilterProvider() {
+    // @codingStandardsIgnoreStart
+    return [
+      [$this->randomString(), 'exists', 'filterExists', TRUE, TRUE],
+      [$this->randomString(), 'exists', 'filterExists', TRUE, FALSE],
+      [$this->randomString(), 'exists', 'filterExists', FALSE, TRUE],
+      [$this->randomString(), 'exists', 'filterExists', FALSE, FALSE],
+
+      [$this->randomString(), 'read', 'filterRead', $this->randomArray(), $this->randomArray()],
+      [$this->randomString(), 'read', 'filterRead', NULL, $this->randomArray()],
+      [$this->randomString(), 'read', 'filterRead', $this->randomArray(), NULL],
+
+      [
+        [$this->randomString(), $this->randomString()],
+        'readMultiple',
+        'filterReadMultiple',
+        [$this->randomArray(), $this->randomArray()],
+        [$this->randomArray(), $this->randomArray()],
+      ],
+      [
+        [$this->randomString(), $this->randomString()],
+        'readMultiple',
+        'filterReadMultiple',
+        [$this->randomArray(), FALSE],
+        [$this->randomArray(), $this->randomArray()],
+      ],
+
+      [
+        $this->randomString(),
+        'listAll',
+        'filterListAll',
+        ['a' . $this->randomString(), 'b' . $this->randomString()],
+        ['a' . $this->randomString(), 'b' . $this->randomString()],
+      ],
+    ];
+    // @codingStandardsIgnoreEnd
+  }
+
+  /**
+   * Test that when a filter removes config on a readMultiple it is not set.
+   */
+  public function testReadMultipleWithEmptyResults() {
+    $names = [$this->randomString(), $this->randomString()];
+    $source = $this->prophesize(StorageInterface::class);
+    $data = [$this->randomArray(), $this->randomArray()];
+    $source->readMultiple($names)->willReturn($data);
+    $source = $source->reveal();
+
+    foreach ([0, [], NULL] as $none) {
+      $filtered = $data;
+      $filtered[1] = $none;
+      $filter = $this->prophesizeFilter();
+      $filter->filterReadMultiple($names, $data)->willReturn($filtered);
+
+      $storage = new FilteredStorage($source, [$filter->reveal()]);
+      $this->assertEquals([$data[0]], $storage->readMultiple($names));
+    }
+  }
+
+  /**
+   * Test the write method invokes the filterWrite in filters.
+   *
+   * @dataProvider writeFilterProvider
+   */
+  public function testWriteFilter($interim, $expected, $exists = TRUE) {
+    $name = $this->randomString();
+    $data = $this->randomArray();
+    $source = $this->prophesize(StorageInterface::class);
+    $filterA = $this->prophesizeFilter();
+    $filterB = $this->prophesizeFilter();
+
+    $filterA->filterWrite($name, $data)->willReturn($interim);
+    $interim = is_array($interim) ? $interim : [];
+    $filterB->filterWrite($name, $interim)->willReturn($expected);
+
+    if ($expected) {
+      $source->write($name, $expected)->willReturn(TRUE);
+    }
+    else {
+      $source->write(Argument::any())->shouldNotBeCalled();
+      $source->exists($name)->willReturn($exists);
+      if ($exists) {
+        $filterA->filterWriteEmptyIsDelete($name)->willReturn(TRUE);
+        $source->delete($name)->willReturn(TRUE);
+      }
+    }
+
+    $storage = new FilteredStorage($source->reveal(), [$filterA->reveal(), $filterB->reveal()]);
+    $this->assertTrue($storage->write($name, $data));
+  }
+
+  /**
+   * Data provider for testWriteFilter.
+   */
+  public function writeFilterProvider() {
+    return [
+      [$this->randomArray(), $this->randomArray()],
+      [NULL, $this->randomArray()],
+      [[], $this->randomArray()],
+      [$this->randomArray(), NULL, FALSE],
+      [$this->randomArray(), [], FALSE],
+      [$this->randomArray(), NULL, TRUE],
+    ];
+  }
+
+  /**
+   * Test the delete method invokes the filterDelete in filters.
+   *
+   * @dataProvider deleteFilterProvider
+   */
+  public function testDeleteFilter($interim, $expected) {
+    $name = $this->randomString();
+    $source = $this->prophesize(StorageInterface::class);
+    $filterA = $this->prophesizeFilter();
+    $filterB = $this->prophesizeFilter();
+
+    $filterA->filterDelete($name, TRUE)->willReturn($interim);
+    $filterB->filterDelete($name, $interim)->willReturn($expected);
+
+    if ($expected) {
+      $source->delete($name)->willReturn(TRUE);
+    }
+    else {
+      $source->delete(Argument::any())->shouldNotBeCalled();
+    }
+
+    $storage = new FilteredStorage($source->reveal(), [$filterA->reveal(), $filterB->reveal()]);
+    $this->assertEquals($expected, $storage->delete($name));
+  }
+
+  /**
+   * Data provider for testDeleteFilter.
+   */
+  public function deleteFilterProvider() {
+    return [
+      [TRUE, TRUE],
+      [FALSE, TRUE],
+      [TRUE, FALSE],
+      [FALSE, FALSE],
+    ];
+  }
+
+  /**
+   * Test the rename method invokes the filterRename in filters.
+   *
+   * @dataProvider renameFilterProvider
+   */
+  public function testRenameFilter($interim, $expected) {
+    $name = $this->randomString();
+    $name2 = $this->randomString();
+    $source = $this->prophesize(StorageInterface::class);
+    $filterA = $this->prophesizeFilter();
+    $filterB = $this->prophesizeFilter();
+
+    $filterA->filterRename($name, $name2, TRUE)->willReturn($interim);
+    $filterB->filterRename($name, $name2, $interim)->willReturn($expected);
+
+    if ($expected) {
+      $source->rename($name, $name2)->willReturn(TRUE);
+    }
+    else {
+      $source->rename(Argument::any())->shouldNotBeCalled();
+    }
+
+    $storage = new FilteredStorage($source->reveal(), [$filterA->reveal(), $filterB->reveal()]);
+    $this->assertEquals($expected, $storage->rename($name, $name2));
+  }
+
+  /**
+   * Data provider for testRenameFilter.
+   */
+  public function renameFilterProvider() {
+    return [
+      [TRUE, TRUE],
+      [FALSE, TRUE],
+      [TRUE, FALSE],
+      [FALSE, FALSE],
+    ];
+  }
+
+  /**
+   * Test the deleteAll method invokes the filterDeleteAll in filters.
+   *
+   * @dataProvider deleteAllFilterProvider
+   */
+  public function testDeleteAllFilter($interim, $expected) {
+    $name = $this->randomString();
+    $source = $this->prophesize(StorageInterface::class);
+    $filterA = $this->prophesizeFilter();
+    $filterB = $this->prophesizeFilter();
+
+    $filterA->filterDeleteAll($name, TRUE)->willReturn($interim);
+    $filterB->filterDeleteAll($name, $interim)->willReturn($expected);
+
+    if ($expected) {
+      $source->deleteAll($name)->willReturn(TRUE);
+    }
+    else {
+      $source->deleteAll(Argument::any())->shouldNotBeCalled();
+      $all = [$this->randomString(), $this->randomString()];
+      $source->listAll($name)->willReturn($all);
+
+      foreach ($all as $item) {
+        $filterA->filterDelete($item, TRUE)->willReturn(TRUE);
+        $filterB->filterDelete($item, TRUE)->willReturn(FALSE);
+      }
+    }
+
+    $storage = new FilteredStorage($source->reveal(), [$filterA->reveal(), $filterB->reveal()]);
+    $this->assertTrue($storage->deleteAll($name));
+  }
+
+  /**
+   * Data provider for testDeleteAllFilter.
+   */
+  public function deleteAllFilterProvider() {
+    return [
+      [TRUE, TRUE],
+      [FALSE, TRUE],
+      [TRUE, FALSE],
+      [FALSE, FALSE],
+    ];
+  }
+
+  /**
+   * Test that an exception is thrown when invalid arguments are passed.
+   */
+  public function testInvalidStorageFilterArgument() {
+    $source = $this->prophesize(StorageInterface::class);
+
+    // We would do this with $this->expectException but alas drupal is stuck on
+    // phpunit 4 and we try not to add deprecated code.
+    try {
+      new FilteredStorage($source->reveal(), [new \stdClass()]);
+      $this->fail('An exception should have been thrown.');
+    }
+    catch (InvalidStorageFilterException $exception) {
+      $this->assertTrue(TRUE);
+    }
+  }
+
+  /**
+   * Prophesize a StorageFilter.
+   */
+  protected function prophesizeFilter() {
+    $filter = $this->prophesize(StorageFilterInterface::class);
+    $filter->setSourceStorage(Argument::type(ReadOnlyStorage::class))->shouldBeCalledTimes(1);
+    $filter->setFilteredStorage(Argument::type(FilteredStorage::class))->shouldBeCalledTimes(1);
+    return $filter;
+  }
+
+  /**
+   * Get the filters from a FilteredStorageInterface.
+   *
+   * @param \Drupal\Core\Config\StorageInterface $storage
+   *   The storage with the protected filters property.
+   *
+   * @return \Drupal\config_filter\Config\StorageFilterInterface[]
+   *   The array of filters.
+   */
+  protected static function getProtectedFilters(StorageInterface $storage) {
+    $filterReflection = new \ReflectionClass(FilteredStorage::class);
+    $filtersProperty = $filterReflection->getProperty('filters');
+    $filtersProperty->setAccessible(TRUE);
+
+    return $filtersProperty->getValue($storage);
+  }
+
+  /**
+   * Create a random array.
+   */
+  protected function randomArray($size = 4) {
+    return (array) $this->randomObject($size);
+  }
+
+}
diff --git a/web/modules/config_filter/src/Tests/GhostStorageTest.php b/web/modules/config_filter/src/Tests/GhostStorageTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..a384badd5cdff54102994840c164accd3a88c40e
--- /dev/null
+++ b/web/modules/config_filter/src/Tests/GhostStorageTest.php
@@ -0,0 +1,44 @@
+<?php
+
+namespace Drupal\config_filter\Tests;
+
+use Drupal\config_filter\Config\GhostStorage;
+use Drupal\Core\Config\StorageInterface;
+use Prophecy\Argument;
+
+/**
+ * Tests GhostStorage operations.
+ *
+ * @group config_filter
+ */
+class GhostStorageTest extends ReadonlyStorageTest {
+
+  /**
+   * Override the storage decorating.
+   *
+   * @param \Drupal\Core\Config\StorageInterface $source
+   *   The storage to decorate.
+   *
+   * @return \Drupal\config_filter\Config\GhostStorage
+   *   The storage to test.
+   */
+  protected function getStorage(StorageInterface $source) {
+    return new GhostStorage($source);
+  }
+
+  /**
+   * Override the dataprovider for write methods.
+   *
+   * @dataProvider writeMethodsProvider
+   */
+  public function testWriteOperations($method, $arguments) {
+    $source = $this->prophesize(StorageInterface::class);
+    $source->$method(Argument::any())->shouldNotBeCalled();
+
+    $storage = $this->getStorage($source->reveal());
+
+    $actual = call_user_func_array([$storage, $method], $arguments);
+    $this->assertTrue($actual);
+  }
+
+}
diff --git a/web/modules/config_filter/src/Tests/ReadonlyStorageTest.php b/web/modules/config_filter/src/Tests/ReadonlyStorageTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..ee1917133a8ec31beca97529535915429b0a836e
--- /dev/null
+++ b/web/modules/config_filter/src/Tests/ReadonlyStorageTest.php
@@ -0,0 +1,138 @@
+<?php
+
+namespace Drupal\config_filter\Tests;
+
+use Drupal\config_filter\Config\ReadOnlyStorage;
+use Drupal\config_filter\Exception\UnsupportedMethod;
+use Drupal\Core\Config\StorageInterface;
+use Drupal\Tests\UnitTestCase;
+use Prophecy\Argument;
+use Prophecy\Prophecy\MethodProphecy;
+
+/**
+ * Tests ReadonlyStorage operations.
+ *
+ * @group config_filter
+ */
+class ReadonlyStorageTest extends UnitTestCase {
+
+  /**
+   * Wrap a given storage.
+   *
+   * This is useful when testing a subclass of ReadonlyStorage.
+   *
+   * @param \Drupal\Core\Config\StorageInterface $source
+   *   The storage to decorate.
+   *
+   * @return \Drupal\Core\Config\StorageInterface
+   *   The storage wrapping the source.
+   */
+  protected function getStorage(StorageInterface $source) {
+    return new ReadOnlyStorage($source);
+  }
+
+  /**
+   * Test methods that should be transparent.
+   *
+   * @dataProvider readMethodsProvider
+   */
+  public function testReadOperations($method, $arguments, $returnValue) {
+    $source = $this->prophesize(StorageInterface::class);
+    $methodProhecy = new MethodProphecy($source, $method, $arguments);
+    $methodProhecy->shouldBeCalledTimes(1);
+    $methodProhecy->willReturn($returnValue);
+    $source->addMethodProphecy($methodProhecy);
+
+    $storage = $this->getStorage($source->reveal());
+    $actual = call_user_func_array([$storage, $method], $arguments);
+    $this->assertEquals($actual, $returnValue);
+  }
+
+  /**
+   * Provide the methods that should continue to work.
+   *
+   * @return array
+   *   The data.
+   */
+  public function readMethodsProvider() {
+    return [
+      ['exists', [$this->randomMachineName()], $this->randomMachineName()],
+      ['read', [$this->randomMachineName()], $this->randomArray()],
+      ['readMultiple', [$this->randomArray()], $this->randomArray()],
+      ['encode', [$this->randomArray()], $this->randomMachineName()],
+      ['decode', [$this->randomMachineName()], $this->randomArray()],
+      ['listAll', [$this->randomMachineName()], $this->randomArray()],
+      ['getAllCollectionNames', [], $this->randomArray()],
+      ['getCollectionName', [], $this->randomMachineName()],
+    ];
+  }
+
+  /**
+   * Test creating a collection.
+   *
+   * Creating collections returns a new instance, make sure it decorates the
+   * new instance of the source.
+   */
+  public function testCreateCollection() {
+    $name = $this->randomMachineName();
+    $source = $this->prophesize(StorageInterface::class);
+    $collectionSource = $this->prophesize(StorageInterface::class)->reveal();
+    $source->createCollection($name)->willReturn($collectionSource);
+
+    $storage = $this->getStorage($source->reveal());
+    $collectionStorage = $storage->createCollection($name);
+
+    $this->assertInstanceOf(ReadOnlyStorage::class, $collectionStorage);
+
+    $readonlyReflection = new \ReflectionClass(ReadOnlyStorage::class);
+    $storageProperty = $readonlyReflection->getProperty('storage');
+    $storageProperty->setAccessible(TRUE);
+    $actualSource = $storageProperty->getValue($collectionStorage);
+    $this->assertEquals($collectionSource, $actualSource);
+  }
+
+  /**
+   * Test the operations that should throw an error.
+   *
+   * @dataProvider writeMethodsProvider
+   */
+  public function testWriteOperations($method, $arguments) {
+    $source = $this->prophesize(StorageInterface::class);
+    $source->$method(Argument::any())->shouldNotBeCalled();
+
+    $storage = $this->getStorage($source->reveal());
+    try {
+      call_user_func_array([$storage, $method], $arguments);
+      $this->fail();
+    }
+    catch (UnsupportedMethod $exception) {
+      $this->assertEquals(ReadOnlyStorage::class . '::' . $method . ' is not allowed on a ReadOnlyStorage', $exception->getMessage());
+    }
+  }
+
+  /**
+   * Provide the methods that should throw an exception.
+   *
+   * @return array
+   *   The data
+   */
+  public function writeMethodsProvider() {
+    return [
+      ['write', [$this->randomMachineName(), $this->randomArray()]],
+      ['delete', [$this->randomMachineName()]],
+      ['rename', [$this->randomMachineName(), $this->randomMachineName()]],
+      ['deleteAll', [$this->randomMachineName()]],
+    ];
+  }
+
+  /**
+   * Get a random array.
+   *
+   * @return array
+   *   A random array used for data testing.
+   */
+  protected function randomArray() {
+    return (array) $this->getRandomGenerator()->object();
+  }
+
+}
diff --git a/web/modules/config_filter/src/Tests/TransparentFilter.php b/web/modules/config_filter/src/Tests/TransparentFilter.php
new file mode 100644
index 0000000000000000000000000000000000000000..d96d6bb5cde26f41c8297caea53836da4d8a50aa
--- /dev/null
+++ b/web/modules/config_filter/src/Tests/TransparentFilter.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace Drupal\config_filter\Tests;
+
+use Drupal\config_filter\Config\StorageFilterInterface;
+use Drupal\config_filter\Plugin\ConfigFilterBase;
+
+/**
+ * Class TransparentFilter.
+ */
+class TransparentFilter extends ConfigFilterBase implements StorageFilterInterface {
+
+  /**
+   * TransparentFilter constructor.
+   */
+  public function __construct() {
+    parent::__construct([], 'transparent_test', []);
+  }
+
+  /**
+   * Get the read-only source Storage.
+   *
+   * @return \Drupal\Core\Config\StorageInterface
+   *   The source storage.
+   */
+  public function getPrivateSourceStorage() {
+    return $this->getSourceStorage();
+  }
+
+  /**
+   * Get the decorator storage which applies the filters.
+   *
+   * @return \Drupal\Core\Config\StorageInterface
+   *   The filtered decorator storage.
+   */
+  public function getPrivateFilteredStorage() {
+    return $this->getFilteredStorage();
+  }
+
+}
diff --git a/web/modules/config_filter/tests/composer.json b/web/modules/config_filter/tests/composer.json
new file mode 100644
index 0000000000000000000000000000000000000000..fe60edb1787ec9ae079b4a9de7c7a39e9e7b9987
--- /dev/null
+++ b/web/modules/config_filter/tests/composer.json
@@ -0,0 +1,24 @@
+{
+  "name": "nuvoleweb/config-filter-test-site",
+  "description": "Config Filter test site.",
+  "type": "project",
+  "require": {
+    "composer/installers": "^1.2",
+    "drupal-composer/drupal-scaffold": "^2.2",
+    "drupal/core": "~8",
+    "drush/drush": "~8.0",
+    "drupal/coder": "^8.2",
+    "squizlabs/php_codesniffer": "^2.8",
+    "phpunit/phpunit": "5.5.*",
+    "bovigo/assert": "~1.7",
+    "mikey179/vfsStream": "*"
+  },
+  "minimum-stability": "dev",
+  "prefer-stable": true,
+  "repositories": [
+    {"type": "composer", "url": "https://packages.drupal.org/8"}
+  ],
+  "conflict": {
+    "drupal/drupal": "*"
+  }
+}
diff --git a/web/modules/config_filter/tests/modules/config_filter_split_test/README.md b/web/modules/config_filter/tests/modules/config_filter_split_test/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..37b67f46387abe27a046d55ab1270576027aef59
--- /dev/null
+++ b/web/modules/config_filter/tests/modules/config_filter_split_test/README.md
@@ -0,0 +1,40 @@
+# Config Filter Split test
+This is a module for testing the proper functioning of config_filter.
+But it also demonstrates how a filter can be used to read and write to a
+different config storage. As such it is an instructive example.
+But it also has a practical purpose: We can use it to read migrate config
+directly from files. Of course it is in general a bad idea to directly
+edit the active configuration since Drupal does many checks and database
+alterations when synchronizing configuration.
+
+This is just here for the brave. You have been warned.
+
+## Developing with migrate configuration read from the files.
+
+Migrations are configurations, by default active configuration is stored in the
+database. So when developing, the configuration has to be synced all the time.
+To avoid this we can split out the migrate configuration to read directly
+from the files.
+
+Enable the config_filter_split_test testing module from config_filter.
+
+To swap out the active storage, add the following to your services.local.yml:
+```yaml
+services:
+  config.storage:
+    class: Drupal\config_filter_split_test\Config\ActiveMigrateStorage
+    arguments:
+      - '@config.storage.active'
+      - '@cache.config'
+      - '../config/migrate_active' # The path to the folder.
+```
+
+Migrations are plugins, and plugin definitions are cached. The configuration
+storage is also cached.
+So either you have to clear the caches after you edit the migration or you add
+the following to your settings.php (assuming you have the null cache set too):
+```php
+$settings['cache']['bins']['config'] = 'cache.backend.null';
+$settings['cache']['bins']['discovery'] = 'cache.backend.null';
+```
+This has an obvious performance implication.
diff --git a/web/modules/config_filter/tests/modules/config_filter_split_test/config_filter_split_test.info.yml b/web/modules/config_filter/tests/modules/config_filter_split_test/config_filter_split_test.info.yml
new file mode 100644
index 0000000000000000000000000000000000000000..bcb380f924d35a181e806b88b09a562c4c65f14b
--- /dev/null
+++ b/web/modules/config_filter/tests/modules/config_filter_split_test/config_filter_split_test.info.yml
@@ -0,0 +1,12 @@
+name: 'Simple split filter'
+type: module
+# core: 8.x
+package: Testing
+dependencies:
+  - config_filter:config_filter
+
+# Information added by Drupal.org packaging script on 2018-09-26
+version: '8.x-1.3'
+core: '8.x'
+project: 'config_filter'
+datestamp: 1537978084
diff --git a/web/modules/config_filter/tests/modules/config_filter_split_test/src/Config/ActiveMigrateStorage.php b/web/modules/config_filter/tests/modules/config_filter_split_test/src/Config/ActiveMigrateStorage.php
new file mode 100644
index 0000000000000000000000000000000000000000..0680234977d8392a9c2b9fa08375f5a8c8668674
--- /dev/null
+++ b/web/modules/config_filter/tests/modules/config_filter_split_test/src/Config/ActiveMigrateStorage.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace Drupal\config_filter_migrate_test\Config;
+
+use Drupal\config_filter\Config\FilteredStorage;
+use Drupal\config_filter_split_test\Plugin\ConfigFilter\TestSplitFilter;
+use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Config\CachedStorage;
+use Drupal\Core\Config\FileStorage;
+use Drupal\Core\Config\StorageInterface;
+
+/**
+ * Class ActiveMigrateStorage.
+ */
+class ActiveMigrateStorage extends CachedStorage {
+
+  /**
+   * Create an ActiveMigrateStorage.
+   *
+   * @param \Drupal\Core\Config\StorageInterface $storage
+   *   The decorated storage.
+   * @param \Drupal\Core\Cache\CacheBackendInterface $cache
+   *   A cache backend used to store configuration.
+   * @param string $migrate_folder
+   *   The migrate directory.
+   */
+  public function __construct(StorageInterface $storage, CacheBackendInterface $cache, $migrate_folder) {
+    // Create the filter directly, the plugin manager is not yet available.
+    $filter = new TestSplitFilter(new FileStorage($migrate_folder), 'migrate_plus.migration');
+    // Wrap the storage with the the filtered storage.
+    parent::__construct(new FilteredStorage($storage, [$filter]), $cache);
+  }
+
+}
diff --git a/web/modules/config_filter/tests/modules/config_filter_split_test/src/Plugin/ConfigFilter/TestSplitFilter.php b/web/modules/config_filter/tests/modules/config_filter_split_test/src/Plugin/ConfigFilter/TestSplitFilter.php
new file mode 100644
index 0000000000000000000000000000000000000000..39d112f6a96a6977b166990f1f3532ea7ac2b246
--- /dev/null
+++ b/web/modules/config_filter/tests/modules/config_filter_split_test/src/Plugin/ConfigFilter/TestSplitFilter.php
@@ -0,0 +1,167 @@
+<?php
+
+namespace Drupal\config_filter_split_test\Plugin\ConfigFilter;
+
+use Drupal\config_filter\Plugin\ConfigFilterBase;
+use Drupal\Core\Config\DatabaseStorage;
+use Drupal\Core\Config\StorageInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Provides a TestSplitFilter.
+ *
+ * This is a very basic split filter to test that config_filter applies the
+ * filters correctly. For more advanced and configurable split filters use the
+ * Configuration Split (config_split) module.
+ *
+ * @ConfigFilter(
+ *   id = "config_filter_split_test",
+ *   label = @Translation("Filter Split test"),
+ *   storages = {"test_storage"},
+ * )
+ */
+class TestSplitFilter extends ConfigFilterBase implements ContainerFactoryPluginInterface {
+
+  /**
+   * The File storage to read the migrations from.
+   *
+   * @var \Drupal\Core\Config\StorageInterface
+   */
+  protected $storage;
+
+  /**
+   * The name prefix to split.
+   *
+   * @var string
+   */
+  protected $name;
+
+  /**
+   * Constructs a new TestSplitFilter.
+   *
+   * @param \Drupal\Core\Config\StorageInterface $storage
+   *   The migrate storage.
+   * @param string $name
+   *   The config name prefix to split.
+   */
+  public function __construct(StorageInterface $storage, $name) {
+    parent::__construct([], 'config_filter_split_test', []);
+    $this->storage = $storage;
+    $this->name = $name;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(new DatabaseStorage($container->get('database'), 'config_filter_split_test'), 'core.');
+  }
+
+  /**
+   * Decide to split the config off or not.
+   *
+   * @param string $name
+   *   The name of the configuration to check.
+   *
+   * @return bool
+   *   Whether the configuration is supposed to be split.
+   */
+  protected function isSplitConfig($name) {
+    return (strpos($name, $this->name) === 0);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function filterRead($name, $data) {
+    if ($this->isSplitConfig($name)) {
+      if ($this->storage->exists($name)) {
+        $data = $this->storage->read($name);
+      }
+    }
+
+    return $data;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function filterExists($name, $exists) {
+    if ($this->isSplitConfig($name) && !$exists) {
+      $exists = $this->storage->exists($name);
+    }
+
+    return $exists;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function filterReadMultiple(array $names, array $data) {
+    return array_merge($data, $this->storage->readMultiple($names));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function filterListAll($prefix, array $data) {
+    return array_unique(array_merge($data, $this->storage->listAll($prefix)));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function filterWrite($name, array $data) {
+    if ($this->isSplitConfig($name)) {
+      $this->storage->write($name, $data);
+      return NULL;
+    }
+
+    return $data;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function filterWriteEmptyIsDelete($name) {
+    return ($this->isSplitConfig($name) ? TRUE : NULL);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function filterDelete($name, $delete) {
+    if ($delete && $this->storage->exists($name)) {
+      // Call delete on the secondary storage anyway.
+      $this->storage->delete($name);
+    }
+
+    return $delete;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function filterDeleteAll($prefix, $delete) {
+    if ($delete && $this->storage) {
+      try {
+        $this->storage->deleteAll($prefix);
+      }
+      catch (\UnexpectedValueException $exception) {
+        // The file storage tries to remove directories of collections. But this
+        // fails if the directory doesn't exist. So everything is actually fine.
+      }
+    }
+
+    return $delete;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function filterCreateCollection($collection) {
+    return new static($this->storage->createCollection($collection), $this->name);
+  }
+
+}
diff --git a/web/modules/config_filter/tests/modules/config_filter_test/config_filter_test.info.yml b/web/modules/config_filter/tests/modules/config_filter_test/config_filter_test.info.yml
new file mode 100644
index 0000000000000000000000000000000000000000..2da8f4fd401bfc62a2e308ce2cd7e4a0e2d00a7a
--- /dev/null
+++ b/web/modules/config_filter/tests/modules/config_filter_test/config_filter_test.info.yml
@@ -0,0 +1,12 @@
+name: Config Filter Test
+type: module
+# core: 8.x
+package: Testing
+dependencies:
+  - config_filter:config_filter
+
+# Information added by Drupal.org packaging script on 2018-09-26
+version: '8.x-1.3'
+core: '8.x'
+project: 'config_filter'
+datestamp: 1537978084
diff --git a/web/modules/config_filter/tests/modules/config_filter_test/src/Plugin/ConfigFilter/PirateFilter.php b/web/modules/config_filter/tests/modules/config_filter_test/src/Plugin/ConfigFilter/PirateFilter.php
new file mode 100644
index 0000000000000000000000000000000000000000..96b022c9e2f352d744fd4c1814d8d551070c4c17
--- /dev/null
+++ b/web/modules/config_filter/tests/modules/config_filter_test/src/Plugin/ConfigFilter/PirateFilter.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace Drupal\config_filter_test\plugin\ConfigFilter;
+
+use Drupal\config_filter\Plugin\ConfigFilterBase;
+
+/**
+ * Provides a pirate filter that adds "Arrr" to the site name.
+ *
+ * @ConfigFilter(
+ *   id = "pirate_filter",
+ *   label = "More pirates! Arrr",
+ *   weight = 10
+ * )
+ */
+class PirateFilter extends ConfigFilterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function filterRead($name, $data) {
+    if ($name == 'system.site') {
+      $data['name'] = $data['name'] . ' Arrr';
+    }
+
+    return $data;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function filterReadMultiple(array $names, array $data) {
+    if (in_array('system.site', $names)) {
+      $data['system.site'] = $this->filterRead('system.site', $data['system.site']);
+    }
+
+    return $data;
+  }
+
+}
diff --git a/web/modules/config_filter/tests/phpunit.xml.dist b/web/modules/config_filter/tests/phpunit.xml.dist
new file mode 100644
index 0000000000000000000000000000000000000000..abb466ba1c8910770eba96d78b0d2d79f52015d4
--- /dev/null
+++ b/web/modules/config_filter/tests/phpunit.xml.dist
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit bootstrap="core/tests/bootstrap.php" backupGlobals="false" colors="true" >
+  <php>
+    <ini name="error_reporting" value="32767"/>
+    <ini name="memory_limit" value="-1"/>
+    <env name="SIMPLETEST_DB" value="mysql://travis:@127.0.0.1/drupal"/>
+  </php>
+  <testsuites>
+    <testsuite name="tests">
+      <directory>./modules/config_filter/</directory>
+    </testsuite>
+  </testsuites>
+</phpunit>
diff --git a/web/modules/config_filter/tests/src/Kernel/ConfigFilterStorageFactoryTest.php b/web/modules/config_filter/tests/src/Kernel/ConfigFilterStorageFactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..5b801dab204da0c0ded19b1b602bad4d51a72026
--- /dev/null
+++ b/web/modules/config_filter/tests/src/Kernel/ConfigFilterStorageFactoryTest.php
@@ -0,0 +1,88 @@
+<?php
+
+namespace Drupal\Tests\config_filter\Kernel;
+
+use Drupal\Core\Config\DatabaseStorage;
+use Drupal\KernelTests\KernelTestBase;
+
+/**
+ * Class ConfigFilterStorageFactoryTest.
+ *
+ * @group config_filter
+ */
+class ConfigFilterStorageFactoryTest extends KernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = [
+    'system',
+    'config_filter',
+    'config_filter_test',
+    'config_filter_split_test',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->installConfig(['system']);
+  }
+
+  /**
+   * Test that the config.storage.sync is decorated with the filtering version.
+   */
+  public function testServiceProvider() {
+    // Export the configuration.
+    $this->copyConfig($this->container->get('config.storage'), $this->container->get('config.storage.sync'));
+
+    // The pirate filter changes the system.site when importing.
+    $this->assertEquals(['system.site'], $this->configImporter()->getStorageComparer()->getChangelist('update'));
+    $this->assertEmpty($this->configImporter()->getStorageComparer()->getChangelist('create'));
+    $this->assertEmpty($this->configImporter()->getStorageComparer()->getChangelist('delete'));
+    $this->assertEmpty($this->configImporter()->getStorageComparer()->getChangelist('rename'));
+
+    $config = $this->config('system.site')->getRawData();
+    $config['name'] .= ' Arrr';
+
+    $this->assertEquals($config, $this->container->get('config.storage.sync')->read('system.site'));
+  }
+
+  /**
+   * Test the storage factory decorating properly.
+   */
+  public function testStorageFactory() {
+    /** @var \Drupal\Core\Database\Connection $database */
+    $database = $this->container->get('database');
+    $destination = new DatabaseStorage($database, 'config_filter_source_test');
+
+    // The $filtered storage will have the simple split applied to the
+    // destination storage, but is the unified storage.
+    $filtered = $this->container->get('config_filter.storage_factory')->getFilteredStorage($destination, ['test_storage']);
+
+    /** @var \Drupal\Core\Config\StorageInterface $active */
+    $active = $this->container->get('config.storage');
+
+    // Export the configuration to the filtered storage.
+    $this->copyConfig($active, $filtered);
+
+    // Get the storage of the test split plugin.
+    $splitStorage = new DatabaseStorage($database, 'config_filter_split_test');
+
+    // Assert that the storage is properly split.
+    $this->assertTrue(count($destination->listAll()) > 0);
+    $this->assertTrue(count($splitStorage->listAll()) > 0);
+    $this->assertEquals(count($active->listAll()), count($destination->listAll()) + count($splitStorage->listAll()));
+    $this->assertEquals($active->listAll('core'), $splitStorage->listAll());
+    $this->assertEquals($active->listAll('system'), $destination->listAll('system'));
+
+    $this->assertEquals($active->readMultiple($active->listAll('core')), $splitStorage->readMultiple($splitStorage->listAll()));
+    $this->assertEquals($active->readMultiple($active->listAll('system')), $destination->readMultiple($destination->listAll('system')));
+
+    // Reading from the $filtered storage returns the merged config.
+    $this->assertEquals($active->listAll(), $filtered->listAll());
+    $this->assertEquals($active->readMultiple($active->listAll()), $filtered->readMultiple($filtered->listAll()));
+  }
+
+}
diff --git a/web/modules/config_sync/composer.json b/web/modules/config_sync/composer.json
deleted file mode 100644
index b3a37f7ed5bddf8fd163171e5329953fac33750d..0000000000000000000000000000000000000000
--- a/web/modules/config_sync/composer.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
-    "name": "drupal/config_sync",
-    "description": "Synchronize your site with updated configuration provided by modules and themes.",
-    "type": "drupal-module",
-    "homepage": "https://www.drupal.org/project/config_sync",
-    "license": "GPL-2.0+",
-    "authors": [
-        {
-            "name": "Nedjo Rogers (nedjo)",
-            "email": "nedjo@4481.no-reply.drupal.org",
-            "homepage": "https://www.drupal.org/u/nedjo",
-            "role": "Maintainer"
-        }
-    ],
-    "support": {
-        "issues": "https://drupal.org/project/issues/config_sync",
-        "irc": "irc://irc.freenode.org/drupal-contribute",
-        "source": "https://cgit.drupalcode.org/config_sync"
-    },
-    "require": {
-        "symfony/yaml": "~2.7.14|~2.8.7|~3.0.7|^3.1.1"
-    }
-}
diff --git a/web/modules/config_sync/config_sync.info.yml b/web/modules/config_sync/config_sync.info.yml
deleted file mode 100644
index e985e36748a9742f4f8221b4e1d5cd0f32fa8199..0000000000000000000000000000000000000000
--- a/web/modules/config_sync/config_sync.info.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-name: 'Configuration Synchronizer'
-type: module
-description: 'Synchronize your site with updated configuration provided by modules and themes.'
-# core: 8.x
-package: Config
-configure: config_distro.import
-dependencies:
-  - config_distro:config_distro
-  - config_filter:config_filter
-  - config_merge:config_merge
-  - 'config_provider:config_provider (>=8.x-2.x)'
-  - config_update:config_update
-  - 'drupal:system (>=8.3)'
-
-# Information added by Drupal.org packaging script on 2018-06-05
-version: '8.x-2.0-alpha6'
-core: '8.x'
-project: 'config_sync'
-datestamp: 1528236791
diff --git a/web/modules/config_sync/config_sync.install b/web/modules/config_sync/config_sync.install
deleted file mode 100644
index 65c648b159a15c9b6f3297d4cf1023446d0a252a..0000000000000000000000000000000000000000
--- a/web/modules/config_sync/config_sync.install
+++ /dev/null
@@ -1,16 +0,0 @@
-<?php
-
-/**
- * @file
- * Install, update and uninstall functions for the config_sync module.
- */
-
-/**
- * Implements hook_install().
- *
- * Takes a snapshot of configuration from extensions already installed on the
- * site.
- */
-function config_sync_install() {
-  \Drupal::service('config_sync.snapshotter')->createSnapshot();
-}
diff --git a/web/modules/config_sync/config_sync.module b/web/modules/config_sync/config_sync.module
deleted file mode 100644
index dc1f9c3e56c8084a4dd146b9253aec0e7e86caf2..0000000000000000000000000000000000000000
--- a/web/modules/config_sync/config_sync.module
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-
-/**
- * @file
- * Manage synchronizing configuration from extensions.
- */
-
-use Drupal\config_sync\ConfigSyncSnapshotterInterface;
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Routing\RouteMatchInterface;
-
-/**
- * Implements hook_help().
- */
-function config_sync_help($route_name, RouteMatchInterface $route_match) {
-  switch ($route_name) {
-    case 'help.page.config_sync':
-      $output = '';
-      $output .= '<h3>' . t('About') . '</h3>';
-      $output .= '<p>' . t('The Configuration Synchronizer module provides a way to import configuration changes from updated modules and themes.') . '</p>';
-      $output .= '<p>' . t('When you update to a new version of a module or theme, it may come with configuration changes. For example, if you previously installed an <em>Event</em> module that provided an <em>Event</em> content type and related fields, some of those fields may have changed in the new version, while new fields may have been added. With Configuration Synchronizer you can import those changes.') . '</p>';
-      $output .= '<h3>' . t('Usage') . '</h3>';
-      $output .= '<p>' . t('You can import available updates from your installed modules and themes on the <a href=":url">Distribution Updates</a> page.', array(':url' => \Drupal::url('config_distro.import'))) . ' </p>';
-      return $output;
-    case 'config_distro.import':
-      $output = '';
-      $output .= '<p>' . t('Any available configuration updates from installed modules or themes are displayed here.') . '</p>';
-      $output .= '<p>' . t('If you\'re an advanced user, you may wish to use the checkboxes to select which modules and themes to run updates from. Running some updates while skipping others can lead to unexpected results and so should be done with caution.') . '</p>';
-      $output .= '<p>' . t('Changes will be merged into the site\'s active configuration so as to retain any customizations you\'ve made. For example, if you\'ve edited the label of a field for which updates are available, that edit will be retained.') . '</p>';
-      return $output;
-  }
-}
-
-/**
- * Implements hook_modules_installed().
- */
-function config_sync_modules_installed($module_names) {
-  \Drupal::service('config_sync.snapshotter')->refreshExtensionSnapshot('module', $module_names, ConfigSyncSnapshotterInterface::SNAPSHOT_MODE_INSTALL);
-}
-
-/**
- * Implements hook_themes_installed().
- */
-function config_sync_themes_installed($theme_names) {
-  \Drupal::service('config_sync.snapshotter')->refreshExtensionSnapshot('theme', $theme_names, ConfigSyncSnapshotterInterface::SNAPSHOT_MODE_INSTALL);
-}
diff --git a/web/modules/config_sync/config_sync.services.yml b/web/modules/config_sync/config_sync.services.yml
deleted file mode 100644
index 9005c109cd969efabc8ff6676e9fc520f8360ee4..0000000000000000000000000000000000000000
--- a/web/modules/config_sync/config_sync.services.yml
+++ /dev/null
@@ -1,45 +0,0 @@
-services:
-  config_sync.snapshot_storage:
-    class: Drupal\Core\Config\DatabaseStorage
-    arguments:
-     - '@database'
-     - 'config_sync_snapshot_extension'
-    tags:
-      - { name: backend_overridable }
-  config_sync.snapshotter:
-    class: Drupal\config_sync\ConfigSyncSnapshotter
-    arguments:
-     - '@app.root'
-     - '@config_sync.collector'
-     - '@config_provider.storage'
-     - '@config_sync.snapshot_storage'
-     - '@config.manager'
-  config_sync.collector:
-    class: Drupal\config_sync\Plugin\SyncConfigCollector
-    arguments:
-      - '@config.factory'
-      - '@config.storage'
-      - '@config.manager'
-      - '@config_provider.storage'
-      - '@plugin.manager.config_provider.processor'
-  config_sync.lister:
-    class: Drupal\config_sync\ConfigSyncLister
-    arguments:
-     - '@config_sync.collector'
-     - '@config_update.config_list'
-     - '@config.storage'
-     - '@config_provider.storage'
-     - '@config_sync.snapshot_storage'
-     - '@config.manager'
-  config_sync_snapshot_subscriber:
-    class: Drupal\config_sync\EventSubscriber\ConfigSyncSnapshotSubscriber
-    tags:
-      - { name: event_subscriber }
-    arguments:
-      - '@config_sync.snapshotter'
-      - '@plugin.manager.config_filter'
-      - '@state'
-  config_sync.route_subscriber:
-    class: Drupal\config_sync\Routing\RouteSubscriber
-    tags:
-      - { name: event_subscriber }
\ No newline at end of file
diff --git a/web/modules/config_sync/drush.services.yml b/web/modules/config_sync/drush.services.yml
deleted file mode 100644
index 171a3fc5d65be3d5d7f1f56c686ca7f0652a03d3..0000000000000000000000000000000000000000
--- a/web/modules/config_sync/drush.services.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-services:
-  config_sync.commands:
-    class: \Drupal\config_sync\Commands\ConfigSyncCommands
-    arguments:
-      - '@config_sync.lister'
-      - '@config.storage'
-      - '@config.manager'
-      - '@config.import.commands'
-    tags:
-      - { name: drush.command }
diff --git a/web/modules/config_sync/src/Commands/ConfigSyncCommands.php b/web/modules/config_sync/src/Commands/ConfigSyncCommands.php
deleted file mode 100644
index 428da7e89c9efe81a156189f09defd0db63138e5..0000000000000000000000000000000000000000
--- a/web/modules/config_sync/src/Commands/ConfigSyncCommands.php
+++ /dev/null
@@ -1,109 +0,0 @@
-<?php
-
-namespace Drupal\config_sync\Commands;
-
-use Consolidation\OutputFormatters\StructuredData\RowsOfFields;
-use Drupal\config_sync\ConfigSyncListerInterface;
-use Drupal\Core\Config\ConfigManagerInterface;
-use Drupal\Core\Config\StorageComparer;
-use Drupal\Core\Config\StorageInterface;
-use Drush\Commands\DrushCommands;
-use Drush\Drupal\Commands\config\ConfigCommands;
-use Drush\Drupal\Commands\config\ConfigImportCommands;
-use Drush\Exceptions\UserAbortException;
-
-/**
- * Drush integration for the Configuration Synchronizer module.
- */
-class ConfigSyncCommands extends DrushCommands {
-
-  /**
-   * The config synchronisation lister service.
-   *
-   * @var \Drupal\config_sync\ConfigSyncListerInterface
-   */
-  protected $configSyncLister;
-
-  /**
-   * The active configuration storage.
-   *
-   * @var \Drupal\Core\Config\StorageInterface
-   */
-  protected $activeStorage;
-
-  /**
-   * The configuration manager.
-   *
-   * @var \Drupal\Core\Config\ConfigManagerInterface
-   */
-  protected $configManager;
-
-  /**
-   * The service containing Drush commands for regular core config imports.
-   *
-   * @var \Drush\Drupal\Commands\config\ConfigImportCommands
-   */
-  protected $configImportCommands;
-
-  /**
-   * Constructs a new ConfigSyncCommands object.
-   *
-   * @param \Drupal\config_sync\ConfigSyncListerInterface $configSyncLister
-   *   The config synchronisation lister service.
-   * @param \Drupal\Core\Config\StorageInterface $activeStorage
-   *   The active configuration storage.
-   * @param \Drupal\Core\Config\ConfigManagerInterface $configManager
-   *   The configuration manager.
-   * @param \Drush\Drupal\Commands\config\ConfigImportCommands $configImportCommands
-   *   The service containing Drush commands for regular core config imports.
-   */
-  public function __construct(ConfigSyncListerInterface $configSyncLister, StorageInterface $activeStorage, ConfigManagerInterface $configManager, ConfigImportCommands $configImportCommands) {
-    parent::__construct();
-    $this->configSyncLister = $configSyncLister;
-    $this->activeStorage = $activeStorage;
-    $this->configManager = $configManager;
-    $this->configImportCommands = $configImportCommands;
-  }
-
-  /**
-   * Displays a list of all extensions with available configuration updates.
-   *
-   * @command config-sync-list-updates
-   * @usage drush config-sync-list-updates
-   *   Display a list of all extensions with available configuration updates.
-   * @aliases cs-list
-   * @field-labels
-   *   type: Operation type
-   *   id: Config ID
-   *   collection: Collection
-   *   label: Label
-   *   extension_type: Extension type
-   *   extension: Extension
-   * @default-fields extension,type,label
-   * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields
-   */
-  public function syncListUpdates($options = ['format' => 'table']) {
-    $rows = [];
-    foreach ($this->configSyncLister->getExtensionChangelists() as $extension_type => $extensions) {
-      foreach ($extensions as $extension_id => $collection_changelists) {
-        foreach ($collection_changelists as $collection => $operation_types) {
-          foreach ($operation_types as $operation_type => $configurations) {
-            foreach ($configurations as $config_id => $config_label) {
-              $rows[$config_id] = [
-                'type' => $operation_type,
-                'id' => $config_id,
-                'collection' => $collection === '' ? 'default' : $collection,
-                'label' => $config_label,
-                'extension_type' => $extension_type,
-                'extension' => $extension_id,
-              ];
-            }
-          }
-        }
-      }
-    }
-
-    return new RowsOfFields($rows);
-  }
-
-}
diff --git a/web/modules/config_sync/src/ConfigSyncLister.php b/web/modules/config_sync/src/ConfigSyncLister.php
deleted file mode 100644
index 27a9ea6a93825a24c77726cde8ae5b6df7535d73..0000000000000000000000000000000000000000
--- a/web/modules/config_sync/src/ConfigSyncLister.php
+++ /dev/null
@@ -1,221 +0,0 @@
-<?php
-
-namespace Drupal\config_sync;
-
-use Drupal\config_sync\Plugin\SyncConfigCollectorInterface;
-use Drupal\config_update\ConfigListInterface as ConfigUpdateListerInterface;
-use Drupal\Component\Utility\NestedArray;
-use Drupal\Core\Config\ConfigManagerInterface;
-use Drupal\Core\Config\StorageComparer;
-use Drupal\Core\Config\StorageInterface;
-use Drupal\Core\Entity\EntityTypeInterface;
-use Drupal\Core\Extension\Extension;
-use Drupal\Core\StringTranslation\StringTranslationTrait;
-
-/**
- * Provides methods related to listing configuration changes.
- */
-class ConfigSyncLister implements ConfigSyncListerInterface {
-
-  use StringTranslationTrait;
-
-  /**
-   * The configuration collector.
-   *
-   * @var \Drupal\config_sync\Plugin\SyncConfigCollectorInterface
-   */
-  protected $configCollector;
-
-  /**
-   * The configuration update lister.
-   *
-   * @var \Drupal\config_update\ConfigListInterface
-   */
-  protected $configUpdateLister;
-
-  /**
-   * The active configuration storage.
-   *
-   * @var \Drupal\Core\Config\StorageInterface
-   */
-  protected $activeStorage;
-
-  /**
-   * The provider configuration storage.
-   *
-   * @var \Drupal\Core\Config\StorageInterface
-   */
-  protected $providerStorage;
-
-  /**
-   * The snapshot config storage for values from the extension storage.
-   *
-   * @var \Drupal\Core\Config\StorageInterface
-   */
-  protected $snapshotStorage;
-
-  /**
-   * The configuration manager.
-   *
-   * @var \Drupal\Core\Config\ConfigManagerInterface
-   */
-  protected $configManager;
-
-  /**
-   * List of current config entity type labels, keyed by entity type.
-   *
-   * This is not set up until ConfigLister::listTypes() has been called.
-   *
-   * @var array
-   */
-  protected $configTypes = [];
-
-  /**
-   * Constructs a ConfigSyncLister object.
-   *
-   * @param \Drupal\config_sync\Plugin\SyncConfigCollectorInterface $config_collector
-   *   The config collector.
-   * @param \Drupal\config_update\ConfigListInterface $config_update_lister
-   *   The configuration update lister.
-   * @param \Drupal\Core\Config\StorageInterface $active_storage
-   *   The active storage.
-   * @param \Drupal\Core\Config\StorageInterface $provider_storage
-   *   The provider configuration storage.
-   * @param \Drupal\Core\Config\StorageInterface $snapshot_storage
-   *   The snapshot storage for the items from the extension storage.
-   * @param \Drupal\Core\Config\ConfigManagerInterface $config_manager
-   *   The configuration manager.
-   */
-  public function __construct(SyncConfigCollectorInterface $config_collector, ConfigUpdateListerInterface $config_update_lister, StorageInterface $active_storage, StorageInterface $provider_storage, StorageInterface $snapshot_storage, ConfigManagerInterface $config_manager) {
-    $this->configCollector = $config_collector;
-    $this->configUpdateLister = $config_update_lister;
-    $this->activeStorage = $active_storage;
-    $this->providerStorage = $provider_storage;
-    $this->snapshotStorage = $snapshot_storage;
-    $this->configManager = $config_manager;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getExtensionChangelists(array $extension_names = []) {
-    $changelist = [];
-    // If no extensions were specified, use all installed extensions.
-    if (empty($extension_names)) {
-      $installed_extensions = $this->activeStorage->read('core.extension');
-      foreach (array('module', 'theme') as $type) {
-        if (!empty($installed_extensions[$type])) {
-          $extension_names[$type] = array_keys($installed_extensions[$type]);
-        }
-      }
-    }
-    foreach ($extension_names as $type => $names) {
-      foreach ($names as $name) {
-        if ($extension_changelist = $this->getExtensionChangelist($type, $name)) {
-          $changelist[$type][$name] = $extension_changelist;
-        }
-      }
-    }
-
-    return $changelist;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getExtensionChangelist($type, $name) {
-    $pathname = $this->drupalGetFilename($type, $name);
-    $extension = new Extension(\Drupal::root(), $type, $pathname);
-    $extensions = [
-      $name => $extension,
-    ];
-
-    $this->configCollector->addInstallableConfig($extensions);
-    // Set up a storage comparer.
-    $storage_comparer = new StorageComparer(
-      $this->providerStorage,
-      $this->snapshotStorage,
-      $this->configManager
-    );
-
-    $return = [];
-
-    if ($storage_comparer->createChangelist()->hasChanges()) {
-      foreach ($storage_comparer->getAllCollectionNames() as $collection) {
-        $changelist = $storage_comparer->getChangelist(NULL, $collection);
-        // We're only concerned with create and update lists.
-        unset($changelist['delete']);
-        unset($changelist['rename']);
-        $changelist = array_filter($changelist);
-
-        // Convert the changelist into a format that includes the item label.
-        foreach ($changelist as $change_type => $item_names) {
-          foreach ($item_names as $item_name) {
-            $adjusted_change_type = $change_type;
-            // Check to ensure this item exists in the active configuration. If
-            // not, convert this to a 'create' change. This may occur, for
-            // example, where optional configuration that previously did not
-            // meet the criteria for installation now does.
-            if ($change_type === 'update' && !$this->activeStorage->read($item_name)) {
-              $adjusted_change_type = 'create';
-            }
-            // Figure out what type of config it is, and get the ID.
-            $config_type = $this->configUpdateLister->getTypeNameByConfigName($item_name);
-
-            if (!$config_type) {
-              // This is simple config.
-              $label = $item_name;
-            }
-            else {
-              $config = $this->providerStorage->read($item_name);
-              $definition = $this->configUpdateLister->getType($config_type);
-              $key = $definition->getKey('label') ?: $definition->getKey('id');
-              $label = $config[$key];
-            }
-            $return[$collection][$adjusted_change_type][$item_name] = $label;
-          }
-        }
-      }
-    }
-
-    return $return;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function listConfigTypes() {
-    if (empty($this->configTypes)) {
-      $definitions = $this->configUpdateLister->listTypes();
-      $config_types = array_map(function (EntityTypeInterface $definition) {
-        return $definition->getLabel();
-      }, $definitions);
-      $config_types['system_simple'] = $this->t('Simple configuration');
-      // Sort the entity types by label.
-      uasort($config_types, 'strnatcasecmp');
-      $this->configTypes = $config_types;
-    }
-    return $this->configTypes;
-  }
-
-  /**
-   * Wraps the function drupal_get_filename().
-   *
-   * @param $type
-   *   The type of the item; one of 'core', 'profile', 'module', 'theme', or
-   *   'theme_engine'.
-   * @param $name
-   *   The name of the item for which the filename is requested. Ignored for
-   *   $type 'core'.
-   * @param $filename
-   *   (Optional) The filename of the item if it is to be set explicitly rather
-   *   than by consulting the database.
-   *
-   * @return
-   *   The filename of the requested item or NULL if the item is not found.
-   */
-  protected function drupalGetFilename($type, $name, $filename = NULL) {
-    return drupal_get_filename($type, $name, $filename);
-  }
-
-}
diff --git a/web/modules/config_sync/src/ConfigSyncListerInterface.php b/web/modules/config_sync/src/ConfigSyncListerInterface.php
deleted file mode 100644
index 96f97a1c0ef02c5630b8885126fc4b3f7c26ecf6..0000000000000000000000000000000000000000
--- a/web/modules/config_sync/src/ConfigSyncListerInterface.php
+++ /dev/null
@@ -1,38 +0,0 @@
-<?php
-
-namespace Drupal\config_sync;
-
-/**
- * Provides methods related to config listing.
- */
-interface ConfigSyncListerInterface {
-
-  /**
-   * Returns a change list for all installed extensions.
-   *
-   * @param array $extension_names
-   *   Array with keys of extension types ('module', 'theme') and values arrays
-   *   of extension names.
-   *
-   * @return array
-   *   Associative array of configuration changes keyed by extension type
-   *   (module or theme) in which values are arrays keyed by extension name.
-   */
-  public function getExtensionChangelists(array $extension_names = []);
-
-  /**
-   * Returns a change list for a given module or theme.
-   *
-   * @param string $type
-   *   The type of extension (module or theme).
-   * @param string $name
-   *   The machine name of the extension.
-   *
-   * @return array
-   *   Associative array of configuration changes keyed by the type of change
-   *   in which values are arrays of configuration item labels keyed by item
-   *   name.
-   */
-  public function getExtensionChangelist($type, $name);
-
-}
diff --git a/web/modules/config_sync/src/ConfigSyncSnapshotter.php b/web/modules/config_sync/src/ConfigSyncSnapshotter.php
deleted file mode 100644
index 68fa86b39765e9e4680b87aa8a39126a2bc55811..0000000000000000000000000000000000000000
--- a/web/modules/config_sync/src/ConfigSyncSnapshotter.php
+++ /dev/null
@@ -1,207 +0,0 @@
-<?php
-
-namespace Drupal\config_sync;
-
-use Drupal\config_provider\InMemoryStorage;
-use Drupal\config_sync\Plugin\SyncConfigCollectorInterface;
-use Drupal\Core\Config\ConfigManagerInterface;
-use Drupal\Core\Config\StorageComparer;
-use Drupal\Core\Config\StorageInterface;
-use Drupal\Core\Extension\Extension;
-
-/**
- * The ConfigSyncSnapshotter provides helper functions for taking snapshots of
- * extension-provided configuration.
- */
-class ConfigSyncSnapshotter implements ConfigSyncSnapshotterInterface {
-
-  /**
-   * The app root for the current operation.
-   *
-   * @var string
-   */
-  protected $root;
-
-  /**
-   * The configuration collector.
-   *
-   * @var \Drupal\config_sync\Plugin\SyncConfigCollectorInterface
-   */
-  protected $configCollector;
-
-  /**
-   * The provider configuration storage.
-   *
-   * @var \Drupal\Core\Config\StorageInterface
-   */
-  protected $providerStorage;
-
-  /**
-   * The snapshot config storage for values from the extension storage.
-   *
-   * @var \Drupal\Core\Config\StorageInterface
-   */
-  protected $snapshotStorage;
-
-  /**
-   * The configuration manager.
-   *
-   * @var \Drupal\Core\Config\ConfigManagerInterface
-   */
-  protected $configManager;
-
-  /**
-   * Constructs a ConfigSyncSnapshotter object.
-   *
-   * @param string $root
-   *   The app root.
-   * @param \Drupal\config_provider\Plugin\SyncConfigCollectorInterface $config_collector
-   *   The config collector.
-   * @param \Drupal\Core\Config\StorageInterface $provider_storage
-   *   The provider configuration storage.
-   * @param \Drupal\Core\Config\StorageInterface $snapshot_storage
-   *   The snapshot storage for the items from the extension storage.
-   * @param \Drupal\Core\Config\ConfigManagerInterface $config_manager
-   *   The configuration manager.
-   */
-  public function __construct($root, SyncConfigCollectorInterface $config_collector, StorageInterface $provider_storage, StorageInterface $snapshot_storage, ConfigManagerInterface $config_manager) {
-    $this->root = $root;
-    $this->configCollector = $config_collector;
-    $this->providerStorage = $provider_storage;
-    $this->snapshotStorage = $snapshot_storage;
-    $this->configManager = $config_manager;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function refreshExtensionSnapshot($type, array $names, $mode) {
-    $extensions = [];
-    foreach ($names as $name) {
-      $pathname = $this->drupalGetFilename($type, $name);
-      $extensions[$name] = new Extension($this->root, $type, $pathname);
-    }
-
-    switch ($mode) {
-      case ConfigSyncSnapshotterInterface::SNAPSHOT_MODE_INSTALL:
-        // Take the snapshot in two stages.
-        // First, add the unaltered configuration.
-        $this->configCollector->addConfigForSnapshotting($extensions);
-        $this->saveSnapshotChanges();
-        // Now alter the previously added configuration.
-        $this->configCollector->alterConfigForSnapshotting($extensions);
-        $this->saveSnapshotChanges();
-        return;
-      case ConfigSyncSnapshotterInterface::SNAPSHOT_MODE_IMPORT:
-        // No special handling for alter on update since the item will already have
-        // been altered on install.
-        $this->configCollector->addInstallableConfig($extensions);
-        $this->saveSnapshotChanges();
-        return;
-    }
-  }
-
-  /**
-   * Saves changes from the provider storage to the snapshot storage.
-   */
-  protected function saveSnapshotChanges() {
-    // Set up a storage comparer.
-    $storage_comparer = new StorageComparer(
-      $this->providerStorage,
-      $this->snapshotStorage,
-      $this->configManager
-    );
-    $storage_comparer->createChangelist();
-
-    $changelist = $storage_comparer->getChangelist();
-
-    // Only add new or changed items.
-    foreach (['create', 'update'] as $changelist_type) {
-      if (isset($changelist[$changelist_type])) {
-        foreach ($changelist[$changelist_type] as $item_name) {
-          if ($provided_data = $this->providerStorage->read($item_name)) {
-            // Snapshot the configuration item as provided by the extension.
-            $this->snapshotStorage->write($item_name, $provided_data);
-          }
-        }
-      }
-    }
-
-    // Snapshot collections as well.
-    foreach ($this->providerStorage->getAllCollectionNames() as $collection) {
-      $changelist = $storage_comparer->getChangelist(NULL, $collection);
-      $this->providerStorage = $this->providerStorage->createCollection($collection);
-      $snapshot_storage = $this->snapshotStorage->createCollection($collection);
-
-      // Only add new or changed items.
-      foreach (['create', 'update'] as $changelist_type) {
-        if (isset($changelist[$changelist_type])) {
-          foreach ($changelist[$changelist_type] as $item_name) {
-            if ($provided_data = $this->providerStorage->read($item_name)) {
-              // Snapshot the configuration item as provided by the extension.
-              $snapshot_storage->write($item_name, $provided_data);
-            }
-          }
-        }
-      }
-
-    }
-
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function createSnapshot() {
-    // Take the snapshot in two stages.
-    // First, add the unaltered configuration.
-    $this->configCollector->addConfigForSnapshotting();
-    $this->configManager->createSnapshot($this->providerStorage, $this->snapshotStorage);
-    // Now alter the previously added configuration.
-    $this->configCollector->alterConfigForSnapshotting();
-    // Don't call ::createSnapshot() because we don't want to remove what we
-    // added in the first stage.
-    $this->copyStorage($this->providerStorage, $this->snapshotStorage);
-  }
-
-  /**
-   * Copies the content of one storage to another.
-   *
-   * @param \Drupal\Core\Config\StorageInterface $source_storage
-   *   The storage to synchronize configuration from.
-   * @param \Drupal\Core\Config\StorageInterface $snapshot_storage
-   *   The storage to synchronize configuration to.
-   */
-  protected function copyStorage($source_storage, $snapshot_storage) {
-    foreach ($source_storage->listAll() as $name) {
-      $snapshot_storage->write($name, $source_storage->read($name));
-    }
-    // Copy collections as well.
-    foreach ($source_storage->getAllCollectionNames() as $collection) {
-      $source_collection = $source_storage->createCollection($collection);
-      $snapshot_collection = $snapshot_storage->createCollection($collection);
-      foreach ($source_collection->listAll() as $name) {
-        $snapshot_collection->write($name, $source_collection->read($name));
-      }
-    }
-  }
-
-  /**
-   * Wrapper for drupal_get_filename().
-   *
-   * @param $type
-   *   The type of the item; one of 'core', 'profile', 'module', 'theme', or
-   *   'theme_engine'.
-   * @param $name
-   *   The name of the item for which the path is requested. Ignored for
-   *   $type 'core'.
-   *
-   * @return string
-   *   The path to the requested item or an empty string if the item is not
-   *   found.
-   */
-  protected function drupalGetFilename($type, $name) {
-    return drupal_get_filename($type, $name);
-  }
-
-}
diff --git a/web/modules/config_sync/src/ConfigSyncSnapshotterInterface.php b/web/modules/config_sync/src/ConfigSyncSnapshotterInterface.php
deleted file mode 100644
index 53d701bd2717c63d54437f7bac3296a8aec1956b..0000000000000000000000000000000000000000
--- a/web/modules/config_sync/src/ConfigSyncSnapshotterInterface.php
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php
-
-namespace Drupal\config_sync;
-
-/**
- * The ConfigSyncSnapshotter provides helper functions for taking snapshots of
- * extension-provided configuration.
- */
-interface ConfigSyncSnapshotterInterface {
-
-  /**
-   * Install snapshot mode.
-   */
-  const SNAPSHOT_MODE_INSTALL = 'install';
-
-  /**
-   * Import snapshot mode.
-   */
-  const SNAPSHOT_MODE_IMPORT = 'import';
-
-  /**
-   * Takes a snapshot of configuration from specified modules or themes.
-   *
-   * Only new or changed items are added.
-   *
-   * @param string $type
-   *   The type of extension to snapshot.
-   * @param array $names
-   *   An array of extension names.
-   * @param string $mode
-   *   The snapshot mode. Valid values are:
-   *   - \Drupal\config_sync\ConfigSyncSnapshotterInterface::SNAPSHOT_MODE_INSTALL
-   *   - \Drupal\config_sync\ConfigSyncSnapshotterInterface::SNAPSHOT_MODE_IMPORT
-   */
-  public function refreshExtensionSnapshot($type, array $names, $mode);
-
-  /**
-   * Takes a snapshot of configuration from all installed modules and themes.
-   */
-  public function createSnapshot();
-
-}
diff --git a/web/modules/config_sync/src/EventSubscriber/ConfigSyncSnapshotSubscriber.php b/web/modules/config_sync/src/EventSubscriber/ConfigSyncSnapshotSubscriber.php
deleted file mode 100644
index 5c8d5aa1164b73072dd59c43dc694b17a224a964..0000000000000000000000000000000000000000
--- a/web/modules/config_sync/src/EventSubscriber/ConfigSyncSnapshotSubscriber.php
+++ /dev/null
@@ -1,97 +0,0 @@
-<?php
-
-namespace Drupal\config_sync\EventSubscriber;
-
-use Drupal\config_distro\Event\ConfigDistroEvents;
-use Drupal\config_filter\ConfigFilterManagerInterface;
-use Drupal\config_sync\Plugin\ConfigFilter\SyncFilter;
-use Drupal\config_sync\ConfigSyncSnapshotterInterface;
-use Drupal\Core\State\StateInterface;
-use Symfony\Component\EventDispatcher\Event;
-use Symfony\Component\EventDispatcher\EventSubscriberInterface;
-
-/**
- * Updates the snapshot when config is imported.
- */
-class ConfigSyncSnapshotSubscriber implements EventSubscriberInterface {
-
-  /**
-   * The snapshotter.
-   *
-   * @var \Drupal\config_sync\ConfigSyncSnapshotterInterface
-   */
-  protected $snapshotter;
-
-  /**
-   * The filter manager.
-   *
-   * @var \Drupal\config_filter\ConfigFilterManagerInterface
-   */
-  protected $configFilterManager;
-
-  /**
-   * The state storage object.
-   *
-   * @var \Drupal\Core\State\StateInterface
-   */
-  protected $state;
-
-  /**
-   * Constructs the ConfigSnapshotSubscriber object.
-   *
-   * @param \Drupal\config_sync\ConfigSyncSnapshotterInterface $snapshotter
-   *   The snapshotter.
-   * @param \Drupal\config_filter\ConfigFilterManagerInterface $config_filter_manager
-   *   The filter manager.
-   * @param \Drupal\Core\State\StateInterface $state
-   *   The state storage object.
-   */
-  public function __construct(ConfigSyncSnapshotterInterface $snapshotter, ConfigFilterManagerInterface $config_filter_manager, StateInterface $state) {
-    $this->snapshotter = $snapshotter;
-    $this->configFilterManager = $config_filter_manager;
-    $this->state = $state;
-  }
-
-  /**
-   * Refreshes the snapshot for extensions whose updates were imported.
-   *
-   * @param \Drupal\Core\Config\ConfigImporterEvent $event
-   *   The Event to process.
-   */
-  public function onConfigDistroImport(Event $event) {
-    $filters = $this->configFilterManager->getDefinitions();
-    $extensions = [];
-    // There is a filter for each extension that had updates.
-    foreach ($filters as $filter) {
-      // Only process our own filters.
-      if (($filter['provider'] === 'config_sync') &&
-        // The updates were imported if the filter was enabled.
-        $filter['status'] &&
-        // We're only responding to events for filters using the storage
-        // provided by config_distro.
-        in_array('config_distro.storage.distro', $filter['storages'])) {
-        $extensions[$filter['extension_type']][] = $filter['extension_name'];
-      }
-    }
-
-    foreach ($extensions as $type => $names) {
-      $this->snapshotter->refreshExtensionSnapshot($type, $names, ConfigSyncSnapshotterInterface::SNAPSHOT_MODE_IMPORT);
-    }
-
-    // Clear data on previously-selected plugins.
-    $this->state->delete('config_sync.plugins');
-    $this->configFilterManager->clearCachedDefinitions();
-  }
-
-  /**
-   * Registers the methods in this class that should be listeners.
-   *
-   * @return array
-   *   An array of event listener definitions.
-   */
-  public static function getSubscribedEvents() {
-    $events[ConfigDistroEvents::IMPORT][] = ['onConfigDistroImport', 40];
-    return $events;
-  }
-
-}
diff --git a/web/modules/config_sync/src/Form/ConfigSyncImportForm.php b/web/modules/config_sync/src/Form/ConfigSyncImportForm.php
deleted file mode 100644
index f6c06946fcda3b5a2ff6cb971c3d98286bdfdaea..0000000000000000000000000000000000000000
--- a/web/modules/config_sync/src/Form/ConfigSyncImportForm.php
+++ /dev/null
@@ -1,369 +0,0 @@
-<?php
-
-namespace Drupal\config_sync\Form;
-
-use Drupal\config_distro\Form\ConfigDistroImportForm;
-use Drupal\Core\Config\StorageInterface;
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\StringTranslation\StringTranslationTrait;
-use Drupal\Core\Url;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-class ConfigSyncImportForm extends ConfigDistroImportForm {
-
-  use StringTranslationTrait;
-
-  /**
-   * The configuration synchronizer lister.
-   *
-   * @var \Drupal\config_sync\configSyncListerInterface
-   */
-  protected $configSyncLister;
-
-  /**
-   * The configuration update lister.
-   *
-   * @var \Drupal\config_update\ConfigListInterface
-   */
-  protected $configUpdateLister;
-
-  /**
-   * The module handler.
-   *
-   * @var \Drupal\Core\Extension\ModuleHandlerInterface
-   */
-  protected $moduleHandler;
-
-  /**
-   * The theme handler.
-   *
-   * @var \Drupal\Core\Extension\ThemeHandlerInterface
-   */
-  protected $themeHandler;
-
-  /**
-   * The state storage object.
-   *
-   * @var \Drupal\Core\State\StateInterface
-   */
-  protected $state;
-
-  /**
-   * The filter manager.
-   *
-   * @var \Drupal\config_filter\ConfigFilterManagerInterface
-   */
-  protected $configFilterManager;
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container) {
-    $class = parent::create($container);
-    $class->configSyncLister = $container->get('config_sync.lister');
-    $class->configUpdateLister = $container->get('config_update.config_list');
-    $class->moduleHandler = $container->get('module_handler');
-    $class->themeHandler = $container->get('theme_handler');
-    $class->state = $container->get('state');
-    $class->configFilterManager = $container->get('plugin.manager.config_filter');
-    return $class;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildForm(array $form, FormStateInterface $form_state) {
-    // Ensure the filters reflect the current state of the file system.
-    $this->configFilterManager->clearCachedDefinitions();
-    $form = parent::buildForm($form, $form_state);
-
-    // Transform the UI to one based on our changelists.
-    if ($changelists = $this->configSyncLister->getExtensionChangelists()) {
-      // Create a wrapper for the classic UI provided by core.
-      $form['classic'] = [
-        '#type' => 'details',
-        '#title' => $this->t('Classic version of configuration change listings'),
-        '#weight' => 10,
-      ];
-
-      // For each collection, move the original listings coming from core's
-      // form.
-      foreach ($this->getAllChangelistCollections($changelists) as $collection) {
-        if (isset($form[$collection])) {
-          $form['classic'][$collection] = $form[$collection];
-          unset($form[$collection]);
-        }
-      }
-
-      $form['config_sync'] = [
-        '#type' => 'container',
-      ];
-      foreach ($changelists as $type => $extension_changelists) {
-        $form['config_sync'][$type] = $this->buildUpdatesListing($type, $extension_changelists);
-      }
-
-      if (!empty($form['actions']['submit'])) {
-        $form['actions']['submit']['#value'] = $this->t('Import');
-      }
-    }
-
-    return $form;
-  }
-
-
-  /**
-   * Returns a list of collections for a given set of changelists.
-   *
-   * @param array $changelists
-   *   A set of changelists.
-   *
-   * @return array
-   *   An array of collection names.
-   */
-  protected function getAllChangelistCollections(array $changelists) {
-    $collections = [];
-
-    foreach ($changelists as $extension_changelists) {
-      foreach ($extension_changelists as $collection_changelists) {
-        $collections = array_unique(array_merge($collections, array_keys($collection_changelists)));
-      }
-    }
-
-    return $collections;
-  }
-
-  /**
-   * Builds the portion of the form showing a listing of updates.
-   *
-   * @param string $type
-   *   The type of extension (module or theme).
-   * @param array $extension_changelists
-   *   Associative array of configuration changes keyed by extension name.
-   *
-   * @return array
-   *   A render array of a form element.
-   */
-  protected function buildUpdatesListing($type, array $extension_changelists) {
-    $plugin_data = $this->state->get('config_sync.plugins_previous');
-
-    $type_labels = [
-      'module' => $this->t('Module'),
-      'theme' => $this->t('Theme'),
-    ];
-    $header = [
-      'name' => [
-        'data' => $this->t('@type name', ['@type' => $type_labels[$type]]),
-      ],
-      'details' => [
-        'data' => $this->t('Available configuration changes'), 'class' => [RESPONSIVE_PRIORITY_LOW],
-      ],
-    ];
-
-    $options = [];
-    $default_value = [];
-
-    foreach ($extension_changelists as $name => $collection_changelists) {
-      $options[$name] = $this->buildExtensionDetail($type, $name, $collection_changelists);
-      // Status can be overridden in the state.
-      $default_value[$name] = !isset($plugin_data[$type][$name]['status']) || ($plugin_data[$type][$name]['status'] === TRUE);
-    }
-    $element = [
-      '#type' => 'tableselect',
-      '#header' => $header,
-      '#options' => $options,
-      '#multiple' => TRUE,
-      '#attributes' => ['class' => ['config-sync-listing']],
-      '#default_value' => $default_value,
-    ];
-
-    return $element;
-  }
-
-  /**
-   * Builds the details of a package.
-   *
-   * @param string $type
-   *   The type of extension (module or theme).
-   * @param string $name
-   *   The machine name of the extension.
-   * @param array $collection_changelists
-   *   Associative array of configuration changes keyed by the type of change.
-   * @param string $collection
-   *   The configuration collection.
-   *
-   * @return array
-   *   A render array of a form element.
-   */
-  protected function buildExtensionDetail($type, $name, $collection_changelists) {
-    switch ($type) {
-      case 'module':
-        $label = $this->moduleHandler->getName($name);
-        break;
-      case 'theme':
-        $label = $this->themeHandler->getName($name);
-        break;
-    }
-
-    $element['name'] = [
-      'data' => [
-        '#type' => 'html_tag',
-        '#tag' => 'h3',
-        '#value' => $label,
-      ],
-      'class' => ['config-sync-extension-name'],
-    ];
-
-    foreach ($collection_changelists as $collection => $changelist) {
-      $extension_config = [];
-      foreach (['create', 'update'] as $change_type) {
-        if (isset($changelist[$change_type])) {
-          $extension_config[$change_type] = [];
-          foreach ($changelist[$change_type] as $item_name => $item_label) {
-            $config_type = $this->configUpdateLister->getTypeNameByConfigName($item_name);
-            if (!$config_type) {
-              $config_type = 'system_simple';
-            }
-
-            if ($change_type == 'rename') {
-              $names = $storage_comparer->extractRenameNames($item_name);
-              $route_options = array('source_name' => $names['old_name'], 'target_name' => $names['new_name']);
-            }
-            else {
-              $route_options = array('source_name' => $item_name);
-            }
-            if ($collection != StorageInterface::DEFAULT_COLLECTION) {
-              $route_name = 'config_distro.diff_collection';
-              $route_options['collection'] = $collection;
-            }
-            else {
-              $route_name = 'config_distro.diff';
-            }
-            if (!isset($extension_config[$change_type][$config_type])) {
-              $extension_config[$change_type][$config_type] = [];
-            }
-            $extension_config[$change_type][$config_type][$item_name] = [
-              '#type' => 'link',
-              '#title' => $item_label,
-              '#url' => Url::fromRoute($route_name, $route_options),
-              '#options' => [
-                'attributes' => [
-                  'class' => ['use-ajax'],
-                  'data-dialog-type' => 'modal',
-                  'data-dialog-options' => json_encode([
-                    'width' => 700
-                  ]),
-                ],
-              ],
-            ];
-          }
-        }
-      }
-
-      $rows = [];
-
-      if ($collection !== StorageInterface::DEFAULT_COLLECTION) {
-        $rows[] = [
-          [
-            'data' => [
-              '#type' => 'html_tag',
-              '#tag' => 'h2',
-              '#value' => $this->t('@collection configuration collection', ['@collection' => $collection]),
-              '#colspan' => 2,
-            ],
-          ],
-        ];
-      }
-
-      $change_type_labels = [
-        // Match the labels used by core.
-        // @see ConfigSync::buildForm().
-        'create' => $this->t('New'),
-        'update' => $this->t('Changed'),
-      ];
-
-      // List config types for order.
-      $config_types = $this->configSyncLister->listConfigTypes();
-
-      foreach ($extension_config as $change_type => $change_type_data) {
-        $rows[] = [
-          [
-            'data' => [
-              '#type' => 'html_tag',
-              '#tag' => 'strong',
-              '#value' => $change_type_labels[$change_type],
-            ],
-          ],
-          [
-            'data' => [
-              '#type' => 'html_tag',
-              '#tag' => 'strong',
-              '#value' => $this->t('View differences'),
-            ],
-          ],
-        ];
-
-        foreach ($config_types as $config_type => $config_type_label) {
-          if (isset($change_type_data[$config_type])) {
-            $row = [];
-            $row[] = [
-              'data' => [
-                '#type' => 'html_tag',
-                '#tag' => 'span',
-                '#value' => $config_type_label,
-                '#attributes' => [
-                  'title' => $config_type,
-                  'class' => ['config-sync-item-type-label'],
-                ],
-              ],
-            ];
-            $row[] = [
-              'data' => [
-                '#theme' => 'item_list',
-                '#items' => $change_type_data[$config_type],
-                '#context' => [
-                  'list_style' => 'comma-list',
-                ],
-              ],
-              'class' => ['item'],
-            ];
-            $rows[] = $row;
-          }
-        }
-      }
-
-    }
-
-    $element['details'] = [
-      'data' => [
-        '#type' => 'table',
-        '#rows' => $rows,
-      ],
-    ];
-
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, FormStateInterface $form_state) {
-    // Save data on selected modules and themes to the system state.
-    $plugin_data = [];
-    foreach (['module', 'theme'] as $type) {
-      if ($names = $form_state->getValue($type)) {
-        // Convert data to boolean values.
-        array_walk($names, function($value, $key) use($type, &$plugin_data) {
-          $value = (bool) $value;
-          $plugin_data[$type][$key]['status'] = $value;
-        });
-      }
-    }
-
-    $this->state->set('config_sync.plugins', $plugin_data);
-    $this->state->set('config_sync.plugins_previous', $plugin_data);
-    $this->configFilterManager->clearCachedDefinitions();
-
-    parent::submitForm($form, $form_state);
-  }
-
-}
diff --git a/web/modules/config_sync/src/Plugin/ConfigFilter/SyncFilter.php b/web/modules/config_sync/src/Plugin/ConfigFilter/SyncFilter.php
deleted file mode 100644
index 0b0a3b68393f6cc83ddaf748eeada7d82a499dd8..0000000000000000000000000000000000000000
--- a/web/modules/config_sync/src/Plugin/ConfigFilter/SyncFilter.php
+++ /dev/null
@@ -1,212 +0,0 @@
-<?php
-
-namespace Drupal\config_sync\Plugin\ConfigFilter;
-
-use Drupal\config_filter\Plugin\ConfigFilterBase;
-use Drupal\config_merge\ConfigMerger;
-use Drupal\config_provider\InMemoryStorage;
-use Drupal\config_sync\ConfigSyncListerInterface;
-use Drupal\Core\Config\ConfigManagerInterface;
-use Drupal\Core\Config\StorageInterface;
-use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Provides a sync filter that brings in updates from installed extensions.
- *
- * @ConfigFilter(
- *   id = "config_sync",
- *   label = "Config Sync",
- *   storages = {"config_distro.storage.distro"},
- *   weight = 10,
- *   deriver = "\Drupal\config_sync\Plugin\ConfigFilter\SyncFilterDeriver"
- * )
- */
-class SyncFilter extends ConfigFilterBase implements ContainerFactoryPluginInterface {
-
-  /**
-   * The sync source configuration storage.
-   *
-   * @var \Drupal\Core\Config\StorageInterface
-   */
-  protected $syncSourceStorage;
-
-  /**
-   * Constructs a new SyncFilter.
-   *
-   * @param array $configuration
-   *   A configuration array containing information about the plugin instance.
-   * @param string $plugin_id
-   *   The plugin_id for the plugin instance.
-   * @param array $plugin_definition
-   *   The plugin implementation definition.
-   * @param \Drupal\Core\Config\StorageInterface $sync_source_storage
-   *   The sync source configuration storage.
-   */
-  public function __construct(array $configuration, $plugin_id, array $plugin_definition, StorageInterface $sync_source_storage) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition);
-    $this->syncSourceStorage = $sync_source_storage;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    $sync_source_storage = self::initSyncSourceStorage(
-      $configuration,
-      $container->get('config_sync.lister'),
-      $container->get('config_sync.snapshot_storage'),
-      $container->get('config_provider.storage'),
-      $container->get('config.storage')
-    );
-    return new static(
-      $configuration,
-      $plugin_id,
-      $plugin_definition,
-      $sync_source_storage
-    );
-  }
-
-  /**
-   * Initializes the sync source storage.
-   *
-   * @param array $configuration
-   *   The plugin configuration.
-   * @param \Drupal\Core\Config\StorageInterface $snapshot_storage
-   *   The snapshot extension storage.
-   * @param \Drupal\Core\Config\StorageInterface $provider_storage
-   *   The configuration provider storage.
-   * @param \Drupal\Core\Config\StorageInterface $active_storage
-   *   The active configuration storage.
-   *
-   * @return \Drupal\Core\Config\StorageInterface
-   *   The initialised sync source storage
-   */
-  protected static function initSyncSourceStorage(array $configuration, ConfigSyncListerInterface $config_sync_lister, StorageInterface $snapshot_storage, StorageInterface $provider_storage, StorageInterface $active_storage) {
-    $changelists = $config_sync_lister->getExtensionChangelist($configuration['extension_type'], $configuration['extension_name']);
-    $sync_source_storage = new InMemoryStorage();
-
-    foreach ($changelists as $collection => $changelist) {
-      // Ensure storages are using the specified collection.
-      foreach (['snapshot', 'provider', 'active', 'sync_source'] as $storage_prefix) {
-        if ($collection !== ${$storage_prefix . '_storage'}->getCollectionName()) {
-          ${$storage_prefix . '_storage'} = ${$storage_prefix . '_storage'}->getCollection($collection);
-        }
-      }
-      // Process changes.
-      if (!empty($changelist['create'])) {
-        // To create, we simply save the new item to the merge storage.
-        foreach (array_keys($changelist['create']) as $item_name) {
-          $sync_source_storage->write($item_name, $provider_storage->read($item_name));
-        }
-      }
-      // Process update changes.
-      if (!empty($changelist['update'])) {
-        $config_merger = new ConfigMerger();
-        // To update, we merge the value into that of the active storage.
-        foreach (array_keys($changelist['update']) as $item_name) {
-          $current = $provider_storage->read($item_name);
-          $previous = $snapshot_storage->read($item_name);
-          $active = $active_storage->read($item_name);
-          $merged = $config_merger->mergeConfigItemStates($previous, $current, $active);
-
-          $sync_source_storage->write($item_name, $merged);
-        }
-      }
-    }
-
-    return $sync_source_storage;
-  }
-
-  /**
-   * Reads from the sync source configuration.
-   *
-   * @param string $name
-   *   The name of the configuration to read.
-   * @param mixed $data
-   *   The data to be filtered.
-   *
-   * @return mixed
-   *   The data filtered or read from the sync source storage.
-   */
-  protected function syncSourceStorageRead($name, $data) {
-    if ($sync = $this->syncSourceStorage->read($name)) {
-      if (!isset($sync['_core']) && !empty($data['_core'])) {
-        // Merge in uuid and _core while retaining the key order.
-        $merged = array_replace($data, $sync);
-        $sync = array_intersect_key($merged, array_flip(array_merge(array_keys($sync), ['uuid', '_core'])));
-      }
-      return $sync;
-    }
-
-    return $data;
-  }
-
-  /**
-   * Reads multiple from the sync source storage.
-   *
-   * @param array $names
-   *   The names of the configuration to read.
-   * @param array $data
-   *   The data to filter.
-   *
-   * @return array
-   *   The new data.
-   */
-  protected function syncSourceStorageReadMultiple(array $names, array $data) {
-    $filtered_data = [];
-    foreach ($names as $name) {
-      $filtered_data[$name] = $this->syncSourceStorageRead($name, isset($data[$name]) ? $data[$name] : []);
-    }
-
-    return $filtered_data;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function filterRead($name, $data) {
-    return $this->syncSourceStorageRead($name, $data);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function filterExists($name, $exists) {
-    return $exists || $this->syncSourceStorage->exists($name);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function filterReadMultiple(array $names, array $data) {
-    $sync_data = $this->syncSourceStorageReadMultiple($names, $data);
-
-    // Return the data with merged in sync source data.
-    return array_merge($data, $sync_data);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function filterListAll($prefix, array $data) {
-    $sync_names = $this->syncSourceStorage->listAll($prefix);
-
-    return array_unique(array_merge($data, $sync_names));
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function filterCreateCollection($collection) {
-    return new static($this->configuration, $this->pluginId, $this->pluginDefinition, $this->syncSourceStorage->createCollection($collection));
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function filterGetAllCollectionNames(array $collections) {
-    return array_merge($collections, $this->syncSourceStorage->getAllCollectionNames());
-  }
-
-}
diff --git a/web/modules/config_sync/src/Plugin/ConfigFilter/SyncFilterDeriver.php b/web/modules/config_sync/src/Plugin/ConfigFilter/SyncFilterDeriver.php
deleted file mode 100644
index 6cfadcb9173b34881b5f1d4792f38569d0a56d39..0000000000000000000000000000000000000000
--- a/web/modules/config_sync/src/Plugin/ConfigFilter/SyncFilterDeriver.php
+++ /dev/null
@@ -1,115 +0,0 @@
-<?php
-
-namespace Drupal\config_sync\Plugin\ConfigFilter;
-
-use Drupal\config_sync\ConfigSyncListerInterface;
-use Drupal\Component\Plugin\Derivative\DeriverBase;
-use Drupal\Component\Utility\NestedArray;
-use Drupal\Core\Extension\ModuleHandlerInterface;
-use Drupal\Core\Extension\ThemeHandlerInterface;
-use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
-use Drupal\Core\State\StateInterface;
-use Drupal\Core\StringTranslation\StringTranslationTrait;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Deriver for SyncFilter filters.
- */
-class SyncFilterDeriver extends DeriverBase implements ContainerDeriverInterface {
-
-  use StringTranslationTrait;
-
-  /**
-   * The configuration synchronizer lister.
-   *
-   * @var \Drupal\config_sync\configSyncListerInterface
-   */
-  protected $configSyncLister;
-
-  /**
-   * The module handler.
-   *
-   * @var \Drupal\Core\Extension\ModuleHandlerInterface
-   */
-  protected $moduleHandler;
-
-  /**
-   * The theme handler.
-   *
-   * @var \Drupal\Core\Extension\ThemeHandlerInterface
-   */
-  protected $themeHandler;
-
-  /**
-   * The state storage object.
-   *
-   * @var \Drupal\Core\State\StateInterface
-   */
-  protected $state;
-
-  /**
-   * SyncFilter constructor.
-   *
-   * @param \Drupal\config_sync\ConfigSyncListerInterface $config_sync_lister
-   *   The configuration synchronizer lister.
-   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
-   *   The module handler.
-   * @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler
-   *   The theme handler.
-   * @param \Drupal\Core\State\StateInterface $state
-   *   The state storage object.
-   */
-  public function __construct(ConfigSyncListerInterface $config_sync_lister, ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler, StateInterface $state) {
-    $this->configSyncLister = $config_sync_lister;
-    $this->moduleHandler = $module_handler;
-    $this->themeHandler = $theme_handler;
-    $this->state = $state;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container, $base_plugin_id) {
-    return new static(
-      $container->get('config_sync.lister'),
-      $container->get('module_handler'),
-      $container->get('theme_handler'),
-      $container->get('state')
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getDerivativeDefinitions($base_plugin_definition) {
-    $plugin_data = $this->state->get('config_sync.plugins');
-    $type_labels = [
-      'module' => $this->t('Module'),
-      'theme' => $this->t('Theme'),
-    ];
-    foreach ($this->configSyncLister->getExtensionChangelists() as $type => $extension_changelists) {
-      foreach (array_keys($extension_changelists) as $name) {
-        $key = $type . '_' . $name;
-        $this->derivatives[$key] = $base_plugin_definition;
-        $this->derivatives[$key]['extension_type'] = $type;
-        $this->derivatives[$key]['extension_name'] = $name;
-        switch ($type) {
-          case 'module':
-            $label = $this->moduleHandler->getName($name);
-            $type_label = $this->t('Module');
-            break;
-          case 'theme':
-            $label = $this->themeHandler->getName($name);
-            $type_label = $this->t('Theme');
-            break;
-        }
-        $this->derivatives[$key]['label'] = $this->t('@type_label: @label', ['@type_label' => $type_label, '@label' => $label]);
-        // Status can be overridden in the state.
-        $this->derivatives[$key]['status'] = !isset($plugin_data[$type][$name]['status']) || ($plugin_data[$type][$name]['status'] === TRUE);
-      }
-    }
-
-    return $this->derivatives;
-  }
-
-}
diff --git a/web/modules/config_sync/src/Plugin/SyncConfigCollector.php b/web/modules/config_sync/src/Plugin/SyncConfigCollector.php
deleted file mode 100644
index 26dd758b17ffecc33f4d053f724e79adaf42d657..0000000000000000000000000000000000000000
--- a/web/modules/config_sync/src/Plugin/SyncConfigCollector.php
+++ /dev/null
@@ -1,40 +0,0 @@
-<?php
-
-namespace Drupal\config_sync\Plugin;
-
-use Drupal\config_provider\Plugin\ConfigCollector;
-
-/**
- * Class for invoking configuration providers.
- */
-class SyncConfigCollector extends ConfigCollector implements SyncConfigCollectorInterface {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function addConfigForSnapshotting(array $extensions = []) {
-    /* @var \Drupal\config_provider\Plugin\ConfigProviderInterface[] $providers */
-    $providers = $this->getConfigProviders();
-
-    foreach ($providers as $provider) {
-      if (!$provider instanceof SyncConfigProviderInterface) {
-        $provider->addInstallableConfig($extensions);
-      }
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function alterConfigForSnapshotting(array $extensions = []) {
-    /* @var \Drupal\config_provider\Plugin\ConfigProviderInterface[] $providers */
-    $providers = $this->getConfigProviders();
-
-    foreach ($providers as $provider) {
-      if ($provider instanceof SyncConfigProviderInterface) {
-        $provider->alterConfigForSnapshotting($extensions);
-      }
-    }
-  }
-
-}
diff --git a/web/modules/config_sync/src/Plugin/SyncConfigCollectorInterface.php b/web/modules/config_sync/src/Plugin/SyncConfigCollectorInterface.php
deleted file mode 100644
index c125919a9114af5c24610be5fb013ea02b8748dd..0000000000000000000000000000000000000000
--- a/web/modules/config_sync/src/Plugin/SyncConfigCollectorInterface.php
+++ /dev/null
@@ -1,39 +0,0 @@
-<?php
-
-namespace Drupal\config_sync\Plugin;
-
-use Drupal\config_provider\Plugin\ConfigCollectorInterface;
-
-/**
- * Class for invoking configuration providers.
- */
-interface SyncConfigCollectorInterface extends ConfigCollectorInterface {
-
-  /**
-   * Adds configuration for snapshotting.
-   *
-   * Call this method instead of ::addInstallableConfig() to add only unaltered
-   * configuration.
-   *
-   * @param \Drupal\Core\Extension\Extension[] $extensions
-   *   (Optional) An associative array of Extension objects, keyed by extension
-   *   name. If provided, data loaded will be limited to these extensions.
-   */
-  public function addConfigForSnapshotting(array $extensions = []);
-
-  /**
-   * Alters configuration for snapshotting.
-   *
-   * In certain cases, the configuration suitable for snapshotting will differ
-   * from that suitable for comparing to a snapshot. The snapshot should
-   * reflect the current installed state. If alters are in effect, the
-   * snapshot should be updated accordingly as a new module is installed or
-   * updated.
-   *
-   * @param \Drupal\Core\Extension\Extension[] $extensions
-   *   (Optional) An associative array of Extension objects, keyed by extension
-   *   name. If provided, data loaded will be limited to these extensions.
-   */
-  public function alterConfigForSnapshotting(array $extensions = []);
-
-}
diff --git a/web/modules/config_sync/src/Plugin/SyncConfigProviderInterface.php b/web/modules/config_sync/src/Plugin/SyncConfigProviderInterface.php
deleted file mode 100644
index 57f10330e03d756956d4a0f40024d1dffc6aab76..0000000000000000000000000000000000000000
--- a/web/modules/config_sync/src/Plugin/SyncConfigProviderInterface.php
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-
-namespace Drupal\config_sync\Plugin;
-
-use Drupal\config_provider\InMemoryStorage;
-use Drupal\config_provider\Plugin\ConfigProviderInterface;
-
-/**
- * Class for invoking configuration providers for snapshotting.
- */
-interface SyncConfigProviderInterface extends ConfigProviderInterface {
-
-  /**
-   * Alters configuration to be used for snapshotting.
-   *
-   * Not intended to be called an install time, this method instead facilitates
-   * determining what configuration updates are available.
-   *
-   * Implementing plugins should write configuration as appropriate to the
-   * ::providerStorage storage.
-   *
-   * @param \Drupal\Core\Extension\Extension[] $extensions
-   *   (Optional) An associative array of Extension objects, keyed by extension
-   *   name. If provided, data loaded will be limited to these extensions.
-   *
-   * @see \Drupal\config_provider\Plugin\ConfigProviderInterface\addInstallableConfig()
-   */
-  public function alterConfigForSnapshotting(array $extensions = []);
-
-}
diff --git a/web/modules/config_sync/src/Routing/RouteSubscriber.php b/web/modules/config_sync/src/Routing/RouteSubscriber.php
deleted file mode 100644
index e1597c8c8f68d122bb4e3e76294434c176df8c3e..0000000000000000000000000000000000000000
--- a/web/modules/config_sync/src/Routing/RouteSubscriber.php
+++ /dev/null
@@ -1,23 +0,0 @@
-<?php
-
-namespace Drupal\config_sync\Routing;
-
-use Drupal\Core\Routing\RouteSubscriberBase;
-use Symfony\Component\Routing\RouteCollection;
-
-/**
- * Listens to the dynamic route events.
- */
-class RouteSubscriber extends RouteSubscriberBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function alterRoutes(RouteCollection $collection) {
-    // Use our form for distribution imports.
-    if ($route = $collection->get('config_distro.import')) {
-      $route->setDefault('_form', '\Drupal\config_sync\Form\ConfigSyncImportForm');
-    }
-  }
-
-}
diff --git a/web/modules/css_editor/README.md b/web/modules/css_editor/README.md
deleted file mode 100644
index 54fcb3439c853027bd2de7d48504a498870fa69e..0000000000000000000000000000000000000000
--- a/web/modules/css_editor/README.md
+++ /dev/null
@@ -1,33 +0,0 @@
-Custom CSS Editor
-=================
-
-This module allows administrators to customize a theme's CSS through
-the browser, using a rich text editor with syntax highlighting and
-live preview.
-
-On the settings page of each theme it will be displayed a
-textarea where the admin can type custom CSS code. He can choose to
-use a plain textarea or an editor with syntax highlighting (default).
-He can also preview the changes live while he types. This can be disabled
-as well (default is enabled). The feature can be enabled to multiple
-themes on the same site, and all can be lively previewed, not only the
-default one. The custom CSS code is injected after all other CSS.
-
-Requirements
-------------
-
-The syntax highlighting feature is provided by the
-[CodeMirror](https://github.com/codemirror/codemirror) library.
-To install it, clone or download (and extract) the project in the
-`/libraries/codemirror/` folder
-in Drupal's root.
-
-External links
---------------
-
-Check [this video](http://ca.ios.ba/files/drupal/csseditor.ogv) to understand
-better how it works (Drupal 7 version).
-
-Check the module on [Drupal.org](https://www.drupal.org/project/css_editor).
-
-This module was originally sponsored by [Meedan](http://meedan.org).
diff --git a/web/modules/css_editor/css/css_editor.css b/web/modules/css_editor/css/css_editor.css
deleted file mode 100644
index b7e20ccd211e796aa11e1d0c37daf5fb52047420..0000000000000000000000000000000000000000
--- a/web/modules/css_editor/css/css_editor.css
+++ /dev/null
@@ -1,37 +0,0 @@
-#css-editor-field .CodeMirror,
-#css-editor-field textarea,
-#css-editor-preview-path,
-#css-editor-preview {
-  border: 1px solid #ccc;
-}
-
-#css-editor-field .CodeMirror,
-#css-editor-field textarea {
-  height: 200px;
-}
-
-#css-editor-field .form-textarea-wrapper label {
-  display: inline;
-  font-weight: normal;
-  line-height: 36px;
-  font-size: 12px;
-}
-
-#css-editor-preview {
-  width: 100%;
-  height: 400px;
-}
-
-#css-editor-field label + input[type=checkbox] {
-  margin-left: 36px;
-}
-
-#css-editor-preview-path-wrapper label {
-  display: inline;
-  font-weight: normal;
-  margin-right: 6px;
-}
-
-#css-editor-preview-path-wrapper {
-  margin-bottom: 6px;
-}
diff --git a/web/modules/css_editor/css_editor.info.yml b/web/modules/css_editor/css_editor.info.yml
deleted file mode 100644
index ddbb35c90e9c079328e0cb3502ef54ae6d841fab..0000000000000000000000000000000000000000
--- a/web/modules/css_editor/css_editor.info.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-name: CSS Editor
-type: module
-description: Customize your CSS directly from the browser.
-# core: 8.x
-
-# Information added by Drupal.org packaging script on 2016-09-06
-version: '8.x-1.0'
-core: '8.x'
-project: 'css_editor'
-datestamp: 1473167040
diff --git a/web/modules/css_editor/css_editor.libraries.yml b/web/modules/css_editor/css_editor.libraries.yml
deleted file mode 100644
index 4310156ab02ad1af99d5da6645a30a4caf084fdc..0000000000000000000000000000000000000000
--- a/web/modules/css_editor/css_editor.libraries.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-css_editor:
-  version: 1.x
-  css:
-    theme:
-      css/css_editor.css: {}
-  js:
-    js/css_editor.js: {}
-  dependencies:
-    - core/jquery
-    - core/drupalSettings
-
-codemirror:
-  remote: https://github.com/codemirror/CodeMirror
-  license:
-    name: MIT
-    url: https://github.com/codemirror/CodeMirror/blob/master/LICENSE
-    gpl-compatible: true
-  css:
-    theme:
-      /libraries/codemirror/lib/codemirror.css: {}
-      /libraries/codemirror/addon/hint/show-hint.css: {}
-  js:
-    /libraries/codemirror/lib/codemirror.js: {}
-    /libraries/codemirror/mode/css/css.js: {}
-    /libraries/codemirror/addon/hint/show-hint.js: {}
-
diff --git a/web/modules/css_editor/css_editor.module b/web/modules/css_editor/css_editor.module
deleted file mode 100644
index 94684d86e36a14a8655a189a6f3f4cd5ee333c79..0000000000000000000000000000000000000000
--- a/web/modules/css_editor/css_editor.module
+++ /dev/null
@@ -1,101 +0,0 @@
-<?php
-/**
- * @file
- * Allows users to apply customized CSS to themes.
- */
-
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Url;
-
-/**
- * Implements hook_library_info_alter().
- */
-function css_editor_library_info_alter(&$libraries, $extension) {
-  $theme = \Drupal::theme()->getActiveTheme()->getName();
-  if ($extension == $theme) {
-    $config = \Drupal::configFactory()->getEditable('css_editor.theme.' . $theme);
-    $file = $config->get('path');
-    if ($config->get('enabled') && file_exists($file)) {
-      // Append custom style sheet to theme libraries.
-      $libraries['global-styling']['css']['theme'][$file]['weight'] = 9999;
-    }
-  }
-}
-
-/**
- * Implements hook_form_FORM_ID_alter() for `system_theme_settings`.
- */
-function css_editor_form_system_theme_settings_alter(&$form, FormStateInterface $form_state, $form_id) {
-  $theme = _css_editor_get_edited_theme($form_state);
-  if ($theme) {
-    $config = \Drupal::configFactory()->getEditable('css_editor.theme.' . $theme);
-    // Add CSS customization fieldset.
-    $form['css_editor'] = array(
-      '#type' => 'details',
-      '#title' => t('Custom CSS'),
-      '#open' => TRUE,
-    );
-    // Switch to enable/disable customization.
-    $form['css_editor']['css_enabled'] = array(
-      '#title' => t('Enable or disable custom CSS:'),
-      '#type' => 'checkbox',
-      '#default_value' => $config->get('enabled'),
-    );
-    // Editor box.
-    $form['css_editor']['css'] = array(
-      '#type' => 'textarea',
-      '#prefix' => '<div id="css-editor-field">',
-      '#description' => t('Type or paste custom CSS code for this theme.'),
-      '#default_value' => $config->get('css'),
-      '#attributes' => array('id' => 'css-editor-textarea'),
-      '#suffix' => '</div>',
-    );
-    // Preview box.
-    $preview_url = Url::fromRoute('<front>', array(), array('absolute' => TRUE, 'query' => array('theme' => $theme)))->toString();
-    $form['css_editor']['css_preview'] = array(
-      '#type' => 'inline_template',
-      '#template' => '<iframe src="{{ url }}" id="css-editor-preview">' . t('Frames are not supported.') . '</iframe>',
-      '#context' => array(
-        'url' => $preview_url,
-      ),
-    );
-    // Attach CSS and Javascript libraries.
-    $form['#attached']['library'][] = 'css_editor/codemirror';
-    $form['#attached']['library'][] = 'css_editor/css_editor';
-    $form['#attached']['drupalSettings']['CSSEditor']['frontPage'] = $preview_url;
-    $form['#submit'][] = '_css_editor_theme_settings_form_submit';
-  }
-}
-
-/**
- * Form submission handler for hook_form_system_theme_settings_alter().
- */
-function _css_editor_theme_settings_form_submit($form, FormStateInterface $form_state) {
-  $theme = _css_editor_get_edited_theme($form_state);
-  if ($theme) {
-    // Save file.
-    $path = 'public://css_editor';
-    $file = $path . DIRECTORY_SEPARATOR . $theme . '.css';
-    if (file_prepare_directory($path, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) {
-      file_unmanaged_save_data($form_state->getValue('css'), $file, FILE_EXISTS_REPLACE);
-      drupal_chmod($file);
-    }
-    // Save settings.
-    \Drupal::configFactory()->getEditable('css_editor.theme.' . $theme)
-      ->set('enabled', $form_state->getValue('css_enabled'))
-      ->set('css', $form_state->getValue('css'))
-      ->set('path', $file)
-      ->save();
-    // Clear cache.
-    drupal_flush_all_caches();
-  }
-}
-
-/**
- * Form helper.
- */
-function _css_editor_get_edited_theme(FormStateInterface $form_state) {
-  // Return theme being currently edited.
-  $build_info = $form_state->getBuildInfo();
-  return isset($build_info['args'][0]) ? $build_info['args'][0] : FALSE;
-}
diff --git a/web/modules/css_editor/css_editor.services.yml b/web/modules/css_editor/css_editor.services.yml
deleted file mode 100644
index ac59848e4eafe0509bb4d3c2ccad3245356037a5..0000000000000000000000000000000000000000
--- a/web/modules/css_editor/css_editor.services.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-services:
-  theme.negotiator.css_editor:
-    class: Drupal\css_editor\Theme\CssEditorThemeNegotiator
-    tags:
-      - { name: theme_negotiator, priority: 100 }
diff --git a/web/modules/css_editor/js/css_editor.js b/web/modules/css_editor/js/css_editor.js
deleted file mode 100644
index bbbde7c1197600c2099b735d215a6b4b96c48537..0000000000000000000000000000000000000000
--- a/web/modules/css_editor/js/css_editor.js
+++ /dev/null
@@ -1,69 +0,0 @@
-/*jslint nomen: true, plusplus: true, todo: true, white: true, browser: true, indent: 2 */
-
-jQuery(function($) {
-  'use strict';
-
-  // Unobstrusive syntax highlighting
-  var $textarea = $('#css-editor-textarea');
-
-  var createEditor= function() {
-    var editor = CodeMirror.fromTextArea($textarea[0], { lineNumbers : true, extraKeys : {"Ctrl-Space": "autocomplete"} });
-    editor.on('change', function(obj) { autoPreview(); });
-    return editor;
-  };
-
-  var editor = createEditor();
-
-  $('div.CodeMirror').after('<input type="checkbox" id="css-editor-toggle-editor" /> <label for="css-editor-toggle-editor">' + Drupal.t('Use plain text editor') + '</label>');
-
-  $('#css-editor-toggle-editor').click(function() {
-    if ($(this).is(':checked')) {
-      editor.toTextArea();
-    }
-    else {
-      editor = createEditor();
-    }
-  });
-
-  // Preview
-  $('div.CodeMirror').after('<input type="checkbox" id="css-editor-toggle-preview" checked="checked" /> <label for="css-editor-toggle-preview">' + Drupal.t('Enable auto preview') + '</label>');
-  var $preview = $('#css-editor-preview');
-
-  $preview.before('<div id="css-editor-preview-path-wrapper"><label for="css-editor-preview-path">' + Drupal.t('Preview path:') + '</label> <input type="text" id="css-editor-preview-path" size="60" /></div>');
-  var $previewSettings = $('#css-editor-preview-path-wrapper');
-
-  $('#css-editor-toggle-preview').click(function() {
-    if ($(this).is(':checked')) {
-      $preview.show();
-      $previewSettings.show();
-      autoPreview();
-    }
-    else {
-      $preview.hide();
-      $previewSettings.hide();
-    }
-  });
-
-  $textarea.keyup(function() { autoPreview(); });
-
-  $preview.load(function() { autoPreview(); });
-
-  $('#css-editor-preview-path').blur(function() {
-    $preview.attr('src', drupalSettings.CSSEditor.frontPage.replace('?', '/' + $(this).val() + '?'));
-  });
-
-  var autoPreview = function() {
-    if ($('#css-editor-toggle-preview').is(':checked')) {
-      var value = ($('#css-editor-toggle-editor').is(':checked') ? $textarea.val() : editor.getValue());
-      var id = 'css-editor-preview-style';
-      var $css = $preview.contents().find('#' + id);
-      if ($css.length) {
-        $css.html(value);
-      }
-      else {
-        $preview.contents().find('head').append($('<style type="text/css" id="' + id + '">' + value + '</style>'));
-      }
-    }
-  };
-
-});
diff --git a/web/modules/css_editor/src/Theme/CssEditorThemeNegotiator.php b/web/modules/css_editor/src/Theme/CssEditorThemeNegotiator.php
deleted file mode 100644
index 5159e5ed509f37c06b9c86857ab911cc3a0654da..0000000000000000000000000000000000000000
--- a/web/modules/css_editor/src/Theme/CssEditorThemeNegotiator.php
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-
-namespace Drupal\css_editor\Theme;
-
-use Drupal\Core\Theme\ThemeNegotiatorInterface;
-use Drupal\Core\Routing\RouteMatchInterface;
-use Drupal\Core\Url;
-
-class CssEditorThemeNegotiator implements ThemeNegotiatorInterface {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function applies(RouteMatchInterface $route_match) {
-    return isset($_REQUEST['theme']) && isset($_SERVER['HTTP_REFERER']) &&
-      $_SERVER['HTTP_REFERER'] == Url::fromUri('internal:/admin/appearance/settings/' . $_REQUEST['theme'], array('absolute' => TRUE))->toString();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function determineActiveTheme(RouteMatchInterface $route_match) {
-    return $_REQUEST['theme'];
-  }
-
-}
diff --git a/web/modules/css_editor/LICENSE.txt b/web/modules/features/LICENSE.txt
similarity index 100%
rename from web/modules/css_editor/LICENSE.txt
rename to web/modules/features/LICENSE.txt
diff --git a/web/modules/features/LICENSE.txt~HEAD b/web/modules/features/LICENSE.txt~HEAD
deleted file mode 100644
index d159169d1050894d3ea3b98e1c965c4058208fe1..0000000000000000000000000000000000000000
--- a/web/modules/features/LICENSE.txt~HEAD
+++ /dev/null
@@ -1,339 +0,0 @@
-                    GNU GENERAL PUBLIC LICENSE
-                       Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-                            Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-                    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-                            NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-                     END OF TERMS AND CONDITIONS
-
-            How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) year name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  <signature of Ty Coon>, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
diff --git a/web/modules/features/LICENSE.txt~master b/web/modules/features/LICENSE.txt~master
deleted file mode 100644
index d159169d1050894d3ea3b98e1c965c4058208fe1..0000000000000000000000000000000000000000
--- a/web/modules/features/LICENSE.txt~master
+++ /dev/null
@@ -1,339 +0,0 @@
-                    GNU GENERAL PUBLIC LICENSE
-                       Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-                            Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-                    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-                            NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-                     END OF TERMS AND CONDITIONS
-
-            How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) year name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  <signature of Ty Coon>, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
diff --git a/web/modules/features/composer.json b/web/modules/features/composer.json
index 1b7a61d37bc790dc9a7cfe38858cb574588285b0..de7ea040a6df8a17e66567a5dd32ed2c07ab27a9 100644
--- a/web/modules/features/composer.json
+++ b/web/modules/features/composer.json
@@ -6,5 +6,12 @@
   "require": {
     "drupal/config_update": "^1.4"
   },
-  "type": "drupal-module"
+  "type": "drupal-module",
+  "extra": {
+    "drush": {
+      "services": {
+        "drush.services.yml": "^9"
+      }
+    }
+  }
 }
diff --git a/web/modules/features/drush/features.drush8.inc b/web/modules/features/drush/features.drush8.inc
index b4abe91f05224bead461dd95a63096ccf80121f6..35a76abe83d06ef5fd1977039756ab5f918b112e 100644
--- a/web/modules/features/drush/features.drush8.inc
+++ b/web/modules/features/drush/features.drush8.inc
@@ -6,6 +6,7 @@
  */
 
 use Drupal\features\ConfigurationItem;
+use Drupal\features\FeaturesBundleInterface;
 use Drupal\features\FeaturesManagerInterface;
 use Drupal\features\Plugin\FeaturesGeneration\FeaturesGenerationWrite;
 use Drupal\Component\Diff\DiffFormatter;
@@ -14,118 +15,118 @@
  * Implements hook_drush_command().
  */
 function features_drush_command() {
-  $items = array();
+  $items = [];
 
-  $items['features-status'] = array(
+  $items['features-status'] = [
     'description' => 'Display current Features settings.',
-    'aliases' => array('fs'),
-  );
+    'aliases' => ['fs'],
+  ];
 
-  $items['features-list-packages'] = array(
+  $items['features-list-packages'] = [
     'description' => 'Display a list of all existing features and packages available to be generated.  If a package name is provided as an argument, then all of the configuration objects assigned to that package will be listed.',
-    'examples' => array(
+    'examples' => [
       "drush features-list-packages" => 'Display a list of all existing featurea and packages available to be generated.',
       "drush features-list-packages 'example_article'" => "Display a list of all configuration objects assigned to the 'example_article' package.",
-    ),
-    'arguments' => array(
+    ],
+    'arguments' => [
       'package' => 'The package to list. Optional; if specified, lists all configuration objects assigned to that package. If no package is specified, lists all of the features.',
-    ),
-    'outputformat' => array(
+    ],
+    'outputformat' => [
       'default' => 'table',
       'pipe-format' => 'list',
-      'field-labels' => array(
+      'field-labels' => [
         'name' => 'Name',
         'machine_name' => 'Machine name',
         'status' => 'Status',
         'version' => 'Version',
         'state' => 'State',
         'object' => 'Configuration object',
-      ),
+      ],
       'output-data-type' => 'format-table',
-    ),
-    'aliases' => array('fl'),
-  );
+    ],
+    'aliases' => ['fl'],
+  ];
 
-  $items['features-import-all'] = array(
+  $items['features-import-all'] = [
     'description' => 'Import module config from all installed features.',
-    'examples' => array(
+    'examples' => [
       "drush features-import-all" => 'Import module config from all installed features.',
-    ),
-    'aliases' => array('fra', 'fia', 'fim-all'),
-  );
+    ],
+    'aliases' => ['fra', 'fia', 'fim-all'],
+  ];
 
-  $items['features-export'] = array(
+  $items['features-export'] = [
     'description' => "Export the configuration on your site into a custom module.",
-    'arguments' => array(
+    'arguments' => [
       'package' => 'A space delimited list of features to export.',
-    ),
-    'options' => array(
+    ],
+    'options' => [
       'add-profile' => 'Package features into an install profile.',
-    ),
-    'examples' => array(
+    ],
+    'examples' => [
       "drush features-export" => 'Export all available packages.',
       "drush features-export example_article example_page" => "Export the example_article and example_page packages.",
       "drush features-export --add-profile" => "Export all available packages and add them to an install profile.",
-    ),
+    ],
     // Add previous "fu" alias for compatibility.
-    'aliases' => array('fex', 'fu', 'fua', 'fu-all'),
-  );
+    'aliases' => ['fex', 'fu', 'fua', 'fu-all'],
+  ];
 
-  $items['features-add'] = array(
+  $items['features-add'] = [
     'description' => "Add a config item to a feature package.",
-    'arguments' => array(
+    'arguments' => [
       'feature' => 'Feature package to export and add config to.',
       'components' => 'Patterns of config to add, see features-components for the format of patterns.',
-    ),
-    'aliases' => array('fa', 'fe'),
-  );
+    ],
+    'aliases' => ['fa', 'fe'],
+  ];
 
-  $items['features-components'] = array(
+  $items['features-components'] = [
     'description' => 'List features components.',
-    'arguments' => array(
+    'arguments' => [
       'patterns' => 'The features components type to list. Omit this argument to list all components.',
-    ),
-    'options' => array(
-      'exported' => array(
+    ],
+    'options' => [
+      'exported' => [
         'description' => 'Show only components that have been exported.',
-      ),
-      'not-exported' => array(
+      ],
+      'not-exported' => [
         'description' => 'Show only components that have not been exported.',
-      ),
-    ),
-    'aliases' => array('fc'),
-  );
+      ],
+    ],
+    'aliases' => ['fc'],
+  ];
 
-  $items['features-diff'] = array(
+  $items['features-diff'] = [
     'description' => "Show the difference between the active config and the default config stored in a feature package.",
-    'arguments' => array(
+    'arguments' => [
       'feature' => 'The feature in question.',
-    ),
-    'options' => array(
+    ],
+    'options' => [
       'ctypes' => 'Comma separated list of component types to limit the output to. Defaults to all types.',
       'lines' => 'Generate diffs with <n> lines of context instead of the usual two.',
-    ),
-    'aliases' => array('fd'),
-  );
+    ],
+    'aliases' => ['fd'],
+  ];
 
-  $items['features-import'] = array(
+  $items['features-import'] = [
     'description' => "Import a module config into your site.",
-    'arguments' => array(
+    'arguments' => [
       'feature' => 'A space delimited list of features or feature:component pairs to import.',
-    ),
-    'options' => array(
+    ],
+    'options' => [
       'force' => "Force import even if config is not overridden.",
-    ),
-    'examples' => array(
+    ],
+    'examples' => [
       'drush features-import foo:node.type.page foo:taxonomy.vocabulary.tags bar' => 'Import node and taxonomy config of feature "foo". Import all config of feature "bar".',
-    ),
-    'aliases' => array('fim', 'fr'),
-  );
+    ],
+    'aliases' => ['fim', 'fr'],
+  ];
 
   foreach ($items as $name => &$item) {
-    $item['options']['bundle'] = array(
+    $item['options']['bundle'] = [
       'description' => 'Use a specific bundle namespace.',
-    );
+    ];
   }
 
   return $items;
@@ -145,7 +146,7 @@ function _drush_features_options() {
   if (!empty($bundle_name)) {
     $bundle = $assigner->applyBundle($bundle_name);
     if ($bundle->getMachineName() != $bundle_name) {
-      drush_log(dt('Bundle @name not found. Using default.', array('@name' => $bundle_name)), 'warning');
+      drush_log(dt('Bundle @name not found. Using default.', ['@name' => $bundle_name]), 'warning');
     }
   }
   else {
@@ -172,13 +173,13 @@ function drush_features_status() {
   }
   else {
     drush_print(dt('Current bundle: @name (@machine_name)',
-      array(
+      [
         '@name' => $current_bundle->getName(),
         '@machine_name' => $current_bundle->getMachineName(),
-      )));
+      ]));
   }
-  drush_print(dt('Export folder: @folder', array('@folder' => $export_settings['folder'])));
-  $dt_args = array('@methods' => implode(', ', array_keys($methods)));
+  drush_print(dt('Export folder: @folder', ['@folder' => $export_settings['folder']]));
+  $dt_args = ['@methods' => implode(', ', array_keys($methods))];
   drush_print(dt('The following assignment methods are enabled:'));
   drush_print(dt('  @methods', $dt_args));
 
@@ -204,18 +205,18 @@ function drush_features_status() {
 function drush_features_list_packages($package_name = '') {
   $assigner = _drush_features_options();
   $current_bundle = $assigner->getBundle();
-  $namespace = $current_bundle->isDefault() ? '' : $current_bundle->getMachineName();
+  $namespace = $current_bundle->isDefault() ? FeaturesBundleInterface::DEFAULT_BUNDLE : $current_bundle->getMachineName();
 
   /** @var \Drupal\features\FeaturesManagerInterface $manager */
   $manager = \Drupal::service('features.manager');
   $packages = $manager->getPackages();
 
   $packages = $manager->filterPackages($packages, $namespace);
-  $result = array();
+  $result = [];
 
   // If no package was specified, list all packages.
   if (empty($package_name)) {
-    drush_hide_output_fields(array('object'));
+    drush_hide_output_fields(['object']);
     foreach ($packages as $package) {
       $overrides = $manager->detectOverrides($package);
       $state = $package->getState();
@@ -223,7 +224,7 @@ function drush_features_list_packages($package_name = '') {
         $state = FeaturesManagerInterface::STATE_OVERRIDDEN;
       }
 
-      $result[$package->getMachineName()] = array(
+      $result[$package->getMachineName()] = [
         'name' => $package->getName(),
         'machine_name' => $package->getMachineName(),
         'status' => $manager->statusLabel($package->getStatus()),
@@ -231,7 +232,7 @@ function drush_features_list_packages($package_name = '') {
         'state' => ($state != FeaturesManagerInterface::STATE_DEFAULT)
           ? $manager->stateLabel($state)
           : '',
-      );
+      ];
     }
     return $result;
   }
@@ -239,17 +240,17 @@ function drush_features_list_packages($package_name = '') {
   else {
     foreach ($packages as $package) {
       if ($package->getMachineName() == $package_name) {
-        drush_hide_output_fields(array(
+        drush_hide_output_fields([
           'machine_name',
           'name',
           'status',
           'version',
           'state',
-        ));
+        ]);
         foreach ($package->getConfig() as $item_name) {
-          $result[$item_name] = array(
+          $result[$item_name] = [
             'object' => $item_name,
-          );
+          ];
         }
         return $result;
       }
@@ -258,7 +259,7 @@ function drush_features_list_packages($package_name = '') {
   }
 
   // If no matching package found, return an error.
-  drush_log(dt('Package "@package" not found.', array('@package' => $package_name)), 'warning');
+  drush_log(dt('Package "@package" not found.', ['@package' => $package_name]), 'warning');
   return FALSE;
 }
 
@@ -269,13 +270,13 @@ function drush_features_list_packages($package_name = '') {
 function drush_features_import_all() {
   $assigner = _drush_features_options();
   $current_bundle = $assigner->getBundle();
-  $namespace = $current_bundle->isDefault() ? '' : $current_bundle->getMachineName();
+  $namespace = $current_bundle->isDefault() ? FeaturesBundleInterface::DEFAULT_BUNDLE : $current_bundle->getMachineName();
 
   /** @var \Drupal\features\FeaturesManagerInterface $manager */
   $manager = \Drupal::service('features.manager');
   $packages = $manager->getPackages();
   $packages = $manager->filterPackages($packages, $namespace);
-  $overridden = array();
+  $overridden = [];
 
   foreach ($packages as $package) {
     $overrides = $manager->detectOverrides($package);
@@ -317,13 +318,13 @@ function drush_features_export($packages = NULL) {
   $all_packages = $manager->getPackages();
   foreach ($packages as $name) {
     if (!isset($all_packages[$name])) {
-      return drush_set_error('', dt("The package @name does not exist.", array('@name' => $name)));
+      return drush_set_error('', dt("The package @name does not exist.", ['@name' => $name]));
     }
   }
 
   if (empty($packages)) {
     $packages = $all_packages;
-    $dt_args = array('@modules' => implode(', ', array_keys($packages)));
+    $dt_args = ['@modules' => implode(', ', array_keys($packages))];
     drush_print(dt('The following extensions will be exported: @modules', $dt_args));
     if (!drush_confirm(dt('Do you really want to continue?'))) {
       return drush_user_abort('Aborting.');
@@ -333,7 +334,7 @@ function drush_features_export($packages = NULL) {
   // If any packages exist, confirm before overwriting.
   if ($existing_packages = $manager->listPackageDirectories($packages, $current_bundle)) {
     foreach ($existing_packages as $name => $directory) {
-      drush_print(dt("The extension @name already exists at @directory.", array('@name' => $name, '@directory' => $directory)));
+      drush_print(dt("The extension @name already exists at @directory.", ['@name' => $name, '@directory' => $directory]));
     }
     // Apparently, format_plural is not always available.
     if (count($existing_packages) == 1) {
@@ -379,9 +380,9 @@ function drush_features_add() {
       return drush_set_error('', 'No components supplied.');
     }
     $components = _drush_features_component_list();
-    $options = array(
+    $options = [
       'exported' => FALSE,
-    );
+    ];
 
     $filtered_components = _drush_features_component_filter($components, $args, $options);
     $items = $filtered_components['components'];
@@ -390,11 +391,11 @@ function drush_features_add() {
       return drush_set_error('', 'No components to add.');
     }
 
-    $packages = array($module);
+    $packages = [$module];
     // If any packages exist, confirm before overwriting.
     if ($existing_packages = $manager->listPackageDirectories($packages)) {
       foreach ($existing_packages as $name => $directory) {
-        drush_print(dt("The extension @name already exists at @directory.", array('@name' => $name, '@directory' => $directory)));
+        drush_print(dt("The extension @name already exists at @directory.", ['@name' => $name, '@directory' => $directory]));
       }
       // Apparently, format_plural is not always available.
       if (count($existing_packages) == 1) {
@@ -410,7 +411,7 @@ function drush_features_add() {
     else {
       $package = $manager->initPackage($module, NULL, '', 'module', $current_bundle);
       list($full_name, $path) = $manager->getExportInfo($package, $current_bundle);
-      drush_print(dt('Will create a new extension @name in @directory', array('@name' => $full_name, '@directory' => $path)));
+      drush_print(dt('Will create a new extension @name in @directory', ['@name' => $full_name, '@directory' => $path]));
       if (!drush_confirm(dt('Do you really want to continue?'))) {
         drush_die('Aborting.');
       }
@@ -452,15 +453,15 @@ function drush_features_components() {
       return;
     }
 
-    $args = ($choice == 0) ? array('*') : array($types[$choice]);
+    $args = ($choice == 0) ? ['*'] : [$types[$choice]];
   }
-  $options = array(
+  $options = [
     'provided by' => TRUE,
-  );
-  if (drush_get_option(array('exported', 'e'), NULL)) {
+  ];
+  if (drush_get_option(['exported', 'e'], NULL)) {
     $options['not exported'] = FALSE;
   }
-  elseif (drush_get_option(array('not-exported', 'o'), NULL)) {
+  elseif (drush_get_option(['not-exported', 'o'], NULL)) {
     $options['exported'] = FALSE;
   }
 
@@ -496,7 +497,7 @@ function drush_features_diff() {
 
   $feature = $manager->loadPackage($module, TRUE);
   if (empty($feature)) {
-    drush_log(dt('No such feature is available: @module', array('@module' => $module)), 'error');
+    drush_log(dt('No such feature is available: @module', ['@module' => $module]), 'error');
     return;
   }
 
@@ -521,7 +522,7 @@ function drush_features_diff() {
   $overrides = array_merge($overrides, $missing);
 
   if (empty($overrides)) {
-    drush_print(dt('Active config matches stored config for @module.', array('@module' => $module)));
+    drush_print(dt('Active config matches stored config for @module.', ['@module' => $module]));
   }
   else {
     /** @var \Drupal\config_update\ConfigDiffInterface $config_diff */
@@ -538,20 +539,20 @@ function drush_features_diff() {
       $message = '';
       if (in_array($name, $missing)) {
         $message = sprintf($red, t('(missing from active)'));
-        $extension = array();
+        $extension = [];
       }
       else {
         $active = $manager->getActiveStorage()->read($name);
         $extension = $manager->getExtensionStorages()->read($name);
         if (empty($extension)) {
-          $extension = array();
+          $extension = [];
           $message = sprintf($green, t('(not exported)'));
         }
         $diff = $config_diff->diff($extension, $active);
         $rows = explode("\n", $formatter->format($diff));
       }
       drush_print();
-      drush_print(dt("Config @name @message", array('@name' => $name, '@message' => $message)));
+      drush_print(dt("Config @name @message", ['@name' => $name, '@message' => $message]));
       if (!empty($extension)) {
         foreach ($rows as $row) {
           if (strpos($row, '>') === 0) {
@@ -588,7 +589,7 @@ function drush_features_import() {
     $manager = \Drupal::service('features.manager');
 
     // Parse list of arguments.
-    $modules = array();
+    $modules = [];
     foreach ($args as $arg) {
       $arg = explode(':', $arg);
       $module = array_shift($arg);
@@ -602,7 +603,7 @@ function drush_features_import() {
         }
         elseif ($modules[$module] !== TRUE) {
           if (!isset($modules[$module])) {
-            $modules[$module] = array();
+            $modules[$module] = [];
           }
           $modules[$module][] = $component;
         }
@@ -692,7 +693,7 @@ function drush_features_import() {
 function _drush_features_build_config(array $items) {
   /** @var \Drupal\features\FeaturesManagerInterface $manager */
   $manager = \Drupal::service('features.manager');
-  $result = array();
+  $result = [];
   foreach ($items as $config_type => $item) {
     foreach ($item as $item_name => $title) {
       $result[] = $manager->getFullName($config_type, $item_name);
@@ -705,7 +706,7 @@ function _drush_features_build_config(array $items) {
  * Returns a listing of all known components, indexed by source.
  */
 function _drush_features_component_list() {
-  $result = array();
+  $result = [];
   /** @var \Drupal\features\FeaturesManagerInterface $manager */
   $manager = \Drupal::service('features.manager');
   $config = $manager->getConfigCollection();
@@ -718,13 +719,13 @@ function _drush_features_component_list() {
 /**
  * Filters components by patterns.
  */
-function _drush_features_component_filter($all_components, $patterns = array(), $options = array()) {
-  $options += array(
+function _drush_features_component_filter($all_components, $patterns = [], $options = []) {
+  $options += [
     'exported' => TRUE,
     'not exported' => TRUE,
     'provided by' => FALSE,
-  );
-  $pool = array();
+  ];
+  $pool = [];
   // Maps exported components to feature modules.
   $components_map = _drush_features_get_component_map();
   // First filter on exported state.
@@ -753,11 +754,11 @@ function _drush_features_component_filter($all_components, $patterns = array(),
     $state_string = 'exported';
   }
 
-  $selected = array();
+  $selected = [];
   foreach ($patterns as $pattern) {
     // Rewrite * to %. Let users use both as wildcard.
-    $pattern = strtr($pattern, array('*' => '%'));
-    $sources = array();
+    $pattern = strtr($pattern, ['*' => '%']);
+    $sources = [];
     list($source_pattern, $component_pattern) = explode(':', $pattern, 2);
     // If source is empty, use a pattern.
     if ($source_pattern == '') {
@@ -767,8 +768,8 @@ function _drush_features_component_filter($all_components, $patterns = array(),
       $component_pattern = '%';
     }
 
-    $preg_source_pattern = strtr(preg_quote($source_pattern, '/'), array('%' => '.*'));
-    $preg_component_pattern = strtr(preg_quote($component_pattern, '/'), array('%' => '.*'));
+    $preg_source_pattern = strtr(preg_quote($source_pattern, '/'), ['%' => '.*']);
+    $preg_component_pattern = strtr(preg_quote($component_pattern, '/'), ['%' => '.*']);
     // If it isn't a pattern, but a simple string, we don't anchor the
     // pattern. This allows for abbreviating. Otherwise, we do, as this seems
     // more natural for patterns.
@@ -778,7 +779,7 @@ function _drush_features_component_filter($all_components, $patterns = array(),
     if (strpos($component_pattern, '%') !== FALSE) {
       $preg_component_pattern = '^' . $preg_component_pattern . '$';
     }
-    $matches = array();
+    $matches = [];
 
     // Find the sources.
     $all_sources = array_keys($pool);
@@ -789,20 +790,20 @@ function _drush_features_component_filter($all_components, $patterns = array(),
       // use that, or error out.
       if (count($matches) > 1 and $preg_source_pattern[0] != '^') {
         if (in_array($source_pattern, $matches)) {
-          $matches = array($source_pattern);
+          $matches = [$source_pattern];
         }
         else {
-          return drush_set_error('', dt('Ambiguous source "@source", matches @matches', array(
+          return drush_set_error('', dt('Ambiguous source "@source", matches @matches', [
             '@source' => $source_pattern,
             '@matches' => implode(', ', $matches),
-          )));
+          ]));
         }
       }
       // Loose the indexes preg_grep preserved.
       $sources = array_values($matches);
     }
     else {
-      return drush_set_error('', dt('No @state sources match "@source"', array('@state' => $state_string, '@source' => $source_pattern)));
+      return drush_set_error('', dt('No @state sources match "@source"', ['@state' => $state_string, '@source' => $source_pattern]));
     }
 
     // Now find the components.
@@ -817,17 +818,17 @@ function _drush_features_component_filter($all_components, $patterns = array(),
         // use that, or error out.
         if (count($matches) > 1 and $preg_component_pattern[0] != '^') {
           if (in_array($component_pattern, $matches)) {
-            $matches = array($component_pattern);
+            $matches = [$component_pattern];
           }
           else {
-            return drush_set_error('', dt('Ambiguous component "@component", matches @matches', array(
+            return drush_set_error('', dt('Ambiguous component "@component", matches @matches', [
               '@component' => $component_pattern,
               '@matches' => implode(', ', $matches),
-            )));
+            ]));
           }
         }
         if (!is_array($selected[$source])) {
-          $selected[$source] = array();
+          $selected[$source] = [];
         }
         $selected[$source] += array_intersect_key($pool[$source], array_flip($matches));
       }
@@ -835,11 +836,11 @@ function _drush_features_component_filter($all_components, $patterns = array(),
         // No matches. If the source was a pattern, just carry on, else
         // error out. Allows for patterns like :*field*
         if ($preg_source_pattern[0] != '^') {
-          return drush_set_error('', dt('No @state @source components match "@component"', array(
+          return drush_set_error('', dt('No @state @source components match "@component"', [
             '@state' => $state_string,
             '@component' => $component_pattern,
             '@source' => $source,
-          )));
+          ]));
         }
       }
     }
@@ -847,7 +848,7 @@ function _drush_features_component_filter($all_components, $patterns = array(),
 
   // Lastly, provide feature module information on the selected components, if
   // requested.
-  $provided_by = array();
+  $provided_by = [];
   if ($options['provided by'] && $options['exported']) {
     foreach ($selected as $source => $components) {
       foreach ($components as $name => $title) {
@@ -859,17 +860,17 @@ function _drush_features_component_filter($all_components, $patterns = array(),
     }
   }
 
-  return array(
+  return [
     'components' => $selected,
     'sources' => $provided_by,
-  );
+  ];
 }
 
 /**
  * Provides a component to feature map (port of features_get_component_map).
  */
 function _drush_features_get_component_map() {
-  $result = array();
+  $result = [];
   /** @var \Drupal\features\FeaturesManagerInterface $manager */
   $manager = \Drupal::service('features.manager');
   // Recalc full config list without running assignments.
@@ -881,7 +882,7 @@ function _drush_features_get_component_map() {
     $short_name = $item->getShortName();
     $name = $item->getName();
     if (!isset($result[$type][$short_name])) {
-      $result[$type][$short_name] = array();
+      $result[$type][$short_name] = [];
     }
     if (!empty($item->getPackage())) {
       $package = $packages[$item->getPackage()];
@@ -896,10 +897,10 @@ function _drush_features_get_component_map() {
  * Prints a list of filtered components.
  */
 function _drush_features_component_print($filtered_components) {
-  $rows = array(array(dt('Available sources')));
+  $rows = [[dt('Available sources')]];
   foreach ($filtered_components['components'] as $source => $components) {
     foreach ($components as $name => $value) {
-      $row = array($source . ':' . $name);
+      $row = [$source . ':' . $name];
       if (isset($filtered_components['sources'][$source . ':' . $name])) {
         $row[] = dt('Provided by') . ': ' . $filtered_components['sources'][$source . ':' . $name];
       }
diff --git a/web/modules/features/features.info.yml b/web/modules/features/features.info.yml
index 197574cbd5c81e739a5b72b7c08294d4f121270d..65cef8a96ca2a5d8231519bbe1f16df1b6c575d9 100644
--- a/web/modules/features/features.info.yml
+++ b/web/modules/features/features.info.yml
@@ -4,11 +4,11 @@ description: 'Enables administrators to package configuration into modules.'
 package: Development
 # core: 8.x
 dependencies:
-  - config
-  - config_update
+  - drupal:config
+  - config_update:config_update
 
-# Information added by Drupal.org packaging script on 2018-02-27
-version: '8.x-3.7'
+# Information added by Drupal.org packaging script on 2018-09-09
+version: '8.x-3.8'
 core: '8.x'
 project: 'features'
-datestamp: 1519763291
+datestamp: 1536512288
diff --git a/web/modules/features/features.module b/web/modules/features/features.module
index 3fccc79c4daf9d73a904031a9b4232adf418e472..3bf4bf7348140c450ca6243d8c2ad6919d5dbdce 100644
--- a/web/modules/features/features.module
+++ b/web/modules/features/features.module
@@ -15,9 +15,9 @@ function features_help($route_name, RouteMatchInterface $route_match) {
     case 'help.page.features':
       $output = '';
       $output .= '<h3>' . t('About') . '</h3>';
-      $output .= '<p>' . t('The Features module provides a user interface for exporting bundles of configuration into modules. For more information, see the online documentation for <a href=":url">Features module</a>', array(
+      $output .= '<p>' . t('The Features module provides a user interface for exporting bundles of configuration into modules. For more information, see the online documentation for <a href=":url">Features module</a>', [
         ':url' => 'http://drupal.org/node/2404427',
-      )) . '</p>';
+      ]) . '</p>';
       return $output;
   }
 }
@@ -37,9 +37,9 @@ function features_file_download($uri) {
     // "export configuration" permission, token is validated by the controller.
     // @see \Drupal\features\Controller\FeaturesController::downloadExport()
     if ($route == 'features.export_download') {
-      return array(
+      return [
         'Content-disposition' => 'attachment; filename="' . $target . '"',
-      );
+      ];
     }
   }
 }
diff --git a/web/modules/features/modules/features_ui/css/features_ui.admin.css b/web/modules/features/modules/features_ui/css/features_ui.admin.css
index 529a7aa85135a9ffc8fc2bf3aa6451f381f536ae..1f8a7817893f8f97aa3549c615537cdd729427f1 100644
--- a/web/modules/features/modules/features_ui/css/features_ui.admin.css
+++ b/web/modules/features/modules/features_ui/css/features_ui.admin.css
@@ -143,8 +143,7 @@ span.features-component-list span {
   margin-right:5px;
   padding:2px 5px;
   background:#eee;
-  -moz-border-radius:5px;
-  -webkit-border-radius:5px;
+  border-radius:5px;
 }
 
 div.features-export-empty {
@@ -172,8 +171,7 @@ span.features-component-list .features-dependency {
   display: inline-block;
   background: transparent;
   border: 1px solid #DDD;
-  -moz-border-radius: 5px;
-  -webkit-border-radius: 5px;
+  border-radius: 5px;
   white-space: nowrap;
   padding: 0 8px;
   margin: 0 10px 0 0;
@@ -238,8 +236,7 @@ span.features-component-list .features-dependency {
   padding: 0 5px;
   background: transparent;
   background: #EEE;
-  -moz-border-radius: 5px;
-  -webkit-border-radius: 5px;
+  border-radius: 5px;
   cursor: pointer;
 }
 #features-filter span:hover {
diff --git a/web/modules/features/modules/features_ui/features_ui.admin.inc b/web/modules/features/modules/features_ui/features_ui.admin.inc
index 408410ac9b8af4bda1f0ff18655fe4dacb3eca54..0b7186252e680d6a63a895d434909dfb6564f3e3 100644
--- a/web/modules/features/modules/features_ui/features_ui.admin.inc
+++ b/web/modules/features/modules/features_ui/features_ui.admin.inc
@@ -23,60 +23,60 @@ function theme_features_listing(array $variables) {
   $renderer = \Drupal::service('renderer');
 
   // Individual table headers.
-  $rows = array();
+  $rows = [];
   // Iterate through all the features, which are children of this element.
   foreach (Element::children($form) as $key) {
     // Stick the key into $module for easier access.
     $element = $form[$key];
     // Create the row for the table.
-    $row = array();
+    $row = [];
     // Add the checkbox into the first cell.
     unset($element['enable']['#title']);
 
-    $row[] = array('class' => array('checkbox'), 'data' => $renderer->render($element['enable']));
+    $row[] = ['class' => ['checkbox'], 'data' => $renderer->render($element['enable'])];
 
     // Add the module label and expand/collapse functionalty.
     $id = Html::getUniqueId('feature-' . $key);
     $col2 = new FormattableMarkup('<label id="@id" for="@for" class="module-name table-filter-text-source">@name</label>',
-      array(
+      [
         '@id' => $id,
         '@for' => $element['enable']['#id'],
         '@name' => $renderer->render($element['name']),
-      )
+      ]
     );
-    $row[] = array('class' => array('module'), 'data' => $col2);
+    $row[] = ['class' => ['module'], 'data' => $col2];
 
-    $row[] = array('class' => array('machine_name'), 'data' => $renderer->render($element['machine_name']));
+    $row[] = ['class' => ['machine_name'], 'data' => $renderer->render($element['machine_name'])];
 
-    $description = t('@details', array('@details' => $renderer->render($element['details'])));
-    $details = array(
+    $description = t('@details', ['@details' => $renderer->render($element['details'])]);
+    $details = [
       '#type' => 'details',
-      '#title' => new FormattableMarkup('<span class="text">@desc</span>', array( '@desc' => $renderer->render($element['description']))),
-      '#attributes' => array('id' => $element['enable']['#id'] . '-description'),
+      '#title' => new FormattableMarkup('<span class="text">@desc</span>', [ '@desc' => $renderer->render($element['description'])]),
+      '#attributes' => ['id' => $element['enable']['#id'] . '-description'],
       '#description' => $description,
-    );
-    $row[] = array(
-      'class' => array('description', 'expand'),
+    ];
+    $row[] = [
+      'class' => ['description', 'expand'],
       'data' => $renderer->render($details),
-    );
-    $row[] = array(
-      'class' => array('feature-version'),
+    ];
+    $row[] = [
+      'class' => ['feature-version'],
       'data' => $renderer->render($element['version']),
-    );
-    $row[] = array(
-      'class' => array('feature-state'),
+    ];
+    $row[] = [
+      'class' => ['feature-state'],
       'data' => $renderer->render($element['state']),
-    );
+    ];
 
-    $rows[] = array('data' => $row);
+    $rows[] = ['data' => $row];
   }
 
-  $table = array(
+  $table = [
     '#type' => 'tableselect',
     '#header' => $form['#header'],
     '#options' => $rows,
     '#empty' => t('No Features packages available.'),
-  );
+  ];
   return $renderer->render($table);
 }
 
@@ -90,31 +90,31 @@ function theme_features_listing(array $variables) {
 function template_preprocess_features_assignment_configure_form(&$variables) {
   $form =& $variables['form'];
 
-  $header = array(
+  $header = [
     t('Assignment method'),
     t('Description'),
     t('Enabled'),
     t('Weight'),
-  );
+  ];
 
   // If there is at least one operation enabled, show the operation column.
   if ($form['#show_operations']) {
     $header[] = t('Operations');
   }
 
-  $table = array(
+  $table = [
     '#type' => 'table',
     '#weight' => 5,
     '#header' => $header,
-    '#attributes' => array('id' => 'features-assignment-methods'),
-    '#tabledrag' => array(
-      array(
+    '#attributes' => ['id' => 'features-assignment-methods'],
+    '#tabledrag' => [
+      [
         'action' => 'order',
         'relationship' => 'sibling',
         'group' => 'assignment-method-weight',
-      ),
-    ),
-  );
+      ],
+    ],
+  ];
 
   foreach ($form['title'] as $id => $element) {
     // Do not take form control structures.
@@ -122,11 +122,11 @@ function template_preprocess_features_assignment_configure_form(&$variables) {
       $table[$id]['#attributes']['class'][] = 'draggable';
       $table[$id]['#weight'] = $element['#weight'];
 
-      $table[$id]['title'] = array(
+      $table[$id]['title'] = [
         '#prefix' => '<strong>',
         $form['title'][$id],
         '#suffix' => '</strong>',
-      );
+      ];
       $table[$id]['description'] = $form['description'][$id];
       $table[$id]['enabled'] = $form['enabled'][$id];
       $table[$id]['weight'] = $form['weight'][$id];
@@ -157,7 +157,7 @@ function template_preprocess_features_assignment_configure_form(&$variables) {
 function theme_features_items(array $variables) {
   $items = $variables['items'];
 
-  $list = array();
+  $list = [];
   foreach ($items as $item) {
     $class = !empty($item['class']) ? $item['class'] : '';
     $list[] = '<span class="features-item ' . $class . '" title="' . $item['name'] . '">' . $item['label'] . '</span>';
diff --git a/web/modules/features/modules/features_ui/features_ui.info.yml b/web/modules/features/modules/features_ui/features_ui.info.yml
index a5d3cbd89cf2de7f8e4c663ccd5251e8321ee755..d78b3f7722622573240acda9f88a4cf7c2261b52 100644
--- a/web/modules/features/modules/features_ui/features_ui.info.yml
+++ b/web/modules/features/modules/features_ui/features_ui.info.yml
@@ -5,10 +5,10 @@ package: Development
 # core: 8.x
 configure: features.assignment
 dependencies:
-  - features
+  - features:features
 
-# Information added by Drupal.org packaging script on 2018-02-27
-version: '8.x-3.7'
+# Information added by Drupal.org packaging script on 2018-09-09
+version: '8.x-3.8'
 core: '8.x'
 project: 'features'
-datestamp: 1519763291
+datestamp: 1536512288
diff --git a/web/modules/features/modules/features_ui/features_ui.module b/web/modules/features/modules/features_ui/features_ui.module
index 0eae3ee0ae70a08e96130a6cbf1a6d22b3a68974..1860427bd40ff4d4fec4eb13948f6fb30e7e29a2 100644
--- a/web/modules/features/modules/features_ui/features_ui.module
+++ b/web/modules/features/modules/features_ui/features_ui.module
@@ -14,10 +14,10 @@ function features_ui_help($route_name, RouteMatchInterface $route_match) {
   switch ($route_name) {
     case 'features.assignment':
       $output = '';
-      $output .= '<p>' . t('Bundles are used to collect together groups of features. A bundle provides a shared <a href=":namespace">namespace</a> for all features included in it, which prevents conflicts and helps distinguish your features from those produced for other purposes. Common uses of bundles include:', array(':namespace' => 'http://en.wikipedia.org/wiki/Namespace'));
+      $output .= '<p>' . t('Bundles are used to collect together groups of features. A bundle provides a shared <a href=":namespace">namespace</a> for all features included in it, which prevents conflicts and helps distinguish your features from those produced for other purposes. Common uses of bundles include:', [':namespace' => 'http://en.wikipedia.org/wiki/Namespace']);
       $output .= '<ul>';
       $output .= '<li>' . t('Custom features for use on a particular site.') . '</li>';
-      $output .= '<li>' . t('The features of a given <a href=":distributions">distribution</a>.', array(':distributions' => 'https://www.drupal.org/documentation/build/distributions')) . '</li>';
+      $output .= '<li>' . t('The features of a given <a href=":distributions">distribution</a>.', [':distributions' => 'https://www.drupal.org/documentation/build/distributions']) . '</li>';
       $output .= '</ul></p>';
       $output .= '<p>' . t('Use the form below to manage bundles. Each bundle comes with a set of assignment methods. By configuring and ordering the assignment methods, you can set the defaults for what does and doesn\'t get packaged into features for your bundle. Use the <em>Bundle</em> select to choose which bundle to edit, or chose <em>--New--</em> to create a new bundle. The <em>Default</em> bundle does not include a namespace and cannot be deleted.') . '</p>';
       return $output;
@@ -33,23 +33,23 @@ function features_ui_help($route_name, RouteMatchInterface $route_match) {
  * Implements hook_theme().
  */
 function features_ui_theme() {
-  return array(
-    'features_listing' => array(
+  return [
+    'features_listing' => [
       'render element' => 'form',
       'file' => 'features_ui.admin.inc',
       'function' => 'theme_features_listing',
-    ),
-    'features_assignment_configure_form' => array(
+    ],
+    'features_assignment_configure_form' => [
       'render element' => 'form',
       'file' => 'features_ui.admin.inc',
       'function' => 'theme_assignment_form',
-    ),
-    'features_items' => array(
-      'variables' => array(
-        'items' => array(),
-      ),
+    ],
+    'features_items' => [
+      'variables' => [
+        'items' => [],
+      ],
       'file' => 'features_ui.admin.inc',
       'function' => 'theme_features_items',
-    ),
-  );
+    ],
+  ];
 }
diff --git a/web/modules/features/modules/features_ui/src/Controller/FeaturesUIController.php b/web/modules/features/modules/features_ui/src/Controller/FeaturesUIController.php
index 1462b499a6c8dfe06b3d60e6fa634c1da8c8eade..786a51cd05de6b5f25adbab112823841e068e853 100644
--- a/web/modules/features/modules/features_ui/src/Controller/FeaturesUIController.php
+++ b/web/modules/features/modules/features_ui/src/Controller/FeaturesUIController.php
@@ -58,14 +58,14 @@ public static function create(ContainerInterface $container) {
    *   List of auto-detected config items, keyed by type and short name.
    */
   public function detect($name) {
-    $detected = array();
+    $detected = [];
     $this->assigner->assignConfigPackages();
     $config_collection = $this->featuresManager->getConfigCollection();
 
     $items = $_POST['items'];
     if (!empty($items)) {
-      $excluded = (!empty($_POST['excluded'])) ? $_POST['excluded'] : array();
-      $selected = array();
+      $excluded = (!empty($_POST['excluded'])) ? $_POST['excluded'] : [];
+      $selected = [];
       foreach ($items as $key) {
         preg_match('/^([^\[]+)(\[.+\])?\[(.+)\]\[(.+)\]$/', $key, $matches);
         if (!empty($matches[1]) && !empty($matches[4])) {
@@ -76,7 +76,7 @@ public function detect($name) {
           }
         }
       }
-      $detected = !empty($selected) ? $this->getConfigDependents($selected, $name) : array();
+      $detected = !empty($selected) ? $this->getConfigDependents($selected, $name) : [];
       $detected = array_merge($detected, $selected);
     }
 
@@ -112,7 +112,7 @@ protected function getConfigDependents(array $item_names, $package_name) {
 
     // Add any existing auto-detected items already in the package config
     $this->package = $packages[$package_name];
-    $package_config = isset($this->package) ? $this->package->getConfig() : array();
+    $package_config = isset($this->package) ? $this->package->getConfig() : [];
     $package_config = !empty($package_config) ? array_unique(array_merge($package_config, $item_names)) : $item_names;
     foreach ($package_config as $config_name) {
       if (!$config_collection[$config_name]->getPackageExcluded()) {
@@ -177,7 +177,7 @@ protected function domDecode($key) {
    *   An encoding map.
    */
   protected function domEncodeMap() {
-    return array(
+    return [
       ':' => '__' . ord(':') . '__',
       '/' => '__' . ord('/') . '__',
       ',' => '__' . ord(',') . '__',
@@ -187,7 +187,7 @@ protected function domEncodeMap() {
       '%' => '__' . ord('%') . '__',
       ')' => '__' . ord(')') . '__',
       '(' => '__' . ord('(') . '__',
-    );
+    ];
   }
 
 }
diff --git a/web/modules/features/modules/features_ui/src/Form/AssignmentAlterForm.php b/web/modules/features/modules/features_ui/src/Form/AssignmentAlterForm.php
index a29963358e7cca1f5bafb18f3fbcd31d74e7592e..462ee0ba5fb62d71d61625346e675e87644f3d4f 100644
--- a/web/modules/features/modules/features_ui/src/Form/AssignmentAlterForm.php
+++ b/web/modules/features/modules/features_ui/src/Form/AssignmentAlterForm.php
@@ -29,26 +29,26 @@ public function buildForm(array $form, FormStateInterface $form_state, $bundle_n
     $uuid_setting = $settings['uuid'];
     $user_permissions_setting = $settings['user_permissions'];
 
-    $form['core'] = array(
+    $form['core'] = [
       '#type' => 'checkbox',
       '#title' => $this->t('Strip out <em>_core</em> property.'),
       '#default_value' => $core_setting,
       '#description' => $this->t('Select this option to remove the <em>_core</em> configuration property on export. This property is added by Drupal core when configuration is installed.'),
-    );
+    ];
 
-    $form['uuid'] = array(
+    $form['uuid'] = [
       '#type' => 'checkbox',
       '#title' => $this->t('Strip out <em>uuid</em> property.'),
       '#default_value' => $uuid_setting,
       '#description' => $this->t('Select this option to remove the <em>uuid</em> configuration property on export. This property is added by Drupal core when configuration is installed.'),
-    );
+    ];
 
-    $form['user_permissions'] = array(
+    $form['user_permissions'] = [
       '#type' => 'checkbox',
       '#title' => $this->t('Strip out user permissions.'),
       '#default_value' => $user_permissions_setting,
       '#description' => $this->t('Select this option to remove permissions from user roles on export.'),
-    );
+    ];
 
     $this->setActions($form, self::METHOD_ID);
 
diff --git a/web/modules/features/modules/features_ui/src/Form/AssignmentConfigureForm.php b/web/modules/features/modules/features_ui/src/Form/AssignmentConfigureForm.php
index e46862d4453899b1decd0269bdd98863ba0d3be8..44630827522560299cd53cafe80dd57bbd1c4ca1 100644
--- a/web/modules/features/modules/features_ui/src/Form/AssignmentConfigureForm.php
+++ b/web/modules/features/modules/features_ui/src/Form/AssignmentConfigureForm.php
@@ -132,7 +132,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $bundle_n
       $load_values = TRUE;
     }
     elseif ($trigger['#name'] == 'bundle[bundle_select]') {
-      $bundle_name = $form_state->getValue(array('bundle', 'bundle_select'));
+      $bundle_name = $form_state->getValue(['bundle', 'bundle_select']);
       if ($bundle_name != self::NEW_BUNDLE_SELECT_VALUE) {
         $this->assigner->setCurrent($this->assigner->getBundle($bundle_name));
       }
@@ -142,7 +142,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $bundle_n
       $current_bundle = $this->assigner->loadBundle($bundle_name);
       $bundle_name = $current_bundle->getMachineName();
       $this->assigner->removeBundle($bundle_name);
-      return $this->redirect('features.assignment', array(''));
+      return $this->redirect('features.assignment', ['']);
     }
     if (!isset($current_bundle)) {
       switch ($bundle_name) {
@@ -177,28 +177,28 @@ public function buildForm(array $form, FormStateInterface $form_state, $bundle_n
       $this->loadBundleValues($bundle_name, $form_state, $current_bundle, $enabled_methods, $methods_weight);
     }
 
-    $form = array(
-      '#attached' => array(
-        'library' => array(
+    $form = [
+      '#attached' => [
+        'library' => [
           // Provides the copyFieldValue behavior invoked below.
           'system/drupal.system',
           'features_ui/drupal.features_ui.admin',
-        ),
-      ),
+        ],
+      ],
       // '#attributes' => array('class' => 'edit-bundles-wrapper'),
       '#tree' => TRUE,
       '#show_operations' => FALSE,
-      'weight' => array('#tree' => TRUE),
+      'weight' => ['#tree' => TRUE],
       '#prefix' => '<div id="edit-bundles-wrapper">',
       '#suffix' => '</div>',
-    );
+    ];
 
-    $form['bundle'] = array(
+    $form['bundle'] = [
       '#type' => 'fieldset',
       '#title' => $this->t('Bundle'),
       '#tree' => TRUE,
       '#weight' => -9,
-    );
+    ];
 
     if ($bundle_name == self::NEW_BUNDLE_SELECT_VALUE) {
       $default_values = [
@@ -220,86 +220,86 @@ public function buildForm(array $form, FormStateInterface $form_state, $bundle_n
         'profile_name' => $current_bundle->getProfileName(),
       ];
     }
-    $form['bundle']['bundle_select'] = array(
+    $form['bundle']['bundle_select'] = [
       '#title' => $this->t('Bundle'),
       '#title_display' => 'invisible',
       '#type' => 'select',
       '#options' => [self::NEW_BUNDLE_SELECT_VALUE => $this->t('--New--')] + $this->assigner->getBundleOptions(),
       '#default_value' => $default_values['bundle_select'],
-      '#ajax' => array(
+      '#ajax' => [
         'callback' => '::updateForm',
         'wrapper' => 'edit-bundles-wrapper',
-      ),
-    );
+      ],
+    ];
 
     // Don't show the remove button for the default bundle or when adding a new
     // bundle.
     if ($bundle_name != self::NEW_BUNDLE_SELECT_VALUE && !$current_bundle->isDefault()) {
-      $form['bundle']['remove'] = array(
+      $form['bundle']['remove'] = [
         '#type' => 'button',
         '#name' => 'removebundle',
         '#value' => $this->t('Remove bundle'),
-      );
+      ];
     }
 
-    $form['bundle']['name'] = array(
+    $form['bundle']['name'] = [
       '#title' => $this->t('Bundle name'),
       '#type' => 'textfield',
       '#description' => $this->t('A unique human-readable name of this bundle.'),
       '#default_value' => $default_values['name'],
       '#required' => TRUE,
       '#disabled' => $bundle_name == FeaturesBundleInterface::DEFAULT_BUNDLE,
-    );
+    ];
 
     // Don't allow changing the default bundle machine name.
     if ($bundle_name == FeaturesBundleInterface::DEFAULT_BUNDLE) {
-      $form['bundle']['machine_name'] = array(
+      $form['bundle']['machine_name'] = [
         '#type' => 'value',
         '#value' => $default_values['machine_name'],
-      );
+      ];
     }
     else {
-      $form['bundle']['machine_name'] = array(
+      $form['bundle']['machine_name'] = [
         '#title' => $this->t('Machine name'),
         '#type' => 'machine_name',
         '#required' => TRUE,
         '#default_value' => $default_values['machine_name'],
         '#description' => $this->t('A unique machine-readable name of this bundle.  Used to prefix exported packages. It must only contain lowercase letters, numbers, and underscores.'),
-        '#machine_name' => array(
-          'source' => array('bundle', 'name'),
-          'exists' => array($this, 'bundleExists'),
-        ),
-      );
+        '#machine_name' => [
+          'source' => ['bundle', 'name'],
+          'exists' => [$this, 'bundleExists'],
+        ],
+      ];
     }
 
-    $form['bundle']['description'] = array(
+    $form['bundle']['description'] = [
       '#title' => $this->t('Distribution description'),
       '#type' => 'textfield',
       '#default_value' => $default_values['description'],
       '#description' => $this->t('A description of the bundle.'),
       '#size' => 80,
-    );
+    ];
 
-    $form['bundle']['is_profile'] = array(
+    $form['bundle']['is_profile'] = [
       '#type' => 'checkbox',
       '#title' => $this->t('Include install profile'),
       '#default_value' => $default_values['is_profile'],
       '#description' => $this->t('Select this option to have your features packaged into an install profile.'),
-      '#attributes' => array(
+      '#attributes' => [
         'data-add-profile' => 'status',
-      ),
-    );
-
-    $show_and_require_if_profile_checked = array(
-      'visible' => array(
-        ':input[data-add-profile="status"]' => array('checked' => TRUE),
-      ),
-      'required' => array(
-        ':input[data-add-profile="status"]' => array('checked' => TRUE),
-      ),
-    );
-
-    $form['bundle']['profile_name'] = array(
+      ],
+    ];
+
+    $show_and_require_if_profile_checked = [
+      'visible' => [
+        ':input[data-add-profile="status"]' => ['checked' => TRUE],
+      ],
+      'required' => [
+        ':input[data-add-profile="status"]' => ['checked' => TRUE],
+      ],
+    ];
+
+    $form['bundle']['profile_name'] = [
       '#title' => $this->t('Profile name'),
       '#type' => 'textfield',
       '#default_value' => $default_values['profile_name'],
@@ -307,7 +307,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $bundle_n
       '#size' => 30,
       // Show and require only if the profile.add option is selected.
       '#states' => $show_and_require_if_profile_checked,
-    );
+    ];
 
     // Attach the copyFieldValue behavior to the profile_name field. In
     // practice this only works if a user tabs through the bundle machine name
@@ -327,48 +327,48 @@ public function buildForm(array $form, FormStateInterface $form_state, $bundle_n
 
       $method_name = Html::escape($method['name']);
 
-      $form['weight'][$method_id] = array(
+      $form['weight'][$method_id] = [
         '#type' => 'weight',
-        '#title' => $this->t('Weight for @title package assignment method', array('@title' => Unicode::strtolower($method_name))),
+        '#title' => $this->t('Weight for @title package assignment method', ['@title' => Unicode::strtolower($method_name)]),
         '#title_display' => 'invisible',
         '#default_value' => $weight,
-        '#attributes' => array('class' => array('assignment-method-weight')),
+        '#attributes' => ['class' => ['assignment-method-weight']],
         '#delta' => 20,
-      );
+      ];
 
-      $form['title'][$method_id] = array('#markup' => $method_name);
+      $form['title'][$method_id] = ['#markup' => $method_name];
 
-      $form['enabled'][$method_id] = array(
+      $form['enabled'][$method_id] = [
         '#type' => 'checkbox',
-        '#title' => $this->t('Enable @title package assignment method', array('@title' => Unicode::strtolower($method_name))),
+        '#title' => $this->t('Enable @title package assignment method', ['@title' => Unicode::strtolower($method_name)]),
         '#title_display' => 'invisible',
         '#default_value' => $enabled,
-      );
+      ];
 
-      $form['description'][$method_id] = array('#markup' => $method['description']);
+      $form['description'][$method_id] = ['#markup' => $method['description']];
 
-      $config_op = array();
+      $config_op = [];
       if (isset($method['config_route_name'])) {
-        $config_op['configure'] = array(
+        $config_op['configure'] = [
           'title' => $this->t('Configure'),
-          'url' => Url::fromRoute($method['config_route_name'], array('bundle_name' => $current_bundle->getMachineName())),
-        );
+          'url' => Url::fromRoute($method['config_route_name'], ['bundle_name' => $current_bundle->getMachineName()]),
+        ];
         // If there is at least one operation enabled, show the operation
         // column.
         $form['#show_operations'] = TRUE;
       }
-      $form['operation'][$method_id] = array(
+      $form['operation'][$method_id] = [
         '#type' => 'operations',
         '#links' => $config_op,
-      );
+      ];
     }
 
-    $form['actions'] = array('#type' => 'actions', '#weight' => 9);
-    $form['actions']['submit'] = array(
+    $form['actions'] = ['#type' => 'actions', '#weight' => 9];
+    $form['actions']['submit'] = [
       '#type' => 'submit',
       '#button_type' => 'primary',
       '#value' => $this->t('Save settings'),
-    );
+    ];
 
     return $form;
   }
@@ -384,7 +384,7 @@ public function updateForm($form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function validateForm(array &$form, FormStateInterface $form_state) {
-    if ($form_state->getValue(array('bundle', 'is_profile')) && empty($form_state->getValue(array('bundle', 'profile_name')))) {
+    if ($form_state->getValue(['bundle', 'is_profile']) && empty($form_state->getValue(['bundle', 'profile_name']))) {
       $form_state->setErrorByName('bundle][profile_name', $this->t('To create a profile, please enter a profile name.'));
     }
 
@@ -400,28 +400,28 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     $method_weights = $form_state->getValue('weight');
     ksort($method_weights);
 
-    $machine_name = $form_state->getValue(array('bundle', 'machine_name'));
+    $machine_name = $form_state->getValue(['bundle', 'machine_name']);
 
     // If this is a new bundle, create it.
-    if ($form_state->getValue(array('bundle', 'bundle_select')) == self::NEW_BUNDLE_SELECT_VALUE) {
+    if ($form_state->getValue(['bundle', 'bundle_select']) == self::NEW_BUNDLE_SELECT_VALUE) {
       $bundle = $this->assigner->createBundleFromDefault($machine_name);
     }
     // Otherwise, load the current bundle and rename if needed.
     else {
       $bundle = $this->assigner->loadBundle();
       $old_name = $bundle->getMachineName();
-      $new_name = $form_state->getValue(array('bundle', 'machine_name'));
+      $new_name = $form_state->getValue(['bundle', 'machine_name']);
       if ($old_name != $new_name) {
         $bundle = $this->assigner->renameBundle($old_name, $new_name);
       }
     }
 
-    $bundle->setName($form_state->getValue(array('bundle', 'name')));
-    $bundle->setDescription($form_state->getValue(array('bundle', 'description')));
+    $bundle->setName($form_state->getValue(['bundle', 'name']));
+    $bundle->setDescription($form_state->getValue(['bundle', 'description']));
     $bundle->setEnabledAssignments(array_keys($enabled_methods));
     $bundle->setAssignmentWeights($method_weights);
-    $bundle->setIsProfile($form_state->getValue(array('bundle', 'is_profile')));
-    $bundle->setProfileName($form_state->getValue(array('bundle', 'profile_name')));
+    $bundle->setIsProfile($form_state->getValue(['bundle', 'is_profile']));
+    $bundle->setProfileName($form_state->getValue(['bundle', 'profile_name']));
     $bundle->save();
     $this->assigner->setBundle($bundle);
     $this->assigner->setCurrent($bundle);
diff --git a/web/modules/features/modules/features_ui/src/Form/AssignmentExcludeForm.php b/web/modules/features/modules/features_ui/src/Form/AssignmentExcludeForm.php
index 741be59fcdfb615bf8c1b2ae408e5e5de171fb5e..459bf7ce839a0b1ade47145cf643767d60078f31 100644
--- a/web/modules/features/modules/features_ui/src/Form/AssignmentExcludeForm.php
+++ b/web/modules/features/modules/features_ui/src/Form/AssignmentExcludeForm.php
@@ -31,72 +31,72 @@ public function buildForm(array $form, FormStateInterface $form_state, $bundle_n
     $this->setConfigTypeSelect($form, $settings['types']['config'], $this->t('exclude'), FALSE,
       $this->t("Select types of configuration that should be excluded from packaging."));
 
-    $form['curated'] = array(
+    $form['curated'] = [
       '#type' => 'checkbox',
       '#title' => $this->t('Exclude designated site-specific configuration'),
       '#default_value' => $curated_settings,
       '#description' => $this->t('Select this option to exclude a curated list of site-specific configuration from packaging.'),
-    );
+    ];
 
-    $form['module'] = array(
+    $form['module'] = [
       '#type' => 'fieldset',
       '#tree' => TRUE,
       '#title' => $this->t('Exclude configuration provided by modules'),
-    );
+    ];
 
-    $form['module']['installed'] = array(
+    $form['module']['installed'] = [
       '#type' => 'checkbox',
       '#title' => $this->t('Exclude installed module-provided entity configuration'),
       '#default_value' => $module_settings['installed'],
       '#description' => $this->t('Select this option to exclude configuration provided by INSTALLED modules from reassignment.'),
-      '#attributes' => array(
+      '#attributes' => [
         'data-module-installed' => 'status',
-      ),
-    );
+      ],
+    ];
 
-    $show_if_module_installed_checked = array(
-      'visible' => array(
-        ':input[data-module-installed="status"]' => array('checked' => TRUE),
-      ),
-    );
+    $show_if_module_installed_checked = [
+      'visible' => [
+        ':input[data-module-installed="status"]' => ['checked' => TRUE],
+      ],
+    ];
 
     $info = system_get_info('module', drupal_get_profile());
-    $form['module']['profile'] = array(
+    $form['module']['profile'] = [
       '#type' => 'checkbox',
       '#title' => $this->t("Don't exclude install profile's configuration"),
       '#default_value' => $module_settings['profile'],
-      '#description' => $this->t("Select this option to allow configuration provided by the site's install profile (%profile) to be reassigned.", array('%profile' => $info['name'])),
+      '#description' => $this->t("Select this option to allow configuration provided by the site's install profile (%profile) to be reassigned.", ['%profile' => $info['name']]),
       '#states' => $show_if_module_installed_checked,
-    );
+    ];
 
     $bundle_name = $this->currentBundle->getMachineName();
     $bundle_name = !empty($bundle_name) ? $bundle_name : $this->t('none');
-    $form['module']['namespace'] = array(
+    $form['module']['namespace'] = [
       '#type' => 'checkbox',
       '#title' => $this->t("Don't exclude non-installed configuration by namespace"),
       '#default_value' => $module_settings['namespace'],
-      '#description' => $this->t("Select this option to allow configuration provided by uninstalled modules with the bundle namespace (%namespace_*) to be reassigned.", array('%namespace' => $bundle_name)),
+      '#description' => $this->t("Select this option to allow configuration provided by uninstalled modules with the bundle namespace (%namespace_*) to be reassigned.", ['%namespace' => $bundle_name]),
       '#states' => $show_if_module_installed_checked,
-      '#attributes' => array(
+      '#attributes' => [
         'data-namespace' => 'status',
-      ),
-    );
+      ],
+    ];
 
-    $show_if_namespace_checked = array(
-      'visible' => array(
-        ':input[data-namespace="status"]' => array('checked' => TRUE),
-        ':input[data-module-installed="status"]' => array('checked' => TRUE),
-      ),
-    );
+    $show_if_namespace_checked = [
+      'visible' => [
+        ':input[data-namespace="status"]' => ['checked' => TRUE],
+        ':input[data-module-installed="status"]' => ['checked' => TRUE],
+      ],
+    ];
 
-    $form['module']['namespace_any'] = array(
+    $form['module']['namespace_any'] = [
       '#type' => 'checkbox',
       '#title' => $this->t("Don't exclude ANY configuration by namespace"),
       '#default_value' => $module_settings['namespace_any'],
       '#description' => $this->t("Select this option to allow configuration provided by ANY modules with the bundle namespace (%namespace_*) to be reassigned.
-        Warning: Can cause installed configuration to be reassigned to different packages.", array('%namespace' => $bundle_name)),
+        Warning: Can cause installed configuration to be reassigned to different packages.", ['%namespace' => $bundle_name]),
       '#states' => $show_if_namespace_checked,
-    );
+    ];
 
     $this->setActions($form, self::METHOD_ID);
 
diff --git a/web/modules/features/modules/features_ui/src/Form/AssignmentFormBase.php b/web/modules/features/modules/features_ui/src/Form/AssignmentFormBase.php
index 9756c3cfd5397bae8bea9f04bc35e0e540278b0e..9b7dca927976c018f4f866bd73b7df798b764ce7 100644
--- a/web/modules/features/modules/features_ui/src/Form/AssignmentFormBase.php
+++ b/web/modules/features/modules/features_ui/src/Form/AssignmentFormBase.php
@@ -77,19 +77,19 @@ protected function setConfigTypeSelect(&$form, $defaults, $type, $bundles_only =
     $options = $this->featuresManager->listConfigTypes($bundles_only);
 
     if (!isset($form['types'])) {
-      $form['types'] = array(
+      $form['types'] = [
         '#type' => 'container',
         '#tree' => TRUE,
-      );
+      ];
     }
 
-    $form['types']['config'] = array(
+    $form['types']['config'] = [
       '#type' => 'checkboxes',
       '#title' => $this->t('Configuration types'),
-      '#description' => !empty($description) ? $description : $this->t('Select types of configuration that should be considered @type types.', array('@type' => $type)),
+      '#description' => !empty($description) ? $description : $this->t('Select types of configuration that should be considered @type types.', ['@type' => $type]),
       '#options' => $options,
       '#default_value' => $defaults,
-    );
+    ];
   }
 
   /**
@@ -98,13 +98,13 @@ protected function setConfigTypeSelect(&$form, $defaults, $type, $bundles_only =
   protected function setContentTypeSelect(&$form, $defaults, $type, $exclude_has_config_bundles = TRUE) {
     $entity_types = $this->entityTypeManager->getDefinitions();
 
-    $has_config_bundle = array();
+    $has_config_bundle = [];
     foreach ($entity_types as $definition) {
       if ($entity_type_id = $definition->getBundleOf()) {
         $has_config_bundle[] = $entity_type_id;
       }
     }
-    $options = array();
+    $options = [];
 
     foreach ($entity_types as $entity_type_id => $entity_type) {
       if (!$entity_type instanceof ContentEntityTypeInterface) {
@@ -120,19 +120,19 @@ protected function setContentTypeSelect(&$form, $defaults, $type, $exclude_has_c
     uasort($options, 'strnatcasecmp');
 
     if (!isset($form['types'])) {
-      $form['types'] = array(
+      $form['types'] = [
         '#type' => 'container',
         '#tree' => TRUE,
-      );
+      ];
     }
 
-    $form['types']['content'] = array(
+    $form['types']['content'] = [
       '#type' => 'checkboxes',
       '#title' => $this->t('Content entity types'),
-      '#description' => $this->t('Select content entity types that should be considered @type types.', array('@type' => $type)),
+      '#description' => $this->t('Select content entity types that should be considered @type types.', ['@type' => $type]),
       '#options' => $options,
       '#default_value' => $defaults,
-    );
+    ];
   }
 
   /**
@@ -142,25 +142,25 @@ protected function setActions(&$form, $method_id = NULL) {
     $assignment_info = $this->assigner->getAssignmentMethods();
     if (isset($method_id) && isset($assignment_info[$method_id])) {
       $method = $assignment_info[$method_id];
-      $form['help_text'] = array(
+      $form['help_text'] = [
         '#markup' => $method['description'],
         '#prefix' => '<p class="messages messages--status">',
         '#suffix' => '</p>',
         '#weight' => -99,
-      );
+      ];
     }
 
-    $form['actions'] = array('#type' => 'actions');
-    $form['actions']['submit'] = array(
+    $form['actions'] = ['#type' => 'actions'];
+    $form['actions']['submit'] = [
       '#type' => 'submit',
       '#button_type' => 'primary',
       '#value' => $this->t('Save settings'),
-    );
+    ];
     $form['#attributes']['class'][] = 'features-assignment-settings-form';
-    $form['#attached'] = array(
-      'library' => array(
+    $form['#attached'] = [
+      'library' => [
         'features_ui/drupal.features_ui.admin',
-    ));
+    ]];
   }
 
   /**
@@ -170,7 +170,7 @@ protected function setActions(&$form, $method_id = NULL) {
    *   The form state.
    */
   protected function setRedirect(FormStateInterface $form_state) {
-    $form_state->setRedirect('features.assignment', array('bundle_name' => $this->currentBundle->getMachineName()));
+    $form_state->setRedirect('features.assignment', ['bundle_name' => $this->currentBundle->getMachineName()]);
   }
 
 }
diff --git a/web/modules/features/modules/features_ui/src/Form/AssignmentProfileForm.php b/web/modules/features/modules/features_ui/src/Form/AssignmentProfileForm.php
index 2a4b17797aed8f39d6419aa1f1918ab9266c23e3..88c86348dd181d99a76b87bae2078a5d88c845f8 100644
--- a/web/modules/features/modules/features_ui/src/Form/AssignmentProfileForm.php
+++ b/web/modules/features/modules/features_ui/src/Form/AssignmentProfileForm.php
@@ -27,32 +27,32 @@ public function buildForm(array $form, FormStateInterface $form_state, $bundle_n
 
     $this->setConfigTypeSelect($form, $settings['types']['config'], $this->t('profile'));
 
-    $form['curated'] = array(
+    $form['curated'] = [
       '#type' => 'checkbox',
       '#title' => $this->t('Add commonly-needed configuration'),
       '#default_value' => $settings['curated'],
       '#description' => $this->t('Select this option to add a curated list of commonly-needed configuration including cron- and theme-related settings to the install profile.'),
-    );
+    ];
 
     $standard_settings = $settings['standard'];
 
-    $form['standard'] = array(
+    $form['standard'] = [
       '#type' => 'fieldset',
       '#title' => $this->t('Crib from the Standard profile'),
       '#tree' => TRUE,
-    );
-    $form['standard']['files'] = array(
+    ];
+    $form['standard']['files'] = [
       '#type' => 'checkbox',
       '#title' => $this->t('Crib code'),
       '#default_value' => $standard_settings['files'],
       '#description' => $this->t('Select this option to add configuration and other files to the optional install profile from the Drupal core Standard install profile. Without these additions, a generated install profile will be missing some important initial setup.'),
-    );
-    $form['standard']['dependencies'] = array(
+    ];
+    $form['standard']['dependencies'] = [
       '#type' => 'checkbox',
       '#title' => $this->t('Crib dependencies'),
       '#default_value' => $standard_settings['dependencies'],
       '#description' => $this->t('Select this option to add module and theme dependencies from the Standard install profile.'),
-    );
+    ];
 
     $this->setActions($form, self::METHOD_ID);
 
diff --git a/web/modules/features/modules/features_ui/src/Form/FeaturesDiffForm.php b/web/modules/features/modules/features_ui/src/Form/FeaturesDiffForm.php
index 68cc0e9daa6e75d88526f89a38a1d3660a0c8356..b04ca241a9d511cffc86ab400eea7464afe699b9 100644
--- a/web/modules/features/modules/features_ui/src/Form/FeaturesDiffForm.php
+++ b/web/modules/features/modules/features_ui/src/Form/FeaturesDiffForm.php
@@ -99,70 +99,70 @@ public function getFormId() {
   public function buildForm(array $form, FormStateInterface $form_state, $featurename = '') {
     $current_bundle = $this->assigner->applyBundle();
     $packages = $this->featuresManager->getPackages();
-    $form = array();
+    $form = [];
 
     $machine_name = '';
     if (!empty($featurename) && empty($packages[$featurename])) {
-      drupal_set_message($this->t('Feature @name does not exist.', array('@name' => $featurename)), 'error');
-      return array();
+      drupal_set_message($this->t('Feature @name does not exist.', ['@name' => $featurename]), 'error');
+      return [];
     }
     elseif (!empty($featurename)) {
       $machine_name = $packages[$featurename]->getMachineName();
-      $packages = array($packages[$featurename]);
+      $packages = [$packages[$featurename]];
     }
     else {
       $packages = $this->featuresManager->filterPackages($packages, $current_bundle->getMachineName());
     }
 
-    $header = array(
-      'row' => array(
+    $header = [
+      'row' => [
         'data' => !empty($machine_name)
-        ? $this->t('Differences in @name', array('@name' => $machine_name))
-        : ($current_bundle->isDefault() ? $this->t('All differences') : $this->t('All differences in bundle: @bundle', array('@bundle' => $current_bundle->getName()))),
-      ),
-    );
+        ? $this->t('Differences in @name', ['@name' => $machine_name])
+        : ($current_bundle->isDefault() ? $this->t('All differences') : $this->t('All differences in bundle: @bundle', ['@bundle' => $current_bundle->getName()])),
+      ],
+    ];
 
-    $options = array();
+    $options = [];
     foreach ($packages as $package) {
       if ($package->getStatus() != FeaturesManagerInterface::STATUS_NO_EXPORT) {
         $missing = $this->featuresManager->reorderMissing($this->featuresManager->detectMissing($package));
         $overrides = $this->featuresManager->detectOverrides($package, TRUE);
         if (!empty($overrides) || !empty($missing)) {
-          $options += array(
-            $package->getMachineName() => array(
-              'row' => array(
-                'data' => array(
+          $options += [
+            $package->getMachineName() => [
+              'row' => [
+                'data' => [
                   '#type' => 'html_tag',
                   '#tag' => 'h2',
                   '#value' => Html::escape($package->getName()),
-                ),
-              ),
-              '#attributes' => array(
+                ],
+              ],
+              '#attributes' => [
                 'class' => 'features-diff-header',
-              ),
-            ),
-          );
+              ],
+            ],
+          ];
           $options += $this->diffOutput($package, $overrides, $missing);
         }
       }
     }
 
-    $form['diff'] = array(
+    $form['diff'] = [
       '#type' => 'tableselect',
       '#header' => $header,
       '#options' => $options,
-      '#attributes' => array('class' => array('features-diff-listing')),
+      '#attributes' => ['class' => ['features-diff-listing']],
       '#empty' => $this->t('No differences exist in exported features.'),
-    );
+    ];
 
-    $form['actions'] = array('#type' => 'actions', '#tree' => TRUE);
-    $form['actions']['revert'] = array(
+    $form['actions'] = ['#type' => 'actions', '#tree' => TRUE];
+    $form['actions']['revert'] = [
       '#type' => 'submit',
       '#value' => $this->t('Import changes'),
-    );
-    $form['actions']['help'] = array(
+    ];
+    $form['actions']['help'] = [
       '#markup' => $this->t('Import the selected changes above into the active configuration.'),
-    );
+    ];
 
     $form['#attached']['library'][] = 'system/diff';
     $form['#attached']['library'][] = 'features_ui/drupal.features_ui.admin';
@@ -192,7 +192,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
         $type = ConfigurationItem::fromConfigStringToConfigType($item['type']);
         $this->configRevert->import($type, $item['name_short']);
       }
-      drupal_set_message($this->t('Imported @name', array('@name' => $config_name)));
+      drupal_set_message($this->t('Imported @name', ['@name' => $config_name]));
     }
   }
 
@@ -209,59 +209,59 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
    * @return array
    *   A form element.
    */
-  protected function diffOutput(Package $package, $overrides, $missing = array()) {
-    $element = array();
+  protected function diffOutput(Package $package, $overrides, $missing = []) {
+    $element = [];
     $config = $this->featuresManager->getConfigCollection();
     $components = array_merge($missing, $overrides);
 
-    $header = array(
-      array('data' => '', 'class' => 'diff-marker'),
-      array('data' => $this->t('Active site config'), 'class' => 'diff-context'),
-      array('data' => '', 'class' => 'diff-marker'),
-      array('data' => $this->t('Feature code config'), 'class' => 'diff-context'),
-    );
+    $header = [
+      ['data' => '', 'class' => 'diff-marker'],
+      ['data' => $this->t('Active site config'), 'class' => 'diff-context'],
+      ['data' => '', 'class' => 'diff-marker'],
+      ['data' => $this->t('Feature code config'), 'class' => 'diff-context'],
+    ];
 
     foreach ($components as $name) {
-      $rows[] = array(array('data' => $name, 'colspan' => 4, 'header' => TRUE));
+      $rows[] = [['data' => $name, 'colspan' => 4, 'header' => TRUE]];
 
       if (!isset($config[$name])) {
-        $details = array(
+        $details = [
           '#markup' => $this->t('Component in feature missing from active config.'),
-        );
+        ];
       }
       else {
         $active = $this->featuresManager->getActiveStorage()->read($name);
         $extension = $this->featuresManager->getExtensionStorages()->read($name);
         if (empty($extension)) {
-          $details = array(
+          $details = [
             '#markup' => $this->t('Dependency detected in active config but not exported to the feature.'),
-          );
+          ];
         }
         else {
           $diff = $this->configDiff->diff($active, $extension);
-          $details = array(
+          $details = [
             '#type' => 'table',
             '#header' => $header,
             '#rows' => $this->diffFormatter->format($diff),
-            '#attributes' => array('class' => array('diff', 'features-diff')),
-          );
+            '#attributes' => ['class' => ['diff', 'features-diff']],
+          ];
         }
       }
-      $element[$name] = array(
-        'row' => array(
-          'data' => array(
+      $element[$name] = [
+        'row' => [
+          'data' => [
             '#type' => 'details',
             '#title' => Html::escape($name),
             '#open' => TRUE,
-            '#description' => array(
+            '#description' => [
               'data' => $details,
-            ),
-          ),
-        ),
-        '#attributes' => array(
+            ],
+          ],
+        ],
+        '#attributes' => [
           'class' => 'diff-' . $package->getMachineName(),
-        ),
-      );
+        ],
+      ];
     }
 
     return $element;
diff --git a/web/modules/features/modules/features_ui/src/Form/FeaturesEditForm.php b/web/modules/features/modules/features_ui/src/Form/FeaturesEditForm.php
index ae52e2613623a7b5067ada59cd6715cbf558d062..62808765769db24d02ebc1a3e0d8acbf4263d25f 100644
--- a/web/modules/features/modules/features_ui/src/Form/FeaturesEditForm.php
+++ b/web/modules/features/modules/features_ui/src/Form/FeaturesEditForm.php
@@ -180,7 +180,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $featuren
 
     $packages = $this->featuresManager->getPackages();
     if (empty($packages[$featurename])) {
-      $featurename = str_replace(array('-', ' '), '_', $featurename);
+      $featurename = str_replace(['-', ' '], '_', $featurename);
       $this->package = $this->featuresManager->initPackage($featurename, NULL, '', 'module', $bundle);
     }
     else {
@@ -202,107 +202,107 @@ public function buildForm(array $form, FormStateInterface $form_state, $featuren
       $this->package = $packages[$featurename];
     }
 
-    $form = array(
+    $form = [
       '#show_operations' => FALSE,
       '#prefix' => '<div id="features-edit-wrapper">',
       '#suffix' => '</div>',
-    );
+    ];
 
-    $form['info'] = array(
+    $form['info'] = [
       '#type' => 'fieldset',
       '#title' => $this->t('General Information'),
       '#tree' => FALSE,
       '#weight' => 2,
       '#prefix' => "<div id='features-export-info'>",
       '#suffix' => '</div>',
-    );
+    ];
 
-    $form['info']['name'] = array(
+    $form['info']['name'] = [
       '#title' => $this->t('Name'),
       '#description' => $this->t('Example: Image gallery') . ' (' . $this->t('Do not begin name with numbers.') . ')',
       '#type' => 'textfield',
       '#default_value' => $this->package->getName(),
-    );
+    ];
     if (!$bundle->isDefault()) {
       $form['info']['name']['#description'] .= '<br/>' .
-        $this->t('The namespace "@name_" will be prepended to the machine name', array('@name' => $bundle->getMachineName()));
+        $this->t('The namespace "@name_" will be prepended to the machine name', ['@name' => $bundle->getMachineName()]);
     }
 
-    $form['info']['machine_name'] = array(
+    $form['info']['machine_name'] = [
       '#type' => 'machine_name',
       '#title' => $this->t('Machine-readable name'),
       '#description' => $this->t('Example: image_gallery') . ' ' . $this->t('May only contain lowercase letters, numbers and underscores.'),
       '#required' => TRUE,
       '#default_value' => $bundle->getShortName($this->package->getMachineName()),
-      '#machine_name' => array(
-        'source' => array('info', 'name'),
-        'exists' => array($this, 'featureExists'),
-      ),
-    );
+      '#machine_name' => [
+        'source' => ['info', 'name'],
+        'exists' => [$this, 'featureExists'],
+      ],
+    ];
     if (!$bundle->isDefault()) {
       $form['info']['machine_name']['#description'] .= '<br/>' .
-        $this->t('NOTE: Do NOT include the namespace prefix "@name_"; it will be added automatically.', array('@name' => $bundle->getMachineName()));
+        $this->t('NOTE: Do NOT include the namespace prefix "@name_"; it will be added automatically.', ['@name' => $bundle->getMachineName()]);
     }
 
-    $form['info']['description'] = array(
+    $form['info']['description'] = [
       '#title' => $this->t('Description'),
       '#description' => $this->t('Provide a short description of what users should expect when they install your feature.'),
       '#type' => 'textarea',
       '#rows' => 3,
       '#default_value' => $this->package->getDescription(),
-    );
+    ];
 
-    $form['info']['package'] = array(
+    $form['info']['package'] = [
       '#title' => $this->t('Bundle'),
       '#type' => 'select',
       '#options' => $this->assigner->getBundleOptions(),
       '#default_value' => $bundle->getMachineName(),
-      '#ajax' => array(
+      '#ajax' => [
         'callback' => '::updateBundle',
         'wrapper' => 'features-export-info',
-      ),
-    );
+      ],
+    ];
 
-    $form['info']['version'] = array(
+    $form['info']['version'] = [
       '#title' => $this->t('Version'),
       '#description' => $this->t('Examples: 8.x-1.0, 8.x-1.0-beta1'),
       '#type' => 'textfield',
       '#required' => FALSE,
       '#default_value' => $this->package->getVersion(),
       '#size' => 30,
-    );
+    ];
 
     list($full_name, $path) = $this->featuresManager->getExportInfo($this->package, $bundle);
-    $form['info']['directory'] = array(
+    $form['info']['directory'] = [
       '#title' => $this->t('Path'),
       '#description' => $this->t('Path to export package using Write action, relative to root directory.'),
       '#type' => 'textfield',
       '#required' => FALSE,
       '#default_value' => $path,
       '#size' => 30,
-    );
+    ];
 
     $require_all = $this->package->getRequiredAll();
-    $form['info']['require_all'] = array(
+    $form['info']['require_all'] = [
       '#type' => 'checkbox',
       '#title' => $this->t('Mark all config as required'),
       '#default_value' => $this->package->getRequiredAll(),
       '#description' => $this->t('Required config will be assigned to this feature regardless of other assignment plugins.'),
-    );
+    ];
 
-    $form['conflicts'] = array(
+    $form['conflicts'] = [
       '#type' => 'checkbox',
       '#title' => $this->t('Allow conflicts'),
       '#default_value' => $this->allowConflicts,
       '#description' => $this->t('Allow configuration to be exported to more than one feature.'),
       '#weight' => 8,
-      '#ajax' => array(
+      '#ajax' => [
         'callback' => '::updateForm',
         'wrapper' => 'features-edit-wrapper',
-      ),
-    );
+      ],
+    ];
 
-    $generation_info = array();
+    $generation_info = [];
     if (\Drupal::currentUser()->hasPermission('export configuration')) {
       // Offer available generation methods.
       $generation_info = $this->generator->getGenerationMethods();
@@ -310,16 +310,16 @@ public function buildForm(array $form, FormStateInterface $form_state, $featuren
       uasort($generation_info, '\Drupal\Component\Utility\SortArray::sortByWeightElement');
     }
 
-    $form['actions'] = array('#type' => 'actions', '#tree' => TRUE);
+    $form['actions'] = ['#type' => 'actions', '#tree' => TRUE];
     foreach ($generation_info as $method_id => $method) {
-      $form['actions'][$method_id] = array(
+      $form['actions'][$method_id] = [
         '#type' => 'submit',
         '#name' => $method_id,
-        '#value' => $this->t('@name', array('@name' => $method['name'])),
-        '#attributes' => array(
+        '#value' => $this->t('@name', ['@name' => $method['name']]),
+        '#attributes' => [
           'title' => Html::escape($method['description']),
-        ),
-      );
+        ],
+      ];
     }
 
     // Build the Component Listing panel on the right.
@@ -342,29 +342,29 @@ public function buildForm(array $form, FormStateInterface $form_state, $featuren
           $this->t('Or, enable the Allow Conflicts option above.') .
           '</strong>';
       }
-      $form['actions']['import_missing'] = array(
+      $form['actions']['import_missing'] = [
         '#type' => 'submit',
         '#name' => 'import_missing',
         '#value' => $this->t('Import Missing'),
-        '#attributes' => array(
+        '#attributes' => [
           'title' => $this->t('Import only the missing configuration items.'),
-        ),
-      );
+        ],
+      ];
     }
 
-    $form['#attached'] = array(
-      'library' => array(
+    $form['#attached'] = [
+      'library' => [
         'features_ui/drupal.features_ui.admin',
-      ),
-      'drupalSettings' => array(
-        'features' => array(
+      ],
+      'drupalSettings' => [
+        'features' => [
           'excluded' => $this->excluded,
           'required' => $this->required,
           'conflicts' => $this->conflicts,
           'autodetect' => TRUE,
-        ),
-      ),
-    );
+        ],
+      ],
+    ];
 
     return $form;
   }
@@ -414,7 +414,7 @@ public function featureExists($value, $element, $form_state) {
    * form.
    */
   protected function buildComponentList(FormStateInterface $form_state) {
-    $element = array(
+    $element = [
       '#type' => 'fieldset',
       '#title' => $this->t('Components'),
       '#description' => $this->t('Expand each component section and select which items should be included in this feature export.'),
@@ -422,35 +422,35 @@ protected function buildComponentList(FormStateInterface $form_state) {
       '#prefix' => "<div id='features-export-wrapper'>",
       '#suffix' => '</div>',
       '#weight' => 1,
-    );
+    ];
 
     // Filter field used in javascript, so javascript will unhide it.
-    $element['features_filter_wrapper'] = array(
+    $element['features_filter_wrapper'] = [
       '#type' => 'fieldset',
       '#title' => $this->t('Filters'),
       '#tree' => FALSE,
       '#prefix' => "<div id='features-filter' class='element-invisible'>",
       '#suffix' => '</div>',
       '#weight' => -10,
-    );
-    $element['features_filter_wrapper']['features_filter'] = array(
+    ];
+    $element['features_filter_wrapper']['features_filter'] = [
       '#type' => 'textfield',
       '#title' => $this->t('Search'),
       '#hidden' => TRUE,
       '#default_value' => '',
       '#suffix' => "<span class='features-filter-clear'>" . $this->t('Clear') . "</span>",
-    );
-    $element['features_filter_wrapper']['checkall'] = array(
+    ];
+    $element['features_filter_wrapper']['checkall'] = [
       '#type' => 'checkbox',
       '#default_value' => FALSE,
       '#hidden' => TRUE,
       '#title' => $this->t('Select all'),
-      '#attributes' => array(
-        'class' => array('features-checkall'),
-      ),
-    );
+      '#attributes' => [
+        'class' => ['features-checkall'],
+      ],
+    ];
 
-    $sections = array('included', 'detected', 'added');
+    $sections = ['included', 'detected', 'added'];
     $config_types = $this->featuresManager->listConfigTypes();
 
     // Generate the export array for the current feature and user selections.
@@ -460,10 +460,10 @@ protected function buildComponentList(FormStateInterface $form_state) {
 
       $component_items_count = count($component_info['_features_options']['sources']);
       $label = new FormattableMarkup('@component (<span class="component-count">@count</span>)',
-        array(
+        [
           '@component' => $config_types[$component],
           '@count' => $component_items_count,
-        )
+        ]
       );
 
       $count = 0;
@@ -474,76 +474,76 @@ protected function buildComponentList(FormStateInterface $form_state) {
       $component_name = str_replace('_', '-', Html::escape($component));
 
       if ($count + $component_items_count > 0) {
-        $element[$component] = array(
+        $element[$component] = [
           '#markup' => '',
           '#tree' => TRUE,
-        );
+        ];
 
-        $element[$component]['sources'] = array(
+        $element[$component]['sources'] = [
           '#type' => 'details',
           '#title' => $label,
           '#tree' => TRUE,
           '#open' => FALSE,
-          '#attributes' => array('class' => array('features-export-component')),
+          '#attributes' => ['class' => ['features-export-component']],
           '#prefix' => "<div class='features-export-parent component-$component'>",
-        );
-        $element[$component]['sources']['selected'] = array(
+        ];
+        $element[$component]['sources']['selected'] = [
           '#type' => 'checkboxes',
           '#id' => "edit-sources-$component_name",
           '#options' => $this->domDecodeOptions($component_info['_features_options']['sources']),
           '#default_value' => $this->domDecodeOptions($component_info['_features_selected']['sources'], FALSE),
-          '#attributes' => array('class' => array('component-select')),
+          '#attributes' => ['class' => ['component-select']],
           '#prefix' => "<span class='component-select'>",
           '#suffix' => '</span>',
-        );
+        ];
 
-        $element[$component]['before-list'] = array(
+        $element[$component]['before-list'] = [
           '#markup' => "<div class='component-list features-export-list $extra_class'>",
-        );
+        ];
 
         foreach ($sections as $section) {
-          $element[$component][$section] = array(
+          $element[$component][$section] = [
             '#type' => 'checkboxes',
             '#options' => !empty($component_info['_features_options'][$section]) ?
-              $this->domDecodeOptions($component_info['_features_options'][$section]) : array(),
+              $this->domDecodeOptions($component_info['_features_options'][$section]) : [],
             '#default_value' => !empty($component_info['_features_selected'][$section]) ?
-              $this->domDecodeOptions($component_info['_features_selected'][$section], FALSE) : array(),
-            '#attributes' => array('class' => array('component-' . $section)),
+              $this->domDecodeOptions($component_info['_features_selected'][$section], FALSE) : [],
+            '#attributes' => ['class' => ['component-' . $section]],
             '#prefix' => "<span class='component-$section'>",
             '#suffix' => '</span>',
-          );
+          ];
         }
 
         // Close both the before-list as well as the sources div.
-        $element[$component]['after-list'] = array(
+        $element[$component]['after-list'] = [
           '#markup' => "</div></div>",
-        );
+        ];
       }
     }
 
-    $element['features_missing'] = array(
+    $element['features_missing'] = [
       '#theme' => 'item_list',
       '#items' => $export['missing'],
       '#title' => $this->t('Configuration missing from active site:'),
       '#suffix' => '<div class="description">' .
         $this->t('Import the feature to create the missing config listed above.') .
         '</div>',
-    );
+    ];
 
-    $element['features_legend'] = array(
+    $element['features_legend'] = [
       '#type' => 'fieldset',
       '#title' => $this->t('Legend'),
       '#tree' => FALSE,
       '#prefix' => "<div id='features-legend'>",
       '#suffix' => '</div>',
-    );
-    $element['features_legend']['legend'] = array(
+    ];
+    $element['features_legend']['legend'] = [
       '#markup' =>
         "<span class='component-included'>" . $this->t('Normal') . "</span> " .
         "<span class='component-added'>" . $this->t('Added') . "</span> " .
         "<span class='component-detected'>" . $this->t('Auto detected') . "</span> " .
         "<span class='component-conflict'>" . $this->t('Conflict') . "</span> ",
-    );
+    ];
 
     return $element;
   }
@@ -604,8 +604,8 @@ protected function getComponentList(FormStateInterface $form_state) {
     $this->package = $packages[$package_name];
 
     // Make a map of all config data.
-    $components = array();
-    $this->conflicts = array();
+    $components = [];
+    $this->conflicts = [];
     foreach ($config as $item_name => $item) {
       if (($item->getPackage() != $package_name) &&
         !empty($packages[$item->getPackage()]) && ($packages[$item->getPackage()]->getStatus() != FeaturesManagerInterface::STATUS_NO_EXPORT)) {
@@ -619,8 +619,8 @@ protected function getComponentList(FormStateInterface $form_state) {
     }
 
     // Make a map of the config data already exported to the Feature.
-    $this->missing = array();
-    $exported_features_info = array();
+    $this->missing = [];
+    $exported_features_info = [];
     foreach ($this->package->getConfigOrig() as $item_name) {
       // Make sure the extension provided item exists in the active
       // configuration storage.
@@ -638,9 +638,9 @@ protected function getComponentList(FormStateInterface $form_state) {
     $exported_features_info['dependencies'] = $this->package->getDependencyInfo();
 
     // Make a map of any config specifically excluded and/or required.
-    foreach (array('excluded', 'required') as $constraint) {
-      $this->{$constraint} = array();
-      $info = !empty($this->package->{'get' . $constraint}()) ? $this->package->{'get' . $constraint}() : array();
+    foreach (['excluded', 'required'] as $constraint) {
+      $this->{$constraint} = [];
+      $info = !empty($this->package->{'get' . $constraint}()) ? $this->package->{'get' . $constraint}() : [];
       // $info may be boolean.
       if (is_array($info)) {
         foreach ($info as $item_name) {
@@ -654,7 +654,7 @@ protected function getComponentList(FormStateInterface $form_state) {
     }
 
     // Make a map of the config data to be exported within the Feature.
-    $new_features_info = array();
+    $new_features_info = [];
     foreach ($this->package->getConfig() as $item_name) {
       $item = $config[$item_name];
       $new_features_info[$item->getType()][$item->getShortName()] = $item->getLabel();
@@ -662,29 +662,29 @@ protected function getComponentList(FormStateInterface $form_state) {
     $new_features_info['dependencies'] = $this->package->getDependencies();
 
     // Assemble the combined component list.
-    $config_new = array();
-    $sections = array('sources', 'included', 'detected', 'added');
+    $config_new = [];
+    $sections = ['sources', 'included', 'detected', 'added'];
 
     // Generate list of config to be exported.
-    $config_count = array();
+    $config_count = [];
     foreach ($components as $component => $component_info) {
       // User-selected components take precedence.
-      $config_new[$component] = array();
+      $config_new[$component] = [];
       $config_count[$component] = 0;
       // Add selected items from Sources checkboxes.
-      if (!$form_state->isValueEmpty(array($component, 'sources', 'selected'))) {
-        $config_new[$component] = array_merge($config_new[$component], $this->domDecodeOptions(array_filter($form_state->getValue(array(
+      if (!$form_state->isValueEmpty([$component, 'sources', 'selected'])) {
+        $config_new[$component] = array_merge($config_new[$component], $this->domDecodeOptions(array_filter($form_state->getValue([
           $component,
           'sources',
           'selected',
-        )))));
+        ]))));
         $config_count[$component]++;
       }
       // Add selected items from already Included, newly Added, auto-detected
       // checkboxes.
-      foreach (array('included', 'added', 'detected') as $section) {
-        if (!$form_state->isValueEmpty(array($component, $section))) {
-          $config_new[$component] = array_merge($config_new[$component], $this->domDecodeOptions(array_filter($form_state->getValue(array($component, $section)))));
+      foreach (['included', 'added', 'detected'] as $section) {
+        if (!$form_state->isValueEmpty([$component, $section])) {
+          $config_new[$component] = array_merge($config_new[$component], $this->domDecodeOptions(array_filter($form_state->getValue([$component, $section]))));
           $config_count[$component]++;
         }
       }
@@ -710,19 +710,19 @@ protected function getComponentList(FormStateInterface $form_state) {
     foreach ($components as $component => $component_info) {
       $component_export = $component_info;
       foreach ($sections as $section) {
-        $component_export['_features_options'][$section] = array();
-        $component_export['_features_selected'][$section] = array();
+        $component_export['_features_options'][$section] = [];
+        $component_export['_features_selected'][$section] = [];
       }
       if (!empty($component_info)) {
-        $exported_components = !empty($exported_features_info[$component]) ? $exported_features_info[$component] : array();
-        $new_components = !empty($new_features_info[$component]) ? $new_features_info[$component] : array();
+        $exported_components = !empty($exported_features_info[$component]) ? $exported_features_info[$component] : [];
+        $new_components = !empty($new_features_info[$component]) ? $new_features_info[$component] : [];
 
         foreach ($component_info as $key => $label) {
           $config_name = $this->featuresManager->getFullName($component, $key);
           // If checkbox in Sources is checked, move it to Added section.
-          if (!$form_state->isValueEmpty(array($component, 'sources', 'selected', $key))) {
-            $form_state->setValue(array($component, 'sources', 'selected', $key), FALSE);
-            $form_state->setValue(array($component, 'added', $key), 1);
+          if (!$form_state->isValueEmpty([$component, 'sources', 'selected', $key])) {
+            $form_state->setValue([$component, 'sources', 'selected', $key], FALSE);
+            $form_state->setValue([$component, 'added', $key], 1);
             $component_export['_features_options']['added'][$key] = $this->configLabel($component, $key, $label);
             $component_export['_features_selected']['added'][$key] = $key;
             // If this was previously excluded, we don't need to set it as
@@ -746,8 +746,8 @@ protected function getComponentList(FormStateInterface $form_state) {
               // means it was an auto-detect that was previously part of the
               // export and is now de-selected in UI.
               if ($form_state->isSubmitted() &&
-                  ($form_state->hasValue(array($component, 'included', $key)) ||
-                  ($form_state->isValueEmpty(array($component, 'detected', $key)))) &&
+                  ($form_state->hasValue([$component, 'included', $key]) ||
+                  ($form_state->isValueEmpty([$component, 'detected', $key]))) &&
                   empty($config_new[$component][$key])) {
                 $section = 'detected';
                 $default_value = FALSE;
@@ -755,9 +755,9 @@ protected function getComponentList(FormStateInterface $form_state) {
               // Unless it's unchecked in the form, then move it to Newly
               // disabled item.
               elseif ($form_state->isSubmitted() &&
-                  $form_state->isValueEmpty(array($component, 'added', $key)) &&
-                  $form_state->isValueEmpty(array($component, 'detected', $key)) &&
-                  $form_state->isValueEmpty(array($component, 'included', $key))) {
+                  $form_state->isValueEmpty([$component, 'added', $key]) &&
+                  $form_state->isValueEmpty([$component, 'detected', $key]) &&
+                  $form_state->isValueEmpty([$component, 'included', $key])) {
                 $section = 'added';
                 $default_value = FALSE;
               }
@@ -777,16 +777,16 @@ protected function getComponentList(FormStateInterface $form_state) {
               // If it's already checked in Added or Sources, leave it in Added
               // as checked.
               if ($form_state->isSubmitted() &&
-                  (!$form_state->isValueEmpty(array($component, 'added', $key)) ||
-                   !$form_state->isValueEmpty(array($component, 'sources', 'selected', $key)))) {
+                  (!$form_state->isValueEmpty([$component, 'added', $key]) ||
+                   !$form_state->isValueEmpty([$component, 'sources', 'selected', $key]))) {
                 $section = 'added';
                 $default_value = $key;
               }
               // If it's already been unchecked, leave it unchecked.
               elseif ($form_state->isSubmitted() &&
-                  $form_state->isValueEmpty(array($component, 'sources', 'selected', $key)) &&
-                  $form_state->isValueEmpty(array($component, 'detected', $key)) &&
-                  !$form_state->hasValue(array($component, 'added', $key))) {
+                  $form_state->isValueEmpty([$component, 'sources', 'selected', $key]) &&
+                  $form_state->isValueEmpty([$component, 'detected', $key]) &&
+                  !$form_state->hasValue([$component, 'added', $key])) {
                 $section = 'detected';
                 $default_value = FALSE;
               }
@@ -817,10 +817,10 @@ protected function getComponentList(FormStateInterface $form_state) {
             // at 'input'.
             if ($form_state->isSubmitted()) {
               if (!$default_value) {
-                $form_state->setValue(array($component, $section, $key), FALSE);
+                $form_state->setValue([$component, $section, $key], FALSE);
               }
               else {
-                $form_state->setValue(array($component, $section, $key), 1);
+                $form_state->setValue([$component, $section, $key], 1);
               }
             }
           }
@@ -833,9 +833,9 @@ protected function getComponentList(FormStateInterface $form_state) {
           else {
             // Option was not part of the new export.
             $added = FALSE;
-            foreach (array('included', 'added') as $section) {
+            foreach (['included', 'added'] as $section) {
               // Restore any user-selected checkboxes.
-              if (!$form_state->isValueEmpty(array($component, $section, $key))) {
+              if (!$form_state->isValueEmpty([$component, $section, $key])) {
                 $component_export['_features_options'][$section][$key] = $this->configLabel($component, $key, $label);
                 $component_export['_features_selected'][$section][$key] = $key;
                 $added = TRUE;
@@ -927,12 +927,12 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     }
 
     // Set default redirect, but allow generators to change it later.
-    $form_state->setRedirect('features.edit', array('featurename' => $this->package->getMachineName()));
+    $form_state->setRedirect('features.edit', ['featurename' => $this->package->getMachineName()]);
     if ($method_id == 'import_missing') {
       $this->importMissing();
     }
     elseif (!empty($method_id)) {
-      $packages = array($this->package->getMachineName());
+      $packages = [$this->package->getMachineName()];
       $this->generator->generatePackages($method_id, $bundle, $packages);
       $this->generator->applyExportFormSubmit($method_id, $form, $form_state);
     }
@@ -947,7 +947,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
    *   Config array to be exported.
    */
   protected function updatePackageConfig(FormStateInterface $form_state) {
-    $config = array();
+    $config = [];
     $components = $this->getComponentList($form_state);
     foreach ($components['config_new'] as $config_type => $items) {
       foreach ($items as $name) {
@@ -969,10 +969,10 @@ protected function importMissing() {
         $type = ConfigurationItem::fromConfigStringToConfigType($item['type']);
         try {
           $this->configRevert->import($type, $item['name_short']);
-          drupal_set_message($this->t('Imported @name', array('@name' => $config_name)));
+          drupal_set_message($this->t('Imported @name', ['@name' => $config_name]));
         } catch (\Exception $e) {
           drupal_set_message($this->t('Error importing @name : @message',
-            array('@name' => $config_name, '@message' => $e->getMessage())), 'error');
+            ['@name' => $config_name, '@message' => $e->getMessage()]), 'error');
         }
       }
     }
@@ -1010,7 +1010,7 @@ protected function updateRequired() {
    *   suitable for storing in the info.yml file.
    */
   protected function updateConstrained($constraint) {
-    $constrained = array();
+    $constrained = [];
     foreach ($this->{$constraint} as $type => $item) {
       foreach ($item as $name => $value) {
         $constrained[] = $this->featuresManager->getFullName($type, $name);
@@ -1061,7 +1061,7 @@ protected function domDecode($key) {
    */
   protected function domDecodeOptions(array $options, $keys_only = FALSE) {
     $replacements = array_flip($this->domEncodeMap());
-    $encoded = array();
+    $encoded = [];
     foreach ($options as $key => $value) {
       $encoded[strtr($key, $replacements)] = $keys_only ? $value : strtr($value, $replacements);
     }
@@ -1075,7 +1075,7 @@ protected function domDecodeOptions(array $options, $keys_only = FALSE) {
    *   An encoding map.
    */
   protected function domEncodeMap() {
-    return array(
+    return [
       ':' => '__' . ord(':') . '__',
       '/' => '__' . ord('/') . '__',
       ',' => '__' . ord(',') . '__',
@@ -1085,7 +1085,7 @@ protected function domEncodeMap() {
       '%' => '__' . ord('%') . '__',
       ')' => '__' . ord(')') . '__',
       '(' => '__' . ord('(') . '__',
-    );
+    ];
   }
 
 }
diff --git a/web/modules/features/modules/features_ui/src/Form/FeaturesExportForm.php b/web/modules/features/modules/features_ui/src/Form/FeaturesExportForm.php
index d2ffeedd381657becdaff2c91ba93023a783f5a0..bed30b10e95ef052006584821bf09e15753f4da4 100644
--- a/web/modules/features/modules/features_ui/src/Form/FeaturesExportForm.php
+++ b/web/modules/features/modules/features_ui/src/Form/FeaturesExportForm.php
@@ -139,10 +139,10 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     // callback.
     $form['#packages'] = $packages;
     $form['#profile_package'] = $current_bundle->getProfileName();
-    $form['header'] = array(
+    $form['header'] = [
       '#type' => 'container',
-      '#attributes' => array('class' => 'features-header'),
-    );
+      '#attributes' => ['class' => 'features-header'],
+    ];
 
     $bundle_options = $this->assigner->getBundleOptions();
 
@@ -153,29 +153,29 @@ public function buildForm(array $form, FormStateInterface $form_state) {
 
     $form['#prefix'] = '<div id="edit-features-wrapper">';
     $form['#suffix'] = '</div>';
-    $form['header']['bundle'] = array(
+    $form['header']['bundle'] = [
       '#title' => $this->t('Bundle'),
       '#type' => 'select',
       '#options' => $bundle_options,
       '#default_value' => $current_bundle->getMachineName(),
       '#prefix' => '<div id="edit-package-set-wrapper">',
       '#suffix' => '</div>',
-      '#ajax' => array(
+      '#ajax' => [
         'callback' => '::updatePreview',
         'wrapper' => 'edit-features-preview-wrapper',
-      ),
-      '#attributes' => array(
+      ],
+      '#attributes' => [
         'data-new-package-set' => 'status',
-      ),
-    );
+      ],
+    ];
 
     $form['preview'] = $this->buildListing($packages, $current_bundle);
 
-    $form['#attached'] = array(
-      'library' => array(
+    $form['#attached'] = [
+      'library' => [
         'features_ui/drupal.features_ui.admin',
-      ),
-    );
+      ],
+    ];
 
     if (\Drupal::currentUser()->hasPermission('export configuration')) {
       // Offer available generation methods.
@@ -183,24 +183,24 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       // Sort generation methods by weight.
       uasort($generation_info, '\Drupal\Component\Utility\SortArray::sortByWeightElement');
 
-      $form['description'] = array(
+      $form['description'] = [
         '#markup' => '<p>' . $this->t('Use an export method button below to generate the selected features.') . '</p>',
-      );
+      ];
 
-      $form['actions'] = array('#type' => 'actions', '#tree' => TRUE);
+      $form['actions'] = ['#type' => 'actions', '#tree' => TRUE];
       foreach ($generation_info as $method_id => $method) {
-        $form['actions'][$method_id] = array(
+        $form['actions'][$method_id] = [
           '#type' => 'submit',
           '#name' => $method_id,
-          '#value' => $this->t('@name', array('@name' => $method['name'])),
-          '#attributes' => array(
+          '#value' => $this->t('@name', ['@name' => $method['name']]),
+          '#attributes' => [
             'title' => Html::escape($method['description']),
-          ),
-        );
+          ],
+        ];
       }
     }
 
-    $form['#pre_render'][] = array(get_class($this), 'preRenderRemoveInvalidCheckboxes');
+    $form['#pre_render'][] = [get_class($this), 'preRenderRemoveInvalidCheckboxes'];
 
     return $form;
   }
@@ -230,16 +230,16 @@ public function updatePreview($form, FormStateInterface $form_state) {
    */
   protected function buildListing(array $packages, FeaturesBundleInterface $bundle) {
 
-    $header = array(
-      'name' => array('data' => $this->t('Feature')),
-      'machine_name' => array('data' => $this->t('')),
-      'details' => array('data' => $this->t('Description'), 'class' => array(RESPONSIVE_PRIORITY_LOW)),
-      'version' => array('data' => $this->t('Version'), 'class' => array(RESPONSIVE_PRIORITY_LOW)),
-      'status' => array('data' => $this->t('Status'), 'class' => array(RESPONSIVE_PRIORITY_LOW)),
-      'state' => array('data' => $this->t('State'), 'class' => array(RESPONSIVE_PRIORITY_LOW)),
-    );
+    $header = [
+      'name' => ['data' => $this->t('Feature')],
+      'machine_name' => ['data' => $this->t('')],
+      'details' => ['data' => $this->t('Description'), 'class' => [RESPONSIVE_PRIORITY_LOW]],
+      'version' => ['data' => $this->t('Version'), 'class' => [RESPONSIVE_PRIORITY_LOW]],
+      'status' => ['data' => $this->t('Status'), 'class' => [RESPONSIVE_PRIORITY_LOW]],
+      'state' => ['data' => $this->t('State'), 'class' => [RESPONSIVE_PRIORITY_LOW]],
+    ];
 
-    $options = array();
+    $options = [];
     $first = TRUE;
     foreach ($packages as $package) {
       if ($first && $package->getStatus() == FeaturesManagerInterface::STATUS_NO_EXPORT) {
@@ -250,25 +250,25 @@ protected function buildListing(array $packages, FeaturesBundleInterface $bundle
           continue;
         }
         $first = FALSE;
-        $options[] = array(
-          'name' => array(
+        $options[] = [
+          'name' => [
             'data' => $this->t('The following packages are not exported.'),
             'class' => 'features-export-header-row',
             'colspan' => 6,
-          ),
-        );
+          ],
+        ];
       }
       $options[$package->getMachineName()] = $this->buildPackageDetail($package, $bundle);
     }
 
-    $element = array(
+    $element = [
       '#type' => 'tableselect',
       '#header' => $header,
       '#options' => $options,
-      '#attributes' => array('class' => array('features-listing')),
+      '#attributes' => ['class' => ['features-listing']],
       '#prefix' => '<div id="edit-features-preview-wrapper">',
       '#suffix' => '</div>',
-    );
+    ];
 
     return $element;
   }
@@ -287,12 +287,12 @@ protected function buildListing(array $packages, FeaturesBundleInterface $bundle
   protected function buildPackageDetail(Package $package, FeaturesBundleInterface $bundle) {
     $config_collection = $this->featuresManager->getConfigCollection();
 
-    $url = Url::fromRoute('features.edit', array('featurename' => $package->getMachineName()));
+    $url = Url::fromRoute('features.edit', ['featurename' => $package->getMachineName()]);
 
-    $element['name'] = array(
+    $element['name'] = [
       'data' => \Drupal::l($package->getName(), $url),
-      'class' => array('feature-name'),
-    );
+      'class' => ['feature-name'],
+    ];
     $machine_name = $package->getMachineName();
     // Except for the 'unpackaged' pseudo-package, display the full name, since
     // that's what will be generated.
@@ -300,128 +300,128 @@ protected function buildPackageDetail(Package $package, FeaturesBundleInterface
       $machine_name = $bundle->getFullName($machine_name);
     }
     $element['machine_name'] = $machine_name;
-    $element['status'] = array(
+    $element['status'] = [
       'data' => $this->featuresManager->statusLabel($package->getStatus()),
-      'class' => array('column-nowrap'),
-    );
+      'class' => ['column-nowrap'],
+    ];
     // Use 'data' instead of plain string value so a blank version doesn't
     // remove column from table.
-    $element['version'] = array(
+    $element['version'] = [
       'data' => Html::escape($package->getVersion()),
-      'class' => array('column-nowrap'),
-    );
+      'class' => ['column-nowrap'],
+    ];
     $overrides = $this->featuresManager->detectOverrides($package);
     $new_config = $this->featuresManager->detectNew($package);
-    $conflicts = array();
-    $missing = array();
-    $moved = array();
+    $conflicts = [];
+    $missing = [];
+    $moved = [];
 
     if ($package->getStatus() == FeaturesManagerInterface::STATUS_NO_EXPORT) {
-      $overrides = array();
-      $new_config = array();
+      $overrides = [];
+      $new_config = [];
     }
     // Bundle package configuration by type.
-    $package_config = array();
+    $package_config = [];
     foreach ($package->getConfig() as $item_name) {
       if (isset($config_collection[$item_name])) {
         $item = $config_collection[$item_name];
-        $package_config[$item->getType()][] = array(
+        $package_config[$item->getType()][] = [
           'name' => Html::escape($item_name),
           'label' => Html::escape($item->getLabel()),
           'class' => in_array($item_name, $overrides) ? 'features-override' :
             (in_array($item_name, $new_config) ? 'features-detected' : ''),
-        );
+        ];
       }
     }
     // Conflict config from other modules.
     foreach ($package->getConfigOrig() as $item_name) {
       if (!isset($config_collection[$item_name])) {
         $missing[] = $item_name;
-        $package_config['missing'][] = array(
+        $package_config['missing'][] = [
           'name' => Html::escape($item_name),
           'label' => Html::escape($item_name),
           'class' => 'features-missing',
-        );
+        ];
       }
       elseif (!in_array($item_name, $package->getConfig())) {
         $item = $config_collection[$item_name];
         if (empty($item->getProvider())) {
           $conflicts[] = $item_name;
           $package_name = !empty($item->getPackage()) ? $item->getPackage() : $this->t('PACKAGE NOT ASSIGNED');
-          $package_config[$item->getType()][] = array(
+          $package_config[$item->getType()][] = [
             'name' => Html::escape($package_name),
             'label' => Html::escape($item->getLabel()),
             'class' => 'features-conflict',
-          );
+          ];
         }
         else {
           $moved[] = $item_name;
           $package_name = !empty($item->getPackage()) ? $item->getPackage() : $this->t('PACKAGE NOT ASSIGNED');
-          $package_config[$item->getType()][] = array(
-            'name' => $this->t('Moved to @package', array('@package' => $package_name)),
+          $package_config[$item->getType()][] = [
+            'name' => $this->t('Moved to @package', ['@package' => $package_name]),
             'label' => Html::escape($item->getLabel()),
             'class' => 'features-moved',
-          );
+          ];
         }
       }
     }
     // Add dependencies.
-    $package_config['dependencies'] = array();
+    $package_config['dependencies'] = [];
     foreach ($package->getDependencies() as $dependency) {
-      $package_config['dependencies'][] = array(
+      $package_config['dependencies'][] = [
         'name' => $dependency,
-        'label' => $this->moduleHandler->getName($dependency),
+        'label' => $this->moduleHandler->moduleExists($dependency) ? $this->moduleHandler->getName($dependency) : $dependency,
         'class' => '',
-      );
+      ];
     }
 
     $class = '';
     $state_links = [];
     if (!empty($conflicts)) {
-      $state_links[] = array(
+      $state_links[] = [
         '#type' => 'link',
         '#title' => $this->t('Conflicts'),
-        '#url' => Url::fromRoute('features.edit', array('featurename' => $package->getMachineName())),
-        '#attributes' => array('class' => array('features-conflict')),
-      );
+        '#url' => Url::fromRoute('features.edit', ['featurename' => $package->getMachineName()]),
+        '#attributes' => ['class' => ['features-conflict']],
+      ];
     }
     if (!empty($overrides)) {
-      $state_links[] = array(
+      $state_links[] = [
         '#type' => 'link',
         '#title' => $this->featuresManager->stateLabel(FeaturesManagerInterface::STATE_OVERRIDDEN),
-        '#url' => Url::fromRoute('features.diff', array('featurename' => $package->getMachineName())),
-        '#attributes' => array('class' => array('features-override')),
-      );
+        '#url' => Url::fromRoute('features.diff', ['featurename' => $package->getMachineName()]),
+        '#attributes' => ['class' => ['features-override']],
+      ];
     }
     if (!empty($new_config)) {
-      $state_links[] = array(
+      $state_links[] = [
         '#type' => 'link',
         '#title' => $this->t('New detected'),
-        '#url' => Url::fromRoute('features.diff', array('featurename' => $package->getMachineName())),
-        '#attributes' => array('class' => array('features-detected')),
-      );
+        '#url' => Url::fromRoute('features.diff', ['featurename' => $package->getMachineName()]),
+        '#attributes' => ['class' => ['features-detected']],
+      ];
     }
     if (!empty($missing) && ($package->getStatus() == FeaturesManagerInterface::STATUS_INSTALLED)) {
-      $state_links[] = array(
+      $state_links[] = [
         '#type' => 'link',
         '#title' => $this->t('Missing'),
-        '#url' => Url::fromRoute('features.edit', array('featurename' => $package->getMachineName())),
-        '#attributes' => array('class' => array('features-missing')),
-      );
+        '#url' => Url::fromRoute('features.edit', ['featurename' => $package->getMachineName()]),
+        '#attributes' => ['class' => ['features-missing']],
+      ];
     }
     if (!empty($moved)) {
-      $state_links[] = array(
+      $state_links[] = [
         '#type' => 'link',
         '#title' => $this->t('Moved'),
-        '#url' => Url::fromRoute('features.edit', array('featurename' => $package->getMachineName())),
-        '#attributes' => array('class' => array('features-moved')),
-      );
+        '#url' => Url::fromRoute('features.edit', ['featurename' => $package->getMachineName()]),
+        '#attributes' => ['class' => ['features-moved']],
+      ];
     }
     if (!empty($state_links)) {
-      $element['state'] = array(
+      $element['state'] = [
         'data' => $state_links,
-        'class' => array('column-nowrap'),
-      );
+        'class' => ['column-nowrap'],
+      ];
     }
     else {
       $element['state'] = '';
@@ -473,7 +473,7 @@ protected function buildPackageDetail(Package $package, FeaturesBundleInterface
     );
     $details['table'] = array(
       '#type' => 'details',
-      '#title' => array('#markup' => $this->t('Included configuration')),
+      '#title' => $this->t('Included configuration'),
       '#description' => array('data' => $element['table']),
     );
     $element['details'] = array(
diff --git a/web/modules/features/modules/features_ui/src/Tests/FeaturesUITest.php b/web/modules/features/modules/features_ui/src/Tests/FeaturesUITest.php
index 51c4abb9c043017b1e2c371bd5f2f81dca810723..12f92ae5be9b5c5b31037bdce8a5ee26e2c2d39f 100644
--- a/web/modules/features/modules/features_ui/src/Tests/FeaturesUITest.php
+++ b/web/modules/features/modules/features_ui/src/Tests/FeaturesUITest.php
@@ -34,7 +34,7 @@ public function testFeaturesUI() {
     $this->assertText($this->t('You have not yet created any bundles. Before generating features, you may wish to create a bundle to group your features within.'));
     // Creating custom bundle.
     $this->drupalGet('admin/config/development/features/bundle');
-    $this->drupalPostAjaxForm(NULL, array('bundle[bundle_select]' => 'new'), 'bundle[bundle_select]');
+    $this->drupalPostAjaxForm(NULL, ['bundle[bundle_select]' => 'new'], 'bundle[bundle_select]');
     $edit = [
       'bundle[name]' => 'foo',
       'bundle[machine_name]' => 'foo',
diff --git a/web/modules/features/src/Commands/FeaturesCommands.php b/web/modules/features/src/Commands/FeaturesCommands.php
index 79807b63578b584bea138c6bff241d78c031d0b2..a0dec38e30d46f31d88d9c0a65f73b5d8e2cb2fb 100644
--- a/web/modules/features/src/Commands/FeaturesCommands.php
+++ b/web/modules/features/src/Commands/FeaturesCommands.php
@@ -9,6 +9,7 @@
 use Drupal\features\Exception\DomainException;
 use Drupal\features\Exception\InvalidArgumentException;
 use Drupal\features\FeaturesAssignerInterface;
+use Drupal\features\FeaturesBundleInterface;
 use Drupal\features\FeaturesGeneratorInterface;
 use Drupal\features\FeaturesManagerInterface;
 use Drupal\features\Plugin\FeaturesGeneration\FeaturesGenerationWrite;
@@ -246,7 +247,7 @@ public function status($keys = NULL, array $options = self::OPTIONS_STATUS) {
   public function listPackages($package_name = NULL, $options = self::OPTIONS_LIST) {
     $assigner = $this->featuresOptions($options);
     $current_bundle = $assigner->getBundle();
-    $namespace = $current_bundle->isDefault() ? '' : $current_bundle->getMachineName();
+    $namespace = $current_bundle->isDefault() ? FeaturesBundleInterface::DEFAULT_BUNDLE : $current_bundle->getMachineName();
 
     $manager = $this->manager;
     $packages = $manager->getPackages();
@@ -312,7 +313,7 @@ public function listPackages($package_name = NULL, $options = self::OPTIONS_LIST
   public function importAll($options = self::OPTIONS_IMPORT_ALL) {
     $assigner = $this->featuresOptions($options);
     $currentBundle = $assigner->getBundle();
-    $namespace = $currentBundle->isDefault() ? '' : $currentBundle->getMachineName();
+    $namespace = $currentBundle->isDefault() ? FeaturesBundleInterface::DEFAULT_BUNDLE : $currentBundle->getMachineName();
 
     $manager = $this->manager;
     $packages = $manager->getPackages();
diff --git a/web/modules/features/src/Controller/FeaturesController.php b/web/modules/features/src/Controller/FeaturesController.php
index 701895aa2ad8733d7394c083d191c0960a8f4815..e456577e316d9b5f7a3c21e776c4d6501bc31cb9 100644
--- a/web/modules/features/src/Controller/FeaturesController.php
+++ b/web/modules/features/src/Controller/FeaturesController.php
@@ -69,7 +69,7 @@ public function downloadExport($uri, Request $request) {
         throw new AccessDeniedHttpException();
       }
 
-      $request = new Request(array('file' => $uri));
+      $request = new Request(['file' => $uri]);
       return $this->fileDownloadController->download($request, 'temporary');
     }
   }
diff --git a/web/modules/features/src/Entity/FeaturesBundle.php b/web/modules/features/src/Entity/FeaturesBundle.php
index 5901433105527291d30a2c6ecb04b787f86c4e99..ced0be6de6113ec46657f33cb6be0d3922a9731a 100644
--- a/web/modules/features/src/Entity/FeaturesBundle.php
+++ b/web/modules/features/src/Entity/FeaturesBundle.php
@@ -193,7 +193,7 @@ public function setProfileName($machine_name) {
    * {@inheritdoc}
    */
   public function getEnabledAssignments() {
-    $list = array();
+    $list = [];
     foreach ($this->assignments as $method_id => $method) {
       if ($method['enabled']) {
         $list[$method_id] = $method_id;
@@ -221,7 +221,7 @@ public function setEnabledAssignments(array $assignments) {
    * {@inheritdoc}
    */
   public function getAssignmentWeights() {
-    $list = array();
+    $list = [];
     foreach ($this->assignments as $method_id => $method) {
       $list[$method_id] = $method['weight'];
     }
@@ -275,7 +275,7 @@ public function getAssignmentSettings($method_id = NULL) {
       }
     }
     else {
-      $list = array();
+      $list = [];
       foreach (array_keys($this->assignments) as $method_id) {
         $list[$method_id] = $this->getAssignmentSettings($method_id);
       }
diff --git a/web/modules/features/src/FeaturesAssigner.php b/web/modules/features/src/FeaturesAssigner.php
index 75bf5a82d974caa382a0a3f0bf99cd66305e12e2..f06b0d16755ffa5579737c0dfdeca126357c7a3f 100644
--- a/web/modules/features/src/FeaturesAssigner.php
+++ b/web/modules/features/src/FeaturesAssigner.php
@@ -113,7 +113,7 @@ public function initFeaturesManager() {
    * {@inheritdoc}
    */
   public function reset() {
-    $this->methods = array();
+    $this->methods = [];
     $this->featuresManager->reset();
   }
 
@@ -181,7 +181,7 @@ public function getAssignmentMethods() {
    */
   protected function getAssignmentMethodInstance($method_id) {
     if (!isset($this->methods[$method_id])) {
-      $instance = $this->assignerManager->createInstance($method_id, array());
+      $instance = $this->assignerManager->createInstance($method_id, []);
       $instance->setFeaturesManager($this->featuresManager);
       $instance->setAssigner($this);
       $instance->setEntityTypeManager($this->entityTypeManager);
@@ -261,7 +261,7 @@ public function setCurrent(FeaturesBundleInterface $bundle) {
    */
   public function getBundleList() {
     if (empty($this->bundles)) {
-      $this->bundles = array();
+      $this->bundles = [];
       foreach ($this->entityTypeManager->getStorage('features_bundle')->loadMultiple() as $machine_name => $bundle) {
         $this->bundles[$machine_name] = $bundle;
       }
@@ -279,7 +279,7 @@ public function findBundleByName($name, $create = FALSE) {
         return $bundle;
       }
     }
-    $machine_name = strtolower(str_replace(array(' ', '-'), '_', $name));
+    $machine_name = strtolower(str_replace([' ', '-'], '_', $name));
     if (isset($bundles[$machine_name])) {
       return $bundles[$machine_name];
     }
@@ -311,7 +311,7 @@ public function createBundleFromDefault($machine_name, $name = NULL, $descriptio
       $bundle->setDescription($description);
     }
     else {
-      $bundle->setDescription(t('Auto-generated bundle from package @name', array('@name' => $name)));
+      $bundle->setDescription(t('Auto-generated bundle from package @name', ['@name' => $name]));
     }
     $bundle->setIsProfile($is_profile);
     if (isset($profile_name)) {
@@ -374,7 +374,7 @@ public function createBundlesFromPackages() {
    */
   public function getBundleOptions() {
     $list = $this->getBundleList();
-    $result = array();
+    $result = [];
     foreach ($list as $machine_name => $bundle) {
       $result[$machine_name] = $bundle->getName();
     }
diff --git a/web/modules/features/src/FeaturesConfigDependencyManager.php b/web/modules/features/src/FeaturesConfigDependencyManager.php
index cca3507a18a6ea9b6e066835b5d95ca6f0a8dbf8..ea01e305cd632464df1916d1e27b4199d908e5f6 100644
--- a/web/modules/features/src/FeaturesConfigDependencyManager.php
+++ b/web/modules/features/src/FeaturesConfigDependencyManager.php
@@ -17,9 +17,9 @@ class FeaturesConfigDependencyManager extends ConfigDependencyManager{
    * {@inheritdoc}
    */
   public function getDependentEntities($type, $name) {
-    $dependent_entities = array();
+    $dependent_entities = [];
 
-    $entities_to_check = array();
+    $entities_to_check = [];
     if ($type == 'config') {
       $entities_to_check[] = $name;
     }
@@ -42,7 +42,7 @@ public function getDependentEntities($type, $name) {
       // always after field storages. This is because field storages need to be
       // created before a field.
       $this->sorted_graph = $this->getGraph();
-      uasort($this->sorted_graph, array($this, 'sortGraph'));
+      uasort($this->sorted_graph, [$this, 'sortGraph']);
     }
     return array_replace(array_intersect_key($this->sorted_graph, $dependencies), $dependencies);
   }
diff --git a/web/modules/features/src/FeaturesConfigInstaller.php b/web/modules/features/src/FeaturesConfigInstaller.php
index 2d7edd0e6915d43f4cf7bfb5c1b9614e71d5c6a4..da4c2a94170e885ec215bb6dc7e63e2da7a1a2fa 100644
--- a/web/modules/features/src/FeaturesConfigInstaller.php
+++ b/web/modules/features/src/FeaturesConfigInstaller.php
@@ -75,7 +75,7 @@ protected function findPreExistingConfiguration(StorageInterface $storage) {
     $features_config = array_keys($this->featuresManager->listExistingConfig());
     // Map array so we can use isset instead of in_array for faster access.
     $features_config = array_combine($features_config, $features_config);
-    $existing_configuration = array();
+    $existing_configuration = [];
     // Gather information about all the supported collections.
     $collection_info = $this->configManager->getConfigCollectionInfo();
 
diff --git a/web/modules/features/src/FeaturesExtensionStoragesByDirectory.php b/web/modules/features/src/FeaturesExtensionStoragesByDirectory.php
new file mode 100644
index 0000000000000000000000000000000000000000..6c0269e9e106967e369fdcb9c119821d65398015
--- /dev/null
+++ b/web/modules/features/src/FeaturesExtensionStoragesByDirectory.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace Drupal\features;
+
+/**
+ * Wraps FeaturesInstallStorage to support multiple configuration
+ * directories.
+ */
+class FeaturesExtensionStoragesByDirectory extends FeaturesExtensionStorages implements FeaturesExtensionStoragesByDirectoryInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function listAllByDirectory($prefix = '') {
+    if (!isset($this->configurationLists[$prefix])) {
+      $this->configurationLists[$prefix] = [];
+      foreach ($this->extensionStorages as $directory => $extension_storage) {
+        $this->configurationLists[$prefix] += array_fill_keys($extension_storage->listAll($prefix), $directory);
+      }
+    }
+    return $this->configurationLists[$prefix];
+  }
+
+}
diff --git a/web/modules/features/src/FeaturesExtensionStoragesByDirectoryInterface.php b/web/modules/features/src/FeaturesExtensionStoragesByDirectoryInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..e955cecce3cf26963ffd77c5a72ce6e2f7ea0c74
--- /dev/null
+++ b/web/modules/features/src/FeaturesExtensionStoragesByDirectoryInterface.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace Drupal\features;
+
+/**
+ * Defines an extended interface for extension storages.
+ */
+interface FeaturesExtensionStoragesByDirectoryInterface extends FeaturesExtensionStoragesInterface {
+
+  /**
+   * Returns a list of all configuration available from extensions.
+   *
+   * This method was made public late in the 8.x-3.x cycle and so is not
+   * included in the interface.
+   *
+   * @param string $prefix
+   *   (optional) The prefix to search for. If omitted, all configuration object
+   *   names that exist are returned.
+   *
+   * @return array
+   *   An array with configuration item names as keys and configuration
+   *   directories as values.
+   */
+  public function listAllByDirectory($prefix = '');
+
+}
diff --git a/web/modules/features/src/FeaturesGenerationMethodBase.php b/web/modules/features/src/FeaturesGenerationMethodBase.php
index 485fa09fe628ef8107b554ec4d7fab84948d8075..e329f686399b02c82aa7c24daab9566d8a062145 100644
--- a/web/modules/features/src/FeaturesGenerationMethodBase.php
+++ b/web/modules/features/src/FeaturesGenerationMethodBase.php
@@ -65,7 +65,7 @@ protected function mergeInfoFile($package_info, $info_file_uri) {
   /**
    * {@inheritdoc}
    */
-  public function prepare(array &$packages = array(), FeaturesBundleInterface $bundle = NULL) {
+  public function prepare(array &$packages = [], FeaturesBundleInterface $bundle = NULL) {
     // If no packages were specified, get all packages.
     if (empty($packages)) {
       $packages = $this->featuresManager->getPackages();
diff --git a/web/modules/features/src/FeaturesGenerationMethodInterface.php b/web/modules/features/src/FeaturesGenerationMethodInterface.php
index b3191f202631c0d158dade343d9df4b99435dbe1..92b939280492a9e1d18342ad6f026ca991f9fdc8 100644
--- a/web/modules/features/src/FeaturesGenerationMethodInterface.php
+++ b/web/modules/features/src/FeaturesGenerationMethodInterface.php
@@ -37,7 +37,7 @@ public function setAssigner(FeaturesAssignerInterface $assigner);
    * @return array
    *   An array of packages data.
    */
-  public function prepare(array &$packages = array(), FeaturesBundleInterface $bundle = NULL);
+  public function prepare(array &$packages = [], FeaturesBundleInterface $bundle = NULL);
 
   /**
    * Performs package generation.
@@ -56,7 +56,7 @@ public function prepare(array &$packages = array(), FeaturesBundleInterface $bun
    *   - 'message': a message about the result of the operation.
    *   - 'variables': an array of substitutions to be used in the message.
    */
-  public function generate(array $packages = array(), FeaturesBundleInterface $bundle = NULL);
+  public function generate(array $packages = [], FeaturesBundleInterface $bundle = NULL);
 
   /**
    * Responds to the submission of
diff --git a/web/modules/features/src/FeaturesGenerator.php b/web/modules/features/src/FeaturesGenerator.php
index ce461cbf23a9ee7e18678cecf22378ba89321608..ae21e60b7a04a1a3e29bde734740246ec21571ee 100644
--- a/web/modules/features/src/FeaturesGenerator.php
+++ b/web/modules/features/src/FeaturesGenerator.php
@@ -69,13 +69,13 @@ public function initFeaturesManager() {
    * {@inheritdoc}
    */
   public function reset() {
-    $this->methods = array();
+    $this->methods = [];
   }
 
   /**
    * {@inheritdoc}
    */
-  public function applyGenerationMethod($method_id, array $packages = array(), FeaturesBundleInterface $bundle = NULL) {
+  public function applyGenerationMethod($method_id, array $packages = [], FeaturesBundleInterface $bundle = NULL) {
     $method = $this->getGenerationMethodInstance($method_id);
     $method->prepare($packages, $bundle);
     return $method->generate($packages, $bundle);
@@ -107,7 +107,7 @@ public function getGenerationMethods() {
    */
   protected function getGenerationMethodInstance($method_id) {
     if (!isset($this->methods[$method_id])) {
-      $instance = $this->generatorManager->createInstance($method_id, array());
+      $instance = $this->generatorManager->createInstance($method_id, []);
       $instance->setFeaturesManager($this->featuresManager);
       $instance->setAssigner($this->assigner);
       $this->methods[$method_id] = $instance;
@@ -118,7 +118,7 @@ protected function getGenerationMethodInstance($method_id) {
   /**
    * {@inheritdoc}
    */
-  public function generatePackages($method_id, FeaturesBundleInterface $bundle, array $package_names = array()) {
+  public function generatePackages($method_id, FeaturesBundleInterface $bundle, array $package_names = []) {
     $this->featuresManager->setPackageBundleNames($bundle, $package_names);
     return $this->generate($method_id, $bundle, $package_names);
   }
@@ -144,7 +144,7 @@ public function generatePackages($method_id, FeaturesBundleInterface $bundle, ar
    *   - 'message': a message about the result of the operation.
    *   - 'variables': an array of substitutions to be used in the message.
    */
-  protected function generate($method_id, FeaturesBundleInterface $bundle, array $package_names = array()) {
+  protected function generate($method_id, FeaturesBundleInterface $bundle, array $package_names = []) {
     $packages = $this->featuresManager->getPackages();
 
     // Filter out the packages that weren't requested.
diff --git a/web/modules/features/src/FeaturesGeneratorInterface.php b/web/modules/features/src/FeaturesGeneratorInterface.php
index 485e71beaf41d7591a305e2c0b8d36adfc828a3d..0cafa145143558b25bc3ebd1c92b73a89c3b2b06 100644
--- a/web/modules/features/src/FeaturesGeneratorInterface.php
+++ b/web/modules/features/src/FeaturesGeneratorInterface.php
@@ -71,7 +71,7 @@ public function reset();
    *   - 'message': a message about the result of the operation.
    *   - 'variables': an array of substitutions to be used in the message.
    */
-  public function applyGenerationMethod($method_id, array $packages = array(), FeaturesBundleInterface $bundle = NULL);
+  public function applyGenerationMethod($method_id, array $packages = [], FeaturesBundleInterface $bundle = NULL);
 
   /**
    * Responds to the submission of
@@ -98,6 +98,6 @@ public function getGenerationMethods();
    *   Array of names of packages to be generated. If none are specified, all
    *   available packages will be added.
    */
-  public function generatePackages($method_id, FeaturesBundleInterface $bundle, array $package_names = array());
+  public function generatePackages($method_id, FeaturesBundleInterface $bundle, array $package_names = []);
 
 }
diff --git a/web/modules/features/src/FeaturesInstallStorage.php b/web/modules/features/src/FeaturesInstallStorage.php
index 3742ea17bc39b71bc934232f9e7f8a2934fc6b37..666b5d6803ded4287a04628bcda123e08d9c7535 100644
--- a/web/modules/features/src/FeaturesInstallStorage.php
+++ b/web/modules/features/src/FeaturesInstallStorage.php
@@ -66,7 +66,7 @@ public function __construct(StorageInterface $config_storage, $directory = self:
    */
   public function getAllFolders() {
     if (!isset($this->folders)) {
-      $this->folders = array();
+      $this->folders = [];
       $this->folders += $this->getCoreNames();
 
       $install_profile = Settings::get('install_profile');
@@ -117,8 +117,8 @@ public function getAllFolders() {
         // CHANGED START: Put Features modules first in list returned.
         // to allow features to override config provided by other extensions.
         $featuresManager = \Drupal::service('features.manager');
-        $features_list = array();
-        $module_list = array();
+        $features_list = [];
+        $module_list = [];
         foreach (array_keys($module_list_scan) as $module) {
           if ($featuresManager->isFeatureModule($module_list_scan[$module])) {
             $features_list[$module] = $module_list_scan[$module];
@@ -150,7 +150,7 @@ public function getAllFolders() {
             $profile_list = $listing->scan('profile');
           }
           if (isset($profile_list[$profile])) {
-            $profile_folders = $this->getComponentNames(array($profile_list[$profile]));
+            $profile_folders = $this->getComponentNames([$profile_list[$profile]]);
             $this->folders = $profile_folders + $this->folders;
           }
         }
diff --git a/web/modules/features/src/FeaturesManager.php b/web/modules/features/src/FeaturesManager.php
index cf9329707004fd6b5b87c58a1975480874b2ed84..07c46e0427855f187db15011ff2c764c1c941a29 100644
--- a/web/modules/features/src/FeaturesManager.php
+++ b/web/modules/features/src/FeaturesManager.php
@@ -39,7 +39,7 @@ class FeaturesManager implements FeaturesManagerInterface {
   /**
    * The extension storages.
    *
-   * @var \Drupal\features\FeaturesExtensionStoragesInterface
+   * @var \Drupal\features\FeaturesExtensionStoragesByDirectoryInterface
    */
   protected $extensionStorages;
 
@@ -148,7 +148,7 @@ public function __construct($root, EntityTypeManagerInterface $entity_type_manag
     $this->configFactory = $config_factory;
     $this->configReverter = $config_reverter;
     $this->settings = $config_factory->getEditable('features.settings');
-    $this->extensionStorages = new FeaturesExtensionStorages($this->configStorage);
+    $this->extensionStorages = new FeaturesExtensionStoragesByDirectory($this->configStorage);
     $this->extensionStorages->addStorage(InstallStorage::CONFIG_INSTALL_DIRECTORY);
     $this->extensionStorages->addStorage(InstallStorage::CONFIG_OPTIONAL_DIRECTORY);
     $this->packages = [];
@@ -196,10 +196,10 @@ public function getFullName($type, $name) {
    * {@inheritdoc}
    */
   public function getConfigType($fullname) {
-    $result = array(
+    $result = [
       'type' => '',
       'name_short' => '',
-    );
+    ];
     $prefix = FeaturesManagerInterface::SYSTEM_SIMPLE_CONFIG . '.';
     if (strpos($fullname, $prefix) !== FALSE) {
       $result['type'] = FeaturesManagerInterface::SYSTEM_SIMPLE_CONFIG;
@@ -320,7 +320,7 @@ public function loadPackage($module_name, $any = FALSE) {
    * {@inheritdoc}
    */
   public function filterPackages(array $packages, $namespace = '', $only_exported = FALSE) {
-    $result = array();
+    $result = [];
     /** @var \Drupal\features\Package $package */
     foreach ($packages as $key => $package) {
       // A package matches the namespace if:
@@ -417,7 +417,7 @@ public function isFeatureModule(Extension $module, FeaturesBundleInterface $bund
   /**
    * {@inheritdoc}
    */
-  public function listPackageDirectories(array $machine_names = array(), FeaturesBundleInterface $bundle = NULL) {
+  public function listPackageDirectories(array $machine_names = [], FeaturesBundleInterface $bundle = NULL) {
     if (empty($machine_names)) {
       $machine_names = array_keys($this->getPackages());
     }
@@ -438,7 +438,7 @@ public function listPackageDirectories(array $machine_names = array(), FeaturesB
       return in_array($module->getName(), $machine_names);
     });
 
-    $directories = array();
+    $directories = [];
     foreach ($modules as $module) {
       $directories[$module->getName()] = $module->getPath();
     }
@@ -546,7 +546,7 @@ public function initPackageFromExtension(Extension $extension) {
    * @param array $module_list
    * @return array $dependencies
    */
-  protected function getConfigDependency(ConfigurationItem $config, $module_list = array()) {
+  protected function getConfigDependency(ConfigurationItem $config, $module_list = []) {
     $dependencies = [];
     $type = $config->getType();
 
@@ -737,7 +737,7 @@ public function assignPackageDependencies(Package $package = NULL) {
       $packages = $this->getPackages();
     }
     else {
-      $packages = array($package);
+      $packages = [$package];
     }
     $module_list = $this->moduleHandler->getModuleList();
     $config_collection = $this->getConfigCollection();
@@ -940,7 +940,7 @@ protected function addInfoFile(Package $package) {
     }
 
     if ($package->getConfig()) {
-      foreach (array('excluded', 'required') as $constraint) {
+      foreach (['excluded', 'required'] as $constraint) {
         if (!empty($package->{'get' . $constraint}())) {
           $features_info[$constraint] = $package->{'get' . $constraint}();
         }
@@ -957,7 +957,7 @@ protected function addInfoFile(Package $package) {
     // The name and description need to be cast as strings from the
     // TranslatableMarkup objects returned by t() to avoid raising an
     // InvalidDataTypeException on Yaml serialization.
-    foreach (array('name', 'description') as $key) {
+    foreach (['name', 'description'] as $key) {
       $info[$key] = (string) $info[$key];
     }
 
@@ -1008,7 +1008,7 @@ protected function addPackageFiles(Package $package) {
   /**
    * {@inheritdoc}
    */
-  public function mergeInfoArray(array $info1, array $info2, array $keys = array()) {
+  public function mergeInfoArray(array $info1, array $info2, array $keys = []) {
     // If keys were specified, use only those.
     if (!empty($keys)) {
       $info2 = array_intersect_key($info2, array_fill_keys($keys, NULL));
@@ -1061,7 +1061,7 @@ public function listExtensionConfig(Extension $extension) {
    * {@inheritdoc}
    */
   public function listExistingConfig($installed = FALSE, FeaturesBundleInterface $bundle = NULL) {
-    $config = array();
+    $config = [];
     $existing = $this->getFeaturesModules($bundle, $installed);
     foreach ($existing as $extension) {
       // Keys are configuration item names and values are providing extension
@@ -1150,6 +1150,7 @@ protected function initConfigCollection($reset = FALSE) {
       $dependency_manager = $this->getFeaturesConfigDependencyManager();
       // List configuration provided by installed features.
       $existing_config = $this->listExistingConfig(NULL);
+      $existing_config_by_directory = $this->extensionStorages->listAllByDirectory();
       foreach (array_keys($config_types) as $config_type) {
         $config = $this->listConfigByType($config_type);
         foreach ($config as $item_name => $label) {
@@ -1162,7 +1163,7 @@ protected function initConfigCollection($reset = FALSE) {
             'type' => $config_type,
             'dependents' => array_keys($dependency_manager->getDependentEntities('config', $name)),
             // Default to the install directory.
-            'subdirectory' => InstallStorage::CONFIG_INSTALL_DIRECTORY,
+            'subdirectory' => isset($existing_config_by_directory[$name]) ? $existing_config_by_directory[$name] : InstallStorage::CONFIG_INSTALL_DIRECTORY,
             'package' => '',
             'providerExcluded' => NULL,
             'provider' => isset($existing_config[$name]) ? $existing_config[$name] : NULL,
@@ -1211,7 +1212,7 @@ public function getExportInfo(Package $package, FeaturesBundleInterface $bundle
       $path = dirname($extension_path);
     }
 
-    return array($full_name, $path);
+    return [$full_name, $path];
   }
 
   /**
@@ -1221,11 +1222,11 @@ public function detectOverrides(Package $feature, $include_new = FALSE) {
     /** @var \Drupal\config_update\ConfigDiffInterface $config_diff */
     $config_diff = \Drupal::service('config_update.config_diff');
 
-    $different = array();
+    $different = [];
     foreach ($feature->getConfig() as $name) {
       $active = $this->configStorage->read($name);
       $extension = $this->extensionStorages->read($name);
-      $extension = !empty($extension) ? $extension : array();
+      $extension = !empty($extension) ? $extension : [];
       if (($include_new || !empty($extension)) && !$config_diff->same($extension, $active)) {
         $different[] = $name;
       }
@@ -1241,7 +1242,7 @@ public function detectOverrides(Package $feature, $include_new = FALSE) {
    * {@inheritdoc}
    */
   public function detectNew(Package $feature) {
-    $result = array();
+    $result = [];
     foreach ($feature->getConfig() as $name) {
       $extension = $this->extensionStorages->read($name);
       if (empty($extension)) {
@@ -1256,7 +1257,7 @@ public function detectNew(Package $feature) {
    */
   public function detectMissing(Package $feature) {
     $config = $this->getConfigCollection();
-    $result = array();
+    $result = [];
     foreach ($feature->getConfigOrig() as $name) {
       if (!isset($config[$name])) {
         $result[] = $name;
@@ -1269,8 +1270,8 @@ public function detectMissing(Package $feature) {
    * {@inheritdoc}
    */
   public function reorderMissing(array $missing) {
-    $list = array();
-    $result = array();
+    $list = [];
+    $result = [];
     foreach ($missing as $full_name) {
       $this->addConfigList($full_name, $list);
     }
diff --git a/web/modules/features/src/FeaturesManagerInterface.php b/web/modules/features/src/FeaturesManagerInterface.php
index 6416a647a1e2fb5e31672b3e5940c14cdfeccb0b..2f47e5248b2e742034432756de175183f328a1f7 100644
--- a/web/modules/features/src/FeaturesManagerInterface.php
+++ b/web/modules/features/src/FeaturesManagerInterface.php
@@ -328,7 +328,7 @@ public function initPackageFromExtension(Extension $extension);
    * @return array
    *   Array of package directories keyed by package machine name.
    */
-  public function listPackageDirectories(array $machine_names = array(), FeaturesBundleInterface $bundle = NULL);
+  public function listPackageDirectories(array $machine_names = [], FeaturesBundleInterface $bundle = NULL);
 
   /**
    * Assigns a set of configuration items to a given package or profile.
@@ -414,7 +414,7 @@ public function assignInterPackageDependencies(FeaturesBundleInterface $bundle,
    *
    * @fixme Should this be moved to the package object or a related helper?
    */
-  public function mergeInfoArray(array $info1, array $info2, array $keys = array());
+  public function mergeInfoArray(array $info1, array $info2, array $keys = []);
 
   /**
    * Lists the types of configuration available on the site.
diff --git a/web/modules/features/src/Package.php b/web/modules/features/src/Package.php
index 2fb459a1d68f5dbbf0239a98f59328d21665de5a..c7f2872a2909d4c600a7a09ae690c61f24815db5 100644
--- a/web/modules/features/src/Package.php
+++ b/web/modules/features/src/Package.php
@@ -429,7 +429,7 @@ public function setFeaturesInfo($features_info) {
       $this->setBundle($features_info['bundle']);
     }
     $this->setRequired(isset($features_info['required']) ? $features_info['required'] : false);
-    $this->setExcluded(isset($features_info['excluded']) ? $features_info['excluded'] : array());
+    $this->setExcluded(isset($features_info['excluded']) ? $features_info['excluded'] : []);
 
     return $this;
   }
diff --git a/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentBaseType.php b/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentBaseType.php
index 40fcbca85a0dc3ad4a6726e4d2f581384f9522dd..a8f83cb6409259fe36cd3958d259be7ff61784fa 100644
--- a/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentBaseType.php
+++ b/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentBaseType.php
@@ -2,7 +2,7 @@
 
 namespace Drupal\features\Plugin\FeaturesAssignment;
 
-use Drupal\component\Utility\Unicode;
+use Drupal\Component\Utility\Unicode;
 use Drupal\features\FeaturesAssignmentMethodBase;
 
 /**
@@ -37,7 +37,7 @@ public function assignPackages($force = FALSE) {
     foreach ($config_collection as $item_name => $item) {
       if (in_array($item->getType(), $config_base_types)) {
         if (is_null($this->featuresManager->findPackage($item->getShortName())) && !$item->getPackage()) {
-          $description = $this->t('Provides @label @type and related configuration.', array('@label' => $item->getLabel(), '@type' => Unicode::strtolower($config_types[$item->getType()])));
+          $description = $this->t('Provides @label @type and related configuration.', ['@label' => $item->getLabel(), '@type' => Unicode::strtolower($config_types[$item->getType()])]);
           if (isset($item->getData()['description'])) {
             $description .= ' ' . $item->getData()['description'];
           }
@@ -59,7 +59,7 @@ public function assignPackages($force = FALSE) {
     foreach ($content_base_types as $entity_type_id) {
       if (!isset($packages[$entity_type_id]) && isset($entity_types[$entity_type_id])) {
         $label = $entity_types[$entity_type_id]->getLabel();
-        $description = $this->t('Provide @label related configuration.', array('@label' => $label));
+        $description = $this->t('Provide @label related configuration.', ['@label' => $label]);
         $this->featuresManager->initPackage($entity_type_id, $label, $description, 'module', $current_bundle);
       }
     }
diff --git a/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentProfile.php b/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentProfile.php
index 0783d4d548b2c0019e2e485ab70e782f1c7a6376..81c503e073fab4fcc792d1a391c60ea88922ac26 100644
--- a/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentProfile.php
+++ b/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentProfile.php
@@ -71,7 +71,7 @@ public function assignPackages($force = FALSE) {
 
       // Only read in from the Standard profile if this profile doesn't already
       // exist.
-      $package_directories = $this->featuresManager->listPackageDirectories(array(), $current_bundle);
+      $package_directories = $this->featuresManager->listPackageDirectories([], $current_bundle);
       if (!isset($package_directories[$profile_name])) {
         $standard_directory = 'core/profiles/standard';
         // Conditionally add files from the 'standard' install profile.
diff --git a/web/modules/features/src/Plugin/FeaturesGeneration/FeaturesGenerationArchive.php b/web/modules/features/src/Plugin/FeaturesGeneration/FeaturesGenerationArchive.php
index 2565685b55ee91c87e549d939814cadbcdc5ed3a..a40c7a6dcf95761f926f4f6ae5fa19f7c75ee8da 100644
--- a/web/modules/features/src/Plugin/FeaturesGeneration/FeaturesGenerationArchive.php
+++ b/web/modules/features/src/Plugin/FeaturesGeneration/FeaturesGenerationArchive.php
@@ -128,7 +128,7 @@ protected function preparePackage(Package $package, array $existing_packages, Fe
   /**
    * {@inheritdoc}
    */
-  public function generate(array $packages = array(), FeaturesBundleInterface $bundle = NULL) {
+  public function generate(array $packages = [], FeaturesBundleInterface $bundle = NULL) {
 
     // If no packages were specified, get all packages.
     if (empty($packages)) {
diff --git a/web/modules/features/src/Plugin/FeaturesGeneration/FeaturesGenerationWrite.php b/web/modules/features/src/Plugin/FeaturesGeneration/FeaturesGenerationWrite.php
index 118108c7d07a9f2b37a79e65ff2f3fbef92df877..5844c0e2d1c3a89f637f29194bf05fd5dfc08848 100644
--- a/web/modules/features/src/Plugin/FeaturesGeneration/FeaturesGenerationWrite.php
+++ b/web/modules/features/src/Plugin/FeaturesGeneration/FeaturesGenerationWrite.php
@@ -101,7 +101,7 @@ protected function preparePackage(Package $package, array $existing_packages, Fe
   /**
    * {@inheritdoc}
    */
-  public function generate(array $packages = array(), FeaturesBundleInterface $bundle = NULL) {
+  public function generate(array $packages = [], FeaturesBundleInterface $bundle = NULL) {
     // If no packages were specified, get all packages.
     if (empty($packages)) {
       $packages = $this->featuresManager->getPackages();
diff --git a/web/modules/features/tests/modules/test_feature/test_feature.info.yml b/web/modules/features/tests/modules/test_feature/test_feature.info.yml
index 4f9d07045bf16c1c936b7f4da8961341bc20cf04..b90578e884831465e244a463bb0a6b04d24aec19 100644
--- a/web/modules/features/tests/modules/test_feature/test_feature.info.yml
+++ b/web/modules/features/tests/modules/test_feature/test_feature.info.yml
@@ -6,8 +6,8 @@ package: Test
 dependencies:
   - features
 
-# Information added by Drupal.org packaging script on 2018-02-27
-version: '8.x-3.7'
+# Information added by Drupal.org packaging script on 2018-09-09
+version: '8.x-3.8'
 core: '8.x'
 project: 'features'
-datestamp: 1519763291
+datestamp: 1536512288
diff --git a/web/modules/features/tests/modules/test_mybundle_core/test_mybundle_core.info.yml b/web/modules/features/tests/modules/test_mybundle_core/test_mybundle_core.info.yml
index f3c033933524574332e958f096dc020c15f3e1f5..2f0e6404ab97e692cfa72f9e154b11927f7ecb2b 100644
--- a/web/modules/features/tests/modules/test_mybundle_core/test_mybundle_core.info.yml
+++ b/web/modules/features/tests/modules/test_mybundle_core/test_mybundle_core.info.yml
@@ -6,8 +6,8 @@ package: Test
 dependencies:
   - features
 
-# Information added by Drupal.org packaging script on 2018-02-27
-version: '8.x-3.7'
+# Information added by Drupal.org packaging script on 2018-09-09
+version: '8.x-3.8'
 core: '8.x'
 project: 'features'
-datestamp: 1519763291
+datestamp: 1536512288
diff --git a/web/modules/features/tests/src/Kernel/FeaturesAssignerTest.php b/web/modules/features/tests/src/Kernel/FeaturesAssignerTest.php
index 6bf9f03713a297962d89204d6f7e6f7f14daeaf5..0477ece057b4ea2b6050548ad3c92c0596e980d1 100644
--- a/web/modules/features/tests/src/Kernel/FeaturesAssignerTest.php
+++ b/web/modules/features/tests/src/Kernel/FeaturesAssignerTest.php
@@ -18,6 +18,15 @@ class FeaturesAssignerTest extends KernelTestBase {
 
   protected $strictConfigSchema = FALSE;
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    // We need system.site in order to run $this->configImporter->import().
+    $this->installConfig('system');
+  }
+
   /**
    * Test bundle auto-creation during config import.
    *
@@ -41,7 +50,7 @@ public function testBundleAutoCreationImport() {
     // Uninstall modules.
     $installer->uninstall(['features', 'test_feature']);
 
-    // Restore the config from after install..
+    // Restore the config from after install.
     $this->configImporter()->import();
 
     // Find the auto-created bundle.
diff --git a/web/modules/mega_menu-master/.editorconfig b/web/modules/mega_menu-master/.editorconfig
deleted file mode 100644
index 570b8891d9af4b43bd8c0bba5d1b85c2259f8100..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/.editorconfig
+++ /dev/null
@@ -1,17 +0,0 @@
-# This file is for unifying the coding style for various code editors and IDEs.
-# Make sure to have an editorconfig plug-in installed in your editor to have
-# the editor use this file.
-
-# Sets this config file to be the top-most one.
-root = true
-
-[*]
-charset = utf-8
-end_of_line = lf
-indent_style = space
-indent_size = 2
-insert_final_newline = true
-trim_trailing_whitespace = true
-
-[*.md]
-trim_trailing_whitespace = false
diff --git a/web/modules/mega_menu-master/.gitingore b/web/modules/mega_menu-master/.gitingore
deleted file mode 100644
index e43b0f988953ae3a84b00331d0ccf5f7d51cb3cf..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/.gitingore
+++ /dev/null
@@ -1 +0,0 @@
-.DS_Store
diff --git a/web/modules/mega_menu-master/LICENSE b/web/modules/mega_menu-master/LICENSE
deleted file mode 100644
index 92f7edafb61b16ec50923d325349a63004d76d23..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2015 Odd Hill
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
diff --git a/web/modules/mega_menu-master/README.md b/web/modules/mega_menu-master/README.md
deleted file mode 100644
index f566978b5e0f7adf8bd5cb637cd2b569382cf706..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/README.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# Mega menu
-
-The mega menu module lets you create mega menus from existing menus by defining regions and blocks.
-
-The recommended way to add menu items for use with the mega menu module is to add them to a menu through the `module_name.links.menu.yml` file in a custom module or profile.
-
-Doing it like this will let you commit the menu items to your git repository and will make it much easier to transfer these items between different environments without having to copy database content. 
-
-# Note!
-
-This module is still under development and might have some flaws that still needs to be fixed.
diff --git a/web/modules/mega_menu-master/assets/css/mega_menu.admin.css b/web/modules/mega_menu-master/assets/css/mega_menu.admin.css
deleted file mode 100644
index c458f96a743e2a54d245f366fe5decc7c301053a..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/assets/css/mega_menu.admin.css
+++ /dev/null
@@ -1,9 +0,0 @@
-.region-title__action {
-  display: inline-block;
-  margin-left: 1em; /* LTR */
-}
-
-[dir="rtl"] .region-title__action {
-  margin-left: 0;
-  margin-right: 1em;
-}
diff --git a/web/modules/mega_menu-master/assets/css/mega_menu.css b/web/modules/mega_menu-master/assets/css/mega_menu.css
deleted file mode 100644
index d0389e41f63288d8a0b69b546d903a05e2721b3f..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/assets/css/mega_menu.css
+++ /dev/null
@@ -1,7 +0,0 @@
-.mega-menu-content {
-  display: none;
-}
-
-.mega-menu-content.visible {
-  display: block;
-}
diff --git a/web/modules/mega_menu-master/assets/js/mega_menu.admin.js b/web/modules/mega_menu-master/assets/js/mega_menu.admin.js
deleted file mode 100644
index 5a19f399b42a22d0f6cdd16b54f161ef97adc216..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/assets/js/mega_menu.admin.js
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * @file
- * Mega menu behaviors. Most of this code is copied directly from the blocks
- * javascript and slightly modified to fit the mega menu settings.
- */
-
-(function ($, window) {
-
-  'use strict';
-
-  /**
-   * Filters the block list by a text input search string.
-   *
-   * The text input will have the selector `input.block-filter-text`.
-   *
-   * The target element to do searching in will be in the selector
-   * `input.block-filter-text[data-element]`
-   *
-   * The text source where the text should be found will have the selector
-   * `.block-filter-text-source`
-   *
-   * @type {Drupal~behavior}
-   *
-   * @prop {Drupal~behaviorAttach} attach
-   *   Attaches the behavior for the block filtering.
-   */
-  Drupal.behaviors.blockFilterByText = {
-    attach: function (context, settings) {
-      var $input = $('input.block-filter-text').once('block-filter-text');
-      var $table = $($input.attr('data-element'));
-      var $filter_rows;
-
-      /**
-       * Filters the block list.
-       *
-       * @param {jQuery.Event} e
-       *   The jQuery event for the keyup event that triggered the filter.
-       */
-      function filterBlockList(e) {
-        var query = $(e.target).val().toLowerCase();
-
-        /**
-         * Shows or hides the block entry based on the query.
-         *
-         * @param {number} index
-         *   The index in the loop, as provided by `jQuery.each`
-         * @param {HTMLElement} label
-         *   The label of the block.
-         */
-        function toggleBlockEntry(index, label) {
-          var $label = $(label);
-          var $row = $label.parent().parent();
-          var textMatch = $label.text().toLowerCase().indexOf(query) !== -1;
-          $row.toggle(textMatch);
-        }
-
-        // Filter if the length of the query is at least 2 characters.
-        if (query.length >= 2) {
-          $filter_rows.each(toggleBlockEntry);
-        }
-        else {
-          $filter_rows.each(function (index) {
-            $(this).parent().parent().show();
-          });
-        }
-      }
-
-      if ($table.length) {
-        $filter_rows = $table.find('div.block-filter-text-source');
-        $input.on('keyup', filterBlockList);
-      }
-    }
-  };
-
-})(jQuery, window);
diff --git a/web/modules/mega_menu-master/assets/js/mega_menu.js b/web/modules/mega_menu-master/assets/js/mega_menu.js
deleted file mode 100644
index 67c7faa66ff5e654d50bc5e4a7ba81fb6aa6f3b2..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/assets/js/mega_menu.js
+++ /dev/null
@@ -1,264 +0,0 @@
-/**
- * @file
- * Behaviours for mega menus.
- */
-
-(function ($, document) {
-
-  'use strict';
-
-  /**
-   * The main mega menu functionality as a jQuery plugin.
-   *
-   * Available events:
-   *   - mega-menu:opening: Event is triggered when the mega menu is opening
-   *     from a completely closed state.
-   *   - mega-menu:closing: Event will be triggered when the menu is closing
-   *     a panel and not opening up another one.
-   *   - mega-menu:changing: Event is triggered when the mega menu changes
-   *     the active content without completely closing the menu.
-   */
-  $.fn.megamenu = function() {
-    var $element = this;
-
-    var $content = $element.find('[data-mega-menu-content]');
-    var $listItems = $element.find('[data-mega-menu-content-target]');
-    var $links = $listItems.children('a');
-
-    /**
-     * Public method to close the mega menu.
-     */
-    $.fn.megamenu.close = function () {
-      triggerClosingEvent($element);
-    };
-
-    /**
-     * Public method to open the mega menu.
-     */
-    $.fn.megamenu.open = function () {
-      triggerOpeningEvent($element);
-    };
-
-    // Return to expose public methods.
-    return this.each(function() {
-      $links.on('click.mega-menu', onMenuItemClick);
-      $(document).on('click.mega-menu', onOutsideClick);
-    });
-
-    /**
-     * Trigger an opening event. This is used when the mega menu has no
-     * visible content ans is opened for the "first" time.
-     *
-     * @param {Object} target - The target element.
-     */
-    function triggerOpeningEvent(target) {
-      var event = jQuery.Event('mega-menu:opening', {
-        target: target
-      });
-
-      $element.trigger(event);
-
-      if (!event.isDefaultPrevented()) {
-        showContent(target);
-        activateListItem(target);
-      }
-    }
-
-    /**
-     * Triggers a changing event. This event is used when one menu items
-     * content is closed but another menu items content is being opened,
-     * toggling between different mega menu drop downs.
-     *
-     * @param {Object} target - The target element.
-     */
-    function triggerChangingEvent(target) {
-      var previousTarget = $content.filter('.visible');
-
-      var event = jQuery.Event('mega-menu:changing', {
-        megaMenu: {
-          previousTarget: previousTarget,
-          currentTarget: target
-        },
-        target: target
-      });
-
-      $element.trigger(event);
-
-      if (event.isDefaultPrevented()) {
-        return;
-      }
-
-      hideOtherContent(target);
-      showContent(target);
-      deactivateListItem(previousTarget);
-      activateListItem(target);
-    }
-
-    /**
-     * Trigger the mega menu closing event, this is used when all menus are
-     * being closed without opening another menu items content.
-     *
-     * @param {Object} target - The target element.
-     */
-    function triggerClosingEvent(target) {
-      var event = jQuery.Event('mega-menu:closing', {
-        target: target || $element
-      });
-
-      $element.trigger(event);
-
-      if (!event.isDefaultPrevented()) {
-        hideContent();
-        deactivateListItems();
-      }
-    }
-
-    /**
-     * Handle clicks outside of the mega menu.
-     *
-     * @param {Object} event
-     */
-    function onOutsideClick(event) {
-      if (!$(event.target).closest($element).length && menuIsOpen()) {
-        triggerClosingEvent(event.target);
-      }
-    }
-
-    /**
-     * Check to see if the menu is open based on class values.
-     *
-     * @returns {Boolean}
-     */
-    function menuIsOpen() {
-      return ($listItems.filter('.active').length || $content.filter('.visible').length) ? true : false;
-    }
-
-    /**
-     * Hide every menus content except the specified one.
-     *
-     * @param {Object} current - The content element to keep visible.
-     */
-    function hideOtherContent(current) {
-      var elements = $content.not(current);
-      elements.removeClass('visible');
-    }
-
-    /**
-     * Hide all visible menu content.
-     */
-    function hideContent() {
-      $content.removeClass('visible');
-      deactivateListItems();
-    }
-
-    /**
-     * Show the specified content element.
-     *
-     * @param {Object} element - The content element to show.
-     */
-    function showContent(element) {
-      activateListItem(element);
-      element.addClass('visible');
-    }
-
-    /**
-     * Get the specified content elements target list item.
-     *
-     * @param {Object} element
-     * @returns {*|HTMLElement}
-     */
-    function getTargetListItem(element) {
-      var targetId = element.data('mega-menu-content');
-      return $('[data-mega-menu-content-target="'+targetId+'"]');
-    }
-
-    /**
-     * De-activate all list items.
-     */
-    function deactivateListItems() {
-      $listItems.removeClass('active');
-    }
-
-    /**
-     * Activate the specified content elements list item.
-     *
-     * @param {Object} element
-     */
-    function activateListItem(element) {
-      getTargetListItem(element).addClass('active');
-    }
-
-    /**
-     * De-activate the specified content elements list item.
-     *
-     * @param {Object} element
-     */
-    function deactivateListItem(element) {
-      getTargetListItem(element).removeClass('active');
-    }
-
-    /**
-     * Handle clicks on mega menu link items.
-     *
-     * @param {Object} event - The event that triggered the click.
-     */
-    function onMenuItemClick(event) {
-      var element = $(event.target);
-      var menuTarget = element.closest('li').data('mega-menu-content-target');
-
-      // If the menu does not have a content target then return and let the
-      // normal click action take place.
-      if (!menuTarget) {
-        return;
-      }
-
-      var content = $content.filter('[data-mega-menu-content="' + menuTarget + '"]');
-
-      // If no menu content was found let the normal action take place.
-      if (!content.length) {
-        return;
-      }
-
-      event.preventDefault();
-
-      triggerMenuEvents(content);
-    }
-
-    /**
-     * Decide on what events to trigger based on the current mega menu state.
-     *
-     * @param {Object} content - The menu content that an action should be taken for.
-     */
-    function triggerMenuEvents(content) {
-      // If no content element has the visible class then the menu is opening
-      // for the first time so lets trigger the opening event.
-      if (!$content.hasClass('visible')) {
-        triggerOpeningEvent(content);
-      }
-      else if (content.hasClass('visible')) {
-        triggerClosingEvent(content);
-      }
-      else {
-        triggerChangingEvent(content);
-      }
-    }
-  };
-
-  /**
-   * Toggles a mega menus content visibility depending on what was set in the
-   * mega menu configuration.
-   *
-   * @type {Drupal~behavior}
-   *
-   * @prop {Drupal~behaviorAttach} attach
-   *   Attaches the behavior for the block filtering.
-   */
-  Drupal.behaviors.megaMenuToggler = {
-    attach: function () {
-      $('[data-mega-menu]').once('mega-menu').each(function (key, item) {
-        $(item).megamenu();
-      });
-    }
-  };
-
-})(jQuery, document);
diff --git a/web/modules/mega_menu-master/composer.json b/web/modules/mega_menu-master/composer.json
deleted file mode 100644
index 174baee08113819a957f3c33252d5d3d188fd80b..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/composer.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
-  "name": "drupal/mega_menu",
-  "description": "Allows you to create mega menus.",
-  "type": "drupal-module",
-  "license": "MIT",
-  "homepage": "https://github.com/oddhill/mega_menu",
-  "authors": [
-    {
-      "name": "Christoffer Palm",
-      "email": "christoffer.palm@oddhill.se",
-      "homepage": "http://www.oddhill.se/",
-      "role": "Developer"
-    }
-  ],
-  "support": {
-    "issues": "https://github.com/oddhill/mega_menu/issues",
-    "source": "https://github.com/oddhill/mega_menu",
-    "docs": "https://github.com/oddhill/mega_menu"
-  },
-  "require": {
-    "drupal/layout_plugin": "~1.0.0"
-  }
-}
diff --git a/web/modules/mega_menu-master/mega_menu.info.yml b/web/modules/mega_menu-master/mega_menu.info.yml
deleted file mode 100644
index e619b43f9e3c7a7596f076ab2002408a26160cbb..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/mega_menu.info.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-name: Mega menu
-description: 'Allows you to create mega menus.'
-type: module
-core: 8.x
-dependencies:
-  - layout_plugin
-  - menu_link_content
diff --git a/web/modules/mega_menu-master/mega_menu.libraries.yml b/web/modules/mega_menu-master/mega_menu.libraries.yml
deleted file mode 100644
index 241846297429ef5ef76513308d411d8b35475e0e..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/mega_menu.libraries.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-menu:
-  version: VERSION
-  js:
-    assets/js/mega_menu.js: {}
-  css:
-    component:
-      assets/css/mega_menu.css: {}
-  dependencies:
-    - core/drupal
-    - core/jquery
-    - core/jquery.once
-    - core/drupalSettings
-
-admin:
-  version: VERSION
-  js:
-    assets/js/mega_menu.admin.js: {}
-  css:
-    component:
-      assets/css/mega_menu.admin.css: {}
-  dependencies:
-    - core/drupal
-    - core/jquery
-    - core/jquery.once
diff --git a/web/modules/mega_menu-master/mega_menu.links.action.yml b/web/modules/mega_menu-master/mega_menu.links.action.yml
deleted file mode 100644
index bec25090847dd198bf00d9287795324808ca76a1..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/mega_menu.links.action.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-mega_menu.add_form:
-  route_name: mega_menu.add_form
-  title: 'Add mega menu'
-  appears_on:
-    - entity.mega_menu.collection
diff --git a/web/modules/mega_menu-master/mega_menu.links.menu.yml b/web/modules/mega_menu-master/mega_menu.links.menu.yml
deleted file mode 100644
index bf760c0412a459322e1828a80c8c7d34ca5052a2..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/mega_menu.links.menu.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-entity.mega_menu.collection:
-  title: 'Mega menus'
-  parent: system.admin_structure
-  description: 'Manage mega menus.'
-  route_name: entity.mega_menu.collection
diff --git a/web/modules/mega_menu-master/mega_menu.module b/web/modules/mega_menu-master/mega_menu.module
deleted file mode 100644
index 7e8ad3ce66873f3f0b1845950291bf9533a15f74..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/mega_menu.module
+++ /dev/null
@@ -1,55 +0,0 @@
-<?php
-
-/**
- * @file
- * Main module file for the Mega Menu module.
- */
-
-/**
- * Implements hook_theme().
- */
-function mega_menu_theme() {
-
-  $items['menu__mega_menu'] = [
-    'variables' => [
-      'mega_menu' => NULL,
-      'items' => [],
-      'content' => [],
-      'render_content_outside' => FALSE,
-      'attributes' => [],
-    ],
-  ];
-
-  return $items;
-}
-
-/**
- * Preprocess the mega menu templates and add additional content if needed.
- *
- * @param $variables
- */
-function mega_menu_preprocess_menu__mega_menu(&$variables) {
-  // If for some reason a mega menu has not been set to the variables then do
-  // not do anything since there is nothing to process.
-  if (!isset($variables['mega_menu'])) {
-    return;
-  }
-
-  /** @var \Drupal\mega_menu\Contract\MegaMenuInterface $mega_menu */
-  $mega_menu = $variables['mega_menu'];
-
-  if (!$mega_menu->shouldRenderContentOutside()) {
-    return;
-  }
-
-  // Set the should render status to the variables.
-  $variables['render_content_outside'] = (bool) $mega_menu->shouldRenderContentOutside();
-
-  // Add each items content to the content array.
-  foreach ($variables['items'] as $item_key => $item) {
-    if (!isset($item['content']) && empty($item['content'])) {
-      continue;
-    }
-    $variables['content'][$item_key] = $item['content'];
-  }
-}
diff --git a/web/modules/mega_menu-master/mega_menu.permissions.yml b/web/modules/mega_menu-master/mega_menu.permissions.yml
deleted file mode 100644
index c8128c1bf64a4e4e5df8368feab3a929df649f94..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/mega_menu.permissions.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-administer mega menus:
-  title: 'Administer mega menus'
-  restrict access: TRUE
diff --git a/web/modules/mega_menu-master/mega_menu.routing.yml b/web/modules/mega_menu-master/mega_menu.routing.yml
deleted file mode 100644
index f225ec03c89a7aa27e462a5bdd62b32ade8ad2dd..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/mega_menu.routing.yml
+++ /dev/null
@@ -1,69 +0,0 @@
-# Mega menu routes.
-entity.mega_menu.collection:
-  path: '/admin/structure/mega-menu'
-  defaults:
-    _entity_list: 'mega_menu'
-    _title: 'Mega menus'
-  requirements:
-    _permission: 'administer mega menus'
-
-mega_menu.add_form:
-  path: '/admin/structure/mega-menu/add'
-  defaults:
-    _entity_form: 'mega_menu.add'
-    _title: 'Add mega menu'
-  requirements:
-    _permission: 'administer mega menus'
-
-entity.mega_menu.edit_form:
-  path: '/admin/structure/mega-menu/{mega_menu}'
-  defaults:
-    _entity_form: 'mega_menu.edit'
-    _title: 'Edit mega menu'
-  requirements:
-    _permission: 'administer mega menus'
-
-entity.mega_menu.delete_form:
-  path: '/admin/structure/mega-menu/{mega_menu}/delete'
-  defaults:
-    _entity_form: 'mega_menu.delete'
-    _title: 'Delete mega menu'
-  requirements:
-    _permission: 'administer mega menus'
-
-# Block routes.
-mega_menu.block_library:
-  path: '/admin/structure/mega-menu/{mega_menu}/block/library'
-  defaults:
-    _controller: '\Drupal\mega_menu\Controller\MegaMenuController::blockLibrary'
-    _title: 'Block library'
-  requirements:
-    _permission: 'administer mega menus'
-
-mega_menu.block_add:
-  path: '/admin/structure/mega-menu/{mega_menu}/block/{block_id}/add'
-  defaults:
-    _form: '\Drupal\mega_menu\Form\BlockAddForm'
-    _title: 'Add block'
-  requirements:
-    _permission: 'administer mega menus'
-
-mega_menu.block_edit:
-  path: '/admin/structure/mega-menu/{mega_menu}/block/{block_id}/edit'
-  defaults:
-    _form: '\Drupal\mega_menu\Form\BlockEditForm'
-    _title: 'Edit block'
-  requirements:
-    _permission: 'administer mega menus'
-
-mega_menu.block_delete:
-  path: '/admin/structure/mega-menu/{mega_menu}/block/{block_id}/remove'
-  defaults:
-    _form: '\Drupal\mega_menu\Form\BlockDeleteForm'
-    _title: 'Remove block'
-  requirements:
-    _permission: 'administer mega menus'
-  options:
-    parameters:
-      mega_menu:
-        type: entity:mega_menu
diff --git a/web/modules/mega_menu-master/mega_menu.services.yml b/web/modules/mega_menu-master/mega_menu.services.yml
deleted file mode 100644
index 2f105156b057def3cd638d84d00cabf85e3c35ab..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/mega_menu.services.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-services:
-  mega_menu.link_tree:
-    class: Drupal\mega_menu\Menu\MegaMenuLinkTree
-    arguments: ['@menu.tree_storage', '@plugin.manager.menu.link', '@router.route_provider', '@menu.active_trail', '@controller_resolver', '@cache.menu', '@current_route_match']
diff --git a/web/modules/mega_menu-master/src/Contract/MegaMenuInterface.php b/web/modules/mega_menu-master/src/Contract/MegaMenuInterface.php
deleted file mode 100644
index a03204b4e213baf350fc23d89a1aadc97a2e342c..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/src/Contract/MegaMenuInterface.php
+++ /dev/null
@@ -1,133 +0,0 @@
-<?php
-
-namespace Drupal\mega_menu\Contract;
-
-use Drupal\Core\Config\Entity\ConfigEntityInterface;
-use Drupal\ctools\Plugin\BlockPluginCollection;
-
-interface MegaMenuInterface extends ConfigEntityInterface {
-
-  /**
-   * Represents a mega menu link item that does not use a layout.
-   */
-  const NO_LAYOUT = 'mega_menu.no_layout';
-
-  /**
-   * Represents a mega menu link item that does not have a region. And also
-   * used to represent a no region in lists.
-   */
-  const NO_REGION = 'mega_menu.no_region';
-
-  /**
-   * Get the machine name of the target menu.
-   *
-   * @return string
-   */
-  public function getTargetMenu();
-
-  /**
-   * Get the label of the target menu entity.
-   *
-   * @return null|string
-   */
-  public function getTargetMenuLabel();
-
-  /**
-   * Get a list of all blocks associated with a link.
-   *
-   * @return BlockPluginCollection
-   */
-  public function getBlocksByLink($link_id);
-
-  /**
-   * Get an array of all blocks keyed by their link id.
-   *
-   * @return BlockPluginCollection[]
-   */
-  public function getAllBlocksSortedByLink();
-
-  /**
-   * Get the specified block.
-   *
-   * @param $link_id
-   *   The id of the link to get blocks for.
-   * @param string $block_id
-   *   The id of the block to get.
-   *
-   * @return BlockPluginCollection
-   */
-  public function getBlock($link_id, $block_id);
-
-  /**
-   * Add a new block.
-   *
-   * @param $link_id
-   *   The id of the link to add the block to.
-   * @param array $configuration
-   *   An array of configuration values for this block.
-   *
-   * @return $this
-   */
-  public function addBlock($link_id, $block_id, $configuration);
-
-  /**
-   * Update a block instance.
-   *
-   * @param $link_id
-   *   The id of the link to add the block to.
-   * @param $block_id
-   *   The id of the block to update.
-   * @param $configuration
-   *   An array of configuration values for this block.
-   *
-   * @return $this
-   */
-  public function updateBlock($link_id, $block_id, $configuration);
-
-  /**
-   * Remove a block from the configuration.
-   *
-   * @param $link_id
-   * @param $block_id
-   *   The id of the block to remove.
-   *
-   * @return $this
-   */
-  public function removeBlock($link_id, $block_id);
-
-  /**
-   * Check if a block exists.
-   *
-   * @param string $link_id
-   * @param string $block_id
-   *
-   * @return bool
-   */
-  public function hasBlock($link_id, $block_id);
-
-  /**
-   * Get the selected layout for a link.
-   *
-   * @param string $link_id
-   *
-   * @return string|null
-   */
-  public function getLinkLayout($link_id);
-
-  /**
-   * Set the layout of a link.
-   *
-   * @param string $link_id
-   * @param string $layout_id
-   *
-   * @return $this
-   */
-  public function setLinkLayout($link_id, $layout_id);
-
-  /**
-   * Check to see if content should be rendered outside of the list.
-   *
-   * @return bool
-   */
-  public function shouldRenderContentOutside();
-}
diff --git a/web/modules/mega_menu-master/src/Controller/MegaMenuController.php b/web/modules/mega_menu-master/src/Controller/MegaMenuController.php
deleted file mode 100644
index 3493c20c536386b8d4a8eca1502a344c154cf36b..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/src/Controller/MegaMenuController.php
+++ /dev/null
@@ -1,150 +0,0 @@
-<?php
-
-namespace Drupal\mega_menu\Controller;
-
-use Drupal\Component\Serialization\Json;
-use Drupal\Core\Block\BlockManagerInterface;
-use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
-use Drupal\Core\Plugin\Context\ContextRepositoryInterface;
-use Drupal\Core\StringTranslation\StringTranslationTrait;
-use Drupal\Core\Url;
-use Drupal\mega_menu\Contract\MegaMenuInterface;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-use Symfony\Component\HttpFoundation\Request;
-
-class MegaMenuController implements ContainerInjectionInterface {
-
-  use StringTranslationTrait;
-
-  /**
-   * @var BlockManagerInterface
-   */
-  private $blockManager;
-  /**
-   * @var ContextRepositoryInterface
-   */
-  private $contextRepository;
-
-  /**
-   * MegaMenuController constructor.
-   *
-   * @param BlockManagerInterface $blockManager
-   * @param ContextRepositoryInterface $contextRepository
-   */
-  public function __construct(
-    BlockManagerInterface $blockManager,
-    ContextRepositoryInterface $contextRepository
-  ) {
-    $this->blockManager = $blockManager;
-    $this->contextRepository = $contextRepository;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container) {
-    return new static(
-      $container->get('plugin.manager.block'),
-      $container->get('context.repository')
-    );
-  }
-
-  /**
-   * Get a list of blocks that can be placed in a mega menu.
-   *
-   * @param Request $request
-   * @param MegaMenuInterface $mega_menu
-   * @return array
-   */
-  public function blockLibrary(Request $request, MegaMenuInterface $mega_menu) {
-
-    // Get the query parameters needed.
-    $link = $request->query->get('link');
-    $region = $request->query->get('region');
-
-    // Only add blocks which work without any available context.
-    $blocks = $this->blockManager
-      ->getDefinitionsForContexts($this->contextRepository->getAvailableContexts());
-
-    // Order by category, and then by admin label.
-    $blocks = $this->blockManager
-      ->getSortedDefinitions($blocks);
-
-    $build['filter'] = [
-      '#type' => 'search',
-      '#title' => $this->t('Filter'),
-      '#title_display' => 'invisible',
-      '#size' => 30,
-      '#placeholder' => $this->t('Filter by block name'),
-      '#attributes' => [
-        'class' => ['block-filter-text'],
-        'data-element' => '.block-add-table',
-        'title' => $this->t('Enter a part of the block name to filter by.'),
-      ],
-    ];
-
-    $headers = [
-      $this->t('Block'),
-      $this->t('Category'),
-      $this->t('Operations'),
-    ];
-
-    $build['blocks'] = [
-      '#type' => 'table',
-      '#header' => $headers,
-      '#rows' => [],
-      '#empty' => $this->t('No blocks available.'),
-      '#attributes' => [
-        'class' => ['block-add-table'],
-      ],
-    ];
-
-    // Add each block definition to the table.
-    foreach ($blocks as $block_id => $block) {
-      $links = [
-        'add' => [
-          'title' => $this->t('Place block'),
-          'url' => Url::fromRoute('mega_menu.block_add', [
-            'mega_menu' => $mega_menu->id(),
-            'block_id' => $block_id,
-          ], [
-            'query' => [
-              'link' => $link,
-              'region' => $region,
-            ],
-          ]),
-          'attributes' => [
-            'class' => ['use-ajax'],
-            'data-dialog-type' => 'modal',
-            'data-dialog-options' => Json::encode([
-              'width' => 700,
-            ]),
-          ],
-        ],
-      ];
-
-      $build['blocks']['#rows'][] = [
-        'title' => [
-          'data' => [
-            '#type' => 'inline_template',
-            '#template' => '<div class="block-filter-text-source">{{ label }}</div>',
-            '#context' => [
-              'label' => $block['admin_label'],
-            ],
-          ],
-        ],
-        'category' => [
-          'data' => $block['category'],
-        ],
-        'operations' => [
-          'data' => [
-            '#type' => 'operations',
-            '#links' => $links,
-          ],
-        ],
-      ];
-    }
-
-    return $build;
-  }
-}
diff --git a/web/modules/mega_menu-master/src/Entity/MegaMenu.php b/web/modules/mega_menu-master/src/Entity/MegaMenu.php
deleted file mode 100644
index 923c93ac6dfe810ea04ffceb94681db04aaa4c7f..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/src/Entity/MegaMenu.php
+++ /dev/null
@@ -1,274 +0,0 @@
-<?php
-
-namespace Drupal\mega_menu\Entity;
-
-use Drupal\Core\Block\BlockPluginInterface;
-use Drupal\Core\Config\Entity\ConfigEntityBase;
-use Drupal\Core\Entity\EntityStorageInterface;
-use Drupal\ctools\Plugin\BlockPluginCollection;
-use Drupal\mega_menu\Contract\MegaMenuInterface;
-
-/**
- * Defines the Context entity.
- *
- * @ConfigEntityType(
- *   id = "mega_menu",
- *   label = @Translation("Mega menu"),
- *   handlers = {
- *     "form" = {
- *       "add" = "Drupal\mega_menu\Form\MegaMenuAddForm",
- *       "edit" = "Drupal\mega_menu\Form\MegaMenuEditForm",
- *       "delete" = "Drupal\mega_menu\Form\MegaMenuDeleteForm",
- *     },
- *     "list_builder" = "Drupal\mega_menu\MegaMenuListBuilder",
- *   },
- *   links = {
- *     "edit-form" = "/admin/structure/mega-menu/{mega_menu}",
- *     "delete-form" = "/admin/structure/mega-menu/{mega_menu}/delete",
- *     "collection" = "/admin/structure/mega-menu",
- *   },
- *   admin_permission = "administer mega menus",
- *   entity_keys = {
- *     "id" = "name",
- *     "label" = "label",
- *   },
- *   config_export = {
- *     "name",
- *     "label",
- *     "menu",
- *     "links",
- *     "render_content_outside",
- *   }
- * )
- */
-class MegaMenu extends ConfigEntityBase implements MegaMenuInterface {
-
-  /**
-   * The machine name of this mega menu.
-   *
-   * @var string
-   */
-  protected $name;
-
-  /**
-   * The human readable label of this mega menu.
-   *
-   * @var string
-   */
-  protected $label;
-
-  /**
-   * The machine name of the menu this mega menu is configured for.
-   *
-   * @var string
-   */
-  protected $menu;
-
-  /**
-   * An array of block configuration values keyed by menu link id.
-   *
-   * @var array
-   */
-  protected $blocks = [];
-
-  /**
-   * Contains a block collection instance if the blocks has been fetched at
-   * least once.
-   *
-   * @var BlockPluginCollection[]
-   */
-  protected $block_collections = [];
-
-  /**
-   * The configuration for the mega menu links. The mega menu does not actually
-   * hold any links on it's own, it just has configuration for the links that
-   * exists in the referenced menu.
-   *
-   * @var array
-   */
-  protected $links = [];
-
-  /**
-   * If the mega menu content should be rendered outside of the list.
-   *
-   * @var boolean
-   */
-  protected $render_content_outside = FALSE;
-
-  /**
-   * {@inheritdoc}
-   */
-  public function id() {
-    return $this->name;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getTargetMenu() {
-    return $this->menu;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getTargetMenuLabel() {
-    return $this->entityTypeManager()
-      ->getStorage('menu')
-      ->load($this->menu)
-      ->label();
-  }
-
-  /**
-   * Get a list of block plugins associated with this mega menu.
-   *
-   * @return BlockPluginCollection
-   */
-  public function getBlocksByLink($link_id) {
-    if (!isset($this->block_collections[$link_id])) {
-      $block_manager = \Drupal::service('plugin.manager.block');
-
-      $blocks = (isset($this->links[$link_id]['blocks']) && is_array($this->links[$link_id]['blocks']))
-        ? $this->links[$link_id]['blocks']
-        : [];
-
-      $this->block_collections[$link_id] = new BlockPluginCollection($block_manager, $blocks);
-    }
-
-    return $this->block_collections[$link_id];
-  }
-
-  /**
-   * Get an array of all blocks keyed by their link id.
-   *
-   * @return BlockPluginCollection[]
-   */
-  public function getAllBlocksSortedByLink() {
-    foreach ($this->links as $link_key => $link) {
-      $this->getBlocksByLink($link_key);
-    }
-
-    return $this->block_collections;
-  }
-
-  /**
-   * Get the specified block.
-   *
-   * @param string $block_id
-   *   The id of the block to get.
-   *
-   * @return BlockPluginInterface
-   */
-  public function getBlock($link_id, $block_id) {
-    return $this->getBlocksByLink($link_id)->get($block_id);
-  }
-
-  /**
-   * Add a new block.
-   *
-   * @param array $configuration
-   *   An array of configuration values for this block.
-   *
-   * @return $this
-   */
-  public function addBlock($link_id, $block_id, $configuration) {
-    $this->getBlocksByLink($link_id)->addInstanceId($block_id, $configuration);
-
-    return $this;
-  }
-
-  /**
-   * Update an existing block.
-   *
-   * @param $block_id
-   *   The id of the block to update.
-   * @param $configuration
-   *   An array of configuration values for this block.
-   *
-   * @return $this
-   */
-  public function updateBlock($link_id, $block_id, $configuration) {
-    $block = $this->getBlocksByLink($link_id)->get($block_id);
-    $current_configuration = $block->getConfiguration();
-
-    $this->getBlocksByLink($link_id)
-      ->setInstanceConfiguration($block_id, $configuration + $current_configuration);
-
-    return $this;
-  }
-
-  /**
-   * Remove a block from the configuration.
-   *
-   * @param $block_id
-   *   The id of the block to remove.
-   *
-   * @return $this
-   */
-  public function removeBlock($link_id, $block_id) {
-    $this->getBlocksByLink($link_id)->removeInstanceId($block_id);
-
-    return $this;
-  }
-
-  /**
-   * Check if a block exists.
-   *
-   * @param string $link_id
-   * @param string $block_id
-   *
-   * @return bool
-   */
-  public function hasBlock($link_id, $block_id) {
-    return $this->getBlocksByLink($link_id)->has($block_id);
-  }
-
-  /**
-   * Get the selected layout for a link.
-   *
-   * @param string $link_id
-   *
-   * @return string|null
-   */
-  public function getLinkLayout($link_id) {
-    if (isset($this->links[$link_id]['layout'])) {
-      return $this->links[$link_id]['layout'];
-    }
-
-    return MegaMenuInterface::NO_LAYOUT;
-  }
-
-  /**
-   * Set the layout of a link.
-   *
-   * @param string $link_id
-   * @param string $layout_id
-   *
-   * @return $this
-   */
-  public function setLinkLayout($link_id, $layout_id) {
-    $this->links[$link_id]['layout'] = $layout_id;
-    return $this;
-  }
-
-  /**
-   * Pre-save hook.
-   *
-   * @param EntityStorageInterface $storage
-   */
-  public function preSave(EntityStorageInterface $storage) {
-    // Save block configuration to the links.
-    foreach ($this->block_collections as $key => $collection) {
-      $this->links[$key]['blocks'] = $collection->getConfiguration();
-    }
-  }
-
-  /**
-   * Check to see if content should be rendered outside of the list.
-   *
-   * @return bool
-   */
-  public function shouldRenderContentOutside() {
-    return $this->render_content_outside;
-  }
-}
diff --git a/web/modules/mega_menu-master/src/Form/BlockAddForm.php b/web/modules/mega_menu-master/src/Form/BlockAddForm.php
deleted file mode 100644
index 72ab38b85be7b489300f3f7c55ff24929b058eb1..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/src/Form/BlockAddForm.php
+++ /dev/null
@@ -1,27 +0,0 @@
-<?php
-
-namespace Drupal\mega_menu\Form;
-
-class BlockAddForm extends BlockFormBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormId() {
-    return 'mega_menu_block_add_form';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function getSubmitValue() {
-    return $this->t('Add block');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function prepareBlock($link_id, $block_id) {
-    return $this->blockManager->createInstance($block_id);
-  }
-}
diff --git a/web/modules/mega_menu-master/src/Form/BlockDeleteForm.php b/web/modules/mega_menu-master/src/Form/BlockDeleteForm.php
deleted file mode 100644
index 566cccdd2ef69e4ef5e87a38d6f0e4d8862770bf..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/src/Form/BlockDeleteForm.php
+++ /dev/null
@@ -1,90 +0,0 @@
-<?php
-
-namespace Drupal\mega_menu\Form;
-
-use Drupal\Core\Block\BlockPluginInterface;
-use Drupal\Core\Form\ConfirmFormBase;
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\mega_menu\Contract\MegaMenuInterface;
-use Symfony\Component\HttpFoundation\Request;
-
-class BlockDeleteForm extends ConfirmFormBase {
-
-  /**
-   * The mega menu instance.
-   *
-   * @var MegaMenuInterface
-   */
-  protected $megaMenu;
-
-  /**
-   * The block instance to be removed.
-   *
-   * @var BlockPluginInterface
-   */
-  protected $block;
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormId() {
-    return 'mega_menu_block_delete_form¨';
-  }
-
-  /**
-   * Returns the question to ask the user.
-   *
-   * @return string
-   *   The form question. The page title will be set to this value.
-   */
-  public function getQuestion() {
-    return $this->t('Are you sure you want to remove the @label block?', [
-      '@label' => $this->block->getConfiguration()['label'],
-    ]);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getCancelUrl() {
-    return $this->megaMenu->toUrl();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildForm(array $form, FormStateInterface $form_state, Request $request = NULL, MegaMenuInterface $mega_menu = NULL, $block_id = NULL) {
-    $form_state->set('link', $request->query->get('link'));
-
-    $this->megaMenu = $mega_menu;
-    $this->block = $this->megaMenu->getBlock($form_state->get('link'), $block_id);
-
-    $form = parent::buildForm($form, $form_state);
-
-    // Remove the cancel button if this is an AJAX request since Drupals built
-    // in modal dialogues does not handle buttons that are not a primary
-    // button very well.
-    if ($this->getRequest()->isXmlHttpRequest()) {
-      unset($form['actions']['cancel']);
-    }
-
-    return $form;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, FormStateInterface $form_state) {
-    $configuration = $this->block->getConfiguration();
-
-    $this->megaMenu->removeBlock($form_state->get('link'), $configuration['id']);
-
-    $this->megaMenu->save();
-
-    drupal_set_message($this->t('The @label block has been removed.', [
-      '@label' => $configuration['label']
-    ]));
-
-    $form_state->setRedirectUrl($this->getCancelUrl());
-  }
-}
diff --git a/web/modules/mega_menu-master/src/Form/BlockEditForm.php b/web/modules/mega_menu-master/src/Form/BlockEditForm.php
deleted file mode 100644
index d34b6c18add049977d7fe7feea3f5a5e1d666667..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/src/Form/BlockEditForm.php
+++ /dev/null
@@ -1,27 +0,0 @@
-<?php
-
-namespace Drupal\mega_menu\Form;
-
-class BlockEditForm extends BlockFormBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormId() {
-    return 'mega_menu_block_edit_form';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function getSubmitValue() {
-    return $this->t('Update block');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function prepareBlock($link_id, $block_id) {
-    return $this->megaMenu->getBlock($link_id, $block_id);
-  }
-}
diff --git a/web/modules/mega_menu-master/src/Form/BlockFormBase.php b/web/modules/mega_menu-master/src/Form/BlockFormBase.php
deleted file mode 100644
index 63fdc769a9cc70c7fca97349a05928b362749b93..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/src/Form/BlockFormBase.php
+++ /dev/null
@@ -1,181 +0,0 @@
-<?php
-
-namespace Drupal\mega_menu\Form;
-
-use Drupal\Core\Block\BlockPluginInterface;
-use Drupal\Core\Form\FormBase;
-use Drupal\Core\Form\FormState;
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Component\Plugin\PluginManagerInterface;
-use Drupal\Core\Plugin\Context\ContextRepositoryInterface;
-use Drupal\Core\Plugin\ContextAwarePluginInterface;
-use Drupal\Core\StringTranslation\TranslatableMarkup;
-use Drupal\Core\Url;
-use Drupal\mega_menu\Contract\MegaMenuInterface;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-use Symfony\Component\HttpFoundation\Request;
-
-abstract class BlockFormBase extends FormBase {
-
-  /**
-   * The mega menu instance.
-   *
-   * @var MegaMenuInterface
-   */
-  protected $megaMenu;
-
-  /**
-   * The block instance.
-   *
-   * @var BlockPluginInterface
-   */
-  protected $block;
-
-  /**
-   * The Drupal block manager.
-   *
-   * @var PluginManagerInterface
-   */
-  protected $blockManager;
-
-  /**
-   * The Drupal context repository.
-   *
-   * @var ContextRepositoryInterface
-   */
-  protected $contextRepository;
-
-  /**
-   * Constructs a new VariantPluginFormBase.
-   *
-   * @param PluginManagerInterface $blockManager
-   *   The Drupal block manager.
-   * @param ContextRepositoryInterface $contextRepository
-   *   The Drupal context repository.
-   */
-  public function __construct(
-    PluginManagerInterface $blockManager,
-    ContextRepositoryInterface $contextRepository
-  )
-  {
-    $this->blockManager = $blockManager;
-    $this->contextRepository = $contextRepository;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container) {
-    return new static(
-      $container->get('plugin.manager.block'),
-      $container->get('context.repository')
-    );
-  }
-
-  /**
-   * Prepares the block plugin based on the block ID.
-   *
-   * @param string $link_id
-   *   The id of the link.
-   *
-   * @param string $block_id
-   *   Either a block ID, or the plugin ID used to create a new block.
-   *
-   * @return BlockPluginInterface
-   *   The block plugin.
-   */
-  abstract protected function prepareBlock($link_id, $block_id);
-
-  /**
-   * Get the value to use for the submit button.
-   *
-   * @return TranslatableMarkup
-   */
-  abstract protected function getSubmitValue();
-
-  /**
-   * Form constructor.
-   *
-   * @param array $form
-   *   An associative array containing the structure of the form.
-   * @param FormStateInterface $form_state
-   *   The current state of the form.
-   * @param MegaMenuInterface $mega_menu
-   *   The mega menu the block should be added to.
-   * @param string|null $block_id
-   *   The ID of the block to show a configuration form for.
-   *
-   * @return array
-   */
-  public function buildForm(array $form, FormStateInterface $form_state, Request $request = NULL, MegaMenuInterface $mega_menu = NULL, $block_id = NULL) {
-    $this->megaMenu = $mega_menu;
-
-    // Get the query parameters needed.
-    $form_state->set('link', $request->query->get('link'));
-    $form_state->set('region', $request->query->get('region'));
-
-    $this->block = $this->prepareBlock($form_state->get('link'), $block_id);
-
-    // Some blocks require contexts, set a temporary value with gathered
-    // contextual values.
-    $form_state->setTemporaryValue('gathered_contexts', $this->contextRepository->getAvailableContexts());
-
-    $form['#tree'] = TRUE;
-
-    $form['settings'] = $this->block->buildConfigurationForm([], $form_state);
-
-    $form['actions']['submit'] = [
-      '#type' => 'submit',
-      '#value' => $this->getSubmitValue(),
-      '#button_type' => 'primary',
-    ];
-
-    return $form;
-  }
-
-  /**
-   * Form submission handler.
-   *
-   * @param array $form
-   *   An associative array containing the structure of the form.
-   *
-   * @param \Drupal\Core\Form\FormStateInterface $form_state
-   *   The current state of the form.
-   */
-  public function submitForm(array &$form, FormStateInterface $form_state) {
-    $settings = (new FormState())->setValues($form_state->getValue('settings'));
-
-    // Call the plugin submit handler.
-    $this->block->submitConfigurationForm($form, $settings);
-
-    // Update the original form values.
-    $form_state->setValue('settings', $settings->getValues());
-
-    // Add available contexts if this is a context aware block.
-    if ($this->block instanceof ContextAwarePluginInterface) {
-      $this->block->setContextMapping($form_state->getValue(['settings', 'context_mapping'], []));
-    }
-
-    $link = $form_state->get('link');
-    $region = $form_state->get('region');
-
-    $configuration = array_merge($this->block->getConfiguration(), [
-      'link' => $link,
-      'region' => $region,
-    ]);
-
-    if ($this->megaMenu->hasBlock($link, $configuration['id'])) {
-      $this->megaMenu->updateBlock($link, $configuration['id'], $configuration);
-    }
-    else {
-      $this->megaMenu->addBlock($link, $configuration['id'], $configuration);
-    }
-
-    $this->megaMenu->save();
-
-    $form_state->setRedirectUrl(Url::fromRoute('entity.mega_menu.edit_form', [
-      'mega_menu' => $this->megaMenu->id(),
-    ]));
-  }
-}
-
diff --git a/web/modules/mega_menu-master/src/Form/MegaMenuAddForm.php b/web/modules/mega_menu-master/src/Form/MegaMenuAddForm.php
deleted file mode 100644
index 80e6e5a6f84522cdeb89415b9eb06672c7f1ac69..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/src/Form/MegaMenuAddForm.php
+++ /dev/null
@@ -1,17 +0,0 @@
-<?php
-
-namespace Drupal\mega_menu\Form;
-
-use Drupal\Core\Form\FormStateInterface;
-
-class MegaMenuAddForm extends MegaMenuFormBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, FormStateInterface $form_state) {
-    parent::submitForm($form, $form_state);
-
-    $form_state->setRedirectUrl($this->entity->toUrl('edit-form'));
-  }
-}
diff --git a/web/modules/mega_menu-master/src/Form/MegaMenuDeleteForm.php b/web/modules/mega_menu-master/src/Form/MegaMenuDeleteForm.php
deleted file mode 100644
index 0b35bc4cd3afc771e500cde5cd1010014cfa73a9..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/src/Form/MegaMenuDeleteForm.php
+++ /dev/null
@@ -1,40 +0,0 @@
-<?php
-
-namespace Drupal\mega_menu\Form;
-
-use Drupal\Core\Entity\EntityConfirmFormBase;
-use Drupal\Core\Form\FormStateInterface;
-
-class MegaMenuDeleteForm extends EntityConfirmFormBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getQuestion() {
-    return $this->t('Are you sure you want to remove the @label mega menu.', [
-      '@label' => $this->entity->label(),
-    ]);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getCancelUrl() {
-    return $this->entity->toUrl('collection');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, FormStateInterface $form_state) {
-    parent::submitForm($form, $form_state);
-
-    $this->entity->delete();
-
-    drupal_set_message($this->t('The @label mega menu has been removed.', [
-    '@label' => $this->entity->label(),
-    ]));
-
-    $form_state->setRedirectUrl($this->getCancelUrl());
-  }
-}
diff --git a/web/modules/mega_menu-master/src/Form/MegaMenuEditForm.php b/web/modules/mega_menu-master/src/Form/MegaMenuEditForm.php
deleted file mode 100644
index bba171410160206736d95982f096f89870626070..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/src/Form/MegaMenuEditForm.php
+++ /dev/null
@@ -1,310 +0,0 @@
-<?php
-
-namespace Drupal\mega_menu\Form;
-
-use Drupal\Component\Serialization\Json;
-use Drupal\Component\Utility\Html;
-use Drupal\Core\Block\BlockPluginInterface;
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Url;
-use Drupal\mega_menu\Contract\MegaMenuInterface;
-
-class MegaMenuEditForm extends MegaMenuFormBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function form(array $form, FormStateInterface $form_state) {
-    $form = parent::form($form, $form_state);
-
-    $menu_links_elements = $this->getMenuLinkElements($this->entity->getTargetMenu());
-    $layout_options = $this->getLayoutOptions();
-
-    $table_header = [
-      'label' => $this->t('Label'),
-      'category' => $this->t('Category'),
-      'region' => $this->t('Region'),
-      'weight' => $this->t('Weight'),
-      'operations' => $this->t('Operations'),
-    ];
-
-    $form['links'] = [
-      '#type' => 'container',
-      '#title' => $this->t('Menu links'),
-      '#tree' => TRUE,
-    ];
-
-    $blocks = $this->entity->getAllBlocksSortedByLink();
-
-    foreach ($menu_links_elements as $link_element_id => $link_element) {
-      // Replace any dots with a underscore since dots are not supported as
-      // keys in the configuration data.
-      $link_element_id = str_replace('.', '_', $link_element_id);
-
-      $link_layout = $this->entity->getLinkLayout($link_element_id);
-      $regions = $this->getLayoutRegions($link_layout);
-
-      $link_id = Html::getId($link_element_id);
-
-      $form['links'][$link_element_id] = [
-        '#type' => 'fieldset',
-        '#title' => $link_element->link->getTitle(),
-      ];
-
-      $form['links'][$link_element_id]['layout'] = [
-        '#type' => 'select',
-        '#title' => $this->t('Layout'),
-        '#options' => $layout_options,
-        '#default_value' => $link_layout,
-        '#ajax' => [
-          'callback' => '::onLayoutSelect',
-          'wrapper' => "mega-menu-link-{$link_id}-blocks-wrapper",
-        ],
-        '#attributes' => [
-          'data-link-element-id' => $link_element_id,
-        ],
-      ];
-
-      $form['links'][$link_element_id]['blocks'] = [
-        '#prefix' => '<div id="mega-menu-link-'.$link_id.'-blocks-wrapper">',
-        '#suffix' => '</div>',
-        '#type' => 'table',
-        '#header' => $table_header,
-        '#empty' => $this->t('There are no regions for blocks.'),
-      ];
-
-      // Add regions.
-      foreach ($regions as $region_key => $region_name) {
-        // Tabledrag stuff.
-        $form['links'][$link_element_id]['blocks']['#tabledrag'][] = [
-          'action' => 'match',
-          'relationship' => 'sibling',
-          'group' => 'block-region-select',
-          'subgroup' => 'block-region-' . $region_key,
-          'hidden' => FALSE,
-        ];
-
-        $form['links'][$link_element_id]['blocks']['#tabledrag'][] = [
-          'action' => 'order',
-          'relationship' => 'sibling',
-          'group' => 'block-weight',
-          'subgroup' => 'block-weight-' . $region_key,
-        ];
-
-        // Regions.
-        $form['links'][$link_element_id]['blocks'][$region_key] = [
-          '#attributes' => [
-            'class' => ['region-title', 'region-title-' . $region_key],
-            'no_striping' => TRUE,
-          ],
-        ];
-
-        if ($region_key === MegaMenuInterface::NO_REGION) {
-          $form['links'][$link_element_id]['blocks'][$region_key]['title'] = [
-            '#markup' => $region_name,
-            '#wrapper_attributes' => [
-              'colspan' => 5,
-            ],
-          ];
-        }
-        else {
-          $form['links'][$link_element_id]['blocks'][$region_key]['title'] = [
-            '#theme_wrappers' => [
-              'container' => [
-                '#attributes' => [
-                  'class' => ['region-title__action']
-                ],
-              ]
-            ],
-            '#prefix' => $region_name,
-            '#type' => 'link',
-            '#title' => $this->t('Place block <span class="visually-hidden">in the %region region</span>', [
-              '%region' => $region_name,
-            ]),
-            '#url' => Url::fromRoute('mega_menu.block_library', [
-              'mega_menu' => $this->entity->id(),
-            ], [
-              'query' => [
-                'link' => $link_element_id,
-                'region' => $region_key,
-              ],
-            ]),
-            '#wrapper_attributes' => [
-              'colspan' => 5,
-            ],
-            '#attributes' => [
-              'class' => ['use-ajax', 'button', 'button--small'],
-              'data-dialog-type' => 'modal',
-              'data-dialog-options' => Json::encode([
-                'width' => 700,
-              ]),
-            ],
-          ];
-        }
-
-        $blocks_by_region = isset($blocks[$link_element_id])
-          ? $blocks[$link_element_id]->getAllByRegion()
-          : [];
-
-        $region_message_class = empty($blocks_by_region[$region_key])
-          ? 'region-empty'
-          : 'region-populated';
-
-        $form['links'][$link_element_id]['blocks'][$region_key . '-message'] = [
-          '#attributes' => [
-            'class' => [
-              'region-message',
-              'region-' . $region_key . '-message',
-              $region_message_class
-            ],
-          ],
-        ];
-
-        $form['links'][$link_element_id]['blocks'][$region_key . '-message']['message'] = [
-          '#markup' => '<em>' . $this->t('No blocks in this region') . '</em>',
-          '#wrapper_attributes' => [
-            'colspan' => 5,
-          ],
-        ];
-
-        if (!isset($blocks_by_region[$region_key])) {
-          continue;
-        }
-
-        /** @var BlockPluginInterface $block */
-        foreach ($blocks_by_region[$region_key] as $block_id => $block) {
-          if (!isset($form['links'][$link_element_id])) {
-            continue;
-          }
-
-          $operations = [
-            'edit' => [
-              'title' => $this->t('Edit'),
-              'url' => Url::fromRoute('mega_menu.block_edit', [
-                'mega_menu' => $this->entity->id(),
-                'block_id' => $block_id,
-              ], [
-                'query' => [
-                  'link' => $link_element_id,
-                  'region' => $region_key,
-                ],
-              ]),
-              'attributes' => [
-                'class' => ['use-ajax', 'button', 'button--small'],
-                'data-dialog-type' => 'modal',
-                'data-dialog-options' => Json::encode([
-                  'width' => 700,
-                ]),
-              ],
-            ],
-            'delete' => [
-              'title' => $this->t('Delete'),
-              'url' => Url::fromRoute('mega_menu.block_delete', [
-                'mega_menu' => $this->entity->id(),
-                'block_id' => $block_id,
-              ], [
-                'query' => [
-                  'link' => $link_element_id,
-                ],
-              ]),
-              'attributes' => [
-                'class' => ['use-ajax', 'button', 'button--small'],
-                'data-dialog-type' => 'modal',
-                'data-dialog-options' => Json::encode([
-                  'width' => 700,
-                ]),
-              ],
-            ],
-          ];
-
-          $configuration = $block->getConfiguration();
-
-          $form['links'][$link_element_id]['blocks'][$block_id] = [
-            '#attributes' => [
-              'class' => ['draggable'],
-            ],
-            'label' => [
-              '#markup' => $block->label(),
-            ],
-            'category' => [
-              '#markup' => $block->getPluginDefinition()['category'],
-            ],
-            'region' => [
-              '#type' => 'select',
-              '#title' => $this->t('Region for @block block', ['@block' => $block->label()]),
-              '#title_display' => 'invisible',
-              '#default_value' => $region_key,
-              '#options' => $regions,
-              '#attributes' => [
-                'class' => [
-                  'block-region-select',
-                  'block-region-' . $region_key
-                ],
-              ],
-            ],
-            'weight' => [
-              '#type' => 'weight',
-              '#default_value' => isset($configuration['weight']) ? $configuration['weight'] : 0,
-              '#title' => $this->t('Weight for @block block', ['@block' => $block->label()]),
-              '#title_display' => 'invisible',
-              '#attributes' => [
-                'class' => ['block-weight', 'block-weight-' . $configuration['region']],
-              ],
-            ],
-            'operations' => [
-              '#type' => 'operations',
-              '#links' => $operations,
-            ],
-          ];
-        }
-      }
-    }
-
-    return $form;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildEntity(array $form, FormStateInterface $form_state) {
-    $entity = clone $this->entity;
-
-    $entity->set('label', $form_state->getValue('label'));
-    $entity->set('name', $form_state->getValue('name'));
-    $entity->set('menu', $form_state->getValue('menu'));
-    $entity->set('render_content_outside', $form_state->getValue('render_content_outside'));
-
-    foreach ($form_state->getValue('links', []) as $link_key => $link) {
-      $entity->setLinkLayout($link_key, $link['layout']);
-
-      if (!is_array($link['blocks']) || !count($link['blocks'])) {
-        continue;
-      }
-
-      foreach ($link['blocks'] as $block_id => $configuration) {
-        $this->entity->updateBlock($link_key, $block_id, $configuration);
-      }
-    }
-
-    return $entity;
-  }
-
-  /**
-   * AJAX callback for when a layout is selected.
-   *
-   * @param array $form
-   *   The form array.
-   * @param FormStateInterface $form_state
-   *   The form state instance.
-   *
-   * @return mixed
-   */
-  public function onLayoutSelect(array $form, FormStateInterface $form_state) {
-    $triggering_element = $form_state->getTriggeringElement();
-    $link_element_id = $triggering_element['#attributes']['data-link-element-id'];
-
-    $this->save($form, $form_state);
-
-    return $form['links'][$link_element_id]['blocks'];
-  }
-}
diff --git a/web/modules/mega_menu-master/src/Form/MegaMenuFormBase.php b/web/modules/mega_menu-master/src/Form/MegaMenuFormBase.php
deleted file mode 100644
index 7200ebfb98e6e7ed5cf31f54a184bd3f650caae2..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/src/Form/MegaMenuFormBase.php
+++ /dev/null
@@ -1,212 +0,0 @@
-<?php
-
-namespace Drupal\mega_menu\Form;
-
-use Drupal\Core\Entity\EntityForm;
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Menu\MenuLinkTreeElement;
-use Drupal\Core\Menu\MenuLinkTreeInterface;
-use Drupal\Core\Menu\MenuTreeParameters;
-use Drupal\layout_plugin\Plugin\Layout\LayoutPluginManagerInterface;
-use Drupal\mega_menu\Contract\MegaMenuInterface;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-abstract class MegaMenuFormBase extends EntityForm {
-
-  /**
-   * The mega menu entity.
-   *
-   * @var MegaMenuInterface
-   */
-  protected $entity;
-
-  /**
-   * The layout plugin manager.
-   *
-   * @var LayoutPluginManagerInterface
-   */
-  protected $layoutPluginManager;
-
-  /**
-   * The Drupal menu link tree builder.
-   *
-   * @var MenuLinkTreeInterface
-   */
-  protected $menuLinkTree;
-
-  /**
-   * MegaMenuFormBase constructor.
-   *
-   * @param LayoutPluginManagerInterface $layoutPluginManager
-   *   The layout plugin manager.
-   * @param MenuLinkTreeInterface $menuLinkTree
-   *   The Drupal menu link tree builder.
-   */
-  public function __construct(
-    LayoutPluginManagerInterface $layoutPluginManager,
-    MenuLinkTreeInterface $menuLinkTree
-  ) {
-    $this->layoutPluginManager = $layoutPluginManager;
-    $this->menuLinkTree = $menuLinkTree;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container) {
-    return new static(
-      $container->get('plugin.manager.layout_plugin'),
-      $container->get('menu.link_tree')
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function form(array $form, FormStateInterface $form_state) {
-    $form = parent::form($form, $form_state);
-
-    $form['#attached']['library'][] = 'mega_menu/admin';
-
-    $form['general'] = [
-      '#title' => $this->t('General details'),
-      '#type' => 'fieldset',
-    ];
-
-    $form['general']['label'] = [
-      '#type' => 'textfield',
-      '#title' => $this->t('Label'),
-      '#description' => $this->t('Enter label for this mega menu.'),
-      '#required' => TRUE,
-      '#default_value' => $this->entity->label(),
-    ];
-
-    $form['general']['name'] = [
-      '#type' => 'machine_name',
-      '#title' => $this->t('Machine name'),
-      '#machine_name' => [
-        'source' => ['general', 'label'],
-        'exists' => [$this, 'megaMenuExists'],
-      ],
-      '#default_value' => $this->entity->id(),
-      '#disabled' => $this->entity->id() ? TRUE : FALSE,
-    ];
-
-    $form['general']['menu'] = [
-      '#type' => 'select',
-      '#title' => $this->t('Menu'),
-      '#description' => $this->t('The menu that should be used as a base for the mega menu.'),
-      '#empty_option' => $this->t('- Select a menu -'),
-      '#options' => $this->getMenusListOptions(),
-      '#required' => TRUE,
-      '#default_value' => $this->entity->getTargetMenu(),
-      '#disabled' => $this->entity->getTargetMenu() ? TRUE : FALSE,
-    ];
-
-    $form['general']['render_content_outside'] = [
-      '#type' => 'checkbox',
-      '#title' => $this->t('Render content outside of list'),
-      '#description' => $this->t('Check this box if you want to render the mega menu dropdown content outside of the list.'),
-      '#default_value' => $this->entity->get('render_content_outside'),
-    ];
-
-    return $form;
-  }
-
-  /**
-   * Get a list of options to be used for the menu select.
-   *
-   * @return array
-   */
-  protected function getMenusListOptions() {
-    $list = [];
-
-    $menus = $this->entityTypeManager
-      ->getStorage('menu')
-      ->loadMultiple();
-
-    foreach ($menus as $menu_id => $menu) {
-      $list[$menu_id] = $menu->label();
-    }
-
-    return $list;
-  }
-
-  /**
-   * Get a list of layout options suitable for a select list.
-   *
-   * @return array
-   */
-  protected function getLayoutOptions() {
-    $options = [
-      MegaMenuInterface::NO_LAYOUT => $this->t('No layout'),
-    ];
-
-    return $options + $this->layoutPluginManager->getLayoutOptions();
-  }
-
-  /**
-   * Get a list of default regions. This includes the no region option.
-   *
-   * @return array
-   */
-  protected function getDefaultRegions() {
-   return [];
-  }
-
-  /**
-   * Get a list of regions for the specified layout.
-   *
-   * @param string $layout
-   *
-   * @return array
-   */
-  protected function getLayoutRegions($layout) {
-    $default_regions = $this->getDefaultRegions();
-
-    if ($layout === MegaMenuInterface::NO_LAYOUT) {
-      return $default_regions;
-    }
-
-    $definition = $this->layoutPluginManager
-      ->getDefinition($layout, FALSE);
-
-    if (!$definition) {
-      return $default_regions;
-    }
-
-    if (!isset($definition['region_names']) || !count($definition['region_names'])) {
-      return $default_regions;
-    }
-
-    return $definition['region_names'] + $default_regions;
-  }
-
-  /**
-   * Get a list of menu link elements for the specified menu.
-   *
-   * @param string $menu
-   *
-   * @return MenuLinkTreeElement[]
-   */
-  protected function getMenuLinkElements($menu) {
-    $parameters = (new MenuTreeParameters())
-      ->setMaxDepth(1);
-
-    return $this->menuLinkTree->load($menu, $parameters);
-  }
-
-  /**
-   * Check to see if a mega menu already exists with the specified name.
-   *
-   * @param  string $name
-   *   The machine name to check for.
-   *
-   * @return bool
-   */
-  public function megaMenuExists($name) {
-    return $this->entityTypeManager
-      ->getStorage('mega_menu')
-      ->load($name);
-  }
-}
diff --git a/web/modules/mega_menu-master/src/MegaMenuListBuilder.php b/web/modules/mega_menu-master/src/MegaMenuListBuilder.php
deleted file mode 100644
index 8e307226c0f4420f0ef3897a9f40b1c68fc680da..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/src/MegaMenuListBuilder.php
+++ /dev/null
@@ -1,33 +0,0 @@
-<?php
-
-namespace Drupal\mega_menu;
-
-use Drupal\Core\Config\Entity\ConfigEntityListBuilder;
-use Drupal\Core\Entity\EntityInterface;
-
-class MegaMenuListBuilder extends ConfigEntityListBuilder {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildHeader() {
-    $header = [
-      'label' => $this->t('Label'),
-      'menu' => $this->t('Menu'),
-    ];
-
-    return $header + parent::buildHeader();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildRow(EntityInterface $entity) {
-    $row = [
-      'label' => $entity->label(),
-      'menu' => $entity->getTargetMenuLabel()
-    ];
-
-    return $row + parent::buildRow($entity);
-  }
-}
diff --git a/web/modules/mega_menu-master/src/Menu/MegaMenuLinkTree.php b/web/modules/mega_menu-master/src/Menu/MegaMenuLinkTree.php
deleted file mode 100644
index 93ac6f2119ec8f1d7127018560be6e2def0b6d48..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/src/Menu/MegaMenuLinkTree.php
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-
-namespace Drupal\mega_menu\Menu;
-
-use Drupal\Core\Menu\MenuLinkTree;
-
-class MegaMenuLinkTree extends MenuLinkTree {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function build(array $tree) {
-    $build = parent::build($tree);
-
-    /** @var \Drupal\Core\Menu\MenuLinkInterface $first_link */
-    $first_link = reset($tree)->link;
-    $menu_name = $first_link->getMenuName();
-
-    // Add a more specific theme suggestion to differentiate this rendered
-    // menu from others.
-    $build['#menu_name'] = $menu_name;
-    $build['#theme'] = 'menu__mega_menu__' . strtr($menu_name, '-', '_');
-
-    return $build;
-  }
-}
diff --git a/web/modules/mega_menu-master/src/Plugin/Block/MegaMenuBlock.php b/web/modules/mega_menu-master/src/Plugin/Block/MegaMenuBlock.php
deleted file mode 100644
index 47591221c39b27ccc3c35f4522debfd3b780efb7..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/src/Plugin/Block/MegaMenuBlock.php
+++ /dev/null
@@ -1,319 +0,0 @@
-<?php
-
-namespace Drupal\mega_menu\Plugin\Block;
-
-use Drupal\Core\Block\BlockBase;
-use Drupal\Core\Cache\Cache;
-use Drupal\Core\Cache\CacheableMetadata;
-use Drupal\Core\Entity\EntityTypeManagerInterface;
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Menu\MenuLinkTreeElement;
-use Drupal\Core\Menu\MenuLinkTreeInterface;
-use Drupal\Core\Menu\MenuTreeParameters;
-use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
-use Drupal\Core\Plugin\Context\ContextHandlerInterface;
-use Drupal\Core\Plugin\Context\ContextRepositoryInterface;
-use Drupal\Core\Plugin\ContextAwarePluginInterface;
-use Drupal\Core\Render\Element;
-use Drupal\Core\Session\AccountInterface;
-use Drupal\layout_plugin\Plugin\Layout\LayoutInterface;
-use Drupal\layout_plugin\Plugin\Layout\LayoutPluginManagerInterface;
-use Drupal\mega_menu\Contract\MegaMenuInterface;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Provides a 'Mega menu' block.
- *
- * @Block(
- *   id = "mega_menu_block",
- *   admin_label = @Translation("Mega menu"),
- *   category = @Translation("Mega menu"),
- *   deriver = "Drupal\mega_menu\Plugin\Derivative\MegaMenuBlock"
- * )
- */
-class MegaMenuBlock extends BlockBase implements ContainerFactoryPluginInterface {
-
-  /**
-   * @var EntityTypeManagerInterface
-   */
-  protected $entityTypeManager;
-
-  /**
-   * @var MenuLinkTreeInterface
-   */
-  protected $menuLinkTree;
-
-  /**
-   * @var LayoutPluginManagerInterface
-   */
-  protected $layoutPluginManager;
-
-  /**
-   * @var ContextHandlerInterface
-   */
-  protected $contextHandler;
-
-  /**
-   * @var ContextRepositoryInterface
-   */
-  protected $contextRepository;
-
-  /**
-   * @var AccountInterface
-   */
-  protected $account;
-
-  /**
-   * MegaMenuBlock constructor.
-   *
-   * {@inheritdoc}
-   *
-   * @param EntityTypeManagerInterface $entityTypeManager
-   *   The Drupal entity type manager.
-   */
-  public function __construct(
-    array $configuration,
-    $plugin_id,
-    $plugin_definition,
-    EntityTypeManagerInterface $entityTypeManager,
-    MenuLinkTreeInterface $menuLinkTree,
-    LayoutPluginManagerInterface $layoutPluginManager,
-    ContextHandlerInterface $contextHandler,
-    ContextRepositoryInterface $contextRepository,
-    AccountInterface $account
-  ) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition);
-    $this->entityTypeManager = $entityTypeManager;
-    $this->menuLinkTree = $menuLinkTree;
-    $this->layoutPluginManager = $layoutPluginManager;
-    $this->contextHandler = $contextHandler;
-    $this->contextRepository = $contextRepository;
-    $this->account = $account;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static(
-      $configuration,
-      $plugin_id,
-      $plugin_definition,
-      $container->get('entity.manager'),
-      $container->get('mega_menu.link_tree'),
-      $container->get('plugin.manager.layout_plugin'),
-      $container->get('context.handler'),
-      $container->get('context.repository'),
-      $container->get('current_user')
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function build() {
-    $mega_menu = $this->loadMegaMenu($this->getDerivativeId());
-
-    // Use the menu tree as the base build.
-    $build = $this->buildMegaMenuTree($mega_menu);
-
-    $build['#attributes'] = [
-      'data-mega-menu' => $mega_menu->id(),
-    ];
-
-    $build['#attached']['library'][] = 'mega_menu/menu';
-
-    return $build;
-  }
-
-  /**
-   * Build the mega menu link/content tree.
-   *
-   * @param MegaMenuInterface $mega_menu
-   *
-   * @return array
-   */
-  private function buildMegaMenuTree(MegaMenuInterface $mega_menu) {
-    $tree = $this->loadMenuTree($mega_menu->getTargetMenu());
-
-    $build = $this->menuLinkTree->build($tree);
-
-    $build['#mega_menu'] = $mega_menu;
-
-    $cacheability = CacheableMetadata::createFromRenderArray($build);
-    $cacheability->addCacheableDependency($mega_menu);
-
-    // Add content from the mega menus to the link tree.
-    foreach ($build['#items'] as $item_key => $item) {
-      $safe_item_key = str_replace('.', '_', $item_key);
-
-      $layout = $mega_menu->getLinkLayout($safe_item_key);
-
-      if ($layout === MegaMenuInterface::NO_LAYOUT) {
-        continue;
-      }
-
-      $build['#items'][$item_key]['attributes']['data-mega-menu-content-target'] = $item_key;
-
-      /** @var LayoutInterface $layout_plugin */
-      $layout_plugin = $this->layoutPluginManager->createInstance($layout);
-      $plugin_definition = $layout_plugin->getPluginDefinition();
-
-      // Build an array of the region names in the right order.
-      $empty = array_fill_keys(array_keys($plugin_definition['region_names']), []);
-      $full = $mega_menu->getBlocksByLink($safe_item_key)->getAllByRegion();
-
-      // Merge it with the actual values to maintain the ordering.
-      $block_assignments = array_intersect_key(array_merge($empty, $full), $empty);
-
-      $build['#items'][$item_key]['content'] = [
-        '#prefix' => '<div data-mega-menu-content="'.$item_key.'" class="mega-menu-content">',
-        '#suffix' => '</div>',
-        '#theme' => $plugin_definition['theme'],
-        '#settings' => [],
-        '#layout' => $plugin_definition,
-      ];
-
-      if (isset($plugin_definition['library'])) {
-        $build['#items'][$item_key]['content']['#attached']['library'][] = $plugin_definition['library'];
-      }
-
-      foreach ($block_assignments as $region => $blocks) {
-        $build['#items'][$item_key]['content'][$region] = [];
-
-        /** @var \Drupal\Core\Block\BlockPluginInterface[] $blocks */
-        foreach ($blocks as $block_id => $block) {
-
-          if ($block instanceof ContextAwarePluginInterface) {
-            $contexts = $this->contextRepository->getRuntimeContexts($block->getContextMapping());
-            $this->contextHandler->applyContextMapping($block, $contexts);
-          }
-
-          // Make sure the user is allowed to view the block.
-          $access = $block->access($this->account, TRUE);
-          $cacheability->addCacheableDependency($access);
-
-          // If the user is not allowed then do not render the block.
-          if (!$access->isAllowed()) {
-            continue;
-          }
-
-          $configuration = $block->getConfiguration();
-
-          // Create the render array for the block as a whole.
-          // @see template_preprocess_block().
-          $block_build = [
-            '#theme' => 'block',
-            '#attributes' => [],
-            '#weight' => $configuration['weight'],
-            '#configuration' => $configuration,
-            '#plugin_id' => $block->getPluginId(),
-            '#base_plugin_id' => $block->getBaseId(),
-            '#derivative_plugin_id' => $block->getDerivativeId(),
-            '#block_plugin' => $block,
-            '#pre_render' => [[$this, 'preRenderBlock']],
-            '#cache' => [
-              'keys' => ['mega_menu', $mega_menu->id(), 'block', $block_id],
-              'tags' => Cache::mergeTags($mega_menu->getCacheTags(), $block->getCacheTags()),
-              'contexts' => $block->getCacheContexts(),
-              'max-age' => $block->getCacheMaxAge(),
-            ],
-          ];
-
-          $build['#items'][$item_key]['content'][$region][$block_id] = $block_build;
-
-          $cacheability->addCacheableDependency($block);
-        }
-      }
-    }
-
-    $cacheability->applyTo($build);
-
-    return $build;
-  }
-
-  /**
-   * Renders the content using the provided block plugin.
-   *
-   * @param array $build
-   *
-   * @return array
-   */
-  public function preRenderBlock($build) {
-    $content = $build['#block_plugin']->build();
-
-    unset($build['#block_plugin']);
-
-    // Abort rendering: render as the empty string and ensure this block is
-    // render cached, so we can avoid the work of having to repeatedly
-    // determine whether the block is empty. E.g. modifying or adding entities
-    // could cause the block to no longer be empty.
-    if (is_null($content) || Element::isEmpty($content)) {
-      $build = [
-        '#markup' => '',
-        '#cache' => $build['#cache'],
-      ];
-
-      // If $content is not empty, then it contains cacheability metadata, and
-      // we must merge it with the existing cacheability metadata. This allows
-      // blocks to be empty, yet still bubble cacheability metadata, to indicate
-      // why they are empty.
-      if (!empty($content)) {
-        CacheableMetadata::createFromRenderArray($build)
-          ->merge(CacheableMetadata::createFromRenderArray($content))
-          ->applyTo($build);
-      }
-    }
-    else {
-      $build['content'] = $content;
-    }
-
-    return $build;
-  }
-
-  /**
-   * Load a mega menu entity.
-   *
-   * @param $mega_menu_id
-   *
-   * @return MegaMenuInterface|null
-   */
-  private function loadMegaMenu($mega_menu_id) {
-    return $this->entityTypeManager
-      ->getStorage('mega_menu')
-      ->load($mega_menu_id);
-  }
-
-  /**
-   * Load a list of menu tree elements.
-   *
-   * @param $menu_id
-   *
-   * @return MenuLinkTreeElement[]
-   */
-  private function loadMenuTree($menu_id) {
-    $parameters = (new MenuTreeParameters())
-      ->setMaxDepth(1);
-
-    return $this->menuLinkTree->load($menu_id, $parameters);
-  }
-
-  /**
-   * Get a list of options for the mega menu select.
-   *
-   * @return array
-   */
-  private function getMegaMenuOptions() {
-    $options = [];
-
-    $mega_menus = $this->entityTypeManager
-      ->getStorage('mega_menu')
-      ->loadMultiple();
-
-    foreach ($mega_menus as $mega_menu) {
-      $options[$mega_menu->id()] = $mega_menu->label();
-    }
-
-    return $options;
-  }
-}
diff --git a/web/modules/mega_menu-master/src/Plugin/Derivative/MegaMenuBlock.php b/web/modules/mega_menu-master/src/Plugin/Derivative/MegaMenuBlock.php
deleted file mode 100644
index a8003d6427d798ae849bf6d8d3b741c3a63b4cb7..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/src/Plugin/Derivative/MegaMenuBlock.php
+++ /dev/null
@@ -1,59 +0,0 @@
-<?php
-
-namespace Drupal\mega_menu\Plugin\Derivative;
-
-use Drupal\Component\Plugin\Derivative\DeriverBase;
-use Drupal\Core\Entity\EntityTypeManagerInterface;
-use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
-use Drupal\mega_menu\Contract\MegaMenuInterface;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-class MegaMenuBlock extends DeriverBase implements ContainerDeriverInterface {
-
-  /**
-   * @var EntityTypeManagerInterface
-   */
-  private $entityTypeManager;
-
-  /**
-   * MegaMenuBlock constructor.
-   *
-   * @param EntityTypeManagerInterface $entityTypeManager
-   */
-  public function __construct(EntityTypeManagerInterface $entityTypeManager) {
-    $this->entityTypeManager = $entityTypeManager;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container, $base_plugin_id) {
-    return new static(
-      $container->get('entity.manager')
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getDerivativeDefinitions($base_plugin_definition) {
-    foreach ($this->getMegaMenus() as $name => $mega_menu) {
-      $this->derivatives[$name] = $base_plugin_definition;
-      $this->derivatives[$name]['admin_label'] = $mega_menu->label();
-      $this->derivatives[$name]['config_dependencies']['config'] = [$mega_menu->getConfigDependencyName()];
-    }
-
-    return $this->derivatives;
-  }
-
-  /**
-   * Get all mega menus.
-   *
-   * @return MegaMenuInterface[]
-   */
-  private function getMegaMenus() {
-    return $this->entityTypeManager
-      ->getStorage('mega_menu')
-      ->loadMultiple();
-  }
-}
diff --git a/web/modules/mega_menu-master/templates/menu--mega-menu.html.twig b/web/modules/mega_menu-master/templates/menu--mega-menu.html.twig
deleted file mode 100644
index c0632ec9bb253341320e585ed263da9c055612ca..0000000000000000000000000000000000000000
--- a/web/modules/mega_menu-master/templates/menu--mega-menu.html.twig
+++ /dev/null
@@ -1,37 +0,0 @@
-{#
-/**
- * @file
- * Default theme implementation to display a mega menu.
- *
- * Available variables:
- * - render_content_outside: If the mega menu content should be rendered
- *   outside of the list.
- * - content: A render array of menu content.
- *
- * @see menu.html.twig for additional variables.
- */
-#}
-<div {{ attributes.addClass('mega-menu') }}>
-  {% if items %}
-    {% if menu_level == 0 %}
-      <ul>
-    {% else %}
-      <ul>
-    {% endif %}
-
-    {% for item in items %}
-      <li{{ item.attributes }}>
-        {{ link(item.title, item.url) }}
-
-        {% if item.content and render_content_outside == false %}
-          {{ item.content }}
-        {% endif %}
-      </li>
-    {% endfor %}
-    </ul>
-
-    {% if render_content_outside == true %}
-      {{ content }}
-    {% endif %}
-  {% endif %}
-</div>