diff --git a/composer.json b/composer.json
index 7d7236e26efaad1d2df403ddd6601235ace6e1e3..32a24f1136ae29b281cd7ab7c922c60e9e7f707a 100644
--- a/composer.json
+++ b/composer.json
@@ -121,7 +121,6 @@
         "drupal/entity_embed": "1.1",
         "drupal/entity_reference_revisions": "1.9",
         "drupal/externalauth": "1.3",
-        "drupal/features": "3.8",
         "drupal/field_group": "3.1",
         "drupal/field_permissions": "1.1",
         "drupal/file_browser": "1.3",
diff --git a/composer.lock b/composer.lock
index d541fe7873fd7aba1a4dad5da7ff221616c7d121..3d7e506764ad348b05e8708de44c031a1e5aaebd 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "843798e535532282f5f95604c8d1c8db",
+    "content-hash": "e3ee1d5a5d5f54ba54a8f18646828dd0",
     "packages": [
         {
             "name": "alchemy/zippy",
@@ -4935,92 +4935,6 @@
                 "source": "https://git.drupalcode.org/project/externalauth"
             }
         },
-        {
-            "name": "drupal/features",
-            "version": "3.8.0",
-            "source": {
-                "type": "git",
-                "url": "https://git.drupalcode.org/project/features.git",
-                "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": "^8"
-            },
-            "type": "drupal-module",
-            "extra": {
-                "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": "donquixote",
-                    "homepage": "https://www.drupal.org/user/459338"
-                },
-                {
-                    "name": "e2thex",
-                    "homepage": "https://www.drupal.org/user/189123"
-                },
-                {
-                    "name": "febbraro",
-                    "homepage": "https://www.drupal.org/user/43670"
-                },
-                {
-                    "name": "flocondetoile",
-                    "homepage": "https://www.drupal.org/user/2006064"
-                },
-                {
-                    "name": "jmiccolis",
-                    "homepage": "https://www.drupal.org/user/31731"
-                },
-                {
-                    "name": "joseph.olstad",
-                    "homepage": "https://www.drupal.org/user/1321830"
-                },
-                {
-                    "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": "https://git.drupalcode.org/project/features"
-            }
-        },
         {
             "name": "drupal/field_group",
             "version": "3.1.0",
diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php
index daedd43494d640dc2902b544ef82e98c2dfa70e6..acc10dc5c0306ff975cae803b186ce7e21587435 100644
--- a/vendor/composer/InstalledVersions.php
+++ b/vendor/composer/InstalledVersions.php
@@ -30,7 +30,7 @@ class InstalledVersions
     'aliases' => 
     array (
     ),
-    'reference' => '11ac4bc4a7dc85d65a11da78cbdc0ddccfae171d',
+    'reference' => 'fb181bce9c126206eb904564a795200a8dbc2b7e',
     'name' => 'osu-asc-webservices/d8-upstream',
   ),
   'versions' => 
@@ -1104,15 +1104,6 @@ class InstalledVersions
       ),
       'reference' => '8.x-1.3',
     ),
-    'drupal/features' => 
-    array (
-      'pretty_version' => '3.8.0',
-      'version' => '3.8.0.0',
-      'aliases' => 
-      array (
-      ),
-      'reference' => '8.x-3.8',
-    ),
     'drupal/field' => 
     array (
       'replaced' => 
@@ -2431,7 +2422,7 @@ class InstalledVersions
       'aliases' => 
       array (
       ),
-      'reference' => '11ac4bc4a7dc85d65a11da78cbdc0ddccfae171d',
+      'reference' => 'fb181bce9c126206eb904564a795200a8dbc2b7e',
     ),
     'pantheon-systems/quicksilver-pushback' => 
     array (
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index a98ae9222003e67923856e1cc92c45fcb432698b..6da2ec35e7c8ff6795c46e7d21d1080238ea1b81 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -5047,86 +5047,6 @@
             },
             "install-path": "../../web/modules/externalauth"
         },
-        {
-            "name": "drupal/features",
-            "version": "3.8.0",
-            "version_normalized": "3.8.0.0",
-            "source": {
-                "type": "git",
-                "url": "https://git.drupalcode.org/project/features.git",
-                "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"
-            },
-            "install-path": "../../web/modules/features"
-        },
         {
             "name": "drupal/field_group",
             "version": "3.1.0",
diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php
index db814007492bb7097979415e4bfc935d998ec567..f1b38e6e80359e59098f56cdbfa8c9cf9475a5db 100644
--- a/vendor/composer/installed.php
+++ b/vendor/composer/installed.php
@@ -6,7 +6,7 @@
     'aliases' => 
     array (
     ),
-    'reference' => '11ac4bc4a7dc85d65a11da78cbdc0ddccfae171d',
+    'reference' => 'fb181bce9c126206eb904564a795200a8dbc2b7e',
     'name' => 'osu-asc-webservices/d8-upstream',
   ),
   'versions' => 
@@ -1080,15 +1080,6 @@
       ),
       'reference' => '8.x-1.3',
     ),
-    'drupal/features' => 
-    array (
-      'pretty_version' => '3.8.0',
-      'version' => '3.8.0.0',
-      'aliases' => 
-      array (
-      ),
-      'reference' => '8.x-3.8',
-    ),
     'drupal/field' => 
     array (
       'replaced' => 
@@ -2407,7 +2398,7 @@
       'aliases' => 
       array (
       ),
-      'reference' => '11ac4bc4a7dc85d65a11da78cbdc0ddccfae171d',
+      'reference' => 'fb181bce9c126206eb904564a795200a8dbc2b7e',
     ),
     'pantheon-systems/quicksilver-pushback' => 
     array (
diff --git a/web/modules/features/LICENSE.txt b/web/modules/features/LICENSE.txt
deleted file mode 100644
index d159169d1050894d3ea3b98e1c965c4058208fe1..0000000000000000000000000000000000000000
--- a/web/modules/features/LICENSE.txt
+++ /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
deleted file mode 100644
index de7ea040a6df8a17e66567a5dd32ed2c07ab27a9..0000000000000000000000000000000000000000
--- a/web/modules/features/composer.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
-  "description": "Enables administrators to package configuration into modules",
-  "license": "GPL-2.0+",
-  "minimum-stability": "dev",
-  "name": "drupal/features",
-  "require": {
-    "drupal/config_update": "^1.4"
-  },
-  "type": "drupal-module",
-  "extra": {
-    "drush": {
-      "services": {
-        "drush.services.yml": "^9"
-      }
-    }
-  }
-}
diff --git a/web/modules/features/config/install/features.bundle.default.yml b/web/modules/features/config/install/features.bundle.default.yml
deleted file mode 100644
index ea4bb8819b1bfb9c2739d448422ed5a0a2495c6a..0000000000000000000000000000000000000000
--- a/web/modules/features/config/install/features.bundle.default.yml
+++ /dev/null
@@ -1,98 +0,0 @@
-langcode: en
-status: true
-dependencies: {  }
-name: Default
-machine_name: default
-description: ''
-assignments:
-  alter:
-    core: true
-    uuid: true
-    user_permissions: true
-    enabled: true
-    weight: 0
-  base:
-    types:
-      config:
-        comment_type: comment_type
-        node_type: node_type
-      content:
-        user: user
-    enabled: true
-    weight: -2
-  core:
-    types:
-      config:
-        date_format: date_format
-        field_storage_config: field_storage_config
-        entity_form_mode: entity_form_mode
-        image_style: image_style
-        menu: menu
-        responsive_image_style: responsive_image_style
-        user_role: user_role
-        entity_view_mode: entity_view_mode
-    enabled: true
-    weight: 5
-  dependency:
-    enabled: true
-    weight: 15
-  exclude:
-    types:
-      config:
-        features_bundle: features_bundle
-    curated: true
-    module:
-      installed: true
-      profile: true
-      namespace: true
-      namespace_any: false
-    enabled: true
-    weight: -5
-  existing:
-    enabled: true
-    weight: 12
-  forward_dependency:
-    enabled: true
-    weight: 4
-  namespace:
-    enabled: true
-    weight: 0
-  optional:
-    types:
-      config: {}
-    enabled: true
-    weight: 0
-  packages:
-    enabled: true
-    weight: -20
-  profile:
-    curated: true
-    standard:
-      files: true
-      dependencies: true
-    types:
-      config:
-        block: block
-        language_content_settings: language_content_settings
-        configurable_language: configurable_language
-        migration: migration
-        shortcut_set: shortcut_set
-        tour: tour
-    enabled: true
-    weight: 10
-  site:
-    types:
-      config:
-        action: action
-        contact_form: contact_form
-        block_content_type: block_content_type
-        rdf_mapping: rdf_mapping
-        search_page: search_page
-        taxonomy_vocabulary: taxonomy_vocabulary
-        editor: editor
-        filter_format: filter_format
-    enabled: true
-    weight: 7
-profile_name: ''
-is_profile: false
-
diff --git a/web/modules/features/config/install/features.settings.yml b/web/modules/features/config/install/features.settings.yml
deleted file mode 100644
index ed8b37a57cb1672f0673de3872e5886bf06f738e..0000000000000000000000000000000000000000
--- a/web/modules/features/config/install/features.settings.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-export:
-  folder: 'custom'
-langcode: en
diff --git a/web/modules/features/config/schema/features.schema.yml b/web/modules/features/config/schema/features.schema.yml
deleted file mode 100644
index 3d53f1d9f81880855aee96700635ce1ccafc0341..0000000000000000000000000000000000000000
--- a/web/modules/features/config/schema/features.schema.yml
+++ /dev/null
@@ -1,188 +0,0 @@
-features.settings:
-  type: config_entity
-  label: 'Features settings'
-  mapping:
-    export:
-      type: mapping
-      label: "Export settings"
-      mapping:
-        folder:
-          type: string
-          label: "Folder"
-    langcode:
-      type: string
-      label: "Language Code"
-
-features.bundle.*:
-  type: config_entity
-  label: 'Features bundle'
-  mapping:
-    machine_name:
-      type: string
-      label: "Machine name"
-    name:
-      type: string
-      label: "Name"
-    description:
-      type: string
-      label: "Description"
-    assignments:
-      type: sequence
-      label: "Assignment"
-      sequence:
-        type: features.assignment.[%key]
-    profile_name:
-      type: string
-      label: "Profile name"
-    is_profile:
-      type: boolean
-      label: "Is install profile"
-
-features.assignment.settings:
-  type: mapping
-  label: "Assignment settings"
-  mapping:
-    enabled:
-      type: boolean
-      label: "Enabled"
-    weight:
-      type: integer
-      label: "Weight"
-
-features.assignment.*:
-  type: features.assignment.settings
-
-features.assignment.base:
-  type: features.assignment.settings
-  label: "Base type"
-  mapping:
-    types:
-      type: mapping
-      label: "Types"
-      mapping:
-        config:
-          type: sequence
-          label: "Configuration Types"
-          sequence:
-            type: string
-        content:
-          type: sequence
-          label: "Content entity types"
-          sequence:
-            type: string
-
-features.assignment.core:
-  type: features.assignment.settings
-  label: "Core type"
-  mapping:
-    types:
-      type: mapping
-      label: "Types"
-      mapping:
-        config:
-          type: sequence
-          label: "Configuration Types"
-          sequence:
-            type: string
-
-features.assignment.exclude:
-  type: features.assignment.settings
-  label: "Exclude"
-  mapping:
-    types:
-      type: mapping
-      label: "Types"
-      mapping:
-        config:
-          type: sequence
-          label: "Configuration Types"
-          sequence:
-            type: string
-    curated:
-      type: boolean
-      label: "Exclude designated site-specific configuration"
-    module:
-      type: mapping
-      label: "Module"
-      mapping:
-        installed:
-          type: boolean
-          label: "Exclude installed module-provided entity configuration"
-        profile:
-          type: boolean
-          label: "Don't exclude install profile's configuration"
-        namespace:
-          type: boolean
-          label: "Don't exclude non-installed configuration by namespace"
-        namespace_any:
-          type: boolean
-          label: "Don't exclude ANY configuration by namespace"
-
-features.assignment.optional:
-  type: features.assignment.settings
-  label: "Optional"
-  mapping:
-    types:
-      type: mapping
-      label: "Types"
-      mapping:
-        config:
-          type: sequence
-          label: "Configuration Types"
-          sequence:
-            type: string
-
-features.assignment.profile:
-  type: features.assignment.settings
-  label: "Profile"
-  mapping:
-    curated:
-      type: boolean
-      label: "Add commonly-needed configuration"
-    standard:
-      type: mapping
-      label: "Standard"
-      mapping:
-        files:
-          type: boolean
-          label: "Add configuration and files from Standard profile"
-        dependencies:
-          type: boolean
-          label: "Add module and theme dependencies from Standard profile"
-    types:
-      type: mapping
-      label: "Types"
-      mapping:
-        config:
-          type: sequence
-          label: "Configuration Types"
-          sequence:
-            type: string
-
-features.assignment.site:
-  type: features.assignment.settings
-  label: "Site"
-  mapping:
-    types:
-      type: mapping
-      label: "Types"
-      mapping:
-        config:
-          type: sequence
-          label: "Configuration Types"
-          sequence:
-            type: string
-
-features.assignment.alter:
-  type: features.assignment.settings
-  label: "Alter"
-  mapping:
-    core:
-      type: boolean
-      label: "Core"
-    uuid:
-      type: boolean
-      label: "UUID"
-    user_permissions:
-      type: boolean
-      label: "User permissions"
diff --git a/web/modules/features/drush.services.yml b/web/modules/features/drush.services.yml
deleted file mode 100644
index 16b0f29c854acd5ec1557fc1d9bd47bc9224c04c..0000000000000000000000000000000000000000
--- a/web/modules/features/drush.services.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-services:
-  features.commands:
-    class: \Drupal\features\Commands\FeaturesCommands
-    arguments:
-      - '@features_assigner'
-      - '@features.manager'
-      - '@features_generator'
-      - '@config_update.config_diff'
-      - '@config.storage'
-    tags:
-      - { name: drush.command }
diff --git a/web/modules/features/drush/features.drush8.inc b/web/modules/features/drush/features.drush8.inc
deleted file mode 100644
index 35a76abe83d06ef5fd1977039756ab5f918b112e..0000000000000000000000000000000000000000
--- a/web/modules/features/drush/features.drush8.inc
+++ /dev/null
@@ -1,912 +0,0 @@
-<?php
-
-/**
- * @file
- * Features module drush integration.
- */
-
-use Drupal\features\ConfigurationItem;
-use Drupal\features\FeaturesBundleInterface;
-use Drupal\features\FeaturesManagerInterface;
-use Drupal\features\Plugin\FeaturesGeneration\FeaturesGenerationWrite;
-use Drupal\Component\Diff\DiffFormatter;
-
-/**
- * Implements hook_drush_command().
- */
-function features_drush_command() {
-  $items = [];
-
-  $items['features-status'] = [
-    'description' => 'Display current Features settings.',
-    'aliases' => ['fs'],
-  ];
-
-  $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' => [
-      "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' => [
-      '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' => [
-      'default' => 'table',
-      'pipe-format' => 'list',
-      'field-labels' => [
-        'name' => 'Name',
-        'machine_name' => 'Machine name',
-        'status' => 'Status',
-        'version' => 'Version',
-        'state' => 'State',
-        'object' => 'Configuration object',
-      ],
-      'output-data-type' => 'format-table',
-    ],
-    'aliases' => ['fl'],
-  ];
-
-  $items['features-import-all'] = [
-    'description' => 'Import module config from all installed features.',
-    'examples' => [
-      "drush features-import-all" => 'Import module config from all installed features.',
-    ],
-    'aliases' => ['fra', 'fia', 'fim-all'],
-  ];
-
-  $items['features-export'] = [
-    'description' => "Export the configuration on your site into a custom module.",
-    'arguments' => [
-      'package' => 'A space delimited list of features to export.',
-    ],
-    'options' => [
-      'add-profile' => 'Package features into an install profile.',
-    ],
-    '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' => ['fex', 'fu', 'fua', 'fu-all'],
-  ];
-
-  $items['features-add'] = [
-    'description' => "Add a config item to a feature package.",
-    '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' => ['fa', 'fe'],
-  ];
-
-  $items['features-components'] = [
-    'description' => 'List features components.',
-    'arguments' => [
-      'patterns' => 'The features components type to list. Omit this argument to list all components.',
-    ],
-    'options' => [
-      'exported' => [
-        'description' => 'Show only components that have been exported.',
-      ],
-      'not-exported' => [
-        'description' => 'Show only components that have not been exported.',
-      ],
-    ],
-    'aliases' => ['fc'],
-  ];
-
-  $items['features-diff'] = [
-    'description' => "Show the difference between the active config and the default config stored in a feature package.",
-    'arguments' => [
-      'feature' => 'The feature in question.',
-    ],
-    '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' => ['fd'],
-  ];
-
-  $items['features-import'] = [
-    'description' => "Import a module config into your site.",
-    'arguments' => [
-      'feature' => 'A space delimited list of features or feature:component pairs to import.',
-    ],
-    'options' => [
-      'force' => "Force import even if config is not overridden.",
-    ],
-    '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' => ['fim', 'fr'],
-  ];
-
-  foreach ($items as $name => &$item) {
-    $item['options']['bundle'] = [
-      'description' => 'Use a specific bundle namespace.',
-    ];
-  }
-
-  return $items;
-}
-
-/**
- * Applies global options for Features drush commands.
- *
- * The option --name="bundle_name" sets the bundle namespace.
- *
- * @return \Drupal\features\FeaturesAssignerInterface
-*/
-function _drush_features_options() {
-  /** @var \Drupal\features\FeaturesAssignerInterface $assigner */
-  $assigner = \Drupal::service('features_assigner');
-  $bundle_name = drush_get_option('bundle');
-  if (!empty($bundle_name)) {
-    $bundle = $assigner->applyBundle($bundle_name);
-    if ($bundle->getMachineName() != $bundle_name) {
-      drush_log(dt('Bundle @name not found. Using default.', ['@name' => $bundle_name]), 'warning');
-    }
-  }
-  else {
-    $assigner->assignConfigPackages();
-  }
-  return $assigner;
-}
-
-/**
- * Provides Drush command callback for features-status.
- */
-function drush_features_status() {
-  $args = func_get_args();
-  $assigner = _drush_features_options();
-
-
-  /** @var \Drupal\features\FeaturesManagerInterface $manager */
-  $manager = \Drupal::service('features.manager');
-  $current_bundle = $assigner->getBundle();
-  $export_settings = $manager->getExportSettings();
-  $methods = $assigner->getEnabledAssigners();
-  if ($current_bundle->isDefault()) {
-    drush_print(dt('Current bundle: none'));
-  }
-  else {
-    drush_print(dt('Current bundle: @name (@machine_name)',
-      [
-        '@name' => $current_bundle->getName(),
-        '@machine_name' => $current_bundle->getMachineName(),
-      ]));
-  }
-  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));
-
-  if (!empty($args)) {
-    $config = $manager->getConfigCollection();
-    if (count($args) > 1) {
-      print_r(array_keys($config));
-    }
-    else {
-      print_r($config[$args[0]]);
-    }
-  }
-}
-
-/**
- * Drush command callback for features-list-packages.
- *
- * @param string $package_name
- *   (optional) The package name.
- *
- * @return array|bool
- */
-function drush_features_list_packages($package_name = '') {
-  $assigner = _drush_features_options();
-  $current_bundle = $assigner->getBundle();
-  $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 = [];
-
-  // If no package was specified, list all packages.
-  if (empty($package_name)) {
-    drush_hide_output_fields(['object']);
-    foreach ($packages as $package) {
-      $overrides = $manager->detectOverrides($package);
-      $state = $package->getState();
-      if (!empty($overrides) && ($package->getStatus() != FeaturesManagerInterface::STATUS_NO_EXPORT)) {
-        $state = FeaturesManagerInterface::STATE_OVERRIDDEN;
-      }
-
-      $result[$package->getMachineName()] = [
-        'name' => $package->getName(),
-        'machine_name' => $package->getMachineName(),
-        'status' => $manager->statusLabel($package->getStatus()),
-        'version' => $package->getVersion(),
-        'state' => ($state != FeaturesManagerInterface::STATE_DEFAULT)
-          ? $manager->stateLabel($state)
-          : '',
-      ];
-    }
-    return $result;
-  }
-  // If a valid package was listed, list its configuration.
-  else {
-    foreach ($packages as $package) {
-      if ($package->getMachineName() == $package_name) {
-        drush_hide_output_fields([
-          'machine_name',
-          'name',
-          'status',
-          'version',
-          'state',
-        ]);
-        foreach ($package->getConfig() as $item_name) {
-          $result[$item_name] = [
-            'object' => $item_name,
-          ];
-        }
-        return $result;
-      }
-    }
-
-  }
-
-  // If no matching package found, return an error.
-  drush_log(dt('Package "@package" not found.', ['@package' => $package_name]), 'warning');
-  return FALSE;
-}
-
-/**
- * Drush command callback for features-import-all.
- *
- */
-function drush_features_import_all() {
-  $assigner = _drush_features_options();
-  $current_bundle = $assigner->getBundle();
-  $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 = [];
-
-  foreach ($packages as $package) {
-    $overrides = $manager->detectOverrides($package);
-    $missing = $manager->detectMissing($package);
-    if ((!empty($missing) || !empty($overrides)) && ($package->getStatus() == FeaturesManagerInterface::STATUS_INSTALLED)) {
-      $overridden[] = $package->getMachineName();
-    }
-  }
-
-  if (!empty($overridden)) {
-    call_user_func_array('drush_features_import', $overridden);
-  }
-  else {
-    drush_log(dt('Current state already matches active config, aborting.'), 'ok');
-  }
-}
-
-/**
- * Provides Drush command callback for features-export.
- */
-function drush_features_export($packages = NULL) {
-  $packages = func_get_args();
-  $assigner = _drush_features_options();
-
-  /** @var \Drupal\features\FeaturesManagerInterface $manager */
-  $manager = \Drupal::service('features.manager');
-  /** @var \Drupal\features\FeaturesGeneratorInterface $generator */
-  $generator = \Drupal::service('features_generator');
-
-  $current_bundle = $assigner->getBundle();
-
-  if (drush_get_option('add-profile')) {
-    if ($current_bundle->isDefault) {
-      return drush_set_error('', dt("Must specify a profile name with --name"));
-    }
-    $current_bundle->setIsProfile(TRUE);
-  }
-
-  $all_packages = $manager->getPackages();
-  foreach ($packages as $name) {
-    if (!isset($all_packages[$name])) {
-      return drush_set_error('', dt("The package @name does not exist.", ['@name' => $name]));
-    }
-  }
-
-  if (empty($packages)) {
-    $packages = $all_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.');
-    }
-  }
-
-  // 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.", ['@name' => $name, '@directory' => $directory]));
-    }
-    // Apparently, format_plural is not always available.
-    if (count($existing_packages) == 1) {
-      $message = dt('Would you like to overwrite it?');
-    }
-    else {
-      $message = dt('Would you like to overwrite them?');
-    }
-    if (!drush_confirm($message)) {
-      return drush_user_abort();
-    }
-  }
-
-  // Use the write generation method.
-  $method_id = FeaturesGenerationWrite::METHOD_ID;
-  $result = $generator->generatePackages($method_id, $current_bundle, $packages);
-
-  foreach ($result as $message) {
-    $type = $message['success'] ? 'success' : 'error';
-    drush_log($message['message'], $message['variables'], $type);
-  }
-}
-
-/**
- * Adds a component to a features module.
- *
- * @param
- *   The selected components.
- */
-function drush_features_add() {
-  if ($args = func_get_args()) {
-    $assigner = _drush_features_options();
-
-    /** @var \Drupal\features\FeaturesManagerInterface $manager */
-    $manager = \Drupal::service('features.manager');
-    /** @var \Drupal\features\FeaturesGeneratorInterface $generator */
-    $generator = \Drupal::service('features_generator');
-
-    $current_bundle = $assigner->getBundle();
-
-    $module = array_shift($args);
-    if (empty($args)) {
-      return drush_set_error('', 'No components supplied.');
-    }
-    $components = _drush_features_component_list();
-    $options = [
-      'exported' => FALSE,
-    ];
-
-    $filtered_components = _drush_features_component_filter($components, $args, $options);
-    $items = $filtered_components['components'];
-
-    if (empty($items)) {
-      return drush_set_error('', 'No components to add.');
-    }
-
-    $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.", ['@name' => $name, '@directory' => $directory]));
-      }
-      // Apparently, format_plural is not always available.
-      if (count($existing_packages) == 1) {
-        $message = dt('Would you like to overwrite it?');
-      }
-      else {
-        $message = dt('Would you like to overwrite them?');
-      }
-      if (!drush_confirm($message)) {
-        return drush_user_abort();
-      }
-    }
-    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', ['@name' => $full_name, '@directory' => $path]));
-      if (!drush_confirm(dt('Do you really want to continue?'))) {
-        drush_die('Aborting.');
-      }
-    }
-
-    $config = _drush_features_build_config($items);
-
-    $manager->assignConfigPackage($module, $config);
-
-    // Use the write generation method.
-    $method_id = FeaturesGenerationWrite::METHOD_ID;
-    $result = $generator->generatePackages($method_id, $current_bundle, $packages);
-
-    foreach ($result as $message) {
-      $type = $message['success'] ? 'success' : 'error';
-      drush_log($message['message'], $message['variables'], $type);
-    }
-  }
-  else {
-    return drush_set_error('', 'No feature name given.');
-  }
-}
-
-/**
- * Lists components, with pattern matching.
- */
-function drush_features_components() {
-  $args = func_get_args();
-  _drush_features_options();
-
-  $components = _drush_features_component_list();
-  ksort($components);
-  // If no args supplied, prompt with a list.
-  if (empty($args)) {
-    $types = array_keys($components);
-    array_unshift($types, 'all');
-    $choice = drush_choice($types, 'Enter a number to choose which component type to list.');
-    if ($choice === FALSE) {
-      return;
-    }
-
-    $args = ($choice == 0) ? ['*'] : [$types[$choice]];
-  }
-  $options = [
-    'provided by' => TRUE,
-  ];
-  if (drush_get_option(['exported', 'e'], NULL)) {
-    $options['not exported'] = FALSE;
-  }
-  elseif (drush_get_option(['not-exported', 'o'], NULL)) {
-    $options['exported'] = FALSE;
-  }
-
-  $filtered_components = _drush_features_component_filter($components, $args, $options);
-  if ($filtered_components) {
-    _drush_features_component_print($filtered_components);
-  }
-}
-
-/**
- * Lists the differences in the package config vs the active store.
- *
- * @param string $package
- *   The machine name of a package.
- */
-function drush_features_diff() {
-  if (!$args = func_get_args()) {
-    drush_print_table(drush_features_list_packages());
-    return;
-  }
-
-  /** @var \Drupal\features\FeaturesManagerInterface $manager */
-  $manager = \Drupal::service('features.manager');
-  /** @var \Drupal\features\FeaturesAssignerInterface $assigner */
-  $assigner = \Drupal::service('features_assigner');
-  $assigner->assignConfigPackages();
-
-  $module = $args[0];
-  $filter_ctypes = drush_get_option("ctypes");
-  if ($filter_ctypes) {
-    $filter_ctypes = explode(',', $filter_ctypes);
-  }
-
-  $feature = $manager->loadPackage($module, TRUE);
-  if (empty($feature)) {
-    drush_log(dt('No such feature is available: @module', ['@module' => $module]), 'error');
-    return;
-  }
-
-  $lines = drush_get_option('lines');
-  $lines = isset($lines) ? $lines : 2;
-
-  $formatter = new DiffFormatter();
-  $formatter->leading_context_lines = $lines;
-  $formatter->trailing_context_lines = $lines;
-  $formatter->show_header = FALSE;
-
-  if (drush_get_context('DRUSH_NOCOLOR')) {
-    $red = $green = "%s";
-  }
-  else {
-    $red = "\033[31;40m\033[1m%s\033[0m";
-    $green = "\033[0;32;40m\033[1m%s\033[0m";
-  }
-
-  $overrides = $manager->detectOverrides($feature);
-  $missing = $manager->reorderMissing($manager->detectMissing($feature));
-  $overrides = array_merge($overrides, $missing);
-
-  if (empty($overrides)) {
-    drush_print(dt('Active config matches stored config for @module.', ['@module' => $module]));
-  }
-  else {
-    /** @var \Drupal\config_update\ConfigDiffInterface $config_diff */
-    $config_diff = \Drupal::service('config_update.config_diff');
-    /** @var \Drupal\Core\Config\StorageInterface $active_storage */
-    $active_storage = \Drupal::service('config.storage');
-
-    // Print key for colors.
-    drush_print(dt('Legend: '));
-    drush_print(sprintf($red, dt('Code:    drush features-import will replace the active config with the displayed code.')));
-    drush_print(sprintf($green, dt('Active:  drush features-export will update the exported feature with the displayed active config')));
-
-    foreach ($overrides as $name) {
-      $message = '';
-      if (in_array($name, $missing)) {
-        $message = sprintf($red, t('(missing from active)'));
-        $extension = [];
-      }
-      else {
-        $active = $manager->getActiveStorage()->read($name);
-        $extension = $manager->getExtensionStorages()->read($name);
-        if (empty($extension)) {
-          $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", ['@name' => $name, '@message' => $message]));
-      if (!empty($extension)) {
-        foreach ($rows as $row) {
-          if (strpos($row, '>') === 0) {
-            drush_print(sprintf($green, $row));
-          }
-          elseif (strpos($row, '<') === 0) {
-            drush_print(sprintf($red, $row));
-          }
-          else {
-            drush_print($row);
-          }
-        }
-      }
-    }
-  }
-}
-
-/**
- * Imports module config into the active store.
- *
- * Same as the old "revert" functionality.
- */
-function drush_features_import() {
-  if ($args = func_get_args()) {
-    _drush_features_options();
-
-    // Determine if revert should be forced.
-    $force = drush_get_option('force');
-    // Determine if -y was supplied. If so, we can filter out needless output
-    // from this command.
-    $skip_confirmation = drush_get_context('DRUSH_AFFIRMATIVE');
-
-    /** @var \Drupal\features\FeaturesManagerInterface $manager */
-    $manager = \Drupal::service('features.manager');
-
-    // Parse list of arguments.
-    $modules = [];
-    foreach ($args as $arg) {
-      $arg = explode(':', $arg);
-      $module = array_shift($arg);
-      $component = array_shift($arg);
-
-      if (isset($module)) {
-        if (empty($component)) {
-          // If we received just a feature name, this means that we need all of
-          // its components.
-          $modules[$module] = TRUE;
-        }
-        elseif ($modules[$module] !== TRUE) {
-          if (!isset($modules[$module])) {
-            $modules[$module] = [];
-          }
-          $modules[$module][] = $component;
-        }
-      }
-    }
-
-    // Process modules.
-    foreach ($modules as $module => $components_needed) {
-
-      $dt_args['@module'] = $module;
-      /** @var \Drupal\features\Package $feature */
-      $feature = $manager->loadPackage($module, TRUE);
-      if (empty($feature)) {
-        drush_log(dt('No such feature is available: @module', $dt_args), 'error');
-        return;
-      }
-
-      if ($feature->getStatus() != FeaturesManagerInterface::STATUS_INSTALLED) {
-        drush_log(dt('No such feature is installed: @module', $dt_args), 'error');
-        return;
-      }
-
-      // Forcefully revert all components of a feature.
-      if ($force) {
-        $components = $feature->getConfigOrig();
-      }
-      // Only revert components that are detected to be Overridden.
-      else {
-        $components = $manager->detectOverrides($feature);
-        $missing = $manager->reorderMissing($manager->detectMissing($feature));
-        // Be sure to import missing components first.
-        $components = array_merge($missing, $components);
-      }
-
-      if (!empty($components_needed) && is_array($components_needed)) {
-        $components = array_intersect($components, $components_needed);
-      }
-
-      if (empty($components)) {
-        drush_log(dt('Current state already matches active config, aborting.'), 'ok');
-      }
-      else {
-        // Determine which config the user wants to import/revert.
-        $config_to_create = [];
-        foreach ($components as $component) {
-          $dt_args['@component'] = $component;
-          $confirmation_message = 'Do you really want to import @module : @component?';
-          if ($skip_confirmation || drush_confirm(dt($confirmation_message, $dt_args))) {
-            $config_to_create[$component] = '';
-          }
-        }
-
-        // Perform the import/revert.
-        $config_imported = $manager->createConfiguration($config_to_create);
-
-        // List the results.
-        foreach ($components as $component) {
-          $dt_args['@component'] = $component;
-          if (isset($config_imported['new'][$component])) {
-            drush_log(dt('Imported @module : @component.', $dt_args), 'ok');
-          }
-          elseif (isset($config_imported['updated'][$component])) {
-            drush_log(dt('Reverted @module : @component.', $dt_args), 'ok');
-          }
-          elseif (!isset($config_to_create[$component])) {
-            drush_log(dt('Skipping @module : @component.', $dt_args), 'ok');
-          }
-          else {
-            drush_log(dt('Error importing @module : @component.', $dt_args), 'error');
-          }
-        }
-      }
-    }
-  }
-  else {
-    drush_print_table(drush_features_list_packages());
-    return;
-  }
-}
-
-/**
- * Returns an array of full config names given a array[$type][$component].
- *
- * @param array $items
- *   The items to return data for.
- */
-function _drush_features_build_config(array $items) {
-  /** @var \Drupal\features\FeaturesManagerInterface $manager */
-  $manager = \Drupal::service('features.manager');
-  $result = [];
-  foreach ($items as $config_type => $item) {
-    foreach ($item as $item_name => $title) {
-      $result[] = $manager->getFullName($config_type, $item_name);
-    }
-  }
-  return $result;
-}
-
-/**
- * Returns a listing of all known components, indexed by source.
- */
-function _drush_features_component_list() {
-  $result = [];
-  /** @var \Drupal\features\FeaturesManagerInterface $manager */
-  $manager = \Drupal::service('features.manager');
-  $config = $manager->getConfigCollection();
-  foreach ($config as $item_name => $item) {
-    $result[$item->getType()][$item->getShortName()] = $item->getLabel();
-  }
-  return $result;
-}
-
-/**
- * Filters components by patterns.
- */
-function _drush_features_component_filter($all_components, $patterns = [], $options = []) {
-  $options += [
-    'exported' => TRUE,
-    'not exported' => TRUE,
-    'provided by' => FALSE,
-  ];
-  $pool = [];
-  // Maps exported components to feature modules.
-  $components_map = _drush_features_get_component_map();
-  // First filter on exported state.
-  foreach ($all_components as $source => $components) {
-    foreach ($components as $name => $title) {
-      $exported = count($components_map[$source][$name]) > 0;
-      if ($exported) {
-        if ($options['exported']) {
-          $pool[$source][$name] = $title;
-        }
-      }
-      else {
-        if ($options['not exported']) {
-          $pool[$source][$name] = $title;
-        }
-      }
-    }
-  }
-
-  $state_string = '';
-
-  if (!$options['exported']) {
-    $state_string = 'unexported';
-  }
-  elseif (!$options['not exported']) {
-    $state_string = 'exported';
-  }
-
-  $selected = [];
-  foreach ($patterns as $pattern) {
-    // Rewrite * to %. Let users use both as wildcard.
-    $pattern = strtr($pattern, ['*' => '%']);
-    $sources = [];
-    list($source_pattern, $component_pattern) = explode(':', $pattern, 2);
-    // If source is empty, use a pattern.
-    if ($source_pattern == '') {
-      $source_pattern = '%';
-    }
-    if ($component_pattern == '') {
-      $component_pattern = '%';
-    }
-
-    $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.
-    if (strpos($source_pattern, '%') !== FALSE) {
-      $preg_source_pattern = '^' . $preg_source_pattern . '$';
-    }
-    if (strpos($component_pattern, '%') !== FALSE) {
-      $preg_component_pattern = '^' . $preg_component_pattern . '$';
-    }
-    $matches = [];
-
-    // Find the sources.
-    $all_sources = array_keys($pool);
-    $matches = preg_grep('/' . $preg_source_pattern . '/', $all_sources);
-    if (count($matches) > 0) {
-      // If we have multiple matches and the source string wasn't a
-      // pattern, check if one of the matches is equal to the pattern, and
-      // use that, or error out.
-      if (count($matches) > 1 and $preg_source_pattern[0] != '^') {
-        if (in_array($source_pattern, $matches)) {
-          $matches = [$source_pattern];
-        }
-        else {
-          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"', ['@state' => $state_string, '@source' => $source_pattern]));
-    }
-
-    // Now find the components.
-    foreach ($sources as $source) {
-      // Find the components.
-      $all_components = array_keys($pool[$source]);
-      // See if there's any matches.
-      $matches = preg_grep('/' . $preg_component_pattern . '/', $all_components);
-      if (count($matches) > 0) {
-        // If we have multiple matches and the components string wasn't a
-        // pattern, check if one of the matches is equal to the pattern, and
-        // use that, or error out.
-        if (count($matches) > 1 and $preg_component_pattern[0] != '^') {
-          if (in_array($component_pattern, $matches)) {
-            $matches = [$component_pattern];
-          }
-          else {
-            return drush_set_error('', dt('Ambiguous component "@component", matches @matches', [
-              '@component' => $component_pattern,
-              '@matches' => implode(', ', $matches),
-            ]));
-          }
-        }
-        if (!is_array($selected[$source])) {
-          $selected[$source] = [];
-        }
-        $selected[$source] += array_intersect_key($pool[$source], array_flip($matches));
-      }
-      else {
-        // 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"', [
-            '@state' => $state_string,
-            '@component' => $component_pattern,
-            '@source' => $source,
-          ]));
-        }
-      }
-    }
-  }
-
-  // Lastly, provide feature module information on the selected components, if
-  // requested.
-  $provided_by = [];
-  if ($options['provided by'] && $options['exported']) {
-    foreach ($selected as $source => $components) {
-      foreach ($components as $name => $title) {
-        $exported = count($components_map[$source][$name]) > 0;
-        if ($exported) {
-          $provided_by[$source . ':' . $name] = implode(', ', $components_map[$source][$name]);
-        }
-      }
-    }
-  }
-
-  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 = [];
-  /** @var \Drupal\features\FeaturesManagerInterface $manager */
-  $manager = \Drupal::service('features.manager');
-  // Recalc full config list without running assignments.
-  $config = $manager->getConfigCollection();
-  $packages = $manager->getPackages();
-
-  foreach ($config as $item_name => $item) {
-    $type = $item->getType();
-    $short_name = $item->getShortName();
-    $name = $item->getName();
-    if (!isset($result[$type][$short_name])) {
-      $result[$type][$short_name] = [];
-    }
-    if (!empty($item->getPackage())) {
-      $package = $packages[$item->getPackage()];
-      $result[$type][$short_name][] = $package->getMachineName();
-    }
-  }
-
-  return $result;
-}
-
-/**
- * Prints a list of filtered components.
- */
-function _drush_features_component_print($filtered_components) {
-  $rows = [[dt('Available sources')]];
-  foreach ($filtered_components['components'] as $source => $components) {
-    foreach ($components as $name => $value) {
-      $row = [$source . ':' . $name];
-      if (isset($filtered_components['sources'][$source . ':' . $name])) {
-        $row[] = dt('Provided by') . ': ' . $filtered_components['sources'][$source . ':' . $name];
-      }
-      $rows[] = $row;
-    }
-  }
-
-  drush_print_table($rows, TRUE);
-}
diff --git a/web/modules/features/features.info.yml b/web/modules/features/features.info.yml
deleted file mode 100644
index 65cef8a96ca2a5d8231519bbe1f16df1b6c575d9..0000000000000000000000000000000000000000
--- a/web/modules/features/features.info.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-name: 'Features'
-type: module
-description: 'Enables administrators to package configuration into modules.'
-package: Development
-# core: 8.x
-dependencies:
-  - drupal:config
-  - config_update:config_update
-
-# Information added by Drupal.org packaging script on 2018-09-09
-version: '8.x-3.8'
-core: '8.x'
-project: 'features'
-datestamp: 1536512288
diff --git a/web/modules/features/features.install b/web/modules/features/features.install
deleted file mode 100644
index 5bb46f01f314ff48308f8048bfac8482f3ca8c68..0000000000000000000000000000000000000000
--- a/web/modules/features/features.install
+++ /dev/null
@@ -1,31 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains install and update functions for Features.
- */
-
-/**
- * Rebuild the container to add a parameter to the features.manager service.
- */
-function features_update_8300() {
-  // Empty update to cause a cache rebuild so that the container is rebuilt.
-}
-
-/**
- * Update existing feature bundles with new alter plugin configuration.
- */
-function features_update_8301() {
-  foreach (\Drupal::service('entity_type.manager')->getStorage('features_bundle')->loadMultiple() as $bundle) {
-    $bundle = \Drupal::configFactory()->getEditable('features.bundle.' . $bundle->id());
-    $assignments = $bundle->get('assignments');
-    $assignments['alter'] = [
-      'core' => TRUE,
-      'uuid' => TRUE,
-      'user_permissions' => TRUE,
-      'enabled' => TRUE,
-      'weight' => 0,
-    ];
-    $bundle->set('assignments', $assignments)->save();
-  }
-}
diff --git a/web/modules/features/features.module b/web/modules/features/features.module
deleted file mode 100644
index 3bf4bf7348140c450ca6243d8c2ad6919d5dbdce..0000000000000000000000000000000000000000
--- a/web/modules/features/features.module
+++ /dev/null
@@ -1,56 +0,0 @@
-<?php
-
-/**
- * @file
- * Main hooks for Features module.
- */
-
-use Drupal\Core\Routing\RouteMatchInterface;
-
-/**
- * Implements hook_help().
- */
-function features_help($route_name, RouteMatchInterface $route_match) {
-  switch ($route_name) {
-    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>', [
-        ':url' => 'http://drupal.org/node/2404427',
-      ]) . '</p>';
-      return $output;
-  }
-}
-
-/**
- * Implements hook_file_download().
- */
-function features_file_download($uri) {
-  $scheme = file_uri_scheme($uri);
-  $target = file_uri_target($uri);
-
-  if ($scheme == 'temporary' && $target) {
-    $request = \Drupal::request();
-    $route = $request->attributes->get('_route');
-    // Check if we were called by Features download route.
-    // No additional access checking needed here: route requires
-    // "export configuration" permission, token is validated by the controller.
-    // @see \Drupal\features\Controller\FeaturesController::downloadExport()
-    if ($route == 'features.export_download') {
-      return [
-        'Content-disposition' => 'attachment; filename="' . $target . '"',
-      ];
-    }
-  }
-}
-
-/**
- * Implements hook_modules_installed().
- */
-function features_modules_installed($modules) {
-  if (!in_array('features', $modules)) {
-    /** @var \Drupal\features\FeaturesAssignerInterface $assigner */
-    $assigner = \Drupal::service('features_assigner');
-    $assigner->purgeConfiguration();
-  }
-}
diff --git a/web/modules/features/features.routing.yml b/web/modules/features/features.routing.yml
deleted file mode 100644
index 3b6c25b334487103a691a1900f9d70361a92ab32..0000000000000000000000000000000000000000
--- a/web/modules/features/features.routing.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-features.export_download:
-  path: '/admin/config/development/features/download/{uri}'
-  defaults:
-    _controller: 'Drupal\features\Controller\FeaturesController::downloadExport'
-  requirements:
-    _permission: 'export configuration'
diff --git a/web/modules/features/features.services.yml b/web/modules/features/features.services.yml
deleted file mode 100644
index 6122f5353fc3f24940b33536eb6c36ddd0ae060f..0000000000000000000000000000000000000000
--- a/web/modules/features/features.services.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-services:
-  plugin.manager.features_assignment_method:
-    class: Drupal\features\FeaturesAssignmentMethodManager
-    arguments: ['@container.namespaces', '@cache.discovery', '@module_handler']
-  plugin.manager.features_generation_method:
-    class: Drupal\features\FeaturesGenerationMethodManager
-    arguments: ['@container.namespaces', '@cache.discovery', '@module_handler']
-  features_assigner:
-    class: Drupal\features\FeaturesAssigner
-    arguments: ['@features.manager', '@plugin.manager.features_assignment_method', '@entity.manager', '@config.factory', '@config.storage']
-    calls:
-      - [initFeaturesManager]
-  features_generator:
-    class: Drupal\features\FeaturesGenerator
-    arguments: ['@features.manager', '@plugin.manager.features_generation_method', '@features_assigner']
-    calls:
-      - [initFeaturesManager]
-  features.manager:
-    class: Drupal\features\FeaturesManager
-    arguments: ['@app.root', '@entity.manager', '@config.factory', '@config.storage', '@config.manager', '@module_handler', '@features.config_update']
-
-  features.config_update:
-    class: Drupal\config_update\ConfigReverter
-    arguments: ['@entity.manager', '@config.storage', '@features.extension_storage', '@features.extension_optional_storage', '@config.factory', '@event_dispatcher']
-
-  features.extension_storage:
-    class: Drupal\features\FeaturesInstallStorage
-    arguments: ['@config.storage']
-
-  features.extension_optional_storage:
-    class: Drupal\features\FeaturesInstallStorage
-    arguments: ['@config.storage', 'config/optional']
-
-  features.config.installer:
-    class: Drupal\features\FeaturesConfigInstaller
-    decorates: config.installer
-    decoration_priority: 9
-    arguments: ['@features.config.installer.inner', '@features.manager', '@config.factory', '@config.storage', '@config.typed', '@config.manager', '@event_dispatcher']
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
deleted file mode 100644
index 1f8a7817893f8f97aa3549c615537cdd729427f1..0000000000000000000000000000000000000000
--- a/web/modules/features/modules/features_ui/css/features_ui.admin.css
+++ /dev/null
@@ -1,283 +0,0 @@
-span.features-item-list span {
-  background: #eee;
-  border-radius: 5px;
-  margin-right: 5px;
-  padding: 2px 5px;
-  white-space: nowrap;
-  line-height: 1.7em;
-}
-
-.features-listing span.features-override,
-.features-listing a.features-override {
-  background: #FFCE6F;
-  border-radius: 5px;
-  margin-right: 5px;
-  padding: 2px 5px;
-  white-space: nowrap;
-}
-
-.features-listing span.features-detected,
-.features-listing a.features-detected {
-  color:#68a;
-  background:#def;
-  border-radius: 5px;
-  margin-right: 5px;
-  padding: 2px 5px;
-  white-space: nowrap;
-}
-
-.features-listing span.features-conflict,
-.features-listing a.features-conflict {
-  color: #fff;
-  background-color: #c30 !important;
-  border-radius: 5px;
-  margin-right: 5px;
-  padding: 2px 5px;
-  white-space: nowrap;
-}
-
-.features-listing span.features-moved,
-.features-listing a.features-moved {
-  color: #fff;
-  background-color: #215900 !important;
-  border-radius: 5px;
-  margin-right: 5px;
-  padding: 2px 5px;
-  white-space: nowrap;
-}
-
-.features-listing span.features-missing,
-.features-listing a.features-missing {
-  color: #fff;
-  background-color: #0E5EA9 !important;
-  border-radius: 5px;
-  margin-right: 5px;
-  padding: 2px 5px;
-  white-space: nowrap;
-}
-
-table.features-listing .column-nowrap {
-  white-space: nowrap;
-}
-
-tr.features-export-header-row td {
-  border-top: 30px solid white;
-  background: #eee;
-  padding-top: 10px;
-}
-
-#features-assignment-methods tr.draggable > td:nth-child(1) {
-  white-space: nowrap;
-}
-
-/** Styles for Features Export/Listing page **/
-.features-listing td {
-  vertical-align: top;
-}
-
-.features-listing td.feature-name {
-  font-size: 14px;
-  white-space: nowrap;
-}
-
-.features-listing td details {
-  border: 0;
-  margin: 0;
-  height: 20px;
-}
-
-.features-listing details[open] {
-  height: auto;
-  overflow: visible;
-  white-space: normal;
-}
-
-.features-listing td summary {
-  padding: 0;
-  text-transform: none;
-  font-weight: normal;
-}
-
-.features-listing td .features-item-label {
-  font-weight: bold;
-}
-
-.features-header > div,
-.features-header > input {
-  display: inline-block;
-}
-
-/** Styles for Features Edit page **/
-
-.fieldset-legend {
-  font-size: 14px;
-}
-
-#features-export-info {
-  width: 49%;
-  float: left;
-  position: relative;
-}
-#features-export-wrapper {
-  width: 49%;
-  float: right;
-  clear: both;
-  position: relative;
-}
-
-.form-type-checkbox.form-item-conflicts {
-  clear: left;
-}
-
-div.features-export-list  {
-  font-weight: normal;
-  font-size: 12px;
-  border: 1px solid #CCC;
-  border-top-width: 0;
-  overflow: hidden;
-  padding: 0 10px 0 30px;
-}
-
-span.features-component-list span {
-  white-space:nowrap;
-  margin-right:5px;
-  padding:2px 5px;
-  background:#eee;
-  border-radius:5px;
-}
-
-div.features-export-empty {
-  display: none;
-}
-
-span.features-component-list span.features-conflict {
-  background-color: #c30 !important;
-  color: #fff;
-}
-
-span.features-component-list .features-detected {
-  color:#68a;
-  background:#def;
-}
-
-span.features-component-list .features-dependency {
-  color:#999;
-  background:#f8f8f8;
-}
-
-#features-legend .fieldset-wrapper span {
-  font-style: normal;
-  color: black;
-  display: inline-block;
-  background: transparent;
-  border: 1px solid #DDD;
-  border-radius: 5px;
-  white-space: nowrap;
-  padding: 0 8px;
-  margin: 0 10px 0 0;
-}
-#features-export-wrapper .config-name {
-  color: #777;
-}
-#features-export-wrapper .component-detected .form-type-checkbox,
-#features-legend .fieldset-wrapper .component-detected {
-  font-style: italic;
-  color:#68a;
-  background:#def;
-  border-width: 0;
-}
-#features-export-wrapper .component-added .form-type-checkbox,
-#features-legend .fieldset-wrapper .component-added {
-  font-weight: bold;
-  background: #EEE;
-  border-width: 0;
-}
-#features-export-wrapper .component-conflict.form-type-checkbox,
-#features-legend .fieldset-wrapper .component-conflict {
-  color: #c30 !important;
-  font-weight: bold !important;
-}
-
-#features-export-wrapper .component-conflict.form-type-checkbox label,
-#features-export-wrapper .component-added .form-type-checkbox label {
-  font-weight: bold !important;
-}
-
-#features-filter input[size="60"].form-text {
-  width: 200px;
-}
-#features-filter .fieldset-content,
-#features-filter .fieldset-wrapper,
-#features-filter fieldset {
-  border: 0;
-  padding: 0;
-  margin: 0;
-}
-#features-filter fieldset legend {
-  display: none;
-}
-#features-filter label,
-#features-filter input {
-  display: inline;
-  width: auto;
-}
-#features-filter .form-item {
-  float: left;
-  margin: 5px 0;
-  padding: 0;
-}
-#features-filter .form-item.form-type-checkbox {
-  margin: 5px 0;
-}
-#features-filter span {
-  float: left;
-  white-space: normal;
-  margin: 5px 5px;
-  padding: 0 5px;
-  background: transparent;
-  background: #EEE;
-  border-radius: 5px;
-  cursor: pointer;
-}
-#features-filter span:hover {
-  background:#def;
-}
-
-#features-export-wrapper div.features-export-parent {
-  clear: both;
-  margin: 0 0 10px;
-}
-
-details.features-export-component  {
-  background: #F3F8FB;
-  margin: 0;
-  padding: 0 5px;
-}
-details.features-export-component summary {
-  white-space: nowrap;
-  text-transform: none;
-  font-weight: normal;
-  font-size: 14px;
-}
-details.features-export-component summary .component-count {
-  font-size: 11px;
-}
-details.features-export-component .details-wrapper {
-  padding-left: 25px;
-  padding-top: 0;
-}
-
-/** Styles for Bundle assignment config form **/
-#edit-bundles-wrapper .form-item-bundle-bundle-select {
-  display: inline-block;
-}
-
-#edit-bundles-wrapper #edit-bundle-remove {
-  display: inline-block;
-  font-size: 10px;
-}
-
-/** Styles for plugin config forms **/
-.features-assignment-settings-form .fieldset-wrapper {
-  padding-left: 16px;
-}
diff --git a/web/modules/features/modules/features_ui/features_ui.admin.inc b/web/modules/features/modules/features_ui/features_ui.admin.inc
deleted file mode 100644
index 0b7186252e680d6a63a895d434909dfb6564f3e3..0000000000000000000000000000000000000000
--- a/web/modules/features/modules/features_ui/features_ui.admin.inc
+++ /dev/null
@@ -1,175 +0,0 @@
-<?php
-
-/**
- * @file
- * Administration functions for features.module.
- */
-
-use Drupal\Core\Render\Element;
-Use \Drupal\Component\Render\FormattableMarkup;
-use Drupal\Component\Utility\Html;
-
-/**
- * Returns HTML for the features listing form.
- *
- * @param array $variables
- *   An associative array containing:
- *   - form: A render element representing the form.
- *
- * @ingroup themeable
- */
-function theme_features_listing(array $variables) {
-  $form = $variables['form'];
-  $renderer = \Drupal::service('renderer');
-
-  // Individual table headers.
-  $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 = [];
-    // Add the checkbox into the first cell.
-    unset($element['enable']['#title']);
-
-    $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>',
-      [
-        '@id' => $id,
-        '@for' => $element['enable']['#id'],
-        '@name' => $renderer->render($element['name']),
-      ]
-    );
-    $row[] = ['class' => ['module'], 'data' => $col2];
-
-    $row[] = ['class' => ['machine_name'], 'data' => $renderer->render($element['machine_name'])];
-
-    $description = t('@details', ['@details' => $renderer->render($element['details'])]);
-    $details = [
-      '#type' => 'details',
-      '#title' => new FormattableMarkup('<span class="text">@desc</span>', [ '@desc' => $renderer->render($element['description'])]),
-      '#attributes' => ['id' => $element['enable']['#id'] . '-description'],
-      '#description' => $description,
-    ];
-    $row[] = [
-      'class' => ['description', 'expand'],
-      'data' => $renderer->render($details),
-    ];
-    $row[] = [
-      'class' => ['feature-version'],
-      'data' => $renderer->render($element['version']),
-    ];
-    $row[] = [
-      'class' => ['feature-state'],
-      'data' => $renderer->render($element['state']),
-    ];
-
-    $rows[] = ['data' => $row];
-  }
-
-  $table = [
-    '#type' => 'tableselect',
-    '#header' => $form['#header'],
-    '#options' => $rows,
-    '#empty' => t('No Features packages available.'),
-  ];
-  return $renderer->render($table);
-}
-
-/**
- * Prepares variables for package assignment configuration form.
- *
- * @param array $variables
- *   An associative array containing:
- *   - form: A render element representing the form.
- */
-function template_preprocess_features_assignment_configure_form(&$variables) {
-  $form =& $variables['form'];
-
-  $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 = [
-    '#type' => 'table',
-    '#weight' => 5,
-    '#header' => $header,
-    '#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.
-    if (is_array($element) && Element::child($id)) {
-      $table[$id]['#attributes']['class'][] = 'draggable';
-      $table[$id]['#weight'] = $element['#weight'];
-
-      $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];
-      if ($form['#show_operations']) {
-        $table[$id]['operation'] = $form['operation'][$id];
-      }
-      // Unset to prevent rendering along with children.
-      unset($form['title'][$id]);
-      unset($form['description'][$id]);
-      unset($form['enabled'][$id]);
-      unset($form['weight'][$id]);
-      unset($form['operation'][$id]);
-    }
-  }
-
-  // For some reason, the #weight is not being handled by drupal_render.
-  // So we remove the actions and then put them back into the form after the
-  // table.
-  $actions = $form['actions'];
-  unset($form['actions']);
-  $form['table'] = $table;
-  $form['actions'] = $actions;
-}
-
-/**
- * Themes individual items in an item list.
- */
-function theme_features_items(array $variables) {
-  $items = $variables['items'];
-
-  $list = [];
-  foreach ($items as $item) {
-    $class = !empty($item['class']) ? $item['class'] : '';
-    $list[] = '<span class="features-item ' . $class . '" title="' . $item['name'] . '">' . $item['label'] . '</span>';
-  }
-
-  return '<span class="features-item-list">' . implode(' ', $list) . '</span>';
-}
-
-/**
- * Themes the assignment form.
- */
-function theme_assignment_form(array $variables) {
-  $renderer = \Drupal::service('renderer');
-  return $renderer->render($variables['form']);
-}
diff --git a/web/modules/features/modules/features_ui/features_ui.info.yml b/web/modules/features/modules/features_ui/features_ui.info.yml
deleted file mode 100644
index d78b3f7722622573240acda9f88a4cf7c2261b52..0000000000000000000000000000000000000000
--- a/web/modules/features/modules/features_ui/features_ui.info.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-name: Features UI
-type: module
-description: 'Provides the user interface for Features.'
-package: Development
-# core: 8.x
-configure: features.assignment
-dependencies:
-  - features:features
-
-# Information added by Drupal.org packaging script on 2018-09-09
-version: '8.x-3.8'
-core: '8.x'
-project: 'features'
-datestamp: 1536512288
diff --git a/web/modules/features/modules/features_ui/features_ui.libraries.yml b/web/modules/features/modules/features_ui/features_ui.libraries.yml
deleted file mode 100644
index 07a4d490aa54707a03833bf5ca336a35ce0816ac..0000000000000000000000000000000000000000
--- a/web/modules/features/modules/features_ui/features_ui.libraries.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-drupal.features_ui.admin:
-  version: VERSION
-  css:
-    theme:
-      css/features_ui.admin.css: {}
-  js:
-    js/features_ui.admin.js: {}
-  dependencies:
-    - core/jquery
-    - core/drupal
-    - core/drupalSettings
diff --git a/web/modules/features/modules/features_ui/features_ui.links.action.yml b/web/modules/features/modules/features_ui/features_ui.links.action.yml
deleted file mode 100644
index 93a37b453cce42b8b3492dfd8527f43c5d1d8452..0000000000000000000000000000000000000000
--- a/web/modules/features/modules/features_ui/features_ui.links.action.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-features_ui.feature_add:
-  route_name: features.edit
-  title: 'Create new feature'
-  appears_on:
-    - features.export
diff --git a/web/modules/features/modules/features_ui/features_ui.links.menu.yml b/web/modules/features/modules/features_ui/features_ui.links.menu.yml
deleted file mode 100644
index 379a3e4cf28039a8339bc6429c7f1ccb0b1b7ee5..0000000000000000000000000000000000000000
--- a/web/modules/features/modules/features_ui/features_ui.links.menu.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-features.export:
-  title: 'Features'
-  description: 'Package your configuration into feature modules.'
-  route_name: features.export
-  parent: system.admin_config_development
diff --git a/web/modules/features/modules/features_ui/features_ui.links.task.yml b/web/modules/features/modules/features_ui/features_ui.links.task.yml
deleted file mode 100644
index fb8d6360d9dcec80fc14a620311814beff053194..0000000000000000000000000000000000000000
--- a/web/modules/features/modules/features_ui/features_ui.links.task.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-features.export:
-  route_name: features.export
-  title: 'Features'
-  base_route: features.export
-
-features.assignment:
-  route_name: features.assignment
-  title: 'Configure Bundles'
-  base_route: features.export
-
-features.diff:
-  route_name: features.diff
-  title: 'Differences'
-  base_route: features.export
diff --git a/web/modules/features/modules/features_ui/features_ui.module b/web/modules/features/modules/features_ui/features_ui.module
deleted file mode 100644
index 1860427bd40ff4d4fec4eb13948f6fb30e7e29a2..0000000000000000000000000000000000000000
--- a/web/modules/features/modules/features_ui/features_ui.module
+++ /dev/null
@@ -1,55 +0,0 @@
-<?php
-
-/**
- * @file
- * Allows site administrators to modify configuration.
- */
-
-use Drupal\Core\Routing\RouteMatchInterface;
-
-/**
- * Implements hook_help().
- */
-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:', [':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>.', [':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;
-
-    case 'features.export':
-      $output = '';
-      $output .= '<p>' . t('Export packages of configuration into modules.') . '</p>';
-      return $output;
-  }
-}
-
-/**
- * Implements hook_theme().
- */
-function features_ui_theme() {
-  return [
-    'features_listing' => [
-      'render element' => 'form',
-      'file' => 'features_ui.admin.inc',
-      'function' => 'theme_features_listing',
-    ],
-    'features_assignment_configure_form' => [
-      'render element' => 'form',
-      'file' => 'features_ui.admin.inc',
-      'function' => 'theme_assignment_form',
-    ],
-    'features_items' => [
-      'variables' => [
-        'items' => [],
-      ],
-      'file' => 'features_ui.admin.inc',
-      'function' => 'theme_features_items',
-    ],
-  ];
-}
diff --git a/web/modules/features/modules/features_ui/features_ui.routing.yml b/web/modules/features/modules/features_ui/features_ui.routing.yml
deleted file mode 100644
index 9343aee071cdc7d6bc11a91f6258167ba6eca3f6..0000000000000000000000000000000000000000
--- a/web/modules/features/modules/features_ui/features_ui.routing.yml
+++ /dev/null
@@ -1,104 +0,0 @@
-features.export:
-  path: '/admin/config/development/features'
-  defaults:
-    _form: '\Drupal\features_ui\Form\FeaturesExportForm'
-    _title: 'Features'
-  requirements:
-    _permission: 'export configuration'
-
-features.assignment:
-  path: '/admin/config/development/features/bundle/{bundle_name}'
-  defaults:
-    _form: '\Drupal\features_ui\Form\AssignmentConfigureForm'
-    _title: 'Bundle assignment'
-    bundle_name: NULL
-  requirements:
-    _permission: 'administer site configuration'
-
-features.assignment_alter:
-  path: '/admin/config/development/features/bundle/_alter/{bundle_name}'
-  defaults:
-    _form: '\Drupal\features_ui\Form\AssignmentAlterForm'
-    _title: 'Configure package configuration altering'
-    bundle_name: NULL
-  requirements:
-    _permission: 'administer site configuration'
-
-features.assignment_base:
-  path: '/admin/config/development/features/bundle/_base/{bundle_name}'
-  defaults:
-    _form: '\Drupal\features_ui\Form\AssignmentBaseForm'
-    _title: 'Configure base package assignment'
-    bundle_name: NULL
-  requirements:
-    _permission: 'administer site configuration'
-
-features.assignment_core:
-  path: '/admin/config/development/features/bundle/_core/{bundle_name}'
-  defaults:
-    _form: '\Drupal\features_ui\Form\AssignmentCoreForm'
-    _title: 'Configure core package assignment'
-    bundle_name: NULL
-  requirements:
-    _permission: 'administer site configuration'
-
-features.assignment_exclude:
-  path: '/admin/config/development/features/bundle/_exclude/{bundle_name}'
-  defaults:
-    _form: '\Drupal\features_ui\Form\AssignmentExcludeForm'
-    _title: 'Configure package exclusion'
-    bundle_name: NULL
-  requirements:
-    _permission: 'administer site configuration'
-
-features.assignment_optional:
-  path: '/admin/config/development/features/bundle/_optional/{bundle_name}'
-  defaults:
-    _form: '\Drupal\features_ui\Form\AssignmentOptionalForm'
-    _title: 'Configure optional package assignment'
-    bundle_name: NULL
-  requirements:
-    _permission: 'administer site configuration'
-
-features.assignment_profile:
-  path: '/admin/config/development/features/bundle/_profile/{bundle_name}'
-  defaults:
-    _form: '\Drupal\features_ui\Form\AssignmentProfileForm'
-    _title: 'Configure profile package assignment'
-    bundle_name: NULL
-  requirements:
-    _permission: 'administer site configuration'
-
-features.assignment_site:
-  path: '/admin/config/development/features/bundle/_site/{bundle_name}'
-  defaults:
-    _form: '\Drupal\features_ui\Form\AssignmentSiteForm'
-    _title: 'Configure site package assignment'
-    bundle_name: NULL
-  requirements:
-    _permission: 'administer site configuration'
-
-features.edit:
-  path: '/admin/config/development/features/edit/{featurename}'
-  defaults:
-    _form: '\Drupal\features_ui\Form\FeaturesEditForm'
-    _title: 'Edit'
-    featurename: ''
-  requirements:
-    _permission: 'administer site configuration'
-
-features.diff:
-  path: '/admin/config/development/features/diff/{featurename}'
-  defaults:
-    _form: '\Drupal\features_ui\Form\FeaturesDiffForm'
-    _title: 'Differences'
-    featurename: ''
-  requirements:
-    _permission: 'administer site configuration'
-
-features.detect:
-  path: '/features/api/detect/{name}'
-  defaults:
-    _controller: '\Drupal\features_ui\Controller\FeaturesUIController::detect'
-  requirements:
-    _permission: 'administer site configuration'
diff --git a/web/modules/features/modules/features_ui/js/features_ui.admin.js b/web/modules/features/modules/features_ui/js/features_ui.admin.js
deleted file mode 100644
index d4019681b1a40acf708906e39e182454c5f78c57..0000000000000000000000000000000000000000
--- a/web/modules/features/modules/features_ui/js/features_ui.admin.js
+++ /dev/null
@@ -1,401 +0,0 @@
-/**
- * jQuery.fn.sortElements
- * --------------
- * @param Function comparator:
- *   Exactly the same behaviour as [1,2,3].sort(comparator)
- *
- * @param Function getSortable
- *   A function that should return the element that is
- *   to be sorted. The comparator will run on the
- *   current collection, but you may want the actual
- *   resulting sort to occur on a parent or another
- *   associated element.
- *
- *   E.g. $('td').sortElements(comparator, function(){
- *      return this.parentNode;
- *   })
- *
- *   The <td>'s parent (<tr>) will be sorted instead
- *   of the <td> itself.
- *
- * Credit: http://james.padolsey.com/javascript/sorting-elements-with-jquery/
- *
- */
-jQuery.fn.sortElements = (function () {
-
-  "use strict";
-
-  var sort = [].sort;
-
-  return function (comparator, getSortable) {
-
-    getSortable = getSortable || function () {return this;};
-
-    var placements = this.map(function () {
-
-      var sortElement = getSortable.call(this);
-      var parentNode = sortElement.parentNode;
-
-      // Since the element itself will change position, we have
-      // to have some way of storing its original position in
-      // the DOM. The easiest way is to have a 'flag' node:
-      var nextSibling = parentNode.insertBefore(
-          document.createTextNode(''),
-          sortElement.nextSibling
-        );
-
-      return function () {
-
-        if (parentNode === this) {
-          throw new Error(
-            "You can't sort elements if any one is a descendant of another."
-          );
-        }
-
-        // Insert before flag:
-        parentNode.insertBefore(this, nextSibling);
-        // Remove flag:
-        parentNode.removeChild(nextSibling);
-
-      };
-
-    });
-
-    return sort.call(this, comparator).each(function (i) {
-      placements[i].call(getSortable.call(this));
-    });
-
-  };
-
-})();
-
-(function ($) {
-
-  "use strict";
-
-  Drupal.behaviors.features = {
-    attach: function (context) {
-
-      // mark any conflicts with a class
-      if ((typeof drupalSettings.features !== 'undefined') && (typeof drupalSettings.features.conflicts !== 'undefined')) {
-      //  for (var configType in drupalSettings.features.conflicts) {
-          if (drupalSettings.features.conflicts) {
-            var configConflicts = drupalSettings.features.conflicts;
-            $('#features-export-wrapper input[type=checkbox]', context).each(function () {
-              if (!$(this).hasClass('features-checkall')) {
-                var key = $(this).attr('name');
-                var matches = key.match(/^([^\[]+)(\[.+\])?\[(.+)\]\[(.+)\]$/);
-                var component = matches[1];
-                var item = matches[4];
-                if ((component in configConflicts) && (item in configConflicts[component])) {
-                  $(this).parent().addClass('component-conflict');
-                }
-              }
-            });
-          }
-        //}
-      }
-
-      function _checkAll(value) {
-        if (value) {
-          $('#features-export-wrapper .component-select input[type=checkbox]:visible', context).each(function () {
-            var move_id = $(this).attr('id');
-            $(this).click();
-            $('#'+ move_id).prop('checked', true);
-          });
-        }
-        else {
-          $('#features-export-wrapper .component-added input[type=checkbox]:visible', context).each(function () {
-            var move_id = $(this).attr('id');
-            $(this).click();
-            $('#'+ move_id).prop('checked', false);
-          });
-        }
-      }
-
-      function updateComponentCountInfo(item, section) {
-        var parent;
-
-        switch (section) {
-          case 'select':
-            parent = $(item).closest('.features-export-list').siblings('.features-export-component');
-            $('.component-count', parent).text(function (index, text) {
-                return +text + 1;
-              }
-            );
-            break;
-          case 'added':
-          case 'detected':
-            parent = $(item).closest('.features-export-component');
-            $('.component-count', parent).text(function (index, text) {
-              return text - 1;
-            });
-        }
-      }
-
-      function moveCheckbox(item, section, value) {
-        updateComponentCountInfo(item, section);
-        var curParent = item;
-        if ($(item).hasClass('form-type-checkbox')) {
-          item = $(item).children('input[type=checkbox]');
-        }
-        else {
-          curParent = $(item).parents('.form-type-checkbox');
-        }
-        var newParent = $(curParent).parents('.features-export-parent').find('.component-'+section+' .form-checkboxes');
-        $(curParent).detach();
-        $(curParent).appendTo(newParent);
-        var list = ['select', 'added', 'detected', 'included'];
-        for (var i in list) {
-          if (list[i]) {
-            $(curParent).removeClass('component-' + list[i]);
-            $(item).removeClass('component-' + list[i]);
-          }
-        }
-        $(curParent).addClass('component-'+section);
-        $(item).addClass('component-'+section);
-        if (value) {
-          $(item).attr('checked', 'checked');
-        }
-        else {
-          $(item).removeAttr('checked');
-        }
-        $(newParent).parents('.component-list').removeClass('features-export-empty');
-
-        // re-sort new list of checkboxes based on labels
-        $(newParent).find('label').sortElements(
-          function (a, b) {
-            return $(a).text() > $(b).text() ? 1 : -1;
-          },
-          function () {
-            return this.parentNode;
-          }
-        );
-      }
-
-      // provide timer for auto-refresh trigger
-      var timeoutID = 0;
-      var inTimeout = 0;
-      function _triggerTimeout() {
-        timeoutID = 0;
-        _updateDetected();
-      }
-      function _resetTimeout() {
-        inTimeout++;
-        // if timeout is already active, reset it
-        if (timeoutID !== 0) {
-          window.clearTimeout(timeoutID);
-          if (inTimeout > 0) { inTimeout--; }
-        }
-        timeoutID = window.setTimeout(_triggerTimeout, 500);
-      }
-
-      function _updateDetected() {
-        if (!drupalSettings.features.autodetect) { return; }
-        // query the server for a list of components/items in the feature and update
-        // the auto-detected items
-        var items = [];  // will contain a list of selected items exported to feature
-        var components = {};  // contains object of component names that have checked items
-        $('#features-export-wrapper input[type=checkbox]:checked', context).each(function () {
-          if (!$(this).hasClass('features-checkall')) {
-            var key = $(this).attr('name');
-            var matches = key.match(/^([^\[]+)(\[.+\])?\[(.+)\]\[(.+)\]$/);
-            components[matches[1]] = matches[1];
-            if (!$(this).hasClass('component-detected')) {
-              items.push(key);
-            }
-          }
-        });
-        var featureName = $('#edit-machine-name').val();
-        if (featureName === '') {
-          featureName = '*';
-        }
-
-        var url = Drupal.url('features/api/detect/' + featureName);
-        var excluded = drupalSettings.features.excluded;
-        var required = drupalSettings.features.required;
-        var postData = {'items': items, 'excluded': excluded, 'required': required};
-        jQuery.post(url, postData, function (data) {
-          if (inTimeout > 0) { inTimeout--; }
-          // if we have triggered another timeout then don't update with old results
-          if (inTimeout === 0) {
-            // data is an object keyed by component listing the exports of the feature
-            for (var component in data) {
-              if (data[component]) {
-                var itemList = data[component];
-                $('#features-export-wrapper .component-' + component + ' input[type=checkbox]', context).each(function () {
-                  var key = $(this).attr('value');
-                  // first remove any auto-detected items that are no longer in component
-                  if ($(this).hasClass('component-detected')) {
-                    if (!(key in itemList)) {
-                      moveCheckbox(this, 'select', false);
-                    }
-                  }
-                  // next, add any new auto-detected items
-                  else if ($(this).hasClass('component-select')) {
-                    if (key in itemList) {
-                      moveCheckbox(this, 'detected', itemList[key]);
-                      $(this).prop('checked', true);
-                      $(this).parent().show(); // make sure it's not hidden from filter
-                    }
-                  }
-                });
-              }
-            }
-            // loop over all selected components and check for any that have been completely removed
-            for (var selectedComponent in components) {
-              if ((data == null) || !(selectedComponent in data)) {
-                $('#features-export-wrapper .component-' + selectedComponent + ' input[type=checkbox].component-detected', context).each(moveCheckbox(this, 'select', false));
-              }
-            }
-          }
-        }, "json");
-      }
-
-      // Handle component selection UI
-      $('#features-export-wrapper input[type=checkbox]', context).click(function () {
-        _resetTimeout();
-        if ($(this).hasClass('component-select')) {
-          moveCheckbox(this, 'added', true);
-        }
-        else if ($(this).hasClass('component-included')) {
-          moveCheckbox(this, 'added', false);
-        }
-        else if ($(this).hasClass('component-added')) {
-          if ($(this).is(':checked')) {
-            moveCheckbox(this, 'included', true);
-          }
-          else {
-            moveCheckbox(this, 'select', false);
-          }
-        }
-      });
-
-      // Handle select/unselect all
-      $('#features-filter .features-checkall.form-checkbox', context).click(function () {
-        if ($(this).prop('checked')) {
-          _checkAll(true);
-          $(this).next().html(Drupal.t('Deselect all'));
-        }
-        else {
-          _checkAll(false);
-          $(this).next().html(Drupal.t('Select all'));
-        }
-        _resetTimeout();
-      });
-
-      // Handle filtering
-
-      // provide timer for auto-refresh trigger
-      var filterTimeoutID = 0;
-      function _triggerFilterTimeout() {
-        filterTimeoutID = 0;
-        _updateFilter();
-      }
-      function _resetFilterTimeout() {
-        // if timeout is already active, reset it
-        if (filterTimeoutID !== 0) {
-          window.clearTimeout(filterTimeoutID);
-          filterTimeoutID = null;
-        }
-        filterTimeoutID = window.setTimeout(_triggerFilterTimeout, 200);
-      }
-      function _updateFilter() {
-        var filter = $('#features-filter input').val();
-        var regex = new RegExp(filter, 'i');
-        // collapse fieldsets
-        var newState = {};
-        var currentState = {};
-        $('#features-export-wrapper details.features-export-component', context).each(function () {
-          // expand parent fieldset
-          var section = $(this).attr('id');
-          var details = $(this);
-
-          currentState[section] = details.prop('open');
-          if (!(section in newState)) {
-            newState[section] = false;
-          }
-
-          details.find('.form-checkboxes label').each(function () {
-            if (filter === '') {
-              // collapse the section, but make checkbox visible
-              if (currentState[section]) {
-                details.prop('open', false);
-                currentState[section] = false;
-              }
-              $(this).parent().show();
-            }
-            else if ($(this).text().match(regex)) {
-              $(this).parent().show();
-              newState[section] = true;
-            }
-            else {
-              $(this).parent().hide();
-            }
-          });
-        });
-        for (var section in newState) {
-          if (currentState[section] !== newState[section]) {
-            if (newState[section]) {
-              $('#'+section).prop('open', true);
-            }
-            else {
-              $('#'+section).prop('open', false);
-            }
-          }
-        }
-      }
-      $('#features-filter input', context).bind("input", function () {
-        _resetFilterTimeout();
-      });
-      $('#features-filter .features-filter-clear', context).click(function () {
-        $('#features-filter input').val('');
-        _updateFilter();
-      });
-
-      // show the filter bar
-      $('#features-filter', context).removeClass('element-invisible');
-
-      // handle Package selection checkboxes in the Differences page
-      $('.features-diff-listing .features-diff-header input.form-checkbox', context).click(function () {
-        var value = $(this).prop('checked');
-        $('.features-diff-listing .diff-'+$(this).prop('value')+' input.form-checkbox', context).each(function () {
-          $(this).prop('checked', value);
-          if (value) {
-            $(this).parents('tr').addClass('selected');
-          }
-          else {
-            $(this).parents('tr').removeClass('selected');
-          }
-        });
-      });
-
-      // handle special theming of headers in tableselect
-      $('td.features-export-header-row', context).each(function () {
-        var row = $(this).parent('tr');
-        row.addClass('features-export-header-row');
-        var checkbox = row.find('td input:checkbox');
-        if (checkbox.length) {
-          checkbox.hide();
-        }
-      });
-
-      // handle clicking anywhere in row on Differences page
-      $('.features-diff-listing tr td:nth-child(2)', context).click(function () {
-        var checkbox = $(this).parent().find('td input:checkbox');
-        checkbox.prop('checked', !checkbox.prop('checked')).triggerHandler('click');
-        if (checkbox.prop('checked')) {
-          $(this).parents('tr').addClass('selected');
-        }
-        else {
-          $(this).parents('tr').removeClass('selected');
-        }
-      });
-      $('.features-diff-listing thead th:nth-child(2)', context).click(function () {
-        var checkbox = $(this).parent().find('th input:checkbox');
-        checkbox.click();
-      });
-    }
-  };
-
-})(jQuery);
diff --git a/web/modules/features/modules/features_ui/src/Controller/FeaturesUIController.php b/web/modules/features/modules/features_ui/src/Controller/FeaturesUIController.php
deleted file mode 100644
index 786a51cd05de6b5f25adbab112823841e068e853..0000000000000000000000000000000000000000
--- a/web/modules/features/modules/features_ui/src/Controller/FeaturesUIController.php
+++ /dev/null
@@ -1,193 +0,0 @@
-<?php
-
-namespace Drupal\features_ui\Controller;
-
-use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-use Symfony\Component\HttpFoundation\JsonResponse;
-use Drupal\features\FeaturesManagerInterface;
-use Drupal\features\FeaturesAssignerInterface;
-
-/**
- * Returns ajax responses for the Features UI.
- */
-class FeaturesUIController implements ContainerInjectionInterface {
-
-  /**
-   * The features manager.
-   *
-   * @var \Drupal\features\FeaturesManagerInterface
-   */
-  protected $featuresManager;
-
-  /**
-   * The package assigner.
-   *
-   * @var array
-   */
-  protected $assigner;
-
-  /**
-   * Constructs a new FeaturesUIController object.
-   *
-   * @param \Drupal\features\FeaturesManagerInterface $features_manager
-   *    The features manager.
-   */
-  public function __construct(FeaturesManagerInterface $features_manager, FeaturesAssignerInterface $assigner) {
-    $this->featuresManager = $features_manager;
-    $this->assigner = $assigner;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container) {
-    return new static(
-      $container->get('features.manager'),
-      $container->get('features_assigner')
-    );
-  }
-
-  /**
-   * Returns a list of auto-detected config items for a feature.
-   *
-   * @param string $name
-   *   Short machine name of feature to process.
-   *
-   * @return array
-   *   List of auto-detected config items, keyed by type and short name.
-   */
-  public function detect($name) {
-    $detected = [];
-    $this->assigner->assignConfigPackages();
-    $config_collection = $this->featuresManager->getConfigCollection();
-
-    $items = $_POST['items'];
-    if (!empty($items)) {
-      $excluded = (!empty($_POST['excluded'])) ? $_POST['excluded'] : [];
-      $selected = [];
-      foreach ($items as $key) {
-        preg_match('/^([^\[]+)(\[.+\])?\[(.+)\]\[(.+)\]$/', $key, $matches);
-        if (!empty($matches[1]) && !empty($matches[4])) {
-          $component = $matches[1];
-          $item = $this->domDecode($matches[4]);
-          if (!isset($excluded[$component][$item])) {
-            $selected[] = $this->featuresManager->getFullName($component, $item);
-          }
-        }
-      }
-      $detected = !empty($selected) ? $this->getConfigDependents($selected, $name) : [];
-      $detected = array_merge($detected, $selected);
-    }
-
-    $result = [];
-    foreach ($detected as $config_name) {
-      $item = $config_collection[$config_name];
-      $result[$item->getType()][$item->getShortName()] = $item->getName();
-    }
-    return new JsonResponse($result);
-  }
-
-  /**
-   * Returns the configuration dependent on given items.
-   *
-   * @param array $item_names
-   *   An array of item names.
-   * @param string $package_name
-   *   Short machine name of feature to process.
-   *
-   * @return array
-   *   An array of config items.
-   */
-  protected function getConfigDependents(array $item_names, $package_name) {
-    $result = [];
-    $config_collection = $this->featuresManager->getConfigCollection();
-    $packages = $this->featuresManager->getPackages();
-    $settings = $this->featuresManager->getSettings();
-    $allow_conflicts = $settings->get('conflicts');
-
-    if (empty($item_names)) {
-      $item_names = array_keys($config_collection);
-    }
-
-    // Add any existing auto-detected items already in the package config
-    $this->package = $packages[$package_name];
-    $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()) {
-        $result[] = $config_name;
-      }
-    }
-
-    // Now add dependents of the items selected
-    foreach ($item_names as $item_name) {
-      if ($config_collection[$item_name]->getPackage()) {
-        foreach ($config_collection[$item_name]->getDependents() as $dependent_item_name) {
-          if (isset($config_collection[$dependent_item_name])) {
-            $allow = TRUE;
-            if (!$allow_conflicts && $config_collection[$dependent_item_name]->getPackage()) {
-              if ($packages[$config_collection[$dependent_item_name]->getPackage()]) {
-                $allow = ($packages[$config_collection[$dependent_item_name]->getPackage()]->getStatus() == FeaturesManagerInterface::STATUS_NO_EXPORT)
-                  || ($config_collection[$item_name]->getPackage() == $config_collection[$dependent_item_name]->getPackage());
-              }
-            }
-            if ($allow) {
-              $result[] = $dependent_item_name;
-            }
-          }
-        }
-      }
-    }
-    return $result;
-  }
-
-  /**
-   * Encodes a given key.
-   *
-   * @param string $key
-   *   The key to encode.
-   *
-   * @return string
-   *   The encoded key.
-   */
-  protected function domEncode($key) {
-    $replacements = $this->domEncodeMap();
-    return strtr($key, $replacements);
-  }
-
-  /**
-   * Decodes a given key.
-   *
-   * @param string $key
-   *   The key to decode.
-   *
-   * @return string
-   *   The decoded key.
-   */
-  protected function domDecode($key) {
-    $replacements = array_flip($this->domEncodeMap());
-    return strtr($key, $replacements);
-  }
-
-  /**
-   * Returns encoding map for decode and encode options.
-   *
-   * @return array
-   *   An encoding map.
-   */
-  protected function domEncodeMap() {
-    return [
-      ':' => '__' . ord(':') . '__',
-      '/' => '__' . ord('/') . '__',
-      ',' => '__' . ord(',') . '__',
-      '.' => '__' . ord('.') . '__',
-      '<' => '__' . ord('<') . '__',
-      '>' => '__' . ord('>') . '__',
-      '%' => '__' . 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
deleted file mode 100644
index 462ee0ba5fb62d71d61625346e675e87644f3d4f..0000000000000000000000000000000000000000
--- a/web/modules/features/modules/features_ui/src/Form/AssignmentAlterForm.php
+++ /dev/null
@@ -1,76 +0,0 @@
-<?php
-
-namespace Drupal\features_ui\Form;
-
-use Drupal\Core\Form\FormStateInterface;
-
-/**
- * Configures the selected configuration assignment method for this site.
- */
-class AssignmentAlterForm extends AssignmentFormBase {
-
-  const METHOD_ID = 'alter';
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormId() {
-    return 'features_assignment_alter_form';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildForm(array $form, FormStateInterface $form_state, $bundle_name = NULL) {
-    $this->currentBundle = $this->assigner->loadBundle($bundle_name);
-
-    $settings = $this->currentBundle->getAssignmentSettings(self::METHOD_ID);
-    $core_setting = $settings['core'];
-    $uuid_setting = $settings['uuid'];
-    $user_permissions_setting = $settings['user_permissions'];
-
-    $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'] = [
-      '#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'] = [
-      '#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);
-
-    return $form;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, FormStateInterface $form_state) {
-    // Merge in selections.
-    $settings = $this->currentBundle->getAssignmentSettings(self::METHOD_ID);
-    $settings = array_merge($settings, [
-      'core' => $form_state->getValue('core'),
-      'uuid' => $form_state->getValue('uuid'),
-      'user_permissions' => $form_state->getValue('user_permissions'),
-    ]);
-
-    $this->currentBundle->setAssignmentSettings(self::METHOD_ID, $settings)->save();
-
-    $this->setRedirect($form_state);
-    drupal_set_message($this->t('Package assignment configuration saved.'));
-  }
-
-}
diff --git a/web/modules/features/modules/features_ui/src/Form/AssignmentBaseForm.php b/web/modules/features/modules/features_ui/src/Form/AssignmentBaseForm.php
deleted file mode 100644
index 44f8022176f321231e0834815a08a66bac6fac7c..0000000000000000000000000000000000000000
--- a/web/modules/features/modules/features_ui/src/Form/AssignmentBaseForm.php
+++ /dev/null
@@ -1,61 +0,0 @@
-<?php
-
-namespace Drupal\features_ui\Form;
-
-use Drupal\Core\Form\FormStateInterface;
-
-/**
- * Configures the selected configuration assignment method for this site.
- */
-class AssignmentBaseForm extends AssignmentFormBase {
-
-  const METHOD_ID = 'base';
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormId() {
-    return 'features_assignment_base_form';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildForm(array $form, FormStateInterface $form_state, $bundle_name = NULL) {
-    $this->currentBundle = $this->assigner->loadBundle($bundle_name);
-    $settings = $this->currentBundle->getAssignmentSettings(self::METHOD_ID);
-
-    // Pass the last argument to limit the select to config entity types that
-    // provide bundles for other entity types.
-    $this->setConfigTypeSelect($form, $settings['types']['config'], $this->t('base'), TRUE);
-    // Pass the last argument to limit the select to content entity types do
-    // not have config entity provided bundles, thus avoiding duplication with
-    // the config type select options.
-    $this->setContentTypeSelect($form, $settings['types']['content'], $this->t('base'), TRUE);
-
-    $this->setActions($form, self::METHOD_ID);
-
-    return $form;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function validateForm(array &$form, FormStateInterface $form_state) {
-    $form_state->setValue('types', array_map('array_filter', $form_state->getValue('types')));
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, FormStateInterface $form_state) {
-    // Merge in types selections.
-    $settings = $this->currentBundle->getAssignmentSettings(self::METHOD_ID);
-    $settings['types'] = $form_state->getValue('types');
-    $this->currentBundle->setAssignmentSettings(self::METHOD_ID, $settings)->save();
-    $this->setRedirect($form_state);
-
-    drupal_set_message($this->t('Package assignment configuration saved.'));
-  }
-
-}
diff --git a/web/modules/features/modules/features_ui/src/Form/AssignmentConfigureForm.php b/web/modules/features/modules/features_ui/src/Form/AssignmentConfigureForm.php
deleted file mode 100644
index 44630827522560299cd53cafe80dd57bbd1c4ca1..0000000000000000000000000000000000000000
--- a/web/modules/features/modules/features_ui/src/Form/AssignmentConfigureForm.php
+++ /dev/null
@@ -1,445 +0,0 @@
-<?php
-
-namespace Drupal\features_ui\Form;
-
-use Drupal\Component\Utility\Html;
-use Drupal\Component\Utility\Unicode;
-use Drupal\features\FeaturesManagerInterface;
-use Drupal\features\FeaturesAssignerInterface;
-use Drupal\features\FeaturesBundleInterface;
-use Drupal\Core\Form\FormBase;
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Url;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Configures the configuration assignment methods for this site.
- */
-class AssignmentConfigureForm extends FormBase {
-
-  /**
-   * Bundle select value that should trigger a new bundle to be created.
-   */
-  const NEW_BUNDLE_SELECT_VALUE = 'new';
-
-  /**
-   * The features manager.
-   *
-   * @var \Drupal\features\FeaturesManagerInterface
-   */
-  protected $featuresManager;
-
-  /**
-   * The package assigner.
-   *
-   * @var \Drupal\features\FeaturesAssignerInterface
-   */
-  protected $assigner;
-
-  /**
-   * Constructs a AssignmentConfigureForm object.
-   *
-   * @param \Drupal\features\FeaturesManagerInterface $features_manager
-   *   The features manager.
-   * @param \Drupal\features\FeaturesAssignerInterface $assigner
-   *   The configuration assignment methods manager.
-   */
-  public function __construct(FeaturesManagerInterface $features_manager, FeaturesAssignerInterface $assigner) {
-    $this->featuresManager = $features_manager;
-    $this->assigner = $assigner;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container) {
-    return new static(
-      $container->get('features.manager'),
-      $container->get('features_assigner')
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormId() {
-    return 'features_assignment_configure_form';
-  }
-
-  /**
-   * Load the values from the bundle into the user input.
-   * Used during Ajax callback since updating #default_values is ignored.
-   * @param $bundle_name
-   * @param \Drupal\Core\Form\FormStateInterface $form_state
-   */
-  protected function loadBundleValues($bundle_name, FormStateInterface &$form_state, $current_bundle, $enabled_methods, $methods_weight) {
-    $input = $form_state->getUserInput();
-    if ($bundle_name == self::NEW_BUNDLE_SELECT_VALUE) {
-      $input['bundle']['name'] = '';
-      $input['bundle']['machine_name'] = '';
-      $input['bundle']['description'] = '';
-      $input['bundle']['is_profile'] = NULL;
-      $input['bundle']['profile_name'] = '';
-    }
-    else {
-      $input['bundle']['name'] = $current_bundle->getName();
-      $input['bundle']['machine_name'] = $current_bundle->getMachineName();
-      $input['bundle']['description'] = $current_bundle->getDescription();
-      $input['bundle']['is_profile'] = $current_bundle->isProfile() ? 1 : null;
-      $input['bundle']['profile_name'] = $current_bundle->isProfile() ? $current_bundle->getProfileName() : '';
-    }
-
-    foreach ($methods_weight as $method_id => $weight) {
-      $enabled = isset($enabled_methods[$method_id]);
-      $input['weight'][$method_id] = $weight;
-      $input['enabled'][$method_id] = $enabled ? 1 : null;
-    }
-
-    $form_state->setUserInput($input);
-  }
-
-  /**
-   * Detects if an element triggered the form submission via Ajax.
-   * TODO: SHOULDN'T NEED THIS!  BUT DRUPAL IS CALLING buildForm AFTER THE
-   * BUNDLE AJAX IS SELECTED AND DOESN'T HAVE getTriggeringElement() SET YET.
-   */
-  protected function elementTriggeredScriptedSubmission(FormStateInterface &$form_state) {
-    $input = $form_state->getUserInput();
-    if (!empty($input['_triggering_element_name'])) {
-      return $input['_triggering_element_name'];
-    }
-    return '';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildForm(array $form, FormStateInterface $form_state, $bundle_name = NULL) {
-    $load_values = FALSE;
-    $trigger = $form_state->getTriggeringElement();
-    // TODO: See if there is a Drupal Core issue for this.
-    // Sometimes the first ajax call on the page causes buildForm to be called
-    // twice!  First time form_state->getTriggeringElement is NOT SET, but
-    // the form_state['input'] shows the _triggering_element_name.  Then the
-    // SECOND time it is called the getTriggeringElement is fine.
-    $real_trigger = $this->elementTriggeredScriptedSubmission($form_state);
-    if (!isset($trigger) && ($real_trigger == 'bundle[bundle_select]')) {
-      $input = $form_state->getUserInput();
-      $bundle_name = $input['bundle']['bundle_select'];
-      if ($bundle_name != self::NEW_BUNDLE_SELECT_VALUE) {
-        $this->assigner->setCurrent($this->assigner->getBundle($bundle_name));
-      }
-      $load_values = TRUE;
-    }
-    elseif ($trigger['#name'] == '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));
-      }
-      $load_values = TRUE;
-    }
-    elseif ($trigger['#name'] == 'removebundle') {
-      $current_bundle = $this->assigner->loadBundle($bundle_name);
-      $bundle_name = $current_bundle->getMachineName();
-      $this->assigner->removeBundle($bundle_name);
-      return $this->redirect('features.assignment', ['']);
-    }
-    if (!isset($current_bundle)) {
-      switch ($bundle_name) {
-        // If no bundle is selected, use the current one.
-        case NULL:
-          $current_bundle = $this->assigner->loadBundle();
-          $bundle_name = $current_bundle->getMachineName();
-          break;
-        case self::NEW_BUNDLE_SELECT_VALUE:
-          $current_bundle = $this->assigner->loadBundle(FeaturesBundleInterface::DEFAULT_BUNDLE);
-          break;
-        default:
-          $current_bundle = $this->assigner->loadBundle($bundle_name);
-          break;
-      }
-    }
-
-    $enabled_methods = $current_bundle->getEnabledAssignments();
-    $methods_weight = $current_bundle->getAssignmentWeights();
-
-    // Add missing data to the methods lists.
-    $assignment_info = $this->assigner->getAssignmentMethods();
-    foreach ($assignment_info as $method_id => $method) {
-      if (!isset($methods_weight[$method_id])) {
-        $methods_weight[$method_id] = isset($method['weight']) ? $method['weight'] : 0;
-      }
-    }
-    // Order methods list by weight.
-    asort($methods_weight);
-
-    if ($load_values) {
-      $this->loadBundleValues($bundle_name, $form_state, $current_bundle, $enabled_methods, $methods_weight);
-    }
-
-    $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' => ['#tree' => TRUE],
-      '#prefix' => '<div id="edit-bundles-wrapper">',
-      '#suffix' => '</div>',
-    ];
-
-    $form['bundle'] = [
-      '#type' => 'fieldset',
-      '#title' => $this->t('Bundle'),
-      '#tree' => TRUE,
-      '#weight' => -9,
-    ];
-
-    if ($bundle_name == self::NEW_BUNDLE_SELECT_VALUE) {
-      $default_values = [
-        'bundle_select' => self::NEW_BUNDLE_SELECT_VALUE,
-        'name' => '',
-        'machine_name' => '',
-        'description' => '',
-        'is_profile' => FALSE,
-        'profile_name' => '',
-      ];
-    }
-    else {
-      $default_values = [
-        'bundle_select' => $current_bundle->getMachineName(),
-        'name' => $current_bundle->getName(),
-        'machine_name' => $current_bundle->getMachineName(),
-        'description' => $current_bundle->getDescription(),
-        'is_profile' => $current_bundle->isProfile(),
-        'profile_name' => $current_bundle->getProfileName(),
-      ];
-    }
-    $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' => [
-        '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'] = [
-        '#type' => 'button',
-        '#name' => 'removebundle',
-        '#value' => $this->t('Remove bundle'),
-      ];
-    }
-
-    $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'] = [
-        '#type' => 'value',
-        '#value' => $default_values['machine_name'],
-      ];
-    }
-    else {
-      $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' => [
-          'source' => ['bundle', 'name'],
-          'exists' => [$this, 'bundleExists'],
-        ],
-      ];
-    }
-
-    $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'] = [
-      '#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' => [
-        'data-add-profile' => 'status',
-      ],
-    ];
-
-    $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'],
-      '#description' => $this->t('The machine name (directory name) of your profile.'),
-      '#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
-    // field or manually edits it.
-    $form['#attached']['drupalSettings']['copyFieldValue']['edit-bundle-machine-name'] = ['edit-bundle-profile-name'];
-
-    foreach ($methods_weight as $method_id => $weight) {
-
-      // A packaging method might no longer be available if the defining module
-      // has been uninstalled after the last configuration saving.
-      if (!isset($assignment_info[$method_id])) {
-        continue;
-      }
-
-      $enabled = isset($enabled_methods[$method_id]);
-      $method = $assignment_info[$method_id];
-
-      $method_name = Html::escape($method['name']);
-
-      $form['weight'][$method_id] = [
-        '#type' => 'weight',
-        '#title' => $this->t('Weight for @title package assignment method', ['@title' => Unicode::strtolower($method_name)]),
-        '#title_display' => 'invisible',
-        '#default_value' => $weight,
-        '#attributes' => ['class' => ['assignment-method-weight']],
-        '#delta' => 20,
-      ];
-
-      $form['title'][$method_id] = ['#markup' => $method_name];
-
-      $form['enabled'][$method_id] = [
-        '#type' => 'checkbox',
-        '#title' => $this->t('Enable @title package assignment method', ['@title' => Unicode::strtolower($method_name)]),
-        '#title_display' => 'invisible',
-        '#default_value' => $enabled,
-      ];
-
-      $form['description'][$method_id] = ['#markup' => $method['description']];
-
-      $config_op = [];
-      if (isset($method['config_route_name'])) {
-        $config_op['configure'] = [
-          'title' => $this->t('Configure'),
-          '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] = [
-        '#type' => 'operations',
-        '#links' => $config_op,
-      ];
-    }
-
-    $form['actions'] = ['#type' => 'actions', '#weight' => 9];
-    $form['actions']['submit'] = [
-      '#type' => 'submit',
-      '#button_type' => 'primary',
-      '#value' => $this->t('Save settings'),
-    ];
-
-    return $form;
-  }
-
-  /**
-   * Ajax callback for handling switching the bundle selector.
-   */
-  public function updateForm($form, FormStateInterface $form_state) {
-    return $form;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function validateForm(array &$form, FormStateInterface $form_state) {
-    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.'));
-    }
-
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, FormStateInterface $form_state) {
-
-    $enabled_methods = array_filter($form_state->getValue('enabled'));
-    ksort($enabled_methods);
-    $method_weights = $form_state->getValue('weight');
-    ksort($method_weights);
-
-    $machine_name = $form_state->getValue(['bundle', 'machine_name']);
-
-    // If this is a new bundle, create it.
-    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(['bundle', 'machine_name']);
-      if ($old_name != $new_name) {
-        $bundle = $this->assigner->renameBundle($old_name, $new_name);
-      }
-    }
-
-    $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(['bundle', 'is_profile']));
-    $bundle->setProfileName($form_state->getValue(['bundle', 'profile_name']));
-    $bundle->save();
-    $this->assigner->setBundle($bundle);
-    $this->assigner->setCurrent($bundle);
-
-    $form_state->setRedirect('features.assignment');
-    drupal_set_message($this->t('Package assignment configuration saved.'));
-  }
-
-  /**
-   * Callback for machine_name exists()
-   * @param $value
-   * @param $element
-   * @param $form_state
-   * @return bool
-   */
-  public function bundleExists($value, $element, $form_state) {
-    $bundle = $this->assigner->getBundle($value);
-    return isset($bundle);
-  }
-
-}
diff --git a/web/modules/features/modules/features_ui/src/Form/AssignmentCoreForm.php b/web/modules/features/modules/features_ui/src/Form/AssignmentCoreForm.php
deleted file mode 100644
index 0e186b814080afddef58f2ca32559231e1244873..0000000000000000000000000000000000000000
--- a/web/modules/features/modules/features_ui/src/Form/AssignmentCoreForm.php
+++ /dev/null
@@ -1,54 +0,0 @@
-<?php
-
-namespace Drupal\features_ui\Form;
-
-use Drupal\Core\Form\FormStateInterface;
-
-/**
- * Configures the selected configuration assignment method for this site.
- */
-class AssignmentCoreForm extends AssignmentFormBase {
-
-  const METHOD_ID = 'core';
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormId() {
-    return 'features_assignment_core_form';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildForm(array $form, FormStateInterface $form_state, $bundle_name = NULL) {
-    $this->currentBundle = $this->assigner->loadBundle($bundle_name);
-    $settings = $this->currentBundle->getAssignmentSettings(self::METHOD_ID);
-
-    $this->setConfigTypeSelect($form, $settings['types']['config'], $this->t('core'));
-    $this->setActions($form, self::METHOD_ID);
-
-    return $form;
-  }
-
- /**
-   * {@inheritdoc}
-   */
-  public function validateForm(array &$form, FormStateInterface $form_state) {
-    $form_state->setValue('types', array_map('array_filter', $form_state->getValue('types')));
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, FormStateInterface $form_state) {
-    // Merge in types selections.
-    $settings = $this->currentBundle->getAssignmentSettings(self::METHOD_ID);
-    $settings['types'] = $form_state->getValue('types');
-    $this->currentBundle->setAssignmentSettings(self::METHOD_ID, $settings)->save();
-    $this->setRedirect($form_state);
-
-    drupal_set_message($this->t('Package assignment configuration saved.'));
-  }
-
-}
diff --git a/web/modules/features/modules/features_ui/src/Form/AssignmentExcludeForm.php b/web/modules/features/modules/features_ui/src/Form/AssignmentExcludeForm.php
deleted file mode 100644
index 459bf7ce839a0b1ade47145cf643767d60078f31..0000000000000000000000000000000000000000
--- a/web/modules/features/modules/features_ui/src/Form/AssignmentExcludeForm.php
+++ /dev/null
@@ -1,131 +0,0 @@
-<?php
-
-namespace Drupal\features_ui\Form;
-
-use Drupal\Core\Form\FormStateInterface;
-
-/**
- * Configures the selected configuration assignment method for this site.
- */
-class AssignmentExcludeForm extends AssignmentFormBase {
-
-  const METHOD_ID = 'exclude';
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormId() {
-    return 'features_assignment_exclude_form';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildForm(array $form, FormStateInterface $form_state, $bundle_name = NULL) {
-    $this->currentBundle = $this->assigner->loadBundle($bundle_name);
-
-    $settings = $this->currentBundle->getAssignmentSettings(self::METHOD_ID);
-    $module_settings = $settings['module'];
-    $curated_settings = $settings['curated'];
-
-    $this->setConfigTypeSelect($form, $settings['types']['config'], $this->t('exclude'), FALSE,
-      $this->t("Select types of configuration that should be excluded from packaging."));
-
-    $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'] = [
-      '#type' => 'fieldset',
-      '#tree' => TRUE,
-      '#title' => $this->t('Exclude configuration provided by modules'),
-    ];
-
-    $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' => [
-        'data-module-installed' => 'status',
-      ],
-    ];
-
-    $show_if_module_installed_checked = [
-      'visible' => [
-        ':input[data-module-installed="status"]' => ['checked' => TRUE],
-      ],
-    ];
-
-    $info = system_get_info('module', drupal_get_profile());
-    $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.", ['%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'] = [
-      '#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.", ['%namespace' => $bundle_name]),
-      '#states' => $show_if_module_installed_checked,
-      '#attributes' => [
-        'data-namespace' => 'status',
-      ],
-    ];
-
-    $show_if_namespace_checked = [
-      'visible' => [
-        ':input[data-namespace="status"]' => ['checked' => TRUE],
-        ':input[data-module-installed="status"]' => ['checked' => TRUE],
-      ],
-    ];
-
-    $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.", ['%namespace' => $bundle_name]),
-      '#states' => $show_if_namespace_checked,
-    ];
-
-    $this->setActions($form, self::METHOD_ID);
-
-    return $form;
-  }
-
- /**
-   * {@inheritdoc}
-   */
-  public function validateForm(array &$form, FormStateInterface $form_state) {
-    $form_state->setValue('types', array_map('array_filter', $form_state->getValue('types')));
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, FormStateInterface $form_state) {
-    // Merge in selections.
-    $settings = $this->currentBundle->getAssignmentSettings(self::METHOD_ID);
-    $settings = array_merge($settings, [
-      'types' => $form_state->getValue('types'),
-      'curated' => $form_state->getValue('curated'),
-      'module' => $form_state->getValue('module'),
-    ]);
-
-    $this->currentBundle->setAssignmentSettings(self::METHOD_ID, $settings)->save();
-
-    $this->setRedirect($form_state);
-    drupal_set_message($this->t('Package assignment configuration saved.'));
-  }
-
-}
diff --git a/web/modules/features/modules/features_ui/src/Form/AssignmentFormBase.php b/web/modules/features/modules/features_ui/src/Form/AssignmentFormBase.php
deleted file mode 100644
index 9b7dca927976c018f4f866bd73b7df798b764ce7..0000000000000000000000000000000000000000
--- a/web/modules/features/modules/features_ui/src/Form/AssignmentFormBase.php
+++ /dev/null
@@ -1,176 +0,0 @@
-<?php
-
-namespace Drupal\features_ui\Form;
-
-use Drupal\features\FeaturesManagerInterface;
-use Drupal\features\FeaturesAssignerInterface;
-use Drupal\Core\Entity\ContentEntityTypeInterface;
-use Drupal\Core\Entity\EntityTypeManagerInterface;
-use Drupal\Core\Form\FormBase;
-use Drupal\Core\Form\FormStateInterface;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Configures the selected configuration assignment method for this site.
- */
-abstract class AssignmentFormBase extends FormBase {
-
-  /**
-   * The features manager.
-   *
-   * @var \Drupal\features\FeaturesManagerInterface
-   */
-  protected $featuresManager;
-
-  /**
-   * The package assigner.
-   *
-   * @var \Drupal\features\FeaturesAssignerInterface
-   */
-  protected $assigner;
-
-  /**
-   * The entity type manager.
-   *
-   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
-   */
-  protected $entityTypeManager;
-
-  /**
-   * The current bundle.
-   *
-   * @var \Drupal\features\FeaturesBundleInterface
-   */
-  protected $currentBundle;
-
-  /**
-   * Constructs a AssignmentBaseForm object.
-   *
-   * @param \Drupal\features\FeaturesManagerInterface $features_manager
-   *   The features manager.
-   * @param \Drupal\features\FeaturesAssignerInterface $assigner
-   *   The assigner.
-   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
-   *   The entity type manager.
-   */
-  public function __construct(FeaturesManagerInterface $features_manager, FeaturesAssignerInterface $assigner, EntityTypeManagerInterface $entity_type_manager) {
-    $this->featuresManager = $features_manager;
-    $this->assigner = $assigner;
-    $this->entityTypeManager = $entity_type_manager;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container) {
-    return new static(
-      $container->get('features.manager'),
-      $container->get('features_assigner'),
-      $container->get('entity_type.manager')
-    );
-  }
-
-  /**
-   * Adds configuration types checkboxes.
-   */
-  protected function setConfigTypeSelect(&$form, $defaults, $type, $bundles_only = FALSE, $description = '') {
-    $options = $this->featuresManager->listConfigTypes($bundles_only);
-
-    if (!isset($form['types'])) {
-      $form['types'] = [
-        '#type' => 'container',
-        '#tree' => TRUE,
-      ];
-    }
-
-    $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.', ['@type' => $type]),
-      '#options' => $options,
-      '#default_value' => $defaults,
-    ];
-  }
-
-  /**
-   * Adds content entity types checkboxes.
-   */
-  protected function setContentTypeSelect(&$form, $defaults, $type, $exclude_has_config_bundles = TRUE) {
-    $entity_types = $this->entityTypeManager->getDefinitions();
-
-    $has_config_bundle = [];
-    foreach ($entity_types as $definition) {
-      if ($entity_type_id = $definition->getBundleOf()) {
-        $has_config_bundle[] = $entity_type_id;
-      }
-    }
-    $options = [];
-
-    foreach ($entity_types as $entity_type_id => $entity_type) {
-      if (!$entity_type instanceof ContentEntityTypeInterface) {
-        continue;
-      }
-      if ($exclude_has_config_bundles && in_array($entity_type_id, $has_config_bundle)) {
-        continue;
-      }
-      $options[$entity_type_id] = $entity_type->getLabel() ?: $entity_type_id;
-    }
-
-    // Sort the entity types by label.
-    uasort($options, 'strnatcasecmp');
-
-    if (!isset($form['types'])) {
-      $form['types'] = [
-        '#type' => 'container',
-        '#tree' => TRUE,
-      ];
-    }
-
-    $form['types']['content'] = [
-      '#type' => 'checkboxes',
-      '#title' => $this->t('Content entity types'),
-      '#description' => $this->t('Select content entity types that should be considered @type types.', ['@type' => $type]),
-      '#options' => $options,
-      '#default_value' => $defaults,
-    ];
-  }
-
-  /**
-   * Adds a "Save settings" submit action.
-   */
-  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'] = [
-        '#markup' => $method['description'],
-        '#prefix' => '<p class="messages messages--status">',
-        '#suffix' => '</p>',
-        '#weight' => -99,
-      ];
-    }
-
-    $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'] = [
-      'library' => [
-        'features_ui/drupal.features_ui.admin',
-    ]];
-  }
-
-  /**
-   * Redirects back to the Bundle config form.
-   *
-   * @param \Drupal\Core\Form\FormStateInterface $form_state
-   *   The form state.
-   */
-  protected function setRedirect(FormStateInterface $form_state) {
-    $form_state->setRedirect('features.assignment', ['bundle_name' => $this->currentBundle->getMachineName()]);
-  }
-
-}
diff --git a/web/modules/features/modules/features_ui/src/Form/AssignmentOptionalForm.php b/web/modules/features/modules/features_ui/src/Form/AssignmentOptionalForm.php
deleted file mode 100644
index 756fb5489cbc8e0e83390a5679d4a52e8435093c..0000000000000000000000000000000000000000
--- a/web/modules/features/modules/features_ui/src/Form/AssignmentOptionalForm.php
+++ /dev/null
@@ -1,54 +0,0 @@
-<?php
-
-namespace Drupal\features_ui\Form;
-
-use Drupal\Core\Form\FormStateInterface;
-
-/**
- * Configures the selected configuration assignment method for this site.
- */
-class AssignmentOptionalForm extends AssignmentFormBase {
-
-  const METHOD_ID = 'optional';
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormId() {
-    return 'features_assignment_optional_form';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildForm(array $form, FormStateInterface $form_state, $bundle_name = NULL) {
-    $this->currentBundle = $this->assigner->loadBundle($bundle_name);
-    $settings = $this->currentBundle->getAssignmentSettings(self::METHOD_ID);
-
-    $this->setConfigTypeSelect($form, $settings['types']['config'], $this->t('optional'));
-    $this->setActions($form, self::METHOD_ID);
-
-    return $form;
-  }
-
- /**
-   * {@inheritdoc}
-   */
-  public function validateForm(array &$form, FormStateInterface $form_state) {
-    $form_state->setValue('types', array_map('array_filter', $form_state->getValue('types')));
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, FormStateInterface $form_state) {
-    // Merge in types selections.
-    $settings = $this->currentBundle->getAssignmentSettings(self::METHOD_ID);
-    $settings['types'] = $form_state->getValue('types');
-    $this->currentBundle->setAssignmentSettings(self::METHOD_ID, $settings)->save();
-    $this->setRedirect($form_state);
-
-    drupal_set_message($this->t('Package assignment configuration saved.'));
-  }
-
-}
diff --git a/web/modules/features/modules/features_ui/src/Form/AssignmentProfileForm.php b/web/modules/features/modules/features_ui/src/Form/AssignmentProfileForm.php
deleted file mode 100644
index 88c86348dd181d99a76b87bae2078a5d88c845f8..0000000000000000000000000000000000000000
--- a/web/modules/features/modules/features_ui/src/Form/AssignmentProfileForm.php
+++ /dev/null
@@ -1,88 +0,0 @@
-<?php
-
-namespace Drupal\features_ui\Form;
-
-use Drupal\Core\Form\FormStateInterface;
-
-/**
- * Configures the selected configuration assignment method for this profile.
- */
-class AssignmentProfileForm extends AssignmentFormBase {
-
-  const METHOD_ID = 'profile';
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormId() {
-    return 'features_assignment_profile_form';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildForm(array $form, FormStateInterface $form_state, $bundle_name = NULL) {
-    $this->currentBundle = $this->assigner->loadBundle($bundle_name);
-    $settings = $this->currentBundle->getAssignmentSettings(self::METHOD_ID);
-
-    $this->setConfigTypeSelect($form, $settings['types']['config'], $this->t('profile'));
-
-    $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'] = [
-      '#type' => 'fieldset',
-      '#title' => $this->t('Crib from the Standard profile'),
-      '#tree' => TRUE,
-    ];
-    $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'] = [
-      '#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);
-
-    return $form;
-  }
-
- /**
-   * {@inheritdoc}
-   */
-  public function validateForm(array &$form, FormStateInterface $form_state) {
-    $form_state->setValue('types', array_map('array_filter', $form_state->getValue('types')));
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, FormStateInterface $form_state) {
-    // Merge in selections.
-    $settings = $this->currentBundle->getAssignmentSettings(self::METHOD_ID);
-
-    $settings = array_merge($settings, [
-      'curated' => $form_state->getValue('curated'),
-      'standard' => $form_state->getValue('standard'),
-      'types' => $form_state->getValue('types'),
-    ]);
-
-    $this->currentBundle->setAssignmentSettings(self::METHOD_ID, $settings)->save();
-    $this->setRedirect($form_state);
-
-    drupal_set_message($this->t('Package assignment configuration saved.'));
-  }
-
-}
diff --git a/web/modules/features/modules/features_ui/src/Form/AssignmentSiteForm.php b/web/modules/features/modules/features_ui/src/Form/AssignmentSiteForm.php
deleted file mode 100644
index 443d1f9454336a1576edede9fd37189f49111c51..0000000000000000000000000000000000000000
--- a/web/modules/features/modules/features_ui/src/Form/AssignmentSiteForm.php
+++ /dev/null
@@ -1,54 +0,0 @@
-<?php
-
-namespace Drupal\features_ui\Form;
-
-use Drupal\Core\Form\FormStateInterface;
-
-/**
- * Configures the selected configuration assignment method for this site.
- */
-class AssignmentSiteForm extends AssignmentFormBase {
-
-  const METHOD_ID = 'site';
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormId() {
-    return 'features_assignment_site_form';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildForm(array $form, FormStateInterface $form_state, $bundle_name = NULL) {
-    $this->currentBundle = $this->assigner->loadBundle($bundle_name);
-    $settings = $this->currentBundle->getAssignmentSettings(self::METHOD_ID);
-
-    $this->setConfigTypeSelect($form, $settings['types']['config'], $this->t('site'));
-    $this->setActions($form, self::METHOD_ID);
-
-    return $form;
-  }
-
- /**
-   * {@inheritdoc}
-   */
-  public function validateForm(array &$form, FormStateInterface $form_state) {
-    $form_state->setValue('types', array_map('array_filter', $form_state->getValue('types')));
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, FormStateInterface $form_state) {
-    // Merge in types selections.
-    $settings = $this->currentBundle->getAssignmentSettings(self::METHOD_ID);
-    $settings['types'] = $form_state->getValue('types');
-    $this->currentBundle->setAssignmentSettings(self::METHOD_ID, $settings)->save();
-    $this->setRedirect($form_state);
-
-    drupal_set_message($this->t('Package assignment configuration saved.'));
-  }
-
-}
diff --git a/web/modules/features/modules/features_ui/src/Form/FeaturesDiffForm.php b/web/modules/features/modules/features_ui/src/Form/FeaturesDiffForm.php
deleted file mode 100644
index b04ca241a9d511cffc86ab400eea7464afe699b9..0000000000000000000000000000000000000000
--- a/web/modules/features/modules/features_ui/src/Form/FeaturesDiffForm.php
+++ /dev/null
@@ -1,270 +0,0 @@
-<?php
-
-namespace Drupal\features_ui\Form;
-
-use Drupal\Component\Utility\Html;
-use Drupal\features\ConfigurationItem;
-use Drupal\features\FeaturesAssignerInterface;
-use Drupal\features\FeaturesManagerInterface;
-use Drupal\Core\Form\FormBase;
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\features\Package;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-use Drupal\Component\Diff\DiffFormatter;
-use Drupal\config_update\ConfigRevertInterface;
-use Drupal\config_update\ConfigDiffInterface;
-
-/**
- * Defines the features differences form.
- */
-class FeaturesDiffForm extends FormBase {
-
-  /**
-   * The features manager.
-   *
-   * @var array
-   */
-  protected $featuresManager;
-
-  /**
-   * The package assigner.
-   *
-   * @var array
-   */
-  protected $assigner;
-
-  /**
-   * The config differ.
-   *
-   * @var \Drupal\config_update\ConfigDiffInterface
-   */
-  protected $configDiff;
-
-  /**
-   * The diff formatter.
-   *
-   * @var \Drupal\Core\Diff\DiffFormatter
-   */
-  protected $diffFormatter;
-
-  /**
-   * The config reverter.
-   *
-   * @var \Drupal\config_update\ConfigRevertInterface
-   */
-  protected $configRevert;
-
-  /**
-   * Constructs a FeaturesDiffForm object.
-   *
-   * @param \Drupal\features\FeaturesManagerInterface $features_manager
-   *   The features manager.
-   */
-  public function __construct(FeaturesManagerInterface $features_manager, FeaturesAssignerInterface $assigner,
-                              ConfigDiffInterface $config_diff, DiffFormatter $diff_formatter,
-                              ConfigRevertInterface $config_revert) {
-    $this->featuresManager = $features_manager;
-    $this->assigner = $assigner;
-    $this->configDiff = $config_diff;
-    $this->diffFormatter = $diff_formatter;
-    $this->configRevert = $config_revert;
-    $this->diffFormatter->show_header = FALSE;
-    $this->diffFormatter->leading_context_lines = 0;
-    $this->diffFormatter->trailing_context_lines = 0;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container) {
-    return new static(
-      $container->get('features.manager'),
-      $container->get('features_assigner'),
-      $container->get('config_update.config_diff'),
-      $container->get('diff.formatter'),
-      $container->get('features.config_update')
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormId() {
-    return 'features_diff_form';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildForm(array $form, FormStateInterface $form_state, $featurename = '') {
-    $current_bundle = $this->assigner->applyBundle();
-    $packages = $this->featuresManager->getPackages();
-    $form = [];
-
-    $machine_name = '';
-    if (!empty($featurename) && empty($packages[$featurename])) {
-      drupal_set_message($this->t('Feature @name does not exist.', ['@name' => $featurename]), 'error');
-      return [];
-    }
-    elseif (!empty($featurename)) {
-      $machine_name = $packages[$featurename]->getMachineName();
-      $packages = [$packages[$featurename]];
-    }
-    else {
-      $packages = $this->featuresManager->filterPackages($packages, $current_bundle->getMachineName());
-    }
-
-    $header = [
-      'row' => [
-        'data' => !empty($machine_name)
-        ? $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 = [];
-    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 += [
-            $package->getMachineName() => [
-              'row' => [
-                'data' => [
-                  '#type' => 'html_tag',
-                  '#tag' => 'h2',
-                  '#value' => Html::escape($package->getName()),
-                ],
-              ],
-              '#attributes' => [
-                'class' => 'features-diff-header',
-              ],
-            ],
-          ];
-          $options += $this->diffOutput($package, $overrides, $missing);
-        }
-      }
-    }
-
-    $form['diff'] = [
-      '#type' => 'tableselect',
-      '#header' => $header,
-      '#options' => $options,
-      '#attributes' => ['class' => ['features-diff-listing']],
-      '#empty' => $this->t('No differences exist in exported features.'),
-    ];
-
-    $form['actions'] = ['#type' => 'actions', '#tree' => TRUE];
-    $form['actions']['revert'] = [
-      '#type' => 'submit',
-      '#value' => $this->t('Import changes'),
-    ];
-    $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';
-
-    return $form;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, FormStateInterface $form_state) {
-    $this->assigner->assignConfigPackages();
-    $config = $this->featuresManager->getConfigCollection();
-    $items = array_filter($form_state->getValue('diff'));
-    if (empty($items)) {
-      drupal_set_message($this->t('No configuration was selected for import.'), 'warning');
-      return;
-    }
-    foreach ($items as $config_name) {
-      if (isset($config[$config_name])) {
-        $item = $config[$config_name];
-        $type = ConfigurationItem::fromConfigStringToConfigType($item->getType());
-        $this->configRevert->revert($type, $item->getShortName());
-      }
-      else {
-        $item = $this->featuresManager->getConfigType($config_name);
-        $type = ConfigurationItem::fromConfigStringToConfigType($item['type']);
-        $this->configRevert->import($type, $item['name_short']);
-      }
-      drupal_set_message($this->t('Imported @name', ['@name' => $config_name]));
-    }
-  }
-
-  /**
-   * Returns a form element for the given overrides.
-   *
-   * @param \Drupal\features\Package $package
-   *   A package.
-   * @param array $overrides
-   *   An array of overrides.
-   * @param array $missing
-   *   An array of missing config.
-   *
-   * @return array
-   *   A form element.
-   */
-  protected function diffOutput(Package $package, $overrides, $missing = []) {
-    $element = [];
-    $config = $this->featuresManager->getConfigCollection();
-    $components = array_merge($missing, $overrides);
-
-    $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[] = [['data' => $name, 'colspan' => 4, 'header' => TRUE]];
-
-      if (!isset($config[$name])) {
-        $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 = [
-            '#markup' => $this->t('Dependency detected in active config but not exported to the feature.'),
-          ];
-        }
-        else {
-          $diff = $this->configDiff->diff($active, $extension);
-          $details = [
-            '#type' => 'table',
-            '#header' => $header,
-            '#rows' => $this->diffFormatter->format($diff),
-            '#attributes' => ['class' => ['diff', 'features-diff']],
-          ];
-        }
-      }
-      $element[$name] = [
-        'row' => [
-          'data' => [
-            '#type' => 'details',
-            '#title' => Html::escape($name),
-            '#open' => TRUE,
-            '#description' => [
-              'data' => $details,
-            ],
-          ],
-        ],
-        '#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
deleted file mode 100644
index 62808765769db24d02ebc1a3e0d8acbf4263d25f..0000000000000000000000000000000000000000
--- a/web/modules/features/modules/features_ui/src/Form/FeaturesEditForm.php
+++ /dev/null
@@ -1,1091 +0,0 @@
-<?php
-
-namespace Drupal\features_ui\Form;
-
-use Drupal\Component\Utility\Html;
-use Drupal\Component\Utility\Xss;
-use Drupal\features\FeaturesAssignerInterface;
-use Drupal\features\FeaturesGeneratorInterface;
-use Drupal\features\FeaturesManagerInterface;
-use Drupal\features\ConfigurationItem;
-use Drupal\Core\Form\FormBase;
-use Drupal\Core\Form\FormStateInterface;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-Use Drupal\Component\Render\FormattableMarkup;
-use Drupal\config_update\ConfigRevertInterface;
-
-/**
- * Defines the features settings form.
- */
-class FeaturesEditForm extends FormBase {
-
-  /**
-   * The features manager.
-   *
-   * @var array
-   */
-  protected $featuresManager;
-
-  /**
-   * The package assigner.
-   *
-   * @var array
-   */
-  protected $assigner;
-
-  /**
-   * The package generator.
-   *
-   * @var array
-   */
-  protected $generator;
-
-  /**
-   * Current package being edited.
-   *
-   * @var \Drupal\features\Package
-   */
-  protected $package;
-
-  /**
-   * Current bundle machine name.
-   *
-   * NOTE: D8 cannot serialize objects within forms so you can't directly
-   * store the entire Bundle object here.
-   *
-   * @var string
-   */
-  protected $bundle;
-
-  /**
-   * Previous bundle name for ajax processing.
-   *
-   * @var string
-   */
-  protected $oldBundle;
-
-  /**
-   * Config to be specifically excluded.
-   *
-   * @var array
-   */
-  protected $excluded;
-
-  /**
-   * Config to be specifically required.
-   *
-   * @var array
-   */
-  protected $required;
-
-  /**
-   * Config referenced by other packages.
-   *
-   * @var array
-   */
-  protected $conflicts;
-
-  /**
-   * Determine if conflicts are allowed to be added.
-   *
-   * @var bool
-   */
-  protected $allowConflicts;
-
-  /**
-   * Config missing from active site.
-   *
-   * @var array
-   */
-  protected $missing;
-
-  /**
-   * The config reverter.
-   *
-   * @var \Drupal\config_update\ConfigRevertInterface
-   */
-  protected $configRevert;
-
-  /**
-   * Constructs a FeaturesEditForm object.
-   *
-   * @param \Drupal\features\FeaturesManagerInterface $features_manager
-   *   The features manager.
-   */
-  public function __construct(FeaturesManagerInterface $features_manager, FeaturesAssignerInterface $assigner, FeaturesGeneratorInterface $generator, ConfigRevertInterface $config_revert) {
-    $this->featuresManager = $features_manager;
-    $this->assigner = $assigner;
-    $this->generator = $generator;
-    $this->configRevert = $config_revert;
-    $this->excluded = [];
-    $this->required = [];
-    $this->conflicts = [];
-    $this->missing = [];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container) {
-    return new static(
-      $container->get('features.manager'),
-      $container->get('features_assigner'),
-      $container->get('features_generator'),
-      $container->get('features.config_update')
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormId() {
-    return 'features_edit_form';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildForm(array $form, FormStateInterface $form_state, $featurename = '') {
-    $session = $this->getRequest()->getSession();
-    $trigger = $form_state->getTriggeringElement();
-    if ($trigger['#name'] == 'package') {
-      // Save current bundle name for later ajax callback.
-      $this->oldBundle = $this->bundle;
-    }
-    elseif ($trigger['#name'] == 'conflicts') {
-      if (isset($session)) {
-        $session->set('features_allow_conflicts', $form_state->getValue('conflicts'));
-      }
-    }
-    if (!$form_state->isValueEmpty('package')) {
-      $bundle_name = $form_state->getValue('package');
-      $bundle = $this->assigner->getBundle($bundle_name);
-    }
-    else {
-      $bundle = $this->assigner->loadBundle();
-    }
-    // Only store bundle name, not full object.
-    $this->bundle = $bundle->getMachineName();
-
-    $this->allowConflicts = FALSE;
-    if (isset($session)) {
-      $this->allowConflicts = $session->get('features_allow_conflicts', FALSE);
-    }
-
-    // Pass the $force argument as TRUE because we want to include any excluded
-    // configuration items. These should show up as automatically assigned, but
-    // not selected, thus allowing the admin to reselect if desired.
-    // @see FeaturesManagerInterface::assignConfigPackage()
-    $this->assigner->assignConfigPackages(TRUE);
-
-    $packages = $this->featuresManager->getPackages();
-    if (empty($packages[$featurename])) {
-      $featurename = str_replace(['-', ' '], '_', $featurename);
-      $this->package = $this->featuresManager->initPackage($featurename, NULL, '', 'module', $bundle);
-    }
-    else {
-      $this->package = $packages[$featurename];
-    }
-
-    if (!empty($packages[$featurename]) && $this->package->getBundle() !== $this->bundle && $form_state->isValueEmpty('package')) {
-      // Make sure the current bundle matches what is stored in the package.
-      // But only do this if the Package value hasn't been manually changed.
-      $bundle = $this->assigner->getBundle($this->package->getBundle());
-      if (empty($bundle)) {
-        // Create bundle if it doesn't exist yet
-        $bundle = $this->assigner->createBundleFromDefault($this->package->getBundle());
-      }
-      $this->bundle = $bundle->getMachineName();
-      $this->assigner->reset();
-      $this->assigner->assignConfigPackages(TRUE);
-      $packages = $this->featuresManager->getPackages();
-      $this->package = $packages[$featurename];
-    }
-
-    $form = [
-      '#show_operations' => FALSE,
-      '#prefix' => '<div id="features-edit-wrapper">',
-      '#suffix' => '</div>',
-    ];
-
-    $form['info'] = [
-      '#type' => 'fieldset',
-      '#title' => $this->t('General Information'),
-      '#tree' => FALSE,
-      '#weight' => 2,
-      '#prefix' => "<div id='features-export-info'>",
-      '#suffix' => '</div>',
-    ];
-
-    $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', ['@name' => $bundle->getMachineName()]);
-    }
-
-    $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' => [
-        '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.', ['@name' => $bundle->getMachineName()]);
-    }
-
-    $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'] = [
-      '#title' => $this->t('Bundle'),
-      '#type' => 'select',
-      '#options' => $this->assigner->getBundleOptions(),
-      '#default_value' => $bundle->getMachineName(),
-      '#ajax' => [
-        'callback' => '::updateBundle',
-        'wrapper' => 'features-export-info',
-      ],
-    ];
-
-    $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'] = [
-      '#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'] = [
-      '#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'] = [
-      '#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' => [
-        'callback' => '::updateForm',
-        'wrapper' => 'features-edit-wrapper',
-      ],
-    ];
-
-    $generation_info = [];
-    if (\Drupal::currentUser()->hasPermission('export configuration')) {
-      // Offer available generation methods.
-      $generation_info = $this->generator->getGenerationMethods();
-      // Sort generation methods by weight.
-      uasort($generation_info, '\Drupal\Component\Utility\SortArray::sortByWeightElement');
-    }
-
-    $form['actions'] = ['#type' => 'actions', '#tree' => TRUE];
-    foreach ($generation_info as $method_id => $method) {
-      $form['actions'][$method_id] = [
-        '#type' => 'submit',
-        '#name' => $method_id,
-        '#value' => $this->t('@name', ['@name' => $method['name']]),
-        '#attributes' => [
-          'title' => Html::escape($method['description']),
-        ],
-      ];
-    }
-
-    // Build the Component Listing panel on the right.
-    $form['export'] = $this->buildComponentList($form_state);
-
-    if (!empty($this->missing)) {
-      if ($this->allowConflicts) {
-        $form['actions']['#prefix'] = '<strong>' .
-          $this->t('WARNING: Package contains configuration missing from site.') . '<br>' .
-          $this->t('This configuration will be removed if you export it.') .
-          '</strong>';
-      }
-      else {
-        foreach ($generation_info as $method_id => $method) {
-          unset($form['actions'][$method_id]);
-        }
-        $form['actions']['#prefix'] = '<strong>' .
-          $this->t('Package contains configuration missing from site.') . '<br>' .
-          $this->t('Import the feature to create the missing config before you can export it.') . '<br>' .
-          $this->t('Or, enable the Allow Conflicts option above.') .
-          '</strong>';
-      }
-      $form['actions']['import_missing'] = [
-        '#type' => 'submit',
-        '#name' => 'import_missing',
-        '#value' => $this->t('Import Missing'),
-        '#attributes' => [
-          'title' => $this->t('Import only the missing configuration items.'),
-        ],
-      ];
-    }
-
-    $form['#attached'] = [
-      'library' => [
-        'features_ui/drupal.features_ui.admin',
-      ],
-      'drupalSettings' => [
-        'features' => [
-          'excluded' => $this->excluded,
-          'required' => $this->required,
-          'conflicts' => $this->conflicts,
-          'autodetect' => TRUE,
-        ],
-      ],
-    ];
-
-    return $form;
-  }
-
-  /**
-   * Provides an ajax callback for handling conflict checkbox.
-   */
-  public function updateForm($form, FormStateInterface $form_state) {
-    return $form;
-  }
-
-  /**
-   * Provides an ajax callback for handling switching the bundle selector.
-   */
-  public function updateBundle($form, FormStateInterface $form_state) {
-    $old_bundle = $this->assigner->getBundle($this->oldBundle);
-    $bundle_name = $form_state->getValue('package');
-    $bundle = $this->assigner->getBundle($bundle_name);
-    if (isset($bundle) && isset($old_bundle)) {
-      $short_name = $old_bundle->getShortName($this->package->getMachineName());
-      if ($bundle->isDefault()) {
-        $short_name = $old_bundle->getFullName($short_name);
-      }
-      $this->package->setMachineName($bundle->getFullName($short_name));
-      $form['info']['machine_name']['#value'] = $bundle->getShortName($this->package->getMachineName());
-    }
-    return $form['info'];
-  }
-
-  /**
-   * Callback for machine_name exists()
-   * @param $value
-   * @param $element
-   * @param $form_state
-   * @return bool
-   */
-  public function featureExists($value, $element, $form_state) {
-    $bundle = $this->assigner->getBundle($this->bundle);
-    $value = $bundle->getFullName($value);
-    $packages = $this->featuresManager->getPackages();
-    // A package may conflict only if it's been exported.
-    return (isset($packages[$value]) && ($packages[$value]->getState() !== FeaturesManagerInterface::STATUS_NO_EXPORT)) || \Drupal::moduleHandler()->moduleExists($value);
-  }
-
-  /**
-   * Returns the render array elements for the Components selection on the Edit
-   * form.
-   */
-  protected function buildComponentList(FormStateInterface $form_state) {
-    $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.'),
-      '#tree' => FALSE,
-      '#prefix' => "<div id='features-export-wrapper'>",
-      '#suffix' => '</div>',
-      '#weight' => 1,
-    ];
-
-    // Filter field used in javascript, so javascript will unhide it.
-    $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'] = [
-      '#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'] = [
-      '#type' => 'checkbox',
-      '#default_value' => FALSE,
-      '#hidden' => TRUE,
-      '#title' => $this->t('Select all'),
-      '#attributes' => [
-        'class' => ['features-checkall'],
-      ],
-    ];
-
-    $sections = ['included', 'detected', 'added'];
-    $config_types = $this->featuresManager->listConfigTypes();
-
-    // Generate the export array for the current feature and user selections.
-    $export = $this->getComponentList($form_state);
-
-    foreach ($export['components'] as $component => $component_info) {
-
-      $component_items_count = count($component_info['_features_options']['sources']);
-      $label = new FormattableMarkup('@component (<span class="component-count">@count</span>)',
-        [
-          '@component' => $config_types[$component],
-          '@count' => $component_items_count,
-        ]
-      );
-
-      $count = 0;
-      foreach ($sections as $section) {
-        $count += count($component_info['_features_options'][$section]);
-      }
-      $extra_class = ($count == 0) ? 'features-export-empty' : '';
-      $component_name = str_replace('_', '-', Html::escape($component));
-
-      if ($count + $component_items_count > 0) {
-        $element[$component] = [
-          '#markup' => '',
-          '#tree' => TRUE,
-        ];
-
-        $element[$component]['sources'] = [
-          '#type' => 'details',
-          '#title' => $label,
-          '#tree' => TRUE,
-          '#open' => FALSE,
-          '#attributes' => ['class' => ['features-export-component']],
-          '#prefix' => "<div class='features-export-parent component-$component'>",
-        ];
-        $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' => ['class' => ['component-select']],
-          '#prefix' => "<span class='component-select'>",
-          '#suffix' => '</span>',
-        ];
-
-        $element[$component]['before-list'] = [
-          '#markup' => "<div class='component-list features-export-list $extra_class'>",
-        ];
-
-        foreach ($sections as $section) {
-          $element[$component][$section] = [
-            '#type' => 'checkboxes',
-            '#options' => !empty($component_info['_features_options'][$section]) ?
-              $this->domDecodeOptions($component_info['_features_options'][$section]) : [],
-            '#default_value' => !empty($component_info['_features_selected'][$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'] = [
-          '#markup' => "</div></div>",
-        ];
-      }
-    }
-
-    $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'] = [
-      '#type' => 'fieldset',
-      '#title' => $this->t('Legend'),
-      '#tree' => FALSE,
-      '#prefix' => "<div id='features-legend'>",
-      '#suffix' => '</div>',
-    ];
-    $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;
-  }
-
-  /**
-   * Returns the full feature export array based upon user selections in
-   * form_state.
-   *
-   * @param \Drupal\Core\Form\FormStateInterface $form_state
-   *   Optional form_state information for user selections. Can be updated to
-   *   reflect new selection status.
-   *
-   * @return \Drupal\features\Package
-   *   New export array to be exported
-   *   array['components'][$component_name] = $component_info
-   *     $component_info['_features_options'][$section] is list of available options
-   *     $component_info['_features_selected'][$section] is option state TRUE/FALSE
-   *   $section = array('sources', included', 'detected', 'added')
-   *     sources - options that are available to be added to the feature
-   *     included - options that have been previously exported to the feature
-   *     detected - options that have been auto-detected
-   *     added - newly added options to the feature
-   *
-   * NOTE: This routine gets a bit complex to handle all of the different
-   * possible user checkbox selections and de-selections.
-   * Cases to test:
-   *   1a) uncheck Included item -> mark as Added but unchecked
-   *   1b) re-check unchecked Added item -> return it to Included check item
-   *   2a) check Sources item -> mark as Added and checked
-   *   2b) uncheck Added item -> return it to Sources as unchecked
-   *   3a) uncheck Included item that still exists as auto-detect -> mark as
-   *       Detected but unchecked
-   *   3b) re-check Detected item -> return it to Included and checked
-   *   4a) check Sources item should also add any auto-detect items as Detected
-   *       and checked
-   *   4b) uncheck Sources item with auto-detect and auto-detect items should
-   *       return to Sources and unchecked
-   *   5a) uncheck a Detected item -> refreshing page should keep it as
-   *       unchecked Detected
-   *   6)  when nothing changes, refresh should not change any state
-   *   7)  should never see an unchecked Included item
-   */
-  protected function getComponentList(FormStateInterface $form_state) {
-    $config = $this->featuresManager->getConfigCollection();
-
-    $package_name = $this->package->getMachineName();
-    // Auto-detect dependencies for included config.
-    $package_config = $this->package->getConfig();
-    if (!empty($this->package->getConfigOrig())) {
-      $package_config = array_unique(array_merge($package_config, $this->package->getConfigOrig()));
-    }
-    if (!empty($package_config)) {
-      $this->featuresManager->assignConfigDependents($package_config, $package_name);
-    }
-
-    $packages = $this->featuresManager->getPackages();
-    // Re-fetch the package in case config was updated with Dependents above.
-    $this->package = $packages[$package_name];
-
-    // Make a map of all config data.
-    $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)) {
-        $this->conflicts[$item->getType()][$item->getShortName()] = $item->getLabel();
-      }
-      if ($this->allowConflicts
-        || !isset($this->conflicts[$item->getType()][$item->getShortName()])
-        || ($this->package->getConfigOrig() && in_array($item_name, $this->package->getConfigOrig()))) {
-        $components[$item->getType()][$item->getShortName()] = $item->getLabel();
-      }
-    }
-
-    // Make a map of the config data already exported to the Feature.
-    $this->missing = [];
-    $exported_features_info = [];
-    foreach ($this->package->getConfigOrig() as $item_name) {
-      // Make sure the extension provided item exists in the active
-      // configuration storage.
-      if (isset($config[$item_name])) {
-        $item = $config[$item_name];
-      // Remove any conflicts if those are not being allowed.
-          // if ($this->allowConflicts || !isset($this->conflicts[$item['type']][$item['name_short']])) {
-        $exported_features_info[$item->getType()][$item->getShortName()] = $item->getLabel();
-        // }
-      }
-      else {
-        $this->missing[] = $item_name;
-      }
-    }
-    $exported_features_info['dependencies'] = $this->package->getDependencyInfo();
-
-    // Make a map of any config specifically excluded and/or required.
-    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) {
-          if (!isset($config[$item_name])) {
-            continue;
-          }
-          $item = $config[$item_name];
-          $this->{$constraint}[$item->getType()][$item->getShortName()] = $item->getLabel();
-        }
-      }
-    }
-
-    // Make a map of the config data to be exported within the Feature.
-    $new_features_info = [];
-    foreach ($this->package->getConfig() as $item_name) {
-      $item = $config[$item_name];
-      $new_features_info[$item->getType()][$item->getShortName()] = $item->getLabel();
-    }
-    $new_features_info['dependencies'] = $this->package->getDependencies();
-
-    // Assemble the combined component list.
-    $config_new = [];
-    $sections = ['sources', 'included', 'detected', 'added'];
-
-    // Generate list of config to be exported.
-    $config_count = [];
-    foreach ($components as $component => $component_info) {
-      // User-selected components take precedence.
-      $config_new[$component] = [];
-      $config_count[$component] = 0;
-      // Add selected items from Sources checkboxes.
-      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 (['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]++;
-        }
-      }
-      // Only fallback to an existing feature's values if there are no export
-      // options for the component.
-      if ($component == 'dependencies') {
-        if (($config_count[$component] == 0) && !empty($exported_features_info['dependencies'])) {
-          $config_new[$component] = array_combine($exported_features_info['dependencies'], $exported_features_info['dependencies']);
-        }
-      }
-      elseif (($config_count[$component] == 0) && !empty($exported_features_info[$component])) {
-        $config_names = array_keys($exported_features_info[$component]);
-        $config_new[$component] = array_combine($config_names, $config_names);
-      }
-    }
-
-    // Generate new populated feature.
-    $export['package'] = $this->package;
-    $export['config_new'] = $config_new;
-
-    // Now fill the $export with categorized sections of component options
-    // based upon user selections and de-selections.
-    foreach ($components as $component => $component_info) {
-      $component_export = $component_info;
-      foreach ($sections as $section) {
-        $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] : [];
-        $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([$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
-            // required because it was automatically assigned.
-            if (isset($this->excluded[$component][$key])) {
-              unset($this->excluded[$component][$key]);
-            }
-            else {
-              $this->required[$component][$key] = $key;
-            }
-          }
-          elseif (isset($new_components[$key]) || isset($config_new[$component][$key])) {
-            // Option is in the New exported array.
-            if (isset($exported_components[$key])) {
-              // Option was already previously exported so it's part of the
-              // Included checkboxes.
-              $section = 'included';
-              $default_value = $key;
-              // If Included item was un-selected (removed from export
-              // $config_new) but was re-detected in the $new_components
-              // 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([$component, 'included', $key]) ||
-                  ($form_state->isValueEmpty([$component, 'detected', $key]))) &&
-                  empty($config_new[$component][$key])) {
-                $section = 'detected';
-                $default_value = FALSE;
-              }
-              // Unless it's unchecked in the form, then move it to Newly
-              // disabled item.
-              elseif ($form_state->isSubmitted() &&
-                  $form_state->isValueEmpty([$component, 'added', $key]) &&
-                  $form_state->isValueEmpty([$component, 'detected', $key]) &&
-                  $form_state->isValueEmpty([$component, 'included', $key])) {
-                $section = 'added';
-                $default_value = FALSE;
-              }
-            }
-            else {
-              // Option was in New exported array, but NOT in already exported
-              // so it's a user-selected or an auto-detect item.
-              $section = 'detected';
-              $default_value = NULL;
-              // Check for item explicitly excluded.
-              if (isset($this->excluded[$component][$key]) && !$form_state->isSubmitted()) {
-                $default_value = FALSE;
-              }
-              else {
-                $default_value = $key;
-              }
-              // If it's already checked in Added or Sources, leave it in Added
-              // as checked.
-              if ($form_state->isSubmitted() &&
-                  (!$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([$component, 'sources', 'selected', $key]) &&
-                  $form_state->isValueEmpty([$component, 'detected', $key]) &&
-                  !$form_state->hasValue([$component, 'added', $key])) {
-                $section = 'detected';
-                $default_value = FALSE;
-              }
-            }
-            $component_export['_features_options'][$section][$key] = $this->configLabel($component, $key, $label);
-            $component_export['_features_selected'][$section][$key] = $default_value;
-            // Save which dependencies are specifically excluded from
-            // auto-detection.
-            if (($section == 'detected') && ($default_value === FALSE)) {
-              // If this was previously required, we don't need to set it as
-              // excluded because it wasn't automatically assigned.
-              if (!isset($this->required[$component][$key]) || ($this->package->getRequired() === TRUE)) {
-                $this->excluded[$component][$key] = $key;
-              }
-              unset($this->required[$component][$key]);
-              // Remove excluded item from export.
-              if ($component == 'dependencies') {
-                $export['package']->removeDependency($key);
-              }
-              else {
-                $export['package']->removeConfig($config_name);
-              }
-            }
-            else {
-              unset($this->excluded[$component][$key]);
-            }
-            // Remove the 'input' and set the 'values' so Drupal stops looking
-            // at 'input'.
-            if ($form_state->isSubmitted()) {
-              if (!$default_value) {
-                $form_state->setValue([$component, $section, $key], FALSE);
-              }
-              else {
-                $form_state->setValue([$component, $section, $key], 1);
-              }
-            }
-          }
-          elseif (!$form_state->isSubmitted() && isset($exported_components[$key])) {
-            // Component is not part of new export, but was in original export.
-            // Mark component as Added when creating initial form.
-            $component_export['_features_options']['added'][$key] = $this->configLabel($component, $key, $label);
-            $component_export['_features_selected']['added'][$key] = $key;
-          }
-          else {
-            // Option was not part of the new export.
-            $added = FALSE;
-            foreach (['included', 'added'] as $section) {
-              // Restore any user-selected checkboxes.
-              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;
-              }
-            }
-            if (!$added) {
-              // If not Included or Added, then put it back in the unchecked
-              // Sources checkboxes.
-              $component_export['_features_options']['sources'][$key] = $this->configLabel($component, $key, $label);
-              $component_export['_features_selected']['sources'][$key] = FALSE;
-            }
-          }
-        }
-      }
-      $export['components'][$component] = $component_export;
-    }
-    $export['features_exclude'] = $this->excluded;
-    $export['features_require'] = $this->required;
-    $export['conflicts'] = $this->conflicts;
-    $export['missing'] = $this->missing;
-
-    return $export;
-  }
-
-  /**
-   * Returns a formatted and sanitized label for a config item.
-   *
-   * @param string $type
-   *   The config type.
-   * @param string $key
-   *   The short machine name of the item.
-   * @param string $label
-   *   The human label for the item.
-   */
-  protected function configLabel($type, $key, $label) {
-    $value = Html::escape($label);
-    if ($key != $label) {
-      $value .= '  <span class="config-name">(' . Html::escape($key) . ')</span>';
-    }
-    if (isset($this->conflicts[$type][$key])) {
-      // Show what package the conflict is stored in.
-      $config = $this->featuresManager->getConfigCollection();
-      $config_name = $this->featuresManager->getFullName($type, $key);
-      $package_name = isset($config[$config_name]) ? $config[$config_name]->getPackage() : '';
-      // Get the full machine name instead of the short name.
-      $packages = $this->featuresManager->getPackages();
-      if (isset($packages[$package_name])) {
-        $package_name = $packages[$package_name]->getMachineName();
-      }
-      $value .= '  <span class="config-name">[' . $this->t('in') . ' ' . Html::escape($package_name) . ']</span>';
-    }
-    return Xss::filterAdmin($value);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, FormStateInterface $form_state) {
-    $bundle = $this->assigner->getBundle($this->bundle);
-    $this->assigner->assignConfigPackages();
-
-    $this->package->setName($form_state->getValue('name'));
-    $this->package->setMachineName($form_state->getValue('machine_name'));
-    $this->package->setDescription($form_state->getValue('description'));
-    $this->package->setVersion($form_state->getValue('version'));
-    $this->package->setDirectory($form_state->getValue('directory'));
-    $this->package->setBundle($bundle->getMachineName());
-    // Save it first just to create it in case it's a new package.
-    $this->featuresManager->setPackage($this->package);
-
-    $config = $this->updatePackageConfig($form_state);
-    $this->featuresManager->assignConfigPackage($this->package->getMachineName(), $config, TRUE);
-    $this->package->setExcluded($this->updateExcluded());
-    if ($form_state->getValue('require_all')) {
-      $this->package->setRequired(TRUE);
-    }
-    else {
-      $required = $this->updateRequired();
-      $this->package->setRequired($required);
-    }
-    // Now save it with the selected config data.
-    $this->featuresManager->setPackage($this->package);
-
-    $method_id = NULL;
-    $trigger = $form_state->getTriggeringElement();
-    $op = $form_state->getValue('op');
-    if (!empty($trigger) && empty($op)) {
-      $method_id = $trigger['#name'];
-    }
-
-    // Set default redirect, but allow generators to change it later.
-    $form_state->setRedirect('features.edit', ['featurename' => $this->package->getMachineName()]);
-    if ($method_id == 'import_missing') {
-      $this->importMissing();
-    }
-    elseif (!empty($method_id)) {
-      $packages = [$this->package->getMachineName()];
-      $this->generator->generatePackages($method_id, $bundle, $packages);
-      $this->generator->applyExportFormSubmit($method_id, $form, $form_state);
-    }
-
-    $this->assigner->setCurrent($bundle);
-  }
-
-  /**
-   * Updates the config stored in the package from the current edit form.
-   *
-   * @return array
-   *   Config array to be exported.
-   */
-  protected function updatePackageConfig(FormStateInterface $form_state) {
-    $config = [];
-    $components = $this->getComponentList($form_state);
-    foreach ($components['config_new'] as $config_type => $items) {
-      foreach ($items as $name) {
-        $config[] = $this->featuresManager->getFullName($config_type, $name);
-      }
-    }
-    return $config;
-  }
-
-  /**
-   * Imports the configuration missing from the active store
-   */
-  protected function importMissing() {
-    $config = $this->featuresManager->getConfigCollection();
-    $missing = $this->featuresManager->reorderMissing($this->missing);
-    foreach ($missing as $config_name) {
-      if (!isset($config[$config_name])) {
-        $item = $this->featuresManager->getConfigType($config_name);
-        $type = ConfigurationItem::fromConfigStringToConfigType($item['type']);
-        try {
-          $this->configRevert->import($type, $item['name_short']);
-          drupal_set_message($this->t('Imported @name', ['@name' => $config_name]));
-        } catch (\Exception $e) {
-          drupal_set_message($this->t('Error importing @name : @message',
-            ['@name' => $config_name, '@message' => $e->getMessage()]), 'error');
-        }
-      }
-    }
-  }
-
-  /**
-   * Updates the list of excluded config.
-   *
-   * @return array
-   *   The list of excluded config in a simple array of full config names
-   *   suitable for storing in the info.yml file.
-   */
-  protected function updateExcluded() {
-    return $this->updateConstrained('excluded');
-  }
-
-  /**
-   * Updates the list of required config.
-   *
-   * @return array
-   *   The list of required config in a simple array of full config names
-   *   suitable for storing in the info.yml file.
-   */
-  protected function updateRequired() {
-    return $this->updateConstrained('required');
-  }
-
-  /**
-   * Returns a list of constrained (excluded or required) configuration.
-   *
-   * @param string $constraint
-   *   The constraint (excluded or required).
-   * @return array
-   *   The list of constrained config in a simple array of full config names
-   *   suitable for storing in the info.yml file.
-   */
-  protected function updateConstrained($constraint) {
-    $constrained = [];
-    foreach ($this->{$constraint} as $type => $item) {
-      foreach ($item as $name => $value) {
-        $constrained[] = $this->featuresManager->getFullName($type, $name);
-      }
-    }
-    return $constrained;
-  }
-
-  /**
-   * Encodes a given key.
-   *
-   * @param string $key
-   *   The key to encode.
-   *
-   * @return string
-   *   The encoded key.
-   */
-  protected function domEncode($key) {
-    $replacements = $this->domEncodeMap();
-    return strtr($key, $replacements);
-  }
-
-  /**
-   * Decodes a given key.
-   *
-   * @param string $key
-   *   The key to decode.
-   *
-   * @return string
-   *   The decoded key.
-   */
-  protected function domDecode($key) {
-    $replacements = array_flip($this->domEncodeMap());
-    return strtr($key, $replacements);
-  }
-
-  /**
-   * Decodes an array of option values that have been encoded by
-   * features_dom_encode_options().
-   *
-   * @param array $options
-   *   The key to encode.
-   * @param bool $keys_only
-   *   Whether to decode only the keys.
-   *
-   * @return array
-   *   An array of encoded options.
-   */
-  protected function domDecodeOptions(array $options, $keys_only = FALSE) {
-    $replacements = array_flip($this->domEncodeMap());
-    $encoded = [];
-    foreach ($options as $key => $value) {
-      $encoded[strtr($key, $replacements)] = $keys_only ? $value : strtr($value, $replacements);
-    }
-    return $encoded;
-  }
-
-  /**
-   * Returns encoding map for decode and encode options.
-   *
-   * @return array
-   *   An encoding map.
-   */
-  protected function domEncodeMap() {
-    return [
-      ':' => '__' . ord(':') . '__',
-      '/' => '__' . ord('/') . '__',
-      ',' => '__' . ord(',') . '__',
-      '.' => '__' . ord('.') . '__',
-      '<' => '__' . ord('<') . '__',
-      '>' => '__' . ord('>') . '__',
-      '%' => '__' . 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
deleted file mode 100644
index bed30b10e95ef052006584821bf09e15753f4da4..0000000000000000000000000000000000000000
--- a/web/modules/features/modules/features_ui/src/Form/FeaturesExportForm.php
+++ /dev/null
@@ -1,561 +0,0 @@
-<?php
-
-namespace Drupal\features_ui\Form;
-
-use Drupal\Component\Utility\Html;
-use Drupal\Component\Utility\Xss;
-use Drupal\features\FeaturesAssignerInterface;
-use Drupal\features\FeaturesGeneratorInterface;
-use Drupal\features\FeaturesManagerInterface;
-use Drupal\features\FeaturesBundleInterface;
-use Drupal\Core\Extension\ModuleHandlerInterface;
-use Drupal\Core\Form\FormBase;
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Render\Element;
-use Drupal\features\Package;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-use Drupal\Core\Url;
-
-/**
- * Defines the configuration export form.
- */
-class FeaturesExportForm extends FormBase {
-
-  /**
-   * The features manager.
-   *
-   * @var array
-   */
-  protected $featuresManager;
-
-  /**
-   * The package assigner.
-   *
-   * @var array
-   */
-  protected $assigner;
-
-  /**
-   * The package generator.
-   *
-   * @var array
-   */
-  protected $generator;
-
-  /**
-   * The module handler service.
-   *
-   * @var \Drupal\Core\Extension\ModuleHandlerInterface
-   */
-  protected $moduleHandler;
-
-  /**
-   * Constructs a FeaturesExportForm object.
-   *
-   * @param \Drupal\features\FeaturesManagerInterface $features_manager
-   *    The features manager.
-   * @param \Drupal\features\FeaturesAssignerInterface $features_assigner
-   *    The features assigner.
-   * @param \Drupal\features\FeaturesGeneratorInterface $features_generator
-   *    The features generator.
-   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
-   *    The features generator.
-   */
-  public function __construct(FeaturesManagerInterface $features_manager, FeaturesAssignerInterface $assigner, FeaturesGeneratorInterface $generator, ModuleHandlerInterface $module_handler) {
-    $this->featuresManager = $features_manager;
-    $this->assigner = $assigner;
-    $this->generator = $generator;
-    $this->moduleHandler = $module_handler;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container) {
-    return new static(
-      $container->get('features.manager'),
-      $container->get('features_assigner'),
-      $container->get('features_generator'),
-      $container->get('module_handler')
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormId() {
-    return 'features_export_form';
-  }
-
-  /**
-   * Detects if an element triggered the form submission via Ajax.
-   * TODO: SHOULDN'T NEED THIS!  BUT DRUPAL IS CALLING buildForm AFTER THE
-   * BUNDLE AJAX IS SELECTED AND DOESN'T HAVE getTriggeringElement() SET YET.
-   */
-  protected function elementTriggeredScriptedSubmission(FormStateInterface &$form_state) {
-    $input = $form_state->getUserInput();
-    if (!empty($input['_triggering_element_name'])) {
-      return $input['_triggering_element_name'];
-    }
-    return '';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildForm(array $form, FormStateInterface $form_state) {
-
-    $trigger = $form_state->getTriggeringElement();
-    // TODO: See if there is a Drupal Core issue for this.
-    // Sometimes the first ajax call on the page causes buildForm to be called
-    // twice!  First time form_state->getTriggeringElement is NOT SET, but
-    // the form_state['input'] shows the _triggering_element_name.  Then the
-    // SECOND time it is called the getTriggeringElement is fine.
-    $real_trigger = $this->elementTriggeredScriptedSubmission($form_state);
-    if (!isset($trigger) && ($real_trigger == 'bundle')) {
-      $input = $form_state->getUserInput();
-      $bundle_name = $input['bundle'];
-      $this->assigner->setCurrent($this->assigner->getBundle($bundle_name));
-    }
-    elseif ($trigger['#name'] == 'bundle') {
-      $bundle_name = $form_state->getValue('bundle', '');
-      $this->assigner->setCurrent($this->assigner->getBundle($bundle_name));
-    }
-    else {
-      $this->assigner->loadBundle();
-    }
-    $current_bundle = $this->assigner->getBundle();
-    $this->assigner->assignConfigPackages();
-
-    $packages = $this->featuresManager->getPackages();
-    $config_collection = $this->featuresManager->getConfigCollection();
-
-    // Add in un-packaged configuration items.
-    $this->addUnpackaged($packages, $config_collection);
-
-    $packages = $this->featuresManager->filterPackages($packages, $current_bundle->getMachineName());
-
-    // Pass the packages and bundle data for use in the form pre_render
-    // callback.
-    $form['#packages'] = $packages;
-    $form['#profile_package'] = $current_bundle->getProfileName();
-    $form['header'] = [
-      '#type' => 'container',
-      '#attributes' => ['class' => 'features-header'],
-    ];
-
-    $bundle_options = $this->assigner->getBundleOptions();
-
-    // If there are no custom bundles, provide message.
-    if (count($bundle_options) < 2) {
-      drupal_set_message($this->t('You have not yet created any bundles. Before generating features, you may wish to <a href=":create">create a bundle</a> to group your features within.', [':create' => Url::fromRoute('features.assignment')->toString()]));
-    }
-
-    $form['#prefix'] = '<div id="edit-features-wrapper">';
-    $form['#suffix'] = '</div>';
-    $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' => [
-        'callback' => '::updatePreview',
-        'wrapper' => 'edit-features-preview-wrapper',
-      ],
-      '#attributes' => [
-        'data-new-package-set' => 'status',
-      ],
-    ];
-
-    $form['preview'] = $this->buildListing($packages, $current_bundle);
-
-    $form['#attached'] = [
-      'library' => [
-        'features_ui/drupal.features_ui.admin',
-      ],
-    ];
-
-    if (\Drupal::currentUser()->hasPermission('export configuration')) {
-      // Offer available generation methods.
-      $generation_info = $this->generator->getGenerationMethods();
-      // Sort generation methods by weight.
-      uasort($generation_info, '\Drupal\Component\Utility\SortArray::sortByWeightElement');
-
-      $form['description'] = [
-        '#markup' => '<p>' . $this->t('Use an export method button below to generate the selected features.') . '</p>',
-      ];
-
-      $form['actions'] = ['#type' => 'actions', '#tree' => TRUE];
-      foreach ($generation_info as $method_id => $method) {
-        $form['actions'][$method_id] = [
-          '#type' => 'submit',
-          '#name' => $method_id,
-          '#value' => $this->t('@name', ['@name' => $method['name']]),
-          '#attributes' => [
-            'title' => Html::escape($method['description']),
-          ],
-        ];
-      }
-    }
-
-    $form['#pre_render'][] = [get_class($this), 'preRenderRemoveInvalidCheckboxes'];
-
-    return $form;
-  }
-
-  /**
-   * Handles switching the configuration type selector.
-   */
-  public function updatePreview($form, FormStateInterface $form_state) {
-    // We should really be able to add this pre_render callback to the
-    // 'preview' element. However, since doing so leads to an error (no rows
-    // are displayed), we need to instead explicitly invoke it here for the
-    // processing to apply to the Ajax-rendered form element.
-    $form = $this->preRenderRemoveInvalidCheckboxes($form);
-    return $form['preview'];
-  }
-
-  /**
-   * Builds the portion of the form showing a listing of features.
-   *
-   * @param \Drupal\features\Package[] $packages
-   *   The packages.
-   * @param \Drupal\features\FeaturesBundleInterface $bundle
-   *   The current bundle
-   *
-   * @return array
-   *   A render array of a form element.
-   */
-  protected function buildListing(array $packages, FeaturesBundleInterface $bundle) {
-
-    $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 = [];
-    $first = TRUE;
-    foreach ($packages as $package) {
-      if ($first && $package->getStatus() == FeaturesManagerInterface::STATUS_NO_EXPORT) {
-        // Don't offer new non-profile packages that are empty.
-        if ($package->getStatus() === FeaturesManagerInterface::STATUS_NO_EXPORT &&
-          !$bundle->isProfilePackage($package->getMachineName()) &&
-          empty($package->getConfig())) {
-          continue;
-        }
-        $first = FALSE;
-        $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 = [
-      '#type' => 'tableselect',
-      '#header' => $header,
-      '#options' => $options,
-      '#attributes' => ['class' => ['features-listing']],
-      '#prefix' => '<div id="edit-features-preview-wrapper">',
-      '#suffix' => '</div>',
-    ];
-
-    return $element;
-  }
-
-  /**
-   * Builds the details of a package.
-   *
-   * @param \Drupal\features\Package $package
-   *   The package.
-   * @param \Drupal\features\FeaturesBundleInterface
-   *   The current bundle.
-   *
-   * @return array
-   *   A render array of a form element.
-   */
-  protected function buildPackageDetail(Package $package, FeaturesBundleInterface $bundle) {
-    $config_collection = $this->featuresManager->getConfigCollection();
-
-    $url = Url::fromRoute('features.edit', ['featurename' => $package->getMachineName()]);
-
-    $element['name'] = [
-      'data' => \Drupal::l($package->getName(), $url),
-      'class' => ['feature-name'],
-    ];
-    $machine_name = $package->getMachineName();
-    // Except for the 'unpackaged' pseudo-package, display the full name, since
-    // that's what will be generated.
-    if ($machine_name !== 'unpackaged') {
-      $machine_name = $bundle->getFullName($machine_name);
-    }
-    $element['machine_name'] = $machine_name;
-    $element['status'] = [
-      'data' => $this->featuresManager->statusLabel($package->getStatus()),
-      'class' => ['column-nowrap'],
-    ];
-    // Use 'data' instead of plain string value so a blank version doesn't
-    // remove column from table.
-    $element['version'] = [
-      'data' => Html::escape($package->getVersion()),
-      'class' => ['column-nowrap'],
-    ];
-    $overrides = $this->featuresManager->detectOverrides($package);
-    $new_config = $this->featuresManager->detectNew($package);
-    $conflicts = [];
-    $missing = [];
-    $moved = [];
-
-    if ($package->getStatus() == FeaturesManagerInterface::STATUS_NO_EXPORT) {
-      $overrides = [];
-      $new_config = [];
-    }
-    // Bundle package configuration by type.
-    $package_config = [];
-    foreach ($package->getConfig() as $item_name) {
-      if (isset($config_collection[$item_name])) {
-        $item = $config_collection[$item_name];
-        $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'][] = [
-          '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()][] = [
-            '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()][] = [
-            'name' => $this->t('Moved to @package', ['@package' => $package_name]),
-            'label' => Html::escape($item->getLabel()),
-            'class' => 'features-moved',
-          ];
-        }
-      }
-    }
-    // Add dependencies.
-    $package_config['dependencies'] = [];
-    foreach ($package->getDependencies() as $dependency) {
-      $package_config['dependencies'][] = [
-        'name' => $dependency,
-        'label' => $this->moduleHandler->moduleExists($dependency) ? $this->moduleHandler->getName($dependency) : $dependency,
-        'class' => '',
-      ];
-    }
-
-    $class = '';
-    $state_links = [];
-    if (!empty($conflicts)) {
-      $state_links[] = [
-        '#type' => 'link',
-        '#title' => $this->t('Conflicts'),
-        '#url' => Url::fromRoute('features.edit', ['featurename' => $package->getMachineName()]),
-        '#attributes' => ['class' => ['features-conflict']],
-      ];
-    }
-    if (!empty($overrides)) {
-      $state_links[] = [
-        '#type' => 'link',
-        '#title' => $this->featuresManager->stateLabel(FeaturesManagerInterface::STATE_OVERRIDDEN),
-        '#url' => Url::fromRoute('features.diff', ['featurename' => $package->getMachineName()]),
-        '#attributes' => ['class' => ['features-override']],
-      ];
-    }
-    if (!empty($new_config)) {
-      $state_links[] = [
-        '#type' => 'link',
-        '#title' => $this->t('New detected'),
-        '#url' => Url::fromRoute('features.diff', ['featurename' => $package->getMachineName()]),
-        '#attributes' => ['class' => ['features-detected']],
-      ];
-    }
-    if (!empty($missing) && ($package->getStatus() == FeaturesManagerInterface::STATUS_INSTALLED)) {
-      $state_links[] = [
-        '#type' => 'link',
-        '#title' => $this->t('Missing'),
-        '#url' => Url::fromRoute('features.edit', ['featurename' => $package->getMachineName()]),
-        '#attributes' => ['class' => ['features-missing']],
-      ];
-    }
-    if (!empty($moved)) {
-      $state_links[] = [
-        '#type' => 'link',
-        '#title' => $this->t('Moved'),
-        '#url' => Url::fromRoute('features.edit', ['featurename' => $package->getMachineName()]),
-        '#attributes' => ['class' => ['features-moved']],
-      ];
-    }
-    if (!empty($state_links)) {
-      $element['state'] = [
-        'data' => $state_links,
-        'class' => ['column-nowrap'],
-      ];
-    }
-    else {
-      $element['state'] = '';
-    }
-
-    $config_types = $this->featuresManager->listConfigTypes();
-    // Add dependencies.
-    $config_types['dependencies'] = $this->t('Dependencies');
-    $config_types['missing'] = $this->t('Missing');
-    uasort($config_types, 'strnatcasecmp');
-
-    $rows = array();
-    // Use sorted array for order.
-    foreach ($config_types as $type => $label) {
-      // For each component type, offer alternating rows.
-      $row = array();
-      if (isset($package_config[$type])) {
-        $row[] = array(
-          'data' => array(
-            '#type' => 'html_tag',
-            '#tag' => 'span',
-            '#value' => Html::escape($label),
-            '#attributes' => array(
-              'title' => Html::escape($type),
-              'class' => 'features-item-label',
-            ),
-          ),
-        );
-        $row[] = array(
-          'data' => array(
-            '#theme' => 'features_items',
-            '#items' => $package_config[$type],
-            '#value' => Html::escape($label),
-            '#title' => Html::escape($type),
-          ),
-          'class' => 'item',
-        );
-        $rows[] = $row;
-      }
-    }
-    $element['table'] = array(
-      '#type' => 'table',
-      '#rows' => $rows,
-    );
-
-    $details = array();
-    $details['description'] = array(
-      '#markup' => Xss::filterAdmin($package->getDescription()),
-    );
-    $details['table'] = array(
-      '#type' => 'details',
-      '#title' => $this->t('Included configuration'),
-      '#description' => array('data' => $element['table']),
-    );
-    $element['details'] = array(
-      'class' => array('description', 'expand'),
-      'data' => $details,
-    );
-
-    return $element;
-  }
-
-  /**
-   * Adds a pseudo-package to display unpackaged configuration.
-   *
-   * @param array $packages
-   *   An array of package names.
-   * @param \Drupal\features\ConfigurationItem[] $config_collection
-   *   A collection of configuration.
-   */
-  protected function addUnpackaged(array &$packages, array $config_collection) {
-    $packages['unpackaged'] = new Package('unpackaged', [
-      'name' => $this->t('Unpackaged'),
-      'description' => $this->t('Configuration that has not been added to any package.'),
-      'config' => [],
-      'status' => FeaturesManagerInterface::STATUS_NO_EXPORT,
-      'version' => '',
-    ]);
-    foreach ($config_collection as $item_name => $item) {
-      if (!$item->getPackage() && !$item->isExcluded() && !$item->isProviderExcluded()) {
-        $packages['unpackaged']->appendConfig($item_name);
-      }
-    }
-  }
-
-  /**
-   * Denies access to the checkboxes for uninstalled or empty packages and the
-   * "unpackaged" pseudo-package.
-   *
-   * @param array $form
-   *   The form build array to alter.
-   *
-   * @return array
-   *   The form build array.
-   */
-  public static function preRenderRemoveInvalidCheckboxes(array $form) {
-    /** @var \Drupal\features\Package $package */
-    foreach ($form['#packages'] as $package) {
-      // Remove checkboxes for packages that:
-      // - have no configuration assigned and are not the profile, or
-      // - are the "unpackaged" pseudo-package.
-      if ((empty($package->getConfig()) && !($package->getMachineName() == $form['#profile_package'])) ||
-        $package->getMachineName() == 'unpackaged') {
-        $form['preview'][$package->getMachineName()]['#access'] = FALSE;
-      }
-    }
-    return $form;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, FormStateInterface $form_state) {
-    $current_bundle = $this->assigner->loadBundle();
-    $this->assigner->assignConfigPackages();
-
-    $package_names = array_filter($form_state->getValue('preview'));
-
-    if (empty($package_names)) {
-      drupal_set_message($this->t('Please select one or more packages to export.'), 'warning');
-      return;
-    }
-
-    $method_id = NULL;
-    $trigger = $form_state->getTriggeringElement();
-    $op = $form_state->getValue('op');
-    if (!empty($trigger) && empty($op)) {
-      $method_id = $trigger['#name'];
-    }
-
-    if (!empty($method_id)) {
-      $this->generator->generatePackages($method_id, $current_bundle, $package_names);
-      $this->generator->applyExportFormSubmit($method_id, $form, $form_state);
-    }
-  }
-
-}
diff --git a/web/modules/features/modules/features_ui/src/Tests/FeaturesBundleUITest.php b/web/modules/features/modules/features_ui/src/Tests/FeaturesBundleUITest.php
deleted file mode 100644
index 091c55e22f39e7c2f87082b8d7ef6cef2b7b6e13..0000000000000000000000000000000000000000
--- a/web/modules/features/modules/features_ui/src/Tests/FeaturesBundleUITest.php
+++ /dev/null
@@ -1,188 +0,0 @@
-<?php
-
-namespace Drupal\features_ui\Tests;
-
-use Drupal\Core\Entity\EntityStorageInterface;
-use Drupal\features\FeaturesBundleInterface;
-use Drupal\simpletest\WebTestBase;
-use Drupal\Core\StringTranslation\StringTranslationTrait;
-
-/**
- * Tests configuring bundles.
- *
- * @group features_ui
- */
-class FeaturesBundleUITest extends WebTestBase {
-  use StringTranslationTrait;
-
-  /**
-   * @todo Remove the disabled strict config schema checking.
-   */
-  protected $strictConfigSchema = FALSE;
-
-  /**
-   * {@inheritdoc}
-   */
-  public static $modules = ['block', 'features', 'features_ui'];
-
-  /**
-   * The features bundle storage.
-   *
-   * @var \Drupal\Core\Entity\EntityStorageInterface $bundleStorage
-   */
-  protected $bundleStorage;
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setUp() {
-    parent::setUp();
-    $this->bundleStorage = \Drupal::entityTypeManager()->getStorage('features_bundle');
-
-    $admin_user = $this->createUser(['administer site configuration', 'export configuration', 'administer modules']);
-    $this->drupalLogin($admin_user);
-    $this->drupalPlaceBlock('local_actions_block');
-  }
-
-  /**
-   * Get the default features bundle.
-   *
-   * @return \Drupal\features\FeaturesBundleInterface
-   *   The features bundle.
-   */
-  protected function defaultBundle() {
-    return $this->bundleStorage->load(FeaturesBundleInterface::DEFAULT_BUNDLE);
-  }
-
-  /**
-   * Completely remove a features assignment method from the bundle.
-   *
-   * @param string $method_id
-   *   The assignment method ID.
-   */
-  protected function removeAssignment($method_id) {
-    $bundle = $this->defaultBundle();
-    $assignments = $bundle->get('assignments');
-    unset($assignments[$method_id]);
-    $bundle->set('assignments', $assignments);
-    $bundle->save();
-  }
-
-  /**
-   * Tests configuring an assignment.
-   */
-  public function testAssignmentConfigure() {
-    // Check initial values.
-    $settings = $this->defaultBundle()->getAssignmentSettings('exclude');
-    $this->assertTrue(isset($settings['types']['config']['features_bundle']), 'Excluding features_bundle');
-    $this->assertFalse(isset($settings['types']['config']['system_simple']), 'Not excluding system_simple');
-    $this->assertFalse(isset($settings['types']['config']['user_role']), 'Not excluding user_role');
-    $this->assertTrue($settings['curated'], 'Excluding curated items');
-    $this->assertTrue($settings['module']['namespace'], 'Excluding by namespace');
-
-    // Check initial form.
-    $this->drupalGet('admin/config/development/features/bundle/_exclude/default');
-    $this->assertFieldChecked('edit-types-config-features-bundle', 'features_bundle is checked');
-    $this->assertNoFieldChecked('edit-types-config-system-simple', 'system_simple is not checked');
-    $this->assertNoFieldChecked('edit-types-config-user-role', 'user_role is not checked');
-    $this->assertFieldChecked('edit-curated', 'curated is checked');
-    $this->assertFieldChecked('edit-module-namespace', 'namespace is checked');
-
-    // Configure the form.
-    $this->drupalPostForm(NULL, [
-      'types[config][system_simple]' => TRUE,
-      'types[config][user_role]' => FALSE,
-      'curated' => TRUE,
-      'module[namespace]' => FALSE,
-    ], $this->t('Save settings'));
-
-    // Check form results.
-    $this->drupalGet('admin/config/development/features/bundle/_exclude/default');
-    $this->assertFieldChecked('edit-types-config-features-bundle', 'Saved, features_bundle is checked');
-    $this->assertFieldChecked('edit-types-config-system-simple', 'Saved, system_simple is checked');
-    $this->assertNoFieldChecked('edit-types-config-user-role', 'Saved, user_role is not checked');
-    $this->assertFieldChecked('edit-curated', 'Saved, curated is checked');
-    $this->assertNoFieldChecked('edit-module-namespace', 'Saved, namespace is not checked');
-
-    // Check final values.
-    $settings = $this->defaultBundle()->getAssignmentSettings('exclude');
-    $this->assertTrue(isset($settings['types']['config']['features_bundle']), 'Saved, excluding features_bundle');
-    $this->assertTrue(isset($settings['types']['config']['system_simple']), 'Saved, excluding system_simple');
-    $this->assertFalse(isset($settings['types']['config']['user_role']), 'Saved, not excluding user_role');
-    $this->assertTrue($settings['curated'], 'Saved, excluding curated items');
-    $this->assertFalse($settings['module']['namespace'], 'Saved, not excluding by namespace');
-  }
-
-  /**
-   * Tests configuring an assignment that didn't exist before.
-   */
-  public function testNewAssignmentConfigure() {
-    $this->removeAssignment('exclude');
-
-    // Is it really removed?
-    $all_settings = $this->defaultBundle()->getAssignmentSettings();
-    $this->assertFalse(isset($all_settings['exclude']), 'Exclude plugin is unknown');
-
-    // Can still get settings.
-    $settings = $this->defaultBundle()->getAssignmentSettings('exclude');
-    $this->assertFalse($settings['enabled'], 'Disabled exclude plugin');
-    $this->assertFalse(isset($settings['types']['config']['features_bundle']), 'Not excluding features_bundle');
-    $this->assertFalse(isset($settings['types']['config']['system_simple']), 'Not excluding system_simple');
-    $this->assertFalse(isset($settings['types']['config']['user_role']), 'Not excluding user_role');
-    $this->assertFalse($settings['curated'], 'Not excluding curated items');
-    $this->assertFalse($settings['module']['namespace'], 'Not excluding by namespace');
-
-    // Can we visit the config page with no settings?
-    $this->drupalGet('admin/config/development/features/bundle/_exclude/default');
-    $this->assertNoFieldChecked('edit-types-config-features-bundle', 'features_bundle is not checked');
-    $this->assertNoFieldChecked('edit-types-config-system-simple', 'system_simple is not checked');
-    $this->assertNoFieldChecked('edit-types-config-user-role', 'user_role is not checked');
-    $this->assertNoFieldChecked('edit-curated', 'curated is not checked');
-    $this->assertNoFieldChecked('edit-module-namespace', 'namespace is not checked');
-
-    // Can we enable the method?
-    $this->drupalGet('admin/config/development/features/bundle');
-    $this->assertNoFieldChecked('edit-enabled-exclude', 'Exclude disabled');
-    $this->drupalPostForm(NULL, [
-      'enabled[exclude]' => TRUE,
-    ], $this->t('Save settings'));
-    $this->assertFieldChecked('edit-enabled-exclude', 'Exclude enabled');
-
-    // Check new settings.
-    $settings = $this->defaultBundle()->getAssignmentSettings('exclude');
-    $this->assertTrue($settings['enabled'], 'Enabled exclude plugin');
-    $this->assertFalse(isset($settings['types']['config']['features_bundle']), 'Not excluding features_bundle');
-    $this->assertFalse(isset($settings['types']['config']['system_simple']), 'Not excluding system_simple');
-    $this->assertFalse(isset($settings['types']['config']['user_role']), 'Not excluding user_role');
-    $this->assertFalse($settings['curated'], 'Not excluding curated items');
-    $this->assertFalse($settings['module']['namespace'], 'Not excluding by namespace');
-
-    // Can we run assignment with no settings?
-    $this->drupalGet('admin/config/development/features');
-
-    // Can we configure the method?
-    $this->drupalPostForm('admin/config/development/features/bundle/_exclude/default', [
-      'types[config][system_simple]' => TRUE,
-      'types[config][user_role]' => FALSE,
-      'curated' => TRUE,
-      'module[namespace]' => FALSE,
-    ], $this->t('Save settings'));
-
-    // Check form results.
-    $this->drupalGet('admin/config/development/features/bundle/_exclude/default');
-    $this->assertNoFieldChecked('edit-types-config-features-bundle', 'Saved, features_bundle is not checked');
-    $this->assertFieldChecked('edit-types-config-system-simple', 'Saved, system_simple is checked');
-    $this->assertNoFieldChecked('edit-types-config-user-role', 'Saved, user_role is not checked');
-    $this->assertFieldChecked('edit-curated', 'Saved, curated is checked');
-    $this->assertNoFieldChecked('edit-module-namespace', 'Saved, namespace is not checked');
-
-    // Check final values.
-    $settings = $this->defaultBundle()->getAssignmentSettings('exclude');
-    $this->assertFalse(isset($settings['types']['config']['features_bundle']), 'Saved, not excluding features_bundle');
-    $this->assertTrue(isset($settings['types']['config']['system_simple']), 'Saved, excluding system_simple');
-    $this->assertFalse(isset($settings['types']['config']['user_role']), 'Saved, not excluding user_role');
-    $this->assertTrue($settings['curated'], 'Saved, excluding curated items');
-    $this->assertFalse($settings['module']['namespace'], 'Saved, not excluding by namespace');
-  }
-
-}
diff --git a/web/modules/features/modules/features_ui/src/Tests/FeaturesCreateUITest.php b/web/modules/features/modules/features_ui/src/Tests/FeaturesCreateUITest.php
deleted file mode 100644
index 70c1da4d39caa3ba43cbefa0af0c6cd26bd057ee..0000000000000000000000000000000000000000
--- a/web/modules/features/modules/features_ui/src/Tests/FeaturesCreateUITest.php
+++ /dev/null
@@ -1,184 +0,0 @@
-<?php
-
-namespace Drupal\features_ui\Tests;
-
-use Drupal\Component\Serialization\Yaml;
-use Drupal\Core\Archiver\ArchiveTar;
-use Drupal\simpletest\WebTestBase;
-use Drupal\Core\StringTranslation\StringTranslationTrait;
-
-/**
- * Tests the creation of a feature.
- *
- * @group features_ui
- */
-class FeaturesCreateUITest extends WebTestBase {
-  use StringTranslationTrait;
-
-  /**
-   * @todo Remove the disabled strict config schema checking.
-   */
-  protected $strictConfigSchema = FALSE;
-
-  /**
-   * {@inheritdoc}
-   */
-  public static $modules = ['block', 'features', 'features_ui'];
-
-  /**
-   * Tests creating a feature via UI and download it.
-   */
-  public function testCreateFeaturesUI() {
-    list($major, $minor, ) = explode('.', \Drupal::VERSION);
-    // In D8.3 the module category was removed from the module name field.
-    $name_prefix = (intval($major) == 8 && intval($minor) > 2) ? 'modules[' : 'modules[Other][';
-
-    $feature_name = 'test_feature2';
-    $admin_user = $this->createUser(['administer site configuration', 'export configuration', 'administer modules']);
-    $this->drupalLogin($admin_user);
-    $this->drupalPlaceBlock('local_actions_block');
-    $this->drupalGet('admin/config/development/features');
-    $this->clickLink('Create new feature');
-    $this->assertResponse(200);
-
-    $edit = [
-      'name' => 'Test feature',
-      'machine_name' => $feature_name,
-      'description' => 'Test description: <strong>giraffe</strong>',
-      'version' => '8.x-1.0',
-      'system_simple[sources][selected][system.theme]' => TRUE,
-      'system_simple[sources][selected][user.settings]' => TRUE,
-    ];
-    $this->drupalPostForm(NULL, $edit, $this->t('Download Archive'));
-
-    $this->assertResponse(200);
-    $archive = $this->getRawContent();
-    $filename = tempnam($this->tempFilesDirectory, 'feature');
-    file_put_contents($filename, $archive);
-
-    $archive = new ArchiveTar($filename);
-    $files = $archive->listContent();
-
-    $this->assertEqual(4, count($files));
-    $this->assertEqual($feature_name . '/' . $feature_name . '.info.yml', $files[0]['filename']);
-    $this->assertEqual($feature_name . '/' . $feature_name . '.features.yml', $files[1]['filename']);
-    $this->assertEqual($feature_name . '/config/install/system.theme.yml', $files[2]['filename']);
-    $this->assertEqual($feature_name . '/config/install/user.settings.yml', $files[3]['filename']);
-
-    // Ensure that the archive contains the expected values.
-    $info_filename = tempnam($this->tempFilesDirectory, 'feature');
-    file_put_contents($info_filename, $archive->extractInString($feature_name . '/' . $feature_name . '.info.yml'));
-    $features_info_filename = tempnam($this->tempFilesDirectory, 'feature');
-    file_put_contents($features_info_filename, $archive->extractInString($feature_name . '/' . $feature_name . '.features.yml'));
-    /** @var \Drupal\Core\Extension\InfoParser $info_parser */
-    $info_parser = \Drupal::service('info_parser');
-    $parsed_info = $info_parser->parse($info_filename);
-    $this->assertEqual('Test feature', $parsed_info['name']);
-    $parsed_features_info = Yaml::decode(file_get_contents($features_info_filename));
-    $this->assertEqual([
-      'required' => ['system.theme', 'user.settings'],
-    ], $parsed_features_info);
-
-    $archive->extract(\Drupal::service('kernel')->getSitePath() . '/modules');
-    $module_path = \Drupal::service('kernel')->getSitePath() . '/modules/' . $feature_name;
-
-    // Ensure that the features listing renders the right content.
-    $this->drupalGet('admin/config/development/features');
-    $tr = $this->xpath('//table[contains(@class, "features-listing")]/tbody/tr[td[3] = "' . $feature_name . '"]')[0];
-    $this->assertLink('Test feature');
-    $this->assertEqual($feature_name, (string) $tr->children()[2]);
-    $description_column = (string) $tr->children()[3]->asXml();
-    $this->assertTrue(strpos($description_column, 'system.theme') !== FALSE);
-    $this->assertTrue(strpos($description_column, 'user.settings') !== FALSE);
-    $this->assertRaw('Test description: <strong>giraffe</strong>');
-    $this->assertEqual('Uninstalled', (string) $tr->children()[5]);
-    $this->assertEqual('', (string) $tr->children()[6]);
-
-    // Remove one and add new configuration.
-    $this->clickLink('Test feature');
-    $edit = [
-      'system_simple[included][system.theme]' => FALSE,
-      'user_role[sources][selected][authenticated]' => TRUE,
-    ];
-    $this->drupalPostForm(NULL, $edit, $this->t('Write'));
-    $info_filename = $module_path . '/' . $feature_name . '.info.yml';
-
-    $parsed_info = $info_parser->parse($info_filename);
-    $this->assertEqual('Test feature', $parsed_info['name']);
-
-    $features_info_filename = $module_path . '/' . $feature_name . '.features.yml';
-    $parsed_features_info = Yaml::decode(file_get_contents($features_info_filename));
-    $this->assertEqual([
-      'excluded' => ['system.theme'],
-      'required' => true,
-    ], $parsed_features_info);
-
-    $this->drupalGet('admin/modules');
-    $edit = [
-      $name_prefix . $feature_name . '][enable]' => TRUE,
-    ];
-    $this->drupalPostForm(NULL, $edit, $this->t('Install'));
-
-    // Check that the feature is listed as installed.
-    $this->drupalGet('admin/config/development/features');
-
-    $tr = $this->xpath('//table[contains(@class, "features-listing")]/tbody/tr[td[3] = "' . $feature_name . '"]')[0];
-    $this->assertEqual('Installed', (string) $tr->children()[5]);
-
-    // Check that a config change results in a feature marked as changed.
-    \Drupal::configFactory()->getEditable('user.settings')
-      ->set('anonymous', 'Anonymous giraffe')
-      ->save();
-
-    $this->drupalGet('admin/config/development/features');
-
-    $tr = $this->xpath('//table[contains(@class, "features-listing")]/tbody/tr[td[3] = "' . $feature_name . '"]')[0];
-    $this->assertTrue(strpos($tr->children()[6]->asXml(), 'Changed') !== FALSE);
-
-    // Uninstall module.
-    $this->drupalPostForm('admin/modules/uninstall', [
-      'uninstall[' . $feature_name . ']' => TRUE,
-    ], $this->t('Uninstall'));
-    $this->drupalPostForm(NULL, [], $this->t('Uninstall'));
-
-    $this->drupalGet('admin/config/development/features');
-
-    $tr = $this->xpath('//table[contains(@class, "features-listing")]/tbody/tr[td[3] = "' . $feature_name . '"]')[0];
-    $this->assertTrue(strpos($tr->children()[6]->asXml(), 'Changed') !== FALSE);
-
-    $this->clickLink($this->t('Changed'));
-    $this->drupalGet('admin/config/development/features/diff/' . $feature_name);
-    $this->assertRaw('<td class="diff-context diff-deletedline">anonymous : Anonymous <span class="diffchange">giraffe</span></td>');
-    $this->assertRaw('<td class="diff-context diff-addedline">anonymous : Anonymous</td>');
-
-    $this->drupalGet('admin/modules');
-    $edit = [
-      $name_prefix . $feature_name . '][enable]' => TRUE,
-    ];
-    $this->drupalPostForm(NULL, $edit, $this->t('Install'));
-    $this->drupalGet('admin/config/development/features');
-    $tr = $this->xpath('//table[contains(@class, "features-listing")]/tbody/tr[td[3] = "' . $feature_name . '"]')[0];
-    $this->assertEqual('Installed', (string) $tr->children()[5]);
-
-    // Ensure that the changed config got overridden.
-    $this->assertEqual('Anonymous', \Drupal::config('user.settings')->get('anonymous'));
-
-    // Change the value, export and ensure that its not shown as changed.
-    \Drupal::configFactory()->getEditable('user.settings')
-      ->set('anonymous', 'Anonymous giraffe')
-      ->save();
-
-    // Ensure that exporting this change will result in an unchanged feature.
-    $this->drupalGet('admin/config/development/features');
-    $tr = $this->xpath('//table[contains(@class, "features-listing")]/tbody/tr[td[3] = "' . $feature_name . '"]')[0];
-    $this->assertTrue(strpos($tr->children()[6]->asXml(), 'Changed') !== FALSE);
-
-    $this->clickLink('Test feature');
-    $this->drupalPostForm(NULL, [], $this->t('Write'));
-
-    $this->drupalGet('admin/config/development/features');
-    $tr = $this->xpath('//table[contains(@class, "features-listing")]/tbody/tr[td[3] = "' . $feature_name . '"]')[0];
-    $this->assertEqual('Installed', (string) $tr->children()[5]);
-  }
-
-}
diff --git a/web/modules/features/modules/features_ui/src/Tests/FeaturesUITest.php b/web/modules/features/modules/features_ui/src/Tests/FeaturesUITest.php
deleted file mode 100644
index 12f92ae5be9b5c5b31037bdce8a5ee26e2c2d39f..0000000000000000000000000000000000000000
--- a/web/modules/features/modules/features_ui/src/Tests/FeaturesUITest.php
+++ /dev/null
@@ -1,49 +0,0 @@
-<?php
-
-namespace Drupal\features_ui\Tests;
-
-use Drupal\simpletest\WebTestBase;
-use Drupal\Core\StringTranslation\StringTranslationTrait;
-
-/**
- * Tests the creation of a feature.
- *
- * @group features_ui
- */
-class FeaturesUITest extends WebTestBase {
-  use StringTranslationTrait;
-
-  /**
-   * @todo Remove the disabled strict config schema checking.
-   */
-  protected $strictConfigSchema = FALSE;
-
-  /**
-   * {@inheritdoc}
-   */
-  public static $modules = ['features', 'features_ui'];
-
-  /**
-   * Tests creating a feature via UI and download it.
-   */
-  public function testFeaturesUI() {
-    $admin_user = $this->drupalCreateUser(['administer site configuration', 'export configuration', 'administer modules']);
-    $this->drupalLogin($admin_user);
-    $this->drupalGet('admin/config/development/features');
-    // Check the message is displaying if there are no custom bundles.
-    $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, ['bundle[bundle_select]' => 'new'], 'bundle[bundle_select]');
-    $edit = [
-      'bundle[name]' => 'foo',
-      'bundle[machine_name]' => 'foo',
-      'bundle[description]' => $this->randomString(),
-    ];
-    $this->drupalPostForm(NULL, $edit, $this->t('Save settings'));
-    $this->drupalGet('admin/config/development/features');
-    // Check the message is not displaying if there are custom bundles.
-    $this->assertNoText($this->t('You have not yet created any bundles. Before generating features, you may wish to create a bundle to group your features within.'));
-  }
-
-}
diff --git a/web/modules/features/src/Commands/FeaturesCommands.php b/web/modules/features/src/Commands/FeaturesCommands.php
deleted file mode 100644
index a0dec38e30d46f31d88d9c0a65f73b5d8e2cb2fb..0000000000000000000000000000000000000000
--- a/web/modules/features/src/Commands/FeaturesCommands.php
+++ /dev/null
@@ -1,1053 +0,0 @@
-<?php
-
-namespace Drupal\features\Commands;
-
-use Consolidation\OutputFormatters\StructuredData\RowsOfFields;
-use Drupal\Component\Diff\DiffFormatter;
-use Drupal\config_update\ConfigDiffInterface;
-use Drupal\Core\Config\StorageInterface;
-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;
-use Drush\Commands\DrushCommands;
-use Drush\Exceptions\UserAbortException;
-use Drush\Utils\StringUtils;
-
-/**
- * Drush commands for Features.
- */
-class FeaturesCommands extends DrushCommands {
-
-  const OPTIONS =[
-    'bundle' => NULL,
-  ];
-
-  const OPTIONS_ADD = self::OPTIONS;
-
-  const OPTIONS_COMPONENTS = self::OPTIONS + [
-    'exported' => NULL,
-    'format' => 'table',
-    'not-exported' => NULL,
-  ];
-
-  const OPTIONS_DIFF = self::OPTIONS + [
-    'ctypes' => NULL,
-    'lines' => NULL,
-  ];
-
-  const OPTIONS_EXPORT = self::OPTIONS + [
-    'add-profile' => NULL,
-  ];
-
-  const OPTIONS_IMPORT = self::OPTIONS + [
-    'force' => NULL,
-  ];
-
-  const OPTIONS_IMPORT_ALL = self::OPTIONS;
-
-  const OPTIONS_LIST = self::OPTIONS + [
-    'format' => 'table',
-  ];
-
-  const OPTIONS_STATUS = self::OPTIONS;
-
-  /**
-   * The features_assigner service.
-   *
-   * @var \Drupal\features\FeaturesAssignerInterface
-   */
-  protected $assigner;
-
-  /**
-   * The features.manager service.
-   *
-   * @var \Drupal\features\FeaturesManagerInterface
-   */
-  protected $manager;
-
-  /**
-   * The features_generator service.
-   *
-   * @var \Drupal\features\FeaturesGeneratorInterface
-   */
-  protected $generator;
-
-  /**
-   * The config_update.config_diff service.
-   *
-   * @var \Drupal\config_update\ConfigDiffInterface
-   */
-  protected $configDiff;
-
-  /**
-   * The config.storage service.
-   *
-   * @var \Drupal\Core\Config\StorageInterface
-   */
-  protected $configStorage;
-
-  /**
-   * FeaturesCommands constructor.
-   *
-   * @param \Drupal\features\FeaturesAssignerInterface $assigner
-   *   The features_assigner service.
-   * @param \Drupal\features\FeaturesManagerInterface $manager
-   *   The features.manager service.
-   * @param \Drupal\features\FeaturesGeneratorInterface $generator
-   *   The features_generator service.
-   * @param \Drupal\config_update\ConfigDiffInterface $configDiff
-   *   The config_update.config_diff service.
-   * @param \Drupal\Core\Config\StorageInterface $configStorage
-   *   The config.storage service.
-   */
-  public function __construct(
-    FeaturesAssignerInterface $assigner,
-    FeaturesManagerInterface $manager,
-    FeaturesGeneratorInterface $generator,
-    ConfigDiffInterface $configDiff,
-    StorageInterface $configStorage
-  ) {
-    parent::__construct();
-    $this->assigner = $assigner;
-    $this->configDiff = $configDiff;
-    $this->configStorage = $configStorage;
-    $this->generator = $generator;
-    $this->manager = $manager;
-  }
-
-  /**
-   * Applies global options for Features drush commands, including the bundle.
-   *
-   * The option --name="bundle_name" sets the bundle namespace.
-   *
-   * @return \Drupal\features\FeaturesAssignerInterface
-   *   The features.assigner with options applied.
-   */
-  protected function featuresOptions(array $options) {
-    $bundleName = $this->getOption($options, 'bundle');
-    if (!empty($bundleName)) {
-      $bundle = $this->assigner->applyBundle($bundleName);
-      if ($bundle->getMachineName() !== $bundleName) {
-        $this->logger()->warning('Bundle {name} not found. Using default.', [
-          'name' => $bundleName,
-        ]);
-      }
-    }
-    else {
-      $this->assigner->assignConfigPackages();
-    }
-    return $this->assigner;
-  }
-
-  /**
-   * Get the value of an option.
-   *
-   * @param array $options
-   *   The options array.
-   * @param string $name
-   *   The option name.
-   * @param mixed $default
-   *   The default value of the option.
-   *
-   * @return mixed|null
-   *   The option value, defaulting to NULL.
-   */
-  protected function getOption(array $options, $name, $default = NULL) {
-    return isset($options[$name])
-      ? $options[$name]
-      : $default;
-  }
-
-  /**
-   * Display current Features settings.
-   *
-   * @param string $keys
-   *   A possibly empty, comma-separated, list of config information to display.
-   *
-   * @command features:status
-   *
-   * @option bundle Use a specific bundle namespace.
-   *
-   * @aliases fs,features-status
-   */
-  public function status($keys = NULL, array $options = self::OPTIONS_STATUS) {
-    $this->featuresOptions($options);
-
-    $currentBundle = $this->assigner->getBundle();
-    $export_settings = $this->manager->getExportSettings();
-    $methods = $this->assigner->getEnabledAssigners();
-    $output = $this->output();
-    if ($currentBundle->isDefault()) {
-      $output->writeln(dt('Current bundle: none'));
-    }
-    else {
-      $output->writeln(dt('Current bundle: @name (@machine_name)', [
-        '@name' => $currentBundle->getName(),
-        '@machine_name' => $currentBundle->getMachineName(),
-      ]));
-    }
-    $output->writeln(dt('Export folder: @folder', [
-      '@folder' => $export_settings['folder'],
-    ]));
-    $output
-      ->writeln(dt('The following assignment methods are enabled:'));
-    $output->writeln(dt('  @methods', [
-      '@methods' => implode(', ', array_keys($methods)),
-    ]));
-
-    if (!empty($keys)) {
-      $config = $this->manager->getConfigCollection();
-      $keys = StringUtils::csvToArray($keys);
-      $data = count($keys) > 1
-        ? array_keys($config)
-        : $config[$keys[0]];
-      $output->writeln(print_r($data, TRUE));
-    }
-  }
-
-  /**
-   * Display a list of all generate-able existing features and packages.
-   *
-   * If a package name is provided as an argument, then all of the configuration
-   * objects assigned to that package will be listed.
-   *
-   * @param string $package_name
-   *   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.
-   *
-   * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields|bool
-   *   The command output, or FALSE if a requested package was not found.
-   *
-   * @command features:list:packages
-   *
-   * @option bundle Use a specific bundle namespace.
-   *
-   * @usage drush features:list:packages
-   *   Display a list of all existing features and packages available to be
-   *   generated.
-   * @usage drush features:list:packages 'example_article'
-   *   Display a list of all configuration objects assigned to the
-   *   'example_article' package.
-   *
-   * @field-labels
-   *   config: Config
-   *   name: Name
-   *   machine_name: Machine name
-   *   status: Status
-   *   version: Version
-   *   state: State
-   *
-   * @aliases fl,features-list-packages
-   */
-  public function listPackages($package_name = NULL, $options = self::OPTIONS_LIST) {
-    $assigner = $this->featuresOptions($options);
-    $current_bundle = $assigner->getBundle();
-    $namespace = $current_bundle->isDefault() ? FeaturesBundleInterface::DEFAULT_BUNDLE : $current_bundle->getMachineName();
-
-    $manager = $this->manager;
-    $packages = $manager->getPackages();
-
-    $packages = $manager->filterPackages($packages, $namespace);
-    $result = [];
-
-    // If no package was specified, list all packages.
-    if (empty($package_name)) {
-      foreach ($packages as $package) {
-        $overrides = $manager->detectOverrides($package);
-        $state = $package->getState();
-        if (!empty($overrides) && ($package->getStatus() != FeaturesManagerInterface::STATUS_NO_EXPORT)) {
-          $state = FeaturesManagerInterface::STATE_OVERRIDDEN;
-        }
-
-        $packageState = ($state != FeaturesManagerInterface::STATE_DEFAULT)
-          ? $manager->stateLabel($state)
-          : '';
-
-        $result[$package->getMachineName()] = [
-          'name' => $package->getName(),
-          'machine_name' => $package->getMachineName(),
-          'status' => $manager->statusLabel($package->getStatus()),
-          'version' => $package->getVersion(),
-          'state' => $packageState,
-        ];
-      }
-      return new RowsOfFields($result);
-    }
-
-    // A valid package was listed.
-    $package = $this->manager->findPackage($package_name);
-
-    // If no matching package found, return an error.
-    if (empty($package)) {
-      $this->logger()->warning(dt('Package "@package" not found.', [
-        '@package' => $package_name,
-      ]));
-      return FALSE;
-    }
-
-    // This is a valid package, list its configuration.
-    $config = array_map(function ($name) {
-      return ['config' => $name];
-    }, $package->getConfig());
-
-    return new RowsOfFields($config);
-  }
-
-  /**
-   * Import module config from all installed features.
-   *
-   * @command features:import:all
-   *
-   * @option bundle Use a specific bundle namespace.
-   *
-   * @usage drush features-import-all
-   *   Import module config from all installed features.
-   *
-   * @aliases fra,fia,fim-all,features-import-all
-   */
-  public function importAll($options = self::OPTIONS_IMPORT_ALL) {
-    $assigner = $this->featuresOptions($options);
-    $currentBundle = $assigner->getBundle();
-    $namespace = $currentBundle->isDefault() ? FeaturesBundleInterface::DEFAULT_BUNDLE : $currentBundle->getMachineName();
-
-    $manager = $this->manager;
-    $packages = $manager->getPackages();
-    $packages = $manager->filterPackages($packages, $namespace);
-    $overridden = [];
-
-    foreach ($packages as $package) {
-      $overrides = $manager->detectOverrides($package);
-      $missing = $manager->detectMissing($package);
-      if ((!empty($missing) || !empty($overrides)) && ($package->getStatus() == FeaturesManagerInterface::STATUS_INSTALLED)) {
-        $overridden[] = $package->getMachineName();
-      }
-    }
-
-    if (!empty($overridden)) {
-      $this->import($overridden);
-    }
-    else {
-      $this->logger->info(dt('Current state already matches active config, aborting.'));
-    }
-  }
-
-  /**
-   * Export the configuration on your site into a custom module.
-   *
-   * @param array $packages
-   *   A list of features to export.
-   *
-   * @command features:export
-   *
-   * @option add-profile Package features into an install profile.
-   * @option bundle Use a specific bundle namespace.
-   *
-   * @usage drush features-export
-   *   Export all available packages.
-   * @usage drush features-export example_article example_page
-   *   Export the example_article and example_page packages.
-   * @usage drush features-export --add-profile
-   *   Export all available packages and add them to an install profile.
-   *
-   * @aliases fex,fu,fua,fu-all,features-export
-   *
-   * @throws \Drupal\features\Exception\DomainException
-   * @throws \Drupal\features\Exception\InvalidArgumentException
-   * @throws \Drush\Exceptions\UserAbortException
-   * @throws \Exception
-   */
-  public function export(array $packages, $options = self::OPTIONS_EXPORT) {
-    $assigner = $this->featuresOptions($options);
-    $manager = $this->manager;
-    $generator = $this->generator;
-
-    $current_bundle = $assigner->getBundle();
-
-    if ($options['add-profile']) {
-      if ($current_bundle->isDefault) {
-        throw new InvalidArgumentException(dt("Must specify a profile name with --name"));
-      }
-      $current_bundle->setIsProfile(TRUE);
-    }
-
-    $all_packages = $manager->getPackages();
-    foreach ($packages as $name) {
-      if (!isset($all_packages[$name])) {
-        throw new DomainException(dt("The package @name does not exist.", [
-          '@name' => $name,
-        ]));
-      }
-    }
-
-    if (empty($packages)) {
-      $packages = $all_packages;
-      $dt_args = ['@modules' => implode(', ', array_keys($packages))];
-      drush_print(dt('The following extensions will be exported: @modules',
-        $dt_args));
-      if (!$this->io()->confirm('Do you really want to continue?')) {
-        throw new UserAbortException();
-      }
-    }
-    else {
-      $packages = array_combine($packages, $packages);
-    }
-
-    // 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.",
-          ['@name' => $name, '@directory' => $directory]));
-      }
-      // Apparently, format_plural is not always available.
-      if (count($existing_packages) == 1) {
-        $message = dt('Would you like to overwrite it?');
-      }
-      else {
-        $message = dt('Would you like to overwrite them?');
-      }
-      if (!$this->io()->confirm($message)) {
-        throw new UserAbortException();
-      }
-    }
-
-    // Use the write generation method.
-    $method_id = FeaturesGenerationWrite::METHOD_ID;
-    $result = $generator->generatePackages($method_id, $current_bundle, array_keys($packages));
-
-    foreach ($result as $message) {
-      $method = $message['success'] ? 'success' : 'error';
-      $this->logger()->$method(dt($message['message'], $message['variables']));
-    }
-  }
-
-  /**
-   * Add a config item to a feature package.
-   *
-   * @param array|null $components
-   *   Patterns of config to add, see features:components for the format to use.
-   *
-   * @command features:add
-   *
-   * @todo @param $feature Feature package to export and add config to.
-   *
-   * @option bundle Use a specific bundle namespace.
-   *
-   * @aliases fa,fe,features-add
-   *
-   * @throws \Drush\Exceptions\UserAbortException
-   * @throws \Exception
-   */
-  public function add($components = NULL, $options = self::OPTIONS_ADD) {
-    if ($components) {
-      $assigner = $this->featuresOptions($options);
-      $manager = $this->manager;
-      $generator = $this->generator;
-
-      $current_bundle = $assigner->getBundle();
-
-      $module = array_shift($args);
-      if (empty($args)) {
-        throw new \Exception('No components supplied.');
-      }
-      $components = $this->componentList();
-      $options = [
-        'exported' => FALSE,
-      ];
-
-      $filtered_components = $this->componentFilter($components, $args,
-        $options);
-      $items = $filtered_components['components'];
-
-      if (empty($items)) {
-        throw new \Exception('No components to add.');
-      }
-
-      $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.",
-            ['@name' => $name, '@directory' => $directory]));
-        }
-        // Apparently, format_plural is not always available.
-        if (count($existing_packages) == 1) {
-          $message = dt('Would you like to overwrite it?');
-        }
-        else {
-          $message = dt('Would you like to overwrite them?');
-        }
-        if (!$this->io()->confirm($message)) {
-          throw new UserAbortException();
-        }
-      }
-      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',
-          ['@name' => $full_name, '@directory' => $path]));
-        if (!$this->io()->confirm(dt('Do you really want to continue?'))) {
-          throw new UserAbortException();
-        }
-      }
-
-      $config = $this->buildConfig($items);
-
-      $manager->assignConfigPackage($module, $config);
-
-      // Use the write generation method.
-      $method_id = FeaturesGenerationWrite::METHOD_ID;
-      $result = $generator->generatePackages($method_id, $current_bundle,
-        $packages);
-
-      foreach ($result as $message) {
-        $method = $message['success'] ? 'success' : 'error';
-        $this->logger()->$method(dt($message['message'],
-          $message['variables']));
-      }
-    }
-    else {
-      throw new \Exception('No feature name given.');
-    }
-  }
-
-  /**
-   * List features components.
-   *
-   * @param array $patterns
-   *   The components types to list. Omit this argument to list them all.
-   *
-   * @command features:components
-   *
-   * @option exported Show only components that have been exported.
-   * @option not-exported Show only components that have not been exported.
-   * @option bundle Use a specific bundle namespace.
-   *
-   * @aliases fc,features-components
-   *
-   * @field-labels
-   *  source: Available sources
-   *
-   * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields|null
-   *   The command output. May be empty.
-   */
-  public function components(array $patterns, $options = self::OPTIONS_COMPONENTS) {
-    $args = $patterns;
-    $this->featuresOptions($options);
-
-    $components = $this->componentList();
-    ksort($components);
-    // If no args supplied, prompt with a list.
-    if (empty($args)) {
-      $types = array_keys($components);
-      array_unshift($types, 'all');
-      $choice = $this->io()
-        ->choice('Enter a number to choose which component type to list.', $types);
-      if ($choice === FALSE) {
-        return NULL;
-      }
-
-      $args = ($choice == 0) ? ['*'] : [$types[$choice]];
-    }
-    $options = [
-      'provided by' => TRUE,
-    ];
-    if ($options['exported']) {
-      $options['not exported'] = FALSE;
-    }
-    elseif ($options['not-exported']) {
-      $options['exported'] = FALSE;
-    }
-
-    $filtered_components = $this->componentFilter($components, $args, $options);
-    if ($filtered_components) {
-      return $this->componentPrint($filtered_components);
-    }
-  }
-
-  /**
-   * Show the difference between active|default config from a feature package.
-   *
-   * @param string $feature
-   *   The feature in question.
-   *
-   * @command features:diff
-   *
-   * @option ctypes Comma-separated list of component types to limit the output
-   *   to. Defaults to all types.
-   * @option lines Generate diffs with <n> lines of context instead of the
-   *   usual two.
-   * @option bundle Use a specific bundle namespace.
-   *
-   * @aliases fd,features-diff
-   *
-   * @throws \Exception
-   */
-  public function diff($feature, $options = self::OPTIONS_DIFF) {
-    $manager = $this->manager;
-    $assigner = $this->featuresOptions($options);
-    $assigner->assignConfigPackages();
-
-    $module = $feature;
-
-    // @FIXME Actually do something with the "ctypes" option.
-    $filter_ctypes = $options['ctypes'];
-    if ($filter_ctypes) {
-      $filter_ctypes = explode(',', $filter_ctypes);
-    }
-
-    $feature = $manager->loadPackage($module, TRUE);
-    if (empty($feature)) {
-      throw new DomainException(dt('No such feature is available: @module', [
-        '@module' => $module,
-      ]));
-    }
-
-    $lines = $options['lines'];
-    $lines = isset($lines) ? $lines : 2;
-
-    $formatter = new DiffFormatter();
-    $formatter->leading_context_lines = $lines;
-    $formatter->trailing_context_lines = $lines;
-    $formatter->show_header = FALSE;
-
-    if (drush_get_context('DRUSH_NOCOLOR')) {
-      $red = $green = "%s";
-    }
-    else {
-      $red = "\033[31;40m\033[1m%s\033[0m";
-      $green = "\033[0;32;40m\033[1m%s\033[0m";
-    }
-
-    $overrides = $manager->detectOverrides($feature);
-    $missing = $manager->reorderMissing($manager->detectMissing($feature));
-    $overrides = array_merge($overrides, $missing);
-
-    $output = $this->output();
-
-    if (empty($overrides)) {
-      $output->writeln(dt('Active config matches stored config for @module.', [
-        '@module' => $module,
-      ]));
-    }
-    else {
-      $config_diff = $this->configDiff;
-
-      // Print key for colors.
-      $output->writeln(dt('Legend: '));
-      $output->writeln(sprintf($red,
-        dt('Code:   drush features-import will replace the active config with the displayed code.')));
-      $output->writeln(sprintf($green,
-        dt('Active: drush features-export will update the exported feature with the displayed active config')));
-
-      foreach ($overrides as $name) {
-        $message = '';
-        if (in_array($name, $missing)) {
-          $extension = [];
-          $message = sprintf($red, dt('(missing from active)'));
-        }
-        else {
-          $active = $manager->getActiveStorage()->read($name);
-          $extension = $manager->getExtensionStorages()->read($name);
-          if (empty($extension)) {
-            $extension = [];
-            $message = sprintf($green, dt('(not exported)'));
-          }
-          $diff = $config_diff->diff($extension, $active);
-          $rows = explode("\n", $formatter->format($diff));
-        }
-
-        $output->writeln('');
-        $output->writeln(dt("Config @name @message", [
-          '@name' => $name,
-          '@message' => $message,
-        ]));
-
-        if (!empty($extension)) {
-          foreach ($rows as $row) {
-            if (strpos($row, '>') === 0) {
-              $output->writeln(sprintf($green, $row));
-            }
-            elseif (strpos($row, '<') === 0) {
-              $output->writeln(sprintf($red, $row));
-            }
-            else {
-              $output->writeln($row);
-            }
-          }
-        }
-      }
-    }
-  }
-
-  /**
-   * Import a module config into your site.
-   *
-   * @param string $feature
-   *   A comma-delimited list of features or feature:component pairs to import.
-   *
-   * @command features:import
-   *
-   * @option force Force import even if config is not overridden.
-   * @option bundle Use a specific bundle namespace.
-   *
-   * @usage 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 fim,fr,features-import
-   *
-   * @throws \Exception
-   */
-  public function import($feature, $options = self::OPTIONS_IMPORT) {
-    $this->featuresOptions($options);
-
-    $features = StringUtils::csvToArray($feature);
-    if (empty($features)) {
-      drush_invoke_process('@self', 'features:list:packages', [], $options);
-      return;
-    }
-
-    // Determine if revert should be forced.
-    $force = $this->getOption($options, 'force');
-
-    // Determine if -y was supplied. If so, we can filter out needless output
-    // from this command.
-    $skip_confirmation = drush_get_context('DRUSH_AFFIRMATIVE');
-    $manager = $this->manager;
-
-    // Parse list of arguments.
-    $modules = [];
-    foreach ($features as $featureString) {
-      list($module, $component) = explode(':', $featureString);
-
-      // We cannot use just a component name without its module.
-      if (empty($module)) {
-        continue;
-      }
-
-      // We received just a feature name, meaning we need all of its components.
-      if (empty($component)) {
-        $modules[$module] = TRUE;
-        continue;
-      }
-
-      if (empty($modules[$module])) {
-        $modules[$module] = [];
-      }
-
-      if ($modules[$module] !== TRUE) {
-        $modules[$module][] = $component;
-      }
-    }
-
-    // Process modules.
-    foreach ($modules as $module => $componentsNeeded) {
-      // Reset the arguments on each loop pass.
-      $dt_args = ['@module' => $module];
-
-      /** @var \Drupal\features\Package $feature */
-      $feature = $manager->loadPackage($module, TRUE);
-      if (empty($feature)) {
-        throw new DomainException(dt('No such feature is available: @module', $dt_args));
-      }
-
-      if ($feature->getStatus() != FeaturesManagerInterface::STATUS_INSTALLED) {
-        throw new DomainException(dt('No such feature is installed: @module', $dt_args));
-      }
-
-      // Forcefully revert all components of a feature.
-      if ($force) {
-        $components = $feature->getConfigOrig();
-      }
-      // Only revert components that are detected to be Overridden.
-      else {
-        $overrides = $manager->detectOverrides($feature);
-        $missing = $manager->reorderMissing($manager->detectMissing($feature));
-
-        // Be sure to import missing components first.
-        $components = array_merge($missing, $overrides);
-      }
-
-      if (!empty($componentsNeeded) && is_array($componentsNeeded)) {
-        $components = array_intersect($components, $componentsNeeded);
-      }
-
-      if (empty($components)) {
-        $this->logger()->info(dt('Current state already matches active config, aborting.'));
-        continue;
-      }
-
-      // Determine which config the user wants to import/revert.
-      $configToCreate = [];
-      foreach ($components as $component) {
-        $dt_args['@component'] = $component;
-        $confirmation_message = 'Do you really want to import @module : @component?';
-        if ($skip_confirmation || $this->io()->confirm(dt($confirmation_message, $dt_args))) {
-          $configToCreate[$component] = '';
-        }
-      }
-
-      // Perform the import/revert.
-      $importedConfig = $manager->createConfiguration($configToCreate);
-
-      // List the results.
-      foreach ($components as $component) {
-        $dt_args['@component'] = $component;
-        if (isset($importedConfig['new'][$component])) {
-          $this->logger()->info(dt('Imported @module : @component.', $dt_args));
-        }
-        elseif (isset($importedConfig['updated'][$component])) {
-          $this->logger()->info(dt('Reverted @module : @component.', $dt_args));
-        }
-        elseif (!isset($configToCreate[$component])) {
-          $this->logger()->info(dt('Skipping @module : @component.', $dt_args));
-        }
-        else {
-          $this->logger()->error(dt('Error importing @module : @component.', $dt_args));
-        }
-      }
-    }
-  }
-
-  /**
-   * Returns an array of full config names given a array[$type][$component].
-   *
-   * @param array $items
-   *   The items to return data for.
-   *
-   * @return array
-   *   An array of config items.
-   */
-  protected function buildConfig(array $items) {
-    $result = [];
-    foreach ($items as $config_type => $item) {
-      foreach ($item as $item_name => $title) {
-        $result[] = $this->manager->getFullName($config_type, $item_name);
-      }
-    }
-    return $result;
-  }
-
-  /**
-   * Returns a listing of all known components, indexed by source.
-   */
-  protected function componentList() {
-    $result = [];
-    $config = $this->manager->getConfigCollection();
-    foreach ($config as $item) {
-      $result[$item->getType()][$item->getShortName()] = $item->getLabel();
-    }
-    return $result;
-  }
-
-  /**
-   * Filters components by patterns.
-   */
-  protected function componentFilter($all_components, $patterns = [], $options = []) {
-    $options += [
-      'exported' => TRUE,
-      'not exported' => TRUE,
-      'provided by' => FALSE,
-    ];
-    $pool = [];
-    // Maps exported components to feature modules.
-    $components_map = $this->componentMap();
-    // First filter on exported state.
-    foreach ($all_components as $source => $components) {
-      foreach ($components as $name => $title) {
-        $exported = count($components_map[$source][$name]) > 0;
-        if ($exported) {
-          if ($options['exported']) {
-            $pool[$source][$name] = $title;
-          }
-        }
-        else {
-          if ($options['not exported']) {
-            $pool[$source][$name] = $title;
-          }
-        }
-      }
-    }
-
-    $state_string = '';
-
-    if (!$options['exported']) {
-      $state_string = 'unexported';
-    }
-    elseif (!$options['not exported']) {
-      $state_string = 'exported';
-    }
-
-    $selected = [];
-    foreach ($patterns as $pattern) {
-      // Rewrite * to %. Let users use both as wildcard.
-      $pattern = strtr($pattern, ['*' => '%']);
-      $sources = [];
-      list($source_pattern, $component_pattern) = explode(':', $pattern, 2);
-      // If source is empty, use a pattern.
-      if ($source_pattern == '') {
-        $source_pattern = '%';
-      }
-      if ($component_pattern == '') {
-        $component_pattern = '%';
-      }
-
-      $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.
-      if (strpos($source_pattern, '%') !== FALSE) {
-        $preg_source_pattern = '^' . $preg_source_pattern . '$';
-      }
-      if (strpos($component_pattern, '%') !== FALSE) {
-        $preg_component_pattern = '^' . $preg_component_pattern . '$';
-      }
-      $matches = [];
-
-      // Find the sources.
-      $all_sources = array_keys($pool);
-      $matches = preg_grep('/' . $preg_source_pattern . '/', $all_sources);
-      if (count($matches) > 0) {
-        // If we have multiple matches and the source string wasn't a
-        // pattern, check if one of the matches is equal to the pattern, and
-        // use that, or error out.
-        if (count($matches) > 1 and $preg_source_pattern[0] != '^') {
-          if (in_array($source_pattern, $matches)) {
-            $matches = [$source_pattern];
-          }
-          else {
-            throw new \Exception(dt('Ambiguous source "@source", matches @matches',
-              [
-                '@source' => $source_pattern,
-                '@matches' => implode(', ', $matches),
-              ]));
-          }
-        }
-        // Loose the indexes preg_grep preserved.
-        $sources = array_values($matches);
-      }
-      else {
-        throw new \Exception(dt('No @state sources match "@source"',
-          ['@state' => $state_string, '@source' => $source_pattern]));
-      }
-
-      // Now find the components.
-      foreach ($sources as $source) {
-        // Find the components.
-        $all_components = array_keys($pool[$source]);
-        // See if there's any matches.
-        $matches = preg_grep('/' . $preg_component_pattern . '/',
-          $all_components);
-        if (count($matches) > 0) {
-          // If we have multiple matches and the components string wasn't a
-          // pattern, check if one of the matches is equal to the pattern, and
-          // use that, or error out.
-          if (count($matches) > 1 and $preg_component_pattern[0] != '^') {
-            if (in_array($component_pattern, $matches)) {
-              $matches = [$component_pattern];
-            }
-            else {
-              throw new \Exception(dt('Ambiguous component "@component", matches @matches',
-                [
-                  '@component' => $component_pattern,
-                  '@matches' => implode(', ', $matches),
-                ]));
-            }
-          }
-          if (!is_array($selected[$source])) {
-            $selected[$source] = [];
-          }
-          $selected[$source] += array_intersect_key($pool[$source],
-            array_flip($matches));
-        }
-        else {
-          // No matches. If the source was a pattern, just carry on, else
-          // error out. Allows for patterns like ":*field*".
-          if ($preg_source_pattern[0] != '^') {
-            throw new \Exception(dt('No @state @source components match "@component"',
-              [
-                '@state' => $state_string,
-                '@component' => $component_pattern,
-                '@source' => $source,
-              ]));
-          }
-        }
-      }
-    }
-
-    // Lastly, provide feature module information on the selected components, if
-    // requested.
-    $provided_by = [];
-    if ($options['provided by'] && $options['exported']) {
-      foreach ($selected as $source => $components) {
-        foreach ($components as $name => $title) {
-          $exported = count($components_map[$source][$name]) > 0;
-          if ($exported) {
-            $provided_by[$source . ':' . $name] = implode(', ',
-              $components_map[$source][$name]);
-          }
-        }
-      }
-    }
-
-    return [
-      'components' => $selected,
-      'sources' => $provided_by,
-    ];
-  }
-
-  /**
-   * Provides a component to feature map (port of features_get_component_map).
-   */
-  protected function componentMap() {
-    $result = [];
-    $manager = $this->manager;
-    // Recalc full config list without running assignments.
-    $config = $manager->getConfigCollection();
-    $packages = $manager->getPackages();
-
-    foreach ($config as $item) {
-      $type = $item->getType();
-      $short_name = $item->getShortName();
-      if (!isset($result[$type][$short_name])) {
-        $result[$type][$short_name] = [];
-      }
-      if (!empty($item->getPackage())) {
-        $package = $packages[$item->getPackage()];
-        $result[$type][$short_name][] = $package->getMachineName();
-      }
-    }
-
-    return $result;
-  }
-
-  /**
-   * Prints a list of filtered components.
-   */
-  protected function componentPrint($filtered_components) {
-    $rows = [];
-    foreach ($filtered_components['components'] as $source => $components) {
-      foreach ($components as $name => $value) {
-        $row = ['source' => $source . ':' . $name];
-        if (isset($filtered_components['sources'][$source . ':' . $name])) {
-          $row['source'] = dt('Provided by') . ': ' . $filtered_components['sources'][$source . ':' . $name];
-        }
-        $rows[] = $row;
-      }
-    }
-
-    return new RowsOfFields($rows);
-  }
-
-}
diff --git a/web/modules/features/src/ConfigurationItem.php b/web/modules/features/src/ConfigurationItem.php
deleted file mode 100644
index 52e39586131278a8debb773a875dcfc043482734..0000000000000000000000000000000000000000
--- a/web/modules/features/src/ConfigurationItem.php
+++ /dev/null
@@ -1,351 +0,0 @@
-<?php
-
-namespace Drupal\features;
-
-/**
- * Contains some configuration together with metadata like the name + package.
- *
- * @todo Should the object be immutable?
- * @todo Should this object have an interface?
- */
-class ConfigurationItem {
-
-  /**
-   * Prefixed configuration item name.
-   *
-   * @var string
-   */
-  protected $name;
-
-  /**
-   * Configuration item name without prefix.
-   *
-   * @var string
-   */
-  protected $shortName;
-
-  /**
-   * Human readable name of configuration item.
-   *
-   * @var string
-   */
-  protected $label;
-
-  /**
-   * Type of configuration.
-   *
-   * @var string
-   */
-  protected $type;
-
-  /**
-   * The contents of the configuration item in exported format.
-   *
-   * @var array
-   */
-  protected $data;
-
-  /**
-   * Array of names of dependent configuration items.
-   *
-   * @var string[]
-   */
-  protected $dependents = [];
-
-  /**
-   * Feature subdirectory to export item to.
-   *
-   * @var string
-   */
-  protected $subdirectory;
-
-  /**
-   * Machine name of a package the configuration is assigned to.
-   *
-   * @var string
-   */
-  protected $package;
-
-  /**
-   * Whether the configuration is marked as excluded.
-   *
-   * @var bool
-   */
-  protected $excluded = FALSE;
-
-  /**
-   * Whether the configuration provider is excluded.
-   *
-   * @var bool
-   */
-  protected $providerExcluded = FALSE;
-
-  /**
-   * The provider of the config item.
-   *
-   * @var string
-   */
-  protected $provider;
-
-  /**
-   * Array of package names that this item should be excluded from.
-   *
-   * @var string[]
-   */
-  protected $packageExcluded = [];
-
-  /**
-   * Creates a new ConfigurationItem instance.
-   *
-   * @param string $name
-   *   The config name.
-   * @param array $data
-   *   The config data.
-   * @param array $additional_properties
-   *   (optional) Additional properties set on the object.
-   */
-  public function __construct($name, array $data, array $additional_properties = []) {
-    $this->name = $name;
-    $this->data = $data;
-
-    $properties = get_object_vars($this);
-    foreach ($additional_properties as $property => $value) {
-      if (!array_key_exists($property, $properties)) {
-        throw new \InvalidArgumentException('Invalid property: ' . $property);
-      }
-      $this->{$property} = $value;
-    }
-  }
-
-  /**
-   * Calculates the config type usable in configuration.
-   *
-   * By default Drupal uses system.simple as config type, which cannot be used
-   * inside configuration itself. Therefore convert it to system_simple.
-   *
-   * @param string $type
-   *   The config type provided by core.
-   *
-   * @return string
-   *   The config type as string without dots.
-   */
-  public static function fromConfigTypeToConfigString($type) {
-    return $type == 'system.simple' ? FeaturesManagerInterface::SYSTEM_SIMPLE_CONFIG : $type;
-  }
-
-  /**
-   * Converts a config type string in configuration back to the config type.
-   *
-   * @param string $type
-   *   The config type as string without dots.
-   *
-   * @return string
-   *   The config type provided by core.
-   */
-  public static function fromConfigStringToConfigType($type) {
-    return $type == FeaturesManagerInterface::SYSTEM_SIMPLE_CONFIG ? 'system.simple' : $type;
-  }
-
-  /**
-   * @return mixed
-   */
-  public function getName() {
-    return $this->name;
-  }
-
-  /**
-   * @param mixed $name
-   *
-   * @return ConfigurationItem
-   */
-  public function setName($name) {
-    $this->name = $name;
-    return $this;
-  }
-
-  /**
-   * @return mixed
-   */
-  public function getShortName() {
-    return $this->shortName;
-  }
-
-  /**
-   * @param mixed $shortName
-   *
-   * @return ConfigurationItem
-   */
-  public function setShortName($shortName) {
-    $this->shortName = $shortName;
-    return $this;
-  }
-
-  /**
-   * @return mixed
-   */
-  public function getLabel() {
-    return $this->label;
-  }
-
-  /**
-   * @param mixed $label
-   *
-   * @return ConfigurationItem
-   */
-  public function setLabel($label) {
-    $this->label = $label;
-    return $this;
-  }
-
-  /**
-   * @return mixed
-   */
-  public function getType() {
-    return $this->type;
-  }
-
-  /**
-   * @param mixed $type
-   *
-   * @return ConfigurationItem
-   */
-  public function setType($type) {
-    $this->type = $type;
-    return $this;
-  }
-
-  /**
-   * @return mixed
-   */
-  public function getData() {
-    return $this->data;
-  }
-
-  /**
-   * @param mixed array
-   *
-   * @return ConfigurationItem
-   */
-  public function setData(array $data) {
-    $this->data = $data;
-    return $this;
-  }
-
-  /**
-   * @return string[]
-   */
-  public function getDependents() {
-    return $this->dependents;
-  }
-
-  /**
-   * @param array $dependents
-   *
-   * @return ConfigurationItem
-   */
-  public function setDependents($dependents) {
-    $this->dependents = $dependents;
-    return $this;
-  }
-
-  /**
-   * @return mixed
-   */
-  public function getSubdirectory() {
-    return $this->subdirectory;
-  }
-
-  /**
-   * @param mixed $subdirectory
-   *
-   * @return ConfigurationItem
-   */
-  public function setSubdirectory($subdirectory) {
-    $this->subdirectory = $subdirectory;
-    return $this;
-  }
-
-  /**
-   * @return mixed
-   */
-  public function getPackage() {
-    return $this->package;
-  }
-
-  /**
-   * @param mixed $package
-   *
-   * @return ConfigurationItem
-   */
-  public function setPackage($package) {
-    $this->package = $package;
-    return $this;
-  }
-
-  /**
-   * @return boolean
-   */
-  public function isExcluded() {
-    return $this->excluded;
-  }
-
-  /**
-   * @param boolean $excluded
-   *
-   * @return ConfigurationItem
-   */
-  public function setExcluded($excluded) {
-    $this->excluded = $excluded;
-    return $this;
-  }
-
-  /**
-   * @return boolean
-   */
-  public function isProviderExcluded() {
-    return $this->providerExcluded;
-  }
-
-  /**
-   * @param boolean $providerExcluded
-   *
-   * @return ConfigurationItem
-   */
-  public function setProviderExcluded($providerExcluded) {
-    $this->providerExcluded = $providerExcluded;
-    return $this;
-  }
-
-  /**
-   * @return string
-   */
-  public function getProvider() {
-    return $this->provider;
-  }
-
-  /**
-   * @param string $provider
-   */
-  public function setProvider($provider) {
-    $this->provider = $provider;
-    return $this;
-  }
-
-  /**
-   * @return string[]
-   */
-  public function getPackageExcluded() {
-    return $this->packageExcluded;
-  }
-
-  /**
-   * @param array $packageExcluded
-   *
-   * @return ConfigurationItem
-   */
-  public function setPackageExcluded($packageExcluded) {
-    $this->packageExcluded = $packageExcluded;
-    return $this;
-  }
-
-}
diff --git a/web/modules/features/src/Controller/FeaturesController.php b/web/modules/features/src/Controller/FeaturesController.php
deleted file mode 100644
index e456577e316d9b5f7a3c21e776c4d6501bc31cb9..0000000000000000000000000000000000000000
--- a/web/modules/features/src/Controller/FeaturesController.php
+++ /dev/null
@@ -1,77 +0,0 @@
-<?php
-
-namespace Drupal\features\Controller;
-
-use Drupal\Core\Access\CsrfTokenGenerator;
-use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
-use Drupal\system\FileDownloadController;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-use Symfony\Component\HttpFoundation\Request;
-use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
-
-/**
- * Returns responses for config module routes.
- */
-class FeaturesController implements ContainerInjectionInterface {
-
-  /**
-   * The file download controller.
-   *
-   * @var \Drupal\system\FileDownloadController
-   */
-  protected $fileDownloadController;
-
-  /**
-   * The CSRF token generator.
-   *
-   * @var \Drupal\Core\Access\CsrfTokenGenerator
-   */
-  protected $csrfToken;
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container) {
-    return new static(
-      new FileDownloadController(),
-      $container->get('csrf_token')
-    );
-  }
-
-  /**
-   * Constructs a FeaturesController object.
-   *
-   * @param \Drupal\system\FileDownloadController $file_download_controller
-   *   The file download controller.
-   * @param \Drupal\Core\Access\CsrfTokenGenerator $csrf_token
-   *   The CSRF token generator.
-   */
-  public function __construct(FileDownloadController $file_download_controller, CsrfTokenGenerator $csrf_token) {
-    $this->fileDownloadController = $file_download_controller;
-    $this->csrfToken = $csrf_token;
-  }
-
-  /**
-   * Downloads a tarball of the site configuration.
-   *
-   * @param string $uri
-   *   The URI to download.
-   * @param \Symfony\Component\HttpFoundation\Request $request
-   *   The request.
-   *
-   * @return \Symfony\Component\HttpFoundation\BinaryFileResponse
-   *   The downloaded file.
-   */
-  public function downloadExport($uri, Request $request) {
-    if ($uri) {
-      // @todo Simplify once https://www.drupal.org/node/2630920 is solved.
-      if (!$this->csrfToken->validate($request->query->get('token'), $uri)) {
-        throw new AccessDeniedHttpException();
-      }
-
-      $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
deleted file mode 100644
index ced0be6de6113ec46657f33cb6be0d3922a9731a..0000000000000000000000000000000000000000
--- a/web/modules/features/src/Entity/FeaturesBundle.php
+++ /dev/null
@@ -1,310 +0,0 @@
-<?php
-
-namespace Drupal\features\Entity;
-
-use Drupal\Core\Config\Entity\ConfigEntityBase;
-use Drupal\features\FeaturesBundleInterface;
-use Drupal\Core\Site\Settings;
-
-/**
- * Defines a features bundle.
- * @todo Better description
- *
- * @ConfigEntityType(
- *   id = "features_bundle",
- *   label = @Translation("Features bundle"),
- *   handlers = {
- *   },
- *   admin_permission = "administer site configuration",
- *   config_prefix = "bundle",
- *   entity_keys = {
- *     "id" = "machine_name",
- *     "label" = "name"
- *   },
- *   links = {
- *   },
- *   config_export = {
- *     "name",
- *     "machine_name",
- *     "description",
- *     "assignments",
- *     "profile_name",
- *     "is_profile",
- *   }
- * )
- */
-class FeaturesBundle extends ConfigEntityBase implements FeaturesBundleInterface {
-
-  /**
-   * @var string
-   */
-  protected $name;
-
-  /**
-   * @var
-   */
-  protected $machine_name;
-
-  /**
-   * @var string
-   */
-  protected $description;
-
-  /**
-   * @var string[]
-   */
-  protected $assignments = [];
-
-  /**
-   * @var string
-   */
-  protected $profile_name;
-
-  /**
-   * @var bool
-   */
-  protected $is_profile = FALSE;
-
-  public function id() {
-    // @todo Convert it to $this->id in the long run.
-    return $this->getMachineName();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isDefault() {
-    return $this->machine_name == static::DEFAULT_BUNDLE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getMachineName() {
-    return $this->machine_name;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setMachineName($machine_name) {
-    $this->machine_name = $machine_name;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getName() {
-    return $this->name;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setName($name) {
-    $this->name = $name;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFullName($short_name) {
-    if ($this->isDefault() ||
-      // If it's already prefixed, don't repeat the prefix.
-      $this->inBundle($short_name) ||
-      // If we are a profile, don't duplicate the bundle if same as profile.
-      $this->isProfilePackage($short_name)) {
-      return $short_name;
-    }
-    else {
-      return $this->machine_name . '_' . $short_name;
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getShortName($machine_name) {
-    if (!$this->isProfilePackage($machine_name) && $this->inBundle($machine_name)) {
-      return substr($machine_name, strlen($this->getMachineName()) + 1, strlen($machine_name) - strlen($this->getMachineName()) - 1);
-    }
-    return $machine_name;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function inBundle($machine_name) {
-    return ($this->isProfilePackage($machine_name) || strpos($machine_name, $this->machine_name . '_') === 0);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isProfilePackage($machine_name) {
-    return ($this->isProfile() && $machine_name == $this->getProfileName());
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getDescription() {
-    return $this->description;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setDescription($description) {
-    $this->description = $description;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isProfile() {
-    return $this->is_profile;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setIsProfile($value) {
-    $this->is_profile = $value;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getProfileName() {
-    $name = $this->isProfile() ? $this->profile_name : '';
-    // Use Settings::get to fetch current profile name so we can easily test.
-    return !empty($name) ? $name : Settings::get('install_profile');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setProfileName($machine_name) {
-    $this->profile_name = $machine_name;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getEnabledAssignments() {
-    $list = [];
-    foreach ($this->assignments as $method_id => $method) {
-      if ($method['enabled']) {
-        $list[$method_id] = $method_id;
-      }
-    }
-    return $list;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setEnabledAssignments(array $assignments) {
-    // Add any new assignments that we don't yet know about.
-    $new_assignments = array_diff($assignments, array_keys($this->assignments));
-    foreach ($new_assignments as $method_id) {
-      $this->assignments[$method_id] = $this->getAssignmentSettings($method_id);
-    }
-
-    foreach ($this->assignments as $method_id => &$method) {
-      $method['enabled'] = in_array($method_id, $assignments);
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getAssignmentWeights() {
-    $list = [];
-    foreach ($this->assignments as $method_id => $method) {
-      $list[$method_id] = $method['weight'];
-    }
-    return $list;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setAssignmentWeights(array $assignments) {
-    foreach ($this->assignments as $method_id => &$method) {
-      if (isset($assignments[$method_id])) {
-        $method['weight'] = $assignments[$method_id];
-      }
-    }
-  }
-
-  /**
-   * Return array of default settings for the given plugin method
-   *
-   * @param $method_id
-   * @return array
-   */
-  protected function getDefaultSettings($method_id) {
-    $settings = ['enabled' => FALSE, 'weight' => 0];
-
-    $manager = \Drupal::service('plugin.manager.features_assignment_method');
-    $definition = $manager->getDefinition($method_id);
-
-    if (isset($definition['weight'])) {
-      $settings['weight'] = $definition['weight'];
-    }
-    if (isset($definition['default_settings'])) {
-      $settings += $definition['default_settings'];
-    }
-
-    return $settings;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getAssignmentSettings($method_id = NULL) {
-    if (isset($method_id)) {
-      if (isset($this->assignments[$method_id])) {
-        return $this->assignments[$method_id];
-      }
-      else {
-        // Use defaults.
-        return $this->getDefaultSettings($method_id);
-      }
-    }
-    else {
-      $list = [];
-      foreach (array_keys($this->assignments) as $method_id) {
-        $list[$method_id] = $this->getAssignmentSettings($method_id);
-      }
-      return $list;
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setAssignmentSettings($method_id, array $settings) {
-    if (isset($method_id)) {
-      $this->assignments[$method_id] = $settings;
-    }
-    else {
-      foreach ($settings as $method_id => $method_settings) {
-        if (!empty($method_settings)) {
-          $this->setAssignmentSettings($method_id, $method_settings);
-        }
-      }
-    }
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function remove() {
-    $this->delete();
-  }
-
-}
diff --git a/web/modules/features/src/Exception/DomainException.php b/web/modules/features/src/Exception/DomainException.php
deleted file mode 100644
index c496d3b0e9d542419738992332497bf958a11a96..0000000000000000000000000000000000000000
--- a/web/modules/features/src/Exception/DomainException.php
+++ /dev/null
@@ -1,7 +0,0 @@
-<?php
-
-namespace Drupal\features\Exception;
-
-class DomainException extends \DomainException {
-
-}
diff --git a/web/modules/features/src/Exception/InvalidArgumentException.php b/web/modules/features/src/Exception/InvalidArgumentException.php
deleted file mode 100644
index 199d51e163e07f8594f70422660b87907b215caa..0000000000000000000000000000000000000000
--- a/web/modules/features/src/Exception/InvalidArgumentException.php
+++ /dev/null
@@ -1,7 +0,0 @@
-<?php
-
-namespace Drupal\features\Exception;
-
-class InvalidArgumentException extends \InvalidArgumentException {
-
-}
diff --git a/web/modules/features/src/FeaturesAssigner.php b/web/modules/features/src/FeaturesAssigner.php
deleted file mode 100644
index f06b0d16755ffa5579737c0dfdeca126357c7a3f..0000000000000000000000000000000000000000
--- a/web/modules/features/src/FeaturesAssigner.php
+++ /dev/null
@@ -1,446 +0,0 @@
-<?php
-
-namespace Drupal\features;
-
-use Drupal\Component\Plugin\PluginManagerInterface;
-use Drupal\Core\Config\ConfigFactoryInterface;
-use Drupal\Core\Config\ExtensionInstallStorage;
-use Drupal\Core\Entity\EntityTypeManagerInterface;
-use Drupal\Core\Config\StorageInterface;
-use Drupal\Core\StringTranslation\StringTranslationTrait;
-use Drupal\features\Entity\FeaturesBundle;
-
-/**
- * Class responsible for performing package assignment.
- */
-class FeaturesAssigner implements FeaturesAssignerInterface {
-  use StringTranslationTrait;
-
-  /**
-   * The package assignment method plugin manager.
-   *
-   * @var \Drupal\Component\Plugin\PluginManagerInterface
-   */
-  protected $assignerManager;
-
-  /**
-   * The features manager.
-   *
-   * @var \Drupal\features\FeaturesManagerInterface
-   */
-  protected $featuresManager;
-
-  /**
-   * The configuration factory.
-   *
-   * @var \Drupal\Core\Config\ConfigFactoryInterface
-   */
-  protected $configFactory;
-
-  /**
-   * The configuration storage.
-   *
-   * @var \Drupal\Core\Config\StorageInterface
-   */
-  protected $configStorage;
-
-  /**
-   * The entity type manager.
-   *
-   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
-   */
-  protected $entityTypeManager;
-
-  /**
-   * Local cache for package assignment method instances.
-   *
-   * @var array
-   */
-  protected $methods;
-
-  /**
-   * Bundles.
-   *
-   * @var array of \Drupal\features\FeaturesBundleInterface
-   */
-  protected $bundles;
-
-  /**
-   * Currently active bundle.
-   *
-   * @var \Drupal\features\FeaturesBundleInterface
-   */
-  protected $currentBundle;
-
-  /**
-   * Constructs a new FeaturesAssigner object.
-   *
-   * @param \Drupal\features\FeaturesManagerInterface $features_manager
-   *    The features manager.
-   * @param \Drupal\Component\Plugin\PluginManagerInterface $assigner_manager
-   *   The package assignment methods plugin manager.
-   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
-   *   The entity type manager.
-   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
-   *   The configuration factory.
-   * @param \Drupal\Core\Config\StorageInterface $config_storage
-   *   The configuration factory.
-   */
-  public function __construct(FeaturesManagerInterface $features_manager, PluginManagerInterface $assigner_manager, EntityTypeManagerInterface $entity_type_manager, ConfigFactoryInterface $config_factory, StorageInterface $config_storage) {
-    $this->featuresManager = $features_manager;
-    $this->assignerManager = $assigner_manager;
-    $this->entityTypeManager = $entity_type_manager;
-    $this->configFactory = $config_factory;
-    $this->configStorage = $config_storage;
-    $this->bundles = $this->getBundleList();
-    $this->currentBundle = $this->getBundle(FeaturesBundleInterface::DEFAULT_BUNDLE);
-    // Ensure bundle information is fresh.
-    $this->createBundlesFromPackages();
-  }
-
-  /**
-   * Initializes the injected features manager with the assigner.
-   *
-   * This should be called right after instantiating the assigner to make it
-   * available to the features manager without introducing a circular
-   * dependency.
-   */
-  public function initFeaturesManager() {
-    $this->featuresManager->setAssigner($this);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function reset() {
-    $this->methods = [];
-    $this->featuresManager->reset();
-  }
-
-  /**
-   * Gets enabled assignment methods.
-   *
-   * @return array
-   *   An array of enabled assignment methods, sorted by weight.
-   */
-  public function getEnabledAssigners() {
-    $enabled = $this->currentBundle->getEnabledAssignments();
-    $weights = $this->currentBundle->getAssignmentWeights();
-    foreach ($enabled as $key => $value) {
-      $enabled[$key] = $weights[$key];
-    }
-    asort($enabled);
-    return $enabled;
-  }
-
-  /**
-   * Clean up the package list after all config has been assigned
-   */
-  protected function cleanup() {
-    $packages = $this->featuresManager->getPackages();
-    foreach ($packages as $index => $package) {
-      if ($package->getStatus() === FeaturesManagerInterface::STATUS_NO_EXPORT && empty($package->getConfig()) && empty($package->getConfigOrig())) {
-        unset($packages[$index]);
-      }
-    }
-    $this->featuresManager->setPackages($packages);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function assignConfigPackages($force = FALSE) {
-    foreach ($this->getEnabledAssigners() as $method_id => $info) {
-      $this->applyAssignmentMethod($method_id, $force);
-    }
-    $this->cleanup();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function applyAssignmentMethod($method_id, $force = FALSE) {
-    $this->getAssignmentMethodInstance($method_id)->assignPackages($force);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getAssignmentMethods() {
-    return $this->assignerManager->getDefinitions();
-  }
-
-  /**
-   * Returns an instance of the specified package assignment method.
-   *
-   * @param string $method_id
-   *   The string identifier of the package assignment method to use to package
-   *   configuration.
-   *
-   * @return \Drupal\features\FeaturesAssignmentMethodInterface
-   */
-  protected function getAssignmentMethodInstance($method_id) {
-    if (!isset($this->methods[$method_id])) {
-      $instance = $this->assignerManager->createInstance($method_id, []);
-      $instance->setFeaturesManager($this->featuresManager);
-      $instance->setAssigner($this);
-      $instance->setEntityTypeManager($this->entityTypeManager);
-      $instance->setConfigFactory($this->configFactory);
-      $this->methods[$method_id] = $instance;
-    }
-    return $this->methods[$method_id];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function purgeConfiguration() {
-    // Ensure that we are getting the defined package assignment information.
-    // An invocation of \Drupal\Core\Extension\ModuleHandler::install() or
-    // \Drupal\Core\Extension\ModuleHandler::uninstall() could invalidate the
-    // cached information.
-    $this->assignerManager->clearCachedDefinitions();
-    $this->featuresManager->reset();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getBundle($name = NULL) {
-    if (empty($name)) {
-      return $this->currentBundle;
-    }
-    elseif (isset($this->bundles[$name])) {
-      return $this->bundles[$name];
-    }
-    return NULL;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setBundle(FeaturesBundleInterface $bundle, $current = TRUE) {
-    $this->bundles[$bundle->getMachineName()] = $bundle;
-    if (isset($this->currentBundle) && ($current || ($bundle->getMachineName() == $this->currentBundle->getMachineName()))) {
-      $this->currentBundle = $bundle;
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function findBundle(array $info, $features_info = NULL) {
-    $bundle = NULL;
-    if (!empty($features_info['bundle'])) {
-      $bundle = $this->getBundle($features_info['bundle']);
-    }
-    elseif (!empty($info['package'])) {
-      $bundle = $this->findBundleByName($info['package']);
-    }
-    if (!isset($bundle)) {
-      // Return the default bundle.
-      return $this->getBundle(FeaturesBundleInterface::DEFAULT_BUNDLE);
-    }
-    return $bundle;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setCurrent(FeaturesBundleInterface $bundle) {
-    $this->currentBundle = $bundle;
-    $session = \Drupal::request()->getSession();
-    if (isset($session)) {
-      $session->set('features_current_bundle', $bundle->getMachineName());
-    }
-    return $bundle;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getBundleList() {
-    if (empty($this->bundles)) {
-      $this->bundles = [];
-      foreach ($this->entityTypeManager->getStorage('features_bundle')->loadMultiple() as $machine_name => $bundle) {
-        $this->bundles[$machine_name] = $bundle;
-      }
-    }
-    return $this->bundles;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function findBundleByName($name, $create = FALSE) {
-    $bundles = $this->getBundleList();
-    foreach ($bundles as $machine_name => $bundle) {
-      if ($name == $bundle->getName()) {
-        return $bundle;
-      }
-    }
-    $machine_name = strtolower(str_replace([' ', '-'], '_', $name));
-    if (isset($bundles[$machine_name])) {
-      return $bundles[$machine_name];
-    }
-    return NULL;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function createBundleFromDefault($machine_name, $name = NULL, $description = NULL, $is_profile = FALSE, $profile_name = NULL) {
-    // Duplicate the default bundle to get its default configuration.
-    $default = $this->getBundle(FeaturesBundleInterface::DEFAULT_BUNDLE);
-    if (!$default) {
-      // If we don't have the default installed, generate it from the install
-      // config file.
-      $ext_storage = new ExtensionInstallStorage($this->configStorage);
-      $record = $ext_storage->read('features.bundle.default');
-      $bundle_storage = $this->entityTypeManager->getStorage('features_bundle');
-      $default = $bundle_storage->createFromStorageRecord($record);
-    }
-
-    /** @var \Drupal\features\Entity\FeaturesBundle $bundle */
-    $bundle = $default->createDuplicate();
-
-    $bundle->setMachineName($machine_name);
-    $name = !empty($name) ? $name : $machine_name;
-    $bundle->setName($name);
-    if (isset($description)) {
-      $bundle->setDescription($description);
-    }
-    else {
-      $bundle->setDescription(t('Auto-generated bundle from package @name', ['@name' => $name]));
-    }
-    $bundle->setIsProfile($is_profile);
-    if (isset($profile_name)) {
-      $bundle->setProfileName($profile_name);
-    }
-    $bundle->save();
-    $this->setBundle($bundle);
-
-    return $bundle;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function createBundlesFromPackages() {
-    $existing_bundles = $this->getBundleList();
-    $new_bundles = [];
-    // Only parse from installed features.
-    $modules = $this->featuresManager->getFeaturesModules(NULL, TRUE);
-
-    foreach ($modules as $module) {
-      $info = $this->featuresManager->getExtensionInfo($module);
-      // @todo This entire function could be simplified a lot using packages.
-      $features_info = $this->featuresManager->getFeaturesInfo($module);
-      // Create a new bundle if:
-      // - the feature specifies a bundle and
-      // - that bundle doesn't yet exist locally.
-      // Allow profiles to override previous values.
-      if (!empty($features_info['bundle']) &&
-        !isset($existing_bundles[$features_info['bundle']]) &&
-        (!in_array($features_info['bundle'], $new_bundles) || $info['type'] == 'profile')) {
-        if ($info['type'] == 'profile') {
-          $new_bundle = [
-            'name' => $info['name'],
-            'description' => $info['description'],
-            'is_profile' => TRUE,
-            'profile_name' => $module->getName(),
-          ];
-        }
-        else {
-          $new_bundle = [
-            'name' => isset($info['package']) ? $info['package'] : ucwords(str_replace('_', ' ', $features_info['bundle'])),
-            'description' => NULL,
-            'is_profile' => FALSE,
-            'profile_name' => NULL,
-          ];
-        }
-        $new_bundle['machine_name'] = $features_info['bundle'];
-        $new_bundles[$new_bundle['machine_name']] = $new_bundle;
-      }
-    }
-    foreach ($new_bundles as $new_bundle) {
-      $this->createBundleFromDefault($new_bundle['machine_name'], $new_bundle['name'], $new_bundle['description'], $new_bundle['is_profile']);
-    }
-
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getBundleOptions() {
-    $list = $this->getBundleList();
-    $result = [];
-    foreach ($list as $machine_name => $bundle) {
-      $result[$machine_name] = $bundle->getName();
-    }
-    return $result;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function applyBundle($machine_name = NULL) {
-    $this->reset();
-    $bundle = $this->loadBundle($machine_name);
-    if (isset($bundle)) {
-      $this->assignConfigPackages();
-      return $this->currentBundle;
-    }
-    return NULL;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function renameBundle($old_machine, $new_machine) {
-    $is_current = (isset($this->currentBundle) && ($old_machine == $this->currentBundle->getMachineName()));
-    $bundle = $this->getBundle($old_machine);
-    if ($bundle->getMachineName() != '') {
-      // Remove old bundle from the list if it's not the Default bundle.
-      unset($this->bundles[$old_machine]);
-    }
-    $bundle->setMachineName($new_machine);
-    $this->setBundle($bundle);
-    // Put the bundle into the list with the correct name.
-    $this->bundles[$bundle->getMachineName()] = $bundle;
-    if ($is_current) {
-      $this->setCurrent($bundle);
-    }
-    return $bundle;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function loadBundle($machine_name = NULL) {
-    if (!isset($machine_name)) {
-      $session = \Drupal::request()->getSession();
-      if (isset($session)) {
-        $machine_name = isset($session) ? $session->get('features_current_bundle', FeaturesBundleInterface::DEFAULT_BUNDLE) : FeaturesBundleInterface::DEFAULT_BUNDLE;
-      }
-    }
-    $bundle = $this->getBundle($machine_name);
-    if (!isset($bundle)) {
-      // If bundle no longer exists then return default.
-      $bundle = $this->bundles[FeaturesBundleInterface::DEFAULT_BUNDLE];
-    }
-    return $this->setCurrent($bundle);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function removeBundle($machine_name) {
-    $bundle = $this->getBundle($machine_name);
-    if (isset($bundle) && !$bundle->isDefault()) {
-      unset($this->bundles[$machine_name]);
-      $bundle->remove();
-    }
-  }
-
-}
diff --git a/web/modules/features/src/FeaturesAssignerInterface.php b/web/modules/features/src/FeaturesAssignerInterface.php
deleted file mode 100644
index 946c6ec8bf9e7c97e0d801b8b03fa401f7e71738..0000000000000000000000000000000000000000
--- a/web/modules/features/src/FeaturesAssignerInterface.php
+++ /dev/null
@@ -1,228 +0,0 @@
-<?php
-
-namespace Drupal\features;
-
-/**
- * Common interface for features assignment services.
- *
- * The feature API is based on two major concepts:
- * - Packages: modules into which configuration is packaged.
- * - Package assignment methods: responsible for `determining
- *   which package to assign a given piece of configuration to.
- * Assignment methods are customizable.
- *
- * Features defines several package assignment methods, which are simple plugin
- * classes that implement a particular logic to assign pieces of configuration
- * to a given package (module).
- *
- * Modules can define additional package assignment methods by simply providing
- * the related plugins, and alter existing methods through
- * hook_features_assignment_method_info_alter(). Here is an example
- * snippet:
- * @code
- * function mymodule_features_assignment_method_info_alter(&$assignment_info) {
- *   // Replace the original plugin with our own implementation.
- *   $method_id = \Drupal\features\Plugin\FeaturesAssignment\FeaturesAssignmentBaseType::METHOD_ID;
- *   $assignment_info[$method_id]['class'] = 'Drupal\my_module\Plugin\FeaturesAssignment\MyFeaturesAssignmentBaseType';
- * }
- *
- * class MyFeaturesAssignmentBaseType extends FeaturesAssignmentBaseType {
- *   public function assignPackages($force = FALSE) {
- *     // Insert customization here.
- *   }
- * }
- * ?>
- * @endcode
- *
- * For more information, see
- * @link http://drupal.org/node/2404473 Developing for Features 3.x @endlink
- */
-interface FeaturesAssignerInterface {
-
-  /**
-   * The package assignment method id for the package assigner itself.
-   */
-  const METHOD_ID = 'assigner-default';
-
-  /**
-   * Resets the assigned packages and the method instances.
-   */
-  public function reset();
-
-  /**
-   * Apply all enabled package assignment methods.
-   *
-   * @param bool $force
-   *   (optional) If TRUE, assign config regardless of restrictions such as it
-   *   being already assigned to a package.
-   */
-  public function assignConfigPackages($force = FALSE);
-
-  /**
-   * Applies a given package assignment method.
-   *
-   * @param string $method_id
-   *   The string identifier of the package assignment method to use to package
-   *   configuration.
-   * @param bool $force
-   *   (optional) If TRUE, assign config regardless of restrictions such as it
-   *   being already assigned to a package.
-   */
-  public function applyAssignmentMethod($method_id, $force = FALSE);
-
-  /**
-   * Returns the enabled package assignment methods.
-   *
-   * @return array
-   *   An array of package assignment method IDs.
-   */
-  public function getAssignmentMethods();
-
-  /**
-   * Resaves the configuration to purge missing assignment methods.
-   */
-  public function purgeConfiguration();
-
-  /**
-   * Returns a FeaturesBundle object.
-   *
-   * @param string $name
-   *   machine name of package set. If omitted, returns the current bundle.
-   *
-   * @return \Drupal\features\FeaturesBundleInterface
-   *   A features bundle object.
-   */
-  public function getBundle($name = NULL);
-
-  /**
-   * Stores a features bundle.
-   *
-   * Added to list if machine_name is new.
-   *
-   * @param \Drupal\features\FeaturesBundleInterface $bundle
-   *   A features bundle.
-   * @param bool $current
-   *   Determine if the current bundle is set to $bundle.
-   *   If False, the current bundle is only updated if it already has the same
-   *   machine name as the $bundle.
-   */
-  public function setBundle(FeaturesBundleInterface $bundle, $current = TRUE);
-
-  /**
-   * Searches for a bundle that matches the $info.yml or $features.yml export.
-   *
-   * Creates a new bundle as needed.
-   *
-   * @param array $info
-   *   The bundle info.
-   * @param mixed $features_info
-   *   The features info.
-   *
-   * @return \Drupal\features\FeaturesBundleInterface
-   *   A bundle.
-   */
-  public function findBundle(array $info, $features_info = NULL);
-
-  /**
-   * Sets the currently active bundle.
-   *
-   * Updates value in current SESSION.
-   *
-   * @param \Drupal\features\FeaturesBundleInterface $bundle
-   *   A features bundle object.
-   */
-  public function setCurrent(FeaturesBundleInterface $bundle);
-
-  /**
-   * Returns an array of all existing features bundles.
-   *
-   * @return \Drupal\features\FeaturesBundleInterface[]
-   *   Keyed by machine_name with value of
-   *   \Drupal\features\FeaturesBundleInterface.
-   */
-  public function getBundleList();
-
-  /**
-   * Returns a named bundle.
-   *
-   * First searches by Human name, then by machine_name.
-   *
-   * @param string $name
-   *   The bundle name to search by.
-   *
-   * @return \Drupal\features\FeaturesBundleInterface
-   *   A features bundle object.
-   */
-  public function findBundleByName($name);
-
-  /**
-   * Creates a new bundle by duplicating the default bundle and customizing.
-   *
-   * @param string $machine_name
-   *   Machine name.
-   * @param string $name
-   *   (optional) Human readable name of the bundle.
-   * @param string $description
-   *   (optional) Description of the bundle.
-   * @param bool $is_profile
-   *   (optional) TRUE if a profile is used with this bundle.
-   * @param string $profile_name
-   *   (optional) The machine name of the profile.
-   *
-   * @return \Drupal\features\FeaturesBundleInterface
-   *   A features bundle object.
-   */
-  public function createBundleFromDefault($name, $machine_name = '', $description = '', $is_profile = FALSE, $profile_name = NULL);
-
-  /**
-   * Creates bundles by parsing information from installed packages.
-   */
-  public function createBundlesFromPackages();
-
-  /**
-   * Returns an array of bundle names suitable for a select option list.
-   *
-   * @return array
-   *   An array of bundles, keyed by machine_name, with values being human
-   *   readable names.
-   */
-  public function getBundleOptions();
-
-  /**
-   * Makes the named bundle the current bundle.
-   *
-   * @param string $machine_name
-   *   The name of a features bundle. If omitted, gets the last bundle from the
-   *   Session.
-   *
-   * @return \Drupal\features\FeaturesBundleInterface
-   *   A features bundle object.
-   */
-  public function applyBundle($machine_name = NULL);
-
-  /**
-   * Renames a bundle.
-   *
-   * @param string $old_machine
-   *   The old machine name of a bundle.
-   * @param string $new_machine
-   *   The new machine name of a bundle.
-   *
-   * @return \Drupal\features\FeaturesBundleInterface
-   *   A features bundle object.
-   */
-  public function renameBundle($old_machine, $new_machine);
-
-  /**
-   * Loads a named bundle.
-   *
-   * @param string $machine_name
-   *   (optional) The name of a features bundle.
-   *   Defaults to NULL, gets the last bundle from the session.
-   *
-   * @return \Drupal\features\FeaturesBundleInterface
-   *   A features bundle object.
-   */
-  public function loadBundle($machine_name = NULL);
-
-}
diff --git a/web/modules/features/src/FeaturesAssignmentMethodBase.php b/web/modules/features/src/FeaturesAssignmentMethodBase.php
deleted file mode 100644
index 2b7465756e6db9ab01e4e1c305e70b54cbd47892..0000000000000000000000000000000000000000
--- a/web/modules/features/src/FeaturesAssignmentMethodBase.php
+++ /dev/null
@@ -1,124 +0,0 @@
-<?php
-
-namespace Drupal\features;
-
-use Drupal\Core\Config\ConfigFactoryInterface;
-use Drupal\Core\Entity\EntityTypeManagerInterface;
-use Drupal\Core\Plugin\PluginBase;
-
-/**
- * Base class for package assignment methods.
- */
-abstract class FeaturesAssignmentMethodBase extends PluginBase implements FeaturesAssignmentMethodInterface {
-  /**
-   * The features manager.
-   *
-   * @var \Drupal\features\FeaturesManagerInterface
-   */
-  protected $featuresManager;
-
-  /**
-   * The features assigner.
-   *
-   * @var \Drupal\features\FeaturesAssignerInterface
-   */
-  protected $assigner;
-
-  /**
-   * The entity type manager.
-   *
-   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
-   */
-  protected $entityTypeManager;
-
-  /**
-   * The configuration factory.
-   *
-   * @var \Drupal\Core\Config\ConfigFactoryInterface
-   */
-  protected $configFactory;
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setfeaturesManager(FeaturesManagerInterface $features_manager) {
-    $this->featuresManager = $features_manager;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setAssigner(FeaturesAssignerInterface $assigner) {
-    $this->assigner = $assigner;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setEntityTypeManager(EntityTypeManagerInterface $entity_type_manager) {
-    $this->entityTypeManager = $entity_type_manager;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setConfigFactory(ConfigFactoryInterface $config_factory) {
-    $this->configFactory = $config_factory;
-  }
-
-  /**
-   * Assigns configuration of the types specified in a setting to a package.
-   *
-   * @param string $machine_name
-   *   Machine name of the package.
-   * @param bool $force
-   *   (optional) If TRUE, assign config regardless of restrictions such as it
-   *   being already assigned to a package.
-   */
-  protected function assignPackageByConfigTypes($machine_name, $force = FALSE) {
-    $current_bundle = $this->assigner->getBundle();
-    $settings = $current_bundle->getAssignmentSettings($this->getPluginId());
-    $types = $settings['types']['config'];
-
-    $config_collection = $this->featuresManager->getConfigCollection();
-
-    foreach ($config_collection as $item_name => $item) {
-      // Don't assign configuration that's provided by an extension.
-      if (in_array($item->getType(), $types) && !($item->isProviderExcluded())) {
-        try {
-          $this->featuresManager->assignConfigPackage($machine_name, [$item_name]);
-        }
-        catch (\Exception $exception) {
-          \Drupal::logger('features')->error($exception->getMessage());
-        }
-      }
-    }
-  }
-
-  /**
-   * Assigns a given subdirectory to configuration of specified types.
-   *
-   * @param string $subdirectory
-   *   The subdirectory that designated configuration should be exported to.
-   */
-  protected function assignSubdirectoryByConfigTypes($subdirectory) {
-    $current_bundle = $this->assigner->getBundle();
-    $settings = $current_bundle->getAssignmentSettings($this->getPluginId());
-    $types = $settings['types']['config'];
-
-    if (!empty($types)) {
-      $config_collection = $this->featuresManager->getConfigCollection();
-
-      foreach ($config_collection as &$item) {
-        if (in_array($item->getType(), $types)) {
-          $item->setSubdirectory($subdirectory);
-        }
-      }
-      // Clean up the $item pass by reference.
-      unset($item);
-
-      $this->featuresManager->setConfigCollection($config_collection);
-    }
-  }
-
-}
diff --git a/web/modules/features/src/FeaturesAssignmentMethodInterface.php b/web/modules/features/src/FeaturesAssignmentMethodInterface.php
deleted file mode 100644
index abb29f19dbe05c4bdfc5c336b40fd24c0cf0802c..0000000000000000000000000000000000000000
--- a/web/modules/features/src/FeaturesAssignmentMethodInterface.php
+++ /dev/null
@@ -1,56 +0,0 @@
-<?php
-
-namespace Drupal\features;
-
-use Drupal\Component\Plugin\PluginInspectionInterface;
-use Drupal\Core\Config\ConfigFactoryInterface;
-use Drupal\Core\Entity\EntityTypeManagerInterface;
-
-/**
- * Interface for package assignment classes.
- */
-interface FeaturesAssignmentMethodInterface extends PluginInspectionInterface {
-
-  /**
-   * Injects the features manager.
-   *
-   * @param \Drupal\features\FeaturesManagerInterface $features_manager
-   *   The features manager to be used to retrieve the configuration list and
-   *   the already assigned packages.
-   */
-  public function setFeaturesManager(FeaturesManagerInterface $features_manager);
-
-  /**
-   * Injects the features assigner.
-   *
-   * @param \Drupal\features\FeaturesAssignerInterface $assigner
-   *   The features assigner to be used to retrieve the bundle configuration.
-   */
-  public function setAssigner(FeaturesAssignerInterface $assigner);
-
-  /**
-   * Injects the entity manager.
-   *
-   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
-   *   The entity type manager to be used to retrieve entity information.
-   */
-  public function setEntityTypeManager(EntityTypeManagerInterface $entity_type_manager);
-
-  /**
-   * Injects the configuration factory.
-   *
-   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
-   *   The configuration factory to be used to retrieve configuration values.
-   */
-  public function setConfigFactory(ConfigFactoryInterface $config_factory);
-
-  /**
-   * Performs package assignment.
-   *
-   * @param bool $force
-   *   (optional) If TRUE, assign config regardless of restrictions such as it
-   *   being already assigned to a package.
-   */
-  public function assignPackages($force = FALSE);
-
-}
diff --git a/web/modules/features/src/FeaturesAssignmentMethodManager.php b/web/modules/features/src/FeaturesAssignmentMethodManager.php
deleted file mode 100644
index 40b4a5824c0fd0cbda5573f2638a50b0be15b8c6..0000000000000000000000000000000000000000
--- a/web/modules/features/src/FeaturesAssignmentMethodManager.php
+++ /dev/null
@@ -1,32 +0,0 @@
-<?php
-
-namespace Drupal\features;
-
-use Drupal\Core\Cache\CacheBackendInterface;
-use Drupal\Core\Extension\ModuleHandlerInterface;
-use Drupal\Core\Plugin\DefaultPluginManager;
-
-/**
- * Manages configuration packaging methods.
- */
-class FeaturesAssignmentMethodManager extends DefaultPluginManager {
-
-  /**
-   * Constructs a new FeaturesAssignmentMethodManager object.
-   *
-   * @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
-   *   An object that implements CacheBackendInterface.
-   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
-   *   An object that implements ModuleHandlerInterface.
-   */
-  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
-    parent::__construct('Plugin/FeaturesAssignment', $namespaces, $module_handler,
-      'Drupal\features\FeaturesAssignmentMethodInterface');
-    $this->alterInfo('features_assignment_info');
-    $this->setCacheBackend($cache_backend, 'features_assignment_methods');
-  }
-
-}
diff --git a/web/modules/features/src/FeaturesBundleInterface.php b/web/modules/features/src/FeaturesBundleInterface.php
deleted file mode 100644
index 83dfbf5a9bc034dbd43fd8e099477872fb266375..0000000000000000000000000000000000000000
--- a/web/modules/features/src/FeaturesBundleInterface.php
+++ /dev/null
@@ -1,240 +0,0 @@
-<?php
-
-namespace Drupal\features;
-
-/**
- * Provides an interface for the FeaturesBundle object.
- */
-interface FeaturesBundleInterface {
-
-  const DEFAULT_BUNDLE = 'default';
-
-  /**
-   * Determines whether the current bundle is the default one.
-   *
-   * @return bool
-   *   Returns TRUE if this is the default bundle.
-   */
-  public function isDefault();
-
-  /**
-   * Returns the machine name of a bundle.
-   *
-   * @return string
-   *   The machine name of a bundle.
-   *
-   * @see \Drupal\features\FeaturesBundleInterface::setMachineName()
-   */
-  public function getMachineName();
-
-  /**
-   * Sets the machine name of a bundle.
-   *
-   * @param string $machine_name
-   *   The machine name of a bundle.
-   *
-   * @see \Drupal\features\FeaturesBundleInterface::getMachineName()
-   */
-  public function setMachineName($machine_name);
-
-  /**
-   * Gets the human readable name of a bundle.
-   *
-   * @return string
-   *   The human readable name of a bundle.
-   *
-   * @see \Drupal\features\FeaturesBundleInterface::setName()
-   */
-  public function getName();
-
-  /**
-   * Sets the human readable name of a bundle.
-   *
-   * @param string $name
-   *   The human readable name of a bundle.
-   *
-   * @see \Drupal\features\FeaturesBundleInterface::getName()
-   */
-  public function setName($name);
-
-  /**
-   * Returns a full machine name prefixed with the bundle name.
-   *
-   * @param string $short_name
-   *   The short machine_name of a bundle.
-   *
-   * @return string
-   *   The full machine_name of a bundle.
-   */
-  public function getFullName($short_name);
-
-  /**
-   * Returns a short machine name not prefixed with the bundle name.
-   *
-   * @param string $machine_name
-   *   The full machine_name of a bundle.
-   *
-   * @return string
-   *   The short machine_name of a bundle.
-   */
-  public function getShortName($machine_name);
-
-  /**
-   * Determines if the $machine_name is prefixed by the bundle machine name.
-   *
-   * @param string $machine_name
-   *   The machine name of a package.
-   *
-   * @return bool
-   *   TRUE if the machine name is prefixed by the bundle machine name.
-   */
-  public function inBundle($machine_name);
-
-  /**
-   * Determines if the package with $machine_name is the bundle profile.
-   *
-   * @param string $machine_name
-   *   The machine name of a package.
-   *
-   * @return bool
-   *   TRUE if the package with $machine_name is the bundle profile.
-   */
-  public function isProfilePackage($machine_name);
-
-  /**
-   * Gets the description of a bundle.
-   *
-   * @return string
-   *   The description of a bundle.
-   *
-   * @see \Drupal\features\FeaturesBundleInterface::setDescription()
-   */
-  public function getDescription();
-
-  /**
-   * Sets the description of a bundle.
-   *
-   * @param string $description
-   *   The description of a bundle.
-   *
-   * @see \Drupal\features\FeaturesBundleInterface::getDescription()
-   */
-  public function setDescription($description);
-
-  /**
-   * Gets option for using a profile with this bundle.
-   *
-   * @return bool
-   *   TRUE if a profile is used with this profile.
-   */
-  public function isProfile();
-
-  /**
-   * Sets option for using a profile with this bundle.
-   *
-   * @param bool $value
-   *   TRUE if a profile is used with this bundle.
-   */
-  public function setIsProfile($value);
-
-  /**
-   * Returns the machine name of the profile.
-   *
-   * If the bundle doesn't use a profile, return the current site profile.
-   *
-   * @return string
-   *   THe machie name of a profile.
-   *
-   * @see \Drupal\features\FeaturesBundleInterface::setProfileName()
-   */
-  public function getProfileName();
-
-  /**
-   * Sets the name of the profile associated with this bundle.
-   *
-   * @param string $machine_name
-   *   The machine name of a profile.
-   *
-   * @see \Drupal\features\FeaturesBundleInterface::getProfileName()
-   */
-  public function setProfileName($machine_name);
-
-  /**
-   * Gets the list of enabled assignment methods.
-   *
-   * @return array
-   *   An array of method IDs keyed by assignment method IDs.
-   *
-   * @see \Drupal\features\FeaturesBundleInterface::setEnabledAssignments()
-   */
-  public function getEnabledAssignments();
-
-  /**
-   * Sets the list of enabled assignment methods.
-   *
-   * @param array $assignments
-   *   An array of values keyed by assignment method IDs. Non-empty value is
-   *   enabled.
-   *
-   * @see \Drupal\features\FeaturesBundleInterface::getEnabledAssignments()
-   */
-  public function setEnabledAssignments(array $assignments);
-
-  /**
-   * Gets the weights of the assignment methods.
-   *
-   * @return array
-   *   An array keyed by assignment method_id with a numeric weight.
-   *
-   * @see \Drupal\features\FeaturesBundleInterface::setAssignmentWeights()
-   */
-  public function getAssignmentWeights();
-
-  /**
-   * Sets the weights of the assignment methods.
-   *
-   * @param array $assignments
-   *   An array keyed by assignment method_id with a numeric weight value.
-   *
-   * @see \Drupal\features\FeaturesBundleInterface::getAssignmentWeights()
-   */
-  public function setAssignmentWeights(array $assignments);
-
-  /**
-   * Gets settings specific to an assignment method.
-   *
-   * @param string $method_id
-   *   The ID of an assignment method. If NULL, return all assignment settings
-   *   keyed by method_id.
-   *
-   * @return array
-   *   An array of settings. Format specific to assignment method.
-   *
-   * @see \Drupal\features\FeaturesBundleInterface::setAssignmentSettings()
-   */
-  public function getAssignmentSettings($method_id = NULL);
-
-  /**
-   * Sets settings specific to an assignment method.
-   *
-   * @param string $method_id
-   *   The ID of an assignment method. If NULL, all $settings are given keyed
-   *   by method_ID.
-   * @param array $settings
-   *   An array of setting values.
-   *
-   * @see \Drupal\features\FeaturesBundleInterface::getAssignmentSettings()
-   */
-  public function setAssignmentSettings($method_id, array $settings);
-
-  /**
-   * Saves the bundle to the active config.
-   */
-  public function save();
-
-  /**
-   * Removes the bundle from the active config.
-   */
-  public function remove();
-
-}
diff --git a/web/modules/features/src/FeaturesConfigDependencyManager.php b/web/modules/features/src/FeaturesConfigDependencyManager.php
deleted file mode 100644
index ea01e305cd632464df1916d1e27b4199d908e5f6..0000000000000000000000000000000000000000
--- a/web/modules/features/src/FeaturesConfigDependencyManager.php
+++ /dev/null
@@ -1,59 +0,0 @@
-<?php
-
-namespace Drupal\features;
-
-use Drupal\Core\Config\Entity\ConfigDependencyManager;
-use Drupal\Core\Config\Entity\ConfigEntityDependency;
-
-/**
- * Class FeaturesConfigDependencyManager
- * @package Drupal\features
- */
-class FeaturesConfigDependencyManager extends ConfigDependencyManager{
-
-  protected $sorted_graph;
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getDependentEntities($type, $name) {
-    $dependent_entities = [];
-
-    $entities_to_check = [];
-    if ($type == 'config') {
-      $entities_to_check[] = $name;
-    }
-    else {
-      if ($type == 'module' || $type == 'theme' || $type == 'content') {
-        $dependent_entities = array_filter($this->data, function (ConfigEntityDependency $entity) use ($type, $name) {
-          return $entity->hasDependency($type, $name);
-        });
-      }
-      // If checking content, module, or theme dependencies, discover which
-      // entities are dependent on the entities that have a direct dependency.
-      foreach ($dependent_entities as $entity) {
-        $entities_to_check[] = $entity->getConfigDependencyName();
-      }
-    }
-    $dependencies = array_merge($this->createGraphConfigEntityDependencies($entities_to_check), $dependent_entities);
-    if (!$this->sorted_graph) {
-      // Sort dependencies in the reverse order of the graph. So the least
-      // dependent is at the top. For example, this ensures that fields are
-      // 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, [$this, 'sortGraph']);
-    }
-    return array_replace(array_intersect_key($this->sorted_graph, $dependencies), $dependencies);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setData(array $data) {
-    parent::setData($data);
-    $this->sorted_graph = NULL;
-    return $this;
-  }
-
-}
diff --git a/web/modules/features/src/FeaturesConfigInstaller.php b/web/modules/features/src/FeaturesConfigInstaller.php
deleted file mode 100644
index da4c2a94170e885ec215bb6dc7e63e2da7a1a2fa..0000000000000000000000000000000000000000
--- a/web/modules/features/src/FeaturesConfigInstaller.php
+++ /dev/null
@@ -1,109 +0,0 @@
-<?php
-
-namespace Drupal\features;
-
-use Drupal\Core\Config\ConfigInstaller;
-use Drupal\Core\Config\ConfigInstallerInterface;
-use Drupal\Core\Config\ConfigFactoryInterface;
-use Drupal\Core\Config\StorageInterface;
-use Drupal\Core\Config\TypedConfigManagerInterface;
-use Drupal\Core\Config\ConfigManagerInterface;
-use Symfony\Component\EventDispatcher\EventDispatcherInterface;
-
-/**
- * Class for customizing the test for pre existing configuration.
- *
- * Decorates the ConfigInstaller with findPreExistingConfiguration() modified
- * to allow Feature modules to be installed.
- */
-class FeaturesConfigInstaller extends ConfigInstaller {
-
-  /**
-   * The configuration installer.
-   *
-   * @var \Drupal\Core\Config\ConfigInstallerInterface
-   */
-  protected $configInstaller;
-
-  /**
-   * The features manager.
-   *
-   * @var \Drupal\features\FeaturesManagerInterface
-   */
-  protected $featuresManager;
-
-  /**
-   * Constructs the configuration installer.
-   *
-   * @param \Drupal\Core\Config\ConfigInstallerInterface $config_installer
-   *    The configuration installer.
-   * @param \Drupal\features\FeaturesManagerInterface $features_manager
-   *    The features manager.
-   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
-   *   The configuration factory.
-   * @param \Drupal\Core\Config\StorageInterface $active_storage
-   *   The active configuration storage.
-   * @param \Drupal\Core\Config\TypedConfigManagerInterface $typed_config
-   *   The typed configuration manager.
-   * @param \Drupal\Core\Config\ConfigManagerInterface $config_manager
-   *   The configuration manager.
-   * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
-   *   The event dispatcher.
-   */
-  public function __construct(ConfigInstallerInterface $config_installer, FeaturesManagerInterface $features_manager, ConfigFactoryInterface $config_factory, StorageInterface $active_storage, TypedConfigManagerInterface $typed_config, ConfigManagerInterface $config_manager, EventDispatcherInterface $event_dispatcher) {
-    $this->configInstaller = $config_installer;
-    $this->featuresManager = $features_manager;
-
-    list($major, $minor, ) = explode('.', \Drupal::VERSION);
-    if ($major == 8 && $minor > 2) {
-      // D8.3 added the %install_profile% argument.
-      $install_profile = \Drupal::installProfile();
-      parent::__construct($config_factory, $active_storage, $typed_config, $config_manager, $event_dispatcher, $install_profile);
-    }
-    else {
-      parent::__construct($config_factory, $active_storage, $typed_config, $config_manager, $event_dispatcher);
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function findPreExistingConfiguration(StorageInterface $storage) {
-    // Override
-    // Drupal\Core\Config\ConfigInstaller::findPreExistingConfiguration().
-    // Allow config that already exists coming from Features.
-    $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 = [];
-    // Gather information about all the supported collections.
-    $collection_info = $this->configManager->getConfigCollectionInfo();
-
-    foreach ($collection_info->getCollectionNames() as $collection) {
-      $config_to_create = array_keys($this->getConfigToCreate($storage, $collection));
-      $active_storage = $this->getActiveStorages($collection);
-      foreach ($config_to_create as $config_name) {
-        if ($active_storage->exists($config_name)) {
-          // Test if config is part of a Feature package.
-          if (!isset($features_config[$config_name])) {
-            $existing_configuration[$collection][] = $config_name;
-          }
-        }
-      }
-    }
-    return $existing_configuration;
-  }
-
-  /**
-   * Creates configuration in a collection based on the provided list.
-   *
-   * @param string $collection
-   *   The configuration collection.
-   * @param array $config_to_create
-   *   An array of configuration data to create, keyed by name.
-   */
-  public function createConfiguration($collection, array $config_to_create) {
-    return parent::createConfiguration($collection, $config_to_create);
-  }
-
-}
diff --git a/web/modules/features/src/FeaturesExtensionStorages.php b/web/modules/features/src/FeaturesExtensionStorages.php
deleted file mode 100644
index 67dce968e62651ae79c5d4ffa63f8fce121bedb2..0000000000000000000000000000000000000000
--- a/web/modules/features/src/FeaturesExtensionStorages.php
+++ /dev/null
@@ -1,121 +0,0 @@
-<?php
-
-namespace Drupal\features;
-
-use Drupal\Core\Config\InstallStorage;
-use Drupal\Core\Config\StorageInterface;
-use Drupal\Core\Extension\Extension;
-
-/**
- * Wraps FeaturesInstallStorage to support multiple configuration
- * directories.
- */
-class FeaturesExtensionStorages implements FeaturesExtensionStoragesInterface {
-
-  /**
-   * The target storage.
-   *
-   * @var \Drupal\Core\Config\StorageInterface
-   */
-  protected $configStorage;
-
-  /**
-   * The extension storages.
-   *
-   * @var \Drupal\Core\Config\StorageInterface[]
-   */
-  protected $extensionStorages;
-
-  /**
-   * Configuration provided by extension storages.
-   *
-   * @var array
-   */
-  protected $configurationLists;
-
-  /**
-   * Constructs a new FeaturesExtensionStorages object.
-   *
-   * @param \Drupal\Core\Config\StorageInterface $config_storage
-   *   The configuration storage.
-   */
-  public function __construct(StorageInterface $config_storage) {
-    $this->configStorage = $config_storage;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getExtensionStorages() {
-    return $this->extensionStorages;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function addStorage($directory = InstallStorage::CONFIG_INSTALL_DIRECTORY) {
-    $this->extensionStorages[$directory] = new FeaturesInstallStorage($this->configStorage, $directory);
-    $this->reset();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function read($name) {
-    $list = $this->listAllByDirectory('');
-    if (isset($list[$name])) {
-      $directory = $list[$name];
-      return $this->extensionStorages[$directory]->read($name);
-    }
-    return FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function listAll($prefix = '') {
-    return array_keys($this->listAllByDirectory($prefix));
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function listExtensionConfig(Extension $extension) {
-    $extension_config = [];
-    foreach ($this->extensionStorages as $directory => $extension_storage) {
-      $extension_config = array_merge($extension_config, array_keys($extension_storage->getComponentNames([
-        $extension->getName() => $extension,
-      ])));
-    }
-    return $extension_config;
-  }
-
-  /**
-   * Resets packages and configuration assignment.
-   */
-  protected function reset() {
-    $this->configurationLists = [];
-  }
-
-  /**
-   * Returns a list of all configuration available from extensions.
-   *
-   * @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.
-   */
-  protected 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/FeaturesExtensionStoragesByDirectory.php b/web/modules/features/src/FeaturesExtensionStoragesByDirectory.php
deleted file mode 100644
index 6c0269e9e106967e369fdcb9c119821d65398015..0000000000000000000000000000000000000000
--- a/web/modules/features/src/FeaturesExtensionStoragesByDirectory.php
+++ /dev/null
@@ -1,24 +0,0 @@
-<?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
deleted file mode 100644
index e955cecce3cf26963ffd77c5a72ce6e2f7ea0c74..0000000000000000000000000000000000000000
--- a/web/modules/features/src/FeaturesExtensionStoragesByDirectoryInterface.php
+++ /dev/null
@@ -1,26 +0,0 @@
-<?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/FeaturesExtensionStoragesInterface.php b/web/modules/features/src/FeaturesExtensionStoragesInterface.php
deleted file mode 100644
index a48ebd0e5857653166486ac32cc5ef37bb136ee3..0000000000000000000000000000000000000000
--- a/web/modules/features/src/FeaturesExtensionStoragesInterface.php
+++ /dev/null
@@ -1,87 +0,0 @@
-<?php
-
-namespace Drupal\features;
-
-use Drupal\Core\Config\InstallStorage;
-use Drupal\Core\Extension\Extension;
-
-/**
- * The FeaturesExtensionStorages provides a collection of extension storages,
- * one for each supported configuration directory.
- *
- * Typically this will include the install and optional directories defined by
- * Drupal core, but may also include any extension configuration directories
- * added by contributed modules.
- *
- * This class serves as a partial wrapper to
- * Drupal\Core\Config\StorageInterface, providing a subset of methods that can
- * be called to apply to all available extension storages. For example,
- * FeaturesExtensionStoragesInterface::read() will read an extension-provided
- * configuration item regardless of which extension storage directory it is
- * provided in.
- */
-interface FeaturesExtensionStoragesInterface {
-
-  /**
-   * Returns all registered extension storages.
-   *
-   * @return FeaturesInstallStorage[]
-   *   Array of install storages keyed by configuration directory.
-   */
-  public function getExtensionStorages();
-
-  /**
-   * Adds a storage.
-   *
-   * @param string $directory
-   *   (optional) The configuration directory. If omitted,
-   *   InstallStorage::CONFIG_INSTALL_DIRECTORY will be used.
-   */
-  public function addStorage($directory = InstallStorage::CONFIG_INSTALL_DIRECTORY);
-
-  /**
-   * Reads configuration data from the storages.
-   *
-   * @param string $name
-   *   The name of a configuration object to load.
-   *
-   * @return array|bool
-   *   The configuration data stored for the configuration object name. If no
-   *   configuration data exists for the given name, FALSE is returned.
-   */
-  public function read($name);
-
-  /**
-   * Gets configuration object names starting with a given prefix.
-   *
-   * Given the following configuration objects:
-   * - node.type.article
-   * - node.type.page
-   *
-   * Passing the prefix 'node.type.' will return an array containing the above
-   * names.
-   *
-   * @param string $prefix
-   *   (optional) The prefix to search for. If omitted, all configuration object
-   *   names that exist are returned.
-   *
-   * @return array
-   *   An array containing matching configuration object names.
-   */
-  public function listAll($prefix = '');
-
-  /**
-   * Lists names of configuration objects provided by a given extension.
-   *
-   * If a $name and/or $namespace is specified, only matching modules will be
-   * returned. Otherwise, all install are returned.
-   *
-   * @param mixed $extension
-   *   A string name of an extension or a full Extension object.
-   *
-   * @return array
-   *   An array of configuration object names.
-   */
-  public function listExtensionConfig(Extension $extension);
-
-}
diff --git a/web/modules/features/src/FeaturesGenerationMethodBase.php b/web/modules/features/src/FeaturesGenerationMethodBase.php
deleted file mode 100644
index e329f686399b02c82aa7c24daab9566d8a062145..0000000000000000000000000000000000000000
--- a/web/modules/features/src/FeaturesGenerationMethodBase.php
+++ /dev/null
@@ -1,111 +0,0 @@
-<?php
-
-namespace Drupal\features;
-
-use Drupal\Component\Serialization\Yaml;
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\StringTranslation\StringTranslationTrait;
-
-/**
- * Base class for package assignment methods.
- */
-abstract class FeaturesGenerationMethodBase implements FeaturesGenerationMethodInterface {
-  use StringTranslationTrait;
-
-  /**
-   * The features manager.
-   *
-   * @var \Drupal\features\FeaturesManagerInterface
-   */
-  protected $featuresManager;
-
-  /**
-   * The features assigner.
-   *
-   * @var \Drupal\features\FeaturesAssignerInterface
-   */
-  protected $assigner;
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setFeaturesManager(FeaturesManagerInterface $features_manager) {
-    $this->featuresManager = $features_manager;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setAssigner(FeaturesAssignerInterface $assigner) {
-    $this->assigner = $assigner;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function exportFormSubmit(array &$form, FormStateInterface $form_state) {
-
-  }
-
-  /**
-   * Merges an info file into a package's info file.
-   *
-   * @param string $package_info
-   *   The Yaml encoded package info.
-   * @param string $info_file_uri
-   *   The info file's URI.
-   */
-  protected function mergeInfoFile($package_info, $info_file_uri) {
-    $package_info = Yaml::decode($package_info);
-    /** @var \Drupal\Core\Extension\InfoParserInterface $existing_info */
-    $existing_info = \Drupal::service('info_parser')->parse($info_file_uri);
-    return Yaml::encode($this->featuresManager->mergeInfoArray($existing_info, $package_info));
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function prepare(array &$packages = [], FeaturesBundleInterface $bundle = NULL) {
-    // If no packages were specified, get all packages.
-    if (empty($packages)) {
-      $packages = $this->featuresManager->getPackages();
-    }
-
-    // If any packages exist, read in their files.
-    $existing_packages = $this->featuresManager->listPackageDirectories(array_keys($packages), $bundle);
-
-    foreach ($packages as &$package) {
-      list($full_name, $path) = $this->featuresManager->getExportInfo($package, $bundle);
-      if (empty($package->getDirectory())) {
-        $package->setDirectory($path);
-      }
-
-      // If this is the profile, its directory is already assigned.
-      if (!isset($bundle) || !$bundle->isProfilePackage($package->getMachineName())) {
-        $current_path = $package->getDirectory();
-        if (strpos($current_path, $full_name) < strlen($current_path) - strlen($full_name)) {
-          // Only append package name if it isn't already there.
-          $package->setDirectory($package->getDirectory() . '/' . $full_name);
-        }
-      }
-
-      $this->preparePackage($package, $existing_packages, $bundle);
-    }
-    // Clean up the $package pass by reference.
-    unset($package);
-  }
-
-  /**
-   * Performs any required changes on a package prior to generation.
-   *
-   * @param \Drupal\features\Package $package
-   *   The package to be prepared.
-   * @param array $existing_packages
-   *   An array of existing packages with machine names as keys and paths as
-   *   values.
-   * @param \Drupal\features\FeaturesBundleInterface $bundle
-   *   Optional bundle used for export
-   */
-  abstract protected function preparePackage(Package $package, array $existing_packages, FeaturesBundleInterface $bundle = NULL);
-
-}
diff --git a/web/modules/features/src/FeaturesGenerationMethodInterface.php b/web/modules/features/src/FeaturesGenerationMethodInterface.php
deleted file mode 100644
index 92b939280492a9e1d18342ad6f026ca991f9fdc8..0000000000000000000000000000000000000000
--- a/web/modules/features/src/FeaturesGenerationMethodInterface.php
+++ /dev/null
@@ -1,67 +0,0 @@
-<?php
-
-namespace Drupal\features;
-
-use Drupal\Core\Form\FormStateInterface;
-
-/**
- * Interface for package assignment classes.
- */
-interface FeaturesGenerationMethodInterface {
-
-  /**
-   * Injects the features manager.
-   *
-   * @param \Drupal\features\FeaturesManagerInterface $features_manager
-   *   The features manager to be used to retrieve the configuration
-   *   list and the assigned packages.
-   */
-  public function setFeaturesManager(FeaturesManagerInterface $features_manager);
-
-  /**
-   * Injects the features assigner.
-   *
-   * @param \Drupal\features\FeaturesAssignerInterface $assigner
-   *   The features assigner to be used to retrieve the bundle configuration.
-   */
-  public function setAssigner(FeaturesAssignerInterface $assigner);
-
-  /**
-   * Prepares packages for generation.
-   *
-   * @param array $packages
-   *   Array of package data.
-   * @param \Drupal\features\FeaturesBundleInterface $bundle
-   *   The optional bundle used for the generation.  Used to generate profiles.
-   *
-   * @return array
-   *   An array of packages data.
-   */
-  public function prepare(array &$packages = [], FeaturesBundleInterface $bundle = NULL);
-
-  /**
-   * Performs package generation.
-   *
-   * @param array $packages
-   *   Array of package data.
-   * @param \Drupal\features\FeaturesBundleInterface $bundle
-   *   The optional bundle used for the generation.  Used to generate profiles.
-   *
-   * @return array
-   *   Array of results for profile and/or packages, each result including the
-   *   following keys:
-   *   - 'success': boolean TRUE or FALSE for successful writing.
-   *   - 'display': boolean TRUE if the message should be displayed to the
-   *     user, otherwise FALSE.
-   *   - '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 = [], FeaturesBundleInterface $bundle = NULL);
-
-  /**
-   * Responds to the submission of
-   * \Drupal\features_ui\Form\FeaturesExportForm.
-   */
-  public function exportFormSubmit(array &$form, FormStateInterface $form_state);
-
-}
diff --git a/web/modules/features/src/FeaturesGenerationMethodManager.php b/web/modules/features/src/FeaturesGenerationMethodManager.php
deleted file mode 100644
index 9ede58e60801a508f86702d42a0d09147f521ff2..0000000000000000000000000000000000000000
--- a/web/modules/features/src/FeaturesGenerationMethodManager.php
+++ /dev/null
@@ -1,33 +0,0 @@
-<?php
-
-namespace Drupal\features;
-
-use Drupal\Core\Cache\CacheBackendInterface;
-use Drupal\Core\Extension\ModuleHandlerInterface;
-use Drupal\Core\Plugin\DefaultPluginManager;
-
-/**
- * Manages configuration packaging methods.
- */
-class FeaturesGenerationMethodManager extends DefaultPluginManager {
-
-  /**
-   * Constructs a new FeaturesGenerationMethodManager object.
-   *
-   * @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
-   *   An object that implements CacheBackendInterface.
-   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
-   *   An object that implements ModuleHandlerInterface.
-   */
-  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
-    parent::__construct('Plugin/FeaturesGeneration', $namespaces, $module_handler, 'Drupal\features\FeaturesGenerationMethodInterface');
-    $this->cacheBackend = $cache_backend;
-    $this->cacheKeyPrefix = 'features_generation_methods';
-    $this->cacheKey = 'features_generation_methods';
-    $this->alterInfo('features_generation_info');
-  }
-
-}
diff --git a/web/modules/features/src/FeaturesGenerator.php b/web/modules/features/src/FeaturesGenerator.php
deleted file mode 100644
index ae21e60b7a04a1a3e29bde734740246ec21571ee..0000000000000000000000000000000000000000
--- a/web/modules/features/src/FeaturesGenerator.php
+++ /dev/null
@@ -1,173 +0,0 @@
-<?php
-
-namespace Drupal\features;
-
-use Drupal\Component\Plugin\PluginManagerInterface;
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\StringTranslation\StringTranslationTrait;
-
-/**
- * Class responsible for performing package generation.
- */
-class FeaturesGenerator implements FeaturesGeneratorInterface {
-  use StringTranslationTrait;
-
-  /**
-   * The package generation method plugin manager.
-   *
-   * @var \Drupal\Component\Plugin\PluginManagerInterface
-   */
-  protected $generatorManager;
-
-  /**
-   * The features manager.
-   *
-   * @var \Drupal\features\FeaturesManagerInterface
-   */
-  protected $featuresManager;
-
-  /**
-   * The features assigner.
-   *
-   * @var \Drupal\features\FeaturesAssignerInterface
-   */
-  protected $assigner;
-
-  /**
-   * Local cache for package generation method instances.
-   *
-   * @var array
-   */
-  protected $methods;
-
-  /**
-   * Constructs a new FeaturesGenerator object.
-   *
-   * @param \Drupal\features\FeaturesManagerInterface $features_manager
-   *    The features manager.
-   * @param \Drupal\Component\Plugin\PluginManagerInterface $generator_manager
-   *   The package generation methods plugin manager.
-   */
-  public function __construct(FeaturesManagerInterface $features_manager, PluginManagerInterface $generator_manager, FeaturesAssignerInterface $assigner) {
-    $this->featuresManager = $features_manager;
-    $this->generatorManager = $generator_manager;
-    $this->assigner = $assigner;
-  }
-
-  /**
-   * Initializes the injected features manager with the generator.
-   *
-   * This should be called right after instantiating the generator to make it
-   * available to the features manager without introducing a circular
-   * dependency.
-   */
-  public function initFeaturesManager() {
-    $this->featuresManager->setGenerator($this);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function reset() {
-    $this->methods = [];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function applyGenerationMethod($method_id, array $packages = [], FeaturesBundleInterface $bundle = NULL) {
-    $method = $this->getGenerationMethodInstance($method_id);
-    $method->prepare($packages, $bundle);
-    return $method->generate($packages, $bundle);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function applyExportFormSubmit($method_id, &$form, FormStateInterface $form_state) {
-    $method = $this->getGenerationMethodInstance($method_id);
-    $method->exportFormSubmit($form, $form_state);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getGenerationMethods() {
-    return $this->generatorManager->getDefinitions();
-  }
-
-  /**
-   * Returns an instance of the specified package generation method.
-   *
-   * @param string $method_id
-   *   The string identifier of the package generation method to use to package
-   *   configuration.
-   *
-   * @return \Drupal\features\FeaturesGenerationMethodInterface
-   */
-  protected function getGenerationMethodInstance($method_id) {
-    if (!isset($this->methods[$method_id])) {
-      $instance = $this->generatorManager->createInstance($method_id, []);
-      $instance->setFeaturesManager($this->featuresManager);
-      $instance->setAssigner($this->assigner);
-      $this->methods[$method_id] = $instance;
-    }
-    return $this->methods[$method_id];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function generatePackages($method_id, FeaturesBundleInterface $bundle, array $package_names = []) {
-    $this->featuresManager->setPackageBundleNames($bundle, $package_names);
-    return $this->generate($method_id, $bundle, $package_names);
-  }
-
-  /**
-   * Generates a file representation of configuration packages and, optionally,
-   * an install profile.
-   *
-   * @param string $method_id
-   *   The ID of the generation method to use.
-   * @param \Drupal\features\FeaturesBundleInterface $bundle
-   *   The bundle used for the generation.
-   * @param string[] $package_names
-   *   Names of packages to be generated. If none are specified, all
-   *   available packages will be added.
-   *
-   * @return array
-   *   Array of results for profile and/or packages, each result including the
-   *   following keys:
-   *   - 'success': boolean TRUE or FALSE for successful writing.
-   *   - 'display': boolean TRUE if the message should be displayed to the
-   *     user, otherwise FALSE.
-   *   - '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 = []) {
-    $packages = $this->featuresManager->getPackages();
-
-    // Filter out the packages that weren't requested.
-    if (!empty($package_names)) {
-      $packages = array_intersect_key($packages, array_fill_keys($package_names, NULL));
-    }
-
-    $this->featuresManager->assignInterPackageDependencies($bundle, $packages);
-
-    // Prepare the files.
-    $this->featuresManager->prepareFiles($packages);
-
-    $return = $this->applyGenerationMethod($method_id, $packages, $bundle);
-
-    foreach ($return as $message) {
-      if ($message['display']) {
-        $type = $message['success'] ? 'status' : 'error';
-        drupal_set_message($this->t($message['message'], $message['variables']), $type);
-      }
-      $type = $message['success'] ? 'notice' : 'error';
-      \Drupal::logger('features')->{$type}($message['message'], $message['variables']);
-    }
-    return $return;
-  }
-
-}
diff --git a/web/modules/features/src/FeaturesGeneratorInterface.php b/web/modules/features/src/FeaturesGeneratorInterface.php
deleted file mode 100644
index 0cafa145143558b25bc3ebd1c92b73a89c3b2b06..0000000000000000000000000000000000000000
--- a/web/modules/features/src/FeaturesGeneratorInterface.php
+++ /dev/null
@@ -1,103 +0,0 @@
-<?php
-
-namespace Drupal\features;
-
-use Drupal\Core\Form\FormStateInterface;
-
-/**
- * Common interface for features generation services.
- *
- * The configuration packaging API is based on two major concepts:
- * - Packages: modules into which configuration is packaged.
- * - Package generation methods: responsible for `determining
- *   which package to assign a given piece of configuration to.
- * Generation methods are customizable.
- *
- * Features defines two package generation methods, which are simple plugin
- * classes that implement a particular logic to assign pieces of configuration
- * to a given package (module).
- *
- * Modules can define additional package generation methods by simply providing
- * the related plugins, and alter existing methods through
- * hook_features_generation_method_info_alter(). Here is an example
- * snippet:
- * @code
- * function mymodule_features_generation_method_info_alter(&$generation_info) {
- *   // Replace the original plugin with our own implementation.
- *   $method_id = \Drupal\features\Plugin\FeaturesGeneration\FeaturesGenerationArchive::METHOD_ID;
- *   $generation_info[$method_id]['class'] = 'Drupal\my_module\Plugin\FeaturesGeneration\MyFeaturesGenerationArchive';
- * }
- *
- * class MyFeaturesGenerationArchive extends FeaturesGenerationArchive {
- *   public function generate(array $packages = array(), FeaturesBundleInterface $bundle = NULL) {
- *     // Insert customization here.
- *   }
- * }
- * ?>
- * @endcode
- *
- * For more information, see
- * @link http://drupal.org/node/2404473 Developing for Features 3.x @endlink
- */
-interface FeaturesGeneratorInterface {
-
-  /**
-   * The package generation method id for the package generator itself.
-   */
-  const METHOD_ID = 'generator-default';
-
-  /**
-   * Resets the assigned packages and the method instances.
-   */
-  public function reset();
-
-  /**
-   * Apply a given package generation method.
-   *
-   * @param string $method_id
-   *   The string identifier of the package generation method to use to package
-   *   configuration.
-   * @param array $packages
-   *   Array of package data.
-   * @param \Drupal\features\FeaturesBundleInterface $bundle
-   *   The optional bundle used for the generation.  Used to generate profiles.
-   *
-   * @return array
-   *   Array of results for profile and/or packages, each result including the
-   *   following keys:
-   *   - 'success': boolean TRUE or FALSE for successful writing.
-   *   - 'display': boolean TRUE if the message should be displayed to the
-   *     user, otherwise FALSE.
-   *   - '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 = [], FeaturesBundleInterface $bundle = NULL);
-
-  /**
-   * Responds to the submission of
-   * \Drupal\features_ui\Form\FeaturesExportForm.
-   */
-  public function applyExportFormSubmit($method_id, &$form, FormStateInterface $form_state);
-
-  /**
-   * Returns the enabled package generation methods.
-   *
-   * @return array
-   *   An array of package generation method definitions keyed by method id.
-   */
-  public function getGenerationMethods();
-
-  /**
-   * Generates file representations of configuration packages.
-   *
-   * @param string $method_id
-   *   The ID of the generation method to use.
-   * @param \Drupal\features\FeaturesBundleInterface $bundle
-   *   The bundle used for the generation.
-   * @param array $package_names
-   *   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 = []);
-
-}
diff --git a/web/modules/features/src/FeaturesInstallStorage.php b/web/modules/features/src/FeaturesInstallStorage.php
deleted file mode 100644
index 666b5d6803ded4287a04628bcda123e08d9c7535..0000000000000000000000000000000000000000
--- a/web/modules/features/src/FeaturesInstallStorage.php
+++ /dev/null
@@ -1,163 +0,0 @@
-<?php
-
-namespace Drupal\features;
-
-use Drupal\Core\Site\Settings;
-use Drupal\Core\Config\ExtensionInstallStorage;
-use Drupal\Core\Config\StorageInterface;
-use Drupal\Core\Extension\ExtensionDiscovery;
-
-/**
- * Storage to access configuration and schema in installed extensions.
- *
- * Overrides the normal ExtensionInstallStorage to prevent profile from
- * overriding.
- *
- * Also supports modules that are not installed yet.
- *
- * @see \Drupal\Core\Config\ExtensionInstallStorage
- */
-class FeaturesInstallStorage extends ExtensionInstallStorage {
-
-  /**
-   * Overrides \Drupal\Core\Config\ExtensionInstallStorage::__construct().
-   *
-   * Sets includeProfile to FALSE.
-   *
-   * @param \Drupal\Core\Config\StorageInterface $config_storage
-   *   The active configuration store where the list of installed modules and
-   *   themes is stored.
-   * @param string $directory
-   *   The directory to scan in each extension to scan for files. Defaults to
-   *   'config/install'.
-   * @param string $collection
-   *   (optional) The collection to store configuration in. Defaults to the
-   *   default collection.
-   */
-  public function __construct(StorageInterface $config_storage, $directory = self::CONFIG_INSTALL_DIRECTORY, $collection = StorageInterface::DEFAULT_COLLECTION) {
-    list($major, $minor, ) = explode('.', \Drupal::VERSION);
-    if ($major == 8 && $minor > 2) {
-      // D8.3 added the %profile% argument.
-      $profile = \Drupal::installProfile();
-      parent::__construct($config_storage, $directory, $collection, FALSE, $profile);
-    }
-    else {
-      parent::__construct($config_storage, $directory, $collection, FALSE);
-    }
-  }
-
-  /**
-   * Returns a map of all config object names and their folders.
-   *
-   * The list is based on installed modules and themes. The active
-   * configuration storage is used rather than
-   * \Drupal\Core\Extension\ModuleHandler and
-   * \Drupal\Core\Extension\ThemeHandler in order to resolve circular
-   * dependencies between these services and
-   * \Drupal\Core\Config\ConfigInstaller and
-   * \Drupal\Core\Config\TypedConfigManager.
-   *
-   * NOTE: This code is copied from ExtensionInstallStorage::getAllFolders() with
-   * the following changes (Notes in CHANGED below)
-   *   - Load all modules whether installed or not
-   *
-   * @return array
-   *   An array mapping config object names with directories.
-   */
-  public function getAllFolders() {
-    if (!isset($this->folders)) {
-      $this->folders = [];
-      $this->folders += $this->getCoreNames();
-
-      $install_profile = Settings::get('install_profile');
-      $profile = drupal_get_profile();
-      $extensions = $this->configStorage->read('core.extension');
-      // @todo Remove this scan as part of https://www.drupal.org/node/2186491
-      $listing = new ExtensionDiscovery(\Drupal::root());
-
-      // CHANGED START: Add profile directories for any bundles that use a profile.
-      $listing->setProfileDirectoriesFromSettings();
-      $profile_directories = $listing->getProfileDirectories();
-      if ($this->includeProfile) {
-        // Add any profiles used in bundles.
-        /** @var \Drupal\features\FeaturesAssignerInterface $assigner */
-        $assigner = \Drupal::service('features_assigner');
-        $bundles = $assigner->getBundleList();
-        foreach ($bundles as $bundle_name => $bundle) {
-          if ($bundle->isProfile()) {
-            // Register the profile directory.
-            $profile_directory = 'profiles/' . $bundle->getProfileName();
-            if (is_dir($profile_directory)) {
-              $profile_directories[] = $profile_directory;
-            }
-          }
-        }
-      }
-      $listing->setProfileDirectories($profile_directories);
-      // CHANGED END
-
-      if (!empty($extensions['module'])) {
-
-        // CHANGED START: Find ANY modules, not just installed ones.
-        //$modules = $extensions['module'];
-        $module_list_scan = $listing->scan('module');
-        $modules = $module_list_scan;
-        // CHANGED END
-
-        // Remove the install profile as this is handled later.
-        unset($modules[$install_profile]);
-        $profile_list = $listing->scan('profile');
-        if ($profile && isset($profile_list[$profile])) {
-          // Prime the drupal_get_filename() static cache with the profile info
-          // file location so we can use drupal_get_path() on the active profile
-          // during the module scan.
-          // @todo Remove as part of https://www.drupal.org/node/2186491
-          drupal_get_filename('profile', $profile, $profile_list[$profile]->getPathname());
-        }
-        // 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 = [];
-        $module_list = [];
-        foreach (array_keys($module_list_scan) as $module) {
-          if ($featuresManager->isFeatureModule($module_list_scan[$module])) {
-            $features_list[$module] = $module_list_scan[$module];
-          }
-          else {
-            $module_list[$module] = $module_list_scan[$module];
-          }
-        }
-        $this->folders += $this->getComponentNames($features_list);
-        $this->folders += $this->getComponentNames($module_list);
-        // CHANGED END
-      }
-      if (!empty($extensions['theme'])) {
-        $theme_list_scan = $listing->scan('theme');
-        foreach (array_keys($extensions['theme']) as $theme) {
-          if (isset($theme_list_scan[$theme])) {
-            $theme_list[$theme] = $theme_list_scan[$theme];
-          }
-        }
-        $this->folders += $this->getComponentNames($theme_list);
-      }
-
-      if ($this->includeProfile) {
-        // The install profile can override module default configuration. We do
-        // this by replacing the config file path from the module/theme with the
-        // install profile version if there are any duplicates.
-        if (isset($profile)) {
-          if (!isset($profile_list)) {
-            $profile_list = $listing->scan('profile');
-          }
-          if (isset($profile_list[$profile])) {
-            $profile_folders = $this->getComponentNames([$profile_list[$profile]]);
-            $this->folders = $profile_folders + $this->folders;
-          }
-        }
-      }
-    }
-
-    return $this->folders;
-  }
-
-}
diff --git a/web/modules/features/src/FeaturesManager.php b/web/modules/features/src/FeaturesManager.php
deleted file mode 100644
index 07c46e0427855f187db15011ff2c764c1c941a29..0000000000000000000000000000000000000000
--- a/web/modules/features/src/FeaturesManager.php
+++ /dev/null
@@ -1,1399 +0,0 @@
-<?php
-
-namespace Drupal\features;
-use Drupal;
-use Drupal\Component\Serialization\Yaml;
-use Drupal\Component\Utility\NestedArray;
-use Drupal\Core\Config\ConfigFactoryInterface;
-use Drupal\Core\Config\ConfigManagerInterface;
-use Drupal\Core\Config\InstallStorage;
-use Drupal\Core\Config\StorageInterface;
-use Drupal\Core\Entity\EntityTypeManagerInterface;
-use Drupal\Core\Entity\EntityTypeInterface;
-use Drupal\Core\Extension\Extension;
-use Drupal\Core\Extension\ExtensionDiscovery;
-use Drupal\Core\Extension\ModuleHandlerInterface;
-use Drupal\Core\StringTranslation\StringTranslationTrait;
-use Drupal\config_update\ConfigRevertInterface;
-
-/**
- * The FeaturesManager provides helper functions for building packages.
- */
-class FeaturesManager implements FeaturesManagerInterface {
-  use StringTranslationTrait;
-
-  /**
-   * The entity type manager.
-   *
-   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
-   */
-  protected $entityTypeManager;
-
-  /**
-   * The target storage.
-   *
-   * @var \Drupal\Core\Config\StorageInterface
-   */
-  protected $configStorage;
-
-  /**
-   * The extension storages.
-   *
-   * @var \Drupal\features\FeaturesExtensionStoragesByDirectoryInterface
-   */
-  protected $extensionStorages;
-
-  /**
-   * The configuration manager.
-   *
-   * @var \Drupal\Core\Config\ConfigManagerInterface
-   */
-  protected $configManager;
-
-  /**
-   * The configuration factory.
-   *
-   * @var \Drupal\Core\Config\ConfigFactoryInterface
-   */
-  protected $configFactory;
-
-  /**
-   * The module handler.
-   *
-   * @var \Drupal\Core\Extension\ModuleHandlerInterface
-   */
-  protected $moduleHandler;
-
-  /**
-   * The config reverter.
-   *
-   * @var \Drupal\config_update\ConfigRevertInterface
-   */
-  protected $configReverter;
-
-  /**
-   * The Features settings.
-   *
-   * @var array
-   */
-  protected $settings;
-
-  /**
-   * The app root.
-   *
-   * @var string
-   */
-  protected $root;
-
-  /**
-   * The configuration present on the site.
-   *
-   * @var \Drupal\features\ConfigurationItem[]
-   */
-  private $configCollection;
-
-  /**
-   * The packages to be generated.
-   *
-   * @var \Drupal\features\Package[]
-   */
-  protected $packages;
-
-  /**
-   * Whether the packages have been assigned a bundle prefix.
-   *
-   * @var boolean
-   */
-  protected $packagesPrefixed;
-
-  /**
-   * The package assigner.
-   *
-   * @var \Drupal\features\FeaturesAssigner
-   */
-  protected $assigner;
-
-  /**
-   * Cache module.features.yml data keyed by module name.
-   *
-   * @var array
-   */
-  protected $featureInfoCache;
-
-  /**
-   * Constructs a FeaturesManager object.
-   *
-   * @param string $root
-   *   The app root.
-   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
-   *   The entity type manager.
-   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
-   *   The configuration factory.
-   * @param \Drupal\Core\Config\StorageInterface $config_storage
-   *   The target storage.
-   * @param \Drupal\Core\Config\ConfigManagerInterface $config_manager
-   *   The configuration manager.
-   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
-   *   The module handler.
-   * @param \Drupal\config_update\ConfigRevertInterface $config_reverter
-   */
-  public function __construct($root, EntityTypeManagerInterface $entity_type_manager, ConfigFactoryInterface $config_factory,
-                              StorageInterface $config_storage, ConfigManagerInterface $config_manager,
-                              ModuleHandlerInterface $module_handler, ConfigRevertInterface $config_reverter) {
-    $this->root = $root;
-    $this->entityTypeManager = $entity_type_manager;
-    $this->configStorage = $config_storage;
-    $this->configManager = $config_manager;
-    $this->moduleHandler = $module_handler;
-    $this->configFactory = $config_factory;
-    $this->configReverter = $config_reverter;
-    $this->settings = $config_factory->getEditable('features.settings');
-    $this->extensionStorages = new FeaturesExtensionStoragesByDirectory($this->configStorage);
-    $this->extensionStorages->addStorage(InstallStorage::CONFIG_INSTALL_DIRECTORY);
-    $this->extensionStorages->addStorage(InstallStorage::CONFIG_OPTIONAL_DIRECTORY);
-    $this->packages = [];
-    $this->packagesPrefixed = FALSE;
-    $this->configCollection = [];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setRoot($root) {
-    $this->root = $root;
-    // Clear cache.
-    $this->featureInfoCache = [];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getActiveStorage() {
-    return $this->configStorage;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getExtensionStorages() {
-    return $this->extensionStorages;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFullName($type, $name) {
-    if ($type == FeaturesManagerInterface::SYSTEM_SIMPLE_CONFIG || !$type) {
-      return $name;
-    }
-
-    $definition = $this->entityTypeManager->getDefinition($type);
-    $prefix = $definition->getConfigPrefix() . '.';
-    return $prefix . $name;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getConfigType($fullname) {
-    $result = [
-      'type' => '',
-      'name_short' => '',
-    ];
-    $prefix = FeaturesManagerInterface::SYSTEM_SIMPLE_CONFIG . '.';
-    if (strpos($fullname, $prefix) !== FALSE) {
-      $result['type'] = FeaturesManagerInterface::SYSTEM_SIMPLE_CONFIG;
-      $result['name_short'] = substr($fullname, strlen($prefix));
-    }
-    else {
-      foreach ($this->entityTypeManager->getDefinitions() as $entity_type => $definition) {
-        if ($definition->isSubclassOf('Drupal\Core\Config\Entity\ConfigEntityInterface')) {
-          $prefix = $definition->getConfigPrefix() . '.';
-          if (strpos($fullname, $prefix) === 0) {
-            $result['type'] = $entity_type;
-            $result['name_short'] = substr($fullname, strlen($prefix));
-          }
-        }
-      }
-    }
-    return $result;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function reset() {
-    $this->packages = [];
-    // Don't use getConfigCollection because reset() may be called in
-    // cases where we don't need to load config.
-    foreach ($this->configCollection as $config) {
-      $config->setPackage(NULL);
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getConfigCollection($reset = FALSE) {
-    $this->initConfigCollection($reset);
-    return $this->configCollection;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setConfigCollection(array $config_collection) {
-    $this->configCollection = $config_collection;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getPackages() {
-    return $this->packages;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setPackages(array $packages) {
-    $this->packages = $packages;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getPackage($machine_name) {
-    if (isset($this->packages[$machine_name])) {
-      return $this->packages[$machine_name];
-    }
-    return NULL;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function findPackage($machine_name) {
-    $result = $this->getPackage($machine_name);
-    if (!isset($result)) {
-      // Didn't find direct match, but now go through and look for matching
-      // full name (bundle_machinename)
-      foreach ($this->packages as $name => $package) {
-        if ($package->getFullName() == $machine_name) {
-          return $this->packages[$name];
-        }
-      }
-    }
-    return $result;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setPackage(Package $package) {
-    if ($package->getMachineName()) {
-      $this->packages[$package->getMachineName()] = $package;
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function loadPackage($module_name, $any = FALSE) {
-    $package = $this->getPackage($module_name);
-    // Load directly from module if packages are not loaded or
-    // if we want to include ANY module regardless of its a feature.
-    if ((empty($this->packages) || $any) && !isset($package)) {
-      $module_list = $this->moduleHandler->getModuleList();
-      if (!empty($module_list[$module_name])) {
-        $extension = $module_list[$module_name];
-        $package = $this->initPackageFromExtension($extension);
-        $config = $this->listExtensionConfig($extension);
-        $package->setConfigOrig($config);
-        $package->setStatus(FeaturesManagerInterface::STATUS_INSTALLED);
-      }
-    }
-    return $package;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function filterPackages(array $packages, $namespace = '', $only_exported = FALSE) {
-    $result = [];
-    /** @var \Drupal\features\Package $package */
-    foreach ($packages as $key => $package) {
-      // A package matches the namespace if:
-      // - it's prefixed with the namespace, or
-      // - it's assigned to a bundle named for the namespace, or
-      // - the namespace is the default bundle and it has an empty bundle, and
-      // - we're not removing only exported packages, or
-      // - we are removing only exported packages and it's not exported.
-      if ((strpos($package->getMachineName(), $namespace . '_') === 0 ||
-        ($package->getBundle() && $package->getBundle() === $namespace) ||
-        ($namespace === FeaturesBundleInterface::DEFAULT_BUNDLE && empty($package->getBundle()))) &&
-        (!$only_exported || ($package->getStatus() === FeaturesManagerInterface::STATUS_NO_EXPORT))) {
-        $result[$key] = $package;
-      }
-    }
-    return $result;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getAssigner() {
-    if (empty($this->assigner)) {
-      $this->setAssigner(\Drupal::service('features_assigner'));
-    }
-    return $this->assigner;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setAssigner(FeaturesAssignerInterface $assigner) {
-    $this->assigner = $assigner;
-    $this->reset();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getGenerator() {
-    return $this->generator;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setGenerator(FeaturesGeneratorInterface $generator) {
-    $this->generator = $generator;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getExportSettings() {
-    return $this->settings->get('export');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getSettings() {
-    return $this->settings;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getExtensionInfo(Extension $extension) {
-    return \Drupal::service('info_parser')->parse($this->root . '/' . $extension->getPathname());
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isFeatureModule(Extension $module, FeaturesBundleInterface $bundle = NULL) {
-    if ($features_info = $this->getFeaturesInfo($module)) {
-      // If no bundle was requested, it's enough that this is a feature.
-      if (is_null($bundle)) {
-        return TRUE;
-      }
-      // If the default bundle was requested, look for features where
-      // the bundle is not set.
-      elseif ($bundle->isDefault()) {
-        return !isset($features_info['bundle']);
-      }
-      // If we have a bundle name, look for it.
-      else {
-        return (isset($features_info['bundle']) && ($features_info['bundle'] == $bundle->getMachineName()));
-      }
-    }
-    return FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function listPackageDirectories(array $machine_names = [], FeaturesBundleInterface $bundle = NULL) {
-    if (empty($machine_names)) {
-      $machine_names = array_keys($this->getPackages());
-    }
-
-    // If the bundle is a profile, then add the profile's machine name.
-    if (isset($bundle) && $bundle->isProfile() && !in_array($bundle->getProfileName(), $machine_names)) {
-      $machine_names[] = $bundle->getProfileName();
-    }
-
-    // If we are checking the default bundle, return all features.
-    if (isset($bundle) && $bundle->isDefault()) {
-      $bundle = NULL;
-    }
-
-    $modules = $this->getFeaturesModules($bundle);
-    // Filter to include only the requested packages.
-    $modules = array_filter($modules, function ($module) use ($bundle, $machine_names) {
-      return in_array($module->getName(), $machine_names);
-    });
-
-    $directories = [];
-    foreach ($modules as $module) {
-      $directories[$module->getName()] = $module->getPath();
-    }
-
-    return $directories;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getAllModules() {
-    static $modules;
-
-    if (!isset($modules)) {
-      // ModuleHandler::getModuleDirectories() returns data only for installed
-      // modules. system_rebuild_module_data() includes only the site's install
-      // profile directory, while we may need to include a custom profile.
-      // @see _system_rebuild_module_data().
-      $listing = new ExtensionDiscovery($this->root);
-
-      $profile_directories = $listing->setProfileDirectoriesFromSettings()->getProfileDirectories();
-      $installed_profile = $this->drupalGetProfile();
-      if (isset($bundle) && $bundle->isProfile()) {
-        $profile_directory = 'profiles/' . $bundle->getProfileName();
-        if (($bundle->getProfileName() != $installed_profile) && is_dir($profile_directory)) {
-          $profile_directories[] = $profile_directory;
-        }
-      }
-      $listing->setProfileDirectories($profile_directories);
-
-      // Find modules.
-      $modules = $listing->scan('module');
-
-      // Find installation profiles.
-      $profiles = $listing->scan('profile');
-
-      foreach ($profiles as $key => $profile) {
-        $modules[$key] = $profile;
-      }
-    }
-
-    return $modules;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFeaturesModules(FeaturesBundleInterface $bundle = NULL, $installed = FALSE) {
-    $modules = $this->getAllModules();
-
-    // Filter by bundle.
-    $features_manager = $this;
-    $modules = array_filter($modules, function ($module) use ($features_manager, $bundle) {
-      return $features_manager->isFeatureModule($module, $bundle);
-    });
-
-    // Filtered by installed status.
-    if ($installed) {
-      $features_manager = $this;
-      $modules = array_filter($modules, function ($extension) use ($features_manager) {
-        return $features_manager->extensionEnabled($extension);
-      });
-    }
-
-    return $modules;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function extensionEnabled(Extension $extension) {
-    return $this->moduleHandler->moduleExists($extension->getName());
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function initPackage($machine_name, $name = NULL, $description = '', $type = 'module', FeaturesBundleInterface $bundle = NULL, Extension $extension = NULL) {
-    if (isset($this->packages[$machine_name])) {
-      return $this->packages[$machine_name];
-    }
-    // Also look for existing package within the bundle
-    elseif (isset($bundle) && isset($this->packages[$bundle->getFullName($machine_name)])) {
-      return $this->packages[$bundle->getFullName($machine_name)];
-    }
-    return $this->packages[$machine_name] = $this->getPackageObject($machine_name, $name, $description, $type, $bundle, $extension);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function initPackageFromExtension(Extension $extension) {
-    $info = $this->getExtensionInfo($extension);
-    $features_info = $this->getFeaturesInfo($extension);
-    $bundle = $this->getAssigner()->findBundle($info, $features_info);
-    // Use the full extension name as the short_name.  Important to allow
-    // multiple modules with different namespaces such as oa_media, test_media.
-    $short_name = $extension->getName();
-    return $this->initPackage($short_name, $info['name'], !empty($info['description']) ? $info['description'] : '', $info['type'], $bundle, $extension);
-  }
-
-  /**
-   * Helper function to update dependencies array for a specific config item
-   * @param \Drupal\features\ConfigurationItem $config a config item
-   * @param array $module_list
-   * @return array $dependencies
-   */
-  protected function getConfigDependency(ConfigurationItem $config, $module_list = []) {
-    $dependencies = [];
-    $type = $config->getType();
-
-    // For configuration in the InstallStorage::CONFIG_INSTALL_DIRECTORY
-    // directory, set any dependencies of the configuration item as package
-    // dependencies.
-    // As its name implies, the core-provided
-    // InstallStorage::CONFIG_OPTIONAL_DIRECTORY should not create
-    // dependencies.
-    if ($config->getSubdirectory() === InstallStorage::CONFIG_INSTALL_DIRECTORY) {
-      if ($type === FeaturesManagerInterface::SYSTEM_SIMPLE_CONFIG) {
-        $dependencies[] = strtok($config->getName(), '.');
-      }
-      else {
-        $dependencies[] = $this->entityTypeManager->getDefinition($type)->getProvider();
-      }
-
-      if (isset($config->getData()['dependencies']['module'])) {
-        $dependencies = array_merge($dependencies, $config->getData()['dependencies']['module']);
-      }
-
-      // Only return dependencies for installed modules and not, for example,
-      // 'core'.
-      $dependencies = array_intersect($dependencies, array_keys($module_list));
-    }
-
-    return $dependencies;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function assignConfigPackage($package_name, array $item_names, $force = FALSE) {
-    $config_collection = $this->getConfigCollection();
-    $module_list = $this->moduleHandler->getModuleList();
-
-    $packages =& $this->packages;
-    if (isset($packages[$package_name])) {
-      $package =& $packages[$package_name];
-    }
-    else {
-      throw new \Exception($this->t('Failed to package @package_name. Package not found.', ['@package_name' => $package_name]));
-    }
-
-    foreach ($item_names as $item_name) {
-      if (isset($config_collection[$item_name])) {
-        // Add to the package if:
-        // - force is set or
-        //   - the item hasn't already been assigned elsewhere, and
-        //   - the package hasn't been excluded.
-        // - and the item isn't already in the package.
-
-        $item = &$config_collection[$item_name];
-        $already_assigned = !empty($item->getPackage());
-        // If this is the profile package, we can reassign extension-provided configuration.
-        $package_bundle = $this->getAssigner()->getBundle($package->getBundle());
-        $is_profile_package = isset($package_bundle) ? $package_bundle->isProfilePackage($package_name) : FALSE;
-        // An item is assignable if:
-        // - it is not provider excluded or this is the profile package, and
-        // - it is not flagged as excluded.
-        $assignable = (!$item->isProviderExcluded() || $is_profile_package) && !$item->isExcluded();
-        // An item is assignable if it was provided by the current package
-        $assignable = $assignable || ($item->getProvider() == $package->getMachineName());
-        $excluded_from_package = in_array($package_name, $item->getPackageExcluded());
-        $already_in_package = in_array($item_name, $package->getConfig());
-        if (($force || (!$already_assigned && $assignable && !$excluded_from_package)) && !$already_in_package) {
-          // Add the item to the package's config array.
-          $package->appendConfig($item_name);
-          // Mark the item as already assigned.
-          $item->setPackage($package_name);
-
-          $module_dependencies = $this->getConfigDependency($item, $module_list);
-          $package->setDependencies($this->mergeUniqueItems($package->getDependencies(), $module_dependencies));
-        }
-        // Return memory
-        unset($item);
-      }
-    }
-
-    $this->setConfigCollection($config_collection);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function assignConfigByPattern(array $patterns) {
-    // Regular expressions for items that are likely to generate false
-    // positives when assigned by pattern.
-    $false_positives = [
-      // Blocks with the page title should not be assigned to a 'page' package.
-      '/block\.block\..*_page_title/',
-    ];
-    $config_collection = $this->getConfigCollection();
-    // Sort by key so that specific package will claim items before general
-    // package. E.g., event_registration and registration_event will claim
-    // before event.
-    uksort($patterns, function($a, $b) {
-      // Count underscores to determine specificity of the package.
-      return (int) (substr_count($a, '_') <= substr_count($b, '_'));
-    });
-    foreach ($patterns as $pattern => $machine_name) {
-      if (isset($this->packages[$machine_name])) {
-        foreach ($config_collection as $item_name => $item) {
-          // Test for and skip false positives.
-          foreach ($false_positives as $false_positive) {
-            if (preg_match($false_positive, $item_name)) {
-              continue 2;
-            }
-          }
-
-          if (!$item->getPackage() && preg_match('/(\.|-|_|^)' . $pattern . '(\.|-|_|$)/', $item->getShortName())) {
-            try {
-              $this->assignConfigPackage($machine_name, [$item_name]);
-            }
-            catch (\Exception $exception) {
-              \Drupal::logger('features')->error($exception->getMessage());
-            }
-          }
-        }
-      }
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function assignConfigDependents(array $item_names = NULL, $package = NULL) {
-    $config_collection = $this->getConfigCollection();
-    if (empty($item_names)) {
-      $item_names = array_keys($config_collection);
-    }
-    foreach ($item_names as $item_name) {
-      // Make sure the extension provided item exists in the active
-      // configuration storage.
-      if (isset($config_collection[$item_name]) && $config_collection[$item_name]->getPackage()) {
-        foreach ($config_collection[$item_name]->getDependents() as $dependent_item_name) {
-          if (isset($config_collection[$dependent_item_name]) && (!empty($package) || empty($config_collection[$dependent_item_name]->getPackage()))) {
-            try {
-              $package_name = !empty($package) ? $package : $config_collection[$item_name]->getPackage();
-              $this->assignConfigPackage($package_name, [$dependent_item_name]);
-            }
-            catch (\Exception $exception) {
-              \Drupal::logger('features')->error($exception->getMessage());
-            }
-          }
-        }
-      }
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setPackageBundleNames(FeaturesBundleInterface $bundle, array &$package_names = []) {
-    $this->packagesPrefixed = TRUE;
-    if (!$bundle->isDefault()) {
-      $new_package_names = [];
-      // Assign the selected bundle to the exports.
-      $packages = $this->getPackages();
-      if (empty($package_names)) {
-        $package_names = array_keys($packages);
-      }
-      foreach ($package_names as $package_name) {
-        // Rename package to use bundle prefix.
-        $package = $packages[$package_name];
-
-        // The install profile doesn't need renaming.
-        if ($package->getType() != 'profile') {
-          unset($packages[$package_name]);
-          $package->setMachineName($bundle->getFullName($package->getMachineName()));
-          $packages[$package->getMachineName()] = $package;
-        }
-
-        // Set the bundle machine name.
-        $packages[$package->getMachineName()]->setBundle($bundle->getMachineName());
-        $new_package_names[] = $package->getMachineName();
-      }
-      $this->setPackages($packages);
-      $package_names = $new_package_names;
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function assignPackageDependencies(Package $package = NULL) {
-    if (is_null($package)) {
-      $packages = $this->getPackages();
-    }
-    else {
-      $packages = [$package];
-    }
-    $module_list = $this->moduleHandler->getModuleList();
-    $config_collection = $this->getConfigCollection();
-
-    foreach ($packages as $package) {
-      $module_dependencies = [];
-      foreach ($package->getConfig() as $item_name) {
-        if (isset($config_collection[$item_name])) {
-          $dependencies = $this->getConfigDependency($config_collection[$item_name], $module_list);
-          $module_dependencies = array_merge($module_dependencies, $dependencies);
-        }
-      }
-      $package->setDependencies($this->mergeUniqueItems($package->getDependencies(), $module_dependencies));
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function assignInterPackageDependencies(FeaturesBundleInterface $bundle, array &$packages) {
-    if (!$this->packagesPrefixed) {
-      throw new \Exception($this->t('The packages have not yet been prefixed with a bundle name.'));
-    }
-
-    $config_collection = $this->getConfigCollection();
-    $module_list = $this->moduleHandler->getModuleList();
-
-    /** @var \Drupal\features\Package[] $packages */
-    foreach ($packages as $package) {
-      foreach ($package->getConfig() as $item_name) {
-        if (!empty($config_collection[$item_name]->getData()['dependencies']['config'])) {
-          foreach ($config_collection[$item_name]->getData()['dependencies']['config'] as $dependency_name) {
-            if (isset($config_collection[$dependency_name]) &&
-              // For configuration in the
-              // InstallStorage::CONFIG_INSTALL_DIRECTORY directory, set any
-              // package dependencies of the configuration item.
-              // As its name implies, the core-provided
-              // InstallStorage::CONFIG_OPTIONAL_DIRECTORY should not create
-              // dependencies.
-              ($config_collection[$dependency_name]->getSubdirectory() === InstallStorage::CONFIG_INSTALL_DIRECTORY)) {
-              // If the required item is assigned to one of the packages, add
-              // a dependency on that package.
-              $dependency_set = FALSE;
-              if ($dependency_package = $config_collection[$dependency_name]->getPackage()) {
-                $package_name = $bundle->getFullName($dependency_package);
-                // Package shouldn't be dependent on itself.
-                if ($package_name && array_key_exists($package_name, $packages) && $package_name != $package->getMachineName() && isset($module_list[$package_name])) {
-                  $package->setDependencies($this->mergeUniqueItems($package->getDependencies(), [$package_name]));
-                  $dependency_set = TRUE;
-                }
-              }
-              // Otherwise, if the dependency is provided by an existing
-              // feature, add a dependency on that feature.
-              if (!$dependency_set && $extension_name = $config_collection[$dependency_name]->getProvider()) {
-                // No extension should depend on the install profile.
-                $package_name = $bundle->getFullName($package->getMachineName());
-                if ($extension_name != $package_name && $extension_name != $this->drupalGetProfile() && isset($module_list[$extension_name])) {
-                  $package->setDependencies($this->mergeUniqueItems($package->getDependencies(), [$extension_name]));
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-    // Unset the $package pass by reference.
-    unset($package);
-  }
-
- /**
-  * Gets the name of the currently active installation profile.
-  *
-  * @return string|null $profile
-  *   The name of the installation profile or NULL if no installation profile is
-  *   currently active. This is the case for example during the first steps of
-  *   the installer or during unit tests.
-  */
-  protected function drupalGetProfile() {
-    return drupal_get_profile();
-  }
-
-  /**
-   * Merges a set of new item into an array and sorts the result.
-   *
-   * Only unique values are retained.
-   *
-   * @param array $items
-   *   An array of items.
-   * @param array $new_items
-   *   An array of new items to be merged in.
-   *
-   * @return array
-   *   The merged, sorted and unique items.
-   */
-  protected function mergeUniqueItems($items, $new_items) {
-    $items = array_unique(array_merge($items, $new_items));
-    sort($items);
-    return $items;
-  }
-
-  /**
-   * Initializes and returns a package or profile array.
-   *
-   * @param string $machine_name
-   *   Machine name of the package.
-   * @param string $name
-   *   (optional) Human readable name of the package.
-   * @param string $description
-   *   (optional) Description of the package.
-   * @param string $type
-   *   (optional) Type of project.
-   * @param \Drupal\features\FeaturesBundleInterface $bundle
-   *   (optional) Bundle to use to add profile directories to the scan.
-   * @param \Drupal\Core\Extension\Extension $extension
-   *   (optional) An Extension object.
-   *
-   * @return \Drupal\features\Package
-   *   An array of package properties; see
-   *   FeaturesManagerInterface::getPackages().
-   */
-  protected function getPackageObject($machine_name, $name = NULL, $description = '', $type = 'module', FeaturesBundleInterface $bundle = NULL, Extension $extension = NULL) {
-    if (!isset($bundle)) {
-      $bundle = $this->getAssigner()->getBundle();
-    }
-    $package = new Package($machine_name, [
-      'name' => isset($name) ? $name : ucwords(str_replace(['_', '-'], ' ', $machine_name)),
-      'description' => $description,
-      'type' => $type,
-      'core' => Drupal::CORE_COMPATIBILITY,
-      'dependencies' => [],
-      'themes' => [],
-      'config' => [],
-      'status' => FeaturesManagerInterface::STATUS_DEFAULT,
-      'version' => '',
-      'state' => FeaturesManagerInterface::STATE_DEFAULT,
-      'files' => [],
-      'bundle' => $bundle->isDefault() ? '' : $bundle->getMachineName(),
-      'extension' => NULL,
-      'info' => [],
-      'configOrig' => [],
-    ]);
-
-    // If no extension was passed in, look for a match.
-    if (!isset($extension)) {
-      $module_list = $this->getFeaturesModules($bundle);
-      $module_name = $package->getMachineName();
-      if (isset($module_list[$module_name])) {
-        $extension = $module_list[$module_name];
-      }
-    }
-
-    // If there is an extension, set extension-specific properties.
-    if (isset($extension)) {
-      $info = $this->getExtensionInfo($extension);
-      $features_info = $this->getFeaturesInfo($extension);
-      $package->setExtension($extension);
-      $package->setInfo($info);
-      $package->setFeaturesInfo($features_info);
-      $package->setConfigOrig($this->listExtensionConfig($extension));
-      $package->setStatus($this->extensionEnabled($extension)
-        ? FeaturesManagerInterface::STATUS_INSTALLED
-        : FeaturesManagerInterface::STATUS_UNINSTALLED);
-      $package->setVersion(isset($info['version']) ? $info['version'] : '');
-    }
-
-    return $package;
-  }
-
-  /**
-   * Generates and adds .info.yml files to a package.
-   *
-   * @param \Drupal\features\Package $package
-   *   The package.
-   */
-  protected function addInfoFile(Package $package) {
-    $info = [
-      'name' => $package->getName(),
-      'description' => $package->getDescription(),
-      'type' => $package->getType(),
-      'core' => $package->getCore(),
-      'dependencies' => $package->getDependencies(),
-      'themes' => $package->getThemes(),
-      'version' => $package->getVersion(),
-    ];
-
-    $features_info = [];
-
-    // Assign to a "package" named for the profile.
-    if ($package->getBundle()) {
-      $bundle = $this->getAssigner()->getBundle($package->getBundle());
-    }
-    // Save the current bundle in the info file so the package
-    // can be reloaded later by the AssignmentPackages plugin.
-    if (isset($bundle) && !$bundle->isDefault()) {
-      $info['package'] = $bundle->getName();
-      $features_info['bundle'] = $bundle->getMachineName();
-    }
-    else {
-      unset($features_info['bundle']);
-    }
-
-    if ($package->getConfig()) {
-      foreach (['excluded', 'required'] as $constraint) {
-        if (!empty($package->{'get' . $constraint}())) {
-          $features_info[$constraint] = $package->{'get' . $constraint}();
-        }
-        else {
-          unset($features_info[$constraint]);
-        }
-      }
-
-      if (empty($features_info)) {
-        $features_info = TRUE;
-      }
-    }
-
-    // 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 (['name', 'description'] as $key) {
-      $info[$key] = (string) $info[$key];
-    }
-
-    // Add profile-specific info data.
-    if ($info['type'] == 'profile') {
-      // Set the distribution name.
-      $info['distribution'] = [
-        'name' => $info['name']
-      ];
-    }
-
-    $package->appendFile([
-      'filename' => $package->getMachineName() . '.info.yml',
-      'subdirectory' => NULL,
-      // Filter to remove any empty keys, e.g., an empty themes array.
-      'string' => Yaml::encode(array_filter($info))
-    ], 'info');
-
-    $package->appendFile([
-      'filename' => $package->getMachineName() . '.features.yml',
-      'subdirectory' => NULL,
-      'string' => Yaml::encode($features_info)
-    ], 'features');
-  }
-
-  /**
-   * Generates and adds files to a given package or profile.
-   */
-  protected function addPackageFiles(Package $package) {
-    $config_collection = $this->getConfigCollection();
-    // Always add .info.yml and .features.yml files.
-    $this->addInfoFile($package);
-    // Only add files if there is at least one piece of configuration present.
-    if ($package->getConfig()) {
-      // Add configuration files.
-      foreach ($package->getConfig() as $name) {
-        $config = $config_collection[$name];
-
-        $package->appendFile([
-          'filename' => $config->getName() . '.yml',
-          'subdirectory' => $config->getSubdirectory(),
-          'string' => Yaml::encode($config->getData())
-        ], $name);
-      }
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  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));
-    }
-
-    $info = NestedArray::mergeDeep($info1, $info2);
-
-    // Process the dependencies and themes keys.
-    $keys = ['dependencies', 'themes'];
-    foreach ($keys as $key) {
-      if (isset($info[$key]) && is_array($info[$key])) {
-        // NestedArray::mergeDeep() may produce duplicate values.
-        $info[$key] = array_unique($info[$key]);
-        sort($info[$key]);
-      }
-    }
-    return $info;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function listConfigTypes($bundles_only = FALSE) {
-    $definitions = [];
-    foreach ($this->entityTypeManager->getDefinitions() as $entity_type => $definition) {
-      if ($definition->isSubclassOf('Drupal\Core\Config\Entity\ConfigEntityInterface')) {
-        if (!$bundles_only || $definition->getBundleOf()) {
-          $definitions[$entity_type] = $definition;
-        }
-      }
-    }
-    $entity_types = array_map(function (EntityTypeInterface $definition) {
-      return $definition->getLabel();
-    }, $definitions);
-    // Sort the entity types by label, then add the simple config to the top.
-    uasort($entity_types, 'strnatcasecmp');
-    return $bundles_only ? $entity_types : [
-      FeaturesManagerInterface::SYSTEM_SIMPLE_CONFIG => $this->t('Simple configuration'),
-    ] + $entity_types;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function listExtensionConfig(Extension $extension) {
-    return $this->extensionStorages->listExtensionConfig($extension);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function listExistingConfig($installed = FALSE, FeaturesBundleInterface $bundle = NULL) {
-    $config = [];
-    $existing = $this->getFeaturesModules($bundle, $installed);
-    foreach ($existing as $extension) {
-      // Keys are configuration item names and values are providing extension
-      // name.
-      $new_config = array_fill_keys($this->listExtensionConfig($extension), $extension->getName());
-      $config = array_merge($config, $new_config);
-    }
-    return $config;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function listConfigByType($config_type) {
-    // For a given entity type, load all entities.
-    if ($config_type && $config_type !== FeaturesManagerInterface::SYSTEM_SIMPLE_CONFIG) {
-      $entity_storage = $this->entityTypeManager->getStorage($config_type);
-      $names = [];
-      foreach ($entity_storage->loadMultiple() as $entity) {
-        $entity_id = $entity->id();
-        $label = $entity->label() ?: $entity_id;
-        $names[$entity_id] = $label;
-      }
-    }
-    // Handle simple configuration.
-    else {
-      $definitions = [];
-      foreach ($this->entityTypeManager->getDefinitions() as $entity_type => $definition) {
-        if ($definition->isSubclassOf('Drupal\Core\Config\Entity\ConfigEntityInterface')) {
-          $definitions[$entity_type] = $definition;
-        }
-      }
-      // Gather the config entity prefixes.
-      $config_prefixes = array_map(function (EntityTypeInterface $definition) {
-        return $definition->getConfigPrefix() . '.';
-      }, $definitions);
-
-      // Find all config, and then filter our anything matching a config prefix.
-      $names = $this->configStorage->listAll();
-      $names = array_combine($names, $names);
-      foreach ($names as $item_name) {
-        foreach ($config_prefixes as $config_prefix) {
-          if (strpos($item_name, $config_prefix) === 0) {
-            unset($names[$item_name]);
-          }
-        }
-      }
-    }
-    return $names;
-  }
-
-  /**
-   * Creates a high performant version of the ConfigDependencyManager.
-   *
-   * @return \Drupal\features\FeaturesConfigDependencyManager
-   *   A high performant version of the ConfigDependencyManager.
-   *
-   * @see \Drupal\Core\Config\Entity\ConfigDependencyManager
-   */
-  protected function getFeaturesConfigDependencyManager() {
-    $dependency_manager = new FeaturesConfigDependencyManager();
-    // Read all configuration using the factory. This ensures that multiple
-    // deletes during the same request benefit from the static cache. Using the
-    // factory also ensures configuration entity dependency discovery has no
-    // dependencies on the config entity classes. Assume data with UUID is a
-    // config entity. Only configuration entities can be depended on so we can
-    // ignore everything else.
-    $data = array_map(function(Drupal\Core\Config\ImmutableConfig $config) {
-      $data = $config->get();
-      if (isset($data['uuid'])) {
-        return $data;
-      }
-      return FALSE;
-    }, $this->configFactory->loadMultiple($this->configStorage->listAll()));
-    $dependency_manager->setData(array_filter($data));
-    return $dependency_manager;
-  }
-
-  /**
-   * Loads configuration from storage into a property.
-   */
-  protected function initConfigCollection($reset = FALSE) {
-    if ($reset || empty($this->configCollection)) {
-      $config_collection = [];
-      $config_types = $this->listConfigTypes();
-      $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) {
-          $name = $this->getFullName($config_type, $item_name);
-          $data = $this->configStorage->read($name);
-
-          $config_collection[$name] = (new ConfigurationItem($name, $data, [
-            'shortName' => $item_name,
-            'label' => $label,
-            'type' => $config_type,
-            'dependents' => array_keys($dependency_manager->getDependentEntities('config', $name)),
-            // Default to the 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,
-            'packageExcluded' => [],
-          ]));
-        }
-      }
-      $this->setConfigCollection($config_collection);
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function prepareFiles(array $packages) {
-    foreach ($packages as $package) {
-      $this->addPackageFiles($package);
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getExportInfo(Package $package, FeaturesBundleInterface $bundle = NULL) {
-    $full_name = isset($bundle) ? $bundle->getFullName($package->getMachineName()) : $package->getMachineName();
-
-    $path = '';
-
-    // Adjust export directory to be in profile.
-    if (isset($bundle) && $bundle->isProfile()) {
-      $path .= 'profiles/' . $bundle->getProfileName();
-    }
-
-    // If this is not the profile package, nest the directory.
-    if (!isset($bundle) || !$bundle->isProfilePackage($package->getMachineName())) {
-      $path .= empty($path) ? 'modules' : '/modules';
-      $export_settings = $this->getExportSettings();
-      if (!empty($export_settings['folder'])) {
-        $path .= '/' . $export_settings['folder'];
-      }
-    }
-
-    // Use the same path of a package to override it.
-    if ($extension = $package->getExtension()) {
-      $extension_path = $extension->getPath();
-      $path = dirname($extension_path);
-    }
-
-    return [$full_name, $path];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function detectOverrides(Package $feature, $include_new = FALSE) {
-    /** @var \Drupal\config_update\ConfigDiffInterface $config_diff */
-    $config_diff = \Drupal::service('config_update.config_diff');
-
-    $different = [];
-    foreach ($feature->getConfig() as $name) {
-      $active = $this->configStorage->read($name);
-      $extension = $this->extensionStorages->read($name);
-      $extension = !empty($extension) ? $extension : [];
-      if (($include_new || !empty($extension)) && !$config_diff->same($extension, $active)) {
-        $different[] = $name;
-      }
-    }
-
-    if (!empty($different)) {
-      $feature->setState(FeaturesManagerInterface::STATE_OVERRIDDEN);
-    }
-    return $different;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function detectNew(Package $feature) {
-    $result = [];
-    foreach ($feature->getConfig() as $name) {
-      $extension = $this->extensionStorages->read($name);
-      if (empty($extension)) {
-        $result[] = $name;
-      }
-    }
-    return $result;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function detectMissing(Package $feature) {
-    $config = $this->getConfigCollection();
-    $result = [];
-    foreach ($feature->getConfigOrig() as $name) {
-      if (!isset($config[$name])) {
-        $result[] = $name;
-      }
-    }
-    return $result;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function reorderMissing(array $missing) {
-    $list = [];
-    $result = [];
-    foreach ($missing as $full_name) {
-      $this->addConfigList($full_name, $list);
-    }
-    foreach ($list as $full_name) {
-      if (in_array($full_name, $missing)) {
-        $result[] = $full_name;
-      }
-    }
-    return $result;
-  }
-
-  protected function addConfigList($full_name, &$list) {
-    $index = array_search($full_name, $list);
-    if ($index !== FALSE) {
-      unset($list[$index]);
-    }
-    array_unshift($list, $full_name);
-    $value = $this->extensionStorages->read($full_name);
-    if (isset($value['dependencies']['config'])) {
-      foreach ($value['dependencies']['config'] as $config_name) {
-        $this->addConfigList($config_name, $list);
-      }
-    }
-  }
-
-    /**
-   * {@inheritdoc}
-   */
-  public function statusLabel($status) {
-    switch ($status) {
-      case FeaturesManagerInterface::STATUS_NO_EXPORT:
-        return $this->t('Not exported');
-
-      case FeaturesManagerInterface::STATUS_UNINSTALLED:
-        return $this->t('Uninstalled');
-
-      case FeaturesManagerInterface::STATUS_INSTALLED:
-        return $this->t('Installed');
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function stateLabel($state) {
-    switch ($state) {
-      case FeaturesManagerInterface::STATE_DEFAULT:
-        return $this->t('Default');
-
-      case FeaturesManagerInterface::STATE_OVERRIDDEN:
-        return $this->t('Changed');
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFeaturesInfo(Extension $extension) {
-    $module_name = $extension->getName();
-    if (isset($this->featureInfoCache[$module_name])) {
-      return $this->featureInfoCache[$module_name];
-    }
-    $features_info = NULL;
-    $filename = $this->root . '/' . $extension->getPath() . '/' . $module_name . '.features.yml';
-    if (file_exists($filename)) {
-      $features_info = Yaml::decode(file_get_contents($filename));
-    }
-    $this->featureInfoCache[$module_name] = $features_info;
-    return $features_info;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function createConfiguration(array $config_to_create) {
-    $existing_config = $this->getConfigCollection();
-
-    // If config data is not specified, load it from the extension storage.
-    foreach ($config_to_create as $name => $item) {
-      if (empty($item)) {
-        $config = $this->configReverter->getFromExtension('', $name);
-        // For testing purposes, if it couldn't load from a module, get config
-        // from the cached Config Collection
-        if (empty($config) && isset($existing_config[$name])) {
-          $config = $existing_config[$name]->getData();
-        }
-        $config_to_create[$name] = $config;
-      }
-    }
-
-    // Determine which config is new vs existing.
-    $existing = array_intersect_key($config_to_create, $existing_config);
-    $new = array_diff_key($config_to_create, $existing);
-
-    // The FeaturesConfigInstaller exposes the normally protected createConfiguration
-    // function from Core ConfigInstaller than handles the creation of new
-    // config or the changing of existing config.
-    /** @var \Drupal\features\FeaturesConfigInstaller $config_installer */
-    $config_installer = \Drupal::service('features.config.installer');
-    $config_installer->createConfiguration(StorageInterface::DEFAULT_COLLECTION, $config_to_create);
-
-    // Collect results for new and updated config.
-    $new_config = $this->getConfigCollection(TRUE);
-    $result['updated'] = array_intersect_key($new_config, $existing);
-    $result['new'] = array_intersect_key($new_config, $new);
-    return $result;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function import($modules, $any = FALSE) {
-    $result = [];
-    foreach ($modules as $module_name) {
-      $package = $this->loadPackage($module_name, $any);
-      $components = isset($package) ? $package->getConfigOrig() : [];
-      if (empty($components)) {
-        continue;
-      }
-      $result[$module_name] = $this->createConfiguration(array_fill_keys($components, []));
-    }
-    return $result;
-  }
-
-}
diff --git a/web/modules/features/src/FeaturesManagerInterface.php b/web/modules/features/src/FeaturesManagerInterface.php
deleted file mode 100644
index 2f47e5248b2e742034432756de175183f328a1f7..0000000000000000000000000000000000000000
--- a/web/modules/features/src/FeaturesManagerInterface.php
+++ /dev/null
@@ -1,647 +0,0 @@
-<?php
-
-namespace Drupal\features;
-
-use Drupal\Core\Extension\Extension;
-
-/**
- * Provides an interface for the FeaturesManager.
- */
-interface FeaturesManagerInterface {
-
-  /**
-   * Simple configuration.
-   *
-   * Core uses system.simple, but since we're using this key in configuration
-   * arrays we can't include a period.
-   *
-   * @see https://www.drupal.org/node/2297311
-   */
-  const SYSTEM_SIMPLE_CONFIG = 'system_simple';
-
-  /**
-   * Constants for package/module status.
-   */
-  const STATUS_NO_EXPORT = 0;
-  const STATUS_UNINSTALLED = 1;
-  const STATUS_INSTALLED = 2;
-  const STATUS_DEFAULT = self::STATUS_NO_EXPORT;
-
-  /**
-   * Constants for package/module state.
-   */
-  const STATE_DEFAULT = 0;
-  const STATE_OVERRIDDEN = 1;
-
-  /**
-   * Set the app.root.
-   *
-   * Should only be used by tests.
-   * @param string $root
-   */
-  public function setRoot($root);
-
-  /**
-   * Returns the active config store.
-   *
-   * @return \Drupal\Core\Config\StorageInterface
-   */
-  public function getActiveStorage();
-
-  /**
-   * Returns a set of config storages.
-   *
-   * This method is used for support of multiple extension configuration
-   * directories, including the core-provided install and optional directories.
-   *
-   * @return \Drupal\Core\Config\StorageInterface[]
-   */
-  public function getExtensionStorages();
-
-  /**
-   * Resets packages and configuration assignment.
-   */
-  public function reset();
-
-  /**
-   * Gets an array of site configuration.
-   *
-   * @param bool $reset
-   *   If TRUE, recalculate the configuration (undo all assignment methods).
-   *
-   * @return \Drupal\features\ConfigurationItem[]
-   *   An array of items, each with the following keys:
-   *   - 'name': prefixed configuration item name.
-   *   - 'name_short': configuration item name without prefix.
-   *   - 'label': human readable name of configuration item.
-   *   - 'type': type of configuration.
-   *   - 'data': the contents of the configuration item in exported format.
-   *   - 'dependents': array of names of dependent configuration items.
-   *   - 'subdirectory': feature subdirectory to export item to.
-   *   - 'package': machine name of a package the configuration is assigned to.
-   *   - 'extension_provided': whether the configuration is provided by an
-   *     extension.
-   *   - 'package_excluded': array of package names that this item should be
-   *     excluded from.
-   */
-  public function getConfigCollection($reset = FALSE);
-
-  /**
-   * Sets an array of site configuration.
-   *
-   * @param \Drupal\features\ConfigurationItem[] $config_collection
-   *   An array of items.
-   */
-  public function setConfigCollection(array $config_collection);
-
-  /**
-   * Gets an array of packages.
-   *
-   * @return \Drupal\features\Package[]
-   *   An array of items, each with the following keys:
-   *   - 'machine_name': machine name of the package such as 'example_article'.
-   *     'article'.
-   *   - 'name': human readable name of the package such as 'Example Article'.
-   *   - 'description': description of the package.
-   *   - 'type': type of Drupal project ('module').
-   *   - 'core': Drupal core compatibility ('8.x').
-   *   - 'dependencies': array of module dependencies.
-   *   - 'themes': array of names of themes to install.
-   *   - 'config': array of names of configuration items.
-   *   - 'status': status of the package. Valid values are:
-   *      - FeaturesManagerInterface::STATUS_NO_EXPORT
-   *      - FeaturesManagerInterface::STATUS_INSTALLED
-   *      - FeaturesManagerInterface::STATUS_UNINSTALLED
-   *   - 'version': version of the extension.
-   *   - 'state': state of the extension. Valid values are:
-   *      - FeaturesManagerInterface::STATE_DEFAULT
-   *      - FeaturesManagerInterface::STATE_OVERRIDDEN
-   *   - 'directory': the extension's directory.
-   *   - 'files' array of files, each having the following keys:
-   *      - 'filename': the name of the file.
-   *      - 'subdirectory': any subdirectory of the file within the extension
-   *         directory.
-   *      - 'string': the contents of the file.
-   *   - 'bundle': name of the features bundle this package belongs to.
-   *   - 'extension': \Drupal\Core\Extension\Extension object.
-   *   - 'info': the original info array from an existing package.
-   *   - 'config_info': the original config of the module.
-   *
-   * @see \Drupal\features\FeaturesManagerInterface::setPackages()
-   */
-  public function getPackages();
-
-  /**
-   * Sets an array of packages.
-   *
-   * @param \Drupal\features\Package[] $packages
-   *   An array of packages.
-   */
-  public function setPackages(array $packages);
-
-  /**
-   * Gets a specific package.
-   *
-   * @param string $machine_name
-   *   Full machine name of package.
-   *
-   * @return \Drupal\features\Package
-   *   Package data.
-   *
-   * @see \Drupal\features\FeaturesManagerInterface::getPackages()
-   */
-  public function getPackage($machine_name);
-
-  /**
-   * Gets a specific package.
-   * Similar to getPackage but will also match package FullName
-   *
-   * @param string $machine_name
-   *   Full machine name of package.
-   *
-   * @return \Drupal\features\Package
-   *   Package data.
-   *
-   * @see \Drupal\features\FeaturesManagerInterface::getPackages()
-   */
-  public function findPackage($machine_name);
-
-  /**
-   * Updates a package definition in the package list.
-   *
-   * NOTE: This does not "export" the package; it simply updates the internal
-   * data.
-   *
-   * @param \Drupal\features\Package $package
-   *   The package.
-   */
-  public function setPackage(Package $package);
-
-  /**
-   * Load a specific package.
-   *
-   * Similar to getPackage but can also load modules that are not Features.
-   *
-   * @param string $module_name
-   *   Full machine name of module.
-   * @param bool $any
-   *   If TRUE then check for any module, not just a Features module.
-   *
-   * @return \Drupal\features\Package
-   *   Package data.
-   */
-  public function loadPackage($module_name, $any = FALSE);
-
-  /**
-   * Filters the supplied package list by the given namespace.
-   *
-   * @param \Drupal\features\Package[] $packages
-   *   An array of packages.
-   * @param string $namespace
-   *   The namespace to use.
-   * @param bool $only_exported
-   *   If true, only filter out packages that are exported
-   *
-   * @return \Drupal\features\Package[]
-   *   An array of packages.
-   */
-  public function filterPackages(array $packages, $namespace = '', $only_exported = FALSE);
-
-  /**
-   * Gets a reference to a package assigner.
-   *
-   * @return \Drupal\features\FeaturesAssignerInterface
-   *   The package assigner.
-   */
-  public function getAssigner();
-
-  /**
-   * Injects the package assigner.
-   *
-   * @param \Drupal\features\FeaturesAssignerInterface $assigner
-   *   The package assigner.
-   */
-  public function setAssigner(FeaturesAssignerInterface $assigner);
-
-  /**
-   * Gets a reference to a package generator.
-   *
-   * @return \Drupal\features\FeaturesGeneratorInterface
-   *   The package generator.
-   */
-  public function getGenerator();
-
-  /**
-   * Injects the package generator.
-   *
-   * @param \Drupal\features\FeaturesGeneratorInterface $generator
-   *   The package generator.
-   */
-  public function setGenerator(FeaturesGeneratorInterface $generator);
-
-  /**
-   * Returns the current export settings.
-   *
-   * @return array
-   *   An array with the following keys:
-   *   - 'folder' - subdirectory to export packages to.
-   *   - 'namespace' - module namespace being exported.
-   */
-  public function getExportSettings();
-
-  /**
-   * Returns the current general features settings.
-   *
-   * @return \Drupal\Core\Config\Config
-   *   A config object containing settings.
-   */
-  public function getSettings();
-
-  /**
-   * Returns the contents of an extensions info.yml file.
-   *
-   * @param \Drupal\Core\Extension\Extension $extension
-   *   An Extension object.
-   *
-   * @return array
-   *   An array representing data in an info.yml file.
-   */
-  public function getExtensionInfo(Extension $extension);
-
-  /**
-   * Determine if extension is enabled
-   *
-   * @param \Drupal\Core\Extension\Extension $extension
-   * @return bool
-   */
-  public function extensionEnabled(Extension $extension);
-
-  /**
-   * Initializes a configuration package.
-   *
-   * @param string $machine_name
-   *   Machine name of the package.
-   * @param string $name
-   *   (optional) Human readable name of the package.
-   * @param string $description
-   *   (optional) Description of the package.
-   * @param string $type
-   *   (optional) Type of project.
-   * @param \Drupal\features\FeaturesBundleInterface $bundle
-   *   (optional) Bundle to use to add profile directories to the scan.
-   * @param \Drupal\Core\Extension\Extension $extension
-   *   (optional) An Extension object.
-   * @return \Drupal\features\Package
-   *   The created package array.
-   */
-  public function initPackage($machine_name, $name = NULL, $description = '', $type = 'module', FeaturesBundleInterface $bundle = NULL, Extension $extension = NULL);
-
-  /**
-   * Initializes a configuration package using module info data.
-   *
-   * @param \Drupal\Core\Extension\Extension $extension
-   *   An Extension object.
-   *
-   * @return \Drupal\features\Package
-   *   The created package array.
-   */
-  public function initPackageFromExtension(Extension $extension);
-
-  /**
-   * Lists directories in which packages are present.
-   *
-   * This method scans to find package modules whether or not they are
-   * currently active (installed). As well as the directories that are
-   * usually scanned for modules and profiles, a profile directory for the
-   * current profile is scanned if it exists. For example, if the value
-   * for $bundle->getProfileName() is 'example', a
-   * directory profiles/example will be scanned if it exists. Therefore, when
-   * regenerating package modules, existing ones from a prior export will be
-   * recognized.
-   *
-   * @param string[] $machine_names
-   *   Package machine names to return directories for. If omitted, return all
-   *   directories.
-   * @param \Drupal\features\FeaturesBundleInterface $bundle
-   *   Optional bundle to use to add profile directories to the scan.
-   *
-   * @return array
-   *   Array of package directories keyed by package machine name.
-   */
-  public function listPackageDirectories(array $machine_names = [], FeaturesBundleInterface $bundle = NULL);
-
-  /**
-   * Assigns a set of configuration items to a given package or profile.
-   *
-   * @param string $package_name
-   *   Machine name of a package or the profile.
-   * @param string[] $item_names
-   *   Configuration item names.
-   * @param bool $force
-   *   (optional) If TRUE, assign config regardless of restrictions such as it
-   *   being already assigned to a package.
-   *
-   * @throws Exception
-   */
-  public function assignConfigPackage($package_name, array $item_names, $force = FALSE);
-
-  /**
-   * Assigns configuration items with names matching given strings to given
-   * packages.
-   *
-   * @param array $patterns
-   *   Array with string patterns as keys and package machine names as values.
-   */
-  public function assignConfigByPattern(array $patterns);
-
-  /**
-   * For given configuration items, assigns any dependent configuration to the
-   * same package.
-   *
-   * @param string[] $item_names
-   *   Configuration item names.
-   * @param string $package
-   *   Short machine name of package to assign dependent config to. If NULL,
-   *   use the current package of the parent config items.
-   */
-  public function assignConfigDependents(array $item_names = NULL, $package = NULL);
-
-  /**
-   * Adds the optional bundle prefix to package machine names.
-   *
-   * @param \Drupal\features\FeaturesBundleInterface $bundle
-   *   The bundle used for the generation.
-   * @param string[] &$package_names
-   *   (optional) Array of package names, passed by reference.
-   */
-  public function setPackageBundleNames(FeaturesBundleInterface $bundle, array &$package_names = []);
-
-  /**
-   * Assigns dependencies from config items into the package.
-   *
-   * @param \Drupal\features\Package[] $packages
-   *   An array of packages. NULL for all packages
-   */
-  public function assignPackageDependencies(Package $package = NULL);
-
-  /**
-   * Assigns dependencies between packages based on configuration dependencies.
-   *
-   * \Drupal\features\FeaturesBundleInterface::setPackageBundleNames() must be
-   * called prior to calling this method.
-   *
-   * @param \Drupal\features\FeaturesBundleInterface $bundle
-   *   A features bundle.
-   * @param \Drupal\features\Package[] $packages
-   *   An array of packages.
-   */
-  public function assignInterPackageDependencies(FeaturesBundleInterface $bundle, array &$packages);
-
-  /**
-   * Merges two info arrays and processes the resulting array.
-   *
-   * Ensures values are unique and sorted.
-   *
-   * @param array $info1
-   *   The first array.
-   * @param array $info2
-   *   The second array.
-   * @param string[] $keys
-   *   Keys to merge. If not specified, all keys present will be merged.
-   *
-   * @return array
-   *   An array with the merged and processed results.
-   *
-   * @fixme Should this be moved to the package object or a related helper?
-   */
-  public function mergeInfoArray(array $info1, array $info2, array $keys = []);
-
-  /**
-   * Lists the types of configuration available on the site.
-   *
-   * @param boolean $bundles_only
-   *   Whether to list only configuration types that provide bundles.
-   *
-   * @return array
-   *   An array with machine name keys and human readable values.
-   */
-  public function listConfigTypes($bundles_only = FALSE);
-
-  /**
-   * Lists stored configuration for a given configuration type.
-   *
-   * @param string $config_type
-   *   The type of configuration.
-   */
-  public function listConfigByType($config_type);
-
-  /**
-   * Returns a list of all modules present on the site's file system.
-   *
-   * @return Drupal\Core\Extension\Extension[]
-   *   An array of extension objects.
-   */
-  public function getAllModules();
-
-  /**
-   * Returns a list of Features modules regardless of if they are installed.
-   *
-   * @param \Drupal\features\FeaturesBundleInterface $bundle
-   *   Optional bundle to filter module list.
-   *   If given, only modules matching the bundle namespace will be returned.
-   *   If the bundle uses a profile, only modules in the profile will be
-   *   returned.
-   * @param bool $installed
-   *   List only installed modules.
-   *
-   * @return Drupal\Core\Extension\Extension[]
-   *   An array of extension objects.
-   */
-  public function getFeaturesModules(FeaturesBundleInterface $bundle = NULL, $installed = FALSE);
-
-  /**
-   * Lists names of configuration objects provided by a given extension.
-   *
-   * @param \Drupal\Core\Extension\Extension $extension
-   *   An Extension object.
-   *
-   * @return array
-   *   An array of configuration object names.
-   */
-  public function listExtensionConfig(Extension $extension);
-
-  /**
-   * Lists names of configuration items provided by existing Features modules.
-   *
-   * @param bool $installed
-   *   List only installed Features.
-   * @param \Drupal\features\FeaturesBundleInterface $bundle
-   *   (optional) Bundle to find existing configuration for.
-   *
-   * @return array
-   *   An array with config names as keys and providing module names as values.
-   */
-  public function listExistingConfig($installed = FALSE, FeaturesBundleInterface $bundle = NULL);
-
-  /**
-   * Iterates through packages and prepares file names and contents.
-   *
-   * @param array $packages
-   *   An array of packages.
-   */
-  public function prepareFiles(array $packages);
-
-  /**
-   * Returns the full name of a config item.
-   *
-   * @param string $type
-   *   The config type, or '' to indicate $name is already prefixed.
-   * @param string $name
-   *   The config name, without prefix.
-   *
-   * @return string
-   *   The config item's full name.
-   */
-  public function getFullName($type, $name);
-
-  /**
-   * Returns the short name and type of a full config name.
-   *
-   * @param string $fullname
-   *   The full configuration name
-   * @return array
-   *   'type' => string the config type
-   *   'name_short' => string the short config name, without prefix.
-   */
-  public function getConfigType($fullname);
-
-  /**
-   * Returns the full machine name and directory for exporting a package.
-   *
-   * @param \Drupal\features\Package $package
-   *   The package.
-   * @param \Drupal\features\FeaturesBundleInterface $bundle
-   *   Optional bundle being used for export.
-   *
-   * @return array
-   *   An array with the full name as the first item and directory as second
-   *   item.
-   */
-  public function getExportInfo(Package $package, FeaturesBundleInterface $bundle = NULL);
-
-  /**
-   * Determines if the module is a Features package, optionally testing by
-   * bundle.
-   *
-   * @param \Drupal\Core\Extension\Extension $module
-   *   An extension object.
-   * @param \Drupal\features\FeaturesBundleInterface $bundle
-   *   (optional) Bundle to filter by.
-   *
-   * @return bool
-   *   TRUE if the given module is a Features package of the given bundle (if any).
-   */
-  public function isFeatureModule(Extension $module, FeaturesBundleInterface $bundle);
-
-  /**
-   * Determines which config is overridden in a package.
-   *
-   * @param \Drupal\features\Package $feature
-   *   The package array.
-   *   The 'state' property is updated if overrides are detected.
-   * @param bool $include_new
-   *   If set, include newly detected config not yet exported.
-   *
-   * @result array $different
-   *   The array of config items that are overridden.
-   *
-   * @see \Drupal\features\FeaturesManagerInterface::detectNew()
-   */
-  public function detectOverrides(Package $feature, $include_new = FALSE);
-
-  /**
-   * Determines which config has not been exported to the feature.
-   *
-   * Typically added as an auto-detected dependency.
-   *
-   * @param \Drupal\features\Package $feature
-   *   The package array.
-   *
-   * @return array
-   *   The array of config items that are overridden.
-   */
-  public function detectNew(Package $feature);
-
-  /**
-   * Determines which config is exported in the feature but not in the active.
-   *
-   * @param \Drupal\features\Package $feature
-   *   The package array.
-   *
-   * @return array
-   *   The array of config items that are missing from active store.
-   */
-  public function detectMissing(Package $feature);
-
-  /**
-   * Sort the Missing config into order by dependencies.
-   * @param array $missing config items
-   * @return array of config items in dependency order
-   */
-  public function reorderMissing(array $missing);
-
-  /**
-   * Helper function that returns a translatable label for the different status
-   * constants.
-   *
-   * @param int $status
-   *   A status constant.
-   *
-   * @return string
-   *   A translatable label.
-   */
-  public function statusLabel($status);
-
-  /**
-   * Helper function that returns a translatable label for the different state
-   * constants.
-   *
-   * @param int $state
-   *   A state constant.
-   *
-   * @return string
-   *   A translatable label.
-   */
-  public function stateLabel($state);
-
-  /**
-   * @param \Drupal\Core\Extension\Extension $extension
-   *
-   * @return array
-   */
-  public function getFeaturesInfo(Extension $extension);
-
-  /**
-   * Creates configuration in a collection based on the provided list.
-   *
-   * @param array $config_to_create
-   *   An array of configuration data to create, keyed by name.
-   * @return array of config imported
-   *   'new': list of new config created keyed by name.
-   *   'updated': list of updated config keyed by name.
-   */
-  public function createConfiguration(array $config_to_create);
-
-  /**
-   * @param array $modules
-   *   An array of module names to import (revert)
-   * @param bool $any
-   *   Set to TRUE to import config from non-Features modules
-   * @return array of config imported
-   *   keyed by name of module, then:
-   *     'new': list of new config created keyed by name.
-   *     'updated': list of updated config keyed by name.
-   */
-  public function import($modules, $any = FALSE);
-
-}
diff --git a/web/modules/features/src/Package.php b/web/modules/features/src/Package.php
deleted file mode 100644
index c7f2872a2909d4c600a7a09ae690c61f24815db5..0000000000000000000000000000000000000000
--- a/web/modules/features/src/Package.php
+++ /dev/null
@@ -1,562 +0,0 @@
-<?php
-
-namespace Drupal\features;
-
-/**
- * Defines a value object for storing package related data.
- *
- * A package contains of a name, version number, containing config etc.
- */
-class Package {
-
-  /**
-   * @var string
-   */
-  protected $machineName = '';
-
-  /**
-   * @var string
-   */
-  protected $name = '';
-
-  /**
-   * @var string
-   */
-  protected $description = '';
-
-  /**
-   * @todo This could be fetched from the extension object.
-   *
-   * @var string
-   */
-  protected $version = '';
-
-  /**
-   * @var string
-   */
-  protected $core = '8.x';
-
-  /**
-   * @todo This could be fetched from the extension object.
-   *
-   * @var string
-   */
-  protected $type = 'module';
-
-  /**
-   * @var string[]
-   */
-  protected $themes = [];
-
-  /**
-   * @var string
-   */
-  protected $bundle;
-
-  /**
-   * @var string[]
-   */
-  protected $excluded = [];
-
-  /**
-   * @var string[]|bool
-   */
-  protected $required = false;
-
-  /**
-   * @var array
-   */
-  protected $info = [];
-
-  /**
-   * @var string[]
-   */
-  protected $dependencies = [];
-
-  /**
-   * @todo This could be fetched from the extension object.
-   *
-   * @var int
-   */
-  protected $status;
-
-  /**
-   * @var int
-   */
-  protected $state;
-
-  /**
-   * @todo This could be fetched from the extension object.
-   *
-   * @var string
-   */
-  protected $directory;
-
-  /**
-   * @var string[]
-   */
-  protected $files;
-
-  /**
-   * @var \Drupal\Core\Extension\Extension
-   */
-  protected $extension;
-
-  /**
-   * @var string[]
-   */
-  protected $config = [];
-
-  /**
-   * @var string[]
-   */
-  protected $configOrig = [];
-
-  /**
-   * Creates a new Package instance.
-   *
-   * @param string $machine_name
-   *   The machine name.
-   * @param array $additional_properties
-   *   (optional) Additional properties of the object.
-   */
-  public function __construct($machine_name, array $additional_properties = []) {
-    $this->machineName = $machine_name;
-
-    $properties = get_object_vars($this);
-    foreach ($additional_properties as $property => $value) {
-      if (!array_key_exists($property, $properties)) {
-        throw new \InvalidArgumentException('Invalid property: ' . $property);
-      }
-      $this->{$property} = $value;
-    }
-  }
-
-  /**
-   * @return mixed
-   */
-  public function getMachineName() {
-    return $this->machineName;
-  }
-
-  /**
-   * Return TRUE if the machine_name already has the bundle prefix.
-   *
-   * @param string $machine_name
-   * @param string $bundle_name
-   * @return bool
-   */
-  protected function inBundle($machine_name, $bundle_name) {
-    return strpos($machine_name, $bundle_name . '_') === 0;
-  }
-
-  /**
-   * Return the full name of the package by prefixing it with bundle as needed
-   *
-   * NOTE: When possible, use the Bundle::getFullName method since it can
-   * better handle cases where a bundle is a profile.
-   *
-   * @return string
-   */
-  public function getFullName() {
-    if (empty($this->bundle) || $this->inBundle($this->machineName, $this->bundle)) {
-      return $this->machineName;
-    }
-    else {
-      return $this->bundle . '_' . $this->machineName;
-    }
-  }
-
-  /**
-   * @return string
-   */
-  public function getName() {
-    return $this->name;
-  }
-
-  /**
-   * @return string
-   */
-  public function getDescription() {
-    return $this->description;
-  }
-
-  /**
-   * @return string
-   */
-  public function getVersion() {
-    return $this->version;
-  }
-
-  /**
-   * @return int
-   */
-  public function getStatus() {
-    return $this->status;
-  }
-
-  /**
-   * @return string[]
-   */
-  public function getConfig() {
-    return $this->config;
-  }
-
-  /**
-   * Append a new filename.
-   *
-   * @param string $config
-   *
-   * @return $this
-   */
-  public function appendConfig($config) {
-    $this->config[] = $config;
-    $this->config = array_unique($this->config);
-    return $this;
-  }
-
-  public function removeConfig($name) {
-    $this->config = array_diff($this->config, [$name]);
-    return $this;
-  }
-
-  /**
-   * @return string
-   */
-  public function getBundle() {
-    return $this->bundle;
-  }
-
-  /**
-   * @return string[]
-   */
-  public function getExcluded() {
-    return $this->excluded;
-  }
-
-  /**
-   * @return string[]|bool
-   */
-  public function getRequired() {
-    return $this->required;
-  }
-
-  /**
-   * @return bool
-   */
-  public function getRequiredAll() {
-    // Mark all as required if the package is not yet exported.
-    if ($this->getStatus() === FeaturesManagerInterface::STATUS_NO_EXPORT) {
-      return TRUE;
-    }
-
-    // Mark all as required if required is TRUE.
-    if (is_bool($this->required)) {
-      return $this->required;
-    }
-
-    // Mark all as required if required contains all the exported config.
-    $config_orig = $this->getConfigOrig();
-    $diff = array_diff($config_orig, $this->required);
-    return empty($diff);
-  }
-
-  /**
-   * @return string[]
-   */
-  public function getConfigOrig() {
-    return $this->configOrig;
-  }
-
-  /**
-   * @return string
-   */
-  public function getCore() {
-    return $this->core;
-  }
-
-  /**
-   * @return string
-   */
-  public function getType() {
-    return $this->type;
-  }
-
-  /**
-   * @return \string[]
-   */
-  public function getThemes() {
-    return $this->themes;
-  }
-
-  /**
-   * @return array
-   */
-  public function getInfo() {
-    return $this->info;
-  }
-
-  /**
-   * @return mixed
-   */
-  public function getState() {
-    return $this->state;
-  }
-
-  /**
-   * @return string
-   */
-  public function getDirectory() {
-    return $this->directory;
-  }
-
-  /**
-   * @return mixed
-   */
-  public function getFiles() {
-    return $this->files;
-  }
-
-  /**
-   * @return \Drupal\Core\Extension\Extension
-   */
-  public function getExtension() {
-    return $this->extension;
-  }
-
-  public function getDependencies() {
-    return $this->dependencies;
-  }
-
-  public function removeDependency($name) {
-    $this->dependencies = array_diff($this->dependencies, [$name]);
-    return $this;
-  }
-
-  public function getDependencyInfo() {
-    return isset($this->info['dependencies']) ? $this->info['dependencies'] : [];
-  }
-
-  /**
-   * Returns the features info.
-   *
-   * @return array
-   */
-  public function getFeaturesInfo() {
-    $info = [];
-    if (!empty($this->bundle)) {
-      $info['bundle'] = $this->bundle;
-    }
-    if (!empty($this->excluded)) {
-      $info['excluded'] = $this->excluded;
-    }
-    if ($this->required !== FALSE) {
-      $info['required'] = $this->required;
-    }
-    return $info;
-  }
-
-  /**
-   * Sets a new machine name.
-   *
-   * @param string $machine_name
-   *   The machine name
-   *
-   * @return $this
-   */
-  public function setMachineName($machine_name) {
-    $this->machineName = $machine_name;
-    return $this;
-  }
-
-  /**
-   * @param string $name
-   *
-   * @return $this
-   */
-  public function setName($name) {
-    $this->name = $name;
-    return $this;
-  }
-
-  /**
-   * @param string $description
-   *
-   * @return $this
-   */
-  public function setDescription($description) {
-    $this->description = $description;
-    return $this;
-  }
-
-  /**
-   * @param string $version
-   *
-   * @return $this
-   */
-  public function setVersion($version) {
-    $this->version = $version;
-    return $this;
-  }
-
-  /**
-   * @param string $bundle
-   *
-   * @return $this
-   */
-  public function setBundle($bundle) {
-    $this->bundle = $bundle;
-    return $this;
-  }
-
-  /**
-   * @param array $info
-   *
-   * @return $this
-   */
-  public function setInfo($info) {
-    $this->info = $info;
-    return $this;
-  }
-
-  /**
-   * @param \string[] $features_info
-   *
-   * @return $this
-   */
-  public function setFeaturesInfo($features_info) {
-    if (isset($features_info['bundle'])) {
-      $this->setBundle($features_info['bundle']);
-    }
-    $this->setRequired(isset($features_info['required']) ? $features_info['required'] : false);
-    $this->setExcluded(isset($features_info['excluded']) ? $features_info['excluded'] : []);
-
-    return $this;
-  }
-
-  /**
-   * @param \string[] $dependencies
-   *
-   * @return $this
-   */
-  public function setDependencies($dependencies) {
-    $this->dependencies = $dependencies;
-    return $this;
-  }
-
-  /**
-   * @param string $dependency
-   *
-   * return $this
-   */
-  public function appendDependency($dependency) {
-    $this->dependencies[] = $dependency;
-    return $this;
-  }
-
-  /**
-   * @param int $status
-   *
-   * @return $this
-   */
-  public function setStatus($status) {
-    $this->status = $status;
-    return $this;
-  }
-
-  /**
-   * @param \string[] $config
-   *
-   * @return $this
-   */
-  public function setConfig($config) {
-    $this->config = $config;
-    return $this;
-  }
-
-  /**
-   * @param bool $excluded
-   */
-  public function setExcluded($excluded) {
-    $this->excluded = $excluded;
-  }
-
-  /**
-   * @param bool $required
-   */
-  public function setRequired($required) {
-    $this->required = $required;
-  }
-
-  /**
-   * @param string $core
-   */
-  public function setCore($core) {
-    $this->core = $core;
-  }
-
-  /**
-   * @param string $type
-   */
-  public function setType($type) {
-    $this->type = $type;
-  }
-
-  /**
-   * @param \string[] $themes
-   */
-  public function setThemes($themes) {
-    $this->themes = $themes;
-  }
-
-  /**
-   * @param int $state
-   */
-  public function setState($state) {
-    $this->state = $state;
-  }
-
-  /**
-   * @param string $directory
-   */
-  public function setDirectory($directory) {
-    $this->directory = $directory;
-  }
-
-  /**
-   * @param \string[] $files
-   */
-  public function setFiles($files) {
-    $this->files = $files;
-  }
-
-  /**
-   * @param array $file_array
-   *
-   * @return $this
-   */
-  public function appendFile(array $file_array, $key = NULL) {
-    if (!isset($key)) {
-      $this->files[] = $file_array;
-    }
-    else {
-      $this->files[$key] = $file_array;
-    }
-    return $this;
-  }
-
-  /**
-   * @param \Drupal\Core\Extension\Extension $extension
-   */
-  public function setExtension($extension) {
-    $this->extension = $extension;
-  }
-
-  /**
-   * @param \string[] $configOrig
-   */
-  public function setConfigOrig($configOrig) {
-    $this->configOrig = $configOrig;
-  }
-
-}
diff --git a/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentAlter.php b/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentAlter.php
deleted file mode 100644
index 91cbf12f2d64e67c0a09b6baa59346735dfb14ef..0000000000000000000000000000000000000000
--- a/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentAlter.php
+++ /dev/null
@@ -1,63 +0,0 @@
-<?php
-
-namespace Drupal\features\Plugin\FeaturesAssignment;
-
-use Drupal\features\FeaturesAssignmentMethodBase;
-use Drupal\features\FeaturesManagerInterface;
-
-/**
- * Class for excluding configuration from packages.
- *
- * @Plugin(
- *   id = "alter",
- *   weight = 0,
- *   name = @Translation("Alter"),
- *   description = @Translation("Alter configuration items before they are exported. Altering includes options such as removing permissions from roles."),
- *   config_route_name = "features.assignment_alter",
- *   default_settings = {
- *     "core" = TRUE,
- *     "uuid" = TRUE,
- *     "user_permissions" = TRUE,
- *   }
- * )
- */
-class FeaturesAssignmentAlter extends FeaturesAssignmentMethodBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function assignPackages($force = FALSE) {
-    $current_bundle = $this->assigner->getBundle();
-    $settings = $current_bundle->getAssignmentSettings($this->getPluginId());
-
-    // Alter configuration items.
-    if ($settings['core'] || $settings['uuid'] || $settings['user_permissions']) {
-      $config_collection = $this->featuresManager->getConfigCollection();
-      foreach ($config_collection as &$config) {
-        $data = $config->getData();
-        if ($settings['core']) {
-          unset($data['_core']);
-        }
-        // Unset UUID for configuration entities.
-        if ($settings['uuid'] && $config->getType() !== FeaturesManagerInterface::SYSTEM_SIMPLE_CONFIG) {
-          unset($data['uuid']);
-        }
-        // Unset permissions for user roles. Doing so facilitates packaging
-        // roles that may have permissions that relate to multiple packages.
-        if ($settings['user_permissions'] && $config->getType() == 'user_role') {
-          // Unset and not empty permissions data to prevent loss of configured
-          // role permissions in the event of a feature revert.
-          unset($data['permissions']);
-        }
-        $config->setData($data);
-      }
-      // Clean up the $config pass by reference.
-      unset($config);
-
-      // Register the updated data.
-      $this->featuresManager->setConfigCollection($config_collection);
-    }
-
-  }
-
-}
diff --git a/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentBaseType.php b/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentBaseType.php
deleted file mode 100644
index a8f83cb6409259fe36cd3958d259be7ff61784fa..0000000000000000000000000000000000000000
--- a/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentBaseType.php
+++ /dev/null
@@ -1,68 +0,0 @@
-<?php
-
-namespace Drupal\features\Plugin\FeaturesAssignment;
-
-use Drupal\Component\Utility\Unicode;
-use Drupal\features\FeaturesAssignmentMethodBase;
-
-/**
- * Class for assigning configuration to packages based on entity types.
- *
- * @Plugin(
- *   id = "base",
- *   weight = -2,
- *   name = @Translation("Base type"),
- *   description = @Translation("Use designated types of configuration as the base for configuration package modules. For example, if content types are selected as a base type, a package will be generated for each content type and will include all configuration dependent on that content type."),
- *   config_route_name = "features.assignment_base",
- *   default_settings = {
- *     "types" = {
- *       "config" = {},
- *       "content" = {}
- *     }
- *   }
- * )
- */
-class FeaturesAssignmentBaseType extends FeaturesAssignmentMethodBase {
-  /**
-   * {@inheritdoc}
-   */
-  public function assignPackages($force = FALSE) {
-    $current_bundle = $this->assigner->getBundle();
-    $settings = $current_bundle->getAssignmentSettings($this->getPluginId());
-    $config_base_types = $settings['types']['config'];
-
-    $config_types = $this->featuresManager->listConfigTypes();
-    $config_collection = $this->featuresManager->getConfigCollection();
-
-    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.', ['@label' => $item->getLabel(), '@type' => Unicode::strtolower($config_types[$item->getType()])]);
-          if (isset($item->getData()['description'])) {
-            $description .= ' ' . $item->getData()['description'];
-          }
-          $this->featuresManager->initPackage($item->getShortName(), $item->getLabel(), $description, 'module', $current_bundle);
-          // Update list with the package we just added.
-          try {
-            $this->featuresManager->assignConfigPackage($item->getShortName(), [$item_name]);
-          }
-          catch (\Exception $exception) {
-            \Drupal::logger('features')->error($exception->getMessage());
-          }
-        }
-      }
-    }
-
-    $entity_types = $this->entityTypeManager->getDefinitions();
-
-    $content_base_types = $settings['types']['content'];
-    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.', ['@label' => $label]);
-        $this->featuresManager->initPackage($entity_type_id, $label, $description, 'module', $current_bundle);
-      }
-    }
-  }
-
-}
diff --git a/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentCoreType.php b/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentCoreType.php
deleted file mode 100644
index d221b31a8f88522b42a9ed3a34222371b0c14268..0000000000000000000000000000000000000000
--- a/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentCoreType.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-namespace Drupal\features\Plugin\FeaturesAssignment;
-
-use Drupal\features\FeaturesAssignmentMethodBase;
-
-/**
- * Class for assigning configuration to a core package based on entity types.
- *
- * @Plugin(
- *   id = "core",
- *   weight = 5,
- *   name = @Translation("Core type"),
- *   description = @Translation("Assign designated types of configuration to a core configuration package module. For example, if image styles are selected as a core type, a core package will be generated and image styles will be assigned to it."),
- *   config_route_name = "features.assignment_core",
- *   default_settings = {
- *     "types" = {
- *       "config" = {},
- *     }
- *   }
- * )
- */
-class FeaturesAssignmentCoreType extends FeaturesAssignmentMethodBase {
-  /**
-   * {@inheritdoc}
-   */
-  public function assignPackages($force = FALSE) {
-    $current_bundle = $this->assigner->getBundle();
-    $machine_name = 'core';
-    $name = $this->t('Core');
-    $description = $this->t('Provides core components required by other features.');
-    $package = $this->featuresManager->initPackage($machine_name, $name, $description, 'module', $current_bundle);
-    $this->assignPackageByConfigTypes($package->getMachineName(), $force);
-  }
-
-
-}
diff --git a/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentDependency.php b/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentDependency.php
deleted file mode 100644
index e8b596e68568f795e6dd99989a1cb2978957f2dd..0000000000000000000000000000000000000000
--- a/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentDependency.php
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-
-namespace Drupal\features\Plugin\FeaturesAssignment;
-
-use Drupal\features\FeaturesAssignmentMethodBase;
-
-/**
- * Class for assigning configuration to packages based on configuration
- * dependencies.
- *
- * @Plugin(
- *   id = "dependency",
- *   weight = 15,
- *   name = @Translation("Dependency"),
- *   description = @Translation("Add to packages configuration dependent on items already in that package."),
- * )
- */
-class FeaturesAssignmentDependency extends FeaturesAssignmentMethodBase {
-  /**
-   * {@inheritdoc}
-   */
-  public function assignPackages($force = FALSE) {
-    $this->featuresManager->assignConfigDependents();
-  }
-
-}
diff --git a/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentExclude.php b/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentExclude.php
deleted file mode 100644
index 75fecb92ddf1fbf7a7fabbbe0b8a7509c7005512..0000000000000000000000000000000000000000
--- a/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentExclude.php
+++ /dev/null
@@ -1,149 +0,0 @@
-<?php
-
-namespace Drupal\features\Plugin\FeaturesAssignment;
-
-use Drupal\features\FeaturesAssignmentMethodBase;
-
-/**
- * Class for excluding configuration from packages.
- *
- * @Plugin(
- *   id = "exclude",
- *   weight = -5,
- *   name = @Translation("Exclude"),
- *   description = @Translation("Exclude configuration items from packaging by various methods including by configuration type. When configuration is excluded, it won't be automatically reassigned to other packages."),
- *   config_route_name = "features.assignment_exclude",
- *   default_settings = {
- *     "curated" = FALSE,
- *     "module" = {
- *       "installed" = FALSE,
- *       "profile" = FALSE,
- *       "namespace" = FALSE,
- *       "namespace_any" = FALSE,
- *     },
- *     "types" = { "config" = {} }
- *   }
- * )
- */
-class FeaturesAssignmentExclude extends FeaturesAssignmentMethodBase {
-  /**
-   * {@inheritdoc}
-   */
-  public function assignPackages($force = FALSE) {
-    $current_bundle = $this->assigner->getBundle();
-    $settings = $current_bundle->getAssignmentSettings($this->getPluginId());
-
-    $config_collection = $this->featuresManager->getConfigCollection();
-
-    // Exclude by configuration type.
-    $exclude_types = $settings['types']['config'];
-    if (!empty($exclude_types)) {
-      foreach ($config_collection as $item_name => $item) {
-        // Don't exclude already-assigned items.
-        if (empty($item->getPackage()) && in_array($item->getType(), $exclude_types)) {
-          $item->setExcluded(TRUE);
-        }
-      }
-    }
-
-    // Exclude configuration already provided by modules.
-    $exclude_module = $settings['module'];
-    if (!empty($exclude_module['installed'])) {
-      $install_list = $this->featuresManager->getExtensionStorages()->listAll();
-
-      // There are two settings that can limit what's included.
-      // First, we can skip configuration provided by the install profile.
-      $module_profile = !empty($exclude_module['profile']);
-      // Second, we can skip configuration provided by namespaced modules.
-      $module_namespace = !empty($exclude_module['namespace']);
-      if ($module_profile || $module_namespace) {
-        $profile_list = [];
-        $extension_list = [];
-        // Load the names of any configuration objects provided by the install
-        // profile.
-        if ($module_profile) {
-          $all_modules = $this->featuresManager->getAllModules();
-          // FeaturesBundleInterface::getProfileName() would return the profile
-          // for the current bundle, if any. We want the profile that was
-          // installed.
-          $profile_name = drupal_get_profile();
-          if (isset($all_modules[$profile_name])) {
-            $profile_list = $this->featuresManager->listExtensionConfig($all_modules[$profile_name]);
-            // If the configuration has been assigned to a feature that's
-            // present on the file system, don't make an exception for it.
-            foreach ($all_modules as $name => $extension) {
-              if ($name != $profile_name && $this->featuresManager->isFeatureModule($extension)) {
-                $profile_list = array_diff($profile_list, $this->featuresManager->listExtensionConfig($extension));
-              }
-            }
-          }
-        }
-        // Load the names of any configuration objects provided by modules
-        // having the namespace of the current package set.
-        if ($module_namespace) {
-          $modules = $this->featuresManager->getFeaturesModules($current_bundle);
-          foreach ($modules as $extension) {
-            // Only make exception for uninstalled modules or
-            // if namespace_any is set
-            if (!empty($exclude_module['namespace_any']) || !$this->featuresManager->extensionEnabled($extension)) {
-              $extension_list = array_merge($extension_list, $this->featuresManager->listExtensionConfig($extension));
-            }
-          }
-        }
-        // If any configuration was found, remove it from the list.
-        $install_list = array_diff($install_list, $profile_list, $extension_list);
-      }
-      foreach ($install_list as $item_name) {
-        if (isset($config_collection[$item_name])) {
-          // Flag extension-provided configuration, which should not be added
-          // to regular features but can be added to an install profile.
-          $config_collection[$item_name]->setProviderExcluded(TRUE);
-        }
-      }
-    }
-
-    // Exclude configuration items on a curated list of site-specific
-    // configuration.
-    if ($settings['curated']) {
-      $item_names = [
-        'core.extension',
-        'field.settings',
-        'field_ui.settings',
-        'filter.settings',
-        'forum.settings',
-        'image.settings',
-        'node.settings',
-        'system.authorize',
-        'system.date',
-        'system.file',
-        'system.diff',
-        'system.logging',
-        'system.maintenance',
-        'system.performance',
-        'system.site',
-        'update.settings',
-      ];
-      foreach ($item_names as $item_name) {
-        unset($config_collection[$item_name]);
-      }
-      // Unset role-related actions that are automatically created by the
-      // User module.
-      // @see user_user_role_insert()
-      $prefixes = [
-        'system.action.user_add_role_action.',
-        'system.action.user_remove_role_action.',
-      ];
-      foreach (array_keys($config_collection) as $item_name) {
-        foreach ($prefixes as $prefix) {
-          if (strpos($item_name, $prefix) === 0) {
-            unset($config_collection[$item_name]);
-          }
-        }
-      }
-    }
-
-    // Register the updated data.
-    $this->featuresManager->setConfigCollection($config_collection);
-  }
-
-}
diff --git a/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentExisting.php b/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentExisting.php
deleted file mode 100644
index 6d78628d2608533c1bd2a6d518f383c7795dbc48..0000000000000000000000000000000000000000
--- a/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentExisting.php
+++ /dev/null
@@ -1,58 +0,0 @@
-<?php
-
-namespace Drupal\features\Plugin\FeaturesAssignment;
-
-use Drupal\features\FeaturesAssignmentMethodBase;
-use Drupal\features\FeaturesManagerInterface;
-
-/**
- * Class for assigning existing modules to packages.
- *
- * @Plugin(
- *   id = "existing",
- *   weight = 12,
- *   name = @Translation("Existing"),
- *   description = @Translation("Add exported config to existing packages."),
- * )
- */
-class FeaturesAssignmentExisting extends FeaturesAssignmentMethodBase {
-  /**
-   * Calls assignConfigPackage without allowing exceptions to abort us.
-   *
-   * @param string $machine_name
-   *   Machine name of package.
-   * @param \Drupal\Core\Extension\Extension $extension
-   *   An Extension object.
-   */
-  protected function safeAssignConfig($machine_name, $extension) {
-    $config = $this->featuresManager->listExtensionConfig($extension);
-    try {
-      $this->featuresManager->assignConfigPackage($machine_name, $config);
-    }
-    catch (\Exception $exception) {
-      \Drupal::logger('features')->error($exception->getMessage());
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function assignPackages($force = FALSE) {
-    $packages = $this->featuresManager->getPackages();
-
-    // Assign config to installed modules first.
-    foreach ($packages as $name => $package) {
-      // @todo Introduce $package->isInstalled() and / or $package->isUninstalled().
-      if ($package->getStatus() === FeaturesManagerInterface::STATUS_INSTALLED) {
-        $this->safeAssignConfig($package->getMachineName(), $package->getExtension());
-      }
-    }
-    // Now assign to uninstalled modules.
-    foreach ($packages as $name => $package) {
-      if ($package->getStatus() === FeaturesManagerInterface::STATUS_UNINSTALLED) {
-        $this->safeAssignConfig($package->getMachineName(), $package->getExtension());
-      }
-    }
-  }
-
-}
diff --git a/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentForwardDependency.php b/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentForwardDependency.php
deleted file mode 100644
index c0c5801e57779cd8a2bfb95d512544a96c39e238..0000000000000000000000000000000000000000
--- a/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentForwardDependency.php
+++ /dev/null
@@ -1,78 +0,0 @@
-<?php
-
-namespace Drupal\features\Plugin\FeaturesAssignment;
-
-use Drupal\Component\Graph\Graph;
-use Drupal\features\FeaturesAssignmentMethodBase;
-
-/**
- * Class for assigning configuration to packages based on forward dependencies.
- *
- * @Plugin(
- *   id = "forward_dependency",
- *   weight = 20,
- *   name = @Translation("Forward dependency"),
- *   description = @Translation("Add to packages configuration on which items in the package depend."),
- * )
- */
-class FeaturesAssignmentForwardDependency extends FeaturesAssignmentMethodBase {
-  /**
-   * {@inheritdoc}
-   */
-  public function assignPackages($force = FALSE) {
-    $config_collection = $this->featuresManager->getConfigCollection();
-    $ordered = $this->dependencyOrder($config_collection);
-
-    foreach ($ordered as $name) {
-      $item = $config_collection[$name];
-      if ($item->getPackage()) {
-        // Already has a package, not our business.
-        continue;
-      }
-
-      // Find packages of dependent items.
-      $dependent_packages = [];
-      foreach ($item->getDependents() as $dependent) {
-        if (isset($config_collection[$dependent])) {
-          if ($package = $config_collection[$dependent]->getPackage()) {
-            $dependent_packages[$package] = $package;
-          }
-        }
-      }
-
-      // If zero or multiple packages, we don't know what to do.
-      if (count($dependent_packages) == 1) {
-        $package = key($dependent_packages);
-        $this->featuresManager->assignConfigPackage($package, [$name]);
-      }
-    }
-  }
-
-  /**
-   * Get config items such that each item comes before anything it depends on.
-   *
-   * @param \Drupal\features\ConfigurationItem[] $config_collection
-   *   A collection of configuration items.
-   *
-   * @return string[]
-   *   The names of configuration items, in dependency order.
-   */
-  protected function dependencyOrder($config_collection) {
-    // Populate a graph.
-    $graph = [];
-    foreach ($config_collection as $config) {
-      $graph[$config->getName()] = [];
-      foreach ($config->getDependents() as $dependent) {
-        $graph[$config->getName()]['edges'][$dependent] = 1;
-      }
-    }
-    $graph_object = new Graph($graph);
-    $graph = $graph_object->searchAndSort();
-
-    // Order by inverse weight.
-    $weights = array_column($graph, 'weight');
-    array_multisort($weights, SORT_DESC, $graph);
-    return array_keys($graph);
-  }
-
-}
diff --git a/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentNamespace.php b/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentNamespace.php
deleted file mode 100644
index bc2b6d00f360613b07f00b7df43d7c60c098ed71..0000000000000000000000000000000000000000
--- a/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentNamespace.php
+++ /dev/null
@@ -1,38 +0,0 @@
-<?php
-
-namespace Drupal\features\Plugin\FeaturesAssignment;
-
-use Drupal\features\FeaturesAssignmentMethodBase;
-
-/**
- * Class for assigning configuration to packages based on namespaces.
- *
- * @Plugin(
- *   id = "namespace",
- *   weight = 0,
- *   name = @Translation("Namespace"),
- *   description = @Translation("Add config to packages that contain that package's machine name."),
- * )
- */
-class FeaturesAssignmentNamespace extends FeaturesAssignmentMethodBase {
-  /**
-   * {@inheritdoc}
-   */
-  public function assignPackages($force = FALSE) {
-    $packages = $this->featuresManager->getPackages();
-    $current_bundle = $this->assigner->getBundle();
-
-    // Build an array of patterns.
-    // Keys are short names while values are full machine names.
-    // We need full names because existing packages may receive machine names
-    // prefixed with a bundle name.
-    $patterns = [];
-    foreach ($packages as $package) {
-      $machine_name = $package->getMachineName();
-      $pattern = $current_bundle->getShortName($machine_name);
-      $patterns[$pattern] = $machine_name;
-    }
-    $this->featuresManager->assignConfigByPattern($patterns);
-  }
-
-}
diff --git a/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentOptionalType.php b/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentOptionalType.php
deleted file mode 100644
index d76835785e72f45ac9c69c4f31f07bdbbcabf005..0000000000000000000000000000000000000000
--- a/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentOptionalType.php
+++ /dev/null
@@ -1,33 +0,0 @@
-<?php
-
-namespace Drupal\features\Plugin\FeaturesAssignment;
-
-use Drupal\Core\Config\InstallStorage;
-use Drupal\features\FeaturesAssignmentMethodBase;
-
-/**
- * Class for assigning configuration to the
- * InstallStorage::CONFIG_OPTIONAL_DIRECTORY based on entity types.
- *
- * @Plugin(
- *   id = "optional",
- *   weight = 0,
- *   name = @Translation("Optional type"),
- *   description = @Translation("Assign designated types of configuration to the 'config/optional' install directory. For example, if views are selected as optional, views assigned to any feature will be exported to the 'config/optional' directory and will not create a dependency on the Views module."),
- *   config_route_name = "features.assignment_optional",
- *   default_settings = {
- *     "types" = {
- *       "config" = {},
- *     }
- *   }
- * )
- */
-class FeaturesAssignmentOptionalType extends FeaturesAssignmentMethodBase {
-  /**
-   * {@inheritdoc}
-   */
-  public function assignPackages($force = FALSE) {
-    $this->assignSubdirectoryByConfigTypes(InstallStorage::CONFIG_OPTIONAL_DIRECTORY);
-  }
-
-}
diff --git a/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentPackages.php b/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentPackages.php
deleted file mode 100644
index 759e9efc793a6ea6584ae6ed21e58874d06659f9..0000000000000000000000000000000000000000
--- a/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentPackages.php
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php
-
-namespace Drupal\features\Plugin\FeaturesAssignment;
-
-use Drupal\features\FeaturesAssignmentMethodBase;
-
-/**
- * Class for assigning existing modules to packages.
- *
- * @Plugin(
- *   id = "packages",
- *   weight = -20,
- *   name = @Translation("Packages"),
- *   description = @Translation("Detect and add existing package modules."),
- * )
- */
-class FeaturesAssignmentPackages extends FeaturesAssignmentMethodBase {
-  /**
-   * {@inheritdoc}
-   */
-  public function assignPackages($force = FALSE) {
-    $bundle = $this->assigner->getBundle();
-    $existing = $this->featuresManager->getFeaturesModules();
-    foreach ($existing as $extension) {
-      $package = $this->featuresManager->initPackageFromExtension($extension);
-      $short_name = $package->getMachineName();
-
-      // Copy over package excluded settings, if any.
-      if ($package->getExcluded()) {
-        $config_collection = $this->featuresManager->getConfigCollection();
-        foreach ($package->getExcluded() as $config_name) {
-          if (isset($config_collection[$config_name])) {
-            $package_excluded = $config_collection[$config_name]->getPackageExcluded();
-            $package_excluded[] = $short_name;
-            $config_collection[$config_name]->setPackageExcluded($package_excluded);
-          }
-        }
-        $this->featuresManager->setConfigCollection($config_collection);
-      }
-
-      // Assign required components, if any.
-      if ($package->getRequired() !== FALSE) {
-        $config = $package->getRequired();
-        if (empty($config) || !is_array($config)) {
-          // if required is "true" or empty, add all config as required
-          $config = $this->featuresManager->listExtensionConfig($extension);
-        }
-        $this->featuresManager->assignConfigPackage($short_name, $config);
-      }
-    }
-  }
-
-}
diff --git a/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentProfile.php b/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentProfile.php
deleted file mode 100644
index 81c503e073fab4fcc792d1a391c60ea88922ac26..0000000000000000000000000000000000000000
--- a/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentProfile.php
+++ /dev/null
@@ -1,177 +0,0 @@
-<?php
-
-namespace Drupal\features\Plugin\FeaturesAssignment;
-
-use Drupal\features\FeaturesAssignmentMethodBase;
-use Drupal\Core\Config\InstallStorage;
-
-/**
- * Class for adding configuration for the optional install profile.
- *
- * @Plugin(
- *   id = "profile",
- *   weight = 10,
- *   name = @Translation("Profile"),
- *   description = @Translation("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."),
- *   config_route_name = "features.assignment_profile",
- *   default_settings = {
- *     "curated" = FALSE,
- *     "standard" = {
- *       "files" = FALSE,
- *       "dependencies" = FALSE,
- *     },
- *     "types" = { "config" = {} }
- *   }
- * )
- */
-class FeaturesAssignmentProfile extends FeaturesAssignmentMethodBase {
-  /**
-   * {@inheritdoc}
-   */
-  public function assignPackages($force = FALSE) {
-    $current_bundle = $this->assigner->getBundle();
-
-    if ($current_bundle->isProfile()) {
-      $settings = $current_bundle->getAssignmentSettings($this->getPluginId());
-
-      // Ensure the profile package exists.
-      $profile_name = $current_bundle->getProfileName();
-
-      $profile_package = $this->featuresManager->getPackage($profile_name);
-      if (empty($profile_package)) {
-        $profile_package = $this->featuresManager->initPackage($profile_name, $current_bundle->getName(), $current_bundle->getDescription(), 'profile', $current_bundle);
-      }
-
-      // Assign configuration by type.
-      $this->assignPackageByConfigTypes($profile_name, $force);
-
-      // Include a curated list of configuration.
-      if ($settings['curated']) {
-        $config_collection = $this->featuresManager->getConfigCollection();
-        $item_names = [
-          'automated_cron.settings',
-          'system.cron',
-          'system.theme',
-        ];
-        $theme_settings = $this->configFactory->get('system.theme');
-        foreach (['default', 'admin'] as $key) {
-          $item_names[] = $theme_settings->get($key) . '.settings';
-        }
-        foreach ($item_names as $item_name) {
-          if (isset($config_collection[$item_name])) {
-            try {
-              $this->featuresManager->assignConfigPackage($profile_name, [$item_name]);
-            }
-            catch (\Exception $exception) {
-              \Drupal::logger('features')->error($exception->getMessage());
-            }
-          }
-        }
-      }
-
-      // Only read in from the Standard profile if this profile doesn't already
-      // exist.
-      $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.
-        if ($settings['standard']['files']) {
-          // Add configuration from the Standard profile.
-          $config_collection = $this->featuresManager->getConfigCollection();
-          $subdirectory = InstallStorage::CONFIG_INSTALL_DIRECTORY;
-          $item_names = $this->listRequiredStandardConfig();
-          foreach ($item_names as $item_name) {
-            // If the configuration is present on the site, assign it.
-            if (isset($config_collection[$item_name])) {
-              // Only assign it if it's not already assigned to a package.
-              // @todo: if it's provided by a module, add a dependency.
-              if (!$config_collection[$item_name]->getPackage()) {
-                $this->featuresManager->assignConfigPackage($profile_name, [$item_name], $force);
-                // Reload the profile to refresh the config array after the addition.
-                $profile_package = $this->featuresManager->getPackage($profile_name);
-              }
-              // If it's already assigned to a package in the current bundle,
-              // add a dependency.
-              else {
-                $machine_name = $current_bundle->getFullName($config_collection[$item_name]->getPackage());
-                if (!in_array($machine_name, $profile_package->getDependencies())) {
-                  $profile_package->appendDependency($machine_name);
-                }
-              }
-            }
-            // Otherwise, copy it over from Standard.
-            else {
-              $filename = $item_name . '.yml';
-              $profile_package->appendFile([
-                'filename' => $filename,
-                'subdirectory' => $subdirectory,
-                'string' => file_get_contents($standard_directory . '/' . $subdirectory . '/' . $filename)
-              ]);
-            }
-          }
-
-          // Add .profile and .install files from Standard.
-          $files = [
-            'install',
-            'profile',
-          ];
-          // Iterate through the files.
-          foreach ($files as $extension) {
-            $filename = $standard_directory . '/standard.' . $extension;
-            if (file_exists($filename)) {
-              // Read the file contents.
-              $string = file_get_contents($filename);
-              // Substitute the profile's machine name and name for the Standard
-              // profile's equivalents.
-              $string = str_replace(
-                ['standard', 'Standard'],
-                [$profile_name, $current_bundle->getName()],
-                $string
-              );
-              // Add the files to those to be output.
-              $profile_package->appendFile([
-                'filename' => $profile_name . '.' . $extension,
-                'subdirectory' => NULL,
-                'string' => $string
-              ], $extension);
-            }
-          }
-        }
-        // Conditionally merge in module and theme dependencies from the
-        // 'standard' install profile.
-        if ($settings['standard']['dependencies']) {
-          $info_file_uri = $standard_directory . '/standard.info.yml';
-          if (file_exists($info_file_uri)) {
-            $profile_info = \Drupal::service('info_parser')->parse($info_file_uri);
-            $info = [
-              'dependencies' => $profile_package->getDependencies(),
-              'themes' => $profile_package->getThemes(),
-            ];
-            $info = $this->featuresManager->mergeInfoArray($info, $profile_info);
-            $profile_package->setDependencies($info['dependencies']);
-            $profile_package->setThemes($info['themes']);
-          }
-        }
-        $this->featuresManager->setPackage($profile_package);
-      }
-    }
-  }
-
-  /**
-   * Returns the list of configuration items required by the Standard install
-   * profile.
-   *
-   * If install code is adapted from the Standard profile, these configuration
-   * items will be required.
-   *
-   * @return array
-   *   An array of configuration item names.
-   */
-  protected function listRequiredStandardConfig() {
-    return [
-      'contact.form.feedback',
-      'user.role.administrator'
-    ];
-  }
-
-}
diff --git a/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentSiteType.php b/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentSiteType.php
deleted file mode 100644
index 0269658208230bcb4dfbc49068b05d0f36eb71c7..0000000000000000000000000000000000000000
--- a/web/modules/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentSiteType.php
+++ /dev/null
@@ -1,36 +0,0 @@
-<?php
-
-namespace Drupal\features\Plugin\FeaturesAssignment;
-
-use Drupal\features\FeaturesAssignmentMethodBase;
-
-/**
- * Class for assigning configuration to a site package based on entity types.
- *
- * @Plugin(
- *   id = "site",
- *   weight = 7,
- *   name = @Translation("Site type"),
- *   description = @Translation("Assign designated types of configuration to a site configuration package module. For example, if image styles are selected as a site type, a site package will be generated and image styles will be assigned to it."),
- *   config_route_name = "features.assignment_site",
- *   default_settings = {
- *     "types" = {
- *       "config" = {},
- *     }
- *   }
- * )
- */
-class FeaturesAssignmentSiteType extends FeaturesAssignmentMethodBase {
-  /**
-   * {@inheritdoc}
-   */
-  public function assignPackages($force = FALSE) {
-    $current_bundle = $this->assigner->getBundle();
-    $machine_name = 'site';
-    $name = $this->t('Site');
-    $description = $this->t('Provides site components.');
-    $package = $this->featuresManager->initPackage($machine_name, $name, $description, 'module', $current_bundle);
-    $this->assignPackageByConfigTypes($package->getMachineName(), $force);
-  }
-
-}
diff --git a/web/modules/features/src/Plugin/FeaturesGeneration/FeaturesGenerationArchive.php b/web/modules/features/src/Plugin/FeaturesGeneration/FeaturesGenerationArchive.php
deleted file mode 100644
index a40c7a6dcf95761f926f4f6ae5fa19f7c75ee8da..0000000000000000000000000000000000000000
--- a/web/modules/features/src/Plugin/FeaturesGeneration/FeaturesGenerationArchive.php
+++ /dev/null
@@ -1,292 +0,0 @@
-<?php
-
-namespace Drupal\features\Plugin\FeaturesGeneration;
-
-use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
-use Drupal\features\FeaturesGenerationMethodBase;
-use Drupal\Core\Archiver\ArchiveTar;
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\features\FeaturesBundleInterface;
-use Drupal\features\Package;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Class for generating a compressed archive of packages.
- *
- * @Plugin(
- *   id = \Drupal\features\Plugin\FeaturesGeneration\FeaturesGenerationArchive::METHOD_ID,
- *   weight = -2,
- *   name = @Translation("Download Archive"),
- *   description = @Translation("Generate packages and optional profile as a compressed archive for download."),
- * )
- */
-class FeaturesGenerationArchive extends FeaturesGenerationMethodBase implements ContainerFactoryPluginInterface {
-
-  /**
-   * The app root.
-   *
-   * @var string
-   */
-  protected $root;
-
-  /**
-   * The CSRF token generator.
-   *
-   * @var \Drupal\Core\Access\CsrfTokenGenerator
-   */
-  protected $csrfToken;
-
-  /**
-   * Creates a new FeaturesGenerationArchive instance.
-   *
-   * @param string $root
-   *   The app root.
-   * @param \Drupal\Core\Access\CsrfTokenGenerator $csrf_token
-   *   The CSRF token generator.
-   */
-  public function __construct($root, \Drupal\Core\Access\CsrfTokenGenerator $csrf_token) {
-    $this->root = $root;
-    $this->csrfToken = $csrf_token;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static(
-      $container->get('app.root'),
-      $container->get('csrf_token')
-    );
-  }
-
-  /**
-   * The package generation method id.
-   */
-  const METHOD_ID = 'archive';
-
-  /**
-   * The filename being written.
-   *
-   * @var string
-   */
-  protected $archiveName;
-
-  /**
-   * Reads and merges in existing files for a given package or profile.
-   */
-  protected function preparePackage(Package $package, array $existing_packages, FeaturesBundleInterface $bundle = NULL) {
-    if (isset($existing_packages[$package->getMachineName()])) {
-      $existing_directory = $existing_packages[$package->getMachineName()];
-    }
-    else {
-      $existing_directory = $package->getDirectory();
-    }
-    $existing_directory = $this->root . '/' . $existing_directory;
-
-    if (is_dir($existing_directory)) {
-      // Scan for all files.
-      $files = file_scan_directory($existing_directory, '/.*/');
-      // Skip any existing .features.yml as it will be replaced.
-      $exclude_files = [
-        $package->getMachineName() . '.features',
-      ];
-      foreach ($files as $file) {
-        // Skip files in the any existing configuration directory, as these
-        // will be replaced.
-        foreach (array_keys($this->featuresManager->getExtensionStorages()->getExtensionStorages()) as $directory) {
-          if (strpos($file->uri, $directory) !== FALSE) {
-            continue 2;
-          }
-        }
-        // Merge in the info file.
-        if ($file->name == $package->getMachineName() . '.info') {
-          $files = $package->getFiles();
-          $files['info']['string'] = $this->mergeInfoFile($package->getFiles()['info']['string'], $file->uri);
-          $package->setFiles($files);
-        }
-        // Read in remaining files.
-        elseif (!in_array($file->name, $exclude_files)) {
-          // Determine if the file is within a subdirectory of the
-          // extension's directory.
-          $file_directory = dirname($file->uri);
-          if ($file_directory !== $existing_directory) {
-            $subdirectory = substr($file_directory, strlen($existing_directory) + 1);
-          }
-          else {
-            $subdirectory = NULL;
-          }
-          $package->appendFile([
-            'filename' => $file->filename,
-            'subdirectory' => $subdirectory,
-            'string' => file_get_contents($file->uri)
-          ]);
-        }
-      }
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function generate(array $packages = [], FeaturesBundleInterface $bundle = NULL) {
-
-    // If no packages were specified, get all packages.
-    if (empty($packages)) {
-      $packages = $this->featuresManager->getPackages();
-    }
-
-    // Determine the best name for the tar archive.
-    // Single package export, so name by package name.
-    if (count($packages) == 1) {
-      $filename = current($packages)->getMachineName();
-    }
-    // Profile export, so name by profile.
-    elseif (isset($bundle) && $bundle->isProfile()) {
-      $filename = $bundle->getProfileName();
-    }
-    // Non-default bundle, so name by bundle.
-    elseif (isset($bundle) && !$bundle->isDefault()) {
-      $filename = $bundle->getMachineName();
-    }
-    // Set a fallback name.
-    else {
-      $filename = 'generated_features';
-    }
-
-    $return = [];
-
-    $this->archiveName = $filename . '.tar.gz';
-    $archive_name = file_directory_temp() . '/' . $this->archiveName;
-    if (file_exists($archive_name)) {
-      file_unmanaged_delete($archive_name);
-    }
-
-    $archiver = new ArchiveTar($archive_name);
-
-    // Add package files.
-    foreach ($packages as $package) {
-      if (count($packages) == 1) {
-        // Single module export, so don't generate entire modules dir structure.
-        $package->setDirectory($package->getMachineName());
-      }
-      $this->generatePackage($return, $package, $archiver);
-    }
-
-    return $return;
-  }
-
-  /**
-   * Writes a package or profile's files to an archive.
-   *
-   * @param array &$return
-   *   The return value, passed by reference.
-   * @param \Drupal\features\Package $package
-   *   The package or profile.
-   * @param ArchiveTar $archiver
-   *   The archiver.
-   */
-  protected function generatePackage(array &$return, Package $package, ArchiveTar $archiver) {
-    $success = TRUE;
-    foreach ($package->getFiles() as $file) {
-      try {
-        $this->generateFile($package->getDirectory(), $file, $archiver);
-      }
-      catch (\Exception $exception) {
-        $this->failure($return, $package, $exception);
-        $success = FALSE;
-        break;
-      }
-    }
-    if ($success) {
-      $this->success($return, $package);
-    }
-  }
-
-  /**
-   * Registers a successful package or profile archive operation.
-   *
-   * @param array &$return
-   *   The return value, passed by reference.
-   * @param \Drupal\features\Package $package
-   *   The package or profile.
-   */
-  protected function success(array &$return, Package $package) {
-    $type = $package->getType() == 'module' ? $this->t('Package') : $this->t('Profile');
-    $return[] = [
-      'success' => TRUE,
-      // Archive writing doesn't merit a message, and if done through the UI
-      // would appear on the subsequent page load.
-      'display' => FALSE,
-      'message' => '@type @package written to archive.',
-      'variables' => [
-        '@type' => $type,
-        '@package' => $package->getName(),
-      ],
-    ];
-  }
-
-  /**
-   * Registers a failed package or profile archive operation.
-   *
-   * @param array &$return
-   *   The return value, passed by reference.
-   * @param \Drupal\features\Package $package
-   *   The package or profile.
-   * @param \Exception $exception
-   *   The exception object.
-   * @param string $message
-   *   Error message when there isn't an Exception object.
-   */
-  protected function failure(array &$return, Package $package, \Exception $exception = NULL, $message = '') {
-    $type = $package->getType() == 'module' ? $this->t('Package') : $this->t('Profile');
-    $return[] = [
-      'success' => FALSE,
-      // Archive writing doesn't merit a message, and if done through the UI
-      // would appear on the subsequent page load.
-      'display' => FALSE,
-      'message' => '@type @package not written to archive. Error: @error.',
-      'variables' => [
-        '@type' => $type,
-        '@package' => $package->getName(),
-        '@error' => isset($exception) ? $exception->getMessage() : $message,
-      ],
-    ];
-  }
-
-  /**
-   * Writes a file to the file system, creating its directory as needed.
-   *
-   * @param string $directory
-   *   The extension's directory.
-   * @param array $file
-   *   Array with the following keys:
-   *   - 'filename': the name of the file.
-   *   - 'subdirectory': any subdirectory of the file within the extension
-   *      directory.
-   *   - 'string': the contents of the file.
-   * @param ArchiveTar $archiver
-   *   The archiver.
-   *
-   * @throws Exception
-   */
-  protected function generateFile($directory, array $file, ArchiveTar $archiver) {
-    $filename = $directory;
-    if (!empty($file['subdirectory'])) {
-      $filename .= '/' . $file['subdirectory'];
-    }
-    $filename .= '/' . $file['filename'];
-    // Set the mode to 0644 rather than the default of 0600.
-    if ($archiver->addString($filename, $file['string'], FALSE, ['mode' => 0644]) === FALSE) {
-      throw new \Exception($this->t('Failed to archive file @filename.', ['@filename' => $file['filename']]));
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function exportFormSubmit(array &$form, FormStateInterface $form_state) {
-    // Redirect to the archive file download.
-    $form_state->setRedirect('features.export_download', ['uri' => $this->archiveName, 'token' => $this->csrfToken->get($this->archiveName)]);
-  }
-
-}
diff --git a/web/modules/features/src/Plugin/FeaturesGeneration/FeaturesGenerationWrite.php b/web/modules/features/src/Plugin/FeaturesGeneration/FeaturesGenerationWrite.php
deleted file mode 100644
index 5844c0e2d1c3a89f637f29194bf05fd5dfc08848..0000000000000000000000000000000000000000
--- a/web/modules/features/src/Plugin/FeaturesGeneration/FeaturesGenerationWrite.php
+++ /dev/null
@@ -1,237 +0,0 @@
-<?php
-
-namespace Drupal\features\Plugin\FeaturesGeneration;
-
-use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
-use Drupal\Core\File\FileSystemInterface;
-use Drupal\features\FeaturesGenerationMethodBase;
-use Drupal\features\FeaturesBundleInterface;
-use Drupal\features\Package;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Class for writing packages to the local file system.
- *
- * @Plugin(
- *   id = \Drupal\features\Plugin\FeaturesGeneration\FeaturesGenerationWrite::METHOD_ID,
- *   weight = 2,
- *   name = @Translation("Write"),
- *   description = @Translation("Write packages and optional profile to the file system."),
- * )
- */
-class FeaturesGenerationWrite extends FeaturesGenerationMethodBase implements ContainerFactoryPluginInterface {
-
-  /**
-   * The package generation method id.
-   */
-  const METHOD_ID = 'write';
-
-  /**
-   * The app root.
-   *
-   * @var string
-   */
-  protected $root;
-
-  /**
-   * The file_system service.
-   * @var \Drupal\Core\File\FileSystemInterface
-   */
-  protected $fileSystem;
-
-  /**
-   * Creates a new FeaturesGenerationWrite instance.
-   *
-   * @param string $root
-   *   The app root.
-   */
-  public function __construct($root, FileSystemInterface $fileSystem) {
-    $this->root = $root;
-    $this->fileSystem = $fileSystem;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static(
-      $container->get('app.root'),
-      $container->get('file_system')
-    );
-  }
-
-  /**
-   * Reads and merges in existing files for a given package or profile.
-   *
-   * @param \Drupal\features\Package &$package
-   *   The package.
-   * @param array $existing_packages
-   *   An array of existing packages.
-   * @param \Drupal\features\FeaturesBundleInterface $bundle
-   *   The bundle the package belongs to.
-   */
-  protected function preparePackage(Package $package, array $existing_packages, FeaturesBundleInterface $bundle = NULL) {
-    // If this package is already present, prepare files.
-    if (isset($existing_packages[$package->getMachineName()])) {
-      $existing_directory = $existing_packages[$package->getMachineName()];
-      $package->setDirectory($existing_directory);
-    }
-    else {
-      $existing_directory = $package->getDirectory();
-    }
-
-    // Merge in the info file.
-    $info_file_uri = $this->root . '/' . $existing_directory . '/' . $package->getMachineName() . '.info.yml';
-    if (file_exists($info_file_uri)) {
-      $files = $package->getFiles();
-      $files['info']['string'] = $this->mergeInfoFile($package->getFiles()['info']['string'], $info_file_uri);
-      $package->setFiles($files);
-
-      // Remove the config directories, as they will be replaced.
-      foreach (array_keys($this->featuresManager->getExtensionStorages()
-        ->getExtensionStorages()) as $directory) {
-        $config_directory = $this->root . '/' . $existing_directory . '/' . $directory;
-        if (is_dir($config_directory)) {
-          file_unmanaged_delete_recursive($config_directory);
-        }
-      }
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function generate(array $packages = [], FeaturesBundleInterface $bundle = NULL) {
-    // If no packages were specified, get all packages.
-    if (empty($packages)) {
-      $packages = $this->featuresManager->getPackages();
-    }
-
-    $return = [];
-
-    // Add package files.
-    // We need to update the system.module.files state because it's cached.
-    // Cannot just call system_rebuild_module_data() because $listing->scan() has
-    // it's own internal static cache that we cannot clear at this point.
-    $files = \Drupal::state()->get('system.module.files');
-    foreach ($packages as $package) {
-      $this->generatePackage($return, $package);
-      if (!isset($files[$package->getMachineName()]) && isset($package->getFiles()['info'])) {
-        $files[$package->getMachineName()] = $package->getDirectory() . '/' . $package->getFiles()['info']['filename'];
-      }
-    }
-
-    // Rebuild system module cache
-    \Drupal::state()->set('system.module.files', $files);
-
-    return $return;
-  }
-
-  /**
-   * Writes a package or profile's files to the file system.
-   *
-   * @param array &$return
-   *   The return value, passed by reference.
-   * @param \Drupal\features\Package $package
-   *   The package or profile.
-   */
-  protected function generatePackage(array &$return, Package $package) {
-    if (!$package->getFiles()) {
-      $this->failure($return, $package, NULL, $this->t('No configuration was selected to be exported.'));
-      return;
-    }
-    $success = TRUE;
-    foreach ($package->getFiles() as $file) {
-      try {
-        $this->generateFile($package->getDirectory(), $file);
-      }
-      catch (\Exception $exception) {
-        $this->failure($return, $package, $exception);
-        $success = FALSE;
-        break;
-      }
-    }
-    if ($success) {
-      $this->success($return, $package);
-    }
-  }
-
-  /**
-   * Registers a successful package or profile write operation.
-   *
-   * @param array &$return
-   *   The return value, passed by reference.
-   * @param \Drupal\features\Package $package
-   *   The package or profile.
-   */
-  protected function success(array &$return, Package $package) {
-    $type = $package->getType() == 'module' ? $this->t('Package') : $this->t('Profile');
-    $return[] = [
-      'success' => TRUE,
-      'display' => TRUE,
-      'message' => '@type @package written to @directory.',
-      'variables' => [
-        '@type' => $type,
-        '@package' => $package->getName(),
-        '@directory' => $package->getDirectory(),
-      ],
-    ];
-  }
-
-  /**
-   * Registers a failed package or profile write operation.
-   *
-   * @param array &$return
-   *   The return value, passed by reference.
-   * @param \Drupal\features\Package $package
-   *   The package or profile.
-   * @param \Exception $exception
-   *   The exception object.
-   * @param string $message
-   *   Error message when there isn't an Exception object.
-   */
-  protected function failure(array &$return, Package $package, \Exception $exception = NULL, $message = '') {
-    $type = $package->getType() == 'module' ? $this->t('Package') : $this->t('Profile');
-    $return[] = [
-      'success' => FALSE,
-      'display' => TRUE,
-      'message' => '@type @package not written to @directory. Error: @error.',
-      'variables' => [
-        '@type' => $type,
-        '@package' => $package->getName(),
-        '@directory' => $package->getDirectory(),
-        '@error' => isset($exception) ? $exception->getMessage() : $message,
-      ],
-    ];
-  }
-
-  /**
-   * Writes a file to the file system, creating its directory as needed.
-   *
-   * @param string $directory
-   *   The extension's directory.
-   * @param array $file
-   *   Array with the following keys:
-   *   - 'filename': the name of the file.
-   *   - 'subdirectory': any subdirectory of the file within the extension
-   *      directory.
-   *   - 'string': the contents of the file.
-   *
-   * @throws Exception
-   */
-  protected function generateFile($directory, array $file) {
-    if (!empty($file['subdirectory'])) {
-      $directory .= '/' . $file['subdirectory'];
-    }
-    $directory = $this->root . '/' . $directory;
-    if (!is_dir($directory)) {
-      if ($this->fileSystem->mkdir($directory, NULL, TRUE) === FALSE) {
-        throw new \Exception($this->t('Failed to create directory @directory.', ['@directory' => $directory]));
-      }
-    }
-    if (file_put_contents($directory . '/' . $file['filename'], $file['string']) === FALSE) {
-      throw new \Exception($this->t('Failed to write file @filename.', ['@filename' => $file['filename']]));
-    }
-  }
-
-}
diff --git a/web/modules/features/tests/modules/test_feature/config/install/core.date_format.short.yml b/web/modules/features/tests/modules/test_feature/config/install/core.date_format.short.yml
deleted file mode 100644
index f7fbe193a1db067a844ab309b29a0ce2edf2f013..0000000000000000000000000000000000000000
--- a/web/modules/features/tests/modules/test_feature/config/install/core.date_format.short.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-langcode: en
-status: true
-dependencies: {  }
-id: short
-label: 'Default short date'
-locked: false
-pattern: 'm/d/Y - H:i'
diff --git a/web/modules/features/tests/modules/test_feature/config/install/system.cron.yml b/web/modules/features/tests/modules/test_feature/config/install/system.cron.yml
deleted file mode 100644
index e6f30d3d2d8e3a8b8012df9b053938ce86928974..0000000000000000000000000000000000000000
--- a/web/modules/features/tests/modules/test_feature/config/install/system.cron.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-threshold:
-  requirements_warning: 172800
-  requirements_error: 1209600
diff --git a/web/modules/features/tests/modules/test_feature/test_feature.features.yml b/web/modules/features/tests/modules/test_feature/test_feature.features.yml
deleted file mode 100644
index cbe4b9e2f069ea2f9925f34ff30535454879eaa1..0000000000000000000000000000000000000000
--- a/web/modules/features/tests/modules/test_feature/test_feature.features.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-bundle: test
-excluded:
-  - system.theme
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
deleted file mode 100644
index b90578e884831465e244a463bb0a6b04d24aec19..0000000000000000000000000000000000000000
--- a/web/modules/features/tests/modules/test_feature/test_feature.info.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-name: feature
-type: module
-# core: 8.x
-package: Test
-# Force this to install after features.
-dependencies:
-  - features
-
-# Information added by Drupal.org packaging script on 2018-09-09
-version: '8.x-3.8'
-core: '8.x'
-project: 'features'
-datestamp: 1536512288
diff --git a/web/modules/features/tests/modules/test_mybundle_core/config/install/core.date_format.long.yml b/web/modules/features/tests/modules/test_mybundle_core/config/install/core.date_format.long.yml
deleted file mode 100644
index 9e385f1c16877c554a79a0ce14215d90c405d5c3..0000000000000000000000000000000000000000
--- a/web/modules/features/tests/modules/test_mybundle_core/config/install/core.date_format.long.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-langcode: en
-status: true
-dependencies: {  }
-id: long
-label: 'Default long date'
-locked: false
-pattern: 'l, F j, Y - H:i'
diff --git a/web/modules/features/tests/modules/test_mybundle_core/test_mybundle_core.features.yml b/web/modules/features/tests/modules/test_mybundle_core/test_mybundle_core.features.yml
deleted file mode 100644
index 3387e5fee59b597dcfe3d194090dba1e5649be9a..0000000000000000000000000000000000000000
--- a/web/modules/features/tests/modules/test_mybundle_core/test_mybundle_core.features.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-bundle: test_mybundle
-excluded:
-  - system.theme
-required:
-  - core.date_format.long
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
deleted file mode 100644
index 2f0e6404ab97e692cfa72f9e154b11927f7ecb2b..0000000000000000000000000000000000000000
--- a/web/modules/features/tests/modules/test_mybundle_core/test_mybundle_core.info.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-name: Test Core
-type: module
-# core: 8.x
-package: Test
-# Ensure features is enabled first
-dependencies:
-  - features
-
-# Information added by Drupal.org packaging script on 2018-09-09
-version: '8.x-3.8'
-core: '8.x'
-project: 'features'
-datestamp: 1536512288
diff --git a/web/modules/features/tests/src/Kernel/Entity/FeaturesBundleIntegrationTest.php b/web/modules/features/tests/src/Kernel/Entity/FeaturesBundleIntegrationTest.php
deleted file mode 100644
index aaf62bc726c18b02216c193018f8c1264897ef2e..0000000000000000000000000000000000000000
--- a/web/modules/features/tests/src/Kernel/Entity/FeaturesBundleIntegrationTest.php
+++ /dev/null
@@ -1,82 +0,0 @@
-<?php
-
-namespace Drupal\Tests\features\Kernel\Entity;
-
-use Drupal\features\Entity\FeaturesBundle;
-use Drupal\features\FeaturesBundleInterface;
-use Drupal\KernelTests\KernelTestBase;
-
-/**
- * @coversDefaultClass \Drupal\features\Entity\FeaturesBundle
- * @group features
- */
-class FeaturesBundleIntegrationTest extends KernelTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static $modules  = ['features'];
-
-  public function testCrud() {
-    $bundle = FeaturesBundle::create([
-      'machine_name' => 'test',
-      'name' => 'Test',
-    ]);
-    $bundle->save();
-
-    /** @var \Drupal\features\Entity\FeaturesBundle $bundle */
-    $bundle = FeaturesBundle::load('test');
-    $this->assertEquals('Test', $bundle->getName());
-  }
-
-  /**
-   * @covers ::isDefault
-   */
-  public function testIsDefaultWithDefaultBundle() {
-    $bundle = FeaturesBundle::create([
-      'machine_name' => FeaturesBundleInterface::DEFAULT_BUNDLE,
-    ]);
-
-    $this->assertTrue($bundle->isDefault());
-  }
-
-  /**
-   * @covers ::isDefault
-   */
-  public function testIsDefaultWithNonDefaultBundle() {
-    $bundle = FeaturesBundle::create([
-      'machine_name' => 'other',
-    ]);
-
-    $this->assertFalse($bundle->isDefault());
-  }
-
-  /**
-   * @covers ::getFullName
-   */
-  public function testGetFullName() {
-  }
-
-  /**
-   * @covers ::getShortName
-   */
-  public function testGetShortName() {
-  }
-
-  /**
-   * @covers ::getProfileName
-   * @covers ::setProfileName
-   */
-  public function testGetProfile() {
-    $bundle = FeaturesBundle::create([
-      'machine_name' => 'other',
-      'profile_name' => 'example',
-      'is_profile' => TRUE,
-    ]);
-    $this->assertEquals('example', $bundle->getProfileName());
-
-    $bundle->setProfileName('example2');
-    $this->assertEquals('example2', $bundle->getProfileName());
-  }
-
-}
diff --git a/web/modules/features/tests/src/Kernel/FeaturesAssignTest.php b/web/modules/features/tests/src/Kernel/FeaturesAssignTest.php
deleted file mode 100644
index 59b4ad961cd7efc8535de8173a76b082e0806c7c..0000000000000000000000000000000000000000
--- a/web/modules/features/tests/src/Kernel/FeaturesAssignTest.php
+++ /dev/null
@@ -1,855 +0,0 @@
-<?php
-
-namespace Drupal\Tests\features\Kernel;
-
-use Drupal\KernelTests\KernelTestBase;
-use Drupal\features\ConfigurationItem;
-use Drupal\features\FeaturesManagerInterface;
-use Drupal\Core\Config\InstallStorage;
-
-/**
- * @group features
- */
-class FeaturesAssignTest extends KernelTestBase {
-
-  const PACKAGE_NAME = 'my_test_package';
-  // Installed test feature package
-  const TEST_INSTALLED_PACKAGE = 'test_mybundle_core';
-  // Uninstalled test feature package
-  const TEST_UNINSTALLED_PACKAGE = 'test_feature';
-
-  /**
-   * {@inheritdoc}
-   */
-  public static $modules = ['features', 'node', 'system', 'user', self::TEST_INSTALLED_PACKAGE];
-
-  /**
-   * @var \Drupal\features\FeaturesManager
-   */
-  protected $featuresManager;
-
-  /**
-   * @var \Drupal\features\FeaturesAssigner
-   */
-  protected $assigner;
-
-  /**
-   * @var \Drupal\features\FeaturesBundleInterface
-   */
-  protected $bundle;
-
-  /**
-   * @todo Remove the disabled strict config schema checking.
-   */
-  protected $strictConfigSchema = FALSE;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-
-    $this->installConfig('features');
-    $this->installConfig('system');
-
-    $this->featuresManager = \Drupal::service('features.manager');
-    $this->assigner = \Drupal::service('features_assigner');
-    $this->bundle = $this->assigner->getBundle();
-
-    // Turn off all assignment plugins.
-    $this->bundle->setEnabledAssignments([]);
-
-    // Start with an empty configuration collection.
-    $this->featuresManager->setConfigCollection([]);
-  }
-
-  /**
-   * @covers Drupal\features\Plugin\FeaturesAssignment\FeaturesAssignmentAlter
-   */
-  public function testAssignAlter() {
-    $method_id = 'alter';
-
-    // Enable the method.
-    $this->enableAssignmentMethod($method_id);
-
-    // Add some configuration.
-    $this->addConfigurationItem('example.settings', [
-      '_core' => ['something'],
-      'uuid' => 'something',
-    ],
-    [
-      'type' => FeaturesManagerInterface::SYSTEM_SIMPLE_CONFIG,
-    ]);
-    $this->addConfigurationItem('node.type.article', [
-      '_core' => ['something'],
-      'uuid' => 'something',
-      'permissions' => [
-        'first',
-        'second',
-      ],
-    ],
-    [
-      'type' => 'node_type',
-    ]);
-    $this->addConfigurationItem('user.role.test', [
-      '_core' => ['something'],
-      'uuid' => 'something',
-      'permissions' => [
-        'first',
-        'second',
-      ],
-    ],
-    [
-      'type' => 'user_role',
-    ]);
-
-    // Set all settings to FALSE.
-    $settings = [
-      'core' => FALSE,
-      'uuid' => FALSE,
-      'user_permissions' => FALSE,
-    ];
-    $this->bundle->setAssignmentSettings($method_id, $settings);
-
-    $this->assigner->applyAssignmentMethod($method_id);
-
-    $config = $this->featuresManager->getConfigCollection();
-    $this->assertNotEmpty($config['example.settings'], 'Expected config not created.');
-    $this->assertNotEmpty($config['node.type.article'], 'Expected config not created.');
-    $this->assertNotEmpty($config['user.role.test'], 'Expected config not created.');
-
-    $example_settings_data = $config['example.settings']->getData();
-    $this->assertEquals($example_settings_data['_core'], ['something'], 'Expected _core value missing.');
-    $this->assertEquals($example_settings_data['uuid'], 'something', 'Expected uuid value missing.');
-
-    $node_type_data = $config['node.type.article']->getData();
-    $this->assertEquals($node_type_data['_core'], ['something'], 'Expected _core value missing.');
-    $this->assertEquals($node_type_data['uuid'], 'something', 'Expected uuid value missing.');
-    $this->assertEquals($node_type_data['permissions'], [
-      'first',
-      'second',
-    ], 'Expected permissions value missing.');
-
-    $user_role_data = $config['user.role.test']->getData();
-    $this->assertEquals($user_role_data['_core'], ['something'], 'Expected _core value missing.');
-    $this->assertEquals($user_role_data['uuid'], 'something', 'Expected uuid value missing.');
-    $this->assertEquals($user_role_data['permissions'], [
-      'first',
-      'second',
-    ], 'Expected permissions value missing.');
-
-    // Set all settings to TRUE.
-    $settings = [
-      'core' => TRUE,
-      'uuid' => TRUE,
-      'user_permissions' => TRUE,
-    ];
-    $this->bundle->setAssignmentSettings($method_id, $settings);
-
-    $this->assigner->applyAssignmentMethod($method_id);
-
-    $config = $this->featuresManager->getConfigCollection();
-    $this->assertNotEmpty($config['example.settings'], 'Expected config not created.');
-    $this->assertNotEmpty($config['node.type.article'], 'Expected config not created.');
-    $this->assertNotEmpty($config['user.role.test'], 'Expected config not created.');
-
-    $example_settings_data = $config['example.settings']->getData();
-    $this->assertFalse(isset($example_settings_data['_core']), 'Unexpected _core value present.');
-    // uuid should be retained for simple configuration.
-    $this->assertEquals($example_settings_data['uuid'], 'something', 'Expected uuid value missing.');
-
-    $node_type_data = $config['node.type.article']->getData();
-    $this->assertFalse(isset($node_type_data['_core']), 'Unexpected _core value present.');
-    $this->assertFalse(isset($node_type_data['uuid']), 'Unexpected uuid value present.');
-    // permissions should be stripped only for user_role configuration.
-    $this->assertEquals($node_type_data['permissions'], [
-      'first',
-      'second',
-    ], 'Expected permissions value missing.');
-
-    $user_role_data = $config['user.role.test']->getData();
-    $this->assertFalse(isset($user_role_data['_core']), 'Unexpected _core value present.');
-    $this->assertFalse(isset($user_role_data['uuid']), 'Unexpected uuid value present.');
-    $this->assertFalse(isset($user_role_data['permissions']), 'Unexpected permissions value present.');
-
-  }
-
-  /**
-   * @covers Drupal\features\Plugin\FeaturesAssignment\FeaturesAssignmentBaseType
-   */
-  public function testAssignBase() {
-    $method_id = 'base';
-
-    // Enable the method.
-    $this->enableAssignmentMethod($method_id);
-
-    // Test the default options for the base assignment method.
-
-    // Test node type assignments.
-    // Declare the node_type entity 'article'.
-    $this->addConfigurationItem('node.type.article', [], [
-      'shortName' => 'article',
-      'label' => 'Article',
-      'type' => 'node_type',
-      'dependents' => ['field.field.node.article.body'],
-    ]);
-
-    // Add a piece of dependent configuration.
-    $this->addConfigurationItem('field.field.node.article.body', [], [
-      'shortName' => 'node.article.body',
-      'label' => 'Body',
-      'type' => 'field_config',
-      'dependents' => [],
-    ]);
-
-    $this->assigner->applyAssignmentMethod($method_id);
-
-    $packages = $this->featuresManager->getPackages();
-
-    $expected_package_names = ['article', 'user'];
-
-    $this->assertEquals($expected_package_names, array_keys($packages), 'Expected packages not created.');
-
-    // Dependents like field.field.node.article.body should not be assigned.
-    $expected_config_items = [
-      'node.type.article',
-    ];
-
-    $this->assertEquals($expected_config_items, $packages['article']->getConfig(), 'Expected configuration items not present in article package.');
-  }
-
-  /**
-   * @covers Drupal\features\Plugin\FeaturesAssignment\FeaturesAssignmentCoreType
-   */
-  public function testAssignCore() {
-    $method_id = 'core';
-
-    // Enable the method.
-    $this->enableAssignmentMethod($method_id);
-
-    // Test the default options for the core assignment method.
-
-    // Add a piece of configuration of a core type.
-    $this->addConfigurationItem('field.storage.node.body', [], [
-      'shortName' => 'node.body',
-      'label' => 'node.body',
-      'type' => 'field_storage_config',
-      'dependents' => ['field.field.node.article.body'],
-    ]);
-
-    // Add a piece of configuration of a non-core type.
-    $this->addConfigurationItem('field.field.node.article.body', [], [
-      'shortName' => 'node.article.body',
-      'label' => 'Body',
-      'type' => 'field_config',
-      'dependents' => [],
-    ]);
-
-    $this->assigner->applyAssignmentMethod($method_id);
-
-    $packages = $this->featuresManager->getPackages();
-
-    $expected_package_names = ['core'];
-
-    $this->assertEquals($expected_package_names, array_keys($packages), 'Expected packages not created.');
-
-    $this->assertTrue(in_array('field.storage.node.body', $packages['core']->getConfig(), 'Expected configuration item not present in core package.'));
-    $this->assertFalse(in_array('field.field.node.article.body', $packages['core']->getConfig(), 'Unexpected configuration item present in core package.'));
-  }
-
-  /**
-   * @covers Drupal\features\Plugin\FeaturesAssignment\FeaturesAssignmentDependency
-   */
-  public function testAssignDependency() {
-    $method_id = 'dependency';
-
-    // Enable the method.
-    $this->enableAssignmentMethod($method_id);
-
-    // Test the default options for the base assignment method.
-
-    // Test node type assignments.
-    // Declare the node_type entity 'article'.
-    $this->addConfigurationItem('node.type.article', [], [
-      'shortName' => 'article',
-      'label' => 'Article',
-      'type' => 'node_type',
-      'dependents' => ['field.field.node.article.body'],
-    ]);
-
-    // Add a piece of dependent configuration.
-    $this->addConfigurationItem('field.field.node.article.body', [], [
-      'shortName' => 'node.article.body',
-      'label' => 'Body',
-      'type' => 'field_config',
-      'dependents' => [],
-    ]);
-
-    $this->featuresManager->initPackage(self::PACKAGE_NAME, 'My test package');
-    $this->featuresManager->assignConfigPackage(self::PACKAGE_NAME, ['node.type.article']);
-
-    $this->assigner->applyAssignmentMethod($method_id);
-
-    $packages = $this->featuresManager->getPackages();
-
-    $expected_package_names = [self::PACKAGE_NAME];
-
-    $this->assertEquals($expected_package_names, array_keys($packages), 'Expected packages not created.');
-
-    $expected_config_items = [
-      'node.type.article',
-      'field.field.node.article.body',
-    ];
-
-    $this->assertEquals($expected_config_items, $packages[self::PACKAGE_NAME]->getConfig(), 'Expected configuration items not present in article package.');
-  }
-
-  /**
-   * @covers Drupal\features\Plugin\FeaturesAssignment\FeaturesAssignmentExclude
-   */
-  public function testAssignExclude() {
-    $method_id = 'exclude';
-
-    // Enable the method.
-    $this->enableAssignmentMethod($method_id);
-    // Also enable Packages and Core plugins.
-    $this->enableAssignmentMethod('packages', FALSE);
-    $this->enableAssignmentMethod('core', FALSE);
-
-    // Apply the bundle
-    $this->bundle = $this->assigner->loadBundle('test_mybundle');
-
-    $this->assigner->applyAssignmentMethod('packages');
-    $packages = $this->featuresManager->getPackages();
-    $this->assertNotEmpty($packages[self::TEST_INSTALLED_PACKAGE], 'Expected package not created.');
-
-    // 1. When Required is set to True, config should stay with the module
-    // First, test with "Required" set to True.
-    $packages[self::TEST_INSTALLED_PACKAGE]->setRequired(true);
-    $this->featuresManager->setPackages($packages);
-
-    $this->assigner->applyAssignmentMethod('exclude');
-    $this->assigner->applyAssignmentMethod('core');
-    $this->assigner->applyAssignmentMethod('existing');
-    $packages = $this->featuresManager->getPackages();
-
-    $expected_config_items = [
-      'core.date_format.long',
-    ];
-
-    $this->assertEquals($expected_config_items, $packages[self::TEST_INSTALLED_PACKAGE]->getConfig(), 'Expected configuration items not present in existing test_core package.');
-
-    // 2. When Required is set to False, config still stays with module
-    // Because the module is installed.
-    $this->reset();
-    $this->bundle = $this->assigner->loadBundle('test_mybundle');
-
-    $this->assigner->applyAssignmentMethod('packages');
-    $packages = $this->featuresManager->getPackages();
-    $this->assertNotEmpty($packages[self::TEST_INSTALLED_PACKAGE], 'Expected test_mybundle_core package not created.');
-
-    // Set "Required" set to False
-    $packages[self::TEST_INSTALLED_PACKAGE]->setRequired(false);
-    $this->featuresManager->setPackages($packages);
-
-    $this->assigner->applyAssignmentMethod('exclude');
-    $this->assigner->applyAssignmentMethod('core');
-    $this->assigner->applyAssignmentMethod('existing');
-    $packages = $this->featuresManager->getPackages();
-    $this->assertFalse(array_key_exists('core', $packages), 'Core package should not be created.');
-
-    $expected_config_items = [
-      'core.date_format.long',
-    ];
-    $this->assertEquals($expected_config_items, $packages[self::TEST_INSTALLED_PACKAGE]->getConfig(), 'Expected configuration items not present in existing test_core package.');
-
-    // 3. When Required is set to False and module is NOT installed,
-    // Config stays with module if it doesn't match the current namespace
-    $this->reset();
-    // Load a bundle different from TEST_UNINSTALLED_PACKAGE
-    $this->bundle = $this->assigner->loadBundle('test_mybundle');
-
-    $this->assigner->applyAssignmentMethod('packages');
-    $packages = $this->featuresManager->getPackages();
-    $this->assertNotEmpty($packages[self::TEST_UNINSTALLED_PACKAGE], 'Expected test_feature package not created.');
-    $this->assertNotEmpty($packages[self::TEST_INSTALLED_PACKAGE], 'Expected test_mybundle_core package not created.');
-
-    // Mark package as uninstalled, set "Required" set to False
-    $packages[self::TEST_UNINSTALLED_PACKAGE]->setRequired(false);
-    $this->featuresManager->setPackages($packages);
-
-    $this->assigner->applyAssignmentMethod('exclude');
-    $this->assigner->applyAssignmentMethod('core');
-    $this->assigner->applyAssignmentMethod('existing');
-    $packages = $this->featuresManager->getPackages();
-    $this->assertFalse(array_key_exists('core', $packages), 'Core package should not be created.');
-
-    $expected_config_items = [
-      'core.date_format.short',
-      'system.cron',
-    ];
-    $this->assertEquals($expected_config_items, $packages[self::TEST_UNINSTALLED_PACKAGE]->getConfig(), 'Expected configuration items not present in existing test_feature package.');
-
-    // 4. When Required is set to False and module is NOT installed,
-    // Config is reassigned within modules that match the namespace.
-    $this->reset();
-    // Load the bundle used in TEST_UNINSTALLED_PACKAGE
-    $this->bundle = $this->assigner->loadBundle('test');
-    if (empty($this->bundle) || $this->bundle->isDefault()) {
-      // Since we uninstalled the test_feature, we probably need to create
-      // an empty "test" bundle
-      $this->bundle = $this->assigner->createBundleFromDefault('test');
-    }
-
-    $this->assigner->applyAssignmentMethod('packages');
-    $packages = $this->featuresManager->getPackages();
-    $this->assertNotEmpty($packages[self::TEST_UNINSTALLED_PACKAGE], 'Expected test_feature package not created.');
-
-    // Set "Required" set to False
-    $packages[self::TEST_UNINSTALLED_PACKAGE]->setRequired(false);
-    $this->featuresManager->setPackages($packages);
-
-    $this->assigner->applyAssignmentMethod('exclude');
-    $this->assigner->applyAssignmentMethod('core');
-    $this->assigner->applyAssignmentMethod('existing');
-    $packages = $this->featuresManager->getPackages();
-    $this->assertNotEmpty($packages['core'], 'Expected Core package not created.');
-
-    // Ensure "core" package is not confused with "test_core" module
-    // Since we are in a bundle
-    $this->assertEmpty($packages['core']->getExtension(), 'Autogenerated core package should not have an extension');
-
-    // Core config should be reassigned from TEST_UNINSTALLED_PACKAGE into Core
-    $expected_config_items = [
-      'system.cron',
-    ];
-    $this->assertEquals($expected_config_items, $packages[self::TEST_UNINSTALLED_PACKAGE]->getConfig(), 'Expected configuration items not present in existing test_feature package.');
-    $expected_config_items = [
-      'core.date_format.short',
-    ];
-    $this->assertEquals($expected_config_items, $packages['core']->getConfig(), 'Expected configuration items not present in core package.');
-  }
-
-  /**
-   * @covers Drupal\features\Plugin\FeaturesAssignment\FeaturesAssignmentExclude
-   */
-  public function testAssignExisting() {
-    $method_id = 'existing';
-
-    // Enable the method.
-    $this->enableAssignmentMethod($method_id);
-    // Also enable Packages plugin.
-    $this->enableAssignmentMethod('packages', FALSE);
-
-    // First create the existing packages.
-    $this->assigner->applyAssignmentMethod('packages');
-    // Now move config into those existing packages.
-    $this->assigner->applyAssignmentMethod($method_id);
-
-    $packages = $this->featuresManager->getPackages();
-    $this->assertNotEmpty($packages[self::TEST_INSTALLED_PACKAGE], 'Expected package not created.');
-    $this->assertNotEmpty($packages[self::TEST_UNINSTALLED_PACKAGE], 'Expected package not created.');
-
-    // Turn off any "required" option in package to let config get reassigned
-    $package = $packages[self::TEST_INSTALLED_PACKAGE];
-    $package->setRequired(true);
-
-    $expected_config_items = [
-      'core.date_format.long',
-    ];
-    $this->assertEquals($expected_config_items, $packages[self::TEST_INSTALLED_PACKAGE]->getConfig(), 'Expected configuration items not present in existing package.');
-
-    $expected_config_items = [
-      'core.date_format.short',
-      'system.cron',
-    ];
-    $this->assertEquals($expected_config_items, $packages[self::TEST_UNINSTALLED_PACKAGE]->getConfig(), 'Expected configuration items not present in existing package.');
-  }
-
-  /**
-   * @covers Drupal\features\Plugin\FeaturesAssignment\FeaturesAssignmentForwardDependency
-   */
-  public function testAssignForwardDependency() {
-    $method_id = 'forward_dependency';
-
-    // Enable the method.
-    $this->enableAssignmentMethod($method_id);
-
-    // Add some configuration.
-    // Two parent items.
-    $this->addConfigurationItem('parent1', [], [
-      'type' => 'node_type',
-      'dependents' => ['grandparent'],
-    ]);
-    $this->addConfigurationItem('parent2', [], [
-      'type' => 'node_type',
-      'dependents' => [],
-    ]);
-    // Something that belongs to just one parent.
-    $this->addConfigurationItem('child1', [], [
-      'type' => 'node_type',
-      'dependents' => ['parent1'],
-    ]);
-    // Something that belongs to both parents.
-    $this->addConfigurationItem('child2', [], [
-      'type' => 'node_type',
-      'dependents' => ['parent1', 'parent2'],
-    ]);
-    // Something that indirectly belongs to parent1.
-    $this->addConfigurationItem('grandchild', [], [
-      'type' => 'node_type',
-      'dependents' => ['child1'],
-    ]);
-    // A dependent, not a dependency.
-    $this->addConfigurationItem('grandparent', [], [
-      'type' => 'node_type',
-      'dependents' => [],
-    ]);
-    // Something completely unrelated.
-    $this->addConfigurationItem('stranger', [], [
-      'type' => 'node_type',
-      'dependents' => [],
-    ]);
-
-    $this->featuresManager->initPackage(self::PACKAGE_NAME, 'My test package');
-    $this->featuresManager->assignConfigPackage(self::PACKAGE_NAME, ['parent1']);
-
-    $other_package_name = 'other_package';
-    $this->featuresManager->initPackage($other_package_name, 'Other package');
-    $this->featuresManager->assignConfigPackage($other_package_name, ['parent2']);
-
-    $this->assigner->applyAssignmentMethod($method_id);
-
-    $packages = $this->featuresManager->getPackages();
-    $expected_package_names = [self::PACKAGE_NAME, $other_package_name];
-    sort($expected_package_names);
-    $actual_package_names = array_keys($packages);
-    sort($actual_package_names);
-    $this->assertEquals($expected_package_names, $actual_package_names, 'Expected packages not created.');
-
-    $expected_config_items = [
-      'parent1',
-      'child1',
-      'grandchild',
-    ];
-    sort($expected_config_items);
-    $actual_config_items = $packages[self::PACKAGE_NAME]->getConfig();
-    sort($actual_config_items);
-
-    $this->assertEquals($expected_config_items, $actual_config_items, 'Expected configuration items not present in article package.');
-  }
-
-  /**
-   * @covers Drupal\features\Plugin\FeaturesAssignment\FeaturesAssignmentNamespace
-   */
-  public function testAssignNamespace() {
-    $method_id = 'namespace';
-
-    // Enable the method.
-    $this->enableAssignmentMethod($method_id);
-
-    // Apply the bundle
-    $this->bundle = $this->assigner->loadBundle('test_mybundle');
-
-    $package_data = [
-      'article' => [
-        // Items that should be assigned to 'article'.
-        'article',
-        'article-after',
-        'before.article',
-        'something_article',
-        'something-article',
-        'something.article',
-        'article_something',
-        'article-something',
-        'article.something',
-        'something_article_something',
-        'something-article-something',
-        'something.article.something',
-        'something.article_something',
-      ],
-      'article_after' => [
-        // Items that should be assigned to 'article_after'.
-        'article_after',
-        'something_article_after',
-        'something-article_after',
-        'something.article_after',
-        'article_after_something',
-        'article_after-something',
-        'article_after.something',
-        'something_article_after_something',
-        'something-article_after-something',
-        'something.article_after.something',
-        'something.article_after_something',
-      ],
-      'before_article' => [
-        // Items that should be assigned to 'before_article'.
-        'before_article',
-        'something_before_article',
-        'something-before_article',
-        'something.before_article',
-        'before_article_something',
-        'before_article-something',
-        'before_article.something',
-        'something_before_article_something',
-        'something-before_article-something',
-        'something.before_article.something',
-        'something.before_article_something',
-      ],
-      // Emulate an existing feature, which has a machine name prefixed by
-      // the bundle name.
-      'test_mybundle_page' => [
-        // Items that should be assigned to 'test_mybundle_page'.
-        // Items should match the short name, 'page'.
-        'page',
-        'page-after',
-        'before.page',
-        'something_page',
-        'something-page',
-        'something.page',
-        'page_something',
-        'page-something',
-        'page.something',
-        'something_page_something',
-        'something-page-something',
-        'something.page.something',
-        'something.page_something',
-      ],
-    ];
-
-    foreach ($package_data as $machine_name => $config_short_names) {
-      $this->featuresManager->initPackage($machine_name, 'My test package ' . $machine_name);
-      foreach ($config_short_names as $short_name) {
-        $this->addConfigurationItem('node.type.' . $short_name, [], [
-          'type' => 'node_type',
-          'shortName' => $short_name,
-        ]);
-      }
-    }
-
-    // Add some config that should not be matched.
-    $config_short_names = [
-     'example',
-     'example_something',
-     'article~',
-     'myarticle',
-    ];
-    foreach ($config_short_names as $short_name) {
-      $this->addConfigurationItem('node.type.' . $short_name, [], [
-        'type' => 'node_type',
-        'shortName' => $short_name,
-      ]);
-    }
-
-    $this->assigner->applyAssignmentMethod($method_id);
-    $packages = $this->featuresManager->getPackages();
-
-    foreach ($package_data as $machine_name => $config_short_names) {
-      $this->assertNotEmpty($packages[$machine_name], 'Expected package ' . $machine_name . ' not created.');
-      array_walk($config_short_names, function(&$value) {
-        $value = 'node.type.' . $value;
-      });
-      sort($config_short_names);
-      $package_config = $packages[$machine_name]->getConfig();
-      sort($package_config);
-      $this->assertEquals($config_short_names, $package_config, 'Expected configuration items not present in ' . $machine_name . ' package.');
-    }
-
-  }
-
-  /**
-   * @covers Drupal\features\Plugin\FeaturesAssignment\FeaturesAssignmentOptionalType
-   */
-  public function testAssignOptionalType() {
-    $method_id = 'optional';
-
-    // Enable the method.
-    $this->enableAssignmentMethod($method_id);
-
-    $settings = [
-      'types' => [
-        'config' => ['image_style'],
-      ],
-    ];
-    $this->bundle->setAssignmentSettings($method_id, $settings);
-
-    // Add some configuration.
-    $this->addConfigurationItem('node.type.article', [], [
-      'type' => 'node_type',
-    ]);
-    $this->addConfigurationItem('image.style.test', [], [
-      'type' => 'image_style',
-    ]);
-    $this->featuresManager->initPackage(self::PACKAGE_NAME, 'My test package');
-    $this->assigner->applyAssignmentMethod($method_id);
-
-    $packages = $this->featuresManager->getPackages();
-    $this->assertNotEmpty($packages[self::PACKAGE_NAME], 'Expected package not created.');
-
-    $config = $this->featuresManager->getConfigCollection();
-    $this->assertNotEmpty($config['node.type.article'], 'Expected config not created.');
-    $this->assertNotEmpty($config['image.style.test'], 'Expected config not created.');
-
-    $this->assertNull($config['node.type.article']->getSubdirectory(), 'Expected package subdirectory not set to default.');
-    $this->assertEquals($config['image.style.test']->getSubdirectory(), InstallStorage::CONFIG_OPTIONAL_DIRECTORY, 'Expected package subdirectory not set to optional.');
-  }
-
-  /**
-   * @covers Drupal\features\Plugin\FeaturesAssignment\FeaturesAssignmentPackages
-   */
-  public function testAssignPackages() {
-    $method_id = 'packages';
-
-    // A configuration item that will be excluded.
-    $this->addConfigurationItem('system.theme', [], [
-      'type' => FeaturesManagerInterface::SYSTEM_SIMPLE_CONFIG,
-    ]);
-    // A configuration item that will be required.
-    $this->addConfigurationItem('core.date_format.long', [], [
-      'type' => 'date_format',
-    ]);
-    // A configuration item that will be neither excluded nor required.
-    $this->addConfigurationItem('system.theme', [], [
-      'type' => FeaturesManagerInterface::SYSTEM_SIMPLE_CONFIG,
-    ]);
-
-    // Enable the method.
-    $this->enableAssignmentMethod($method_id);
-
-    $this->assigner->applyAssignmentMethod($method_id);
-
-    $packages = $this->featuresManager->getPackages();
-
-    $this->assertNotEmpty($packages[self::TEST_INSTALLED_PACKAGE], 'Expected package not created.');
-
-    $config = $this->featuresManager->getConfigCollection();
-
-    $this->assertTrue(in_array(self::TEST_INSTALLED_PACKAGE, $config['system.theme']->getPackageExcluded()), 'Configuration item not excluded from package.');
-    $this->assertFalse(in_array(self::TEST_INSTALLED_PACKAGE, $config['system.site']->getPackageExcluded()), 'Configuration item excluded from package.');
-
-    $this->assertEquals(self::TEST_INSTALLED_PACKAGE, $config['core.date_format.long']->getPackage(), 'Required item not assigned to package.');
-    $this->assertNotEquals(self::TEST_INSTALLED_PACKAGE, $config['system.site']->getPackage(), 'Unrequired item assigned to package.');
-  }
-
-  /**
-   * @covers Drupal\features\Plugin\FeaturesAssignment\FeaturesAssignmentProfile
-   */
-  public function testAssignProfile() {
-    $method_id = 'profile';
-
-    // Enable the method.
-    $this->enableAssignmentMethod($method_id);
-
-    // Add some configuration.
-    $this->addConfigurationItem('shortcut.myshortcut', [], [
-      'type' => 'shortcut_set',
-    ]);
-    $this->addConfigurationItem('node.type.article', [], [
-      'type' => 'node_type',
-    ]);
-    $this->addConfigurationItem('image.style.test', [], [
-      'type' => 'image_style',
-    ]);
-    $this->addConfigurationItem('system.cron', [], [
-      'type' => FeaturesManagerInterface::SYSTEM_SIMPLE_CONFIG,
-    ]);
-    $this->bundle = $this->assigner->createBundleFromDefault('myprofile');
-    $this->bundle->setProfileName('myprofile');
-    $this->bundle->setIsProfile(TRUE);
-
-    $this->assigner->applyAssignmentMethod($method_id);
-
-    $packages = $this->featuresManager->getPackages();
-    $this->assertNotEmpty($packages['myprofile'], 'Expected package not created.');
-
-    $expected_config_items = [
-      'shortcut.myshortcut',
-      'system.cron',
-      'system.theme',
-    ];
-    $this->assertEquals($expected_config_items, $packages['myprofile']->getConfig(), 'Expected configuration items not present in package.');
-  }
-
-  /**
-   * @covers Drupal\features\Plugin\FeaturesAssignment\FeaturesAssignmentSiteType
-   */
-  public function testAssignSiteType() {
-    $method_id = 'site';
-
-    // Enable the method.
-    $this->enableAssignmentMethod($method_id);
-
-    // Test the default options for the site assignment method.
-
-    // Add a piece of configuration of a site type.
-    $this->addConfigurationItem('filter.format.plain_text', [], [
-      'shortName' => 'plain_text',
-      'label' => 'Plain text',
-      'type' => 'filter_format',
-    ]);
-
-    // Add a piece of configuration of a non-site type.
-    $this->addConfigurationItem('field.field.node.article.body', [], [
-      'shortName' => 'node.article.body',
-      'label' => 'Body',
-      'type' => 'field_config',
-      'dependents' => [],
-    ]);
-
-    $this->assigner->applyAssignmentMethod($method_id);
-
-    $packages = $this->featuresManager->getPackages();
-
-    $expected_package_names = ['site'];
-
-    $this->assertEquals($expected_package_names, array_keys($packages), 'Expected packages not created.');
-
-    $this->assertTrue(in_array('filter.format.plain_text', $packages['site']->getConfig(), 'Expected configuration item not present in site package.'));
-    $this->assertFalse(in_array('field.field.node.article.body', $packages['site']->getConfig(), 'Unexpected configuration item present in site package.'));
-  }
-
-  /**
-   * Enables a specified assignment method.
-   *
-   * @param string $method_id
-   *   The ID of an assignment method.
-   * @param bool $exclusive
-   *   (optional) Whether to set the method as the only enabled method.
-   *   Defaults to TRUE.
-   */
-  protected function enableAssignmentMethod($method_id, $exclusive = TRUE) {
-    if ($exclusive) {
-      $this->bundle->setEnabledAssignments([$method_id]);
-    }
-    else {
-      $enabled = array_keys($this->bundle->getEnabledAssignments());
-      $enabled[] = $method_id;
-      $this->bundle->setEnabledAssignments($enabled);
-    }
-  }
-
-  /**
-   * Adds a configuration item.
-   *
-   * @param string $name
-   *   The config name.
-   * @param array $data
-   *   The config data.
-   * @param array $properties
-   *   (optional) Additional properties set on the object.
-   */
-  protected function addConfigurationItem($name, array $data = [], array $properties = []) {
-    $config_collection = $this->featuresManager->getConfigCollection();
-    $config_collection[$name] = new ConfigurationItem($name, $data, $properties);
-    $this->featuresManager->setConfigCollection($config_collection);
-  }
-
-  /**
-   * Reset the config to reapply assignment plugins
-   */
-  protected function reset() {
-    $this->assigner->reset();
-    // Start with an empty configuration collection.
-    $this->featuresManager->setConfigCollection([]);
-  }
-}
diff --git a/web/modules/features/tests/src/Kernel/FeaturesAssignerTest.php b/web/modules/features/tests/src/Kernel/FeaturesAssignerTest.php
deleted file mode 100644
index 0477ece057b4ea2b6050548ad3c92c0596e980d1..0000000000000000000000000000000000000000
--- a/web/modules/features/tests/src/Kernel/FeaturesAssignerTest.php
+++ /dev/null
@@ -1,67 +0,0 @@
-<?php
-
-namespace Drupal\Tests\features\Kernel;
-
-use Drupal\Core\Config\StorageInterface;
-use Drupal\Core\Entity\EntityStorageInterface;
-use Drupal\features\FeaturesBundleInterface;
-use Drupal\KernelTests\KernelTestBase;
-
-/**
- * @group features
- */
-class FeaturesAssignerTest extends KernelTestBase {
-  /**
-   * {@inheritdoc}
-   */
-  public static $modules = ['system', 'config'];
-
-  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.
-   *
-   * We check the case where the import also causes features to be installed,
-   * so at the time auto-creation happens there's not yet a default bundle.
-   */
-  public function testBundleAutoCreationImport() {
-    // Install the feature.
-    $installer = $this->container->get('module_installer');
-    // Have to do these separately so features_modules_installed() doesn't
-    // just exit.
-    $installer->install(['features']);
-    $installer->install(['test_feature']);
-
-    // Save config.
-    $this->copyConfig(
-      $this->container->get('config.storage'),
-      $this->container->get('config.storage.sync')
-    );
-
-    // Uninstall modules.
-    $installer->uninstall(['features', 'test_feature']);
-
-    // Restore the config from after install.
-    $this->configImporter()->import();
-
-    // Find the auto-created bundle.
-    $bundle_storage = $this->container->get('entity_type.manager')
-      ->getStorage('features_bundle');
-    $bundle = $bundle_storage->load('test');
-    $this->assertNotNull($bundle, "Features bundle doesn't exist");
-    $this->assertContains(
-      'Auto-generated bundle',
-      $bundle->getDescription(),
-      "Features bundle not auto-created");
-  }
-
-}
diff --git a/web/modules/features/tests/src/Kernel/FeaturesGenerateTest.php b/web/modules/features/tests/src/Kernel/FeaturesGenerateTest.php
deleted file mode 100644
index d17c8221fa21d99d5fb496bd838c228d164df6d2..0000000000000000000000000000000000000000
--- a/web/modules/features/tests/src/Kernel/FeaturesGenerateTest.php
+++ /dev/null
@@ -1,210 +0,0 @@
-<?php
-
-namespace Drupal\Tests\features\Kernel;
-
-use Drupal\features\Entity\FeaturesBundle;
-use Drupal\KernelTests\KernelTestBase;
-use Drupal\Component\Serialization\Yaml;
-use Drupal\Core\Archiver\ArchiveTar;
-use org\bovigo\vfs\vfsStream;
-
-/**
- * @group features
- */
-class FeaturesGenerateTest extends KernelTestBase {
-
-  const PACKAGE_NAME = 'my_test_package';
-  const BUNDLE_NAME = 'giraffe';
-
-  /**
-   * {@inheritdoc}
-   */
-  public static $modules = ['features', 'system'];
-
-  /**
-   * @var \Drupal\features\FeaturesManagerInterface
-   */
-  protected $featuresManager;
-
-  /**
-   * @var \Drupal\features\FeaturesGeneratorInterface
-   */
-  protected $generator;
-
-  protected $strictConfigSchema = FALSE;
-
-  /**
-   * @var \Drupal\features\FeaturesAssignerInterface
-   */
-  protected $assigner;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-
-    $this->installConfig('features');
-    $this->installConfig('system');
-
-    $this->featuresManager = \Drupal::service('features.manager');
-    $this->generator = \Drupal::service('features_generator');
-    $this->assigner = \Drupal::service('features_assigner');
-
-    $this->featuresManager->initPackage(self::PACKAGE_NAME, 'My test package');
-    $package = $this->featuresManager->getPackage(self::PACKAGE_NAME);
-    $package->appendConfig('system.site');
-    $this->featuresManager->setPackage($package);
-  }
-
-  /**
-   * @covers \Drupal\features\Plugin\FeaturesGeneration\FeaturesGenerationArchive
-   */
-  public function testExportArchive() {
-    $filename = file_directory_temp() . '/' . self::PACKAGE_NAME . '.tar.gz';
-    if (file_exists($filename)) {
-      unlink($filename);
-    }
-    $this->assertFalse(file_exists($filename), 'Archive file already exists.');
-
-    $this->generator->generatePackages('archive', $this->assigner->getBundle(), [self::PACKAGE_NAME]);
-    $this->assertTrue(file_exists($filename), 'Archive file was not generated.');
-
-    $archive = new ArchiveTar($filename);
-    $files = $archive->listContent();
-
-    $this->assertEquals(3, count($files));
-    $this->assertEquals(self::PACKAGE_NAME . '/' . self::PACKAGE_NAME . '.info.yml', $files[0]['filename']);
-    $this->assertEquals(self::PACKAGE_NAME . '/' . self::PACKAGE_NAME . '.features.yml', $files[1]['filename']);
-    $this->assertEquals(self::PACKAGE_NAME . '/config/install/system.site.yml', $files[2]['filename']);
-
-    $expected_info = [
-      "name" => "My test package",
-      "type" => "module",
-      "core" => "8.x",
-    ];
-    $info = Yaml::decode($archive->extractInString(self::PACKAGE_NAME . '/' . self::PACKAGE_NAME . '.info.yml'));
-    $this->assertEquals($expected_info, $info, 'Incorrect info file generated');
-  }
-
-  public function testGeneratorWithBundle() {
-    $filename = file_directory_temp() . '/' . self::BUNDLE_NAME . '_' . self::PACKAGE_NAME . '.tar.gz';
-    if (file_exists($filename)) {
-      unlink($filename);
-    }
-    $this->assertFalse(file_exists($filename), 'Archive file already exists.');
-
-    $bundle = FeaturesBundle::create([
-      'machine_name' =>  self::BUNDLE_NAME
-    ]);
-
-    $this->generator->generatePackages('archive', $bundle, [self::PACKAGE_NAME]);
-
-    $package = $this->featuresManager->getPackage(self::PACKAGE_NAME);
-    $this->assertNull($package);
-
-    $package = $this->featuresManager->getPackage( self::BUNDLE_NAME . '_' . self::PACKAGE_NAME);
-    $this->assertEquals(self::BUNDLE_NAME . '_' . self::PACKAGE_NAME, $package->getMachineName());
-    $this->assertEquals(self::BUNDLE_NAME, $package->getBundle());
-
-    $this->assertTrue(file_exists($filename), 'Archive file was not generated.');
-  }
-
-  /**
-   * @covers \Drupal\features\Plugin\FeaturesGeneration\FeaturesGenerationWrite
-   */
-  public function testExportWrite() {
-    // Set a fake drupal root, so the testbot can also write into it.
-    vfsStream::setup('drupal');
-    \Drupal::getContainer()->set('app.root', 'vfs://drupal');
-    $this->featuresManager->setRoot('vfs://drupal');
-
-    $package = $this->featuresManager->getPackage(self::PACKAGE_NAME);
-    // Find out where package will be exported
-    list($full_name, $path) = $this->featuresManager->getExportInfo($package, $this->assigner->getBundle());
-    $path = 'vfs://drupal/' . $path . '/' . $full_name;
-    if (file_exists($path)) {
-      file_unmanaged_delete_recursive($path);
-    }
-    $this->assertFalse(file_exists($path), 'Package directory already exists.');
-
-    $this->generator->generatePackages('write', $this->assigner->getBundle(), [self::PACKAGE_NAME]);
-    $info_file_uri = $path . '/' . self::PACKAGE_NAME . '.info.yml';
-    $this->assertTrue(file_exists($path), 'Package directory was not generated.');
-    $this->assertTrue(file_exists($info_file_uri), 'Package info.yml not generated.');
-    $this->assertTrue(file_exists($path . '/config/install'), 'Package config/install not generated.');
-    $this->assertTrue(file_exists($path . '/config/install/system.site.yml'), 'Config.yml not exported.');
-
-    $expected_info = [
-      "name" => "My test package",
-      "type" => "module",
-      "core" => "8.x",
-    ];
-    $info = Yaml::decode(file_get_contents($info_file_uri));
-    $this->assertEquals($expected_info, $info, 'Incorrect info file generated');
-
-    // Now, add stuff to the feature and re-export to ensure it is preserved
-    // Add a dependency to the package itself to see that it gets exported.
-    $package->setDependencies(['user']);
-    $this->featuresManager->setPackage($package);
-    // Add dependency and custom key to the info file to simulate manual edit.
-    $info['dependencies'] = ['node'];
-    $info['mykey'] = "test value";
-    $info_contents = Yaml::encode($info);
-    file_put_contents($info_file_uri, $info_contents);
-
-    // Add an extra file that should be retained.
-    $css_file = $path . '/' . self::PACKAGE_NAME . '.css';
-    $file_contents = "This is a dummy file";
-    file_put_contents($css_file, $file_contents);
-
-    // Add a config file that should be removed since it's not part of the
-    // feature.
-    $config_file = $path . '/config/install/node.type.mytype.yml';
-    file_put_contents($config_file, $file_contents);
-
-    $this->generator->generatePackages('write', $this->assigner->getBundle(), [self::PACKAGE_NAME]);
-    $this->assertTrue(file_exists($info_file_uri), 'Package info.yml not generated.');
-    $expected_info = [
-      "name" => "My test package",
-      "type" => "module",
-      "core" => "8.x",
-      "dependencies" => ["node", "user"],
-      "mykey" => "test value",
-    ];
-    $info = Yaml::decode(file_get_contents($info_file_uri));
-    $this->assertEquals($expected_info, $info, 'Incorrect info file generated');
-    $this->assertTrue(file_exists($css_file), 'Extra file was not retained.');
-    $this->assertFalse(file_exists($config_file), 'Config directory was not cleaned.');
-    $this->assertEquals($file_contents, file_get_contents($css_file), 'Extra file contents not retained');
-
-    // Next, test that generating an Archive picks up the extra files.
-    $filename = file_directory_temp() . '/' . self::PACKAGE_NAME . '.tar.gz';
-    if (file_exists($filename)) {
-      unlink($filename);
-    }
-    $this->assertFalse(file_exists($filename), 'Archive file already exists.');
-    $this->generator->generatePackages('archive', $this->assigner->getBundle(), [self::PACKAGE_NAME]);
-    $this->assertTrue(file_exists($filename), 'Archive file was not generated.');
-
-    $archive = new ArchiveTar($filename);
-    $files = $archive->listContent();
-
-    $this->assertEquals(4, count($files));
-    $this->assertEquals(self::PACKAGE_NAME . '/' . self::PACKAGE_NAME . '.info.yml', $files[0]['filename']);
-    $this->assertEquals(self::PACKAGE_NAME . '/' . self::PACKAGE_NAME . '.features.yml', $files[1]['filename']);
-    $this->assertEquals(self::PACKAGE_NAME . '/config/install/system.site.yml', $files[2]['filename']);
-    $this->assertEquals(self::PACKAGE_NAME . '/' . self::PACKAGE_NAME . '.css', $files[3]['filename']);
-
-    $expected_info = [
-      "name" => "My test package",
-      "type" => "module",
-      "core" => "8.x",
-      "dependencies" => ["node", "user"],
-      "mykey" => "test value",
-    ];
-    $info = Yaml::decode($archive->extractInString(self::PACKAGE_NAME . '/' . self::PACKAGE_NAME . '.info.yml'));
-    $this->assertEquals($expected_info, $info, 'Incorrect info file generated');
-    $this->assertEquals($file_contents, $archive->extractInString(self::PACKAGE_NAME . '/' . self::PACKAGE_NAME . '.css'), 'Extra file contents not retained');
-  }
-}
diff --git a/web/modules/features/tests/src/Kernel/FeaturesManagerKernelTest.php b/web/modules/features/tests/src/Kernel/FeaturesManagerKernelTest.php
deleted file mode 100644
index 2ee7948816bf38d087f083718fdadb9b1919dd06..0000000000000000000000000000000000000000
--- a/web/modules/features/tests/src/Kernel/FeaturesManagerKernelTest.php
+++ /dev/null
@@ -1,103 +0,0 @@
-<?php
-
-namespace Drupal\Tests\features\Kernel;
-
-use Drupal\KernelTests\KernelTestBase;
-use Drupal\features\ConfigurationItem;
-use Drupal\features\Package;
-
-/**
- * @group features
- */
-class FeaturesManagerKernelTest extends KernelTestBase {
-  /**
-   * {@inheritdoc}
-   */
-  public static $modules = ['system', 'config', 'features'];
-
-  protected $strictConfigSchema = FALSE;
-
-  /**
-   * @var \Drupal\features\FeaturesManagerInterface
-   */
-  protected $featuresManager;
-
-  /**
-   * @var \Drupal\Core\Config\ConfigFactory
-   */
-  protected $configFactory;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-
-    $this->installConfig('features');
-    $this->installConfig('system');
-
-    $this->featuresManager = $this->container->get('features.manager');
-    $this->configFactory = $this->container->get('config.factory');
-  }
-
-  /**
-   * @covers \Drupal\features\FeaturesManager::createConfiguration
-   */
-  public function testCreateConfiguration() {
-    $config_name = 'system_simple.testcreate';
-    $config = [
-      'string_value' => 'example',
-      'array_value' => [
-        'item1' => 'value1',
-        'item2' => 'value2',
-      ],
-    ];
-    $this->featuresManager->createConfiguration([$config_name => $config]);
-    $config_item = $this->configFactory->get($config_name);
-    $this->assertEquals($config['string_value'], $config_item->get('string_value'), 'Test config string saved');
-    $this->assertEquals($config['array_value'], $config_item->get('array_value'), 'Test config array saved');
-  }
-
-  /**
-   * @covers \Drupal\features\FeaturesManager::import
-   */
-  public function testImport() {
-    $packages = [
-      'package' => new Package('package', [
-        'configOrig' => ['system_simple.example' => 'system_simple.example'],
-        'dependencies' => [],
-        'bundle' => '',
-      ]),
-      'package2' => new Package('package2', [
-        'configOrig' => ['system_simple.example2' => 'system_simple.example2'],
-        'dependencies' => [],
-        'bundle' => '',
-      ]),
-      'package3' => new Package('package3', [
-        'configOrig' => ['system_simple.example3' => 'system_simple.example3'],
-        'dependencies' => [],
-        'bundle' => '',
-      ]),
-    ];
-    $this->featuresManager->setPackages($packages);
-
-    // Create all three configuration items.
-    $config_item = new ConfigurationItem('system_simple.example', ['value' => 'example'], ['package' => 'package']);
-    $config_item2 = new ConfigurationItem('system_simple.example2', ['value' => 'example2'], ['package' => 'package2']);
-    $config_item3 = new ConfigurationItem('system_simple.example3', ['value' => 'example3'], ['package' => 'package3']);
-    // Only save example and example3 as currently active config (so example2 will be new).
-    $this->featuresManager->setConfigCollection(['system_simple.example' => $config_item, 'system_simple.example3' => $config_item3]);
-
-    // Only import example and example2, so example3 is unchanged.
-    $result = $this->featuresManager->import(['package', 'package2']);
-    $this->assertEquals(['system_simple.example'], array_keys($result['package']['updated']), 'Expected config updated');
-    $this->assertEquals(['system_simple.example2'], array_keys($result['package2']['new']), 'Expected config created');
-
-    // Test if config was actually saved to the Factory.
-    // Cannot test for example2 because we didn't save the original config data
-    // and Package2 isn't a real module so config can't be loaded from module.
-    $example = $this->configFactory->get('system_simple.example')->get('value');
-    $this->assertEquals('example', $example, 'Example config saved');
-  }
-
-}
diff --git a/web/modules/features/tests/src/Unit/ConfigurationItemTest.php b/web/modules/features/tests/src/Unit/ConfigurationItemTest.php
deleted file mode 100644
index 255ee8339dda2cb41ea7408bcd02fc319f7f2f68..0000000000000000000000000000000000000000
--- a/web/modules/features/tests/src/Unit/ConfigurationItemTest.php
+++ /dev/null
@@ -1,21 +0,0 @@
-<?php
-
-namespace Drupal\Tests\features\Unit;
-use Drupal\features\ConfigurationItem;
-use Drupal\features\FeaturesManagerInterface;
-
-/**
- * @coversDefaultClass \Drupal\features\ConfigurationItem
- * @group features
- */
-class ConfigurationItemTest extends \PHPUnit_Framework_TestCase {
-
-  /**
-   * @covers ::fromConfigStringToConfigType
-   */
-  public function testFromConfigStringToConfigType() {
-    $this->assertEquals('system.simple', ConfigurationItem::fromConfigStringToConfigType(FeaturesManagerInterface::SYSTEM_SIMPLE_CONFIG));
-    $this->assertEquals('node', ConfigurationItem::fromConfigStringToConfigType('node'));
-  }
-
-}
diff --git a/web/modules/features/tests/src/Unit/FeaturesBundleTest.php b/web/modules/features/tests/src/Unit/FeaturesBundleTest.php
deleted file mode 100644
index 726df5e04422822c97947a518d17ce70c0d1c93b..0000000000000000000000000000000000000000
--- a/web/modules/features/tests/src/Unit/FeaturesBundleTest.php
+++ /dev/null
@@ -1,206 +0,0 @@
-<?php
-
-namespace Drupal\Tests\features\Unit;
-
-use Drupal\features\Entity\FeaturesBundle;
-use Drupal\Tests\UnitTestCase;
-use Drupal\Core\DependencyInjection\ContainerBuilder;
-use Drupal\Core\Site\Settings;
-
-/**
- * @coversDefaultClass Drupal\features\Entity\FeaturesBundle
- * @group features
- */
-class FeaturesBundleTest extends UnitTestCase {
-
-  public function setUp() {
-    parent::setUp();
-
-    // Mock an assigner.
-    $manager = new DummyPluginManager();
-
-    // Mock the container.
-    $container = $this->prophesize('\Symfony\Component\DependencyInjection\ContainerInterface');
-    $container->get('plugin.manager.features_assignment_method')
-      ->willReturn($manager);
-    \Drupal::setContainer($container->reveal());
-  }
-
-  /**
-   * @covers ::getEnabledAssignments
-   * @covers ::getAssignmentWeights
-   * @covers ::getAssignmentSettings
-   * @covers ::setAssignmentSettings
-   * @covers ::setAssignmentWeights
-   * @covers ::setEnabledAssignments
-   */
-  public function testAssignmentSetting() {
-    // Create an entity.
-    $settings = [
-      'foo' => [
-        'enabled' => TRUE,
-        'weight' => 0,
-        'my_setting' => 42,
-      ],
-      'bar' => [
-        'enabled' => FALSE,
-        'weight' => 1,
-        'another_setting' => 'value',
-      ],
-    ];
-    $bundle = new FeaturesBundle([
-      'assignments' => $settings,
-    ], 'features_bundle');
-
-    // Get assignments and attributes.
-    $this->assertArrayEquals(
-      $bundle->getEnabledAssignments(),
-      ['foo' => 'foo'],
-      'Can get enabled assignments'
-    );
-    $this->assertArrayEquals(
-      $bundle->getAssignmentWeights(),
-      ['foo' => 0, 'bar' => 1],
-      'Can get assignment weights'
-    );
-    $this->assertArrayEquals(
-      $bundle->getAssignmentSettings('foo'),
-      $settings['foo'],
-      'Can get assignment settings'
-    );
-    $this->assertArrayEquals(
-      $bundle->getAssignmentSettings(),
-      $settings,
-      'Can get all assignment settings'
-    );
-
-    // Change settings.
-    $settings['foo']['my_setting'] = 97;
-    $bundle->setAssignmentSettings('foo', $settings['foo']);
-    $this->assertArrayEquals(
-      $bundle->getAssignmentSettings('foo'),
-      $settings['foo'],
-      'Can change assignment settings'
-    );
-
-    // Change weights.
-    $settings['foo']['weight'] = 1;
-    $settings['bar']['weight'] = 0;
-    $bundle->setAssignmentWeights(['foo' => 1, 'bar' => 0]);
-    $this->assertArrayEquals(
-      $bundle->getAssignmentWeights(),
-      ['foo' => 1, 'bar' => 0],
-      'Can change assignment weights'
-    );
-    $this->assertArrayEquals(
-      $bundle->getAssignmentSettings(),
-      $settings,
-      'Weight changes are reflected in settings'
-    );
-
-    // Enable existing assignment.
-    $settings['bar']['enabled'] = TRUE;
-    $bundle->setEnabledAssignments(['foo', 'bar']);
-    $this->assertArrayEquals(
-      $bundle->getEnabledAssignments(),
-      ['foo' => 'foo', 'bar' => 'bar'],
-      'Can enable assignment'
-    );
-    $this->assertArrayEquals(
-      $bundle->getAssignmentSettings(),
-      $settings,
-      'Enabled assignment status is reflected in settings'
-    );
-
-    // Disable existing assignments.
-    $settings['foo']['enabled'] = FALSE;
-    $settings['bar']['enabled'] = FALSE;
-    $bundle->setEnabledAssignments([]);
-    $this->assertArrayEquals(
-      $bundle->getEnabledAssignments(),
-      [],
-      'Can disable assignments'
-    );
-    $this->assertArrayEquals(
-      $bundle->getAssignmentSettings(),
-      $settings,
-      'Disabled assignment status is reflected in settings'
-    );
-
-    // Enable a new assignment.
-    $settings['foo']['enabled'] = TRUE;
-    $settings['iggy'] = ['enabled' => TRUE, 'weight' => 0, 'new_setting' => 3];
-    $bundle->setEnabledAssignments(['foo', 'iggy']);
-    $this->assertArrayEquals(
-      $bundle->getEnabledAssignments(),
-      ['foo' => 'foo', 'iggy' => 'iggy'],
-      'Can enable new assignment'
-    );
-    $bundle->setAssignmentSettings('iggy', $settings['iggy']);
-    $this->assertArrayEquals(
-      $bundle->getAssignmentSettings(),
-      $settings,
-      'New enabled assignment status is reflected in settings'
-    );
-
-  }
-
-  /**
-   * @covers ::getFullName
-   * @covers ::getShortName
-   * @covers ::SetIsProfile
-   * @covers ::isProfile
-   * @covers ::getProfileName
-   * @covers ::isProfilePackage
-   * @covers ::inBundle
-   */
-  public function testFullname() {
-    $bundle = new FeaturesBundle([
-      'machine_name' => 'mybundle',
-      'profile_name' => 'mybundle'
-    ], 'mybundle');
-    $this->assertFalse($bundle->isProfile());
-    // Settings:get('profile_name') isn't defined in test, so this returns NULL.
-    $this->assertNull($bundle->getProfileName());
-    $this->assertFalse($bundle->isProfilePackage('mybundle'));
-    $this->assertEquals('mybundle_test', $bundle->getFullName('test'));
-    $this->assertEquals('mybundle_test', $bundle->getFullName('mybundle_test'));
-    $this->assertEquals('mybundle_mybundle', $bundle->getFullName('mybundle'));
-    $this->assertEquals('test', $bundle->getShortName('test'));
-    $this->assertEquals('test', $bundle->getShortName('mybundle_test'));
-    $this->assertEquals('mybundle', $bundle->getShortName('mybundle_mybundle'));
-    $this->assertEquals('mybundle', $bundle->getShortName('mybundle'));
-    $this->assertFalse($bundle->inBundle('test'));
-    $this->assertTrue($bundle->inBundle('mybundle_test'));
-    $this->assertFalse($bundle->inBundle('mybundle'));
-
-    // Now test it as a profile bundle.
-    $bundle->setIsProfile(TRUE);
-    $this->assertTrue($bundle->isProfile());
-    $this->assertTrue($bundle->isProfilePackage('mybundle'));
-    $this->assertFalse($bundle->isProfilePackage('standard'));
-    $this->assertEquals('mybundle', $bundle->getProfileName());
-    $this->assertEquals('mybundle', $bundle->getFullName('mybundle'));
-    $this->assertFalse($bundle->inBundle('test'));
-    $this->assertTrue($bundle->inBundle('mybundle_test'));
-    $this->assertTrue($bundle->inBundle('mybundle'));
-  }
-
-}
-
-/**
- * A dummy plugin manager, to help testing.
- */
-class DummyPluginManager {
-  public function getDefinition($method_id) {
-    $definition = [
-      'enabled' => TRUE,
-      'weight' => 0,
-      'default_settings' => [
-        'my_setting' => 42,
-      ],
-    ];
-    return $definition;
-  }
-
-}
diff --git a/web/modules/features/tests/src/Unit/FeaturesManagerTest.php b/web/modules/features/tests/src/Unit/FeaturesManagerTest.php
deleted file mode 100644
index f53937a7c4252d60c98011f153e4b3c0c1ff3373..0000000000000000000000000000000000000000
--- a/web/modules/features/tests/src/Unit/FeaturesManagerTest.php
+++ /dev/null
@@ -1,989 +0,0 @@
-<?php
-
-namespace Drupal\Tests\features\Unit;
-
-use Drupal\Component\Serialization\Yaml;
-use Drupal\config_update\ConfigDiffInterface;
-use Drupal\Core\Config\ConfigFactoryInterface;
-use Drupal\Core\Config\ConfigManagerInterface;
-use Drupal\Core\Config\InstallStorage;
-use Drupal\Core\Config\StorageInterface;
-use Drupal\Core\DependencyInjection\ContainerBuilder;
-use Drupal\Core\Extension\Extension;
-use Drupal\Core\Extension\InfoParser;
-use Drupal\Core\Extension\InfoParserInterface;
-use Drupal\Core\Extension\ModuleHandlerInterface;
-use Drupal\config_update\ConfigRevertInterface;
-use Drupal\features\Entity\FeaturesBundle;
-use Drupal\features\FeaturesAssignerInterface;
-use Drupal\features\FeaturesBundleInterface;
-use Drupal\features\ConfigurationItem;
-use Drupal\features\FeaturesExtensionStoragesInterface;
-use Drupal\features\FeaturesManager;
-use Drupal\features\FeaturesManagerInterface;
-use Drupal\features\Package;
-use Drupal\Tests\UnitTestCase;
-use org\bovigo\vfs\vfsStream;
-use Prophecy\Argument;
-
-/**
- * @coversDefaultClass Drupal\features\FeaturesManager
- * @group features
- */
-class FeaturesManagerTest extends UnitTestCase {
-  /**
-   * @var string
-   *   The name of the install profile.
-   */
-  const PROFILE_NAME = 'my_profile';
-
-  /**
-   * @var \Drupal\features\FeaturesManagerInterface
-   */
-  protected $featuresManager;
-
-  /**
-   * @var \Drupal\Core\Entity\EntityTypeManagerInterface|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $entityTypeManager;
-
-  /**
-   * @var \Drupal\Core\Config\StorageInterface|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $configStorage;
-
-  /**
-   * @var \Drupal\Core\Config\ConfigFactoryInterface|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $configFactory;
-
-  /**
-   * @var \Drupal\Core\Config\ConfigManagerInterface|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $configManager;
-
-  /**
-   * @var \Drupal\Core\Extension\ModuleHandlerInterface|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $moduleHandler;
-
-  /**
-   * @var \Drupal\Core\Extension\ModuleHandlerInterface|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $configReverter;
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setUp() {
-    parent::setUp();
-
-    $container = new ContainerBuilder();
-    $container->set('string_translation', $this->getStringTranslationStub());
-    $container->set('app.root', $this->root);
-    // Since in Drupal 8.3 the "\Drupal::installProfile()" was introduced
-    // then we have to spoof a value for the "install_profile" parameter
-    // because it will be used by "ExtensionInstallStorage" class, which
-    // extends the "FeaturesInstallStorage".
-    // @see \Drupal\features\FeaturesConfigInstaller::__construct()
-    $container->setParameter('install_profile', '');
-    \Drupal::setContainer($container);
-
-    $entity_type = $this->getMock('\Drupal\Core\Config\Entity\ConfigEntityTypeInterface');
-    $entity_type->expects($this->any())
-      ->method('getConfigPrefix')
-      ->willReturn('custom');
-    $entity_type->expects($this->any())
-      ->method('getProvider')
-      ->willReturn('my_module');
-    $this->entityTypeManager = $this->getMock('\Drupal\Core\Entity\EntityTypeManagerInterface');
-    $this->entityTypeManager->expects($this->any())
-      ->method('getDefinition')
-      ->willReturn($entity_type);
-    $this->configFactory = $this->getMock(ConfigFactoryInterface::class);
-    $this->configStorage = $this->getMock(StorageInterface::class);
-    $this->configManager = $this->getMock(ConfigManagerInterface::class);
-    $this->moduleHandler = $this->getMock(ModuleHandlerInterface::class);
-    // getModuleList should return an array of extension objects.
-    // but we just need  isset($module_list[$provider]) for
-    // ::getConfigDependency() and ::assignInterPackageDependencies().
-    $this->moduleHandler->expects($this->any())
-      ->method('getModuleList')
-      ->willReturn([
-        'my_module' => true,
-        'example' => true,
-        'example3' => true,
-        'my_feature' => true,
-        'my_other_feature' => true,
-        'package' => true,
-        'package2' => true,
-        'package3' => true,
-        'giraffe_package' => true,
-        'giraffe_package2' => true,
-        'giraffe_package3' => true,
-      ]);
-    $this->configReverter = $this->getMock(ConfigRevertInterface::class);
-    $this->configReverter->expects($this->any())
-      ->method('import')
-      ->willReturn(true);
-    $this->configReverter->expects($this->any())
-      ->method('revert')
-      ->willReturn(true);
-    $this->featuresManager = new FeaturesManager($this->root, $this->entityTypeManager, $this->configFactory, $this->configStorage, $this->configManager, $this->moduleHandler, $this->configReverter);
-  }
-
-  /**
-   * @covers ::getActiveStorage
-   */
-  public function testGetActiveStorage() {
-    $this->assertInstanceOf('\Drupal\Core\Config\StorageInterface', $this->featuresManager->getActiveStorage());
-  }
-
-  /**
-   * @covers ::getExtensionStorages
-   */
-  public function testGetExtensionStorages() {
-    $this->assertInstanceOf('\Drupal\features\FeaturesExtensionStoragesInterface', $this->featuresManager->getExtensionStorages());
-  }
-
-  /**
-   * @covers ::getFullName
-   * @dataProvider providerTestGetFullName
-   */
-  public function testGetFullName($type, $name, $expected) {
-    $this->assertEquals($this->featuresManager->getFullName($type, $name), $expected);
-  }
-
-  /**
-   * Data provider for ::testGetFullName().
-   */
-  public function providerTestGetFullName() {
-    return [
-      [NULL, 'name', 'name'],
-      [FeaturesManagerInterface::SYSTEM_SIMPLE_CONFIG, 'name', 'name'],
-      ['custom', 'name', 'custom.name'],
-    ];
-  }
-
-  /**
-   * @covers ::getPackage
-   * @covers ::getPackages
-   * @covers ::reset
-   * @covers ::setPackages
-   */
-  public function testPackages() {
-    $packages = ['foo' => 'bar'];
-    $this->featuresManager->setPackages($packages);
-    $this->assertEquals($packages, $this->featuresManager->getPackages());
-    $this->assertEquals('bar', $this->featuresManager->getPackage('foo'));
-    $this->featuresManager->reset();
-    $this->assertArrayEquals([], $this->featuresManager->getPackages());
-    $this->assertNull($this->featuresManager->getPackage('foo'));
-  }
-
-  /**
-   * @covers ::setConfigCollection
-   * @covers ::getConfigCollection
-   */
-  public function testConfigCollection() {
-    $config = ['config' => new ConfigurationItem('', [])];
-    $this->featuresManager->setConfigCollection($config);
-    $this->assertArrayEquals($config, $this->featuresManager->getConfigCollection());
-  }
-
-  /**
-   * @covers ::setPackage
-   * @covers ::getPackage
-   */
-  public function testSetPackage() {
-    $package = new Package('foo');
-    $this->featuresManager->setPackage($package);
-    $this->assertEquals($package, $this->featuresManager->getPackage('foo'));
-  }
-
-  /**
-   * @covers ::filterPackages
-   */
-  public function testGetPackages() {
-    $packages = [
-      'package' => new Package('package', [
-        'bundle' => '',
-        'status' => FeaturesManagerInterface::STATUS_NO_EXPORT,
-      ]),
-      'package2' => new Package('package2', [
-        'bundle' => '',
-        'status' => FeaturesManagerInterface::STATUS_UNINSTALLED,
-      ]),
-      'package3' => new Package('package3', [
-        'bundle' => 'my_bundle',
-        'status' => FeaturesManagerInterface::STATUS_NO_EXPORT,
-      ]),
-      'package4' => new Package('package4', [
-        'bundle' => 'my_bundle',
-        'status' => FeaturesManagerInterface::STATUS_UNINSTALLED,
-      ]),
-    ];
-
-    // Filter for the default bundle.
-    $filtered_packages = $this->featuresManager->filterPackages($packages, FeaturesBundleInterface::DEFAULT_BUNDLE);
-    $this->assertEquals(['package', 'package2'], array_keys($filtered_packages));
-
-    // Filter for a custom bundle.
-    $filtered_packages = $this->featuresManager->filterPackages($packages, 'my_bundle');
-    $this->assertEquals(['package3', 'package4'], array_keys($filtered_packages));
-
-    // Filter for a non-matching bundle.
-    $filtered_packages = $this->featuresManager->filterPackages($packages, 'some_bundle');
-    $this->assertEquals([], array_keys($filtered_packages));
-
-    // Filter for the default bundle removing only exported.
-    $filtered_packages = $this->featuresManager->filterPackages($packages, FeaturesBundleInterface::DEFAULT_BUNDLE, TRUE);
-    $this->assertEquals(['package'], array_keys($filtered_packages));
-
-    // Filter for a custom bundle removing only exported.
-    $filtered_packages = $this->featuresManager->filterPackages($packages, 'my_bundle', TRUE);
-    $this->assertEquals(['package3'], array_keys($filtered_packages));
-
-    // Filter for a non-matching bundle removing only exported.
-    $filtered_packages = $this->featuresManager->filterPackages($packages, 'some_bundle', TRUE);
-    $this->assertEquals([], array_keys($filtered_packages));
-  }
-
-
-  protected function getAssignInterPackageDependenciesConfigCollection() {
-    $config_collection = [];
-    $config_collection['example.config'] = (new ConfigurationItem('example.config', [
-      'dependencies' => [
-        'config' => [
-          'example.config2',
-          'example.config3',
-          'example.config4',
-          'example.config5',
-          'example.config6',
-          'example.config7',
-        ],
-      ],
-    ]))
-      ->setSubdirectory(InstallStorage::CONFIG_INSTALL_DIRECTORY)
-      ->setPackage('package');
-    $config_collection['example.config2'] =  (new ConfigurationItem('example.config2', [
-      'dependencies' => [],
-    ]))
-      ->setSubdirectory(InstallStorage::CONFIG_INSTALL_DIRECTORY)
-      ->setPackage('package2')
-      ->setProvider('my_feature');
-    $config_collection['example.config3'] = (new ConfigurationItem('example.config3', [
-      'dependencies' => [],
-    ]))
-      ->setSubdirectory(InstallStorage::CONFIG_INSTALL_DIRECTORY)
-      ->setProvider('my_other_feature');
-    $config_collection['example.config4'] = (new ConfigurationItem('example.config3', [
-      'dependencies' => [],
-    ]))
-      ->setSubdirectory(InstallStorage::CONFIG_INSTALL_DIRECTORY)
-      ->setProvider(static::PROFILE_NAME);
-    $config_collection['example.config5'] =  (new ConfigurationItem('example.config5', [
-      'dependencies' => [],
-    ]))
-      ->setSubdirectory(InstallStorage::CONFIG_OPTIONAL_DIRECTORY)
-      ->setPackage('package3');
-    $config_collection['example.config6'] =  (new ConfigurationItem('example.config6', [
-      'dependencies' => [],
-    ]))
-      ->setSubdirectory(InstallStorage::CONFIG_INSTALL_DIRECTORY)
-      ->setProvider('my_uninstalled_feature');
-    $config_collection['example.config7'] =  (new ConfigurationItem('example.config7', [
-      'dependencies' => [],
-    ]))
-      ->setSubdirectory(InstallStorage::CONFIG_INSTALL_DIRECTORY)
-      ->setProvider('package4');
-
-    return $config_collection;
-  }
-
-  /**
-   * @covers ::assignInterPackageDependencies
-   */
-  public function testAssignInterPackageDependenciesWithoutBundle() {
-    $assigner = $this->prophesize(FeaturesAssignerInterface::class);
-    $bundle = $this->prophesize(FeaturesBundleInterface::class);
-    // Provide a bundle without any prefix.
-    $bundle->getFullName('package')->willReturn('package');
-    $bundle->getFullName('package2')->willReturn('package2');
-    $bundle->getFullName('package3')->willReturn('package3');
-    $bundle->getFullName('package4')->willReturn('package4');
-    $bundle->isDefault()->willReturn(TRUE);
-    $assigner->getBundle()->willReturn($bundle->reveal());
-    // Use the wrapper because we need ::drupalGetProfile().
-    $features_manager = new TestFeaturesManager($this->root, $this->entityTypeManager, $this->configFactory, $this->configStorage, $this->configManager, $this->moduleHandler, $this->configReverter);
-    $features_manager->setAssigner($assigner->reveal());
-
-    $features_manager->setConfigCollection($this->getAssignInterPackageDependenciesConfigCollection());
-
-    $packages = [
-      'package' => new Package('package', [
-        'config' => ['example.config', 'example.config3'],
-        'dependencies' => [],
-        'bundle' => '',
-      ]),
-      'package2' => new Package('package2', [
-        'config' => ['example.config2'],
-        'dependencies' => [],
-        'bundle' => '',
-      ]),
-      'package3' => new Package('package3', [
-        'config' => ['example.config5'],
-        'dependencies' => [],
-        'bundle' => '',
-      ]),
-      'package4' => new Package('package4', [
-        'config' => ['example.config7'],
-        'dependencies' => [],
-        'bundle' => '',
-      ]),
-    ];
-
-    $features_manager->setPackages($packages);
-    // Dependencies require the full package names.
-    $package_names = array_keys($packages);
-    $features_manager->setPackageBundleNames($bundle->reveal(), $package_names);
-    $packages = $features_manager->getPackages();
-    $features_manager->assignInterPackageDependencies($bundle->reveal(), $packages);
-    // example.config3 has a providing_feature but no assigned package.
-    // my_package2 provides configuration required by configuration in
-    // my_package.
-    // Because package assignments take precedence over providing_feature ones,
-    // package2 should have been assigned rather than my_feature.
-    // Because it is assigned to the InstallStorage::CONFIG_OPTIONAL_DIRECTORY
-    // subdirectory, example.config5 does not create a dependency on its
-    // providing feature, package3.
-    // Because it's provided by an uninstalled module, example.config6 doesn't
-    // create a dependency on my_uninstalled_feature.
-    // Because it's provided by an uninstalled module, example.config7 doesn't
-    // create a dependency on package4.
-    $this->assertEquals(['my_other_feature', 'package2'], $packages['package']->getDependencies());
-    $this->assertEquals([], $packages['package2']->getDependencies());
-  }
-
-  /**
-   * @covers ::assignInterPackageDependencies
-   */
-  public function testAssignInterPackageDependenciesWithBundle() {
-    $assigner = $this->prophesize(FeaturesAssignerInterface::class);
-    $bundle = $this->prophesize(FeaturesBundleInterface::class);
-    // Provide a bundle without any prefix.
-    $bundle->getFullName('package')->willReturn('giraffe_package');
-    $bundle->getFullName('package2')->willReturn('giraffe_package2');
-    $bundle->getFullName('package3')->willReturn('giraffe_package3');
-    $bundle->getFullName('package4')->willReturn('giraffe_package4');
-    $bundle->getFullName('giraffe_package')->willReturn('giraffe_package');
-    $bundle->getFullName('giraffe_package2')->willReturn('giraffe_package2');
-    $bundle->isDefault()->willReturn(FALSE);
-    $bundle->getMachineName()->willReturn('giraffe');
-    $assigner->getBundle('giraffe')->willReturn($bundle->reveal());
-    // Use the wrapper because we need ::drupalGetProfile().
-    $features_manager = new TestFeaturesManager($this->root, $this->entityTypeManager, $this->configFactory, $this->configStorage, $this->configManager, $this->moduleHandler, $this->configReverter);
-    $features_manager->setAssigner($assigner->reveal());
-    $features_manager->setConfigCollection($this->getAssignInterPackageDependenciesConfigCollection());
-
-    $packages = [
-      'package' => new Package('package', [
-        'config' => ['example.config'],
-        'dependencies' => [],
-        'bundle' => 'giraffe',
-      ]),
-      'package2' => new Package('package2', [
-        'config' => ['example.config2'],
-        'dependencies' => [],
-        'bundle' => 'giraffe',
-      ]),
-      'package3' => new Package('package3', [
-        'config' => ['example.config5'],
-        'dependencies' => [],
-        'bundle' => 'giraffe',
-      ]),
-      'package4' => new Package('package4', [
-        'config' => ['example.config7'],
-        'dependencies' => [],
-        'bundle' => 'giraffe',
-      ]),
-    ];
-
-    $features_manager->setPackages($packages);
-    // Dependencies require the full package names.
-    $package_names = array_keys($packages);
-    $features_manager->setPackageBundleNames($bundle->reveal(), $package_names);
-    $packages = $features_manager->getPackages();
-    $features_manager->assignInterPackageDependencies($bundle->reveal(), $packages);
-    // example.config3 has a providing_feature but no assigned package.
-    // my_package2 provides configuration required by configuration in
-    // my_package.
-    // Because package assignments take precedence over providing_feature ones,
-    // package2 should have been assigned rather than my_feature.
-    // Because it is assigned to the InstallStorage::CONFIG_OPTIONAL_DIRECTORY
-    // subdirectory, example.config5 does not create a dependency on its
-    // providing feature, package3.
-    // Because it's provided by an uninstalled module, example.config6 doesn't
-    // create a dependency on my_uninstalled_feature.
-    // Because it's provided by an uninstalled module, example.config7 doesn't
-    // create a dependency on giraffe_package4.
-    $expected = ['giraffe_package2', 'my_other_feature'];
-    $this->assertEquals($expected, $packages['giraffe_package']->getDependencies());
-  }
-
-  /**
-   * @covers ::assignInterPackageDependencies
-   * @expectedException \Exception
-   * @expectedExceptionMessage The packages have not yet been prefixed with a bundle name
-   */
-  public function testAssignInterPackageDependenciesPrematureCall() {
-    $bundle = $this->prophesize(FeaturesBundleInterface::class);
-    $packages = [
-      'package' => new Package('package', [
-        'config' => ['example.config', 'example.config3'],
-        'dependencies' => [],
-        'bundle' => 'giraffe',
-      ]),
-    ];
-
-    $this->featuresManager->assignInterPackageDependencies($bundle->reveal(), $packages);
-  }
-
-  /**
-   * @covers ::reset
-   */
-  public function testReset() {
-    $packages = [
-      'package' => [
-        'machine_name' => 'package',
-        'config' => ['example.config', 'example.config3'],
-        'dependencies' => [],
-        'bundle' => 'giraffe',
-      ],
-      'package2' => [
-        'machine_name' => 'package2',
-        'config' => ['example.config2'],
-        'dependencies' => [],
-        'bundle' => 'giraffe',
-      ],
-    ];
-    $this->featuresManager->setPackages($packages);
-
-    $config_item = new ConfigurationItem('example', [], ['package' => 'package']);
-    $config_item2 = new ConfigurationItem('example2', [], ['package' => 'package2']);
-    $this->featuresManager->setConfigCollection([$config_item, $config_item2]);
-
-    $this->featuresManager->reset();
-    $this->assertEmpty($this->featuresManager->getPackages());
-    $config_collection = $this->featuresManager->getConfigCollection();
-    $this->assertEquals('', $config_collection[0]->getPackage());
-    $this->assertEquals('', $config_collection[1]->getPackage());
-  }
-
-
-  /**
-   * @covers ::detectMissing
-   */
-  public function testDetectMissing() {
-    $package = new Package('test-package', [
-      'configOrig' => ['test_config', 'test_config_non_existing'],
-    ]);
-
-    $config_collection = [];
-    $config_collection['test_config'] = new ConfigurationItem('test_config', []);
-    $this->featuresManager->setConfigCollection($config_collection);
-
-    $this->assertEquals(['test_config_non_existing'], $this->featuresManager->detectMissing($package));
-  }
-
-  /**
-   * @covers ::detectOverrides
-   */
-  public function testDetectOverrides() {
-    $config_diff = $this->prophesize(ConfigDiffInterface::class);
-    $config_diff->same(Argument::cetera())->will(function($args) {
-      return $args[0] == $args[1];
-    });
-    \Drupal::getContainer()->set('config_update.config_diff', $config_diff->reveal());
-
-    $package = new Package('test-package', [
-      'config' => ['test_config', 'test_overridden'],
-    ]);
-
-    $config_storage = $this->prophesize(StorageInterface::class);
-    $config_storage->read('test_config')->willReturn([
-      'key' => 'value',
-    ]);
-    $config_storage->read('test_overridden')->willReturn([
-      'key2' => 'value2',
-    ]);
-
-    $extension_storage = $this->prophesize(FeaturesExtensionStoragesInterface::class);
-    $extension_storage->read('test_config')->willReturn([
-      'key' => 'value',
-    ]);
-    $extension_storage->read('test_overridden')->willReturn([
-      'key2' => 'value0',
-    ]);
-
-
-    $features_manager = new TestFeaturesManager($this->root, $this->entityTypeManager, $this->configFactory, $config_storage->reveal(), $this->configManager, $this->moduleHandler, $this->configReverter);
-    $features_manager->setExtensionStorages($extension_storage->reveal());
-
-    $this->assertEquals(['test_overridden'], $features_manager->detectOverrides($package));
-  }
-
-  /**
-   * @covers ::assignConfigPackage
-   */
-  public function testAssignConfigPackageWithNonProviderExcludedConfig() {
-    $assigner = $this->prophesize(FeaturesAssignerInterface::class);
-    $bundle = $this->prophesize(FeaturesBundleInterface::class);
-    $bundle->isProfilePackage('test_package')->willReturn(FALSE);
-    $bundle->isProfilePackage('test_package2')->willReturn(FALSE);
-    $assigner->getBundle(NULL)->willReturn($bundle->reveal());
-    $this->featuresManager->setAssigner($assigner->reveal());
-
-    $config_collection = [
-      'test_config' => new ConfigurationItem('test_config', []),
-      'test_config2' => new ConfigurationItem('test_config2', [
-        'dependencies' => [
-          'module' => ['example', 'example2'],
-        ]
-      ], [
-        'subdirectory' => InstallStorage::CONFIG_INSTALL_DIRECTORY,
-      ]),
-      'example3.settings' => new ConfigurationItem('example3.settings', [], [
-        'type' => FeaturesManagerInterface::SYSTEM_SIMPLE_CONFIG,
-        'subdirectory' => InstallStorage::CONFIG_INSTALL_DIRECTORY,
-      ]),
-      'test_config3' => new ConfigurationItem('test_config3', [
-        'dependencies' => [
-          'module' => ['example2'],
-        ]
-      ], [
-        'subdirectory' => InstallStorage::CONFIG_OPTIONAL_DIRECTORY,
-      ]),
-    ];
-    $this->featuresManager->setConfigCollection($config_collection);
-
-    $package = new Package('test_package');
-    $this->featuresManager->setPackage($package);
-
-    $this->featuresManager->assignConfigPackage('test_package', ['test_config', 'test_config2', 'example3.settings']);
-
-    $this->assertEquals(['test_config', 'test_config2', 'example3.settings'], $this->featuresManager->getPackage('test_package')->getConfig());
-    // 'example2' is not returned by ::getModuleList() and so isn't a
-    // dependency.
-    $this->assertEquals(['example', 'example3', 'my_module'], $this->featuresManager->getPackage('test_package')->getDependencies());
-
-    // Test optional config, which doesn't create module dependencies.
-    $package = new Package('test_package2');
-    $this->featuresManager->setPackage($package);
-
-    $this->featuresManager->assignConfigPackage('test_package2', ['test_config3']);
-
-    $this->assertEquals(['test_config3'], $this->featuresManager->getPackage('test_package2')->getConfig());
-    $this->assertEquals([], $this->featuresManager->getPackage('test_package2')->getDependencies());
-  }
-
-  /**
-   * @covers ::assignConfigPackage
-   */
-  public function testAssignConfigPackageWithProviderExcludedConfig() {
-    $config_collection = [
-      'test_config' => new ConfigurationItem('test_config', []),
-      'test_config2' => new ConfigurationItem('test_config2', [], ['providerExcluded' => TRUE]),
-    ];
-    $this->featuresManager->setConfigCollection($config_collection);
-
-    $feature_assigner = $this->prophesize(FeaturesAssignerInterface::class);
-    $feature_assigner->getBundle(NULL)->willReturn(new FeaturesBundle(['machine_name' => FeaturesBundleInterface::DEFAULT_BUNDLE], 'features_bundle'));
-    $this->featuresManager->setAssigner($feature_assigner->reveal());
-
-    $package = new Package('test_package');
-    $original_package = clone $package;
-
-    $this->featuresManager->setPackage($package);
-    $this->featuresManager->assignConfigPackage('test_package', ['test_config', 'test_config2']);
-    $this->assertEquals(['test_config'], $this->featuresManager->getPackage('test_package')->getConfig(), 'just assign new packages');
-
-    $this->featuresManager->setPackage($original_package);
-    $this->featuresManager->assignConfigPackage('test_package', ['test_config', 'test_config2'], TRUE);
-    $this->assertEquals(['test_config', 'test_config2'], $this->featuresManager->getPackage('test_package')->getConfig(), 'just assign new packages');
-  }
-
-  /**
-   * @covers ::assignConfigPackage
-   */
-  public function testAssignConfigPackageWithPackageExcludedConfig() {
-    $config_collection = [
-      'test_config' => new ConfigurationItem('test_config', []),
-      'test_config2' => new ConfigurationItem('test_config2', [], ['packageExcluded' => ['test_package']]),
-    ];
-    $this->featuresManager->setConfigCollection($config_collection);
-
-    $feature_assigner = $this->prophesize(FeaturesAssignerInterface::class);
-    $feature_assigner->getBundle(NULL)->willReturn(new FeaturesBundle(['machine_name' => 'default'], 'features_bundle'));
-    $this->featuresManager->setAssigner($feature_assigner->reveal());
-
-    $package = new Package('test_package');
-    $original_package = clone $package;
-
-    $this->featuresManager->setPackage($package);
-    $this->featuresManager->assignConfigPackage('test_package', ['test_config', 'test_config2']);
-    $this->assertEquals(['test_config'], $this->featuresManager->getPackage('test_package')->getConfig(), 'just assign new packages');
-
-    $this->featuresManager->setPackage($original_package);
-    $this->featuresManager->assignConfigPackage('test_package', ['test_config', 'test_config2'], TRUE);
-    $this->assertEquals(['test_config', 'test_config2'], $this->featuresManager->getPackage('test_package')->getConfig(), 'just assign new packages');
-  }
-
-  /**
-   * @covers ::initPackageFromExtension
-   * @covers ::getPackageObject
-   */
-  public function testInitPackageFromNonInstalledExtension() {
-    $extension = new Extension($this->root, 'module', 'modules/test_module/test_module.info.yml');
-
-    $info_parser = $this->prophesize(InfoParserInterface::class);
-    $info_parser->parse($this->root . '/modules/test_module/test_module.info.yml')->willReturn([
-      'name' => 'Test module',
-      'description' => 'test description',
-      'type' => 'module',
-    ]);
-    \Drupal::getContainer()->set('info_parser', $info_parser->reveal());
-
-    $bundle = $this->prophesize(FeaturesBundle::class);
-    $bundle->getFullName('test_module')->willReturn('test_module');
-    $bundle->isDefault()->willReturn(TRUE);
-
-    $assigner = $this->prophesize(FeaturesAssignerInterface::class);
-    $assigner->findBundle(Argument::cetera())->willReturn($bundle->reveal());
-    $this->featuresManager->setAssigner($assigner->reveal());
-
-    $result = $this->featuresManager->initPackageFromExtension($extension);
-    $this->assertInstanceOf(Package::class, $result);
-    // Ensure that that calling the function twice works.
-    $result = $this->featuresManager->initPackageFromExtension($extension);
-    $this->assertInstanceOf(Package::class, $result);
-
-    $this->assertEquals('test_module', $result->getMachineName());
-    $this->assertEquals('Test module', $result->getName());
-    $this->assertEquals('test description', $result->getDescription());
-    $this->assertEquals('module', $result->getType());
-
-    $this->assertEquals(FeaturesManagerInterface::STATUS_UNINSTALLED, $result->getStatus());
-  }
-
-  /**
-   * @covers ::initPackageFromExtension
-   * @covers ::getPackageObject
-   */
-  public function testInitPackageFromInstalledExtension() {
-    $extension = new Extension($this->root, 'module', 'modules/test_module/test_module.info.yml');
-
-    $info_parser = $this->prophesize(InfoParserInterface::class);
-    $info_parser->parse($this->root . '/modules/test_module/test_module.info.yml')->willReturn([
-      'name' => 'Test module',
-      'description' => 'test description',
-      'type' => 'module',
-    ]);
-    \Drupal::getContainer()->set('info_parser', $info_parser->reveal());
-
-    $bundle = $this->prophesize(FeaturesBundle::class);
-    $bundle->getFullName('test_module')->willReturn('test_module');
-    $bundle->isDefault()->willReturn(TRUE);
-
-    $assigner = $this->prophesize(FeaturesAssignerInterface::class);
-    $assigner->findBundle(Argument::cetera())->willReturn($bundle->reveal());
-    $this->featuresManager->setAssigner($assigner->reveal());
-
-    $this->moduleHandler->expects($this->any())
-      ->method('moduleExists')
-      ->with('test_module')
-      ->willReturn(TRUE);
-
-    $result = $this->featuresManager->initPackageFromExtension($extension);
-    $this->assertEquals(FeaturesManagerInterface::STATUS_INSTALLED, $result->getStatus());
-  }
-
-  public function testDetectNewWithNoConfig() {
-    $package = new Package('test_feature');
-
-    $this->assertEmpty($this->featuresManager->detectNew($package));
-  }
-
-  public function testDetectNewWithNoNewConfig() {
-    $package = new Package('test_feature', ['config' => ['test_config']]);
-
-    $extension_storage = $this->prophesize(FeaturesExtensionStoragesInterface::class);
-    $extension_storage->read('test_config')->willReturn([
-      'key' => 'value',
-    ]);
-
-    $features_manager = new TestFeaturesManager($this->root, $this->entityTypeManager, $this->configFactory, $this->configStorage, $this->configManager, $this->moduleHandler, $this->configReverter);
-    $features_manager->setExtensionStorages($extension_storage->reveal());
-
-    $this->assertEmpty($features_manager->detectNew($package));
-  }
-
-  public function testDetectNewWithNewConfig() {
-    $package = new Package('test_feature', ['config' => ['test_config']]);
-
-    $extension_storage = $this->prophesize(FeaturesExtensionStoragesInterface::class);
-    $extension_storage->read('test_config')->willReturn(FALSE);
-
-    $features_manager = new TestFeaturesManager($this->root, $this->entityTypeManager, $this->configFactory, $this->configStorage, $this->configManager, $this->moduleHandler, $this->configReverter);
-    $features_manager->setExtensionStorages($extension_storage->reveal());
-
-    $this->assertEquals(['test_config'], $features_manager->detectNew($package));
-  }
-
-  /**
-   * @todo This could have of course much more test coverage.
-   *
-   * @covers ::mergeInfoArray
-   *
-   * @dataProvider providerTestMergeInfoArray
-   */
-  public function testMergeInfoArray($expected, $info1, $info2, $keys = []) {
-    $this->assertSame($expected, $this->featuresManager->mergeInfoArray($info1, $info2, $keys));
-  }
-
-  public function providerTestMergeInfoArray() {
-    $data = [];
-    $data['empty-info'] = [[], [], []];
-    $data['override-info'] = [
-      ['name' => 'New name', 'core' => '8.x'],
-      ['name' => 'Old name', 'core' => '8.x'],
-      ['name' => 'New name']
-    ];
-    $data['dependency-merging'] = [
-      ['dependencies' => ['a', 'b', 'c', 'd', 'e']],
-      ['dependencies' => ['b', 'd', 'c']],
-      ['dependencies' => ['a', 'b', 'e']],
-      [],
-    ];
-
-    return $data;
-  }
-
-  /**
-   * @covers ::initPackage
-   **/
-  public function testInitPackageWithNewPackage() {
-    $bundle = new FeaturesBundle(['machine_name' => 'test'], 'features_bundle');
-
-    $features_manager = new TestFeaturesManager($this->root, $this->entityTypeManager, $this->configFactory, $this->configStorage, $this->configManager, $this->moduleHandler, $this->configReverter);
-    $features_manager->setAllModules([]);
-
-    $package = $features_manager->initPackage('test_feature', 'test name', 'test description', 'module', $bundle);
-
-    $this->assertInstanceOf(Package::class, $package);
-    $this->assertEquals('test_feature', $package->getMachineName());
-    $this->assertEquals('test name', $package->getName());
-    $this->assertEquals('test description', $package->getDescription());
-    $this->assertEquals('module', $package->getType());
-    $this->assertEquals(['bundle' => 'test'], $package->getFeaturesInfo());
-    $this->assertEquals('test', $package->getBundle());
-    $this->assertEquals(FALSE, $package->getRequired());
-    $this->assertEquals([], $package->getExcluded());
-  }
-
-  /**
-   * @covers ::getFeaturesInfo
-   * @covers ::getFeaturesModules
-   **/
-  public function testInitPackageWithExistingPackage() {
-    $bundle = new FeaturesBundle(['machine_name' => 'test'], 'features_bundle');
-
-    $features_manager = new TestFeaturesManager('vfs://drupal', $this->entityTypeManager, $this->configFactory, $this->configStorage, $this->configManager, $this->moduleHandler, $this->configReverter);
-
-    vfsStream::setup('drupal');
-    \Drupal::getContainer()->set('app.root', 'vfs://drupal');
-    vfsStream::create([
-      'modules' => [
-        'test_feature' => [
-          'test_feature.info.yml' => <<<EOT
-name: Test feature 2
-type: module
-core: 8.x
-description: test description 2
-EOT
-      ,
-          'test_feature.features.yml' => <<<EOT
-bundle: test
-excluded:
-  - system.theme
-required: true
-EOT
-          ,
-        ],
-      ],
-    ]);
-    $extension = new Extension('vfs://drupal', 'module', 'modules/test_feature/test_feature.info.yml');
-    $features_manager->setAllModules(['test_feature' => $extension]);
-
-    $this->moduleHandler->expects($this->any())
-      ->method('exists')
-      ->with('test_feature')
-      ->willReturn(TRUE);
-
-    $info_parser = new InfoParser();
-    \Drupal::getContainer()->set('info_parser', $info_parser);
-
-    $package = $features_manager->initPackage('test_feature', 'test name', 'test description', 'module', $bundle);
-
-    $this->assertEquals([
-      'bundle' => 'test',
-      'excluded' => [
-        0 => 'system.theme',
-      ],
-      'required' => TRUE,
-    ], $features_manager->getFeaturesInfo($extension));
-    $this->assertEquals(['test_feature' => $extension], $features_manager->getFeaturesModules($bundle));
-
-    $this->assertInstanceOf(Package::class, $package);
-    $this->assertEquals([
-      'bundle' => 'test',
-      'excluded' => [
-        0 => 'system.theme',
-      ],
-      'required' => TRUE,
-    ], $package->getFeaturesInfo());
-    $this->assertEquals('test', $package->getBundle());
-    $this->assertEquals(TRUE, $package->getRequired());
-    $this->assertEquals(['system.theme'], $package->getExcluded());
-  }
-
-  /**
-   * @covers ::prepareFiles
-   * @covers ::addInfoFile
-   */
-  public function testPrepareFiles() {
-    $packages = [];
-    $packages['test_feature'] = new Package('test_feature', [
-      'config' => ['test_config'],
-      'name' => 'Test feature',
-    ]);
-
-    $packages['test_feature2'] = new Package('test_feature2', [
-      'config' => ['test_config2'],
-      'name' => 'Test feature 2',
-      'type' => 'profile',
-      'excluded' => ['my_config'],
-      'required' => ['test_config2'],
-    ]);
-
-    $config_collection = [];
-    $config_collection['test_config'] = new ConfigurationItem('test_config', ['foo' => 'bar']);
-    $config_collection['test_config2'] = new ConfigurationItem('test_config2', ['foo' => 'bar']);
-
-    $this->featuresManager->setConfigCollection($config_collection);
-    $this->featuresManager->prepareFiles($packages);
-
-    // Test test_feature package.
-    $files = $packages['test_feature']->getFiles();
-    $this->assertCount(3, $files);
-    $this->assertEquals('test_feature.info.yml', $files['info']['filename']);
-    $this->assertEquals(Yaml::encode([
-      'name' => 'Test feature',
-      'type' => 'module',
-      'core' => '8.x',
-    ]), $files['info']['string']);
-    $this->assertEquals(Yaml::encode(TRUE), $files['features']['string']);
-
-    $this->assertEquals('test_config.yml', $files['test_config']['filename']);
-    $this->assertEquals(Yaml::encode([
-      'foo' => 'bar'
-    ]), $files['test_config']['string']);
-
-    $this->assertEquals('test_feature.features.yml', $files['features']['filename']);
-    $this->assertEquals(Yaml::encode(TRUE), $files['features']['string']);
-
-    // Test test_feature2 package.
-    $files = $packages['test_feature2']->getFiles();
-
-    $this->assertEquals(Yaml::encode([
-      'excluded' => ['my_config'],
-      'required' => ['test_config2'],
-    ]), $files['features']['string']);
-  }
-
-  /**
-   * @covers ::getExportInfo
-   */
-  public function testGetExportInfoWithoutBundle() {
-    $config_factory = $this->getConfigFactoryStub([
-      'features.settings' => [
-        'export' => [
-          'folder' => 'custom',
-        ],
-      ],
-    ]);
-    $this->featuresManager = new FeaturesManager($this->root, $this->entityTypeManager, $config_factory, $this->configStorage, $this->configManager, $this->moduleHandler, $this->configReverter);
-
-    $package = new Package('test_feature');
-    $result = $this->featuresManager->getExportInfo($package);
-
-    $this->assertEquals(['test_feature', 'modules/custom'], $result);
-  }
-
-  /**
-   * @covers ::getExportInfo
-   */
-  public function testGetExportInfoWithBundle() {
-    $config_factory = $this->getConfigFactoryStub([
-      'features.settings' => [
-        'export' => [
-          'folder' => 'custom',
-        ],
-      ],
-    ]);
-    $this->featuresManager = new FeaturesManager($this->root, $this->entityTypeManager, $config_factory, $this->configStorage, $this->configManager, $this->moduleHandler, $this->configReverter);
-
-    $package = new Package('test_feature');
-    $bundle = new FeaturesBundle(['machine_name' => 'test_bundle'], 'features_bundle');
-
-    $result = $this->featuresManager->getExportInfo($package, $bundle);
-
-    $this->assertEquals(['test_bundle_test_feature', 'modules/custom'], $result);
-  }
-
-}
-
-class TestFeaturesManager extends FeaturesManager {
-
-  protected $allModules;
-
-  /**
-   * @param \Drupal\features\FeaturesExtensionStoragesInterface $extensionStorages
-   */
-  public function setExtensionStorages($extensionStorages) {
-    $this->extensionStorages = $extensionStorages;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getAllModules() {
-    if (isset($this->allModules)) {
-      return $this->allModules;
-    }
-    return parent::getAllModules();
-  }
-
-  /**
-   * @param mixed $all_modules
-   */
-  public function setAllModules($all_modules) {
-    $this->allModules = $all_modules;
-    return $this;
-  }
-
-  protected function drupalGetProfile() {
-    return FeaturesManagerTest::PROFILE_NAME;
-  }
-
-}
diff --git a/web/modules/features/tests/src/Unit/PackageTest.php b/web/modules/features/tests/src/Unit/PackageTest.php
deleted file mode 100644
index f1b322231ec8044b79b126f62a55adfe66ff39b3..0000000000000000000000000000000000000000
--- a/web/modules/features/tests/src/Unit/PackageTest.php
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php
-
-namespace Drupal\Tests\features\Unit;
-
-use Drupal\features\Package;
-
-/**
- * @coversDefaultClass \Drupal\features\Package
- * @group features
- */
-class PackageTest extends \PHPUnit_Framework_TestCase {
-
-  /**
-   * @covers ::setFeaturesInfo
-   */
-  public function testSetFeaturesInfo() {
-    $package = new Package('test_feature', []);
-
-    $this->assertEquals([], $package->getFeaturesInfo());
-    $package->setFeaturesInfo(['bundle' => 'test_bundle']);
-    $this->assertEquals(['bundle' => 'test_bundle'], $package->getFeaturesInfo());
-    $this->assertEquals('test_bundle', $package->getBundle());
-  }
-
-  public function testGetConfig() {
-    $package = new Package('test_feature', ['config' => ['test_config_a', 'test_config_b']]);
-    $this->assertEquals(['test_config_a', 'test_config_b'], $package->getConfig());
-    return $package;
-  }
-
-  /**
-   * @depends testGetConfig
-   * @covers ::appendConfig
-   */
-  public function testAppendConfig(Package $package) {
-    $package->appendConfig('test_config_a');
-    $package->appendConfig('test_config_c');
-
-    $this->assertEquals(['test_config_a', 'test_config_b', 'test_config_c'], array_values($package->getConfig()));
-    return $package;
-  }
-
-  /**
-   * @depends testAppendConfig
-   * @covers ::removeConfig
-   */
-  public function testRemoveConfig(Package $package) {
-    $package->removeConfig('test_config_a');
-
-    $this->assertEquals(['test_config_b', 'test_config_c'], array_values($package->getConfig()));
-  }
-
-}