diff --git a/composer.json b/composer.json
index 4c099b5ea7921ba48556fd4e6580fb862d7dfd99..1edf2bc14ba4d1abb5da61b15943bbc9d6a3108d 100644
--- a/composer.json
+++ b/composer.json
@@ -114,7 +114,7 @@
         "drupal/editor_advanced_link": "1.4",
         "drupal/embed": "1.0",
         "drupal/entity": "1.0-beta1",
-        "drupal/entity_browser": "1.4",
+        "drupal/entity_browser": "1.10",
         "drupal/entity_clone": "1.0.0-beta3",
         "drupal/entity_embed": "1.0-beta2",
         "drupal/entity_reference_revisions": "1.8",
diff --git a/composer.lock b/composer.lock
index 6e8ee99d0c75a54d4341f30f94dbf443417018b0..eca52f3412f30742dde63d3d0e0684cc9fe785b4 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": "e4746447f1d486ac63e393e17d8faba2",
+    "content-hash": "94677203e7554a130543f5a5bf9d86d8",
     "packages": [
         {
             "name": "alchemy/zippy",
@@ -4327,37 +4327,39 @@
         },
         {
             "name": "drupal/entity_browser",
-            "version": "1.4.0",
+            "version": "1.10.0",
             "source": {
                 "type": "git",
                 "url": "https://git.drupalcode.org/project/entity_browser.git",
-                "reference": "8.x-1.4"
+                "reference": "8.x-1.10"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://ftp.drupal.org/files/projects/entity_browser-8.x-1.4.zip",
-                "reference": "8.x-1.4",
-                "shasum": "4375e996b8d1e103ca5daf9ce352e2af9cab568f"
+                "url": "https://ftp.drupal.org/files/projects/entity_browser-8.x-1.10.zip",
+                "reference": "8.x-1.10",
+                "shasum": "1a6b9f293f4763759fee2362ed7566f270829356"
             },
             "require": {
-                "drupal/core": "~8.0"
+                "drupal/core": "^8.7.7 || ^9"
             },
             "require-dev": {
-                "drupal/ctools": "*",
-                "drupal/inline_entity_form": "*",
-                "drupal/media_entity": "*",
-                "drupal/paragraphs": "*",
-                "drupal/token": "*"
+                "drupal/embed": "~1.0",
+                "drupal/entity": "~1.0",
+                "drupal/entity_embed": "~1.0",
+                "drupal/entityqueue": "~1.0",
+                "drupal/inline_entity_form": "~1.0",
+                "drupal/media_entity": "~1.0",
+                "drupal/paragraphs": "~1.0",
+                "drupal/token": "~1.0"
             },
             "type": "drupal-module",
             "extra": {
                 "branch-alias": {
-                    "dev-1.x": "1.x-dev",
-                    "dev-8.x-1.x": "8.1.x-dev"
+                    "dev-1.x": "1.x-dev"
                 },
                 "drupal": {
-                    "version": "8.x-1.4",
-                    "datestamp": "1528140780",
+                    "version": "8.x-1.10",
+                    "datestamp": "1579563787",
                     "security-coverage": {
                         "status": "covered",
                         "message": "Covered by Drupal's security advisory policy"
@@ -4384,6 +4386,10 @@
                     "homepage": "https://www.drupal.org/node/1943336/committers",
                     "role": "contributor"
                 },
+                {
+                    "name": "Drupal Media Team",
+                    "homepage": "https://www.drupal.org/user/3260690"
+                },
                 {
                     "name": "Primsi",
                     "homepage": "https://www.drupal.org/user/282629"
@@ -4392,6 +4398,10 @@
                     "name": "marcingy",
                     "homepage": "https://www.drupal.org/user/77320"
                 },
+                {
+                    "name": "oknate",
+                    "homepage": "https://www.drupal.org/user/471638"
+                },
                 {
                     "name": "samuel.mortenson",
                     "homepage": "https://www.drupal.org/user/2582268"
@@ -4404,16 +4414,16 @@
             "description": "Entity browsing and selecting component.",
             "homepage": "http://drupal.org/project/entity_browser",
             "support": {
-                "source": "http://cgit.drupalcode.org/entity_browser",
-                "issues": "http://drupal.org/project/issues/entity_browser",
+                "source": "https://git.drupalcode.org/project/entity_browser",
+                "issues": "https://www.drupal.org/project/issues/entity_browser",
                 "irc": "irc://irc.freenode.org/drupal-contribute"
             }
         },
         {
             "name": "drupal/entity_browser_entity_form",
-            "version": "1.4.0",
+            "version": "1.10.0",
             "require": {
-                "drupal/core": "~8.0",
+                "drupal/core": "^8.7.7 || ^9",
                 "drupal/entity_browser": "self.version",
                 "drupal/inline_entity_form": "*"
             },
@@ -4423,8 +4433,8 @@
                     "dev-1.x": "1.x-dev"
                 },
                 "drupal": {
-                    "version": "8.x-1.4",
-                    "datestamp": "1528140780",
+                    "version": "8.x-1.10",
+                    "datestamp": "1579563787",
                     "security-coverage": {
                         "status": "covered",
                         "message": "Covered by Drupal's security advisory policy"
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index c55698ce71041d090964b9b4b503c0c2c98c7506..84d8bc52eda762e8fbff65a79b9da4285e9aa94e 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -4456,38 +4456,40 @@
     },
     {
         "name": "drupal/entity_browser",
-        "version": "1.4.0",
-        "version_normalized": "1.4.0.0",
+        "version": "1.10.0",
+        "version_normalized": "1.10.0.0",
         "source": {
             "type": "git",
             "url": "https://git.drupalcode.org/project/entity_browser.git",
-            "reference": "8.x-1.4"
+            "reference": "8.x-1.10"
         },
         "dist": {
             "type": "zip",
-            "url": "https://ftp.drupal.org/files/projects/entity_browser-8.x-1.4.zip",
-            "reference": "8.x-1.4",
-            "shasum": "4375e996b8d1e103ca5daf9ce352e2af9cab568f"
+            "url": "https://ftp.drupal.org/files/projects/entity_browser-8.x-1.10.zip",
+            "reference": "8.x-1.10",
+            "shasum": "1a6b9f293f4763759fee2362ed7566f270829356"
         },
         "require": {
-            "drupal/core": "~8.0"
+            "drupal/core": "^8.7.7 || ^9"
         },
         "require-dev": {
-            "drupal/ctools": "*",
-            "drupal/inline_entity_form": "*",
-            "drupal/media_entity": "*",
-            "drupal/paragraphs": "*",
-            "drupal/token": "*"
+            "drupal/embed": "~1.0",
+            "drupal/entity": "~1.0",
+            "drupal/entity_embed": "~1.0",
+            "drupal/entityqueue": "~1.0",
+            "drupal/inline_entity_form": "~1.0",
+            "drupal/media_entity": "~1.0",
+            "drupal/paragraphs": "~1.0",
+            "drupal/token": "~1.0"
         },
         "type": "drupal-module",
         "extra": {
             "branch-alias": {
-                "dev-1.x": "1.x-dev",
-                "dev-8.x-1.x": "8.1.x-dev"
+                "dev-1.x": "1.x-dev"
             },
             "drupal": {
-                "version": "8.x-1.4",
-                "datestamp": "1528140780",
+                "version": "8.x-1.10",
+                "datestamp": "1579563787",
                 "security-coverage": {
                     "status": "covered",
                     "message": "Covered by Drupal's security advisory policy"
@@ -4515,6 +4517,10 @@
                 "homepage": "https://www.drupal.org/node/1943336/committers",
                 "role": "contributor"
             },
+            {
+                "name": "Drupal Media Team",
+                "homepage": "https://www.drupal.org/user/3260690"
+            },
             {
                 "name": "Primsi",
                 "homepage": "https://www.drupal.org/user/282629"
@@ -4523,6 +4529,10 @@
                 "name": "marcingy",
                 "homepage": "https://www.drupal.org/user/77320"
             },
+            {
+                "name": "oknate",
+                "homepage": "https://www.drupal.org/user/471638"
+            },
             {
                 "name": "samuel.mortenson",
                 "homepage": "https://www.drupal.org/user/2582268"
@@ -4535,17 +4545,17 @@
         "description": "Entity browsing and selecting component.",
         "homepage": "http://drupal.org/project/entity_browser",
         "support": {
-            "source": "http://cgit.drupalcode.org/entity_browser",
-            "issues": "http://drupal.org/project/issues/entity_browser",
+            "source": "https://git.drupalcode.org/project/entity_browser",
+            "issues": "https://www.drupal.org/project/issues/entity_browser",
             "irc": "irc://irc.freenode.org/drupal-contribute"
         }
     },
     {
         "name": "drupal/entity_browser_entity_form",
-        "version": "1.4.0",
-        "version_normalized": "1.4.0.0",
+        "version": "1.10.0",
+        "version_normalized": "1.10.0.0",
         "require": {
-            "drupal/core": "~8.0",
+            "drupal/core": "^8.7.7 || ^9",
             "drupal/entity_browser": "self.version",
             "drupal/inline_entity_form": "*"
         },
@@ -4555,8 +4565,8 @@
                 "dev-1.x": "1.x-dev"
             },
             "drupal": {
-                "version": "8.x-1.4",
-                "datestamp": "1528140780",
+                "version": "8.x-1.10",
+                "datestamp": "1579563787",
                 "security-coverage": {
                     "status": "covered",
                     "message": "Covered by Drupal's security advisory policy"
diff --git a/web/modules/entity_browser/.travis-before-script.sh b/web/modules/entity_browser/.travis-before-script.sh
index 3127f466c149581a7f6460685636e52731e055ab..5c1bae54367ba11525d5de6f5acf3ad7097abc2b 100644
--- a/web/modules/entity_browser/.travis-before-script.sh
+++ b/web/modules/entity_browser/.travis-before-script.sh
@@ -14,7 +14,6 @@
 cd "$DRUPAL_TI_MODULES_PATH"
 
 git clone --depth 1 --branch 8.x-1.x http://git.drupal.org/project/token.git
-git clone --depth 1 --branch 8.x-3.x http://git.drupal.org/project/ctools.git
 git clone --depth 1 --branch 8.x-1.x http://git.drupal.org/project/inline_entity_form.git
 git clone --depth 1 --branch 8.x-1.x http://git.drupal.org/project/media_entity.git
 git clone --depth 1 --branch 8.x-1.x http://git.drupal.org/project/paragraphs.git
diff --git a/web/modules/entity_browser/.travis-phpcs.sh b/web/modules/entity_browser/.travis-phpcs.sh
old mode 100644
new mode 100755
diff --git a/web/modules/entity_browser/DEVELOPING.md b/web/modules/entity_browser/DEVELOPING.md
deleted file mode 100644
index 065d9f30251d15a374827f84ca7f631d4ac98d36..0000000000000000000000000000000000000000
--- a/web/modules/entity_browser/DEVELOPING.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# Developing
-
-* Issues should be filed at http://drupal.org/project/issues/entity_browser
-* Pull requests can be made against https://github.com/drupal-media/entity_browser/pulls
diff --git a/web/modules/entity_browser/README.md b/web/modules/entity_browser/README.md
index 0489948043d000fe6817a0d11d7f92b2efc075d0..b46d6275ecd4d798cb5dc59e6df0c2d52eb43d68 100644
--- a/web/modules/entity_browser/README.md
+++ b/web/modules/entity_browser/README.md
@@ -1,20 +1,16 @@
-# Entity Browser Module
-
-[![Build Status](https://travis-ci.org/drupal-media/entity_browser.svg?branch=8.x-1.x)](https://travis-ci.org/drupal-media/entity_browser) [![Scrutinizer](https://img.shields.io/scrutinizer/g/drupal-media/entity_browser.svg)](https://scrutinizer-ci.com/g/drupal-media/entity_browser)
+Entity Browser Module
 
 Provides standardized interface to list, create and select entities.
 
 ## Requirements
 
 * Latest dev release of Drupal 8.x.
-* [Chaos tool set](https://drupal.org/project/ctools) (soft dependency for configuration UI)
 
 ## Configuration
 
 Module ships with a simple configuration UI which allows you to create, edit
-and delete entity browsers. It depends on
-[Chaos tool set](https://drupal.org/project/ctools). Enable it and navigate to
-/admin/config/content/entity_browser.
+and delete entity browsers. Navigate to
+/admin/config/content/entity_browser to use the UI.
 
 In order to use this configuration for testing or to help you contribute just 
 enable "Entity Browser example" module (entity_browser_example).
diff --git a/web/modules/entity_browser/composer.json b/web/modules/entity_browser/composer.json
index 2174fcb75cabcb7ee558cf70fd8ddcc309ae8b31..2b970368df5517ca92ba9e9e68cd1f37a90db5f8 100644
--- a/web/modules/entity_browser/composer.json
+++ b/web/modules/entity_browser/composer.json
@@ -21,16 +21,23 @@
     }
   ],
   "support": {
-    "issues": "http://drupal.org/project/issues/entity_browser",
+    "issues": "https://www.drupal.org/project/issues/entity_browser",
     "irc": "irc://irc.freenode.org/drupal-contribute",
-    "source": "http://cgit.drupalcode.org/entity_browser"
+    "source": "https://git.drupalcode.org/project/entity_browser"
   },
   "license": "GPL-2.0+",
   "minimum-stability": "dev",
-  "require": { },
-  "extra": {
-    "branch-alias": {
-      "dev-8.x-1.x": "8.1.x-dev"
-    }
+  "require": {
+    "drupal/core": "^8.7.7 || ^9"
+  },
+  "require-dev": {
+    "drupal/token": "~1.0",
+    "drupal/inline_entity_form": "~1.0",
+    "drupal/paragraphs": "~1.0",
+    "drupal/entity": "~1.0",
+    "drupal/media_entity": "~1.0",
+    "drupal/embed": "~1.0",
+    "drupal/entity_embed": "~1.0",
+    "drupal/entityqueue": "~1.0"
   }
 }
diff --git a/web/modules/entity_browser/config/schema/entity_browser.schema.yml b/web/modules/entity_browser/config/schema/entity_browser.schema.yml
index 741679929fde821e2040ceaa50d3eb6b9b3df30d..84ff907017fdc046ba44676780588a3ce60c019f 100644
--- a/web/modules/entity_browser/config/schema/entity_browser.schema.yml
+++ b/web/modules/entity_browser/config/schema/entity_browser.schema.yml
@@ -61,7 +61,7 @@ entity_browser.browser.display.iframe:
       type: string
       label: 'iFrame height'
     link_text:
-      type: string
+      type: label
       label: 'Link text'
     auto_open:
       type: boolean
@@ -78,7 +78,7 @@ entity_browser.browser.display.modal:
       type: string
       label: 'Modal height'
     link_text:
-      type: string
+      type: label
       label: 'Link text'
     auto_open:
       type: boolean
@@ -89,7 +89,7 @@ entity_browser.browser.widget.upload:
   label: 'Upload widget configuration'
   mapping:
     submit_text:
-      type: string
+      type: label
       label: 'Submit button text'
     upload_location:
       type: string
@@ -106,7 +106,7 @@ entity_browser.browser.widget.view:
   label: 'View widget configuration'
   mapping:
     submit_text:
-      type: string
+      type: label
       label: 'Submit button text'
     auto_select:
       type: boolean
@@ -136,7 +136,7 @@ entity_browser.browser.selection_display.multi_step_display:
     display_settings:
       type: entity_browser.field_widget_display.[%parent.display]
     select_text:
-      type: string
+      type: label
       label: 'Select text'
     selection_hidden:
       type: boolean
@@ -169,6 +169,9 @@ field.widget.settings.entity_browser_entity_reference:
     field_widget_remove:
       type: boolean
       label: 'Field widget remove'
+    field_widget_replace:
+      type: boolean
+      label: 'Field widget replace'
     open:
       type: boolean
       label: 'Open'
@@ -211,6 +214,9 @@ field.widget.settings.entity_browser_file:
     field_widget_remove:
       type: boolean
       label: 'Field widget remove'
+    field_widget_replace:
+      type: boolean
+      label: 'Field widget replace'
     open:
       type: boolean
       label: 'Open'
@@ -224,6 +230,24 @@ field.widget.settings.entity_browser_file:
       type: string
       label: 'Preview image style'
 
+views.filter.entity_browser_bundle:
+  type: views.filter.in_operator
+  label: 'Bundle'
+
 views.display.entity_browser:
   type: views_display
   label: 'Entity browser display options'
+
+views.argument_default.entity_browser_widget_context:
+  type: mapping
+  label: 'Entity Browser Context'
+  mapping:
+    context_key:
+      type: string
+      label: 'Context key'
+    fallback:
+      type: string
+      label: 'Fallback value'
+    multiple:
+      type: string
+      label: 'Multiple values'
diff --git a/web/modules/entity_browser/config/schema/entity_browser.views.schema.yml b/web/modules/entity_browser/config/schema/entity_browser.views.schema.yml
new file mode 100644
index 0000000000000000000000000000000000000000..a2a2e287848e6aa06ae38563c6cc40ed7dade67e
--- /dev/null
+++ b/web/modules/entity_browser/config/schema/entity_browser.views.schema.yml
@@ -0,0 +1,7 @@
+views.field.entity_browser_select:
+  type: views_field
+  label: 'Entity Browser select'
+  mapping:
+    use_field_cardinality:
+      type: boolean
+      label: 'Use field cardinality'
diff --git a/web/modules/entity_browser/css/entity_browser.file_browser.css b/web/modules/entity_browser/css/entity_browser.file_browser.css
index c8ed44ca7559665efd013f5ffcad4dbe6cabeaa7..43b6a58df567ace3dd01754a17ac722225514ea5 100644
--- a/web/modules/entity_browser/css/entity_browser.file_browser.css
+++ b/web/modules/entity_browser/css/entity_browser.file_browser.css
@@ -1,70 +1,75 @@
 @media screen and (max-width: 1250px) {
-    .entities-list tbody * {
-        display: block;
-    }
+  .entities-list tbody * {
+    display: block;
+  }
 
-    .entities-list thead tr th:nth-child(2), .entities-list thead tr th:nth-child(3), .entities-list thead tr th:nth-child(4) {
-        display: none;
-    }
+  .entities-list thead tr th:nth-child(2),
+  .entities-list thead tr th:nth-child(3),
+  .entities-list thead tr th:nth-child(4) {
+    display: none;
+  }
 
-    .entities-list tbody tr td a.tabledrag-handle {
-        position: absolute;
-        margin-left: -40px;
-    }
+  .entities-list tbody tr td a.tabledrag-handle {
+    position: absolute;
+    margin-left: -40px;
+  }
 
-    .entities-list tbody tr td {
-        margin-left: 20px;
-    }
+  .entities-list tbody tr td {
+    margin-left: 20px;
+  }
 }
 
 @media screen and (min-width: 1251px) {
-    .entities-list {
-        table-layout: fixed;
-    }
+  .entities-list {
+    table-layout: fixed;
+  }
 }
 
 @media screen and (min-width: 1021px) and (max-width: 1100px) {
-    .toolbar-tray-open.toolbar-vertical .entities-list {
-        display: inline-block;
-    }
+  .toolbar-tray-open.toolbar-vertical .entities-list {
+    display: inline-block;
+  }
 
-    .toolbar-tray-open.toolbar-vertical .entities-list thead, .toolbar-tray-open .entities-list tbody {
-        display: inline-block;
-        width: 100%;
-    }
+  .toolbar-tray-open.toolbar-vertical .entities-list thead,
+  .toolbar-tray-open .entities-list tbody {
+    display: inline-block;
+    width: 100%;
+  }
 
-    .toolbar-tray-open.toolbar-vertical .entities-list thead > tr {
-        display: table;
-        width: 100%;
-    }
+  .toolbar-tray-open.toolbar-vertical .entities-list thead > tr {
+    display: table;
+    width: 100%;
+  }
 
-    .toolbar-tray-open.toolbar-vertical .entities-list tbody tr td {
-        padding-right: 0;
-    }
+  .toolbar-tray-open.toolbar-vertical .entities-list tbody tr td {
+    padding-right: 0;
+  }
 }
 
 @media screen and (min-width: 780px) and (max-width: 920px) {
-    .entities-list input.form-text, .entities-list textarea.form-textarea {
-        width: 100%;
-    }
+  .entities-list input.form-text,
+  .entities-list textarea.form-textarea {
+    width: 100%;
+  }
 }
 
 @media screen and (min-width: 610px) and (max-width: 780px) {
-    .toolbar-tray-open .entities-list {
-        display: inline-block;
-    }
+  .toolbar-tray-open .entities-list {
+    display: inline-block;
+  }
 
-    .toolbar-tray-open .entities-list thead, .toolbar-tray-open .entities-list tbody {
-        display: inline-block;
-        width: 100%;
-    }
+  .toolbar-tray-open .entities-list thead,
+  .toolbar-tray-open .entities-list tbody {
+    display: inline-block;
+    width: 100%;
+  }
 
-    .toolbar-tray-open .entities-list thead > tr {
-        display: table;
-        width: 100%;
-    }
+  .toolbar-tray-open .entities-list thead > tr {
+    display: table;
+    width: 100%;
+  }
 
-    .toolbar-tray-open .entities-list tbody tr td {
-        padding-right: 0;
-    }
+  .toolbar-tray-open .entities-list tbody tr td {
+    padding-right: 0;
+  }
 }
diff --git a/web/modules/entity_browser/css/entity_browser.iframe.css b/web/modules/entity_browser/css/entity_browser.iframe.css
index badefbb16d60d94ec3a69dfaef42a946b30a4057..a503f8b116ad38d386466e06df485176fff274da 100644
--- a/web/modules/entity_browser/css/entity_browser.iframe.css
+++ b/web/modules/entity_browser/css/entity_browser.iframe.css
@@ -3,12 +3,14 @@
  * Styles for the iFrame Display Plugin.
  */
 
-/* Remove the border on our iframe element. */
-
 .entity-browser-iframe-container iframe {
-  border: none;
+  /* IFrame is rendered as inline element by default and thus have a line height
+  which can add unwanted vertical space around it. */
+  display: block;
   position: relative;
   z-index: 501;
+  /* Remove the border on our iframe element. */
+  border: none;
 }
 
 .entity-browser-iframe-container .ajax-progress-fullscreen {
diff --git a/web/modules/entity_browser/css/entity_browser.modal.css b/web/modules/entity_browser/css/entity_browser.modal.css
new file mode 100644
index 0000000000000000000000000000000000000000..c81687e113524129c804b980f4899386ba04a523
--- /dev/null
+++ b/web/modules/entity_browser/css/entity_browser.modal.css
@@ -0,0 +1,16 @@
+/**
+ * @file
+ * Styles for entity browser modal.
+ */
+
+/** IFrame is rendered as inline element by default and thus have a line height
+    which can trigger vertical scrollbar on a parent ui-dialog-content wrapper
+    element. */
+.entity-browser-modal-iframe {
+  display: block;
+}
+
+/** Prevent div wrapper to have height bigger then dialog content height. */
+.entity-browser-modal .ui-dialog-content > * {
+  max-height: 100%;
+}
diff --git a/web/modules/entity_browser/css/entity_browser.modal_selection.css b/web/modules/entity_browser/css/entity_browser.modal_selection.css
index df6622e7c6531ef227ae78fde5f038c245fac719..f461a3f8fc313351ae327783199c082e1fc39304 100644
--- a/web/modules/entity_browser/css/entity_browser.modal_selection.css
+++ b/web/modules/entity_browser/css/entity_browser.modal_selection.css
@@ -4,5 +4,5 @@
  */
 
 body {
-    display: none;
+  display: none;
 }
diff --git a/web/modules/entity_browser/css/entity_browser.pager.css b/web/modules/entity_browser/css/entity_browser.pager.css
index 22746e6dfb065257ed8097db52fdfc858c5b4bdd..70ceb6a35fe307dec1056e8aa1cb273e195e580c 100644
--- a/web/modules/entity_browser/css/entity_browser.pager.css
+++ b/web/modules/entity_browser/css/entity_browser.pager.css
@@ -1,38 +1,38 @@
 .js-form-type-entity-browser-pager {
-    margin-top: 10px;
-    text-align: center;
+  margin-top: 10px;
+  text-align: center;
 }
 
 .js-form-type-entity-browser-pager input,
 .js-form-type-entity-browser-pager input:hover,
 .js-form-type-entity-browser-pager input:focus {
-    background: 0;
-    border: 0;
-    border-radius: 0;
-    box-shadow: none;
-    color: #2a678c;
-    font-size: 1.08em;
-    font-weight: bold;
-    margin: 0;
-    padding: 0;
+  background: 0;
+  border: 0;
+  border-radius: 0;
+  box-shadow: none;
+  color: #2a678c;
+  font-size: 1.08em;
+  font-weight: bold;
+  margin: 0;
+  padding: 0;
 }
 
 .js-form-type-entity-browser-pager span {
-    color: #8c8c8c;
-    font-size: 1.08em;
-    font-weight: bold;
-    margin: 0.8em;
+  color: #8c8c8c;
+  font-size: 1.08em;
+  font-weight: bold;
+  margin: 0.8em;
 }
 
 .js-form-type-entity-browser-pager input[name="prev_page"]:disabled,
 .js-form-type-entity-browser-pager input[name="next_page"]:disabled {
-    visibility: hidden;
+  visibility: hidden;
 }
 
 .js-form-type-entity-browser-pager input:focus:not(:disabled),
 .js-form-type-entity-browser-pager input:hover:not(:disabled) {
-    border-radius: 0;
-    color: #0074bd;
-    font-size: 1.08em;
-    font-weight: bold;
+  border-radius: 0;
+  color: #0074bd;
+  font-size: 1.08em;
+  font-weight: bold;
 }
diff --git a/web/modules/entity_browser/entity_browser.api.php b/web/modules/entity_browser/entity_browser.api.php
index 3c4b874a5719639927cb6298a874a62b98d1a37d..c33e9e14a873e73bed4645eaa5016a4040c98b75 100644
--- a/web/modules/entity_browser/entity_browser.api.php
+++ b/web/modules/entity_browser/entity_browser.api.php
@@ -72,6 +72,24 @@ function hook_entity_browser_widget_validation_info_alter(array &$validation_plu
   $field_displays['not_null']['label'] = t('Not null fabulous validator');
 }
 
+/**
+ * Edit any entity browser form.
+ *
+ * Implements hook_form_BASE_FORM_ID_alter().
+ */
+function hook_form_entity_browser_form_alter(&$form, FormStateInterface $form_state, $form_id) {
+  $form['#attributes']['class'][] = 'hello-world';
+}
+
+/**
+ * Edit specific entity browser form.
+ *
+ * Implements hook_form_FORM_ID_alter().
+ */
+function hook_form_entity_browser_ENTITY_BROWSER_ID_form_alter(&$form, FormStateInterface $form_state, $form_id) {
+  $form['#attributes']['class'][] = 'hello-world';
+}
+
 /**
  * @} End of "addtogroup hooks".
  */
diff --git a/web/modules/entity_browser/entity_browser.info.yml b/web/modules/entity_browser/entity_browser.info.yml
index 5b6653b66e2162e526dfb8afe8422ba342faa265..6a4e303bca0d76f525b79417c14b0024644c6088 100644
--- a/web/modules/entity_browser/entity_browser.info.yml
+++ b/web/modules/entity_browser/entity_browser.info.yml
@@ -2,17 +2,17 @@ name: Entity Browser
 description: 'Provide a generic entity browser/picker/selector.'
 type: module
 package: Media
-# core: 8.x
+core_version_requirement: ^8.7.7 || ^9
 test_dependencies:
-  - ctools:ctools
   - token:token
   - inline_entity_form:inline_entity_form
   - media_entity:media_entity
   - paragraphs:paragraphs
+  - embed:embed
+  - entity_embed:entity_embed
 configure: entity.entity_browser.collection
 
-# Information added by Drupal.org packaging script on 2017-11-30
-version: '8.x-1.4'
-core: '8.x'
+# Information added by Drupal.org packaging script on 2020-01-20
+version: '8.x-1.10'
 project: 'entity_browser'
-datestamp: 1512033788
+datestamp: 1579563796
diff --git a/web/modules/entity_browser/entity_browser.libraries.yml b/web/modules/entity_browser/entity_browser.libraries.yml
index 6c5f396db27209a005a1947927abf155c2bb61a3..3bb86c86175766609a3506bec71ce60f9fc4e097 100644
--- a/web/modules/entity_browser/entity_browser.libraries.yml
+++ b/web/modules/entity_browser/entity_browser.libraries.yml
@@ -61,6 +61,9 @@ file_browser:
 
 modal:
   version: VERSION
+  css:
+    component:
+      css/entity_browser.modal.css: {}
   js:
     js/entity_browser.modal.js: {}
   dependencies:
diff --git a/web/modules/entity_browser/entity_browser.links.task.yml b/web/modules/entity_browser/entity_browser.links.task.yml
new file mode 100644
index 0000000000000000000000000000000000000000..2ec83ec6241e5ed6094e509f8c9d39cfb1a43578
--- /dev/null
+++ b/web/modules/entity_browser/entity_browser.links.task.yml
@@ -0,0 +1,17 @@
+entity.entity_browser.edit_form:
+  route_name: entity.entity_browser.edit_form
+  base_route: entity.entity_browser.edit_form
+  title: 'Edit'
+entity.entity_browser.edit_form_overview:
+  route_name: entity.entity_browser.edit_form
+  parent_id: entity.entity_browser.edit_form
+  title: 'General Settings'
+entity.entity_browser.edit_widgets:
+  route_name: entity.entity_browser.edit_widgets
+  parent_id: entity.entity_browser.edit_form
+  title: 'Widget Settings'
+entity.entity_browser.delete_form:
+  route_name: entity.entity_browser.delete_form
+  base_route: entity.entity_browser.edit_form
+  title: Delete
+  weight: 10
diff --git a/web/modules/entity_browser/entity_browser.module b/web/modules/entity_browser/entity_browser.module
index 872164516d716a888751ac5c9fa4ab7c3da502e6..db086afefd56b0a5e4770fe52ff174e390bde76e 100644
--- a/web/modules/entity_browser/entity_browser.module
+++ b/web/modules/entity_browser/entity_browser.module
@@ -5,10 +5,12 @@
  * Allows to flexibly create, browse and select entities.
  */
 
-use \Drupal\Core\Form\FormStateInterface;
-use \Drupal\Core\Render\Element;
+use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Render\Element;
 use Drupal\Core\Url;
-use \Drupal\file\FileInterface;
+use Drupal\file\FileInterface;
 use Drupal\Core\Routing\RouteMatchInterface;
 
 /**
@@ -19,7 +21,7 @@ function entity_browser_help($route_name, RouteMatchInterface $arg) {
     case 'help.page.entity_browser':
       $output = '';
       $output .= '<h3>' . t('About') . '</h3>';
-      $output .= '<p>' . t('The Entity Browser module provides a generic entity browser/picker/selector. It can be used in any context where one needs to select a few entities and do something with them. For more information, see the online documentation for <a href=":entity_browser-documentation">Entity Browser</a>.', [':entity_browser-documentation' => 'https://drupal-media.gitbooks.io/drupal8-guide/content/modules/entity_browser/intro.html']) . '</p>';
+      $output .= '<p>' . t('The Entity Browser module provides a generic entity browser/picker/selector. It can be used in any context where one needs to select a few entities and do something with them. For more information, see the online documentation for <a href=":entity_browser-documentation">Entity Browser</a>.', [':entity_browser-documentation' => 'https://www.drupal.org/docs/8/modules/entity-browser']) . '</p>';
       $output .= '<h3>' . t('Uses') . '</h3>';
       $output .= '<dl>';
       $output .= '<dt>' . t('General') . '</dt>';
@@ -81,6 +83,7 @@ function entity_browser_form_alter(&$form, FormStateInterface &$form_state) {
           'details_id' => \Drupal::request()->query->get('details_id'),
         ],
       ],
+      'disable-refocus' => TRUE,
     ];
   }
 }
@@ -149,7 +152,7 @@ function entity_browser_file_validate_image_resolution(FileInterface $file, $max
         if (!$file->isPermanent() && $image->scale($width, $height)) {
           $image->save();
           $file->filesize = $image->getFileSize();
-          drupal_set_message(t('The image was resized to fit within the maximum allowed dimensions of %dimensions pixels.', ['%dimensions' => $maximum_dimensions]));
+          \Drupal::messenger()->addMessage(t('The image was resized to fit within the maximum allowed dimensions of %dimensions pixels.', ['%dimensions' => $maximum_dimensions]));
         }
         else {
           $errors[] = t('The image exceeds the maximum allowed dimensions.');
@@ -168,3 +171,61 @@ function entity_browser_file_validate_image_resolution(FileInterface $file, $max
 
   return $errors;
 }
+
+/**
+ * Implements hook_form_BASE_FORM_ID_alter().
+ */
+function entity_browser_form_entity_embed_dialog_alter(&$form, FormStateInterface $form_state) {
+
+  // Add contextual information to entity browser's widget context array.
+  if (!empty($form['entity_browser']['#entity_browser'])) {
+    $embed_button = $form_state->get('embed_button');
+    $type_settings = $embed_button->getTypeSettings();
+
+    // Cardinality is always 1 with entity embed.
+    $context = [
+      'embed_button_id' => $embed_button->id(),
+      'cardinality' => 1,
+    ];
+
+    if (!empty($type_settings['entity_type'])) {
+      $context['target_entity_type'] = $type_settings['entity_type'];
+    }
+    if (!empty($type_settings['bundles'])) {
+      $context['target_bundles'] = $type_settings['bundles'];
+    }
+
+    $form['entity_browser']['#widget_context'] = $context;
+  }
+}
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ */
+function entity_browser_form_views_ui_add_handler_form_alter(&$form, FormStateInterface $form_state) {
+
+  // Hide 'entity_browser_bundle' views filter plugin for displays other than
+  // entity_browser.
+  $display_id = $form_state->get('display_id');
+  $display_plugin = $form_state
+    ->get('view')
+    ->get('storage')
+    ->get('display')[$display_id]['display_plugin'];
+
+  if ($display_plugin != 'entity_browser') {
+    foreach ($form['options']['name']['#options'] as $key => $value) {
+      if (strpos($key, 'entity_browser_bundle') !== FALSE) {
+        unset($form['options']['name']['#options'][$key]);
+      }
+    }
+  }
+}
+
+/**
+ * Implements hook_entity_view_alter().
+ */
+function entity_browser_entity_view_alter(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display) {
+  if (isset($build['#entity_browser_suppress_contextual'])) {
+    unset($build['#contextual_links']);
+  }
+}
diff --git a/web/modules/entity_browser/entity_browser.routing.yml b/web/modules/entity_browser/entity_browser.routing.yml
index e88bef511b919606455f5f0e6b3e7a7b4946627c..13162b14ae3288a8ae127673b9afbbf28110a127 100644
--- a/web/modules/entity_browser/entity_browser.routing.yml
+++ b/web/modules/entity_browser/entity_browser.routing.yml
@@ -16,19 +16,25 @@ entity_browser.edit_form:
 entity.entity_browser.add_form:
   path: '/admin/config/content/entity_browser/add'
   defaults:
-    _entity_wizard: 'entity_browser.add'
+    _entity_form: 'entity_browser.edit'
     _title: 'Add Entity browser'
     tempstore_id: 'entity_browser.config'
   requirements:
     _permission: 'administer entity browsers'
 
 entity.entity_browser.edit_form:
-  path: '/admin/config/content/entity_browser/{entity_browser}/{step}'
+  path: '/admin/config/content/entity_browser/{entity_browser}/edit'
   defaults:
-    _entity_wizard: 'entity_browser.edit'
-    _title: 'Edit Entity browser'
-    tempstore_id: 'entity_browser.config'
-    step: 'general'
+    _entity_form: 'entity_browser.edit'
+    _title: 'Edit Entity Browser'
+  requirements:
+    _permission: 'administer entity browsers'
+
+entity.entity_browser.edit_widgets:
+  path: '/admin/config/content/entity_browser/{entity_browser}/widgets'
+  defaults:
+    _entity_form: 'entity_browser.edit_widgets'
+    _title: 'Edit Widgets'
   requirements:
     _permission: 'administer entity browsers'
 
diff --git a/web/modules/entity_browser/entity_browser.services.yml b/web/modules/entity_browser/entity_browser.services.yml
index 769092d020cc98fa8370bd5611255261795fb16e..17dc5b1b1c08db8f1480aebd1497e9570ee429be 100644
--- a/web/modules/entity_browser/entity_browser.services.yml
+++ b/web/modules/entity_browser/entity_browser.services.yml
@@ -19,12 +19,7 @@ services:
     parent: default_plugin_manager
   entity_browser.route_subscriber:
     class: Drupal\entity_browser\RouteSubscriber
-    arguments: ['@entity.manager', '@plugin.manager.entity_browser.display', '@entity.query']
-  entity_browser.ctools_fallback_route_enhancer:
-    class: Drupal\entity_browser\Routing\CtoolsFallbackRouteEnhancer
-    arguments: ['@module_handler']
-    tags:
-      - { name: route_enhancer }
+    arguments: ['@entity_type.manager', '@plugin.manager.entity_browser.display']
   entity_browser.selection_storage:
     # Symfony will complain if the class is not defined. However, it seems that
     # it doesn't use it at all. Interface is not the best thing to set here, but
diff --git a/web/modules/entity_browser/entity_browser.views.inc b/web/modules/entity_browser/entity_browser.views.inc
index 934fde06a426c32abe76480152604d9d2f8a0f10..19bcf0466c77050e3e1f508c29cccd4d57473789 100644
--- a/web/modules/entity_browser/entity_browser.views.inc
+++ b/web/modules/entity_browser/entity_browser.views.inc
@@ -5,6 +5,8 @@
  * Provide views data for entity_browser.module.
  */
 
+use Drupal\search_api\Entity\Index;
+
 /**
  * Implements hook_views_data_alter().
  */
@@ -20,6 +22,31 @@ function entity_browser_views_data_alter(&$data) {
           'real field' => $entity_keys['id'],
         ],
       ];
+
+      if (!empty($entity_keys['bundle'])) {
+        $data[$base_table]['entity_browser_bundle'] = [
+          'title' => t('Entity Browser Target Bundles'),
+          'filter' => [
+            'id' => 'entity_browser_bundle',
+            'real field' => $entity_keys['bundle'],
+          ],
+        ];
+      }
     }
   }
+  if (\Drupal::moduleHandler()->moduleExists('search_api')) {
+    /** @var \Drupal\search_api\IndexInterface $index */
+    foreach (Index::loadMultiple() as $index) {
+      $key = 'search_api_index_' . $index->id();
+      $data[$key]['entity_browser_select'] = [
+        'title' => t('Entity browser bulk select form for Search API views'),
+        'help' => t('Add a form element that lets you use a view as a base to select entities in entity browser.'),
+        'field' => [
+          'id' => 'entity_browser_search_api_select',
+          'real field' => 'id',
+        ],
+      ];
+    }
+  }
+
 }
diff --git a/web/modules/entity_browser/js/entity_browser.entity_reference.js b/web/modules/entity_browser/js/entity_browser.entity_reference.js
index 882799afbd9ecaa304854b0d7d07d077982d5833..e3e343e809823451717debda0a9fa8b3cdbe3a59 100644
--- a/web/modules/entity_browser/js/entity_browser.entity_reference.js
+++ b/web/modules/entity_browser/js/entity_browser.entity_reference.js
@@ -19,6 +19,21 @@
           stop: Drupal.entityBrowserEntityReference.entitiesReordered
         });
       });
+      // The AJAX callback will give us a flag when we need to re-open the
+      // browser, most likely due to a "Replace" button being clicked.
+      if (typeof drupalSettings.entity_browser_reopen_browser !== 'undefined' &&  drupalSettings.entity_browser_reopen_browser) {
+        var data_drupal_selector = '[data-drupal-selector^="edit-' + drupalSettings.entity_browser_reopen_browser.replace(/_/g, '-') + '-entity-browser-entity-browser-' + '"][data-uuid]';
+        var $launch_browser_element = $(context).find(data_drupal_selector);
+        if ($launch_browser_element.attr('data-uuid') in drupalSettings.entity_browser && !drupalSettings.entity_browser[$launch_browser_element.attr('data-uuid')].auto_open) {
+          $launch_browser_element.click();
+        }
+        // In case this is inside a fieldset closed by default, open it so the
+        // user doesn't need to guess the browser is open but hidden there.
+        var $fieldset_summary = $launch_browser_element.closest('details').find('summary');
+        if ($fieldset_summary.length && $fieldset_summary.attr('aria-expanded') === 'false') {
+          $fieldset_summary.click();
+        }
+      }
     }
   };
 
diff --git a/web/modules/entity_browser/js/entity_browser.modal.js b/web/modules/entity_browser/js/entity_browser.modal.js
index e29802f3ae337eb53afd1117383510fbfcb11bb1..9418e07929bc3969a222159ed82ff2e7170abd77 100644
--- a/web/modules/entity_browser/js/entity_browser.modal.js
+++ b/web/modules/entity_browser/js/entity_browser.modal.js
@@ -49,9 +49,16 @@
    */
   Drupal.behaviors.fluidModal = {
     attach: function (context) {
+      var $window = $(window);
+      var $document = $(document);
+
+      // Be sure to run only once per window document.
+      if ($document.once('fluid-modal').length === 0) {
+        return;
+      }
 
       // Recalculate dialog size on window resize.
-      $(window).resize(function (context) {
+      $window.resize(function (event) {
         Drupal.entityBrowserModal.fluidDialog();
       });
 
@@ -63,7 +70,7 @@
 
       // Disable scrolling of the whole browser window to not interfere with the
       // iframe scrollbar.
-      $(window).on({
+      $window.on({
         'dialog:aftercreate': function (event, dialog, $element, settings) {
           $('body').css({overflow: 'hidden'});
         },
@@ -103,11 +110,11 @@
         }
         else {
           // If no maxHeight is defined, make it responsive.
-          dialog.option('height', vHeight - 100);
+          dialog.option('height', .92 * vHeight);
 
           // Because there is no iframe height 100% in HTML 5, we have to set
           // the height of the iframe as well.
-          var contentHeight = $this.find('.ui-dialog-content').height() - 20;
+          var contentHeight = $this.find('.ui-dialog-content').height();
           $this.find('iframe').css('height', contentHeight);
         }
 
diff --git a/web/modules/entity_browser/js/entity_browser.view.js b/web/modules/entity_browser/js/entity_browser.view.js
index 921bebd682354b0d472948d7aa3591aa61892bda..daaec6fc5893651af9fe2a76078d2ac704dcc777 100644
--- a/web/modules/entity_browser/js/entity_browser.view.js
+++ b/web/modules/entity_browser/js/entity_browser.view.js
@@ -19,8 +19,7 @@
       // views-related ID, which ours does not.
       var views_instance = Drupal.views.instances[Object.keys(Drupal.views.instances)[0]];
       if (views_instance) {
-        // Initialize the exposed form AJAX.
-        views_instance.$exposed_form = $('div#views-exposed-form-' + views_instance.settings.view_name.replace(/_/g, '-') + '-' + views_instance.settings.view_display_id.replace(/_/g, '-'));
+        views_instance.$exposed_form = $('.js-view-dom-id-' + views_instance.settings.view_dom_id + ' .views-exposed-form');
         views_instance.$exposed_form.once('exposed-form').each(jQuery.proxy(views_instance.attachExposedFormAjax, views_instance));
 
         // The form values form_id, form_token, and form_build_id will break
@@ -63,9 +62,8 @@
 
               var $row = $(this);
 
-              // Ensure to use input (checkbox) field from entity browser
-              // column dedicated for selection checkbox.
-              var $input = $row.find('.views-field-entity-browser-select input.form-checkbox');
+              // Ensure the use of the entity browser input.
+              var $input = $row.find('.views-field-entity-browser-select input.form-checkbox, .views-field-entity-browser-select input.form-radio');
 
               // Get selection display element and trigger adding of entity
               // over ajax request.
diff --git a/web/modules/entity_browser/modules/entity_form/entity_browser_entity_form.info.yml b/web/modules/entity_browser/modules/entity_form/entity_browser_entity_form.info.yml
index 3cf4ba739e521f4418006fa03dfae64fcfd8a7cc..04c941f7d6b9b4cc2efa2ede06dc73e2c9246318 100644
--- a/web/modules/entity_browser/modules/entity_form/entity_browser_entity_form.info.yml
+++ b/web/modules/entity_browser/modules/entity_form/entity_browser_entity_form.info.yml
@@ -2,13 +2,12 @@ name: Entity Browser IEF
 description: 'Entity browser inline entity form integration.'
 type: module
 package: Media
-# core: 8.x
+core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - entity_browser:entity_browser
   - inline_entity_form:inline_entity_form
 
-# Information added by Drupal.org packaging script on 2017-11-30
-version: '8.x-1.4'
-core: '8.x'
+# Information added by Drupal.org packaging script on 2020-01-20
+version: '8.x-1.10'
 project: 'entity_browser'
-datestamp: 1512033788
+datestamp: 1579563796
diff --git a/web/modules/entity_browser/modules/entity_form/entity_browser_entity_form.module b/web/modules/entity_browser/modules/entity_form/entity_browser_entity_form.module
index 477980f934b821ed6dd76f47c32c32d8b5f7e70f..4d7b8087609e97f55069a06e93db711c09659b59 100644
--- a/web/modules/entity_browser/modules/entity_form/entity_browser_entity_form.module
+++ b/web/modules/entity_browser/modules/entity_form/entity_browser_entity_form.module
@@ -14,6 +14,7 @@
 use Drupal\Component\Utility\NestedArray;
 use Drupal\entity_browser\Element\EntityBrowserElement;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
+use Drupal\inline_entity_form\Plugin\Field\FieldWidget\InlineEntityFormComplex;
 
 /**
  * Implements hook_inline_entity_form_reference_form_alter().
@@ -47,15 +48,25 @@ function entity_browser_entity_form_inline_entity_form_reference_form_alter(&$re
   ]));
 
   $cardinality = FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED;
-  if($instance->getFieldStorageDefinition()->get('cardinality') !== $cardinality) {
+  if ($instance->getFieldStorageDefinition()->get('cardinality') !== $cardinality) {
     $cardinality = $instance->getFieldStorageDefinition()->get('cardinality') - $count_existing_selection;
   }
 
+  $bundles = $reference_form['entity_id']['#selection_settings']['target_bundles'];
+  $target_entity_type = $reference_form['entity_id']['#target_type'];
   unset($reference_form['entity_id']);
   $reference_form['entity_browser'] = [
     '#type' => 'entity_browser',
     '#entity_browser' => $entity_browser_id,
     '#cardinality' => $cardinality,
+    '#entity_browser_validators' => [
+      'entity_type' => ['type' => $target_entity_type],
+    ],
+    '#widget_context' => [
+      'target_bundles' => $bundles,
+      'target_entity_type' => $target_entity_type,
+      'cardinality' => $cardinality,
+    ],
   ];
   $reference_form['#attached']['library'][] = 'entity_browser_entity_form/ief_autocomplete';
   $reference_form['actions']['ief_reference_save']['#ajax']['event'] = 'entities-selected';
@@ -93,8 +104,9 @@ function entity_browser_entity_form_reference_form_validate(array &$reference_fo
   if (!empty($attach_entities)) {
     foreach ($attach_entities as $attach_entity) {
       foreach ($form_state->get(['inline_entity_form', $ief_id, 'entities']) as $key => $value) {
-        if ($value['entity'] == $attach_entity) {
-          $form_state->setError($reference_form, t('The selected @label has already been added.', ['@label' => $labels['singular']]));
+        if ($value['entity']->getEntityTypeId() == $attach_entity->getEntityTypeId() && $value['entity']->id() == $attach_entity->id()) {
+          $form_state->setError($reference_form['entity_browser'], t('The selected @label has already been added.', ['@label' => $labels['singular']]));
+          $reference_form['entity_browser']['entity_ids']['#value'] = '';
         }
       }
     }
@@ -115,7 +127,7 @@ function entity_browser_entity_form_reference_form_validate(array &$reference_fo
  *
  * @see inline_entity_form_reference_form_submit()
  */
-function entity_browser_entity_form_reference_form_submit($reference_form, FormStateInterface $form_state) {
+function entity_browser_entity_form_reference_form_submit(array $reference_form, FormStateInterface $form_state) {
   $ief_id = $reference_form['#ief_id'];
   $form_values = NestedArray::getValue($form_state->getValues(), $reference_form['#parents']);
   $attach_entities = EntityBrowserElement::processEntityIds($form_values['entity_browser']['entity_ids']);
@@ -150,7 +162,7 @@ function entity_browser_entity_form_reference_form_submit($reference_form, FormS
  * Implements hook_field_widget_third_party_settings_form().
  */
 function entity_browser_entity_form_field_widget_third_party_settings_form(WidgetInterface $plugin, FieldDefinitionInterface $field_definition, $form_mode, $form, FormStateInterface $form_state) {
-  if ($plugin->getPluginId() == 'inline_entity_form_complex') {
+  if ($plugin instanceof InlineEntityFormComplex) {
     $entity_browsers = \Drupal::service('entity_type.manager')->getStorage('entity_browser')->loadMultiple();
     if ($entity_browsers) {
       $options = [];
@@ -180,7 +192,7 @@ function entity_browser_entity_form_field_widget_third_party_settings_form(Widge
  */
 function entity_browser_entity_form_field_widget_settings_summary_alter(&$summary, $context) {
   $plugin = $context['widget'];
-  if ($plugin->getPluginId() == 'inline_entity_form_complex' && $plugin->getThirdPartySetting('entity_browser_entity_form', 'entity_browser_id') && $plugin->getThirdPartySetting('entity_browser_entity_form', 'entity_browser_id') !== '_none') {
+  if ($plugin instanceof InlineEntityFormComplex && $plugin->getThirdPartySetting('entity_browser_entity_form', 'entity_browser_id') && $plugin->getThirdPartySetting('entity_browser_entity_form', 'entity_browser_id') !== '_none') {
     $entity_browser_id = $plugin->getThirdPartySetting('entity_browser_entity_form', 'entity_browser_id');
     $entity_browser = \Drupal::service('entity_type.manager')->getStorage('entity_browser')->load($entity_browser_id);
     if ($entity_browser) {
diff --git a/web/modules/entity_browser/modules/entity_form/src/Plugin/EntityBrowser/Widget/EntityForm.php b/web/modules/entity_browser/modules/entity_form/src/Plugin/EntityBrowser/Widget/EntityForm.php
index 6ecfa7561f65d313771f4699fe595212223b0e4a..af08d77d3fd9add628abd3afe0f2c33e61e052fa 100644
--- a/web/modules/entity_browser/modules/entity_form/src/Plugin/EntityBrowser/Widget/EntityForm.php
+++ b/web/modules/entity_browser/modules/entity_form/src/Plugin/EntityBrowser/Widget/EntityForm.php
@@ -16,7 +16,7 @@
 use Drupal\Core\Entity\EntityDisplayRepositoryInterface;
 
 /**
- * Uses a view to provide entity listing in a browser's widget.
+ * Provides entity form widget.
  *
  * @EntityBrowserWidget(
  *   id = "entity_form",
@@ -107,7 +107,7 @@ public function getForm(array &$original_form, FormStateInterface $form_state, a
 
     // Pretend to be IEFs submit button.
     $form['#submit'] = [['Drupal\inline_entity_form\ElementSubmit', 'trigger']];
-    $form['actions']['submit']['#ief_submit_trigger']  = TRUE;
+    $form['actions']['submit']['#ief_submit_trigger'] = TRUE;
     $form['actions']['submit']['#ief_submit_trigger_all'] = TRUE;
 
     $form['inline_entity_form'] = [
@@ -239,4 +239,13 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s
     $this->configuration['form_mode'] = $this->configuration['form_mode']['form_select'];
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function access() {
+    return $this->entityTypeManager
+      ->getAccessControlHandler($this->configuration['entity_type'])
+      ->createAccess($this->configuration['bundle'], NULL, [], TRUE);
+  }
+
 }
diff --git a/web/modules/entity_browser/modules/entity_form/src/Tests/InlineEntityIntegrationTest.php b/web/modules/entity_browser/modules/entity_form/src/Tests/InlineEntityIntegrationTest.php
index 6ae5b79a5e0e9e2136a20f789a1c1a591d6db88c..59e3687ac868ff891d5d9c4a10766ba640c6671a 100644
--- a/web/modules/entity_browser/modules/entity_form/src/Tests/InlineEntityIntegrationTest.php
+++ b/web/modules/entity_browser/modules/entity_form/src/Tests/InlineEntityIntegrationTest.php
@@ -2,14 +2,14 @@
 
 namespace Drupal\entity_browser_entity_form\Tests;
 
-use Drupal\simpletest\WebTestBase;
+use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
 
 /**
  * Tests integration with Inline entity form.
  *
  * @group entity_browser_entity_form
  */
-class InlineEntityIntegrationTest extends WebTestBase {
+class InlineEntityIntegrationTest extends WebDriverTestBase {
 
   /**
    * Modules to enable.
@@ -18,11 +18,17 @@ class InlineEntityIntegrationTest extends WebTestBase {
    */
   public static $modules = [
     'entity_browser_entity_form',
+    'entity_browser_test',
     'node',
     'field_ui',
     'entity_browser_entity_form_test',
   ];
 
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'stark';
+
   /**
    * {@inheritdoc}
    */
@@ -37,40 +43,65 @@ protected function setUp() {
    * Tests integration with Inline entity form.
    */
   public function testInlineEntityIntegration() {
+
+    $this->createNode(['type' => 'article', 'title' => 'Daddy Shark']);
+    $this->createNode(['type' => 'article', 'title' => 'Mommy Shark']);
+    $this->createNode(['type' => 'article', 'title' => 'Baby Shark']);
+
     $account = $this->drupalCreateUser([
       'administer node form display',
       'administer node display',
       'create article content',
+      'access test_entity_browser_iframe_node_view entity browser pages',
     ]);
     $this->drupalLogin($account);
     $this->drupalGet('admin/structure/types/manage/article/form-display');
-    $edit = [
-      'fields[field_content_reference][region]' => 'content',
-      'fields[field_content_reference][type]' => 'inline_entity_form_complex',
-    ];
-    $this->drupalPostForm(NULL, $edit, t('Save'));
-    $this->drupalPostAjaxForm(NULL, [], 'field_content_reference_settings_edit');
-    $this->assertRaw('fields[field_content_reference][settings_edit_form][third_party_settings][entity_browser_entity_form][entity_browser_id]', 'Field to select entity browser is available.');
-    $edit = [
-      'fields[field_content_reference][settings_edit_form][third_party_settings][entity_browser_entity_form][entity_browser_id]' => 'entity_browser_entity_form_test',
-      'fields[field_content_reference][settings_edit_form][settings][allow_existing]' => TRUE,
-    ];
-    $this->drupalPostAjaxForm(NULL, $edit, 'field_content_reference_plugin_settings_update');
-    $this->drupalPostForm(NULL, [], t('Save'));
-    $this->assertText('Entity browser: Entity browser entity form test', 'Settings summary is working correctly.');
-
-    $this->drupalGet('node/add');
-    $elements = $this->xpath('//input[@type="submit" and @value="Add existing node"]');
-    $button_name = $elements[0]->attributes()['name'];
-    $this->drupalPostAjaxForm(NULL, [], $button_name);
-    $this->assertLink('Select entities', 0, 'Entity browser is available.');
-
-    $browsers = $this->container->get('entity_type.manager')->getStorage('entity_browser')->loadMultiple();
-    $browser = current($browsers);
-    $this->container->get('entity_type.manager')->getStorage('entity_browser')->delete([$browser]);
+    $this->assertSession()->buttonExists('Show row weights')->click();
+
+    // Enable field (by default it's in the disabled region).
+    $this->assertSession()
+      ->selectExists('fields[field_content_reference][region]')
+      ->selectOption('content');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    // Switch to using inline_entity_form_complex, so we can test
+    // entity browser alterations to field widget settings form.
+    $this->assertSession()
+      ->selectExists('fields[field_content_reference][type]')
+      ->setValue('inline_entity_form_complex');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    // Open field widget settings form.
+    $this->assertSession()->waitForButton('field_content_reference_settings_edit')->press();
+    $prefix = 'fields[field_content_reference][settings_edit_form]';
+    $this->assertSession()
+      ->waitforField($prefix . '[third_party_settings][entity_browser_entity_form][entity_browser_id]')
+      ->setValue('test_entity_browser_iframe_node_view');
+
+    $this->assertSession()
+      ->fieldExists($prefix . '[settings][allow_existing]')
+      ->check();
+
+    $this->submitForm([], 'Save');
+    $this->assertSession()->responseContains('Test entity browser iframe with view widget for nodes');
+
+    $this->drupalGet('node/add/article');
+    $this->assertSession()->buttonExists('Add existing node')->press();
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->assertSession()->responseContains('Select entities');
+    $this->getSession()->switchToIFrame('entity_browser_iframe_test_entity_browser_iframe_node_view');
+    $this->assertSession()->pageTextContains('Daddy Shark');
+    $this->assertSession()->pageTextContains('Mommy Shark');
+    $this->assertSession()->pageTextContains('Baby Shark');
+
+    $storage = $this->container->get('entity_type.manager')->getStorage('entity_browser');
+    $browsers = $storage->loadMultiple();
+    $storage->delete($browsers);
     $this->drupalGet('admin/structure/types/manage/article/form-display');
-    $this->drupalPostAjaxForm(NULL, [], 'field_content_reference_settings_edit');
-    $this->assertText(t('There are no entity browsers available. You can create one here'), 'Massage displays when no entity browser is available.');
+    $this->assertSession()->buttonExists('field_content_reference_settings_edit')->press();
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->assertSession()->pageTextContains('There are no entity browsers available. You can create one here');
+
   }
 
 }
diff --git a/web/modules/entity_browser/modules/entity_form/tests/modules/entity_browser_entity_form_test/config/install/field.field.node.article.field_content_reference.yml b/web/modules/entity_browser/modules/entity_form/tests/modules/entity_browser_entity_form_test/config/install/field.field.node.article.field_content_reference.yml
index 61426438a7354bcf7f0d8e115b4db3c5631dfef9..044eef3272f9d51981cd497f605615d9eefe6a2d 100644
--- a/web/modules/entity_browser/modules/entity_form/tests/modules/entity_browser_entity_form_test/config/install/field.field.node.article.field_content_reference.yml
+++ b/web/modules/entity_browser/modules/entity_form/tests/modules/entity_browser_entity_form_test/config/install/field.field.node.article.field_content_reference.yml
@@ -1,6 +1,8 @@
 langcode: en
 status: true
 dependencies:
+  module:
+    - entity_browser_test
   config:
     - field.storage.node.field_content_reference
     - node.type.article
diff --git a/web/modules/entity_browser/modules/entity_form/tests/modules/entity_browser_entity_form_test/config/install/node.type.article.yml b/web/modules/entity_browser/modules/entity_form/tests/modules/entity_browser_entity_form_test/config/install/node.type.article.yml
deleted file mode 100644
index 1fd439ce71bf22657ff5b7e15805eb6f9b93ae05..0000000000000000000000000000000000000000
--- a/web/modules/entity_browser/modules/entity_form/tests/modules/entity_browser_entity_form_test/config/install/node.type.article.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-langcode: en
-status: true
-dependencies: {  }
-name: Article
-type: article
-description: 'Use <em>articles</em> for time-sensitive content like news, press releases or blog posts.'
-help: ''
-new_revision: true
-preview_mode: 1
-display_submitted: true
diff --git a/web/modules/entity_browser/modules/entity_form/tests/modules/entity_browser_entity_form_test/entity_browser_entity_form_test.info.yml b/web/modules/entity_browser/modules/entity_form/tests/modules/entity_browser_entity_form_test/entity_browser_entity_form_test.info.yml
index b8919bf9f228dbe6cf3c901f2939ed176b3ec7a6..1ab7ad9c68b471d9eb2327f59b8856fa578a958e 100644
--- a/web/modules/entity_browser/modules/entity_form/tests/modules/entity_browser_entity_form_test/entity_browser_entity_form_test.info.yml
+++ b/web/modules/entity_browser/modules/entity_form/tests/modules/entity_browser_entity_form_test/entity_browser_entity_form_test.info.yml
@@ -1,15 +1,14 @@
 name: 'Entity browser entity form test'
 type: module
 description: 'Support module for the Entity browser entity form module tests.'
-# core: 8.x
+core_version_requirement: ^8.7.7 || ^9
 package: Testing
-# version: VERSION
 dependencies:
-  - entity_browser_entity_form
-  - views
+  - entity_browser_entity_form:entity_browser_entity_form
+  - entity_browser_test:entity_browser_test
+  - drupal:views
 
-# Information added by Drupal.org packaging script on 2017-11-30
-version: '8.x-1.4'
-core: '8.x'
+# Information added by Drupal.org packaging script on 2020-01-20
+version: '8.x-1.10'
 project: 'entity_browser'
-datestamp: 1512033788
+datestamp: 1579563796
diff --git a/web/modules/entity_browser/modules/entity_form/tests/src/FunctionalJavascript/EntityFormWidgetTest.php b/web/modules/entity_browser/modules/entity_form/tests/src/FunctionalJavascript/EntityFormWidgetTest.php
index aef8ebb349152a68f38eca7fdd651411fd957520..80269bba002223c97a8d1d47f1210f924672eafb 100644
--- a/web/modules/entity_browser/modules/entity_form/tests/src/FunctionalJavascript/EntityFormWidgetTest.php
+++ b/web/modules/entity_browser/modules/entity_form/tests/src/FunctionalJavascript/EntityFormWidgetTest.php
@@ -5,14 +5,14 @@
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
-use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
+use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
 
 /**
  * Class for Entity browser entity form Javascript functional tests.
  *
  * @group entity_browser_entity_form
  */
-class EntityFormWidgetTest extends JavascriptTestBase {
+class EntityFormWidgetTest extends WebDriverTestBase {
 
   /**
    * Modules to enable.
@@ -21,7 +21,6 @@ class EntityFormWidgetTest extends JavascriptTestBase {
    */
   public static $modules = [
     'entity_browser_entity_form_test',
-    'ctools',
     'views',
     'block',
     'node',
@@ -32,6 +31,11 @@ class EntityFormWidgetTest extends JavascriptTestBase {
     'system',
   ];
 
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'stark';
+
   /**
    * {@inheritdoc}
    */
@@ -75,6 +79,7 @@ protected function setUp() {
     $account = $this->drupalCreateUser([
       'access entity_browser_test_entity_form entity browser pages',
       'create foo content',
+      'create article content',
       'access content',
     ]);
     $this->drupalLogin($account);
@@ -102,12 +107,12 @@ public function testEntityForm() {
     $this->assertSession()->buttonNotExists('Save entity');
     $this->assertSession()->buttonExists('Save node');
 
-    // Make sure that the widget works correctly with the field widget
+    // Make sure that the widget works correctly with the field widget.
     $this->drupalGet('node/add/foo');
     $this->getSession()->getPage()->clickLink('Select entities');
     $this->getSession()->switchToIFrame('entity_browser_iframe_entity_browser_test_entity_form');
     $this->getSession()->getPage()->fillField('inline_entity_form[title][0][value]', 'War is peace');
-    $this->getSession()->getPage()->pressButton('Save node');
+    $this->assertSession()->buttonExists('Save node')->press();
 
     // Switch back to the main page.
     $this->getSession()->switchToIFrame();
@@ -115,7 +120,7 @@ public function testEntityForm() {
 
     $this->assertSession()->pageTextContains('War is peace');
     $this->getSession()->getPage()->fillField('title[0][value]', 'Freedom is slavery');
-    $this->getSession()->getPage()->pressButton('Save');
+    $this->assertSession()->buttonExists('Save')->press();
 
     $parent_node = $this->container->get('entity_type.manager')
       ->getStorage('node')
@@ -131,8 +136,8 @@ public function testEntityForm() {
     $this->getSession()->getPage()->clickLink('Select entities');
     $this->getSession()->switchToIFrame('entity_browser_iframe_entity_browser_test_entity_form');
     $this->getSession()->getPage()->fillField('inline_entity_form[title][0][value]', 'War is peace');
-    $this->getSession()->getPage()->pressButton('Save node');
-    $this->getSession()->getPage()->pressButton('Use selected');
+    $this->assertSession()->buttonExists('Save node')->press();
+    $this->assertSession()->buttonExists('Use selected')->press();
 
     // Switch back to the main page.
     $this->getSession()->switchToIFrame();
@@ -140,7 +145,7 @@ public function testEntityForm() {
 
     $this->assertSession()->pageTextContains('War is peace');
     $this->getSession()->getPage()->fillField('title[0][value]', 'Ignorance is strength');
-    $this->getSession()->getPage()->pressButton('Save');
+    $this->assertSession()->buttonExists('Save')->press();
 
     $parent_node = $this->container->get('entity_type.manager')
       ->getStorage('node')
@@ -148,6 +153,16 @@ public function testEntityForm() {
     $parent_node = current($parent_node);
     $this->assertEquals(1, $parent_node->get('field_reference')->count(), 'There is one child node.');
     $this->assertEquals('War is peace', $parent_node->field_reference->entity->label(), 'Child node has correct title.');
+
+    // Make sure entity create access is respected.
+    $account = $this->drupalCreateUser([
+      'access entity_browser_test_entity_form entity browser pages',
+      'create foo content',
+      'access content',
+    ]);
+    $this->drupalLogin($account);
+    $this->drupalGet('entity-browser/iframe/entity_browser_test_entity_form');
+    $this->assertSession()->pageTextContains('No widgets are available.');
   }
 
 }
diff --git a/web/modules/entity_browser/modules/example/config/install/core.entity_form_display.node.entity_browser_test.default.yml b/web/modules/entity_browser/modules/example/config/install/core.entity_form_display.node.entity_browser_test.default.yml
index de7d83cbc7d83d61322d0a24f60c55667253719a..0bf7b37fd88b60ea00f03c83edaf114920a3668b 100644
--- a/web/modules/entity_browser/modules/example/config/install/core.entity_form_display.node.entity_browser_test.default.yml
+++ b/web/modules/entity_browser/modules/example/config/install/core.entity_form_display.node.entity_browser_test.default.yml
@@ -44,6 +44,7 @@ content:
       open: false
       field_widget_edit: true
       field_widget_remove: true
+      field_widget_replace: false
     third_party_settings: {  }
   field_files1:
     type: entity_browser_entity_reference
@@ -55,6 +56,7 @@ content:
       open: false
       field_widget_edit: true
       field_widget_remove: true
+      field_widget_replace: false
     third_party_settings: {  }
   field_files_over_ajax:
     weight: 36
@@ -63,6 +65,7 @@ content:
       field_widget_display: label
       field_widget_edit: true
       field_widget_remove: true
+      field_widget_replace: false
       selection_mode: selection_edit
       open: false
       field_widget_display_settings: {  }
@@ -74,6 +77,7 @@ content:
       entity_browser: test_files
       field_widget_edit: true
       field_widget_remove: true
+      field_widget_replace: false
       open: false
     third_party_settings: {  }
     type: entity_browser_file
@@ -87,6 +91,7 @@ content:
       open: false
       field_widget_edit: true
       field_widget_remove: true
+      field_widget_replace: false
     third_party_settings: {  }
   path:
     type: path
diff --git a/web/modules/entity_browser/modules/example/config/install/views.view.files_entity_browser.yml b/web/modules/entity_browser/modules/example/config/install/views.view.files_entity_browser.yml
index ece197ab486eaa2bb249093cfad17867b4b41efd..7ba408c67ebeb4dfb7a3aaaf505d1e659a70614e 100644
--- a/web/modules/entity_browser/modules/example/config/install/views.view.files_entity_browser.yml
+++ b/web/modules/entity_browser/modules/example/config/install/views.view.files_entity_browser.yml
@@ -181,6 +181,7 @@ display:
           hide_alter_empty: true
           entity_type: file
           plugin_id: entity_browser_select
+          use_field_cardinality: false
         filename:
           id: filename
           table: file_managed
diff --git a/web/modules/entity_browser/modules/example/config/install/views.view.nodes_entity_browser.yml b/web/modules/entity_browser/modules/example/config/install/views.view.nodes_entity_browser.yml
index 0b2ed9204c03207305e297d5bdd1af042e5415f2..65a4213135f707ae7f85dcb0218320ea7d507dd3 100644
--- a/web/modules/entity_browser/modules/example/config/install/views.view.nodes_entity_browser.yml
+++ b/web/modules/entity_browser/modules/example/config/install/views.view.nodes_entity_browser.yml
@@ -471,4 +471,4 @@ display:
         - user.permissions
       cacheable: false
       max-age: 0
-      tags: {  }
\ No newline at end of file
+      tags: {  }
diff --git a/web/modules/entity_browser/modules/example/entity_browser_example.info.yml b/web/modules/entity_browser/modules/example/entity_browser_example.info.yml
index efc31b4f54617cfe98d195eee64d37a7d54a688b..9f79978b3e4480b56f201dc92b6d94046813255d 100644
--- a/web/modules/entity_browser/modules/example/entity_browser_example.info.yml
+++ b/web/modules/entity_browser/modules/example/entity_browser_example.info.yml
@@ -2,7 +2,7 @@ name: Entity Browser example
 description: 'Entity browser example module.'
 type: module
 package: Media
-# core: 8.x
+core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - entity_browser:entity_browser
   - drupal:views
@@ -11,8 +11,7 @@ dependencies:
   - drupal:node
   - drupal:image
 
-# Information added by Drupal.org packaging script on 2017-11-30
-version: '8.x-1.4'
-core: '8.x'
+# Information added by Drupal.org packaging script on 2020-01-20
+version: '8.x-1.10'
 project: 'entity_browser'
-datestamp: 1512033788
+datestamp: 1579563796
diff --git a/web/modules/entity_browser/modules/example/tests/src/FunctionalJavascript/EntityBrowserExampleTest.php b/web/modules/entity_browser/modules/example/tests/src/FunctionalJavascript/EntityBrowserExampleTest.php
index da7f2bd001d3667c550d6e852d89d83dee0d9fd4..b415c2d8eec594f3bdb50e8f901338b520a8a1b0 100644
--- a/web/modules/entity_browser/modules/example/tests/src/FunctionalJavascript/EntityBrowserExampleTest.php
+++ b/web/modules/entity_browser/modules/example/tests/src/FunctionalJavascript/EntityBrowserExampleTest.php
@@ -18,6 +18,11 @@ class EntityBrowserExampleTest extends BrowserTestBase {
    */
   public static $modules = ['entity_browser_example'];
 
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'stark';
+
   /**
    * Tests Entity Browser example module.
    */
diff --git a/web/modules/entity_browser/src/Annotation/EntityBrowserDisplay.php b/web/modules/entity_browser/src/Annotation/EntityBrowserDisplay.php
index f7c853c4b13454fb539939e644dd932c79d1c0f5..15e13850051b0bba0e7d1af35089a30c57045c2c 100644
--- a/web/modules/entity_browser/src/Annotation/EntityBrowserDisplay.php
+++ b/web/modules/entity_browser/src/Annotation/EntityBrowserDisplay.php
@@ -23,9 +23,9 @@ class EntityBrowserDisplay extends Plugin {
   /**
    * The human-readable name of the display.
    *
-   * @ingroup plugin_translatable
-   *
    * @var \Drupal\Core\Annotation\Translation
+   *
+   * @ingroup plugin_translatable
    */
   public $label;
 
@@ -34,9 +34,9 @@ class EntityBrowserDisplay extends Plugin {
    *
    * This will be shown when adding or configuring this display.
    *
-   * @ingroup plugin_translatable
+   * @var \Drupal\Core\Annotation\Translation
    *
-   * @var \Drupal\Core\Annotation\Translation (optional)
+   * @ingroup plugin_translatable
    */
   public $description = '';
 
diff --git a/web/modules/entity_browser/src/Annotation/EntityBrowserFieldWidgetDisplay.php b/web/modules/entity_browser/src/Annotation/EntityBrowserFieldWidgetDisplay.php
index 435ad9b7ea681d06689b841aa8882c0de38308f4..2d439b0446d1770d5dede2de5cc1704cc4350f89 100644
--- a/web/modules/entity_browser/src/Annotation/EntityBrowserFieldWidgetDisplay.php
+++ b/web/modules/entity_browser/src/Annotation/EntityBrowserFieldWidgetDisplay.php
@@ -23,9 +23,9 @@ class EntityBrowserFieldWidgetDisplay extends Plugin {
   /**
    * The human-readable name of the field widget display display.
    *
-   * @ingroup plugin_translatable
-   *
    * @var \Drupal\Core\Annotation\Translation
+   *
+   * @ingroup plugin_translatable
    */
   public $label;
 
@@ -34,9 +34,9 @@ class EntityBrowserFieldWidgetDisplay extends Plugin {
    *
    * This will be shown when adding or configuring this display.
    *
-   * @ingroup plugin_translatable
+   * @var \Drupal\Core\Annotation\Translation
    *
-   * @var \Drupal\Core\Annotation\Translation (optional)
+   * @ingroup plugin_translatable
    */
   public $description = '';
 
diff --git a/web/modules/entity_browser/src/Annotation/EntityBrowserSelectionDisplay.php b/web/modules/entity_browser/src/Annotation/EntityBrowserSelectionDisplay.php
index fe54f953b930f0d31b41a74f271c138ec7667874..854cc64fc6cc6db57cae6aa0c5f169e53ffaab49 100644
--- a/web/modules/entity_browser/src/Annotation/EntityBrowserSelectionDisplay.php
+++ b/web/modules/entity_browser/src/Annotation/EntityBrowserSelectionDisplay.php
@@ -23,9 +23,9 @@ class EntityBrowserSelectionDisplay extends Plugin {
   /**
    * The human-readable name of the selection display.
    *
-   * @ingroup plugin_translatable
-   *
    * @var \Drupal\Core\Annotation\Translation
+   *
+   * @ingroup plugin_translatable
    */
   public $label;
 
@@ -34,9 +34,9 @@ class EntityBrowserSelectionDisplay extends Plugin {
    *
    * This will be shown when adding or configuring this selection display.
    *
-   * @ingroup plugin_translatable
+   * @var \Drupal\Core\Annotation\Translation
    *
-   * @var \Drupal\Core\Annotation\Translation (optional)
+   * @ingroup plugin_translatable
    */
   public $description = '';
 
diff --git a/web/modules/entity_browser/src/Annotation/EntityBrowserWidget.php b/web/modules/entity_browser/src/Annotation/EntityBrowserWidget.php
index 22a059ad6af16d847d4c03b2f524d399bb136d88..50dbccf475960f549db2f3f8b16d54b33dee7c8d 100644
--- a/web/modules/entity_browser/src/Annotation/EntityBrowserWidget.php
+++ b/web/modules/entity_browser/src/Annotation/EntityBrowserWidget.php
@@ -23,9 +23,9 @@ class EntityBrowserWidget extends Plugin {
   /**
    * The human-readable name of the widget.
    *
-   * @ingroup plugin_translatable
-   *
    * @var \Drupal\Core\Annotation\Translation
+   *
+   * @ingroup plugin_translatable
    */
   public $label;
 
@@ -34,9 +34,9 @@ class EntityBrowserWidget extends Plugin {
    *
    * This will be shown when adding or configuring this widget.
    *
-   * @ingroup plugin_translatable
+   * @var \Drupal\Core\Annotation\Translation
    *
-   * @var \Drupal\Core\Annotation\Translation (optional)
+   * @ingroup plugin_translatable
    */
   public $description = '';
 
diff --git a/web/modules/entity_browser/src/Annotation/EntityBrowserWidgetSelector.php b/web/modules/entity_browser/src/Annotation/EntityBrowserWidgetSelector.php
index a10ef84cbd208666efa78199e4e0c7e4e73e6883..a68d9539a452e2b01b60ad6db19d3f8463c729ce 100644
--- a/web/modules/entity_browser/src/Annotation/EntityBrowserWidgetSelector.php
+++ b/web/modules/entity_browser/src/Annotation/EntityBrowserWidgetSelector.php
@@ -23,9 +23,9 @@ class EntityBrowserWidgetSelector extends Plugin {
   /**
    * The human-readable name of the widget selector.
    *
-   * @ingroup plugin_translatable
-   *
    * @var \Drupal\Core\Annotation\Translation
+   *
+   * @ingroup plugin_translatable
    */
   public $label;
 
@@ -34,9 +34,9 @@ class EntityBrowserWidgetSelector extends Plugin {
    *
    * This will be shown when adding or configuring this widget selector.
    *
-   * @ingroup plugin_translatable
+   * @var \Drupal\Core\Annotation\Translation
    *
-   * @var \Drupal\Core\Annotation\Translation (optional)
+   * @ingroup plugin_translatable
    */
   public $description = '';
 
diff --git a/web/modules/entity_browser/src/Annotation/EntityBrowserWidgetValidation.php b/web/modules/entity_browser/src/Annotation/EntityBrowserWidgetValidation.php
index 065b2959c6fe0475fddb02b24ac32e6ba53ea3b9..41afe911029f47c34d7c97cb52b68992fb53a883 100644
--- a/web/modules/entity_browser/src/Annotation/EntityBrowserWidgetValidation.php
+++ b/web/modules/entity_browser/src/Annotation/EntityBrowserWidgetValidation.php
@@ -23,23 +23,24 @@ class EntityBrowserWidgetValidation extends Plugin {
   /**
    * The human-readable name of the widget validator.
    *
-   * @ingroup plugin_translatable
-   *
    * @var \Drupal\Core\Annotation\Translation
+   *
+   * @ingroup plugin_translatable
    */
   public $label;
 
   /**
-   * (Optional) The data type plugin ID, for which a constraint should be added.
+   * The data type plugin ID, for which a constraint should be added (Optional).
    *
    * @var string
    */
   public $data_type;
 
   /**
-   * (Optional) The constraint ID.
+   * The constraint ID (Optional).
    *
    * @var string
    */
   public $constraint;
+
 }
diff --git a/web/modules/entity_browser/src/Controllers/CtoolsFallback.php b/web/modules/entity_browser/src/Controllers/CtoolsFallback.php
deleted file mode 100644
index b85cd3745b8fc9f710c38e4a75061967b48a62f7..0000000000000000000000000000000000000000
--- a/web/modules/entity_browser/src/Controllers/CtoolsFallback.php
+++ /dev/null
@@ -1,29 +0,0 @@
-<?php
-
-namespace Drupal\entity_browser\Controllers;
-
-use Drupal\Core\Controller\ControllerBase;
-use Drupal\Core\Url;
-
-/**
- * Returns markup for entity browser entity add/edit page if ctools is missing.
- */
-class CtoolsFallback extends ControllerBase {
-
-  /**
-   * Displays message about missing dependency on edit/add page.
-   *
-   * @return \Drupal\Core\Ajax\AjaxResponse
-   *   An Ajax response with a command for opening or closing the dialog
-   *   containing the edit form.
-   */
-  public function displayMessage() {
-    return [
-      '#markup' => $this->t(
-        'This form depends on <a href=":url">Chaos tool suite module</a>. Enable it and reload this page.',
-        [':url' => Url::fromUri('https://drupal.org/project/ctools')->toString()]
-      ),
-    ];
-  }
-
-}
diff --git a/web/modules/entity_browser/src/Controllers/EntityBrowserController.php b/web/modules/entity_browser/src/Controllers/EntityBrowserController.php
index aebb4be8060a5e9c0441aed6b862f3d9bb270239..9ecf6eb9a26b8757dd454807c76b7a582bc66a85 100644
--- a/web/modules/entity_browser/src/Controllers/EntityBrowserController.php
+++ b/web/modules/entity_browser/src/Controllers/EntityBrowserController.php
@@ -10,6 +10,8 @@
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\entity_browser\Ajax\ValueUpdatedCommand;
 use Symfony\Component\HttpFoundation\Request;
+use Drupal\Core\Ajax\AlertCommand;
+use Symfony\Component\HttpFoundation\ParameterBag;
 
 /**
  * Returns responses for entity browser routes.
@@ -29,17 +31,46 @@ class EntityBrowserController extends ControllerBase {
    *   containing the edit form.
    */
   public function entityBrowserEdit(EntityInterface $entity, Request $request) {
-    // Build the entity edit form.
-    $form_object = $this->entityTypeManager()->getFormObject($entity->getEntityTypeId(), 'edit');
-    $form_object->setEntity($entity);
-    $form_state = (new FormState())
-      ->setFormObject($form_object)
-      ->disableRedirect();
-    // Building the form also submits.
-    $form = $this->formBuilder()->buildForm($form_object, $form_state);
+
+    $trigger_name = $request->request->get('_triggering_element_name');
+    $edit_button = (strpos($trigger_name, 'edit_button') !== FALSE);
+
+    if ($edit_button) {
+      // Remove posted values from original form to prevent
+      // data leakage into this form when the form is of the same bundle.
+      $original_request = $request->request;
+      $request->request = new ParameterBag();
+    }
+
+    // Use edit form class if it exists, otherwise use default form class.
+    $entity_type = $entity->getEntityType();
+    if ($entity_type->getFormClass('edit')) {
+      $operation = 'edit';
+    }
+    elseif ($entity_type->getFormClass('default')) {
+      $operation = 'default';
+    }
+
+    if (!empty($operation)) {
+      // Build the entity edit form.
+      $form_object = $this->entityTypeManager()->getFormObject($entity->getEntityTypeId(), $operation);
+      $form_object->setEntity($entity);
+      $form_state = (new FormState())
+        ->setFormObject($form_object)
+        ->disableRedirect();
+      // Building the form also submits.
+      $form = $this->formBuilder()->buildForm($form_object, $form_state);
+    }
+
+    // Restore original request now that the edit form is built.
+    // This fixes a bug where closing modal and re-opening it would
+    // cause two modals to open.
+    if ($edit_button) {
+      $request->request = $original_request;
+    }
 
     // Return a response, depending on whether it's successfully submitted.
-    if (!$form_state->isExecuted()) {
+    if ($operation && $form_state && !$form_state->isExecuted()) {
       // Return the form as a modal dialog.
       $form['#attached']['library'][] = 'core/drupal.dialog.ajax';
       $title = $this->t('Edit entity @entity', ['@entity' => $entity->label()]);
@@ -53,7 +84,12 @@ public function entityBrowserEdit(EntityInterface $entity, Request $request) {
       $details_id = $request->query->get('details_id');
       if (!empty($details_id)) {
         $response->addCommand(new ValueUpdatedCommand($details_id));
+
+        if (empty($operation)) {
+          $response->addCommand(new AlertCommand($this->t("An edit form couldn't be found.")));
+        }
       }
+
       return $response;
     }
   }
diff --git a/web/modules/entity_browser/src/Controllers/EntityBrowserFormController.php b/web/modules/entity_browser/src/Controllers/EntityBrowserFormController.php
index 41620319e59b8d1ff9c9c9ecd98f850cf055ed1c..0a644c4078292baad99efd94077c890c15b03490 100644
--- a/web/modules/entity_browser/src/Controllers/EntityBrowserFormController.php
+++ b/web/modules/entity_browser/src/Controllers/EntityBrowserFormController.php
@@ -3,7 +3,6 @@
 namespace Drupal\entity_browser\Controllers;
 
 use Drupal\Component\Utility\Xss;
-use Drupal\Core\Controller\ControllerResolverInterface;
 use Drupal\Core\Controller\HtmlFormController;
 use Drupal\Core\DependencyInjection\ClassResolverInterface;
 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
@@ -12,6 +11,7 @@
 use Drupal\Core\Routing\RouteMatchInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface;
 
 /**
  * Standalone entity browser page.
@@ -42,21 +42,21 @@ class EntityBrowserFormController extends HtmlFormController implements Containe
   /**
    * Constructs Entity browser form controller.
    *
-   * @param \Drupal\Core\Controller\ControllerResolverInterface $controller_resolver
-   *   The controller resolver.
+   * @param \Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface $argument_resolver
+   *   The argument resolver.
    * @param \Drupal\Core\Form\FormBuilderInterface $form_builder
    *   The form builder.
    * @param \Drupal\Core\DependencyInjection\ClassResolverInterface $class_resolver
    *   The class resolver.
-   * @param RouteMatchInterface $route_match
+   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
    *   Current route match service.
    * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
    *   Entity type manager service.
    * @param \Symfony\Component\HttpFoundation\Request $request
    *   Current request.
    */
-  public function __construct(ControllerResolverInterface $controller_resolver, FormBuilderInterface $form_builder, ClassResolverInterface $class_resolver, RouteMatchInterface $route_match, EntityTypeManagerInterface $entity_type_manager, Request $request) {
-    parent::__construct($controller_resolver, $form_builder, $class_resolver);
+  public function __construct(ArgumentResolverInterface $argument_resolver, FormBuilderInterface $form_builder, ClassResolverInterface $class_resolver, RouteMatchInterface $route_match, EntityTypeManagerInterface $entity_type_manager, Request $request) {
+    parent::__construct($argument_resolver, $form_builder, $class_resolver);
     $this->currentRouteMatch = $route_match;
     $this->browserStorage = $entity_type_manager->getStorage('entity_browser');
     $this->request = $request;
@@ -68,11 +68,11 @@ public function __construct(ControllerResolverInterface $controller_resolver, Fo
    */
   public static function create(ContainerInterface $container) {
     return new static(
-      $container->get('controller_resolver'),
+      $container->get('http_kernel.controller.argument_resolver'),
       $container->get('form_builder'),
       $container->get('class_resolver'),
       $container->get('current_route_match'),
-      $container->get('entity.manager'),
+      $container->get('entity_type.manager'),
       $container->get('request_stack')->getCurrentRequest()
     );
   }
@@ -104,9 +104,9 @@ public function title() {
    *   Loads the entity browser object
    */
   protected function loadBrowser() {
-    /** @var $route \Symfony\Component\Routing\Route */
+    /* @var $route \Symfony\Component\Routing\Route */
     $route = $this->currentRouteMatch->getRouteObject();
-    /** @var $browser \Drupal\entity_browser\EntityBrowserInterface */
+    /* @var $browser \Drupal\entity_browser\EntityBrowserInterface */
     return $this->browserStorage->load($route->getDefault('entity_browser_id'));
   }
 
diff --git a/web/modules/entity_browser/src/Controllers/EntityBrowserListBuilder.php b/web/modules/entity_browser/src/Controllers/EntityBrowserListBuilder.php
index a6d5535ed277c91d02d89099dc5c9ebc00a3e4d4..e7762a154e518f68b371f08dfd57bc5fa66a97f1 100644
--- a/web/modules/entity_browser/src/Controllers/EntityBrowserListBuilder.php
+++ b/web/modules/entity_browser/src/Controllers/EntityBrowserListBuilder.php
@@ -40,14 +40,26 @@ public function buildRow(EntityInterface $entity) {
    * {@inheritdoc}
    */
   protected function getDefaultOperations(EntityInterface $entity) {
-    $operations = parent::getDefaultOperations($entity);
 
-    // Destination parameter messes up with the entity form wizard redirects.
-    $options = $operations['edit']['url']->getOptions();
-    if (!empty($options['query']['destination'])) {
-      unset($options['query']['destination']);
+    if ($entity->access('update')) {
+      $operations['edit'] = [
+        'title' => $this->t('Edit'),
+        'url' => $entity->toUrl('edit-form'),
+      ];
+    }
+
+    $operations['edit-widgets'] = [
+      'title' => $this->t('Edit Widgets'),
+      'url' => $entity->toUrl('edit-widgets'),
+    ];
+
+    if ($entity->access('delete')) {
+      $operations['delete'] = [
+        'title' => $this->t('Delete'),
+        'url' => $entity->toUrl('delete-form'),
+        'weight' => 100,
+      ];
     }
-    $operations['edit']['url']->setOptions($options);
 
     return $operations;
   }
diff --git a/web/modules/entity_browser/src/DisplayInterface.php b/web/modules/entity_browser/src/DisplayInterface.php
index 4d9fbf2cbe7e779bcc35eb34ae418ad978582e46..1ffd6ebff26e208bfd2af836dd5e2ea926542187 100644
--- a/web/modules/entity_browser/src/DisplayInterface.php
+++ b/web/modules/entity_browser/src/DisplayInterface.php
@@ -2,7 +2,8 @@
 
 namespace Drupal\entity_browser;
 
-use Drupal\Component\Plugin\ConfigurablePluginInterface;
+use Drupal\Component\Plugin\ConfigurableInterface;
+use Drupal\Component\Plugin\DependentPluginInterface;
 use Drupal\Component\Plugin\PluginInspectionInterface;
 use Drupal\Core\Plugin\PluginFormInterface;
 use Drupal\Core\Form\FormStateInterface;
@@ -17,7 +18,7 @@
  * - Displaying the entity browser in an iframe.
  * - Displaying the entity browser in a modal dialog box.
  */
-interface DisplayInterface extends PluginInspectionInterface, ConfigurablePluginInterface, PluginFormInterface {
+interface DisplayInterface extends PluginInspectionInterface, ConfigurableInterface, PluginFormInterface, DependentPluginInterface {
 
   /**
    * Returns the display label.
@@ -47,15 +48,15 @@ public function label();
    *   is needed as the widget may display after a new bootstrap, which would
    *   discard the current form state. Arbitrary values can be added and used
    *   by widgets, if needed.
-   *   Expected array keys:
-   *     @type \Drupal\Core\Entity\EntityInterface[] $selected_entities
-   *       An array of currently selected entities.
-   *     @type array $validators
-   *       An associative array mapping EntityBrowserWidgetValidation IDs to
-   *       an array of options to pass to the plugin's validate method.
+   *   The expected array keys are "selected_entities" and "validators".
+   *     - Drupal\Core\Entity\EntityInterface[] selected_entities
+   *        An array of currently selected entities.
+   *     - array validators
+   *        An associative array mapping EntityBrowserWidgetValidation IDs to
+   *        an array of options to pass to the plugin's validate method.
    *
    * @return array
-   *   An array suitable for drupal_render().
+   *   A render array.
    */
   public function displayEntityBrowser(array $element, FormStateInterface $form_state, array &$complete_form, array $persistent_data = []);
 
diff --git a/web/modules/entity_browser/src/Element/EntityBrowserElement.php b/web/modules/entity_browser/src/Element/EntityBrowserElement.php
index 4dccdc5d9a8099da9bcf3d630e22b033f453f0e6..4808eb24a4c7407c133137ffa2138001ac26b2d2 100644
--- a/web/modules/entity_browser/src/Element/EntityBrowserElement.php
+++ b/web/modules/entity_browser/src/Element/EntityBrowserElement.php
@@ -7,6 +7,7 @@
 use Drupal\Core\Render\Element\FormElement;
 use Drupal\entity_browser\Entity\EntityBrowser;
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\Component\Utility\NestedArray;
 
 /**
  * Provides an Entity Browser form element.
@@ -148,9 +149,18 @@ public static function processEntityBrowser(&$element, FormStateInterface $form_
     // Propagate selection if edit selection mode is used.
     $entity_browser_preselected_entities = [];
     if ($element['#selection_mode'] === static::SELECTION_MODE_EDIT) {
-      $entity_browser->getSelectionDisplay()->checkPreselectionSupport();
-
-      $entity_browser_preselected_entities = $element['#default_value'];
+      if ($entity_browser->getSelectionDisplay()->supportsPreselection()) {
+        $entity_browser_preselected_entities = $element['#default_value'];
+      }
+      else {
+        $field_element = NestedArray::getValue($complete_form, array_slice($element['#array_parents'], 0, -1));
+        $tparams = [
+          '@field_name' => !empty($field_element['#title']) ? $field_element['#title'] : $element['#custom_hidden_id'],
+          '%selection_mode' => static::getSelectionModeOptions()[static::SELECTION_MODE_EDIT],
+          '@browser_link' => $entity_browser->toLink($entity_browser->label(), 'edit-form')->toString(),
+        ];
+        \Drupal::messenger()->addWarning(t('There is a configuration problem with field "@field_name". The selection mode %selection_mode requires an entity browser with a selection display plugin that supports preselection.  Either change the selection mode or update the @browser_link entity browser to use a selection display plugin that supports preselection.', $tparams));
+      }
     }
 
     $default_value = implode(' ', array_map(
@@ -171,7 +181,7 @@ function (EntityInterface $item) {
         '#markup' => is_string($element['#entity_browser']) ? t('Entity browser @browser not found.', ['@browser' => $element['#entity_browser']]) : t('Entity browser not found.'),
       ];
     }
-    // Display entity_browser
+    // Display entity_browser.
     else {
       $display = $entity_browser->getDisplay();
       $display->setUuid(sha1(implode('-', array_merge([$complete_form['#build_id']], $element['#parents']))));
@@ -245,7 +255,8 @@ public static function processEntityIds($ids) {
     return array_map(
       function ($item) {
         list($entity_type, $entity_id) = explode(':', $item);
-        return \Drupal::entityTypeManager()->getStorage($entity_type)->load($entity_id);
+        $entity = \Drupal::entityTypeManager()->getStorage($entity_type)->load($entity_id);
+        return \Drupal::service('entity.repository')->getTranslationFromContext($entity);
       },
       $ids
     );
diff --git a/web/modules/entity_browser/src/Element/EntityBrowserPagerElement.php b/web/modules/entity_browser/src/Element/EntityBrowserPagerElement.php
index e85730a58dc37f2646119fb42d0ab29ab5975780..c20b38ebc1c9a77b0de1856a2aa6498c1e071160 100644
--- a/web/modules/entity_browser/src/Element/EntityBrowserPagerElement.php
+++ b/web/modules/entity_browser/src/Element/EntityBrowserPagerElement.php
@@ -87,10 +87,12 @@ public static function processEntityBrowserPager(&$element, FormStateInterface $
   /**
    * Submit handler for next and previous buttons.
    *
+   * @param array $form
+   *   The form.
    * @param \Drupal\Core\Form\FormStateInterface $form_state
    *   Form state.
    */
-  public static function submitPager($form, FormStateInterface $form_state) {
+  public static function submitPager(array $form, FormStateInterface $form_state) {
     $page = static::getCurrentPage($form_state);
 
     $triggering_element = $form_state->getTriggeringElement();
@@ -130,4 +132,5 @@ public static function getCurrentPage(FormStateInterface $form_state) {
   public static function setCurrentPage(FormStateInterface $form_state, $page = 1) {
     $form_state->set('page', $page);
   }
+
 }
diff --git a/web/modules/entity_browser/src/Entity/EntityBrowser.php b/web/modules/entity_browser/src/Entity/EntityBrowser.php
index 53bc9f2aff5efde138786b9da1dea79898b4fe80..54d9793ab5212509358ae2e4d6eb5dfaacce333e 100644
--- a/web/modules/entity_browser/src/Entity/EntityBrowser.php
+++ b/web/modules/entity_browser/src/Entity/EntityBrowser.php
@@ -21,19 +21,19 @@
  *   handlers = {
  *     "form" = {
  *       "entity_browser" = "Drupal\entity_browser\Form\EntityBrowserForm",
+ *       "default" = "Drupal\entity_browser\Form\EntityBrowserEditForm",
+ *       "edit" = "Drupal\entity_browser\Form\EntityBrowserEditForm",
  *       "delete" = "Drupal\entity_browser\Form\EntityBrowserDeleteForm",
+ *       "edit_widgets" = "Drupal\entity_browser\Form\WidgetsConfig",
  *     },
  *     "access" = "Drupal\Core\Entity\EntityAccessControlHandler",
  *     "list_builder" = "Drupal\entity_browser\Controllers\EntityBrowserListBuilder",
- *     "wizard" = {
- *       "add" = "Drupal\entity_browser\Wizard\EntityBrowserWizardAdd",
- *       "edit" = "Drupal\entity_browser\Wizard\EntityBrowserWizard",
- *     }
  *   },
  *   links = {
- *     "canonical" = "/admin/config/content/entity_browser/{machine_name}/{step}",
+ *     "canonical" = "/admin/config/content/entity_browser/{entity_browser}",
  *     "collection" = "/admin/config/content/entity_browser",
- *     "edit-form" = "/admin/config/content/entity_browser/{machine_name}/{step}",
+ *     "edit-form" = "/admin/config/content/entity_browser/{entity_browser}/edit",
+ *     "edit-widgets" = "/admin/config/content/entity_browser/{entity_browser}/edit_widgets",
  *     "delete-form" = "/admin/config/content/entity_browser/{entity_browser}/delete",
  *   },
  *   admin_permission = "administer entity browsers",
@@ -205,6 +205,7 @@ public function setLabel($label) {
   public function setDisplay($display) {
     $this->display = $display;
     $this->displayPluginCollection = NULL;
+    $this->display_configuration = [];
     $this->getDisplay();
     return $this;
   }
@@ -215,6 +216,7 @@ public function setDisplay($display) {
   public function setWidgetSelector($widget_selector) {
     $this->widget_selector = $widget_selector;
     $this->widgetSelectorCollection = NULL;
+    $this->widget_selector_configuration = [];
     $this->getWidgetSelector();
     return $this;
   }
@@ -225,6 +227,7 @@ public function setWidgetSelector($widget_selector) {
   public function setSelectionDisplay($selection_display) {
     $this->selection_display = $selection_display;
     $this->selectionDisplayCollection = NULL;
+    $this->selection_display_configuration = [];
     $this->getSelectionDisplay();
     return $this;
   }
@@ -294,7 +297,6 @@ public function addWidget(array $configuration) {
    */
   public function deleteWidget(WidgetInterface $widget) {
     $this->getWidgets()->removeInstanceId($widget->uuid());
-    $this->save();
     return $this;
   }
 
@@ -303,6 +305,14 @@ public function deleteWidget(WidgetInterface $widget) {
    */
   public function getFirstWidget() {
     $instance_ids = $this->getWidgets()->getInstanceIds();
+    $instance_ids = array_filter($instance_ids, function ($id) {
+      return $this->getWidget($id)->access()->isAllowed();
+    });
+
+    if (empty($instance_ids)) {
+      return NULL;
+    }
+
     return reset($instance_ids);
   }
 
@@ -410,7 +420,9 @@ public function preSave(EntityStorageInterface $storage) {
   }
 
   /**
-   * Prevent plugin collections from being serialized and correctly serialize
+   * Sleep method.
+   *
+   * Prevents plugin collections from being serialized and correctly serializes
    * selected entities.
    */
   public function __sleep() {
diff --git a/web/modules/entity_browser/src/EntityBrowserFormInterface.php b/web/modules/entity_browser/src/EntityBrowserFormInterface.php
index 335fe96abeceb6899711dad04201a8f53185e969..8e1ac453391561330f962a1d4374ff1b76d42c9f 100644
--- a/web/modules/entity_browser/src/EntityBrowserFormInterface.php
+++ b/web/modules/entity_browser/src/EntityBrowserFormInterface.php
@@ -12,9 +12,17 @@ interface EntityBrowserFormInterface extends FormInterface {
   /**
    * Sets entity browser entity.
    *
-   * @param \Drupal\entity_browser\EntityBrowserInterface
+   * @param \Drupal\entity_browser\EntityBrowserInterface $entity_browser
    *   Entity browser entity.
    */
   public function setEntityBrowser(EntityBrowserInterface $entity_browser);
 
+  /**
+   * Returns the entity browser entity.
+   *
+   * @return \Drupal\entity_browser\EntityBrowserInterface
+   *   Entity browser entity.
+   */
+  public function getEntityBrowser();
+
 }
diff --git a/web/modules/entity_browser/src/EntityBrowserInterface.php b/web/modules/entity_browser/src/EntityBrowserInterface.php
index cfad3254aa1cffca6c89c68a8417a2c0f03dec32..09a5e867388f2c86fd70596e44d8367d48da887e 100644
--- a/web/modules/entity_browser/src/EntityBrowserInterface.php
+++ b/web/modules/entity_browser/src/EntityBrowserInterface.php
@@ -123,8 +123,8 @@ public function deleteWidget(WidgetInterface $widget);
   /**
    * Gets first widget based on weights.
    *
-   * @return string
-   *   First widget instance ID.
+   * @return string|null
+   *   First widget instance ID or NULL if no widgets are available.
    */
   public function getFirstWidget();
 
diff --git a/web/modules/entity_browser/src/FieldWidgetDisplayInterface.php b/web/modules/entity_browser/src/FieldWidgetDisplayInterface.php
index e589fa3dce9b4efa0a489fba03636e9c395fa199..cda9785a974715d4f6f7fadd480f6af4ea6ad106 100644
--- a/web/modules/entity_browser/src/FieldWidgetDisplayInterface.php
+++ b/web/modules/entity_browser/src/FieldWidgetDisplayInterface.php
@@ -2,7 +2,8 @@
 
 namespace Drupal\entity_browser;
 
-use Drupal\Component\Plugin\ConfigurablePluginInterface;
+use Drupal\Component\Plugin\ConfigurableInterface;
+use Drupal\Component\Plugin\DependentPluginInterface;
 use Drupal\Component\Plugin\PluginInspectionInterface;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityTypeInterface;
@@ -11,12 +12,12 @@
 /**
  * Defines the interface for entity browser field widget display plugins.
  */
-interface FieldWidgetDisplayInterface extends PluginInspectionInterface, ConfigurablePluginInterface {
+interface FieldWidgetDisplayInterface extends PluginInspectionInterface, ConfigurableInterface, DependentPluginInterface {
 
   /**
    * Builds and gets render array for the entity.
    *
-   * @param EntityInterface $entity
+   * @param \Drupal\Core\Entity\EntityInterface $entity
    *   Entity to be displayed.
    *
    * @return array
diff --git a/web/modules/entity_browser/src/Form/DisplayConfig.php b/web/modules/entity_browser/src/Form/DisplayConfig.php
deleted file mode 100644
index 14be01d922fa5267b287e6179e90fb5191054a8d..0000000000000000000000000000000000000000
--- a/web/modules/entity_browser/src/Form/DisplayConfig.php
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-
-namespace Drupal\entity_browser\Form;
-
-use Drupal\entity_browser\EntityBrowserInterface;
-
-/**
- * Display configuration step in entity browser form wizard.
- */
-class DisplayConfig extends PluginConfigFormBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormId() {
-    return 'entity_browser_display_config_form';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getPlugin(EntityBrowserInterface $entity_browser) {
-    return $entity_browser->getDisplay();
-  }
-
-}
diff --git a/web/modules/entity_browser/src/Form/EntityBrowserEditForm.php b/web/modules/entity_browser/src/Form/EntityBrowserEditForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..465dc757d5376a25fee44032bb5c0c58353e85d6
--- /dev/null
+++ b/web/modules/entity_browser/src/Form/EntityBrowserEditForm.php
@@ -0,0 +1,472 @@
+<?php
+
+namespace Drupal\entity_browser\Form;
+
+use Drupal\Core\Entity\EntityForm;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\entity_browser\DisplayManager;
+use Drupal\entity_browser\SelectionDisplayManager;
+use Drupal\entity_browser\WidgetManager;
+use Drupal\entity_browser\WidgetSelectorManager;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Drupal\Core\Form\SubformState;
+use Drupal\Core\Messenger\MessengerInterface;
+
+/**
+ * Class EntityBrowserEditForm.
+ */
+class EntityBrowserEditForm extends EntityForm {
+
+  /**
+   * Entity browser display plugin manager.
+   *
+   * @var \Drupal\entity_browser\DisplayManager
+   */
+  protected $displayManager;
+
+  /**
+   * Entity browser widget selector plugin manager.
+   *
+   * @var \Drupal\entity_browser\WidgetSelectorManager
+   */
+  protected $widgetSelectorManager;
+
+  /**
+   * Entity browser selection display plugin manager.
+   *
+   * @var \Drupal\entity_browser\SelectionDisplayManager
+   */
+  protected $selectionDisplayManager;
+
+  /**
+   * Entity browser widget plugin manager.
+   *
+   * @var \Drupal\entity_browser\WidgetManager
+   */
+  protected $widgetManager;
+
+  /**
+   * Constructs EntityBrowserEditForm form class.
+   *
+   * @param \Drupal\entity_browser\DisplayManager $display_manager
+   *   Entity browser display plugin manager.
+   * @param \Drupal\entity_browser\WidgetSelectorManager $widget_selector_manager
+   *   Entity browser widget selector plugin manager.
+   * @param \Drupal\entity_browser\SelectionDisplayManager $selection_display_manager
+   *   Entity browser selection display plugin manager.
+   * @param \Drupal\entity_browser\WidgetManager $widget_manager
+   *   Entity browser widget plugin manager.
+   * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+   *   The messenger.
+   */
+  public function __construct(DisplayManager $display_manager, WidgetSelectorManager $widget_selector_manager, SelectionDisplayManager $selection_display_manager, WidgetManager $widget_manager, MessengerInterface $messenger) {
+    $this->displayManager = $display_manager;
+    $this->selectionDisplayManager = $selection_display_manager;
+    $this->widgetSelectorManager = $widget_selector_manager;
+    $this->widgetManager = $widget_manager;
+    $this->messenger = $messenger;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('plugin.manager.entity_browser.display'),
+      $container->get('plugin.manager.entity_browser.widget_selector'),
+      $container->get('plugin.manager.entity_browser.selection_display'),
+      $container->get('plugin.manager.entity_browser.widget'),
+      $container->get('messenger')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function form(array $form, FormStateInterface $form_state) {
+    $form = parent::form($form, $form_state);
+
+    /** @var \Drupal\entity_browser\Entity\EntityBrowser $entity_browser */
+    $entity_browser = $this->entity;
+
+    $form['label'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Label'),
+      '#maxlength' => 255,
+      '#default_value' => $entity_browser->label(),
+      '#description' => $this->t("Label for the Entity Browser."),
+      '#required' => TRUE,
+    ];
+
+    $form['name'] = [
+      '#type' => 'machine_name',
+      '#default_value' => $entity_browser->id(),
+      '#machine_name' => [
+        'exists' => '\Drupal\entity_browser\Entity\EntityBrowser::load',
+      ],
+      '#disabled' => !$entity_browser->isNew(),
+    ];
+
+    if ($entity_browser->isNew()) {
+      $help_text = '<div class="clearfix eb-help-text"><h2>' . $this->t('Entity Browser creation instructions') . '</h2>';
+      $help_text .= '<p>' . $this->t('When you save this form, you will be taken to another form to configure widgets for the entity browser.') . '</p>';
+      $help_text .= '<p>' . $this->t('You can find more detailed information about creating and configuring Entity Browsers at the <a href="@guide_href" target="_blank">official documentation</a>.', ['@guide_href' => 'https://drupal-media.gitbooks.io/drupal8-guide/content/modules/entity_browser/intro.html']) . '</p>';
+      $help_text .= '</div>';
+      $form['help_text'] = [
+        '#markup' => $help_text,
+      ];
+    }
+
+    $form['display_wrapper'] = [
+      '#type' => 'fieldset',
+      '#title' => $this->t('Display'),
+    ];
+
+    $form['display_wrapper']['description'] = $this->getPluginDescription('display');
+    // Default if not set.
+    if (empty($entity_browser->display)) {
+      $entity_browser->setDisplay('modal');
+    }
+
+    $display_plugin = $entity_browser->getDisplay();
+
+    $form['display_wrapper']['display'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Display plugin'),
+      '#default_value' => $display_plugin->getPluginId(),
+      '#options' => $this->getPluginOptions('display'),
+      '#required' => TRUE,
+      '#ajax' => [
+        'callback' => [get_class($this), 'displayPluginAjaxCallback'],
+        'wrapper' => 'display-config-ajax-wrapper',
+        'event' => 'change',
+      ],
+      '#executes_submit_callback' => TRUE,
+      '#submit' => [[get_class($this), 'submitUpdateDisplayPluginSettings']],
+      '#limit_validation_errors' => [['display']],
+    ];
+
+    $form['display_wrapper']['display_configuration'] = [
+      '#type' => 'details',
+      '#title' => $this->t('Display Plugin settings'),
+      '#open' => FALSE,
+      '#prefix' => '<div id="display-config-ajax-wrapper">',
+      '#suffix' => '</div>',
+      '#tree' => TRUE,
+    ];
+
+    if ($display_config_form = $display_plugin->buildConfigurationForm([], $form_state)) {
+      $form['display_wrapper']['display_configuration'] = array_merge($form['display_wrapper']['display_configuration'], $display_config_form);
+    }
+    else {
+      $form['display_wrapper']['display_configuration']['no_options'] = [
+        '#prefix' => '<p>',
+        '#suffix' => '</p>',
+        '#markup' => $this->t('This plugin has no configuration options.'),
+      ];
+    }
+
+    $form['widget_selector_wrapper'] = [
+      '#type' => 'fieldset',
+      '#title' => $this->t('Widget Selector'),
+    ];
+
+    $form['widget_selector_wrapper']['description'] = $this->getPluginDescription('widget_selector');
+
+    // Set default if empty.
+    if (empty($entity_browser->widget_selector)) {
+      $entity_browser->setWidgetSelector('tabs');
+    }
+
+    $widget_selector_plugin = $entity_browser->getWidgetSelector();
+
+    $form['widget_selector_wrapper']['widget_selector'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Widget selector plugin'),
+      '#default_value' => $widget_selector_plugin->getPluginId(),
+      '#options' => $this->getPluginOptions('widget_selector'),
+      '#required' => TRUE,
+      '#ajax' => [
+        'callback' => [get_class($this), 'widgetSelectorAjaxCallback'],
+        'wrapper' => 'widget-selector-config-ajax-wrapper',
+        'event' => 'change',
+      ],
+      '#executes_submit_callback' => TRUE,
+      '#submit' => [[get_class($this), 'submitUpdateWidgetSelector']],
+      '#limit_validation_errors' => [['widget_selector']],
+    ];
+
+    $form['widget_selector_wrapper']['widget_selector_configuration'] = [
+      '#type' => 'details',
+      '#title' => $this->t('Widget Selector Plugin settings'),
+      '#open' => FALSE,
+      '#prefix' => '<div id="widget-selector-config-ajax-wrapper">',
+      '#suffix' => '</div>',
+      '#tree' => TRUE,
+    ];
+
+    if ($widget_selector_config_form = $widget_selector_plugin->buildConfigurationForm([], $form_state)) {
+      $form['widget_selector_wrapper']['widget_selector_configuration'] = array_merge($form['widget_selector_wrapper']['widget_selector_configuration'], $widget_selector_config_form);
+    }
+    else {
+      $form['widget_selector_wrapper']['widget_selector_configuration']['no_options'] = [
+        '#prefix' => '<p>',
+        '#suffix' => '</p>',
+        '#markup' => $this->t('This plugin has no configuration options.'),
+      ];
+    }
+
+    $form['selection_display_wrapper'] = [
+      '#type' => 'fieldset',
+      '#title' => $this->t('Selection Display'),
+    ];
+
+    $form['selection_display_wrapper']['description'] = $this->getPluginDescription('selection_display');
+
+    if (empty($entity_browser->selection_display)) {
+      $entity_browser->setSelectionDisplay('no_display');
+    }
+
+    $selection_display = $entity_browser->getSelectionDisplay();
+
+    $form['selection_display_wrapper']['selection_display'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Selection display plugin'),
+      '#default_value' => $selection_display->getPluginId(),
+      '#options' => $this->getPluginOptions('selection_display'),
+      '#required' => TRUE,
+      '#ajax' => [
+        'callback' => [get_class($this), 'selectionDisplayAjaxCallback'],
+        'wrapper' => 'selection-display-config-ajax-wrapper',
+        'event' => 'change',
+      ],
+      '#executes_submit_callback' => TRUE,
+      '#submit' => [[get_class($this), 'submitUpdateSelectionDisplay']],
+      '#limit_validation_errors' => [['selection_display']],
+    ];
+
+    $form['selection_display_wrapper']['selection_display_configuration'] = [
+      '#type' => 'details',
+      '#title' => $this->t('Selection Display Plugin settings'),
+      '#open' => FALSE,
+      '#prefix' => '<div id="selection-display-config-ajax-wrapper">',
+      '#suffix' => '</div>',
+      '#tree' => TRUE,
+    ];
+
+    if ($selection_display_config_form = $selection_display->buildConfigurationForm([], $form_state)) {
+      $form['selection_display_wrapper']['selection_display_configuration'] = array_merge($form['selection_display_wrapper']['selection_display_configuration'], $selection_display_config_form);
+    }
+    else {
+      $form['selection_display_wrapper']['selection_display_configuration']['no_options'] = [
+        '#prefix' => '<p>',
+        '#suffix' => '</p>',
+        '#markup' => $this->t('This plugin has no configuration options.'),
+      ];
+    }
+
+    return $form;
+  }
+
+  /**
+   * Get options for form element.
+   *
+   * @return array
+   *   Plugin options.
+   */
+  protected function getPluginOptions($plugin_type) {
+
+    switch ($plugin_type) {
+      case 'display':
+        $definitions = $this->displayManager->getDefinitions();
+        break;
+
+      case 'widget_selector':
+        $definitions = $this->widgetSelectorManager->getDefinitions();
+        break;
+
+      case 'selection_display':
+        $definitions = $this->selectionDisplayManager->getDefinitions();
+        break;
+
+      default:
+        return [];
+    }
+
+    $options = [];
+    foreach ($definitions as $plugin_id => $plugin_definition) {
+      $options[$plugin_id] = $plugin_definition['label'];
+    }
+
+    return $options;
+  }
+
+  /**
+   * Get an introductory description to the one of the three plugin types.
+   *
+   * @param string $plugin_type
+   *   The plugin type.
+   *
+   * @return array
+   *   Markup render element.
+   */
+  protected function getPluginDescription($plugin_type = '') {
+
+    switch ($plugin_type) {
+      case 'display':
+        $intro = $this->t('Choose here how the entity browser should be presented to the end user.');
+        $definitions = $this->displayManager->getDefinitions();
+        break;
+
+      case 'widget_selector':
+        $intro = $this->t('In the last step of the entity browser configuration you can decide how the widgets will be available to the editor.');
+        $definitions = $this->widgetSelectorManager->getDefinitions();
+        break;
+
+      case 'selection_display':
+        $intro = $this->t('You can optionally allow a "work-in-progress selection zone" to be available to the editor, while still navigating, browsing and selecting the entities.');
+        $definitions = $this->selectionDisplayManager->getDefinitions();
+        break;
+
+      default:
+        return NULL;
+    }
+
+    $output = "<p>$intro</p>";
+    $output .= '<p>' . $this->t('The available plugins are:') . '</p>';
+
+    $output .= '<dl>';
+
+    foreach ($definitions as $plugin_id => $plugin_definition) {
+      $output .= '<dt><strong>' . $plugin_definition['label'] . ':</strong></dt>';
+      $output .= '<dd>' . $plugin_definition['description'] . '</dd>';
+    }
+    $output .= '</dl>';
+
+    return ['#markup' => $output];
+  }
+
+  /**
+   * AJAX callback for returning new display configuration.
+   */
+  public static function displayPluginAjaxCallback($form, $form_state) {
+    $form['display_wrapper']['display_configuration']['#open'] = TRUE;
+    return $form['display_wrapper']['display_configuration'];
+  }
+
+  /**
+   * AJAX callback for returning new widget selector configuration.
+   */
+  public static function widgetSelectorAjaxCallback($form, $form_state) {
+    $form['widget_selector_wrapper']['widget_selector_configuration']['#open'] = TRUE;
+    return $form['widget_selector_wrapper']['widget_selector_configuration'];
+  }
+
+  /**
+   * AJAX callback for returning new widget selector configuration.
+   */
+  public static function selectionDisplayAjaxCallback($form, $form_state) {
+    $form['selection_display_wrapper']['selection_display_configuration']['#open'] = TRUE;
+    return $form['selection_display_wrapper']['selection_display_configuration'];
+  }
+
+  /**
+   * AJAX submit callback for updating display.
+   */
+  public static function submitUpdateDisplayPluginSettings($form, FormStateInterface $form_state) {
+    $display = $form_state->getValue('display');
+    $form_state->getFormObject()->getEntity()->setDisplay($display);
+    $form_state->setRebuild();
+  }
+
+  /**
+   * AJAX submit callback for updating widget selector.
+   */
+  public static function submitUpdateWidgetSelector($form, FormStateInterface $form_state) {
+    $widget_selector = $form_state->getValue('widget_selector');
+    $form_state->getFormObject()->getEntity()->setWidgetSelector($widget_selector);
+    $form_state->setRebuild();
+  }
+
+  /**
+   * AJAX submit callback for updating display.
+   */
+  public static function submitUpdateSelectionDisplay($form, FormStateInterface $form_state) {
+    $selection_display = $form_state->getValue('selection_display');
+    $form_state->getFormObject()->getEntity()->setSelectionDisplay($selection_display);
+    $form_state->setRebuild();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildEntity(array $form, FormStateInterface $form_state) {
+
+    $this->entity->setName($form_state->getValue('name'))
+      ->setLabel($form_state->getValue('label'))
+      ->setDisplay($form_state->getValue('display'))
+      ->setWidgetSelector($form_state->getValue('widget_selector'))
+      ->setSelectionDisplay($form_state->getValue('selection_display'));
+
+    $subform_state = SubformState::createForSubform($form['display_wrapper']['display_configuration'], $form, $form_state);
+    $this->entity->getDisplay()->submitConfigurationForm($form, $subform_state);
+
+    $subform_state = SubformState::createForSubform($form['widget_selector_wrapper']['widget_selector_configuration'], $form, $form_state);
+    $this->entity->getWidgetSelector()->submitConfigurationForm($form, $subform_state);
+
+    $subform_state = SubformState::createForSubform($form['selection_display_wrapper']['selection_display_configuration'], $form, $form_state);
+    $this->entity->getSelectionDisplay()->submitConfigurationForm($form, $subform_state);
+
+    return parent::buildEntity($form, $form_state);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateForm(array &$form, FormStateInterface $form_state) {
+
+    // Only validate on form submission.
+    if ($form_state->getTriggeringElement()['#name'] !== 'op') {
+      return;
+    }
+
+    $subform_state = SubformState::createForSubform($form['display_wrapper']['display_configuration'], $form, $form_state);
+    $this->entity->getDisplay()->validateConfigurationForm($form['display_wrapper']['display_configuration'], $subform_state);
+
+    $subform_state = SubformState::createForSubform($form['widget_selector_wrapper']['widget_selector_configuration'], $form, $form_state);
+    $this->entity->getWidgetSelector()->validateConfigurationForm($form['widget_selector_wrapper']['widget_selector_configuration'], $subform_state);
+
+    $subform_state = SubformState::createForSubform($form['selection_display_wrapper']['selection_display_configuration'], $form, $form_state);
+    $this->entity->getSelectionDisplay()->validateConfigurationForm($form['selection_display_wrapper']['selection_display_configuration'], $subform_state);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state) {
+    parent::submitForm($form, $form_state);
+
+    // If this is a new entity, redirect to the widget edit form.
+    if ($this->entity->isNew()) {
+      $params = [
+        'entity_browser' => $this->entity->id(),
+      ];
+      $form_state->setRedirect('entity.entity_browser.edit_widgets', $params);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function save(array $form, FormStateInterface $form_state) {
+    $status = $this->entity->save();
+
+    if ($status == SAVED_UPDATED) {
+      $this->messenger->addMessage($this->t('The entity browser %name has been updated.', ['%name' => $this->entity->label()]));
+    }
+    elseif ($status == SAVED_NEW) {
+      $this->messenger->addMessage($this->t('The entity browser %name has been added. Now you may configure the widgets you would like to use.', ['%name' => $this->entity->label()]));
+    }
+  }
+
+}
diff --git a/web/modules/entity_browser/src/Form/EntityBrowserForm.php b/web/modules/entity_browser/src/Form/EntityBrowserForm.php
index 340e425fd3cdb896f4d4f266aba1ac78ed23e440..1f274c9ef3c76e5e05826a3ebcd324adc447c4ab 100644
--- a/web/modules/entity_browser/src/Form/EntityBrowserForm.php
+++ b/web/modules/entity_browser/src/Form/EntityBrowserForm.php
@@ -4,18 +4,21 @@
 
 use Drupal\Component\Uuid\UuidInterface;
 use Drupal\Core\Config\ConfigException;
+use Drupal\Core\Form\BaseFormIdInterface;
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface;
+use Drupal\Core\Messenger\MessengerInterface;
 use Drupal\entity_browser\DisplayAjaxInterface;
 use Drupal\entity_browser\EntityBrowserFormInterface;
 use Drupal\entity_browser\EntityBrowserInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
+use Drupal\Core\Render\RendererInterface;
 
 /**
  * The entity browser form.
  */
-class EntityBrowserForm extends FormBase implements EntityBrowserFormInterface {
+class EntityBrowserForm extends FormBase implements EntityBrowserFormInterface, BaseFormIdInterface {
 
   /**
    * UUID generator service.
@@ -38,6 +41,13 @@ class EntityBrowserForm extends FormBase implements EntityBrowserFormInterface {
    */
   protected $selectionStorage;
 
+  /**
+   * The renderer service.
+   *
+   * @var \Drupal\Core\Render\RendererInterface
+   */
+  protected $renderer;
+
   /**
    * Constructs a EntityBrowserForm object.
    *
@@ -45,10 +55,16 @@ class EntityBrowserForm extends FormBase implements EntityBrowserFormInterface {
    *   The UUID generator service.
    * @param \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface $selection_storage
    *   Selection storage.
+   * @param \Drupal\Core\Render\RendererInterface $renderer
+   *   The renderer service.
+   * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+   *   The messenger.
    */
-  public function __construct(UuidInterface $uuid_generator, KeyValueStoreExpirableInterface $selection_storage) {
+  public function __construct(UuidInterface $uuid_generator, KeyValueStoreExpirableInterface $selection_storage, RendererInterface $renderer, MessengerInterface $messenger) {
     $this->uuidGenerator = $uuid_generator;
     $this->selectionStorage = $selection_storage;
+    $this->renderer = $renderer;
+    $this->messenger = $messenger;
   }
 
   /**
@@ -57,7 +73,9 @@ public function __construct(UuidInterface $uuid_generator, KeyValueStoreExpirabl
   public static function create(ContainerInterface $container) {
     return new static(
       $container->get('uuid'),
-      $container->get('entity_browser.selection_storage')
+      $container->get('entity_browser.selection_storage'),
+      $container->get('renderer'),
+      $container->get('messenger')
     );
   }
 
@@ -68,6 +86,13 @@ public function getFormId() {
     return 'entity_browser_' . $this->entityBrowser->id() . '_form';
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getBaseFormId() {
+    return 'entity_browser_form';
+  }
+
   /**
    * {@inheritdoc}
    */
@@ -75,6 +100,13 @@ public function setEntityBrowser(EntityBrowserInterface $entity_browser) {
     $this->entityBrowser = $entity_browser;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getEntityBrowser() {
+    return $this->entityBrowser;
+  }
+
   /**
    * Initializes form state.
    *
@@ -124,16 +156,33 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       'widget' => 'widget',
       'selection_display' => 'selection_display',
     ];
+
+    if (!($current_widget_id = $this->getCurrentWidget($form_state))) {
+      $this->messenger->addWarning($this->t('No widgets are available.'));
+      return $form;
+    }
+
     $this->entityBrowser
       ->getWidgetSelector()
-      ->setDefaultWidget($this->getCurrentWidget($form_state));
+      ->setDefaultWidget($current_widget_id);
     $form[$form['#browser_parts']['widget_selector']] = $this->entityBrowser
       ->getWidgetSelector()
       ->getForm($form, $form_state);
-    $form[$form['#browser_parts']['widget']] = $this->entityBrowser
-      ->getWidgets()
-      ->get($this->getCurrentWidget($form_state))
-      ->getForm($form, $form_state, $this->entityBrowser->getAdditionalWidgetParameters());
+
+    $widget = $this->entityBrowser->getWidget($current_widget_id);
+    if ($widget->access()->isAllowed()) {
+      $form[$form['#browser_parts']['widget']] = $widget->getForm($form, $form_state, $this->entityBrowser->getAdditionalWidgetParameters());
+    }
+    else {
+      $this->messenger->addWarning($this->t('Access to the widget forbidden.'));
+    }
+
+    // Add cache access cache metadata from the widgets to the form directly as
+    // it is affected.
+    foreach ($this->entityBrowser->getWidgets() as $widget) {
+      /** @var \Drupal\entity_browser\WidgetInterface $widget */
+      $this->renderer->addCacheableDependency($form, $widget->access());
+    }
 
     $form[$form['#browser_parts']['selection_display']] = $this->entityBrowser
       ->getSelectionDisplay()
diff --git a/web/modules/entity_browser/src/Form/GeneralInfoConfig.php b/web/modules/entity_browser/src/Form/GeneralInfoConfig.php
deleted file mode 100644
index 908ff383b3aeafbc6a49ae8c9c32eb78ccd84255..0000000000000000000000000000000000000000
--- a/web/modules/entity_browser/src/Form/GeneralInfoConfig.php
+++ /dev/null
@@ -1,166 +0,0 @@
-<?php
-
-namespace Drupal\entity_browser\Form;
-
-use Drupal\Core\Form\FormBase;
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\entity_browser\DisplayManager;
-use Drupal\entity_browser\SelectionDisplayManager;
-use Drupal\entity_browser\WidgetManager;
-use Drupal\entity_browser\WidgetSelectorManager;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * General information configuration step in entity browser form wizard.
- */
-class GeneralInfoConfig extends FormBase {
-
-  /**
-   * Entity browser display plugin manager.
-   *
-   * @var \Drupal\entity_browser\DisplayManager
-   */
-  protected $displayManager;
-
-  /**
-   * Entity browser widget selector plugin manager.
-   *
-   * @var \Drupal\entity_browser\WidgetSelectorManager
-   */
-  protected $widgetSelectorManager;
-
-  /**
-   * Entity browser selection display plugin manager.
-   *
-   * @var \Drupal\entity_browser\SelectionDisplayManager
-   */
-  protected $selectionDisplayManager;
-
-  /**
-   * Entity browser widget plugin manager.
-   *
-   * @var \Drupal\entity_browser\WidgetManager
-   */
-  protected $widgetManager;
-
-  /**
-   * Constructs GeneralInfoConfig form class.
-   *
-   * @param \Drupal\entity_browser\DisplayManager $display_manager
-   *   Entity browser display plugin manager.
-   * @param \Drupal\entity_browser\WidgetSelectorManager $widget_selector_manager
-   *   Entity browser widget selector plugin manager.
-   * @param \Drupal\entity_browser\SelectionDisplayManager $selection_display_manager
-   *   Entity browser selection display plugin manager.
-   * @param \Drupal\entity_browser\WidgetManager $widget_manager
-   *   Entity browser widget plugin manager.
-   */
-  function __construct(DisplayManager $display_manager, WidgetSelectorManager $widget_selector_manager, SelectionDisplayManager $selection_display_manager, WidgetManager $widget_manager) {
-    $this->displayManager = $display_manager;
-    $this->selectionDisplayManager = $selection_display_manager;
-    $this->widgetSelectorManager = $widget_selector_manager;
-    $this->widgetManager = $widget_manager;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container) {
-    return new static(
-      $container->get('plugin.manager.entity_browser.display'),
-      $container->get('plugin.manager.entity_browser.widget_selector'),
-      $container->get('plugin.manager.entity_browser.selection_display'),
-      $container->get('plugin.manager.entity_browser.widget')
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormId() {
-    return 'entity_browser_general_info_config_form';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildForm(array $form, FormStateInterface $form_state) {
-    $cached_values = $form_state->getTemporaryValue('wizard');
-    /** @var \Drupal\entity_browser\EntityBrowserInterface  $entity_browser */
-    $entity_browser = $cached_values['entity_browser'];
-
-    if (empty($entity_browser->id())) {
-      $help_text = '<div class="clearfix eb-help-text"><h2>' . $this->t('Entity Browser creation instructions') . '</h2>';
-      $help_text .= '<p>' . $this->t('This is a multi-step form. In this first step you need to define the main characteristics of the Entity Browser (in other words, which plugins will be used for each functionality). In the following steps of this wizard, each individual plugin can be configured, when necessary.') . '</p>';
-      $help_text .= '<p>' . $this->t('You can find more detailed information about creating and configuring Entity Browsers at the <a href="@guide_href" target="_blank">official documentation</a>.', ['@guide_href' => 'https://drupal-media.gitbooks.io/drupal8-guide/content/modules/entity_browser/intro.html']) . '</p>';
-      $help_text .= '</div>';
-      $form['help_text'] = [
-        '#markup' => $help_text,
-      ];
-    }
-
-    $displays = [];
-    $display_description = $this->t('Choose here how the browser(s) should be presented to the end user. The available plugins are:') . '<ul>';
-    foreach ($this->displayManager->getDefinitions() as $plugin_id => $plugin_definition) {
-      $displays[$plugin_id] = $plugin_definition['label'];
-      $display_description .= '<li><b>' . $plugin_definition['label'] . ':</b> ' . $plugin_definition['description'] . '</li>';
-    }
-    $display_description .= '</ul>';
-    $form['display'] = [
-      '#type' => 'select',
-      '#title' => $this->t('Display plugin'),
-      '#description' => $display_description,
-      '#default_value' => $entity_browser->get('display') ? $entity_browser->getDisplay()->getPluginId() : 'modal',
-      '#options' => $displays,
-      '#required' => TRUE,
-    ];
-
-    $widget_selectors = [];
-    $widget_description = $this->t('In the last step of the entity browser configuration you can decide how the widgets will be available to the editor. The available plugins are:') . '<ul>';
-    foreach ($this->widgetSelectorManager->getDefinitions() as $plugin_id => $plugin_definition) {
-      $widget_selectors[$plugin_id] = $plugin_definition['label'];
-      $widget_description .= '<li><b>' . $plugin_definition['label'] . ':</b> ' . $plugin_definition['description'] . '</li>';
-    }
-    $widget_description .= '</ul>';
-    $form['widget_selector'] = [
-      '#type' => 'select',
-      '#title' => $this->t('Widget selector plugin'),
-      '#description' => $widget_description,
-      '#default_value' => $entity_browser->get('widget_selector') ? $entity_browser->getWidgetSelector()->getPluginId() : 'tabs',
-      '#options' => $widget_selectors,
-      '#required' => TRUE,
-    ];
-
-    $selection_display = [];
-    $selection_description = $this->t('You can optionally allow a "work-in-progress selection zone" to be available to the editor, while still navigating, browsing and selecting the entities. The available plugins are:') . '<ul>';
-    foreach ($this->selectionDisplayManager->getDefinitions() as $plugin_id => $plugin_definition) {
-      $selection_display[$plugin_id] = $plugin_definition['label'];
-      $selection_description .= '<li><b>' . $plugin_definition['label'] . ':</b> ' . $plugin_definition['description'] . '</li>';
-    }
-    $selection_description .= '</ul>';
-    $form['selection_display'] = [
-      '#type' => 'select',
-      '#title' => $this->t('Selection display plugin'),
-      '#description' => $selection_description,
-      '#default_value' => $entity_browser->get('selection_display') ? $entity_browser->getSelectionDisplay()->getPluginId() : 'no_display',
-      '#options' => $selection_display,
-      '#required' => TRUE,
-    ];
-
-    return $form;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, FormStateInterface $form_state) {
-    /** @var \Drupal\entity_browser\EntityBrowserInterface $entity_browser */
-    $entity_browser = $form_state->getTemporaryValue('wizard')['entity_browser'];
-    $entity_browser->setName($form_state->getValue('id'))
-      ->setLabel($form_state->getValue('label'))
-      ->setDisplay($form_state->getValue('display'))
-      ->setWidgetSelector($form_state->getValue('widget_selector'))
-      ->setSelectionDisplay($form_state->getValue('selection_display'));
-  }
-
-}
diff --git a/web/modules/entity_browser/src/Form/PluginConfigFormBase.php b/web/modules/entity_browser/src/Form/PluginConfigFormBase.php
deleted file mode 100644
index 95372dd45eaf947be44e943750b374d3477d2326..0000000000000000000000000000000000000000
--- a/web/modules/entity_browser/src/Form/PluginConfigFormBase.php
+++ /dev/null
@@ -1,61 +0,0 @@
-<?php
-
-namespace Drupal\entity_browser\Form;
-
-use Drupal\Core\Form\FormBase;
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Render\Element;
-use Drupal\entity_browser\EntityBrowserInterface;
-
-/**
- * Base class for steps in entity browser form wizard.
- */
-abstract class PluginConfigFormBase extends FormBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildForm(array $form, FormStateInterface $form_state) {
-    /** @var \Drupal\entity_browser\EntityBrowserInterface $entity_browser */
-    $entity_browser = $form_state->getTemporaryValue('wizard')['entity_browser'];
-    $form = $this->getPlugin($entity_browser)->buildConfigurationForm($form, $form_state);
-
-    $fields = Element::children($form);
-    if (empty($fields)) {
-      $form['no_options'] = [
-        '#prefix' => '<p>',
-        '#suffix' => '</p>',
-        '#markup' => $this->t('This plugin has no configuration options.'),
-      ];
-    }
-
-    return $form;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function validateForm(array &$form, FormStateInterface $form_state) {
-    /** @var \Drupal\entity_browser\EntityBrowserInterface $entity_browser */
-    $entity_browser = $form_state->getTemporaryValue('wizard')['entity_browser'];
-    $this->getPlugin($entity_browser)->validateConfigurationForm($form, $form_state);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, FormStateInterface $form_state) {
-    /** @var \Drupal\entity_browser\EntityBrowserInterface $entity_browser */
-    $entity_browser = $form_state->getTemporaryValue('wizard')['entity_browser'];
-    $this->getPlugin($entity_browser)->submitConfigurationForm($form, $form_state);
-  }
-
-  /**
-   * Gets plugin that form operates with.
-   *
-   * @return \Drupal\Core\Plugin\PluginFormInterface|\Drupal\Component\Plugin\PluginInspectionInterface
-   *   Plugin instance.
-   */
-  abstract public function getPlugin(EntityBrowserInterface $entity_browser);
-
-}
diff --git a/web/modules/entity_browser/src/Form/SelectionDisplayConfig.php b/web/modules/entity_browser/src/Form/SelectionDisplayConfig.php
deleted file mode 100644
index fd1278d00bb78c1c04ea850f4f7d972b0eb39ae1..0000000000000000000000000000000000000000
--- a/web/modules/entity_browser/src/Form/SelectionDisplayConfig.php
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-
-namespace Drupal\entity_browser\Form;
-
-use Drupal\entity_browser\EntityBrowserInterface;
-
-/**
- * Selection display configuration step in entity browser form wizard.
- */
-class SelectionDisplayConfig extends PluginConfigFormBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormId() {
-    return 'entity_browser_selection_display_config_form';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getPlugin(EntityBrowserInterface $entity_browser) {
-    return $entity_browser->getSelectionDisplay();
-  }
-
-}
diff --git a/web/modules/entity_browser/src/Form/WidgetSelectorConfig.php b/web/modules/entity_browser/src/Form/WidgetSelectorConfig.php
deleted file mode 100644
index 2625ed0521900109025ae1da295d4edc5942162f..0000000000000000000000000000000000000000
--- a/web/modules/entity_browser/src/Form/WidgetSelectorConfig.php
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-
-namespace Drupal\entity_browser\Form;
-
-use Drupal\entity_browser\EntityBrowserInterface;
-
-/**
- * Widget selector configuration step in entity browser form wizard.
- */
-class WidgetSelectorConfig extends PluginConfigFormBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormId() {
-    return 'entity_browser_widget_selector_config_form';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getPlugin(EntityBrowserInterface $entity_browser) {
-    return $entity_browser->getWidgetSelector();
-  }
-
-}
diff --git a/web/modules/entity_browser/src/Form/WidgetsConfig.php b/web/modules/entity_browser/src/Form/WidgetsConfig.php
index a60d76d03c656f86fe40dfa16b387a9c86717465..cde1f70c22b3d8fdb6c5b6c8c8d3f2026abc8e76 100644
--- a/web/modules/entity_browser/src/Form/WidgetsConfig.php
+++ b/web/modules/entity_browser/src/Form/WidgetsConfig.php
@@ -2,15 +2,16 @@
 
 namespace Drupal\entity_browser\Form;
 
-use Drupal\Core\Form\FormBase;
+use Drupal\Core\Entity\EntityForm;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Messenger\MessengerInterface;
 use Drupal\entity_browser\WidgetManager;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
- * Widget configuration step in entity browser form wizard.
+ * Form for configuring widgets for entity browser.
  */
-class WidgetsConfig extends FormBase {
+class WidgetsConfig extends EntityForm {
 
   /**
    * Entity browser widget plugin manager.
@@ -24,9 +25,12 @@ class WidgetsConfig extends FormBase {
    *
    * @param \Drupal\entity_browser\WidgetManager $widget_manager
    *   Entity browser widget plugin manager.
+   * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+   *   The messenger.
    */
-  function __construct(WidgetManager $widget_manager) {
+  public function __construct(WidgetManager $widget_manager, MessengerInterface $messenger) {
     $this->widgetManager = $widget_manager;
+    $this->messenger = $messenger;
   }
 
   /**
@@ -34,7 +38,8 @@ function __construct(WidgetManager $widget_manager) {
    */
   public static function create(ContainerInterface $container) {
     return new static(
-      $container->get('plugin.manager.entity_browser.widget')
+      $container->get('plugin.manager.entity_browser.widget'),
+      $container->get('messenger')
     );
   }
 
@@ -49,16 +54,26 @@ public function getFormId() {
    * {@inheritdoc}
    */
   public function buildForm(array $form, FormStateInterface $form_state) {
+
     /** @var \Drupal\entity_browser\EntityBrowserInterface $entity_browser */
-    $entity_browser = $form_state->getTemporaryValue('wizard')['entity_browser'];
+    $entity_browser = $this->getEntity();
+
+    $options = [
+      '_none_' => '- ' . $this->t('Select a widget to add it') . ' -',
+    ];
+
+    $description = [
+      '#theme' => 'item_list',
+      '#list_type' => 'ul',
+      '#title' => $this->t('The available plugins are:'),
+      '#items' => [],
+      '#attributes' => ['class' => 'widget-description-list'],
+    ];
 
-    $widgets = [];
-    $description = $this->t('The available plugins are:') . '<ul>';
     foreach ($this->widgetManager->getDefinitions() as $plugin_id => $plugin_definition) {
-      $widgets[$plugin_id] = $plugin_definition['label'];
-      $description .= '<li><b>' . $plugin_definition['label'] . ':</b> ' . $plugin_definition['description'] . '</li>';
+      $options[$plugin_id] = $plugin_definition['label'];
+      $description['#items'][] = ['#markup' => '<strong>' . $plugin_definition['label'] . ':</strong> ' . $plugin_definition['description']];
     }
-    $description .= '</ul>';
     $default_widgets = [];
     foreach ($entity_browser->getWidgets() as $widget) {
       /** @var \Drupal\entity_browser\WidgetInterface $widget */
@@ -67,7 +82,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     $form['widget'] = [
       '#type' => 'select',
       '#title' => $this->t('Add widget plugin'),
-      '#options' => ['_none_' => '- ' . $this->t('Select a widget to add it') . ' -'] + $widgets,
+      '#options' => $options,
       '#description' => $description,
       '#ajax' => [
         'callback' => [get_class($this), 'tableUpdatedAjaxCallback'],
@@ -143,6 +158,12 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       ];
       $form['widgets']['table'][$uuid] = $row;
     }
+
+    $form['submit'] = [
+      '#type' => 'submit',
+      '#value' => t('Save'),
+    ];
+
     return $form;
   }
 
@@ -150,12 +171,9 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    * AJAX submit callback for adding widgets to the entity browser.
    */
   public static function submitAddWidget($form, FormStateInterface $form_state) {
-    $cached_values = $form_state->getTemporaryValue('wizard');
-    /** @var \Drupal\entity_browser\EntityBrowserInterface $entity_browser */
-    $entity_browser = $cached_values['entity_browser'];
-    $widgets_num = count($entity_browser->getWidgets());
+    $entity_browser = $form_state->getFormObject()->getEntity();
     $widget = $form_state->getValue('widget');
-    $weight = $widgets_num + 1;
+    $weight = count($entity_browser->getWidgets()) + 1;
     $entity_browser->addWidget([
       'id' => $widget,
       'label' => $widget,
@@ -163,9 +181,7 @@ public static function submitAddWidget($form, FormStateInterface $form_state) {
       // Configuration will be set on the widgets page.
       'settings' => [],
     ]);
-    \Drupal::service('user.shared_tempstore')
-      ->get('entity_browser.config')
-      ->set($entity_browser->id(), $cached_values);
+
     $form_state->setRebuild();
   }
 
@@ -173,13 +189,8 @@ public static function submitAddWidget($form, FormStateInterface $form_state) {
    * AJAX submit callback for removing widgets from the entity browser.
    */
   public static function submitDeleteWidget($form, FormStateInterface $form_state) {
-    $cached_values = $form_state->getTemporaryValue('wizard');
-    /** @var \Drupal\entity_browser\EntityBrowserInterface $entity_browser */
-    $entity_browser = $cached_values['entity_browser'];
+    $entity_browser = $form_state->getFormObject()->getEntity();
     $entity_browser->deleteWidget($entity_browser->getWidget($form_state->getTriggeringElement()['#arguments']));
-    \Drupal::service('user.shared_tempstore')
-      ->get('entity_browser.config')
-      ->set($entity_browser->id(), $cached_values);
     $form_state->setRebuild();
   }
 
@@ -194,8 +205,7 @@ public static function tableUpdatedAjaxCallback($form, $form_state) {
    * {@inheritdoc}
    */
   public function validateForm(array &$form, FormStateInterface $form_state) {
-    /** @var \Drupal\entity_browser\EntityBrowserInterface $entity_browser */
-    $entity_browser = $form_state->getTemporaryValue('wizard')['entity_browser'];
+    $entity_browser = $this->getEntity();
     /** @var \Drupal\entity_browser\WidgetInterface $widget */
     foreach ($entity_browser->getWidgets() as $widget) {
       $widget->validateConfigurationForm($form, $form_state);
@@ -206,8 +216,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    /** @var \Drupal\entity_browser\EntityBrowserInterface $entity_browser */
-    $entity_browser = $form_state->getTemporaryValue('wizard')['entity_browser'];
+    $entity_browser = $this->getEntity();
     $table = $form_state->getValue('table');
     /** @var \Drupal\entity_browser\WidgetInterface $widget */
     foreach ($entity_browser->getWidgets() as $uuid => $widget) {
@@ -215,6 +224,11 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       $widget->setWeight($table[$uuid]['weight']);
       $widget->setLabel($table[$uuid]['label']);
     }
+    $status = $entity_browser->save();
+
+    if ($status == SAVED_UPDATED) {
+      $this->messenger->addMessage($this->t('The entity browser %name has been updated.', ['%name' => $this->entity->label()]));
+    }
   }
 
 }
diff --git a/web/modules/entity_browser/src/Plugin/EntityBrowser/Display/IFrame.php b/web/modules/entity_browser/src/Plugin/EntityBrowser/Display/IFrame.php
index 11a78bb2bd4369d97cdd0e25fdb57362a455e42a..3eda8aa32ceb3473b7900f499a00fb6fe72755cf 100644
--- a/web/modules/entity_browser/src/Plugin/EntityBrowser/Display/IFrame.php
+++ b/web/modules/entity_browser/src/Plugin/EntityBrowser/Display/IFrame.php
@@ -16,9 +16,10 @@
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 use Drupal\Core\Path\CurrentPathStack;
-use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
 use Symfony\Component\HttpFoundation\Request;
+use Drupal\Core\Render\RendererInterface;
+use Drupal\Core\Render\BareHtmlPageRendererInterface;
 
 /**
  * Presents entity browser in an iFrame.
@@ -53,6 +54,20 @@ class IFrame extends DisplayBase implements DisplayRouterInterface {
    */
   protected $request;
 
+  /**
+   * The renderer service.
+   *
+   * @var \Drupal\Core\Render\RendererInterface
+   */
+  protected $renderer;
+
+  /**
+   * The bare HTML page renderer.
+   *
+   * @var \Drupal\Core\Render\BareHtmlPageRendererInterface
+   */
+  protected $bareHtmlPageRenderer;
+
   /**
    * Constructs display plugin.
    *
@@ -74,12 +89,18 @@ class IFrame extends DisplayBase implements DisplayRouterInterface {
    *   Current request.
    * @param \Drupal\Core\Path\CurrentPathStack $current_path
    *   The current path.
+   * @param \Drupal\Core\Render\RendererInterface $renderer
+   *   The renderer service.
+   * @param \Drupal\Core\Render\BareHtmlPageRendererInterface $bare_html_page_renderer
+   *   The bare HTML page renderer.
    */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, EventDispatcherInterface $event_dispatcher, UuidInterface $uuid, KeyValueStoreExpirableInterface $selection_storage, RouteMatchInterface $current_route_match, Request $request, CurrentPathStack $current_path) {
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, EventDispatcherInterface $event_dispatcher, UuidInterface $uuid, KeyValueStoreExpirableInterface $selection_storage, RouteMatchInterface $current_route_match, Request $request, CurrentPathStack $current_path, RendererInterface $renderer, BareHtmlPageRendererInterface $bare_html_page_renderer) {
     parent::__construct($configuration, $plugin_id, $plugin_definition, $event_dispatcher, $uuid, $selection_storage);
     $this->currentRouteMatch = $current_route_match;
     $this->request = $request;
     $this->currentPath = $current_path;
+    $this->renderer = $renderer;
+    $this->bareHtmlPageRenderer = $bare_html_page_renderer;
   }
 
   /**
@@ -95,7 +116,9 @@ public static function create(ContainerInterface $container, array $configuratio
       $container->get('entity_browser.selection_storage'),
       $container->get('current_route_match'),
       $container->get('request_stack')->getCurrentRequest(),
-      $container->get('path.current')
+      $container->get('path.current'),
+      $container->get('renderer'),
+      $container->get('bare_html_page_renderer')
     );
   }
 
@@ -155,6 +178,9 @@ public function displayEntityBrowser(array $element, FormStateInterface $form_st
           'library' => ['entity_browser/iframe'],
           'drupalSettings' => [
             'entity_browser' => [
+              $this->getUuid() => [
+                'auto_open' => $this->configuration['auto_open'],
+              ],
               'iframe' => [
                 $this->getUuid() => [
                   'src' => Url::fromRoute('entity_browser.' . $this->configuration['entity_browser_id'], [], $data['query_parameters'])
@@ -179,32 +205,27 @@ public function displayEntityBrowser(array $element, FormStateInterface $form_st
    * Intercepts default response and injects response that will trigger JS to
    * propagate selected entities upstream.
    *
-   * @param FilterResponseEvent $event
+   * @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event
    *   Response event.
    */
   public function propagateSelection(FilterResponseEvent $event) {
     $render = [
-      'labels' => [
-        '#markup' => 'Labels: ' . implode(', ', array_map(function (EntityInterface $item) {
-          return $item->label();
-        }, $this->entities)),
-        '#attached' => [
-          'library' => ['entity_browser/'. $this->pluginDefinition['id'] . '_selection'],
-          'drupalSettings' => [
-            'entity_browser' => [
-              $this->pluginDefinition['id'] => [
-                'entities' => array_map(function (EntityInterface $item) {
-                  return [$item->id(), $item->uuid(), $item->getEntityTypeId()];
-                }, $this->entities),
-                'uuid' => $this->request->query->get('uuid'),
-              ],
+      '#attached' => [
+        'library' => ['entity_browser/' . $this->pluginDefinition['id'] . '_selection'],
+        'drupalSettings' => [
+          'entity_browser' => [
+            $this->pluginDefinition['id'] => [
+              'entities' => array_map(function (EntityInterface $item) {
+                return [$item->id(), $item->uuid(), $item->getEntityTypeId()];
+              }, $this->entities),
+              'uuid' => $this->request->query->get('uuid'),
             ],
           ],
         ],
       ],
     ];
 
-    $event->setResponse(new Response(\Drupal::service('bare_html_page_renderer')->renderBarePage($render, 'Entity browser', 'page')));
+    $event->setResponse($this->bareHtmlPageRenderer->renderBarePage($render, $this->t('Entity browser'), 'page'));
   }
 
   /**
diff --git a/web/modules/entity_browser/src/Plugin/EntityBrowser/Display/Modal.php b/web/modules/entity_browser/src/Plugin/EntityBrowser/Display/Modal.php
index aeeac5f690598509707e67cfdf99abf8c0e97b32..01562b249fefb2885e6116f81c7268a91e276a77 100644
--- a/web/modules/entity_browser/src/Plugin/EntityBrowser/Display/Modal.php
+++ b/web/modules/entity_browser/src/Plugin/EntityBrowser/Display/Modal.php
@@ -71,6 +71,9 @@ public function displayEntityBrowser(array $element, FormStateInterface $form_st
           'library' => ['core/drupal.dialog.ajax', 'entity_browser/modal'],
           'drupalSettings' => [
             'entity_browser' => [
+              $this->getUuid() => [
+                'auto_open' => $this->configuration['auto_open'],
+              ],
               'modal' => [
                 $this->getUuid() => [
                   'uuid' => $this->getUuid(),
@@ -125,7 +128,7 @@ public function openModal(array &$form, FormStateInterface $form_state) {
     if (!empty($this->configuration['height']) && is_numeric($this->configuration['height']) && $this->configuration['height'] > 90) {
       $content['#attributes']['height'] = $this->configuration['height'] - 90;
     }
-    $html = drupal_render($content);
+    $html = $this->renderer->render($content);
 
     $response = new AjaxResponse();
     $response->addCommand(new OpenDialogCommand('#' . Html::getUniqueId($field_name . '-' . $element_name . '-dialog'), $this->configuration['link_text'], $html, [
@@ -137,6 +140,7 @@ public function openModal(array &$form, FormStateInterface $form_state) {
       'fluid' => 1,
       'autoResize' => 0,
       'resizable' => 0,
+      'classes' => ['ui-dialog' => 'entity-browser-modal'],
     ]));
     return $response;
   }
diff --git a/web/modules/entity_browser/src/Plugin/EntityBrowser/Display/Standalone.php b/web/modules/entity_browser/src/Plugin/EntityBrowser/Display/Standalone.php
index 84c8fced5995c0340ee7ab53311511f3068e2e08..47a5ab299c27e9aa7757cf4d21f24281543dae89 100644
--- a/web/modules/entity_browser/src/Plugin/EntityBrowser/Display/Standalone.php
+++ b/web/modules/entity_browser/src/Plugin/EntityBrowser/Display/Standalone.php
@@ -64,4 +64,15 @@ public function path() {
     return $this->configuration['path'];
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
+    $path = $form_state->getValue('path');
+
+    if ($path[0] != '/') {
+      $form_state->setError($form['path'], $this->t('The Path field must begin with a forward slash.'));
+    }
+  }
+
 }
diff --git a/web/modules/entity_browser/src/Plugin/EntityBrowser/FieldWidgetDisplay/EntityLabel.php b/web/modules/entity_browser/src/Plugin/EntityBrowser/FieldWidgetDisplay/EntityLabel.php
index 632170bfe7466d612457fcd288cee0dc474a47d4..3cb41c99187c81726af981eb521b17170bcefc64 100644
--- a/web/modules/entity_browser/src/Plugin/EntityBrowser/FieldWidgetDisplay/EntityLabel.php
+++ b/web/modules/entity_browser/src/Plugin/EntityBrowser/FieldWidgetDisplay/EntityLabel.php
@@ -4,6 +4,10 @@
 
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\entity_browser\FieldWidgetDisplayBase;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Drupal\Core\Entity\EntityRepositoryInterface;
 
 /**
  * Displays a label of the entity.
@@ -14,13 +18,61 @@
  *   description = @Translation("Displays entity with a label.")
  * )
  */
-class EntityLabel extends FieldWidgetDisplayBase {
+class EntityLabel extends FieldWidgetDisplayBase implements ContainerFactoryPluginInterface {
+
+  /**
+   * The entity repository.
+   *
+   * @var \Drupal\Core\Entity\EntityRepositoryInterface
+   */
+  protected $entityRepository;
+
+  /**
+   * Constructs entity label plugin.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param Drupal\Core\Entity\EntityRepositoryInterface $entity_repository
+   *   The entity repository.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityRepositoryInterface $entity_repository) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+    $this->entityRepository = $entity_repository;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('entity.repository')
+    );
+  }
 
   /**
    * {@inheritdoc}
    */
   public function view(EntityInterface $entity) {
-    return $entity->label();
+    $translation = $this->entityRepository->getTranslationFromContext($entity);
+    return $translation->label();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, FormStateInterface $form_state) {
+    return [
+      '#prefix' => '<p>',
+      '#suffix' => '</p>',
+      '#markup' => $this->t('This plugin has no configuration options.'),
+    ];
   }
 
 }
diff --git a/web/modules/entity_browser/src/Plugin/EntityBrowser/FieldWidgetDisplay/ImageThumbnail.php b/web/modules/entity_browser/src/Plugin/EntityBrowser/FieldWidgetDisplay/ImageThumbnail.php
index 3519803a59c776a08b89167a619aa42501426ad0..9ecca60e981c49383f74ec6f6d1547cc48c807b8 100644
--- a/web/modules/entity_browser/src/Plugin/EntityBrowser/FieldWidgetDisplay/ImageThumbnail.php
+++ b/web/modules/entity_browser/src/Plugin/EntityBrowser/FieldWidgetDisplay/ImageThumbnail.php
@@ -95,7 +95,7 @@ public function settingsForm(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function isApplicable(EntityTypeInterface $entity_type) {
-    return $entity_type->isSubclassOf(FileInterface::class);
+    return $entity_type->entityClassImplements(FileInterface::class);
   }
 
   /**
diff --git a/web/modules/entity_browser/src/Plugin/EntityBrowser/FieldWidgetDisplay/RenderedEntity.php b/web/modules/entity_browser/src/Plugin/EntityBrowser/FieldWidgetDisplay/RenderedEntity.php
index 618b1bce830200433135518f0eaf4c75bb8566e9..fb43de237cecc9ec97733a1367dfbbefbbfc90a1 100644
--- a/web/modules/entity_browser/src/Plugin/EntityBrowser/FieldWidgetDisplay/RenderedEntity.php
+++ b/web/modules/entity_browser/src/Plugin/EntityBrowser/FieldWidgetDisplay/RenderedEntity.php
@@ -72,7 +72,28 @@ public static function create(ContainerInterface $container, array $configuratio
    * {@inheritdoc}
    */
   public function view(EntityInterface $entity) {
-    return $this->entityTypeManager->getViewBuilder($this->configuration['entity_type'])->view($entity, $this->configuration['view_mode']);
+    $build = $this->entityTypeManager->getViewBuilder($this->configuration['entity_type'])
+      ->view($entity, $this->configuration['view_mode']);
+
+    $build['#entity_browser_suppress_contextual'] = TRUE;
+    $build['#cache']['keys'][] = 'entity_browser';
+
+    return $build;
+  }
+
+  /**
+   * Get the label from the view mode.
+   *
+   * @return string
+   *   View mode label.
+   */
+  public function getViewModeLabel() {
+    if (!empty($this->configuration['entity_type']) && !empty($this->configuration['view_mode'])) {
+      $view_modes = $this->entityDisplayRepository->getViewModeOptions($this->configuration['entity_type']);
+      return $view_modes[$this->configuration['view_mode']];
+    }
+
+    return $this->t('Default');
   }
 
   /**
diff --git a/web/modules/entity_browser/src/Plugin/EntityBrowser/SelectionDisplay/MultiStepDisplay.php b/web/modules/entity_browser/src/Plugin/EntityBrowser/SelectionDisplay/MultiStepDisplay.php
index 17f5cf327d3f6ddd5f4a8e03f6d4a22a395e4136..88c57c315bfaae4027e039b89adf84299f99faa6 100644
--- a/web/modules/entity_browser/src/Plugin/EntityBrowser/SelectionDisplay/MultiStepDisplay.php
+++ b/web/modules/entity_browser/src/Plugin/EntityBrowser/SelectionDisplay/MultiStepDisplay.php
@@ -157,7 +157,7 @@ public function getForm(array &$original_form, FormStateInterface $form_state) {
 
     $form['use_selected'] = [
       '#type' => 'submit',
-      '#value' => $this->t($this->configuration['select_text']),
+      '#value' => $this->configuration['select_text'],
       '#name' => 'use_selected',
       '#attributes' => [
         'class' => ['entity-browser-use-selected', 'button--primary'],
@@ -391,7 +391,7 @@ public function submit(array &$form, FormStateInterface $form_state) {
   /**
    * Saves new ordering of entities based on weight.
    *
-   * @param FormStateInterface $form_state
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
    *   Form state.
    */
   public static function saveNewOrder(FormStateInterface $form_state) {
@@ -420,23 +420,26 @@ public static function saveNewOrder(FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
-    $default_entity_type = $form_state->getValue('entity_type', $this->configuration['entity_type']);
-    $default_display = $form_state->getValue('display', $this->configuration['display']);
-    $default_display_settings = $form_state->getValue('display_settings', $this->configuration['display_settings']);
-    $default_display_settings += ['entity_type' => $default_entity_type];
 
-    if ($form_state->isRebuilding()) {
-      $form['#prefix'] = '<div id="multi-step-form-wrapper">';
-    } else {
-      $form['#prefix'] .= '<div id="multi-step-form-wrapper">';
-    }
-    $form['#suffix'] = '</div>';
+    $entity_browser = $form_state->getFormObject()->getEntity();
+
+    $defaults = $entity_browser->getSelectionDisplay()->getConfiguration();
+
+    $default_entity_type = $defaults['entity_type'];
+    $default_display = $defaults['display'];
+    $default_display_settings = $defaults['display_settings'];
+    $default_display_settings += ['entity_type' => $default_entity_type];
 
     $entity_types = [];
     foreach ($this->entityTypeManager->getDefinitions() as $entity_type_id => $entity_type) {
       /** @var \Drupal\Core\Entity\EntityTypeInterface $entity_type */
       $entity_types[$entity_type_id] = $entity_type->getLabel();
     }
+
+    $form['multi_step_form_wrapper'] = [
+      '#type' => 'container',
+    ];
+
     $form['entity_type'] = [
       '#type' => 'select',
       '#title' => $this->t('Entity type'),
@@ -445,7 +448,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
       '#options' => $entity_types,
       '#ajax' => [
         'callback' => [$this, 'updateSettingsAjax'],
-        'wrapper' => 'multi-step-form-wrapper',
+        'wrapper' => 'selection-display-config-ajax-wrapper',
       ],
     ];
 
@@ -463,7 +466,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
       '#options' => $displays,
       '#ajax' => [
         'callback' => [$this, 'updateSettingsAjax'],
-        'wrapper' => 'multi-step-form-wrapper',
+        'wrapper' => 'selection-display-config-ajax-wrapper',
       ],
     ];
 
@@ -481,14 +484,14 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
     $form['select_text'] = [
       '#type' => 'textfield',
       '#title' => $this->t('Select button text'),
-      '#default_value' => $this->configuration['select_text'],
+      '#default_value' => $defaults['select_text'],
       '#description' => $this->t('Text to display on the entity browser select button.'),
     ];
 
     $form['selection_hidden'] = [
       '#type' => 'checkbox',
       '#title' => $this->t('Selection hidden by default'),
-      '#default_value' => $this->configuration['selection_hidden'],
+      '#default_value' => $defaults['selection_hidden'],
       '#description' => $this->t('Whether or not the selection should be hidden by default.'),
     ];
 
@@ -496,10 +499,11 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
   }
 
   /**
-   * Ajax callback that updates multi-step plugin configuration form on AJAX updates.
+   * Ajax callback that updates multi-step plugin configuration form.
    */
   public function updateSettingsAjax(array $form, FormStateInterface $form_state) {
-    return $form;
+    $form['selection_display_wrapper']['selection_display_configuration']['#open'] = TRUE;
+    return $form['selection_display_wrapper']['selection_display_configuration'];
   }
 
 }
diff --git a/web/modules/entity_browser/src/Plugin/EntityBrowser/SelectionDisplay/View.php b/web/modules/entity_browser/src/Plugin/EntityBrowser/SelectionDisplay/View.php
index 6d43421c3fd8c7ab93df27be296d467e532cc1d8..1542d7f31c9174d428bc27c63478c6bb6e837339 100644
--- a/web/modules/entity_browser/src/Plugin/EntityBrowser/SelectionDisplay/View.php
+++ b/web/modules/entity_browser/src/Plugin/EntityBrowser/SelectionDisplay/View.php
@@ -38,8 +38,9 @@ public function defaultConfiguration() {
   public function getForm(array &$original_form, FormStateInterface $form_state) {
     $form = [];
 
-    // TODO - do we need better error handling for view and view_display (in case
-    // either of those is nonexistent or display not of correct type)?
+    // TODO - do we need better error handling for view and view_display
+    // (in case either of those is nonexistent
+    // or display not of correct type)?
     $storage = &$form_state->getStorage();
     if (empty($storage['selection_display_view']) || $form_state->isRebuilding()) {
       $storage['selection_display_view'] = $this->entityTypeManager
@@ -48,9 +49,9 @@ public function getForm(array &$original_form, FormStateInterface $form_state) {
         ->getExecutable();
     }
 
-    // TODO - if there are entities that are selected multiple times this displays
-    // them only once. Reason for that is how SQL and Views work and we probably
-    // can't do much about it.
+    // TODO - if there are entities that are selected multiple times this
+    // displays them only once. Reason for that is how SQL and Views work and
+    // we probably can't do much about it.
     $selected_entities = $form_state->get(['entity_browser', 'selected_entities']);
     if (!empty($selected_entities)) {
       $ids = array_map(function (EntityInterface $item) {
@@ -99,7 +100,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
       '#default_value' => $this->configuration['view'] . '.' . $this->configuration['view_display'],
       '#options' => $options,
       '#required' => TRUE,
-      '#description' => $this->t('View display to use for displaying currently selected items. Do note that to get something usefull out of this display, its first contextual filter should be a filter on the primary identifier field of your entity type (e.g., Node ID, Media ID).'),
+      '#description' => $this->t('View display to use for displaying currently selected items. Do note that to get something useful out of this display, its first contextual filter should be a filter on the primary identifier field of your entity type (e.g., Node ID, Media ID).'),
     ];
 
     return $form;
diff --git a/web/modules/entity_browser/src/Plugin/EntityBrowser/Widget/Upload.php b/web/modules/entity_browser/src/Plugin/EntityBrowser/Widget/Upload.php
index c6b2eb646bf7a4578ba637909d0ff6fac7bfd13c..a0b7edfd612bd46468ed8f27a02b008f447afdde 100644
--- a/web/modules/entity_browser/src/Plugin/EntityBrowser/Widget/Upload.php
+++ b/web/modules/entity_browser/src/Plugin/EntityBrowser/Widget/Upload.php
@@ -14,7 +14,7 @@
 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 
 /**
- * Uses a view to provide entity listing in a browser's widget.
+ * Adds an upload field browser's widget.
  *
  * @EntityBrowserWidget(
  *   id = "upload",
diff --git a/web/modules/entity_browser/src/Plugin/EntityBrowser/Widget/View.php b/web/modules/entity_browser/src/Plugin/EntityBrowser/Widget/View.php
index f0aaa19e30ff6d5fc56f8511287af34b6d0d4cc5..51b7ba227d26d914550f96ce08aa6d377cc92cf0 100644
--- a/web/modules/entity_browser/src/Plugin/EntityBrowser/Widget/View.php
+++ b/web/modules/entity_browser/src/Plugin/EntityBrowser/Widget/View.php
@@ -3,6 +3,7 @@
 namespace Drupal\entity_browser\Plugin\EntityBrowser\Widget;
 
 use Drupal\Component\Plugin\Exception\PluginNotFoundException;
+use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Render\Element;
 use Drupal\entity_browser\WidgetBase;
@@ -89,8 +90,8 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition
    */
   public function getForm(array &$original_form, FormStateInterface $form_state, array $additional_widget_parameters) {
     $form = parent::getForm($original_form, $form_state, $additional_widget_parameters);
-    // TODO - do we need better error handling for view and view_display (in case
-    // either of those is nonexistent or display not of correct type)?
+    // TODO - do we need better error handling for view and view_display (in
+    // case either of those is nonexistent or display not of correct type)?
     $form['#attached']['library'] = ['entity_browser/view'];
 
     /** @var \Drupal\views\ViewExecutable $view */
@@ -99,13 +100,6 @@ public function getForm(array &$original_form, FormStateInterface $form_state, a
       ->load($this->configuration['view'])
       ->getExecutable();
 
-    // Check if the current user has access to this view.
-    if (!$view->access($this->configuration['view_display'])) {
-      return [
-        '#markup' => $this->t('You do not have access to this View.'),
-      ];
-    }
-
     if (!empty($this->configuration['arguments'])) {
       if (!empty($additional_widget_parameters['path_parts'])) {
         $arguments = [];
@@ -135,7 +129,7 @@ public function getForm(array &$original_form, FormStateInterface $form_state, a
 
     // When rebuilding makes no sense to keep checkboxes that were previously
     // selected.
-    if (!empty($form['view']['entity_browser_select']) && $form_state->isRebuilding()) {
+    if (!empty($form['view']['entity_browser_select'])) {
       foreach (Element::children($form['view']['entity_browser_select']) as $child) {
         $form['view']['entity_browser_select'][$child]['#process'][] = ['\Drupal\entity_browser\Plugin\EntityBrowser\Widget\View', 'processCheckbox'];
         $form['view']['entity_browser_select'][$child]['#process'][] = ['\Drupal\Core\Render\Element\Checkbox', 'processAjaxForm'];
@@ -158,7 +152,10 @@ public function getForm(array &$original_form, FormStateInterface $form_state, a
    * @see \Drupal\Core\Render\Element\Checkbox::processCheckbox()
    */
   public static function processCheckbox(&$element, FormStateInterface $form_state, &$complete_form) {
-    $element['#checked'] = FALSE;
+    if ($form_state->isRebuilding()) {
+      $element['#checked'] = FALSE;
+    }
+
     return $element;
   }
 
@@ -168,7 +165,22 @@ public static function processCheckbox(&$element, FormStateInterface $form_state
   public function validate(array &$form, FormStateInterface $form_state) {
     $user_input = $form_state->getUserInput();
     if (isset($user_input['entity_browser_select'])) {
-      $selected_rows = array_values(array_filter($user_input['entity_browser_select']));
+      if (is_array($user_input['entity_browser_select'])) {
+        $selected_rows = array_values(array_filter($user_input['entity_browser_select']));
+      }
+      else {
+        $selected_rows = [$user_input['entity_browser_select']];
+      }
+
+      $use_field_cardinality = !empty($user_input['entity_browser_select_form_metadata']['use_field_cardinality']);
+      if ($use_field_cardinality) {
+        $cardinality = !empty($user_input['entity_browser_select_form_metadata']['cardinality']) ? $user_input['entity_browser_select_form_metadata']['cardinality'] : 0;
+        if ($cardinality > 0 && count($selected_rows) > $cardinality) {
+          $message = $this->formatPlural($cardinality, 'You can only select one item.', 'You can only select up to @number items.', ['@number' => $cardinality]);
+          $form_state->setError($form['widget']['view']['entity_browser_select'], $message);
+        }
+      }
+
       foreach ($selected_rows as $row) {
         // Verify that the user input is a string and split it.
         // Each $row is in the format entity_type:id.
@@ -206,13 +218,22 @@ public function validate(array &$form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   protected function prepareEntities(array $form, FormStateInterface $form_state) {
-    $selected_rows = array_values(array_filter($form_state->getUserInput()['entity_browser_select']));
+    if (is_array($form_state->getUserInput()['entity_browser_select'])) {
+      $selected_rows = array_values(array_filter($form_state->getUserInput()['entity_browser_select']));
+    }
+    else {
+      $selected_rows = [$form_state->getUserInput()['entity_browser_select']];
+    }
+
     $entities = [];
     foreach ($selected_rows as $row) {
-      list($type, $id) = explode(':', $row);
-      $storage = $this->entityTypeManager->getStorage($type);
-      if ($entity = $storage->load($id)) {
-        $entities[] = $entity;
+      $item = explode(':', $row);
+      if (count($item) == 2) {
+        list($type, $id) = $item;
+        $storage = $this->entityTypeManager->getStorage($type);
+        if ($entity = $storage->load($id)) {
+          $entities[] = $entity;
+        }
       }
     }
     return $entities;
@@ -279,4 +300,19 @@ public function calculateDependencies() {
     return $dependencies;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function access() {
+    // Mark the widget as not visible if the user has no access to the view.
+    /** @var \Drupal\views\ViewExecutable $view */
+    $view = $this->entityTypeManager
+      ->getStorage('view')
+      ->load($this->configuration['view'])
+      ->getExecutable();
+
+    // Check if the current user has access to this view.
+    return AccessResult::allowedIf($view->access($this->configuration['view_display']));
+  }
+
 }
diff --git a/web/modules/entity_browser/src/Plugin/EntityBrowser/WidgetSelector/DropDown.php b/web/modules/entity_browser/src/Plugin/EntityBrowser/WidgetSelector/DropDown.php
index d5d32d5185cebd1deb5440c969f68a6d0f2872d8..497cbacb8233a6ac1dca9407be8907e2bb895fcf 100644
--- a/web/modules/entity_browser/src/Plugin/EntityBrowser/WidgetSelector/DropDown.php
+++ b/web/modules/entity_browser/src/Plugin/EntityBrowser/WidgetSelector/DropDown.php
@@ -24,9 +24,19 @@ public function getForm(array &$form = [], FormStateInterface &$form_state = NUL
     $form['#prefix'] = '<div id="entity-browser-form">';
     $form['#suffix'] = '</div>';
 
+    /** @var \Drupal\entity_browser\EntityBrowserInterface $browser */
+    $browser = $form_state->getFormObject()->getEntityBrowser();
+
+    $widget_ids = [];
+    foreach ($this->widget_ids as $widget_id => $widget_name) {
+      if ($browser->getWidget($widget_id)->access()->isAllowed()) {
+        $widget_ids[$widget_id] = $widget_name;
+      }
+    }
+
     $element['widget'] = [
       '#type' => 'select',
-      '#options' => $this->widget_ids,
+      '#options' => $widget_ids,
       '#default_value' => $this->getDefaultWidget(),
       '#executes_submit_callback' => TRUE,
       '#limit_validation_errors' => [['widget']],
@@ -60,7 +70,7 @@ public function submit(array &$form, FormStateInterface $form_state) {
    *
    * @param array $form
    *   Form.
-   * @param FormStateInterface $form_state
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
    *   Form state object.
    *
    * @return array
diff --git a/web/modules/entity_browser/src/Plugin/EntityBrowser/WidgetSelector/Tabs.php b/web/modules/entity_browser/src/Plugin/EntityBrowser/WidgetSelector/Tabs.php
index e6d511d446fb9b869157c838942c97eea63e9299..0128b2907d0d96f8507f01be52c9dcdd93ce2445 100644
--- a/web/modules/entity_browser/src/Plugin/EntityBrowser/WidgetSelector/Tabs.php
+++ b/web/modules/entity_browser/src/Plugin/EntityBrowser/WidgetSelector/Tabs.php
@@ -21,6 +21,8 @@ class Tabs extends WidgetSelectorBase {
    */
   public function getForm(array &$form = [], FormStateInterface &$form_state = NULL) {
     $element = [];
+    /** @var \Drupal\entity_browser\EntityBrowserInterface $browser */
+    $browser = $form_state->getFormObject()->getEntityBrowser();
     foreach ($this->widget_ids as $id => $label) {
       $name = 'tab_selector_' . $id;
       $element[$name] = [
@@ -34,6 +36,7 @@ public function getForm(array &$form = [], FormStateInterface &$form_state = NUL
         '#submit' => [],
         '#name' => $name,
         '#widget_id' => $id,
+        '#access' => $browser->getWidget($id)->access(),
       ];
     }
 
diff --git a/web/modules/entity_browser/src/Plugin/EntityBrowser/WidgetValidation/Cardinality.php b/web/modules/entity_browser/src/Plugin/EntityBrowser/WidgetValidation/Cardinality.php
index 617ddd43c7ab00eb398ec9f269d2ed096d8e7e51..e26d3f6ec2a1666eeab9a0d06c56d21615374be9 100644
--- a/web/modules/entity_browser/src/Plugin/EntityBrowser/WidgetValidation/Cardinality.php
+++ b/web/modules/entity_browser/src/Plugin/EntityBrowser/WidgetValidation/Cardinality.php
@@ -20,7 +20,7 @@ class Cardinality extends WidgetValidationBase {
   /**
    * {@inheritdoc}
    */
-  public function validate(array $entities, $options = []) {
+  public function validate(array $entities, array $options = []) {
     $violations = new ConstraintViolationList();
 
     // As this validation happens at a level above the individual entities,
@@ -28,7 +28,7 @@ public function validate(array $entities, $options = []) {
     $count = count($entities);
     $max = $options['cardinality'];
     if ($max !== EntityBrowserElement::CARDINALITY_UNLIMITED && $count > $max) {
-      $message = $this->formatPlural($max, 'You can not select more than 1 entity.', 'You can not select more than @count entities.');
+      $message = $this->formatPlural($max, 'You can only select one item.', 'You can only select up to @number items.', ['@number' => $max]);
       $violation = new ConstraintViolation($message, $message, [], $count, '', $count);
       $violations->add($violation);
     }
diff --git a/web/modules/entity_browser/src/Plugin/EntityBrowser/WidgetValidation/File.php b/web/modules/entity_browser/src/Plugin/EntityBrowser/WidgetValidation/File.php
index 244f1d881f685cda998943f20bd7484b84595ced..c5e48c85825a399db17d2b800c509c8d552e617a 100644
--- a/web/modules/entity_browser/src/Plugin/EntityBrowser/WidgetValidation/File.php
+++ b/web/modules/entity_browser/src/Plugin/EntityBrowser/WidgetValidation/File.php
@@ -19,7 +19,7 @@ class File extends WidgetValidationBase {
   /**
    * {@inheritdoc}
    */
-  public function validate(array $entities, $options = []) {
+  public function validate(array $entities, array $options = []) {
     $violations = new ConstraintViolationList();
 
     // We implement the same logic as \Drupal\file\Plugin\Validation\Constraint\FileValidationConstraintValidator
diff --git a/web/modules/entity_browser/src/Plugin/Field/FieldWidget/EntityReferenceBrowserWidget.php b/web/modules/entity_browser/src/Plugin/Field/FieldWidget/EntityReferenceBrowserWidget.php
index c2096b55619ba46b8387a322a7915b4d06b9ebb1..0901eba5f30ded9efe408dbd78069e1227c1d897 100644
--- a/web/modules/entity_browser/src/Plugin/Field/FieldWidget/EntityReferenceBrowserWidget.php
+++ b/web/modules/entity_browser/src/Plugin/Field/FieldWidget/EntityReferenceBrowserWidget.php
@@ -4,6 +4,7 @@
 
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\entity_browser\Element\EntityBrowserElement;
+use Drupal\entity_browser\Entity\EntityBrowser;
 use Symfony\Component\Validator\ConstraintViolationInterface;
 use Drupal\Component\Utility\Html;
 use Drupal\Component\Utility\NestedArray;
@@ -18,11 +19,11 @@
 use Drupal\Core\Validation\Plugin\Validation\Constraint\NotNullConstraint;
 use Drupal\entity_browser\FieldWidgetDisplayManager;
 use Symfony\Component\DependencyInjection\ContainerInterface;
-use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 use Symfony\Component\Validator\ConstraintViolation;
 use Symfony\Component\Validator\ConstraintViolationListInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Session\AccountInterface;
+use Drupal\Core\Messenger\MessengerInterface;
 
 /**
  * Plugin implementation of the 'entity_reference' widget for entity browser.
@@ -91,21 +92,22 @@ class EntityReferenceBrowserWidget extends WidgetBase implements ContainerFactor
    *   Any third party settings.
    * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
    *   Entity type manager service.
-   * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
-   *   Event dispatcher.
    * @param \Drupal\entity_browser\FieldWidgetDisplayManager $field_display_manager
    *   Field widget display plugin manager.
    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
    *   The module handler service.
    * @param \Drupal\Core\Session\AccountInterface $current_user
    *   The current user.
+   * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+   *   The messenger.
    */
-  public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings, EntityTypeManagerInterface $entity_type_manager, EventDispatcherInterface $event_dispatcher, FieldWidgetDisplayManager $field_display_manager, ModuleHandlerInterface $module_handler, AccountInterface $current_user) {
+  public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings, EntityTypeManagerInterface $entity_type_manager, FieldWidgetDisplayManager $field_display_manager, ModuleHandlerInterface $module_handler, AccountInterface $current_user, MessengerInterface $messenger) {
     parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $third_party_settings);
     $this->entityTypeManager = $entity_type_manager;
     $this->fieldDisplayManager = $field_display_manager;
     $this->moduleHandler = $module_handler;
     $this->currentUser = $current_user;
+    $this->messenger = $messenger;
   }
 
   /**
@@ -119,10 +121,10 @@ public static function create(ContainerInterface $container, array $configuratio
       $configuration['settings'],
       $configuration['third_party_settings'],
       $container->get('entity_type.manager'),
-      $container->get('event_dispatcher'),
       $container->get('plugin.manager.entity_browser.field_widget_display'),
       $container->get('module_handler'),
-      $container->get('current_user')
+      $container->get('current_user'),
+      $container->get('messenger')
     );
   }
 
@@ -136,6 +138,7 @@ public static function defaultSettings() {
       'field_widget_display' => 'label',
       'field_widget_edit' => TRUE,
       'field_widget_remove' => TRUE,
+      'field_widget_replace' => FALSE,
       'field_widget_display_settings' => [],
       'selection_mode' => EntityBrowserElement::SELECTION_MODE_APPEND,
     ] + parent::defaultSettings();
@@ -170,18 +173,57 @@ public function settingsForm(array $form, FormStateInterface $form_state) {
       }
     }
 
-    $id = Html::getUniqueId('field-' . $this->fieldDefinition->getName() . '-display-settings-wrapper');
+    $id = Html::getId($this->fieldDefinition->getName()) . '-field-widget-display-settings-ajax-wrapper-' . md5($this->fieldDefinition->getUniqueIdentifier());
     $element['field_widget_display'] = [
       '#title' => $this->t('Entity display plugin'),
-      '#type' => 'select',
+      '#type' => 'radios',
       '#default_value' => $this->getSetting('field_widget_display'),
       '#options' => $displays,
       '#ajax' => [
-        'callback' => [$this, 'updateSettingsAjax'],
+        'callback' => [get_class($this), 'updateFieldWidgetDisplaySettings'],
         'wrapper' => $id,
       ],
+      '#limit_validation_errors' => [],
     ];
 
+    if ($this->getSetting('field_widget_display')) {
+      $element['field_widget_display_settings'] = [
+        '#type' => 'details',
+        '#title' => $this->t('Entity display plugin configuration'),
+        '#open' => TRUE,
+        '#prefix' => '<div id="' . $id . '">',
+        '#suffix' => '</div>',
+        '#tree' => TRUE,
+      ];
+
+      $element['field_widget_display_settings'] += $this->fieldDisplayManager
+        ->createInstance(
+          $form_state->getValue(
+            [
+              'fields',
+              $this->fieldDefinition->getName(),
+              'settings_edit_form',
+              'settings',
+              'field_widget_display',
+            ],
+            $this->getSetting('field_widget_display')
+          ),
+          $form_state->getValue(
+            [
+              'fields',
+              $this->fieldDefinition->getName(),
+              'settings_edit_form',
+              'settings',
+              'field_widget_display_settings',
+            ],
+            $this->getSetting('field_widget_display_settings')
+          ) + [
+            'entity_type' => $this->fieldDefinition->getFieldStorageDefinition()->getSetting('target_type'),
+          ]
+        )
+        ->settingsForm($form, $form_state);
+    }
+
     $edit_button_access = TRUE;
     if ($entity_type->id() == 'file') {
       // For entities of type "file", it only makes sense to have the edit
@@ -201,6 +243,13 @@ public function settingsForm(array $form, FormStateInterface $form_state) {
       '#default_value' => $this->getSetting('field_widget_remove'),
     ];
 
+    $element['field_widget_replace'] = [
+      '#title' => $this->t('Display Replace button'),
+      '#description' => $this->t('This button will only be displayed if there is a single entity in the current selection.'),
+      '#type' => 'checkbox',
+      '#default_value' => $this->getSetting('field_widget_replace'),
+    ];
+
     $element['open'] = [
       '#title' => $this->t('Show widget details as open by default'),
       '#description' => $this->t('If marked, the fieldset container that wraps the browser on the entity form will be loaded initially expanded.'),
@@ -216,37 +265,41 @@ public function settingsForm(array $form, FormStateInterface $form_state) {
       '#default_value' => $this->getSetting('selection_mode'),
     ];
 
-    $element['field_widget_display_settings'] = [
-      '#type' => 'fieldset',
-      '#title' => $this->t('Entity display plugin configuration'),
-      '#tree' => TRUE,
-      '#prefix' => '<div id="' . $id . '">',
-      '#suffix' => '</div>',
-    ];
-
-    if ($this->getSetting('field_widget_display')) {
-      $element['field_widget_display_settings'] += $this->fieldDisplayManager
-        ->createInstance(
-          $form_state->getValue(
-            ['fields', $this->fieldDefinition->getName(), 'settings_edit_form', 'settings', 'field_widget_display'],
-            $this->getSetting('field_widget_display')
-          ),
-          $form_state->getValue(
-            ['fields', $this->fieldDefinition->getName(), 'settings_edit_form', 'settings', 'field_widget_display_settings'],
-            $this->getSetting('field_widget_display_settings')
-          ) + ['entity_type' => $this->fieldDefinition->getFieldStorageDefinition()->getSetting('target_type')]
-        )
-        ->settingsForm($form, $form_state);
-    }
+    $element['#element_validate'] = [[get_class($this), 'validateSettingsForm']];
 
     return $element;
   }
 
+  /**
+   * Validate the settings form.
+   */
+  public static function validateSettingsForm($element, FormStateInterface $form_state, $form) {
+
+    $values = NestedArray::getValue($form_state->getValues(), $element['#parents']);
+
+    if ($values['selection_mode'] == 'selection_edit') {
+      /** @var \Drupal\entity_browser\Entity\EntityBrowser $entity_browser */
+      $entity_browser = EntityBrowser::load($values['entity_browser']);
+      if ($entity_browser->getSelectionDisplay()->supportsPreselection() === FALSE) {
+        $tparams = [
+          '%selection_mode' => EntityBrowserElement::getSelectionModeOptions()[EntityBrowserElement::SELECTION_MODE_EDIT],
+          '@browser_link' => $entity_browser->toLink($entity_browser->label(), 'edit-form')->toString(),
+        ];
+        $form_state->setError($element['entity_browser']);
+        $form_state->setError($element['selection_mode'], t('The selection mode %selection_mode requires an entity browser with a selection display plugin that supports preselection.  Either change the selection mode or update the @browser_link entity browser to use a selection display plugin that supports preselection.', $tparams));
+      }
+    }
+  }
+
   /**
    * Ajax callback that updates field widget display settings fieldset.
    */
-  public function updateSettingsAjax(array $form, FormStateInterface $form_state) {
-    return $form['fields'][$this->fieldDefinition->getName()]['plugin']['settings_edit_form']['settings']['field_widget_display_settings'];
+  public static function updateFieldWidgetDisplaySettings(array $form, FormStateInterface $form_state) {
+    $array_parents = $form_state->getTriggeringElement()['#array_parents'];
+    $up_two_levels = array_slice($array_parents, 0, count($array_parents) - 2);
+    $settings_path = array_merge($up_two_levels, ['field_widget_display_settings']);
+    $settingsElement = NestedArray::getValue($form, $settings_path);
+    return $settingsElement;
   }
 
   /**
@@ -257,8 +310,17 @@ public function settingsSummary() {
     $field_widget_display = $this->getSetting('field_widget_display');
 
     if (!empty($field_widget_display)) {
-      $plugin = $this->fieldDisplayManager->getDefinition($field_widget_display);
-      $summary[] = $this->t('Entity display: @name', ['@name' => $plugin['label']]);
+      $pluginDefinition = $this->fieldDisplayManager->getDefinition($field_widget_display);
+      $field_widget_display_settings = $this->getSetting('field_widget_display_settings');
+      $field_widget_display_settings += [
+        'entity_type' => $this->fieldDefinition->getFieldStorageDefinition()->getSetting('target_type'),
+      ];
+      $plugin = $this->fieldDisplayManager->createInstance($field_widget_display, $field_widget_display_settings);
+      $summary[] = $this->t('Entity display: @name', ['@name' => $pluginDefinition['label']]);
+      if ($field_widget_display == 'rendered_entity') {
+        $view_mode_label = $plugin->getViewModeLabel();
+        $summary[] = $this->t('View Mode: @view_mode', ['@view_mode' => $view_mode_label]);
+      }
     }
     return $summary;
   }
@@ -310,7 +372,7 @@ protected function getFormStateKey(FieldItemListInterface $items) {
    * {@inheritdoc}
    */
   public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
-    $entity_type = $this->fieldDefinition->getFieldStorageDefinition()->getSetting('target_type');
+
     $entities = $this->formElementEntities($items, $element, $form_state);
 
     // Get correct ordered list of entity IDs.
@@ -420,18 +482,29 @@ public function massageFormValues(array $values, array $form, FormStateInterface
    */
   public static function updateWidgetCallback(array &$form, FormStateInterface $form_state) {
     $trigger = $form_state->getTriggeringElement();
+    $reopen_browser = FALSE;
     // AJAX requests can be triggered by hidden "target_id" element when
     // entities are added or by one of the "Remove" buttons. Depending on that
     // we need to figure out where root of the widget is in the form structure
     // and use this information to return correct part of the form.
+    $parents = [];
     if (!empty($trigger['#ajax']['event']) && $trigger['#ajax']['event'] == 'entity_browser_value_updated') {
       $parents = array_slice($trigger['#array_parents'], 0, -1);
     }
     elseif ($trigger['#type'] == 'submit' && strpos($trigger['#name'], '_remove_')) {
       $parents = array_slice($trigger['#array_parents'], 0, -static::$deleteDepth);
     }
+    elseif ($trigger['#type'] == 'submit' && strpos($trigger['#name'], '_replace_')) {
+      $parents = array_slice($trigger['#array_parents'], 0, -static::$deleteDepth);
+      // We need to re-open the browser. Instead of just passing "TRUE", send
+      // to the JS the unique part of the button's name that needs to be clicked
+      // on to relaunch the browser.
+      $reopen_browser = implode("-", array_slice($trigger['#parents'], 0, -static::$deleteDepth));
+    }
 
-    return NestedArray::getValue($form, $parents);
+    $parents = NestedArray::getValue($form, $parents);
+    $parents['#attached']['drupalSettings']['entity_browser_reopen_browser'] = $reopen_browser;
+    return $parents;
   }
 
   /**
@@ -461,7 +534,8 @@ public static function removeItemSubmit(&$form, FormStateInterface $form_state)
       // Find and remove correct entity.
       $values = explode(' ', $form_state->getValue(array_merge($parents, ['target_id'])));
       foreach ($values as $index => $item) {
-        if ($item == $id && $index == $row_id) {
+        // @todo add weight field.
+        if ($item == $id) {
           array_splice($values, $index, 1);
 
           break;
@@ -492,23 +566,33 @@ public static function removeItemSubmit(&$form, FormStateInterface $form_state)
    * @return array
    *   The render array for the current selection.
    */
-  protected function displayCurrentSelection($details_id, $field_parents, $entities) {
+  protected function displayCurrentSelection($details_id, array $field_parents, array $entities) {
+
+    $target_entity_type = $this->fieldDefinition->getFieldStorageDefinition()->getSetting('target_type');
 
     $field_widget_display = $this->fieldDisplayManager->createInstance(
       $this->getSetting('field_widget_display'),
       $this->getSetting('field_widget_display_settings') + ['entity_type' => $this->fieldDefinition->getFieldStorageDefinition()->getSetting('target_type')]
     );
 
-    $classes = ['entities-list'];
+    $classes = [
+      'entities-list',
+      Html::cleanCssIdentifier("entity-type--$target_entity_type"),
+    ];
     if ($this->fieldDefinition->getFieldStorageDefinition()->getCardinality() != 1) {
       $classes[] = 'sortable';
     }
 
+    // The "Replace" button will only be shown if this setting is enabled in the
+    // widget, and there is only one entity in the current selection.
+    $replace_button_access = $this->getSetting('field_widget_replace') && (count($entities) === 1);
+
     return [
       '#theme_wrappers' => ['container'],
       '#attributes' => ['class' => $classes],
+      '#prefix' => '<p>' . $this->getCardinalityMessage($entities) . '</p>',
       'items' => array_map(
-        function (ContentEntityInterface $entity, $row_id) use ($field_widget_display, $details_id, $field_parents) {
+        function (ContentEntityInterface $entity, $row_id) use ($field_widget_display, $details_id, $field_parents, $replace_button_access) {
           $display = $field_widget_display->view($entity);
           $edit_button_access = $this->getSetting('field_widget_edit') && $entity->access('update', $this->currentUser);
           if ($entity->getEntityTypeId() == 'file') {
@@ -541,12 +625,31 @@ function (ContentEntityInterface $entity, $row_id) use ($field_widget_display, $
               '#attributes' => [
                 'data-entity-id' => $entity->getEntityTypeId() . ':' . $entity->id(),
                 'data-row-id' => $row_id,
+                'class' => ['remove-button'],
               ],
               '#access' => (bool) $this->getSetting('field_widget_remove'),
             ],
+            'replace_button' => [
+              '#type' => 'submit',
+              '#value' => $this->t('Replace'),
+              '#ajax' => [
+                'callback' => [get_class($this), 'updateWidgetCallback'],
+                'wrapper' => $details_id,
+              ],
+              '#submit' => [[get_class($this), 'removeItemSubmit']],
+              '#name' => $this->fieldDefinition->getName() . '_replace_' . $entity->id() . '_' . $row_id . '_' . md5(json_encode($field_parents)),
+              '#limit_validation_errors' => [array_merge($field_parents, [$this->fieldDefinition->getName()])],
+              '#attributes' => [
+                'data-entity-id' => $entity->getEntityTypeId() . ':' . $entity->id(),
+                'data-row-id' => $row_id,
+                'class' => ['replace-button'],
+              ],
+              '#access' => $replace_button_access,
+            ],
             'edit_button' => [
               '#type' => 'submit',
               '#value' => $this->t('Edit'),
+              '#name' => $this->fieldDefinition->getName() . '_edit_button_' . $entity->id() . '_' . $row_id . '_' . md5(json_encode($field_parents)),
               '#ajax' => [
                 'url' => Url::fromRoute(
                   'entity_browser.edit_form', [
@@ -560,6 +663,9 @@ function (ContentEntityInterface $entity, $row_id) use ($field_widget_display, $
                   ],
                 ],
               ],
+              '#attributes' => [
+                'class' => ['edit-button'],
+              ],
               '#access' => $edit_button_access,
             ],
           ];
@@ -570,6 +676,42 @@ function (ContentEntityInterface $entity, $row_id) use ($field_widget_display, $
     ];
   }
 
+  /**
+   * Generates a message informing the user how many more items they can choose.
+   *
+   * @param array|int $selected
+   *   The current selections, or how many items are selected.
+   *
+   * @return string
+   *   A message informing the user who many more items they can select.
+   */
+  protected function getCardinalityMessage($selected) {
+    $message = NULL;
+
+    $storage = $this->fieldDefinition->getFieldStorageDefinition();
+    $cardinality = $storage->getCardinality();
+    $target_type = $storage->getSetting('target_type');
+    $target_type = $this->entityTypeManager->getDefinition($target_type);
+
+    if (is_array($selected)) {
+      $selected = count($selected);
+    }
+
+    if ($cardinality === 1 && $selected === 0) {
+      $message = $this->t('You can select one @entity_type.', [
+        '@entity_type' => $target_type->getSingularLabel(),
+      ]);
+    }
+    elseif ($cardinality >= $selected) {
+      $message = $this->t('You can select up to @maximum @entity_type (@remaining left).', [
+        '@maximum' => $cardinality,
+        '@entity_type' => $target_type->getPluralLabel(),
+        '@remaining' => $cardinality - $selected,
+      ]);
+    }
+    return (string) $message;
+  }
+
   /**
    * Gets data that should persist across Entity Browser renders.
    *
@@ -577,11 +719,17 @@ function (ContentEntityInterface $entity, $row_id) use ($field_widget_display, $
    *   Data that should persist after the Entity Browser is rendered.
    */
   protected function getPersistentData() {
+    $settings = $this->fieldDefinition->getSettings();
+    $handler = $settings['handler_settings'];
     return [
       'validators' => [
-        'entity_type' => ['type' => $this->fieldDefinition->getFieldStorageDefinition()->getSetting('target_type')],
+        'entity_type' => ['type' => $settings['target_type']],
+      ],
+      'widget_context' => [
+        'target_bundles' => !empty($handler['target_bundles']) ? $handler['target_bundles'] : [],
+        'target_entity_type' => $settings['target_type'],
+        'cardinality' => $this->fieldDefinition->getFieldStorageDefinition()->getCardinality(),
       ],
-      'widget_context' => [],
     ];
   }
 
@@ -613,7 +761,7 @@ protected function summaryBase() {
         $summary[] = $this->t('Entity browser: @browser', ['@browser' => $browser->label()]);
       }
       else {
-        drupal_set_message($this->t('Missing entity browser!'), 'error');
+        $this->messenger->addError($this->t('Missing entity browser!'));
         return [$this->t('Missing entity browser!')];
       }
     }
@@ -658,7 +806,8 @@ protected function formElementEntities(FieldItemListInterface $items, array $ele
     $is_relevant_submit = FALSE;
     if (($trigger = $form_state->getTriggeringElement())) {
       // Can be triggered by hidden target_id element or "Remove" button.
-      if (end($trigger['#parents']) === 'target_id' || (end($trigger['#parents']) === 'remove_button')) {
+      $last_parent = end($trigger['#parents']);
+      if (in_array($last_parent, ['target_id', 'remove_button', 'replace_button'])) {
         $is_relevant_submit = TRUE;
 
         // In case there are more instances of this widget on the same page we
@@ -758,7 +907,11 @@ protected function getEntitiesByTargetId(array $element, FormStateInterface $for
       [$this->fieldDefinition->getName(), 'target_id']
     );
 
-    if (!NestedArray::keyExists($form_state->getUserInput(), $target_id_element_path)) {
+    $user_input = $form_state->getUserInput();
+
+    $ief_submit = (!empty($user_input['_triggering_element_name']) && strpos($user_input['_triggering_element_name'], 'ief-edit-submit') === 0);
+
+    if (!$ief_submit || !NestedArray::keyExists($form_state->getUserInput(), $target_id_element_path)) {
       return FALSE;
     }
 
diff --git a/web/modules/entity_browser/src/Plugin/Field/FieldWidget/FileBrowserWidget.php b/web/modules/entity_browser/src/Plugin/Field/FieldWidget/FileBrowserWidget.php
index 6db9c8d476a748d64062317ec0164ce1e00fd136..e298ab12c226751f23ebc4c5013419c07aa3a755 100644
--- a/web/modules/entity_browser/src/Plugin/Field/FieldWidget/FileBrowserWidget.php
+++ b/web/modules/entity_browser/src/Plugin/Field/FieldWidget/FileBrowserWidget.php
@@ -11,12 +11,14 @@
 use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldItemListInterface;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Messenger\MessengerInterface;
 use Drupal\Core\Url;
 use Drupal\entity_browser\FieldWidgetDisplayManager;
 use Drupal\image\Entity\ImageStyle;
 use Symfony\Component\DependencyInjection\ContainerInterface;
-use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 use Drupal\Core\Session\AccountInterface;
+use Drupal\Component\Utility\Environment;
+use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface;
 
 /**
  * Entity browser file widget.
@@ -62,6 +64,13 @@ class FileBrowserWidget extends EntityReferenceBrowserWidget {
    */
   protected $displayRepository;
 
+  /**
+   * The mime type guesser service.
+   *
+   * @var \Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface
+   */
+  protected $mimeTypeGuesser;
+
   /**
    * Constructs widget plugin.
    *
@@ -77,8 +86,6 @@ class FileBrowserWidget extends EntityReferenceBrowserWidget {
    *   Any third party settings.
    * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
    *   Entity type manager service.
-   * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
-   *   Event dispatcher.
    * @param \Drupal\entity_browser\FieldWidgetDisplayManager $field_display_manager
    *   Field widget display plugin manager.
    * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
@@ -89,13 +96,18 @@ class FileBrowserWidget extends EntityReferenceBrowserWidget {
    *   The module handler service.
    * @param \Drupal\Core\Session\AccountInterface $current_user
    *   The current user.
+   * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+   *   The messenger.
+   * @param \Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface $mime_type_guesser
+   *   The mime type guesser service.
    */
-  public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings, EntityTypeManagerInterface $entity_type_manager, EventDispatcherInterface $event_dispatcher, FieldWidgetDisplayManager $field_display_manager, ConfigFactoryInterface $config_factory, EntityDisplayRepositoryInterface $display_repository, ModuleHandlerInterface $module_handler, AccountInterface $current_user) {
-    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $third_party_settings, $entity_type_manager, $event_dispatcher, $field_display_manager, $module_handler, $current_user);
+  public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings, EntityTypeManagerInterface $entity_type_manager, FieldWidgetDisplayManager $field_display_manager, ConfigFactoryInterface $config_factory, EntityDisplayRepositoryInterface $display_repository, ModuleHandlerInterface $module_handler, AccountInterface $current_user, MimeTypeGuesserInterface $mime_type_guesser, MessengerInterface $messenger) {
+    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $third_party_settings, $entity_type_manager, $field_display_manager, $module_handler, $current_user, $messenger);
     $this->entityTypeManager = $entity_type_manager;
     $this->fieldDisplayManager = $field_display_manager;
     $this->configFactory = $config_factory;
     $this->displayRepository = $display_repository;
+    $this->mimeTypeGuesser = $mime_type_guesser;
   }
 
   /**
@@ -109,12 +121,13 @@ public static function create(ContainerInterface $container, array $configuratio
       $configuration['settings'],
       $configuration['third_party_settings'],
       $container->get('entity_type.manager'),
-      $container->get('event_dispatcher'),
       $container->get('plugin.manager.entity_browser.field_widget_display'),
       $container->get('config.factory'),
       $container->get('entity_display.repository'),
       $container->get('module_handler'),
-      $container->get('current_user')
+      $container->get('current_user'),
+      $container->get('file.mime_type.guesser'),
+      $container->get('messenger')
     );
   }
 
@@ -200,7 +213,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
   /**
    * {@inheritdoc}
    */
-  protected function displayCurrentSelection($details_id, $field_parents, $entities) {
+  protected function displayCurrentSelection($details_id, array $field_parents, array $entities) {
     $field_type = $this->fieldDefinition->getType();
     $field_settings = $this->fieldDefinition->getSettings();
     $field_machine_name = $this->fieldDefinition->getName();
@@ -239,7 +252,7 @@ protected function displayCurrentSelection($details_id, $field_parents, $entitie
 
     // Add the remaining columns.
     $current['#header'][] = $this->t('Metadata');
-    $current['#header'][] = ['data' => $this->t('Operations'), 'colspan' => 2];
+    $current['#header'][] = ['data' => $this->t('Operations'), 'colspan' => 3];
     $current['#header'][] = $this->t('Order', [], ['context' => 'Sort order']);
 
     /** @var \Drupal\file\FileInterface[] $entities */
@@ -253,6 +266,10 @@ protected function displayCurrentSelection($details_id, $field_parents, $entitie
         $edit_button_access = $can_edit && $entity->access('update', $this->currentUser);
       }
 
+      // The "Replace" button will only be shown if this setting is enabled in
+      // the widget, and there is only one entity in the current selection.
+      $replace_button_access = $this->getSetting('field_widget_replace') && (count($entities) === 1);
+
       $entity_id = $entity->id();
 
       // Find the default description.
@@ -356,9 +373,27 @@ protected function displayCurrentSelection($details_id, $field_parents, $entitie
           '#attributes' => [
             'data-entity-id' => $entity->getEntityTypeId() . ':' . $entity->id(),
             'data-row-id' => $delta,
+            'class' => ['edit-button'],
           ],
           '#access' => $edit_button_access,
         ],
+        'replace_button' => [
+          '#type' => 'submit',
+          '#value' => $this->t('Replace'),
+          '#ajax' => [
+            'callback' => [get_class($this), 'updateWidgetCallback'],
+            'wrapper' => $details_id,
+          ],
+          '#submit' => [[get_class($this), 'removeItemSubmit']],
+          '#name' => $field_machine_name . '_replace_' . $entity_id . '_' . md5(json_encode($field_parents)),
+          '#limit_validation_errors' => [array_merge($field_parents, [$field_machine_name, 'target_id'])],
+          '#attributes' => [
+            'data-entity-id' => $entity->getEntityTypeId() . ':' . $entity->id(),
+            'data-row-id' => $delta,
+            'class' => ['replace-button'],
+          ],
+          '#access' => $replace_button_access,
+        ],
         'remove_button' => [
           '#type' => 'submit',
           '#value' => $this->t('Remove'),
@@ -372,6 +407,7 @@ protected function displayCurrentSelection($details_id, $field_parents, $entitie
           '#attributes' => [
             'data-entity-id' => $entity->getEntityTypeId() . ':' . $entity->id(),
             'data-row-id' => $delta,
+            'class' => ['remove-button'],
           ],
           '#access' => (bool) $widget_settings['field_widget_remove'],
         ],
@@ -453,7 +489,7 @@ public function getFileValidators($upload = FALSE) {
 
     if ($upload) {
       // Cap the upload size according to the PHP limit.
-      $max_filesize = Bytes::toInt(file_upload_max_size());
+      $max_filesize = Bytes::toInt(Environment::getUploadMaxSize());
       if (!empty($settings['max_filesize'])) {
         $max_filesize = min($max_filesize, Bytes::toInt($settings['max_filesize']));
       }
@@ -493,6 +529,16 @@ protected function getPersistentData() {
     // Provide context for widgets to enhance their configuration.
     $data['widget_context']['upload_location'] = $settings['uri_scheme'] . '://' . $settings['file_directory'];
     $data['widget_context']['upload_validators'] = $this->getFileValidators(TRUE);
+    // Assemble valid mime types for filtering. This is required if we want to
+    // contextually filter allowed extensions in views, as views arguments can
+    // only filter on exact values. Otherwise we would pass %png or use REGEXP.
+    $mimetypes = [];
+    foreach (explode(' ', $settings['file_extensions']) as $extension) {
+      if ($guess = $this->mimeTypeGuesser->guess('file.' . $extension)) {
+        $mimetypes[] = $guess;
+      }
+    }
+    $data['widget_context']['target_file_mimetypes'] = $mimetypes;
     return $data;
   }
 
diff --git a/web/modules/entity_browser/src/Plugin/views/argument_default/EntityBrowserWidgetContext.php b/web/modules/entity_browser/src/Plugin/views/argument_default/EntityBrowserWidgetContext.php
new file mode 100644
index 0000000000000000000000000000000000000000..97604f94187a6cf8b96468a6eab6b8371b390722
--- /dev/null
+++ b/web/modules/entity_browser/src/Plugin/views/argument_default/EntityBrowserWidgetContext.php
@@ -0,0 +1,126 @@
+<?php
+
+namespace Drupal\entity_browser\Plugin\views\argument_default;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface;
+use Drupal\views\Plugin\views\argument_default\ArgumentDefaultPluginBase;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * The entity browser widget context argument default handler.
+ *
+ * @ViewsArgumentDefault(
+ *   id = "entity_browser_widget_context",
+ *   title = @Translation("Entity Browser Context")
+ * )
+ */
+class EntityBrowserWidgetContext extends ArgumentDefaultPluginBase {
+
+  /**
+   * The selection storage.
+   *
+   * @var \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface
+   */
+  protected $selectionStorage;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, KeyValueStoreExpirableInterface $selection_storage) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+    $this->selectionStorage = $selection_storage;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('entity_browser.selection_storage')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function defineOptions() {
+    $options = parent::defineOptions();
+    $options['context_key'] = ['default' => 'target_bundles'];
+    $options['fallback'] = ['default' => 'all'];
+    $options['multiple'] = ['default' => 'or'];
+    return $options;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildOptionsForm(&$form, FormStateInterface $form_state) {
+    parent::buildOptionsForm($form, $form_state);
+    $form['context_key'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Context key'),
+      '#description' => $this->t('The key within the widget context.'),
+      '#default_value' => $this->options['context_key'],
+    ];
+    $form['fallback'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Fallback value'),
+      '#description' => $this->t('The fallback value to use when the context is not present. (ex: "all")'),
+      '#default_value' => $this->options['fallback'],
+    ];
+    $form['multiple'] = [
+      '#type' => 'radios',
+      '#title' => $this->t('Multiple values'),
+      '#description' => $this->t('Conjunction to use when handling multiple values. NOTE: for multiple values to work, at the bottom of this form expand the "More" fieldset and and check "Allow multiple values".'),
+      '#default_value' => $this->options['multiple'],
+      '#options' => [
+        'or' => $this->t('OR'),
+        'and' => $this->t('AND'),
+      ],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function access() {
+    return $this->view->getDisplay()->pluginId === 'entity_browser';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getArgument() {
+    $current_request = $this->view->getRequest();
+    $context_key = $this->options['context_key'];
+    $argument = $this->options['fallback'];
+    // Check if the widget context is available.
+    if (!empty($context_key) && $current_request->query->has('uuid')) {
+      $uuid = $current_request->query->get('uuid');
+      if ($storage = $this->selectionStorage->get($uuid)) {
+        if (isset($storage['widget_context']) && !empty($storage['widget_context'][$context_key])) {
+          $value = $storage['widget_context'][$context_key];
+          if (is_string($value)) {
+            $argument = $value;
+          }
+          // If the context value is an array, test that it can be imploded.
+          elseif (is_array($value)) {
+            $non_scalar = array_filter($value, function ($item) {
+              return !is_scalar($item);
+            });
+            if (empty($non_scalar)) {
+              $conjunction = ($this->options['multiple'] == 'and') ? ',' : '+';
+              $argument = implode($conjunction, $value);
+            }
+          }
+        }
+      }
+    }
+    return $argument;
+  }
+
+}
diff --git a/web/modules/entity_browser/src/Plugin/views/display/EntityBrowser.php b/web/modules/entity_browser/src/Plugin/views/display/EntityBrowser.php
index 5b382c3360e5cde7b76d9eea074881e0c97bed94..f4f7fbe7f9940af407221edd3677e0f94f016c8a 100644
--- a/web/modules/entity_browser/src/Plugin/views/display/EntityBrowser.php
+++ b/web/modules/entity_browser/src/Plugin/views/display/EntityBrowser.php
@@ -60,7 +60,6 @@ public function getOption($option) {
     }
   }
 
-
   /**
    * {@inheritdoc}
    */
diff --git a/web/modules/entity_browser/src/Plugin/views/field/SearchApiSelectForm.php b/web/modules/entity_browser/src/Plugin/views/field/SearchApiSelectForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..a75ef1ee8e3cc8ccaa927b6a3ec9931882a7ad5e
--- /dev/null
+++ b/web/modules/entity_browser/src/Plugin/views/field/SearchApiSelectForm.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace Drupal\entity_browser\Plugin\views\field;
+
+use Drupal\views\ResultRow;
+
+/**
+ * Defines a bulk operation form element that works with entity browser.
+ *
+ * @ViewsField("entity_browser_search_api_select")
+ */
+class SearchApiSelectForm extends SelectForm {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getRowId(ResultRow $row) {
+    $entity = $row->_object->getValue();
+    return $entity->getEntityTypeId() . ':' . $entity->id();
+  }
+
+}
diff --git a/web/modules/entity_browser/src/Plugin/views/field/SelectForm.php b/web/modules/entity_browser/src/Plugin/views/field/SelectForm.php
index d498082b89d670e2a871be40e098a9a608d0454c..30039b9ca41f28be59fc14ee4e16a202a8ea2537 100644
--- a/web/modules/entity_browser/src/Plugin/views/field/SelectForm.php
+++ b/web/modules/entity_browser/src/Plugin/views/field/SelectForm.php
@@ -2,10 +2,14 @@
 
 namespace Drupal\entity_browser\Plugin\views\field;
 
+use Drupal\Core\Form\FormStateInterface;
 use Drupal\views\Plugin\views\field\FieldPluginBase;
 use Drupal\views\Plugin\views\style\Table;
 use Drupal\views\ResultRow;
 use Drupal\views\Render\ViewsRenderPipelineMarkup;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\HttpFoundation\RequestStack;
+use Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface;
 
 /**
  * Defines a bulk operation form element that works with entity browser.
@@ -14,6 +18,79 @@
  */
 class SelectForm extends FieldPluginBase {
 
+  /**
+   * The current request.
+   *
+   * @var null|\Symfony\Component\HttpFoundation\Request
+   */
+  protected $currentRequest;
+
+  /**
+   * The entity browser selection storage.
+   *
+   * @var \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface
+   */
+  protected $selectionStorage;
+
+  /**
+   * EntityBrowser constructor.
+   *
+   * @param array $configuration
+   *   The plugin configuration.
+   * @param string $plugin_id
+   *   The plugin id.
+   * @param mixed $plugin_definition
+   *   The plugin definition.
+   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
+   *   The request stack.
+   * @param \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface $selection_storage
+   *   The selection storage.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, RequestStack $request_stack, KeyValueStoreExpirableInterface $selection_storage) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+    $this->currentRequest = $request_stack->getCurrentRequest();
+    $this->selectionStorage = $selection_storage;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('request_stack'),
+      $container->get('entity_browser.selection_storage')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function defineOptions() {
+    $options = parent::defineOptions();
+    $options['use_field_cardinality'] = [
+      'default' => FALSE,
+    ];
+
+    return $options;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildOptionsForm(&$form, FormStateInterface $form_state) {
+    parent::buildOptionsForm($form, $form_state);
+
+    $form['use_field_cardinality'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Use field cardinality'),
+      '#default_value' => $this->options['use_field_cardinality'],
+      '#description' => $this->t('If the view is used in a context where cardinality is 1, use radios instead of checkboxes.'),
+    ];
+  }
+
   /**
    * Returns the ID for a result row.
    *
@@ -63,6 +140,12 @@ public function viewsForm(&$render) {
       // Render checkboxes for all rows.
       $render[$this->options['id']]['#tree'] = TRUE;
       $render[$this->options['id']]['#printed'] = TRUE;
+
+      $cardinality = $this->getCardinality();
+      $use_field_cardinality = $this->options['use_field_cardinality'];
+
+      $use_radios = ($use_field_cardinality && $cardinality === 1);
+
       foreach ($this->view->result as $row) {
         $value = $this->getRowId($row);
 
@@ -74,8 +157,62 @@ public function viewsForm(&$render) {
           '#attributes' => ['name' => "entity_browser_select[$value]"],
           '#default_value' => NULL,
         ];
+
+        if ($use_radios) {
+          $render[$this->options['id']][$value]['#type'] = 'radio';
+          $render[$this->options['id']][$value]['#attributes'] = ['name' => "entity_browser_select"];
+          $render[$this->options['id']][$value]['#parents'] = ['entity_browser_select'];
+          // Add the #value property to suppress a php notice in Radio.php.
+          $render[$this->options['id']][$value]['#value'] = FALSE;
+        }
+      }
+
+      $render['entity_browser_select_form_metadata'] = [
+        'cardinality' => [
+          '#type' => 'hidden',
+          '#value' => $cardinality,
+        ],
+        'use_field_cardinality' => [
+          '#type' => 'hidden',
+          '#value' => (int) $use_field_cardinality,
+        ],
+        '#tree' => TRUE,
+      ];
+    }
+
+    $render['view']['#cache']['tags'][] = 'config:entity_browser.settings';
+  }
+
+  /**
+   * Get widget context from entity_browser.selection_storage service.
+   *
+   * @return array
+   *   Array of contextual information.
+   */
+  protected function getWidgetContext() {
+    if ($this->currentRequest->query->has('uuid')) {
+      $uuid = $this->currentRequest->query->get('uuid');
+      if ($storage = $this->selectionStorage->get($uuid)) {
+        if (isset($storage['widget_context'])) {
+          return $storage['widget_context'];
+        }
       }
     }
+    return [];
+  }
+
+  /**
+   * Get cardinality from widget context.
+   *
+   * @return int|null
+   *   Returns cardinality from widget context.
+   */
+  protected function getCardinality() {
+    $widget_context = $this->getWidgetContext();
+    if (!empty($widget_context['cardinality'])) {
+      return $widget_context['cardinality'];
+    }
+    return NULL;
   }
 
   /**
diff --git a/web/modules/entity_browser/src/Plugin/views/filter/ContextualBundle.php b/web/modules/entity_browser/src/Plugin/views/filter/ContextualBundle.php
new file mode 100644
index 0000000000000000000000000000000000000000..d59ed6adaf3b53aba4c3df4a68724042d23ebbed
--- /dev/null
+++ b/web/modules/entity_browser/src/Plugin/views/filter/ContextualBundle.php
@@ -0,0 +1,235 @@
+<?php
+
+namespace Drupal\entity_browser\Plugin\views\filter;
+
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\views\Plugin\views\HandlerBase;
+use Drupal\views\Plugin\views\filter\Bundle;
+use Drupal\Core\Form\FormStateInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\HttpFoundation\RequestStack;
+use Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface;
+use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
+use Drupal\views\ViewExecutable;
+use Drupal\views\Plugin\views\display\DisplayPluginBase;
+
+/**
+ * Filter class which allows filtering by entity bundles.
+ *
+ * @ingroup views_filter_handlers
+ *
+ * @ViewsFilter("entity_browser_bundle")
+ */
+class ContextualBundle extends Bundle {
+
+  /**
+   * The entity type manager.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected $entityTypeManager;
+
+  /**
+   * A request stack symfony instance.
+   *
+   * @var \Symfony\Component\HttpFoundation\RequestStack
+   */
+  protected $requestStack;
+
+  /**
+   * The entity browser selection storage.
+   *
+   * @var \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface
+   */
+  protected $selectionStorage;
+
+  /**
+   * The bundle info service.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface
+   */
+  protected $bundleInfoService;
+
+  /**
+   * Constructs a Bundle object.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity manager.
+   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
+   *   A request stack symfony instance.
+   * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $bundle_info_service
+   *   The bundle info service.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, RequestStack $request_stack, KeyValueStoreExpirableInterface $selection_storage, EntityTypeBundleInfoInterface $bundle_info_service) {
+    HandlerBase::__construct($configuration, $plugin_id, $plugin_definition);
+    $this->requestStack = $request_stack;
+    $this->entityTypeManager = $entity_type_manager;
+    $this->selectionStorage = $selection_storage;
+    $this->is_handler = TRUE;
+    $this->bundleInfoService = $bundle_info_service;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
+    parent::init($view, $display, $options);
+
+    $this->entityTypeId = $this->getEntityType();
+    $this->entityType = $this->entityTypeManager->getDefinition($this->entityTypeId);
+    $this->real_field = $this->entityType->getKey('bundle');
+
+    // Pull $this->value from entity browser storage.
+    $current_request = $this->requestStack->getCurrentRequest();
+    if ($current_request->query->has('uuid')) {
+      $uuid = $current_request->query->get('uuid');
+      if ($storage = $this->selectionStorage->get($uuid)) {
+        if (isset($storage['widget_context']) && !empty($storage['widget_context']['target_bundles'])) {
+          $this->value = $storage['widget_context']['target_bundles'];
+        }
+      }
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('entity_type.manager'),
+      $container->get('request_stack'),
+      $container->get('entity_browser.selection_storage'),
+      $container->get('entity_type.bundle.info')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function operatorForm(&$form, FormStateInterface $form_state) {
+    // Don't allow selecting "not in".
+    $form['operator'] = [
+      '#type' => 'hidden',
+      '#value' => 'in',
+    ];
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+
+    if (empty($this->value)) {
+      return;
+    }
+
+    $this->ensureMyTable();
+
+    // We use array_values() because the checkboxes keep keys and that can cause
+    // array addition problems.
+    $this->query->addWhere($this->options['group'], "$this->tableAlias.$this->realField", array_values($this->value), 'in');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function canExpose() {
+    return TRUE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function adminSummary() {
+    return NULL;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function calculateDependencies() {
+    // Removes the bundle dependencies in parent::calculateDependencies, since
+    // they are dynamic.
+    $dependencies = HandlerBase::calculateDependencies();
+    return $dependencies;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getValueOptions() {
+    $this->valueOptions = parent::getValueOptions();
+
+    // Don't limit on config form, we'll display all greyed out.
+    if ($this->requestStack->getCurrentRequest()->attributes->get('_route') == 'views_ui.form_handler') {
+      return $this->valueOptions;
+    }
+
+    // Remove options that are not in this context.
+    foreach ($this->valueOptions as $key => $value) {
+      if (!in_array($key, $this->value)) {
+        unset($this->valueOptions[$key]);
+      }
+    }
+
+    return $this->valueOptions;
+  }
+
+  /**
+   * Determines if the input from a filter should change the generated query.
+   *
+   * @param array $input
+   *   The exposed data for this view.
+   *
+   * @return bool
+   *   TRUE if the input for this filter should be included in the view query.
+   *   FALSE otherwise.
+   */
+  public function acceptExposedInput($input) {
+
+    if (empty($this->options['exposed'])) {
+      return TRUE;
+    }
+
+    // If "All" option selected, Do call ::query.
+    $identifier = $this->options['expose']['identifier'];
+    if (!empty($input[$identifier]) && $input[$identifier] == 'All') {
+      return TRUE;
+    }
+
+    return parent::acceptExposedInput($input);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function valueForm(&$form, FormStateInterface $form_state) {
+    parent::valueForm($form, $form_state);
+
+    // Disable element on config form.
+    if ($this->requestStack->getCurrentRequest()->attributes->get('_route') == 'views_ui.form_handler') {
+      $form['value']['#default_value'] = array_combine(array_keys($form['value']['#options']), array_keys($form['value']['#options']));
+      $form['value']['#disabled'] = TRUE;
+      $form['value']['#description'] = $this->t('You cannot edit this list because the options update in response to entity browser context.');
+    }
+    // Hide element in exposed filter form if there's only one value.
+    elseif (!empty($this->value) && count($this->value) === 1) {
+      $form['value'] = [
+        '#type' => 'hidden',
+        '#value' => array_values($this->value)[0],
+      ];
+    }
+
+  }
+
+}
diff --git a/web/modules/entity_browser/src/PluginConfigurationFormTrait.php b/web/modules/entity_browser/src/PluginConfigurationFormTrait.php
index 312c05a992f80926631430c3860b097aab2eaad0..a55cbdb6e295fa82076426b74dc421872346205a 100644
--- a/web/modules/entity_browser/src/PluginConfigurationFormTrait.php
+++ b/web/modules/entity_browser/src/PluginConfigurationFormTrait.php
@@ -1,6 +1,7 @@
 <?php
 
 namespace Drupal\entity_browser;
+
 use Drupal\Core\Form\FormStateInterface;
 
 /**
diff --git a/web/modules/entity_browser/src/RouteSubscriber.php b/web/modules/entity_browser/src/RouteSubscriber.php
index 5509a3176f1216b9353a4135d721ca053bd19472..6d307b3827efa248263d4d9c762972b3c4e4cd1b 100644
--- a/web/modules/entity_browser/src/RouteSubscriber.php
+++ b/web/modules/entity_browser/src/RouteSubscriber.php
@@ -3,7 +3,6 @@
 namespace Drupal\entity_browser;
 
 use Drupal\Core\Entity\EntityTypeManagerInterface;
-use Drupal\Core\Entity\Query\QueryFactory;
 use Symfony\Component\Routing\RouteCollection;
 
 /**
@@ -25,27 +24,17 @@ class RouteSubscriber {
    */
   protected $displayManager;
 
-  /**
-   * Entity browser query.
-   *
-   * @var \Drupal\Core\Entity\Query\QueryInterface
-   */
-  protected $browserQuery;
-
   /**
    * Constructs a \Drupal\views\EventSubscriber\RouteSubscriber instance.
    *
    * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
-   *   The entity manager.
+   *   The entity type manager.
    * @param \Drupal\entity_browser\DisplayManager $display_manager
    *   The display manager.
-   * @param \Drupal\Core\Entity\Query\QueryFactory $entity_query
-   *   The entity query factory.
    */
-  public function __construct(EntityTypeManagerInterface $entity_type_manager, DisplayManager $display_manager, QueryFactory $entity_query) {
+  public function __construct(EntityTypeManagerInterface $entity_type_manager, DisplayManager $display_manager) {
     $this->browserStorage = $entity_type_manager->getStorage('entity_browser');
     $this->displayManager = $display_manager;
-    $this->browserQuery = $entity_query->get('entity_browser');
   }
 
   /**
@@ -56,7 +45,7 @@ public function __construct(EntityTypeManagerInterface $entity_type_manager, Dis
    */
   public function routes() {
     $collection = new RouteCollection();
-    // Return $collection;.
+
     foreach ($this->getBrowserIDsWithRoute() as $id) {
       /** @var $browser \Drupal\entity_browser\EntityBrowserInterface */
       $browser = $this->browserStorage->load($id);
@@ -84,7 +73,7 @@ protected function getBrowserIDsWithRoute() {
       }
     }
 
-    return $this->browserQuery
+    return $this->browserStorage->getQuery()
       ->condition('status', TRUE)
       ->condition("display", $ids, 'IN')
       ->execute();
diff --git a/web/modules/entity_browser/src/Routing/CtoolsFallbackRouteEnhancer.php b/web/modules/entity_browser/src/Routing/CtoolsFallbackRouteEnhancer.php
deleted file mode 100644
index e2988e25263803c95fe2411cba9b22eb9a08cf80..0000000000000000000000000000000000000000
--- a/web/modules/entity_browser/src/Routing/CtoolsFallbackRouteEnhancer.php
+++ /dev/null
@@ -1,50 +0,0 @@
-<?php
-
-namespace Drupal\entity_browser\Routing;
-
-use Drupal\Core\Extension\ModuleHandlerInterface;
-use Drupal\Core\Routing\Enhancer\RouteEnhancerInterface;
-use Symfony\Component\HttpFoundation\Request;
-use Symfony\Component\Routing\Route;
-
-/**
- * Enhances Entity browser edit/add form routes to display a message if ctools is missing.
- */
-class CtoolsFallbackRouteEnhancer implements RouteEnhancerInterface {
-
-  /**
-   * The module handler service.
-   *
-   * @var \Drupal\Core\Extension\ModuleHandlerInterface
-   */
-  protected $moduleHandler;
-
-  /**
-   * Constructs a CtoolsFallbackRouteEnhancer object.
-   *
-   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
-   *   Module handler service.
-   */
-  public function __construct(ModuleHandlerInterface $module_handler) {
-    $this->moduleHandler = $module_handler;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function enhance(array $defaults, Request $request) {
-    if (!$this->moduleHandler->moduleExists('ctools')) {
-      $defaults['_controller'] = '\Drupal\entity_browser\Controllers\CtoolsFallback::displayMessage';
-    }
-
-    return $defaults;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function applies(Route $route) {
-    return $route->hasDefault('_entity_wizard') && strpos($route->getDefault('_entity_wizard'), 'entity_browser.') === 0;
-  }
-
-}
diff --git a/web/modules/entity_browser/src/SelectionDisplayBase.php b/web/modules/entity_browser/src/SelectionDisplayBase.php
index 5df54d818e83788b1157367f7e81ba0f78a98e00..7591acbfdca4175f8beda6cb4e75abac1b597bfd 100644
--- a/web/modules/entity_browser/src/SelectionDisplayBase.php
+++ b/web/modules/entity_browser/src/SelectionDisplayBase.php
@@ -130,11 +130,19 @@ public function submit(array &$form, FormStateInterface $form_state) {}
    * {@inheritdoc}
    */
   public function checkPreselectionSupport() {
+    @trigger_error('checkPreselectionSupport method is deprecated. Use supportsPreselection instead.', E_USER_DEPRECATED);
     if (!$this->getPluginDefinition()['acceptPreselection']) {
       throw new ConfigException('Used entity browser selection display does not support preselection.');
     }
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function supportsPreselection() {
+    return $this->getPluginDefinition()['acceptPreselection'];
+  }
+
   /**
    * {@inheritdoc}
    */
diff --git a/web/modules/entity_browser/src/SelectionDisplayInterface.php b/web/modules/entity_browser/src/SelectionDisplayInterface.php
index 84e156473262c331348d1dc1eaf375bc72c082f4..19583205572661fd6b53c282ba27dbc88c3a0ddd 100644
--- a/web/modules/entity_browser/src/SelectionDisplayInterface.php
+++ b/web/modules/entity_browser/src/SelectionDisplayInterface.php
@@ -2,7 +2,8 @@
 
 namespace Drupal\entity_browser;
 
-use Drupal\Component\Plugin\ConfigurablePluginInterface;
+use Drupal\Component\Plugin\ConfigurableInterface;
+use Drupal\Component\Plugin\DependentPluginInterface;
 use Drupal\Component\Plugin\PluginInspectionInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Plugin\PluginFormInterface;
@@ -14,7 +15,7 @@
  * entities in an entity browser and delivering them upstream. The selections
  * are displayed in a form which delivers the selected entities on submit.
  */
-interface SelectionDisplayInterface extends PluginInspectionInterface, ConfigurablePluginInterface, PluginFormInterface {
+interface SelectionDisplayInterface extends PluginInspectionInterface, ConfigurableInterface, PluginFormInterface, DependentPluginInterface {
 
   /**
    * Returns the selection display label.
@@ -65,10 +66,20 @@ public function submit(array &$form, FormStateInterface $form_state);
    * If preselection is not allowed by entity browser selection display, then
    * exception will be thrown.
    *
+   * @deprecated Use ::supportsPreselection instead.
+   *
    * @throws \Drupal\Core\Config\ConfigException
    */
   public function checkPreselectionSupport();
 
+  /**
+   * Check if the plugin supports preselection.
+   *
+   * @returns bool
+   *   Returns TRUE if preselection is supported.
+   */
+  public function supportsPreselection();
+
   /**
    * Returns true if selection display supports selection over javascript.
    *
diff --git a/web/modules/entity_browser/src/Tests/ConfigUITest.php b/web/modules/entity_browser/src/Tests/ConfigUITest.php
deleted file mode 100644
index da58a79d60b055328747fb6e9f15530a92aa8941..0000000000000000000000000000000000000000
--- a/web/modules/entity_browser/src/Tests/ConfigUITest.php
+++ /dev/null
@@ -1,282 +0,0 @@
-<?php
-
-namespace Drupal\entity_browser\Tests;
-
-use Drupal\entity_browser\Plugin\EntityBrowser\Display\IFrame;
-use Drupal\entity_browser\Plugin\EntityBrowser\SelectionDisplay\NoDisplay;
-use Drupal\entity_browser\Plugin\EntityBrowser\WidgetSelector\Tabs;
-use Drupal\simpletest\WebTestBase;
-
-/**
- * Tests the entity browser config UI.
- *
- * @group entity_browser
- */
-class ConfigUITest extends WebTestBase {
-
-  /**
-   * The test user.
-   *
-   * @var \Drupal\User\UserInterface
-   */
-  protected $adminUser;
-
-  /**
-   * Modules to enable.
-   *
-   * @var array
-   */
-  public static $modules = ['entity_browser', 'ctools', 'block', 'views', 'entity_browser_entity_form'];
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-    $this->drupalPlaceBlock('local_actions_block');
-    $this->adminUser = $this->drupalCreateUser([
-      'administer entity browsers',
-    ]);
-  }
-
-  /**
-   * Tests the entity browser config UI.
-   */
-  public function testConfigUI() {
-    // We need token module to test upload widget settings.
-    $this->container->get('module_installer')->install(['token']);
-
-    $this->drupalGet('/admin/config/content/entity_browser');
-    $this->assertResponse(403, "Anonymous user can't access entity browser listing page.");
-    $this->drupalGet('/admin/config/content/entity_browser/add');
-    $this->assertResponse(403, "Anonymous user can't access entity browser add form.");
-
-    // Listing is empty.
-    $this->drupalLogin($this->adminUser);
-    $this->drupalGet('/admin/config/content/entity_browser');
-    $this->assertResponse(200, 'Admin user is able to navigate to the entity browser listing page.');
-    $this->assertText('There is no Entity browser yet.', 'Entity browsers table is empty.');
-
-    // Add page.
-    $this->clickLink('Add Entity browser');
-    $this->assertUrl('/admin/config/content/entity_browser/add');
-    $edit = [
-      'label' => 'Test entity browser',
-      'id' => 'test_entity_browser',
-      'display' => 'iframe',
-      'widget_selector' => 'tabs',
-      'selection_display' => 'no_display',
-    ];
-    $this->drupalPostForm(NULL, $edit, 'Next');
-
-    // Display configuration step.
-    $this->assertUrl('/admin/config/content/entity_browser/test_entity_browser/display', ['query' => ['js' => 'nojs']]);
-    $edit = [
-      'width' => 100,
-      'height' => 100,
-      'link_text' => 'All animals are created equal',
-      'auto_open' => TRUE,
-    ];
-    $this->drupalPostForm(NULL, $edit, 'Next');
-
-    // Widget selector step.
-    $this->assertUrl('/admin/config/content/entity_browser/test_entity_browser/widget_selector', ['query' => ['js' => 'nojs']]);
-    $this->assertText('This plugin has no configuration options.');
-    $this->drupalPostForm(NULL, [], 'Next');
-
-    // Selection display step.
-    $this->assertUrl('/admin/config/content/entity_browser/test_entity_browser/selection_display', ['query' => ['js' => 'nojs']]);
-    $this->assertText('This plugin has no configuration options.');
-    $this->drupalPostForm(NULL, [], 'Previous');
-
-    // Widget selector step again.
-    $this->assertUrl('/admin/config/content/entity_browser/test_entity_browser/widget_selector', ['query' => ['js' => 'nojs']]);
-    $this->assertText('This plugin has no configuration options.');
-    $this->drupalPostForm(NULL, [], 'Next');
-
-    // Selection display step.
-    $this->assertUrl('/admin/config/content/entity_browser/test_entity_browser/selection_display', ['query' => ['js' => 'nojs']]);
-    $this->assertText('This plugin has no configuration options.');
-    $this->drupalPostForm(NULL, [], 'Next');
-
-    // Widgets step.
-    $this->assertUrl('/admin/config/content/entity_browser/test_entity_browser/widgets', ['query' => ['js' => 'nojs']]);
-    $this->assertText('The available plugins are:');
-    $this->assertText("Upload: Adds an upload field browser's widget.");
-    $this->assertText("View: Uses a view to provide entity listing in a browser's widget.");
-    $this->assertText("Entity form: Provides entity form widget.");
-    $this->drupalPostAjaxForm(NULL, ['widget' => 'upload'], 'widget');
-    $this->assertText('Label (Upload)');
-    $this->assertText('You can use tokens in the upload location.');
-    $this->assertLink('Browse available tokens.');
-
-    // Make sure that removing of widgets works.
-    $this->drupalPostAjaxForm(NULL, ['widget' => 'view'], 'widget');
-    $this->assertText('Label (View)');
-    $this->assertText('View : View display', 'View selection dropdown label found.');
-    $this->assertRaw('- Select a view -', 'Empty option appears in the view selection dropdown.');
-    $this->assertText('Submit button text', 'Widget submit button text element found.');
-    $this->assertFieldByXPath('//*[starts-with(@data-drupal-selector, "edit-table-") and contains(@data-drupal-selector, "-form-submit-text")]', 'Select entities', 'Widget submit button text element found.');
-    $delete_buttons = $this->xpath("//input[@value='Delete']");
-    $delete_button_name = (string) $delete_buttons[1]->attributes()['name'];
-    $this->drupalPostAjaxForm(NULL, [], [$delete_button_name => 'Delete']);
-    $this->assertNoText('View : View display', 'View widget was removed.');
-    $this->assertNoRaw('- Select a view -', 'View widget was removed.');
-    $this->assertEqual(count($this->xpath("//input[@value='Delete']")), 1, 'Only one delete button appears on the page.');
-
-    // Make sure the "Entity form" widget has all available config elements.
-    $this->drupalPostAjaxForm(NULL, ['widget' => 'entity_form'], 'widget');
-    $this->assertText('Label (Entity form)');
-    $this->assertText('Entity type', 'Entity type select found on IEF widget.');
-    $this->assertText('Bundle', 'Bundle select found on IEF widget.');
-    $this->assertText('Form mode', 'Form mode select found on IEF widget.');
-    $this->assertFieldByXPath('//*[starts-with(@data-drupal-selector, "edit-table-") and contains(@data-drupal-selector, "-form-submit-text")]', 'Save entity', 'Widget submit button text element found.');
-    $entity_type_element = $this->xpath('//*[starts-with(@data-drupal-selector, "edit-table-") and contains(@data-drupal-selector, "-form-entity-type")]');
-    $entity_type_name = (string) $entity_type_element[0]['name'];
-    $edit = [
-      $entity_type_name => 'user',
-    ];
-    $commands = $this->drupalPostAjaxForm(NULL, $edit, $entity_type_name);
-    // WebTestBase::drupalProcessAjaxResponse() won't correctly execute our ajax
-    // commands so we have to do it manually. Code below is based on the logic
-    // in that function.
-    $content = $this->content;
-    $dom = new \DOMDocument();
-    @$dom->loadHTML($content);
-    $xpath = new \DOMXPath($dom);
-    foreach ($commands as $command) {
-      if ($command['command'] == 'insert' && $command['method'] == 'replaceWith') {
-        $wrapperNode = $xpath->query('//*[@id="' . ltrim($command['selector'], '#') . '"]')->item(0);
-        $newDom = new \DOMDocument();
-        @$newDom->loadHTML('<div>' . $command['data'] . '</div>');
-        $newNode = @$dom->importNode($newDom->documentElement->firstChild->firstChild, TRUE);
-        $wrapperNode->parentNode->replaceChild($newNode, $wrapperNode);
-        $content = $dom->saveHTML();
-        $this->setRawContent($content);
-      }
-    }
-    $this->verbose($content);
-    // Assure the form_mode "Register" is one of the available options.
-    $form_mode_element = $this->xpath('//*[starts-with(@data-drupal-selector, "edit-table-") and contains(@data-drupal-selector, "-form-form-mode-form-select")]');
-    $form_mode_id = (string) $form_mode_element[0]['id'];
-    $form_mode_name = (string) $form_mode_element[0]['name'];
-    $this->assertOption($form_mode_id, 'register', 'A non-default form mode is correctly available to be chosen.');
-    $bundle_element = $this->xpath('//*[starts-with(@data-drupal-selector, "edit-table-") and contains(@data-drupal-selector, "-form-bundle-select")]');
-    $bundle_name = (string) $bundle_element[0]['name'];
-    $submit_text_element = $this->xpath('//*[starts-with(@data-drupal-selector, "edit-table-") and contains(@data-drupal-selector, "-form-submit-text")]');
-    $submit_text_name = (string) $submit_text_element[1]['name'];
-    $edit = [
-      $entity_type_name => 'user',
-      $bundle_name => 'user',
-      $form_mode_name => 'register',
-      $submit_text_name => 'But some are more equal than others',
-    ];
-    $this->drupalPostForm(NULL, $edit, 'Finish');
-
-    // Back on listing page.
-    $this->assertUrl('/admin/config/content/entity_browser');
-    $this->assertText('Test entity browser', 'Entity browser label found on the listing page');
-    $this->assertText('test_entity_browser', 'Entity browser ID found on the listing page.');
-
-    // Check structure of entity browser object.
-    /** @var \Drupal\entity_browser\EntityBrowserInterface $loaded_entity_browser */
-    $loaded_entity_browser = $this->container->get('entity_type.manager')
-      ->getStorage('entity_browser')
-      ->load('test_entity_browser');
-    $this->assertEqual('test_entity_browser', $loaded_entity_browser->id(), 'Entity browser ID was correctly saved.');
-    $this->assertEqual('Test entity browser', $loaded_entity_browser->label(), 'Entity browser label was correctly saved.');
-    $this->assertTrue($loaded_entity_browser->getDisplay() instanceof IFrame, 'Entity browser display was correctly saved.');
-    $expected = [
-      'width' => '100',
-      'height' => '100',
-      'link_text' => 'All animals are created equal',
-      'auto_open' => TRUE,
-    ];
-    $this->assertEqual($expected, $loaded_entity_browser->getDisplay()->getConfiguration(), 'Entity browser display configuration was correctly saved.');
-    $this->assertTrue($loaded_entity_browser->getSelectionDisplay() instanceof NoDisplay, 'Entity browser selection display was correctly saved.');
-    $this->assertEqual([], $loaded_entity_browser->getSelectionDisplay()->getConfiguration(), 'Entity browser selection display configuration was correctly saved.');
-    $this->assertEqual($loaded_entity_browser->getWidgetSelector() instanceof Tabs, 'Entity browser widget selector was correctly saved.');
-    $this->assertEqual([], $loaded_entity_browser->getWidgetSelector()->getConfiguration(), 'Entity browser widget selector configuration was correctly saved.');
-
-    $widgets = $loaded_entity_browser->getWidgets();
-    $instance_ids = $widgets->getInstanceIds();
-    $first_uuid = current($instance_ids);
-    $second_uuid = next($instance_ids);
-    /** @var \Drupal\entity_browser\WidgetInterface $widget */
-    $widget = $widgets->get($first_uuid);
-    $this->assertEqual('upload', $widget->id(), 'Entity browser widget was correctly saved.');
-    $this->assertEqual($first_uuid, $widget->uuid(), 'Entity browser widget uuid was correctly saved.');
-    $configuration = $widget->getConfiguration()['settings'];
-    $this->assertEqual([
-      'upload_location' => 'public://',
-      'multiple' => TRUE,
-      'submit_text' => 'Select files',
-      'extensions' => 'jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp',
-    ], $configuration, 'Entity browser widget configuration was correctly saved.');
-    $this->assertEqual(1, $widget->getWeight(), 'Entity browser widget weight was correctly saved.');
-    $widget = $widgets->get($second_uuid);
-    $this->assertEqual('entity_form', $widget->id(), 'Entity browser widget was correctly saved.');
-    $this->assertEqual($second_uuid, $widget->uuid(), 'Entity browser widget uuid was correctly saved.');
-    $configuration = $widget->getConfiguration()['settings'];
-    $this->assertEqual([
-      'entity_type' => 'user',
-      'bundle' => 'user',
-      'form_mode' => 'register',
-      'submit_text' => 'But some are more equal than others',
-    ], $configuration, 'Entity browser widget configuration was correctly saved.');
-    $this->assertEqual(2, $widget->getWeight(), 'Entity browser widget weight was correctly saved.');
-
-    // Navigate to edit.
-    $this->clickLink('Edit');
-    $this->assertUrl('/admin/config/content/entity_browser/test_entity_browser');
-    $this->assertFieldById('edit-label', 'Test entity browser', 'Correct label found.');
-    $this->assertText('test_entity_browser', 'Correct id found.');
-    $this->assertOptionSelected('edit-display', 'iframe', 'Correct display selected.');
-    $this->assertOptionSelected('edit-widget-selector', 'tabs', 'Correct widget selector selected.');
-    $this->assertOptionSelected('edit-selection-display', 'no_display', 'Correct selection display selected.');
-
-    $this->drupalPostForm(NULL, [], 'Next');
-    $this->assertUrl('/admin/config/content/entity_browser/test_entity_browser/display', ['query' => ['js' => 'nojs']]);
-    $this->assertFieldById('edit-width', '100', 'Correct value for width found.');
-    $this->assertFieldById('edit-height', '100', 'Correct value for height found.');
-    $this->assertFieldById('edit-link-text', 'All animals are created equal', 'Correct value for link text found.');
-    $this->assertFieldChecked('edit-auto-open', 'Auto open is enabled.');
-
-    $this->drupalPostForm(NULL, [], 'Next');
-    $this->assertUrl('/admin/config/content/entity_browser/test_entity_browser/widget_selector', ['query' => ['js' => 'nojs']]);
-
-    $this->drupalPostForm(NULL, [], 'Next');
-    $this->assertUrl('/admin/config/content/entity_browser/test_entity_browser/selection_display', ['query' => ['js' => 'nojs']]);
-
-    $this->drupalPostForm(NULL, [], 'Next');
-    $this->assertFieldById('edit-table-' . $first_uuid . '-label', 'upload', 'Correct value for widget label found.');
-    $this->assertFieldChecked('edit-table-' . $first_uuid . '-form-multiple', 'Accept multiple files option is enabled by default.');
-    $this->assertText('Multiple uploads will only be accepted if the source field allows more than one value.');
-    $this->assertFieldById('edit-table-' . $first_uuid . '-form-upload-location', 'public://', 'Correct value for upload location found.');
-    $this->assertFieldByXPath("//input[@data-drupal-selector='edit-table-" . $first_uuid . "-form-submit-text']", 'Select files', 'Correct value for submit text found.');
-    $this->assertFieldById('edit-table-' . $second_uuid . '-label', 'entity_form', 'Correct value for widget label found.');
-    $this->assertOptionSelectedWithDrupalSelector('edit-table-' . $second_uuid . '-form-entity-type', 'user', 'Correct value for entity type found.');
-    $this->assertOptionSelectedWithDrupalSelector('edit-table-' . $second_uuid . '-form-bundle-select', 'user', 'Correct value for bundle found.');
-    $this->assertOptionSelectedWithDrupalSelector('edit-table-' . $second_uuid . '-form-form-mode-form-select', 'register', 'Correct value for form modes found.');
-    $this->assertFieldByXPath("//input[@data-drupal-selector='edit-table-" . $second_uuid . "-form-submit-text']", 'But some are more equal than others', 'Correct value for submit text found.');
-
-    $this->drupalPostForm(NULL, ['table[' . $first_uuid . '][form][multiple]' => FALSE], 'Finish');
-    $this->drupalGet('/admin/config/content/entity_browser/test_entity_browser/widgets');
-    $this->assertNoFieldChecked('edit-table-' . $first_uuid . '-form-multiple', 'Accept multiple files option is disabled.');
-
-    $this->drupalLogout();
-    $this->drupalGet('/admin/config/content/entity_browser/test_entity_browser');
-    $this->assertResponse(403, "Anonymous user can't access entity browser edit form.");
-
-    $this->drupalLogin($this->adminUser);
-    $this->drupalGet('/admin/config/content/entity_browser');
-    $this->clickLink('Delete');
-    $this->assertText('This action cannot be undone.', 'Delete question found.');
-    $this->drupalPostForm(NULL, [], 'Delete Entity Browser');
-
-    $this->assertText('Entity browser Test entity browser was deleted.', 'Confirmation message found.');
-    $this->assertText('There is no Entity browser yet.', 'Entity browsers table is empty.');
-    $this->drupalLogout();
-  }
-
-}
diff --git a/web/modules/entity_browser/src/Tests/FormElementTest.php b/web/modules/entity_browser/src/Tests/FormElementTest.php
deleted file mode 100644
index 0a4ac415bd75e4a0858a95d77a5a26d7b3d0846f..0000000000000000000000000000000000000000
--- a/web/modules/entity_browser/src/Tests/FormElementTest.php
+++ /dev/null
@@ -1,74 +0,0 @@
-<?php
-
-namespace Drupal\entity_browser\Tests;
-
-use Drupal\entity_browser\Element\EntityBrowserElement;
-use Drupal\simpletest\WebTestBase;
-
-/**
- * Tests the entity browser form element.
- *
- * @group entity_browser
- */
-class FormElementTest extends WebTestBase {
-
-  /**
-   * Modules to enable.
-   *
-   * @var array
-   */
-  public static $modules = ['entity_browser_test', 'node', 'views'];
-
-  /**
-   * Test nodes.
-   *
-   * @var \Drupal\node\NodeInterface[]
-   */
-  protected $nodes;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-    $this->container
-      ->get('entity_type.manager')
-      ->getStorage('node_type')
-      ->create([
-        'type' => 'page',
-        'name' => 'page',
-      ])->save();
-
-    $this->nodes[] = $this->drupalCreateNode();
-    $this->nodes[] = $this->drupalCreateNode();
-  }
-
-  /**
-   * Tests the Entity browser form element.
-   */
-  public function testFormElement() {
-    $this->drupalGet('/test-element');
-    $this->assertLink('Select entities', 0, 'Trigger link found.');
-    $this->assertFieldByXPath("//input[@type='hidden' and @id='edit-fancy-entity-browser-target']", '', "Entity browser's hidden element found.");
-
-    $edit = [
-      'fancy_entity_browser[entity_ids]' => $this->nodes[0]->getEntityTypeId() . ':' . $this->nodes[0]->id() . ' ' . $this->nodes[1]->getEntityTypeId() . ':' . $this->nodes[1]->id(),
-    ];
-    $this->drupalPostForm(NULL, $edit, 'Submit');
-    $expected = 'Selected entities: ' . $this->nodes[0]->label() . ', ' . $this->nodes[1]->label();
-    $this->assertText($expected, 'Selected entities detected.');
-
-    $default_entity = $this->nodes[0]->getEntityTypeId() . ':' . $this->nodes[0]->id();
-    $this->drupalGet('/test-element', ['query' => ['default_entity' => $default_entity, 'selection_mode' => EntityBrowserElement::SELECTION_MODE_EDIT]]);
-    $this->assertLink('Select entities', 0, 'Trigger link found.');
-    $this->assertFieldByXPath("//input[@type='hidden' and @id='edit-fancy-entity-browser-target']", $default_entity, "Entity browser's hidden element found.");
-
-    $edit = [
-      'fancy_entity_browser[entity_ids]' => $this->nodes[1]->getEntityTypeId() . ':' . $this->nodes[1]->id() . ' ' . $this->nodes[0]->getEntityTypeId() . ':' . $this->nodes[0]->id(),
-    ];
-    $this->drupalPostForm(NULL, $edit, 'Submit');
-    $expected = 'Selected entities: ' . $this->nodes[1]->label() . ', ' . $this->nodes[0]->label();
-    $this->assertText($expected, 'Selected entities detected.');
-  }
-
-}
diff --git a/web/modules/entity_browser/src/Tests/MultistepDisplayTest.php b/web/modules/entity_browser/src/Tests/MultistepDisplayTest.php
deleted file mode 100644
index 1d91a5d344f1593cc727471b8d5360fb17ccb08a..0000000000000000000000000000000000000000
--- a/web/modules/entity_browser/src/Tests/MultistepDisplayTest.php
+++ /dev/null
@@ -1,80 +0,0 @@
-<?php
-
-namespace Drupal\entity_browser\Tests;
-
-use Drupal\simpletest\WebTestBase;
-
-/**
- * Tests the multistep display selection display.
- *
- * @group entity_browser
- */
-class MultistepDisplayTest extends WebTestBase {
-
-  /**
-   * Modules to enable.
-   *
-   * @var array
-   */
-  public static $modules = ['entity_browser', 'ctools', 'block', 'node', 'file'];
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-    $this->drupalPlaceBlock('local_actions_block');
-  }
-
-  /**
-   * Tests multistep display.
-   */
-  public function testMultistepDisplay() {
-    $account = $this->drupalCreateUser([
-      'administer entity browsers',
-    ]);
-    $this->drupalLogin($account);
-    $this->drupalGet('/admin/config/content/entity_browser');
-    $this->clickLink('Add Entity browser');
-    $edit = [
-      'label' => 'Test entity browser',
-      'id' => 'test_entity_browser',
-      'display' => 'iframe',
-      'widget_selector' => 'tabs',
-      'selection_display' => 'multi_step_display',
-    ];
-    $this->drupalPostForm(NULL, $edit, 'Next');
-    $this->drupalPostForm(NULL, [], 'Next');
-    $this->drupalPostForm(NULL, [], 'Next');
-
-    $this->assertText('Selection display', 'Trail is shown.');
-    $this->assertText('Select button text', 'Title is correct.');
-    $this->assertText('Text to display on the entity browser select button.', 'Description is correct.');
-    $this->assertRaw('Use selected', 'Default text is correct.');
-    $edit = [
-      'entity_type' => 'file',
-      'display' => 'label',
-      'selection_hidden' => 0,
-      'select_text' => 'Use blah selected',
-    ];
-    $this->drupalPostForm(NULL, $edit, 'Next');
-    $this->drupalPostAjaxForm(NULL, ['widget' => 'upload'], 'widget');
-    $this->drupalPostForm(NULL, [], 'Finish');
-
-    $account = $this->drupalCreateUser([
-      'access test_entity_browser entity browser pages',
-    ]);
-    $this->drupalLogin($account);
-    // Go to the entity browser iframe link.
-    $this->drupalGet('/entity-browser/iframe/test_entity_browser');
-    $this->assertNoRaw('Use blah selected');
-
-    $image = current($this->drupalGetTestFiles('image'));
-    $edit = [
-      'files[upload][]' => $this->container->get('file_system')->realpath($image->uri),
-    ];
-    $this->drupalPostForm(NULL, $edit, 'Select files');
-    $this->assertRaw('Use blah selected', 'Select button is displayed if something is selected.');
-  }
-
-}
diff --git a/web/modules/entity_browser/src/WidgetBase.php b/web/modules/entity_browser/src/WidgetBase.php
index da094e4cf556b78840f0bf17130c98076d9ca7de..f5d2ea7a895d7f9396a7010c8e04bdc682dc73ee 100644
--- a/web/modules/entity_browser/src/WidgetBase.php
+++ b/web/modules/entity_browser/src/WidgetBase.php
@@ -3,6 +3,7 @@
 namespace Drupal\entity_browser;
 
 use Drupal\Component\Utility\NestedArray;
+use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Plugin\PluginBase;
 use Drupal\Core\Form\FormStateInterface;
@@ -372,4 +373,11 @@ protected function handleWidgetContext($widget_context) {
     }
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function access() {
+    return AccessResult::allowed();
+  }
+
 }
diff --git a/web/modules/entity_browser/src/WidgetInterface.php b/web/modules/entity_browser/src/WidgetInterface.php
index 0a1140f7a987b371253147cd0ad4cf6a418ec0a1..3e9938a67b6ffdfda9aa25af15ca5493ff92867b 100644
--- a/web/modules/entity_browser/src/WidgetInterface.php
+++ b/web/modules/entity_browser/src/WidgetInterface.php
@@ -2,7 +2,8 @@
 
 namespace Drupal\entity_browser;
 
-use Drupal\Component\Plugin\ConfigurablePluginInterface;
+use Drupal\Component\Plugin\ConfigurableInterface;
+use Drupal\Component\Plugin\DependentPluginInterface;
 use Drupal\Component\Plugin\PluginInspectionInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Plugin\PluginFormInterface;
@@ -14,7 +15,7 @@
  * entity browser. Once entities have been selected, they are delivered upstream
  * to the entity browser's selection display plugin.
  */
-interface WidgetInterface extends PluginInspectionInterface, ConfigurablePluginInterface, PluginFormInterface {
+interface WidgetInterface extends PluginInspectionInterface, ConfigurableInterface, PluginFormInterface, DependentPluginInterface {
 
   /**
    * Returns the widget id.
@@ -118,4 +119,12 @@ public function submit(array &$element, array &$form, FormStateInterface $form_s
    */
   public function requiresJsCommands();
 
+  /**
+   * Defines if the widget is visible / accessible in a given context.
+   *
+   * @return \Drupal\Core\Access\AccessResultInterface
+   *   The access result.
+   */
+  public function access();
+
 }
diff --git a/web/modules/entity_browser/src/WidgetSelectorInterface.php b/web/modules/entity_browser/src/WidgetSelectorInterface.php
index 86d70120a30ea782145266f1e7da385bbf898718..b23bc39aca376e67fcf25af6d1f78096c56e2b00 100644
--- a/web/modules/entity_browser/src/WidgetSelectorInterface.php
+++ b/web/modules/entity_browser/src/WidgetSelectorInterface.php
@@ -2,7 +2,8 @@
 
 namespace Drupal\entity_browser;
 
-use Drupal\Component\Plugin\ConfigurablePluginInterface;
+use Drupal\Component\Plugin\ConfigurableInterface;
+use Drupal\Component\Plugin\DependentPluginInterface;
 use Drupal\Component\Plugin\PluginInspectionInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Plugin\PluginFormInterface;
@@ -15,7 +16,7 @@
  * if the user wants to tab between widgets, the tab set will be created and
  * managed by the widget selector.
  */
-interface WidgetSelectorInterface extends PluginInspectionInterface, ConfigurablePluginInterface, PluginFormInterface {
+interface WidgetSelectorInterface extends PluginInspectionInterface, ConfigurableInterface, PluginFormInterface, DependentPluginInterface {
 
   /**
    * Returns the widget selector label.
diff --git a/web/modules/entity_browser/src/WidgetValidationBase.php b/web/modules/entity_browser/src/WidgetValidationBase.php
index 57db8f79735b16bdf439654741c770dc2e041efb..0bb76d195d28dab23a86d7ce2ac12b6e8587ea0e 100644
--- a/web/modules/entity_browser/src/WidgetValidationBase.php
+++ b/web/modules/entity_browser/src/WidgetValidationBase.php
@@ -28,6 +28,9 @@ abstract class WidgetValidationBase extends PluginBase implements WidgetValidati
    */
   protected $typedDataManager;
 
+  /**
+   * {@inheritdoc}
+   */
   public function __construct(array $configuration, $plugin_id, $plugin_definition, TypedDataManagerInterface $typed_data_manager) {
     $plugin_definition += [
       'constraint' => NULL,
@@ -65,7 +68,7 @@ public function label() {
   /**
    * {@inheritdoc}
    */
-  public function validate(array $entities, $options = []) {
+  public function validate(array $entities, array $options = []) {
     $plugin_definition = $this->getPluginDefinition();
     $data_definition = $this->getDataDefinition($plugin_definition['data_type'], $plugin_definition['constraint'], $options);
     return $this->validateDataDefinition($data_definition, $entities);
@@ -99,13 +102,13 @@ public function calculateDependencies() {
    *   The data type plugin ID, for which a constraint should be added.
    * @param string $constraint_name
    *   The name of the constraint to add, i.e. its plugin id.
-   * @param $options
+   * @param array $options
    *   Array of options needed by the constraint validator.
    *
    * @return \Drupal\Core\TypedData\DataDefinitionInterface
    *   A data definition object for the given data type.
    */
-  protected function getDataDefinition($data_type, $constraint_name = NULL, $options = []) {
+  protected function getDataDefinition($data_type, $constraint_name = NULL, array $options = []) {
     $data_definition = $this->typedDataManager->createDataDefinition($data_type);
     if ($constraint_name) {
       $data_definition->addConstraint($constraint_name, $options);
@@ -119,7 +122,7 @@ protected function getDataDefinition($data_type, $constraint_name = NULL, $optio
    * @param \Drupal\Core\TypedData\DataDefinitionInterface $data_definition
    *   The data definition generated from ::getDataDefinition().
    * @param array $entities
-   *   An array of Entities to validate the definition against
+   *   An array of Entities to validate the definition against.
    *
    * @return \Symfony\Component\Validator\ConstraintViolationListInterface
    *   A list of violations.
@@ -133,4 +136,5 @@ protected function validateDataDefinition(DataDefinitionInterface $data_definiti
 
     return $violations;
   }
+
 }
diff --git a/web/modules/entity_browser/src/WidgetValidationInterface.php b/web/modules/entity_browser/src/WidgetValidationInterface.php
index 65ad7ef25afdee46ea117a7a0e8d2459863ca407..de5e4d566534e1d5d9420c9192d9c9f4964a58d5 100644
--- a/web/modules/entity_browser/src/WidgetValidationInterface.php
+++ b/web/modules/entity_browser/src/WidgetValidationInterface.php
@@ -2,14 +2,14 @@
 
 namespace Drupal\entity_browser;
 
-use Drupal\Component\Plugin\ConfigurablePluginInterface;
+use Drupal\Component\Plugin\ConfigurableInterface;
+use Drupal\Component\Plugin\DependentPluginInterface;
 use Drupal\Component\Plugin\PluginInspectionInterface;
 
-
 /**
  * Defines the interface for entity browser widget validations.
  */
-interface WidgetValidationInterface extends PluginInspectionInterface, ConfigurablePluginInterface {
+interface WidgetValidationInterface extends PluginInspectionInterface, ConfigurableInterface, DependentPluginInterface {
 
   /**
    * Returns the widget validation label.
@@ -31,5 +31,6 @@ public function label();
    *   A list of constraint violations. If the list is empty, validation
    *   succeeded.
    */
-  public function validate(array $entities, $options = []);
+  public function validate(array $entities, array $options = []);
+
 }
diff --git a/web/modules/entity_browser/src/Wizard/EntityBrowserWizard.php b/web/modules/entity_browser/src/Wizard/EntityBrowserWizard.php
deleted file mode 100644
index 4174bcb8046342c1b562abb1d1d6deedc46e34ad..0000000000000000000000000000000000000000
--- a/web/modules/entity_browser/src/Wizard/EntityBrowserWizard.php
+++ /dev/null
@@ -1,122 +0,0 @@
-<?php
-
-namespace Drupal\entity_browser\Wizard;
-
-use Drupal\Core\DependencyInjection\ClassResolverInterface;
-use Drupal\Core\Entity\EntityManagerInterface;
-use Drupal\Core\Form\FormBuilderInterface;
-use Drupal\Core\Routing\RouteMatchInterface;
-use Drupal\ctools\Wizard\EntityFormWizardBase;
-use Drupal\entity_browser\Form\DisplayConfig;
-use Drupal\entity_browser\Form\GeneralInfoConfig;
-use Drupal\entity_browser\Form\SelectionDisplayConfig;
-use Drupal\entity_browser\Form\WidgetsConfig;
-use Drupal\entity_browser\Form\WidgetSelectorConfig;
-use Drupal\user\SharedTempStoreFactory;
-use Symfony\Component\EventDispatcher\EventDispatcherInterface;
-
-/**
- * Custom form wizard for entity browser configuration.
- */
-class EntityBrowserWizard extends EntityFormWizardBase {
-
-  /**
-   * @param \Drupal\user\SharedTempStoreFactory $tempstore
-   *   Tempstore Factory for keeping track of values in each step of the
-   *   wizard.
-   * @param \Drupal\Core\Form\FormBuilderInterface $builder
-   *   The Form Builder.
-   * @param \Drupal\Core\DependencyInjection\ClassResolverInterface $class_resolver
-   *   The class resolver.
-   * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
-   *   The event dispatcher.
-   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
-   *   The entity manager.
-   * @param $tempstore_id
-   *   The shared temp store factory collection name.
-   * @param null $machine_name
-   *   The SharedTempStore key for our current wizard values.
-   * @param null $step
-   *   The current active step of the wizard.
-   */
-  public function __construct(SharedTempStoreFactory $tempstore, FormBuilderInterface $builder, ClassResolverInterface $class_resolver, EventDispatcherInterface $event_dispatcher, EntityManagerInterface $entity_manager, RouteMatchInterface $route_match, $tempstore_id, $entity_browser = NULL, $step = 'general') {
-    parent::__construct($tempstore, $builder, $class_resolver, $event_dispatcher, $entity_manager, $route_match, $tempstore_id, $entity_browser, $step);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getNextParameters($cached_values) {
-    $parameters = parent::getNextParameters($cached_values);
-    $parameters['entity_browser'] = $parameters['machine_name'];
-    unset($parameters['machine_name']);
-    return $parameters;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getPreviousParameters($cached_values) {
-    $parameters = parent::getPreviousParameters($cached_values);
-    $parameters['entity_browser'] = $parameters['machine_name'];
-    unset($parameters['machine_name']);
-    return $parameters;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getWizardLabel() {
-    return $this->t('Entity browser');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getMachineLabel() {
-    return $this->t('Label');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getEntityType() {
-    return 'entity_browser';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function exists() {
-    return 'Drupal\entity_browser\Entity\EntityBrowser::load';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getOperations($cached_values) {
-    return [
-      'general' => [
-        'title' => $this->t('General information'),
-        'form' => GeneralInfoConfig::class,
-      ],
-      'display' => [
-        'title' => $this->t('Display'),
-        'form' => DisplayConfig::class,
-      ],
-      'widget_selector' => [
-        'title' => $this->t('Widget selector'),
-        'form' => WidgetSelectorConfig::class,
-      ],
-      'selection_display' => [
-        'title' => $this->t('Selection display'),
-        'form' => SelectionDisplayConfig::class,
-      ],
-      'widgets' => [
-        'title' => $this->t('Widgets'),
-        'form' => WidgetsConfig::class,
-      ],
-    ];
-  }
-
-}
diff --git a/web/modules/entity_browser/src/Wizard/EntityBrowserWizardAdd.php b/web/modules/entity_browser/src/Wizard/EntityBrowserWizardAdd.php
deleted file mode 100644
index 15a9f92c7c938a88657e165c452e6f2f44d3341c..0000000000000000000000000000000000000000
--- a/web/modules/entity_browser/src/Wizard/EntityBrowserWizardAdd.php
+++ /dev/null
@@ -1,17 +0,0 @@
-<?php
-
-namespace Drupal\entity_browser\Wizard;
-
-/**
- * Custom override for create form.
- */
-class EntityBrowserWizardAdd extends EntityBrowserWizard {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getRouteName() {
-    return 'entity.entity_browser.edit_form';
-  }
-
-}
diff --git a/web/modules/entity_browser/tests/fixtures/update/entity_browser.update-hook-test.php b/web/modules/entity_browser/tests/fixtures/update/entity_browser.update-hook-test.php
index 0a9e0234d0e3bdd2a5257a41ec46ea4fe1502c9b..215f7a57697e2845436f52c51164abbbcd53b188 100644
--- a/web/modules/entity_browser/tests/fixtures/update/entity_browser.update-hook-test.php
+++ b/web/modules/entity_browser/tests/fixtures/update/entity_browser.update-hook-test.php
@@ -1,5 +1,11 @@
 <?php
 
+/**
+ * @file Contains entity_browser.update-hook-test.php.
+ *
+ * Adds some configs to allow testing update hook.
+ */
+
 use Drupal\Core\Database\Database;
 use Drupal\Component\Serialization\Yaml;
 
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_entity_embed_test/config/install/core.entity_form_display.node.test_entity_embed.default.yml b/web/modules/entity_browser/tests/modules/entity_browser_entity_embed_test/config/install/core.entity_form_display.node.test_entity_embed.default.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c66dc4443b7be26238215b6b7a58e7836ff61bc2
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_entity_embed_test/config/install/core.entity_form_display.node.test_entity_embed.default.yml
@@ -0,0 +1,74 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - field.field.node.test_entity_embed.body
+    - node.type.test_entity_embed
+  module:
+    - path
+    - text
+id: node.test_entity_embed.default
+targetEntityType: node
+bundle: test_entity_embed
+mode: default
+content:
+  body:
+    type: text_textarea_with_summary
+    weight: 121
+    settings:
+      rows: 9
+      summary_rows: 3
+      placeholder: ''
+    third_party_settings: {  }
+    region: content
+  created:
+    type: datetime_timestamp
+    weight: 10
+    region: content
+    settings: {  }
+    third_party_settings: {  }
+  path:
+    type: path
+    weight: 30
+    region: content
+    settings: {  }
+    third_party_settings: {  }
+  promote:
+    type: boolean_checkbox
+    settings:
+      display_label: true
+    weight: 15
+    region: content
+    third_party_settings: {  }
+  status:
+    type: boolean_checkbox
+    settings:
+      display_label: true
+    weight: 120
+    region: content
+    third_party_settings: {  }
+  sticky:
+    type: boolean_checkbox
+    settings:
+      display_label: true
+    weight: 16
+    region: content
+    third_party_settings: {  }
+  title:
+    type: string_textfield
+    weight: -5
+    region: content
+    settings:
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+  uid:
+    type: entity_reference_autocomplete
+    weight: 5
+    settings:
+      match_operator: CONTAINS
+      size: 60
+      placeholder: ''
+    region: content
+    third_party_settings: {  }
+hidden: {  }
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_entity_embed_test/config/install/core.entity_view_display.node.test_entity_embed.default.yml b/web/modules/entity_browser/tests/modules/entity_browser_entity_embed_test/config/install/core.entity_view_display.node.test_entity_embed.default.yml
new file mode 100644
index 0000000000000000000000000000000000000000..e30f825c1cb22e6455ca68da8af15603f6b26b26
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_entity_embed_test/config/install/core.entity_view_display.node.test_entity_embed.default.yml
@@ -0,0 +1,27 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - field.field.node.test_entity_embed.body
+    - node.type.test_entity_embed
+  module:
+    - text
+    - user
+id: node.test_entity_embed.default
+targetEntityType: node
+bundle: test_entity_embed
+mode: default
+content:
+  body:
+    label: hidden
+    type: text_default
+    weight: 101
+    settings: {  }
+    third_party_settings: {  }
+    region: content
+  links:
+    weight: 100
+    settings: {  }
+    third_party_settings: {  }
+    region: content
+hidden: {  }
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_entity_embed_test/config/install/editor.editor.full_html.yml b/web/modules/entity_browser/tests/modules/entity_browser_entity_embed_test/config/install/editor.editor.full_html.yml
new file mode 100644
index 0000000000000000000000000000000000000000..d413cfdd9b5c2de80b12597d05351c2307d8aeb1
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_entity_embed_test/config/install/editor.editor.full_html.yml
@@ -0,0 +1,64 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - filter.format.full_html
+  module:
+    - ckeditor
+format: full_html
+editor: ckeditor
+settings:
+  toolbar:
+    rows:
+      -
+        -
+          name: Formatting
+          items:
+            - Bold
+            - Italic
+            - Strike
+            - Superscript
+            - Subscript
+            - '-'
+            - RemoveFormat
+        -
+          name: Linking
+          items:
+            - DrupalLink
+            - DrupalUnlink
+        -
+          name: Lists
+          items:
+            - BulletedList
+            - NumberedList
+        -
+          name: Media
+          items:
+            - Blockquote
+            - DrupalImage
+            - Table
+            - HorizontalRule
+            - jet_shark_embed
+            - bundle_filter_test
+        -
+          name: 'Block Formatting'
+          items:
+            - Format
+        -
+          name: Tools
+          items:
+            - ShowBlocks
+            - Source
+  plugins:
+    language:
+      language_list: un
+    stylescombo:
+      styles: ''
+image_upload:
+  status: true
+  scheme: public
+  directory: inline-images
+  max_size: ''
+  max_dimensions:
+    width: null
+    height: null
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_entity_embed_test/config/install/embed.button.bundle_filter_test.yml b/web/modules/entity_browser/tests/modules/entity_browser_entity_embed_test/config/install/embed.button.bundle_filter_test.yml
new file mode 100644
index 0000000000000000000000000000000000000000..d528c51266bdff07815a413b9c63a04b5aa64acf
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_entity_embed_test/config/install/embed.button.bundle_filter_test.yml
@@ -0,0 +1,26 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - entity_browser.browser.widget_context_default_value
+    - node.type.jet
+    - node.type.shark
+  module:
+    - entity_browser_test
+    - entity_embed
+    - node
+label: 'Bundle Filter Test Embed'
+id: bundle_filter_test
+type_id: entity
+type_settings:
+  entity_type: node
+  bundles:
+    - jet
+    - shark
+  display_plugins:
+    - 'entity_reference:entity_reference_label'
+  entity_browser: bundle_filter
+  entity_browser_settings:
+    display_review: false
+icon_uuid: null
+icon_path: null
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_entity_embed_test/config/install/embed.button.jet_shark_embed.yml b/web/modules/entity_browser/tests/modules/entity_browser_entity_embed_test/config/install/embed.button.jet_shark_embed.yml
new file mode 100644
index 0000000000000000000000000000000000000000..f84c3b5d0fcbf17b160c401ef487afe3af67b026
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_entity_embed_test/config/install/embed.button.jet_shark_embed.yml
@@ -0,0 +1,26 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - entity_browser.browser.widget_context_default_value
+    - node.type.jet
+    - node.type.shark
+  module:
+    - entity_browser_test
+    - entity_embed
+    - node
+label: 'Jet Shark Embed'
+id: jet_shark_embed
+type_id: entity
+type_settings:
+  entity_type: node
+  bundles:
+    - jet
+    - shark
+  display_plugins:
+    - 'entity_reference:entity_reference_label'
+  entity_browser: widget_context_default_value
+  entity_browser_settings:
+    display_review: false
+icon_uuid: null
+icon_path: null
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_entity_embed_test/config/install/field.field.node.test_entity_embed.body.yml b/web/modules/entity_browser/tests/modules/entity_browser_entity_embed_test/config/install/field.field.node.test_entity_embed.body.yml
new file mode 100644
index 0000000000000000000000000000000000000000..3114f763058514eb9367404861211a61840a1770
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_entity_embed_test/config/install/field.field.node.test_entity_embed.body.yml
@@ -0,0 +1,21 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - field.storage.node.body
+    - node.type.test_entity_embed
+  module:
+    - text
+id: node.test_entity_embed.body
+field_name: body
+entity_type: node
+bundle: test_entity_embed
+label: Body
+description: ''
+required: false
+translatable: true
+default_value: {  }
+default_value_callback: ''
+settings:
+  display_summary: true
+field_type: text_with_summary
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_entity_embed_test/config/install/filter.format.basic_html.yml b/web/modules/entity_browser/tests/modules/entity_browser_entity_embed_test/config/install/filter.format.basic_html.yml
new file mode 100644
index 0000000000000000000000000000000000000000..30d77183abb265d1970f2b77b03d3e87b11c550a
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_entity_embed_test/config/install/filter.format.basic_html.yml
@@ -0,0 +1,42 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - editor
+name: 'Basic HTML'
+format: basic_html
+weight: -9
+filters:
+  filter_html:
+    id: filter_html
+    provider: filter
+    status: true
+    weight: -10
+    settings:
+      allowed_html: '<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id> <p> <br> <span> <img src alt height width data-entity-type data-entity-uuid data-align data-caption>'
+      filter_html_help: false
+      filter_html_nofollow: false
+  filter_align:
+    id: filter_align
+    provider: filter
+    status: true
+    weight: 7
+    settings: {  }
+  filter_caption:
+    id: filter_caption
+    provider: filter
+    status: true
+    weight: 8
+    settings: {  }
+  filter_html_image_secure:
+    id: filter_html_image_secure
+    provider: filter
+    status: true
+    weight: 9
+    settings: {  }
+  editor_file_reference:
+    id: editor_file_reference
+    provider: editor
+    status: true
+    weight: 11
+    settings: {  }
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_entity_embed_test/config/install/filter.format.full_html.yml b/web/modules/entity_browser/tests/modules/entity_browser_entity_embed_test/config/install/filter.format.full_html.yml
new file mode 100644
index 0000000000000000000000000000000000000000..a8a4788218bdd34ed809cf4ecaae4fc92a8eebf8
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_entity_embed_test/config/install/filter.format.full_html.yml
@@ -0,0 +1,49 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - editor
+    - entity_embed
+name: 'Full HTML'
+format: full_html
+weight: -10
+filters:
+  filter_align:
+    id: filter_align
+    provider: filter
+    status: true
+    weight: 8
+    settings: {  }
+  filter_caption:
+    id: filter_caption
+    provider: filter
+    status: true
+    weight: 9
+    settings: {  }
+  filter_htmlcorrector:
+    id: filter_htmlcorrector
+    provider: filter
+    status: true
+    weight: 10
+    settings: {  }
+  editor_file_reference:
+    id: editor_file_reference
+    provider: editor
+    status: true
+    weight: 11
+    settings: {  }
+  entity_embed:
+    id: entity_embed
+    provider: entity_embed
+    status: true
+    weight: 0
+    settings: {  }
+  filter_html:
+    id: filter_html
+    provider: filter
+    status: false
+    weight: -10
+    settings:
+      allowed_html: '<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id> <s> <sup> <sub> <img src alt data-entity-type data-entity-uuid data-align data-caption> <table> <caption> <tbody> <thead> <tfoot> <th> <td> <tr> <hr> <p> <h1> <pre> <drupal-entity data-entity-type data-entity-uuid data-entity-embed-display data-entity-embed-display-settings data-align data-caption data-embed-button>'
+      filter_html_help: true
+      filter_html_nofollow: false
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_entity_embed_test/config/install/node.type.test_entity_embed.yml b/web/modules/entity_browser/tests/modules/entity_browser_entity_embed_test/config/install/node.type.test_entity_embed.yml
new file mode 100644
index 0000000000000000000000000000000000000000..b3739d7828f5d9d654917d94920afeb709e31680
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_entity_embed_test/config/install/node.type.test_entity_embed.yml
@@ -0,0 +1,10 @@
+langcode: en
+status: true
+dependencies: {  }
+name: 'Test Entity Embed'
+type: test_entity_embed
+description: 'Test content type for problem with inconsistent state of inline entity form entity browser field widget.'
+help: ''
+new_revision: false
+preview_mode: 1
+display_submitted: true
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_entity_embed_test/entity_browser_entity_embed_test.info.yml b/web/modules/entity_browser/tests/modules/entity_browser_entity_embed_test/entity_browser_entity_embed_test.info.yml
new file mode 100644
index 0000000000000000000000000000000000000000..d6537966dd4487bd2aa58da461b4ba4e1e814c8d
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_entity_embed_test/entity_browser_entity_embed_test.info.yml
@@ -0,0 +1,23 @@
+name: 'Test IEF'
+type: module
+description: 'Test Entity Embed Integration'
+core_version_requirement: ^8.7.7 || ^9
+package: Testing
+dependencies:
+  - media_entity:media_entity
+  - drupal:ckeditor
+  - drupal:node
+  - drupal:views
+  - drupal:file
+  - drupal:text
+  - drupal:path
+  - drupal:editor
+  - embed:embed
+  - entity_embed:entity_embed
+  - entity_browser:entity_browser
+  - entity_browser_test:entity_browser_test
+
+# Information added by Drupal.org packaging script on 2020-01-20
+version: '8.x-1.10'
+project: 'entity_browser'
+datestamp: 1579563796
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_ief_test/config/install/core.entity_form_display.media.ief_media_bundle.default.yml b/web/modules/entity_browser/tests/modules/entity_browser_ief_test/config/install/core.entity_form_display.media.ief_media_bundle.default.yml
index 6288723e9d55828f2f42ebcfa489b1c9c42ce9da..f2ab144332a53aa771064b1a2e2cd9357ec0533f 100644
--- a/web/modules/entity_browser/tests/modules/entity_browser_ief_test/config/install/core.entity_form_display.media.ief_media_bundle.default.yml
+++ b/web/modules/entity_browser/tests/modules/entity_browser_ief_test/config/install/core.entity_form_display.media.ief_media_bundle.default.yml
@@ -18,6 +18,7 @@ content:
       field_widget_display: label
       field_widget_edit: true
       field_widget_remove: true
+      field_widget_replace: false
       open: true
       selection_mode: selection_edit
       field_widget_display_settings: {  }
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_ief_test/config/install/core.entity_form_display.node.ief_content.default.yml b/web/modules/entity_browser/tests/modules/entity_browser_ief_test/config/install/core.entity_form_display.node.ief_content.default.yml
index 6d1e151817d1d3530c4f41de6ecb6543a28e3d05..93cfc2394f72d3ccd9978001db60c060485be224 100644
--- a/web/modules/entity_browser/tests/modules/entity_browser_ief_test/config/install/core.entity_form_display.node.ief_content.default.yml
+++ b/web/modules/entity_browser/tests/modules/entity_browser_ief_test/config/install/core.entity_form_display.node.ief_content.default.yml
@@ -2,6 +2,7 @@ langcode: en
 status: true
 dependencies:
   config:
+    - field.field.node.ief_content.field_nodes
     - field.field.node.ief_content.ief_media_field
     - node.type.ief_content
   module:
@@ -12,6 +13,21 @@ targetEntityType: node
 bundle: ief_content
 mode: default
 content:
+  field_nodes:
+    weight: 121
+    settings:
+      form_mode: default
+      label_singular: ''
+      label_plural: ''
+      allow_existing: true
+      match_operator: CONTAINS
+      override_labels: false
+      allow_new: false
+    third_party_settings:
+      entity_browser_entity_form:
+        entity_browser_id: widget_context_default_value
+    type: inline_entity_form_complex
+    region: content
   ief_media_field:
     weight: 31
     settings:
@@ -26,6 +42,14 @@ content:
       entity_browser_entity_form:
         entity_browser_id: _none
     type: inline_entity_form_complex
+    region: content
+  status:
+    type: boolean_checkbox
+    settings:
+      display_label: true
+    weight: 120
+    region: content
+    third_party_settings: {  }
   title:
     type: string_textfield
     weight: -5
@@ -33,6 +57,7 @@ content:
       size: 60
       placeholder: ''
     third_party_settings: {  }
+    region: content
 hidden:
   created: true
   path: true
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_ief_test/config/install/core.entity_view_display.node.ief_content.default.yml b/web/modules/entity_browser/tests/modules/entity_browser_ief_test/config/install/core.entity_view_display.node.ief_content.default.yml
index f4a79193bfd82ec9c8a89a51501222d43bc2c0ca..2bcb9b35bafc6f55354e3c207e922c3a99a53279 100644
--- a/web/modules/entity_browser/tests/modules/entity_browser_ief_test/config/install/core.entity_view_display.node.ief_content.default.yml
+++ b/web/modules/entity_browser/tests/modules/entity_browser_ief_test/config/install/core.entity_view_display.node.ief_content.default.yml
@@ -2,6 +2,7 @@ langcode: en
 status: true
 dependencies:
   config:
+    - field.field.node.ief_content.field_nodes
     - field.field.node.ief_content.ief_media_field
     - node.type.ief_content
   module:
@@ -11,6 +12,14 @@ targetEntityType: node
 bundle: ief_content
 mode: default
 content:
+  field_nodes:
+    weight: 102
+    label: above
+    settings:
+      link: true
+    third_party_settings: {  }
+    type: entity_reference_label
+    region: content
   ief_media_field:
     weight: 101
     label: above
@@ -18,5 +27,6 @@ content:
       link: true
     third_party_settings: {  }
     type: entity_reference_label
+    region: content
 hidden:
   links: true
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_ief_test/config/install/field.field.node.ief_content.field_nodes.yml b/web/modules/entity_browser/tests/modules/entity_browser_ief_test/config/install/field.field.node.ief_content.field_nodes.yml
new file mode 100644
index 0000000000000000000000000000000000000000..f1bfd25b8c55463b20a1af8b205f933dc82a5abc
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_ief_test/config/install/field.field.node.ief_content.field_nodes.yml
@@ -0,0 +1,31 @@
+langcode: en
+status: true
+dependencies:
+  modules:
+    - entity_browser_test
+  config:
+    - field.storage.node.field_nodes
+    - node.type.shark
+    - node.type.ief_content
+    - node.type.jet
+id: node.ief_content.field_nodes
+field_name: field_nodes
+entity_type: node
+bundle: ief_content
+label: Nodes
+description: ''
+required: false
+translatable: true
+default_value: {  }
+default_value_callback: ''
+settings:
+  handler: 'default:node'
+  handler_settings:
+    target_bundles:
+      jet: jet
+      shark: shark
+    sort:
+      field: _none
+    auto_create: false
+    auto_create_bundle: jet
+field_type: entity_reference
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_ief_test/config/install/field.storage.node.field_nodes.yml b/web/modules/entity_browser/tests/modules/entity_browser_ief_test/config/install/field.storage.node.field_nodes.yml
new file mode 100644
index 0000000000000000000000000000000000000000..7033b07999c473ffce640652adca59c706bfe5d5
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_ief_test/config/install/field.storage.node.field_nodes.yml
@@ -0,0 +1,21 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - entity_browser_ief_test
+    - node
+  enforced:
+    module:
+      - entity_browser_ief_test
+id: node.field_nodes
+field_name: field_nodes
+entity_type: node
+type: entity_reference
+settings:
+  target_type: node
+module: entity_browser_ief_test
+locked: false
+cardinality: -1
+translatable: false
+indexes: {  }
+persist_with_no_fields: false
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_ief_test/config/install/node.type.ief_content.yml b/web/modules/entity_browser/tests/modules/entity_browser_ief_test/config/install/node.type.ief_content.yml
index 43f311accbd3aebad76f857ce20d88c97d70da28..ea326b48bd72ce721fea545a8c59a72d891f2823 100644
--- a/web/modules/entity_browser/tests/modules/entity_browser_ief_test/config/install/node.type.ief_content.yml
+++ b/web/modules/entity_browser/tests/modules/entity_browser_ief_test/config/install/node.type.ief_content.yml
@@ -1,5 +1,6 @@
 langcode: en
 status: true
+dependencies: {  }
 name: 'Test IEF Content'
 type: ief_content
 description: 'Test content type for problem with inconsistent state of inline entity form entity browser field widget.'
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_ief_test/entity_browser_ief_test.info.yml b/web/modules/entity_browser/tests/modules/entity_browser_ief_test/entity_browser_ief_test.info.yml
index e332fec4cfa3953cda8821e36e8588a63996843f..a9831a60ad5b87c016e55c65aa84e8a5d846c5c8 100644
--- a/web/modules/entity_browser/tests/modules/entity_browser_ief_test/entity_browser_ief_test.info.yml
+++ b/web/modules/entity_browser/tests/modules/entity_browser_ief_test/entity_browser_ief_test.info.yml
@@ -1,19 +1,18 @@
 name: 'Test IEF'
 type: module
 description: 'Test Inline Entity Form Integration'
-# core: 8.x
+core_version_requirement: ^8.7.7 || ^9
 package: Testing
-# version: VERSION
 dependencies:
-  - file
-  - entity_browser
-  - entity_browser_entity_form
-  - media_entity
-  - inline_entity_form
-  - views
+  - drupal:file
+  - entity_browser:entity_browser
+  - entity_browser_entity_form:entity_browser_entity_form
+  - entity_browser_test:entity_browser_test
+  - media_entity:media_entity
+  - inline_entity_form:inline_entity_form
+  - drupal:views
 
-# Information added by Drupal.org packaging script on 2017-11-30
-version: '8.x-1.4'
-core: '8.x'
+# Information added by Drupal.org packaging script on 2020-01-20
+version: '8.x-1.10'
 project: 'entity_browser'
-datestamp: 1512033788
+datestamp: 1579563796
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/core.entity_form_display.node.article.default.yml b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/core.entity_form_display.node.article.default.yml
new file mode 100644
index 0000000000000000000000000000000000000000..62fecd40ba18b351984e8ef5a8a2f3e0e69cb27c
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/core.entity_form_display.node.article.default.yml
@@ -0,0 +1,25 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - node.type.article
+  module: { }
+id: node.article.default
+targetEntityType: node
+bundle: article
+mode: default
+content:
+  title:
+    type: string_textfield
+    weight: -5
+    settings:
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+    region: content
+hidden:
+  created: true
+  path: true
+  promote: true
+  sticky: true
+  uid: true
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/core.entity_form_display.node.jet.default.yml b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/core.entity_form_display.node.jet.default.yml
new file mode 100644
index 0000000000000000000000000000000000000000..16c42230e8d3e82ef6c081039cca72e0babdea84
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/core.entity_form_display.node.jet.default.yml
@@ -0,0 +1,25 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - node.type.jet
+  module: { }
+id: node.jet.default
+targetEntityType: node
+bundle: jet
+mode: default
+content:
+  title:
+    type: string_textfield
+    weight: -5
+    settings:
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+    region: content
+hidden:
+  created: true
+  path: true
+  promote: true
+  sticky: true
+  uid: true
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/core.entity_form_display.node.shark.default.yml b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/core.entity_form_display.node.shark.default.yml
new file mode 100644
index 0000000000000000000000000000000000000000..645b8c2322c8cb4dd9051bd1ffc5dee83f409b90
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/core.entity_form_display.node.shark.default.yml
@@ -0,0 +1,25 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - node.type.shark
+  module: { }
+id: node.shark.default
+targetEntityType: node
+bundle: shark
+mode: default
+content:
+  title:
+    type: string_textfield
+    weight: -5
+    settings:
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+    region: content
+hidden:
+  created: true
+  path: true
+  promote: true
+  sticky: true
+  uid: true
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/core.entity_view_display.node.article.default.yml b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/core.entity_view_display.node.article.default.yml
new file mode 100644
index 0000000000000000000000000000000000000000..744f81d943c8ff39d6e6aa6127da6c5b2666d9fa
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/core.entity_view_display.node.article.default.yml
@@ -0,0 +1,14 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - node.type.article
+  module:
+    - user
+id: node.article.default
+targetEntityType: node
+bundle: article
+mode: default
+content: {}
+hidden:
+  links: true
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/core.entity_view_display.node.jet.default.yml b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/core.entity_view_display.node.jet.default.yml
new file mode 100644
index 0000000000000000000000000000000000000000..1a5c3a4e09728ddf71ff072ca3a312480c8f2afb
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/core.entity_view_display.node.jet.default.yml
@@ -0,0 +1,14 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - node.type.jet
+  module:
+    - user
+id: node.jet.default
+targetEntityType: node
+bundle: jet
+mode: default
+content: {}
+hidden:
+  links: true
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/core.entity_view_display.node.shark.default.yml b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/core.entity_view_display.node.shark.default.yml
new file mode 100644
index 0000000000000000000000000000000000000000..697224b4ca09ef13d88251fec4a0a6efc28618af
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/core.entity_view_display.node.shark.default.yml
@@ -0,0 +1,14 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - node.type.shark
+  module:
+    - user
+id: node.shark.default
+targetEntityType: node
+bundle: shark
+mode: default
+content: {}
+hidden:
+  links: true
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/entity_browser.browser.bundle_filter.yml b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/entity_browser.browser.bundle_filter.yml
new file mode 100644
index 0000000000000000000000000000000000000000..a0e6b669f92c17cbd672677f41cf62cda464b7dc
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/entity_browser.browser.bundle_filter.yml
@@ -0,0 +1,35 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - views.view.bundle_filter
+  module:
+    - views
+name: bundle_filter
+label: 'ContextualBundle Test'
+display: iframe
+display_configuration:
+  width: '650'
+  height: '500'
+  link_text: 'Select entities'
+  auto_open: true
+selection_display: multi_step_display
+selection_display_configuration:
+  entity_type: node
+  display: label
+  display_settings: {  }
+  select_text: 'Use selected'
+  selection_hidden: false
+widget_selector: single
+widget_selector_configuration: {  }
+widgets:
+  b882a89d-9ce4-4dfe-9802-62df93af232a:
+    settings:
+      view: bundle_filter
+      view_display: entity_browser_1
+      submit_text: 'Select entities'
+      auto_select: false
+    uuid: b882a89d-9ce4-4dfe-9802-62df93af232a
+    weight: 1
+    label: view
+    id: view
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/entity_browser.browser.cardinality.yml b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/entity_browser.browser.cardinality.yml
new file mode 100644
index 0000000000000000000000000000000000000000..3c4a5dd5455fff505ddd0cb0bc91d82719e8d812
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/entity_browser.browser.cardinality.yml
@@ -0,0 +1,30 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - views.view.bundle_filter_exposed
+  module:
+    - views
+name: cardinality
+label: 'Cardinality Test'
+display: iframe
+display_configuration:
+  width: '650'
+  height: '500'
+  link_text: 'Select entities'
+  auto_open: false
+selection_display: no_display
+selection_display_configuration: {  }
+widget_selector: single
+widget_selector_configuration: {  }
+widgets:
+  b882a89d-9ce4-4dfe-9802-62df93af232a:
+    settings:
+      view: bundle_filter_exposed
+      view_display: entity_browser_1
+      submit_text: 'Select entities'
+      auto_select: false
+    uuid: b882a89d-9ce4-4dfe-9802-62df93af232a
+    weight: 1
+    label: view
+    id: view
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/entity_browser.browser.test_double_underscore.yml b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/entity_browser.browser.test_double_underscore.yml
new file mode 100644
index 0000000000000000000000000000000000000000..1962bf84b93460e8e3e23601843e7bdc3e19d9f6
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/entity_browser.browser.test_double_underscore.yml
@@ -0,0 +1,30 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - views.view.double__underscore
+  module:
+    - views
+name: test_double_underscore
+label: 'Test entity browser with view with double undescore in machine name'
+display: modal
+display_configuration:
+  width: '650'
+  height: '500'
+  link_text: 'Select entities'
+  auto_open: true
+selection_display: no_display
+selection_display_configuration: {  }
+widget_selector: single
+widget_selector_configuration: {  }
+widgets:
+  2bc90663-50f6-4a01-98a3-734f97bf89eb:
+    settings:
+      view: double__underscore
+      view_display: entity_browser_1
+      submit_text: 'Select entities'
+      auto_select: false
+    uuid: 2bc90663-50f6-4a01-98a3-734f97bf89eb
+    weight: 1
+    label: view
+    id: view
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/entity_browser.browser.test_entity_browser_file.yml b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/entity_browser.browser.test_entity_browser_file.yml
index 65178f0e2117a0966f9db7dad7644b28f1c08f30..d75ba00ea951359885e967d874d015635bc2199f 100644
--- a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/entity_browser.browser.test_entity_browser_file.yml
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/entity_browser.browser.test_entity_browser_file.yml
@@ -35,3 +35,10 @@ widgets:
     weight: -10
     label: view
     id: view
+  cbc59500-04ab-4395-b063-c561f0e3bf80:
+    id: dummy
+    label: dummy
+    weight: -8
+    uuid: cbc59500-04ab-4395-b063-c561f0e3bf80
+    settings:
+      text: 'This is dummy widget.'
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/entity_browser.browser.widget_context_default_value.yml b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/entity_browser.browser.widget_context_default_value.yml
new file mode 100644
index 0000000000000000000000000000000000000000..ab0abdcae251ec28f8239f51d1d43f60f8ff90c8
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/entity_browser.browser.widget_context_default_value.yml
@@ -0,0 +1,35 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - views.view.widget_context_default_value
+  module:
+    - views
+name: widget_context_default_value
+label: 'Widget Context Default Value'
+display: iframe
+display_configuration:
+  width: '650'
+  height: '500'
+  link_text: 'Select entities'
+  auto_open: true
+selection_display: multi_step_display
+selection_display_configuration:
+  entity_type: node
+  display: label
+  display_settings: {  }
+  select_text: 'Use selected'
+  selection_hidden: false
+widget_selector: single
+widget_selector_configuration: {  }
+widgets:
+  8ebb9947-ed87-4d65-a810-7edec034de0c:
+    settings:
+      view: widget_context_default_value
+      view_display: entity_browser_1
+      submit_text: 'Select entities'
+      auto_select: false
+    uuid: 8ebb9947-ed87-4d65-a810-7edec034de0c
+    weight: 1
+    label: view
+    id: view
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/node.type.article.yml b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/node.type.article.yml
new file mode 100644
index 0000000000000000000000000000000000000000..a65ff908d029b0359e91368cb455f535d9a12786
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/node.type.article.yml
@@ -0,0 +1,10 @@
+langcode: en
+status: true
+dependencies: {  }
+name: 'Article'
+type: article
+description: 'Article'
+help: ''
+new_revision: false
+preview_mode: 1
+display_submitted: true
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/node.type.jet.yml b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/node.type.jet.yml
new file mode 100644
index 0000000000000000000000000000000000000000..05e265a99211797f65a940e849984089f0def951
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/node.type.jet.yml
@@ -0,0 +1,10 @@
+langcode: en
+status: true
+dependencies: {  }
+name: 'Jet'
+type: jet
+description: 'Jet'
+help: ''
+new_revision: false
+preview_mode: 1
+display_submitted: true
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/node.type.shark.yml b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/node.type.shark.yml
new file mode 100644
index 0000000000000000000000000000000000000000..dc561ea77ae3f46437a47e9ef7d7242768c2e9c6
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/node.type.shark.yml
@@ -0,0 +1,10 @@
+langcode: en
+status: true
+dependencies: {  }
+name: 'Shark'
+type: shark
+description: 'Shark'
+help: ''
+new_revision: false
+preview_mode: 1
+display_submitted: true
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.bundle_filter.yml b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.bundle_filter.yml
new file mode 100644
index 0000000000000000000000000000000000000000..f5a12bc58ee00670b357a0e3d35730ca60335d8a
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.bundle_filter.yml
@@ -0,0 +1,513 @@
+langcode: en
+status: true
+dependencies:
+  enforced:
+    module:
+      - entity_browser_test
+  module:
+    - entity_browser
+    - node
+    - user
+id: bundle_filter
+label: 'Bundle Filter Test'
+module: views
+description: ''
+tag: ''
+base_table: node_field_data
+base_field: nid
+core: 8.x
+display:
+  default:
+    display_plugin: default
+    id: default
+    display_title: Master
+    position: 0
+    display_options:
+      access:
+        type: perm
+        options:
+          perm: 'access content'
+      cache:
+        type: none
+        options: {  }
+      query:
+        type: views_query
+        options:
+          disable_sql_rewrite: false
+          distinct: false
+          replica: false
+          query_comment: ''
+          query_tags: {  }
+      exposed_form:
+        type: basic
+        options:
+          submit_button: Apply
+          reset_button: false
+          reset_button_label: Reset
+          exposed_sorts_label: 'Sort by'
+          expose_sort_order: true
+          sort_asc_label: Asc
+          sort_desc_label: Desc
+      pager:
+        type: full
+        options:
+          items_per_page: 10
+          offset: 0
+          id: 0
+          total_pages: null
+          expose:
+            items_per_page: false
+            items_per_page_label: 'Items per page'
+            items_per_page_options: '5, 10, 25, 50'
+            items_per_page_options_all: false
+            items_per_page_options_all_label: '- All -'
+            offset: false
+            offset_label: Offset
+          tags:
+            previous: '‹ previous'
+            next: 'next ›'
+            first: '« first'
+            last: 'last »'
+          quantity: 9
+      style:
+        type: table
+        options:
+          grouping: {  }
+          row_class: ''
+          default_row_class: true
+          override: true
+          sticky: false
+          caption: ''
+          summary: ''
+          description: ''
+          columns:
+            title: title
+          info:
+            title:
+              sortable: false
+              default_sort_order: asc
+              align: ''
+              separator: ''
+              empty_column: false
+              responsive: ''
+          default: '-1'
+          empty_table: false
+      row:
+        type: fields
+        options:
+          inline: {  }
+          separator: ''
+          hide_empty: false
+          default_field_elements: true
+      fields:
+        entity_browser_select:
+          id: entity_browser_select
+          table: node
+          field: entity_browser_select
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: ''
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: false
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          entity_type: node
+          plugin_id: entity_browser_select
+        title:
+          id: title
+          table: node_field_data
+          field: title
+          entity_type: node
+          entity_field: title
+          label: ''
+          alter:
+            alter_text: false
+            make_link: false
+            absolute: false
+            trim: false
+            word_boundary: false
+            ellipsis: false
+            strip_tags: false
+            html: false
+          hide_empty: false
+          empty_zero: false
+          settings:
+            link_to_entity: true
+          plugin_id: field
+          relationship: none
+          group_type: group
+          admin_label: ''
+          exclude: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_alter_empty: true
+          click_sort_column: value
+          type: string
+          group_column: value
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+        created:
+          id: created
+          table: node_field_data
+          field: created
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: 'Created on'
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          date_format: medium
+          custom_date_format: ''
+          timezone: ''
+          entity_type: node
+          entity_field: created
+          plugin_id: date
+        status:
+          id: status
+          table: node_field_data
+          field: status
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Status
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: value
+          type: boolean
+          settings:
+            format: yes-no
+            format_custom_true: ''
+            format_custom_false: ''
+          group_column: value
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+          entity_type: node
+          entity_field: status
+          plugin_id: field
+        type:
+          id: type
+          table: node_field_data
+          field: type
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Type
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          entity_type: node
+          entity_field: type
+          plugin_id: node_type
+      filters:
+        title:
+          id: title
+          table: node_field_data
+          field: title
+          relationship: none
+          group_type: group
+          admin_label: ''
+          operator: word
+          value: ''
+          group: 1
+          exposed: true
+          expose:
+            operator_id: title_op
+            label: Title
+            description: ''
+            use_operator: false
+            operator: title_op
+            identifier: title
+            required: false
+            remember: false
+            multiple: false
+            remember_roles:
+              authenticated: authenticated
+              anonymous: '0'
+              administrator: '0'
+          is_grouped: false
+          group_info:
+            label: ''
+            description: ''
+            identifier: ''
+            optional: true
+            widget: select
+            multiple: false
+            remember: false
+            default_group: All
+            default_group_multiple: {  }
+            group_items: {  }
+          entity_type: node
+          entity_field: title
+          plugin_id: string
+        entity_browser_bundle:
+          id: entity_browser_bundle
+          table: node
+          field: entity_browser_bundle
+          relationship: none
+          group_type: group
+          admin_label: ''
+          operator: in
+          value:
+            all: all
+            article: article
+            jet: jet
+            shark: shark
+          group: 1
+          exposed: false
+          expose:
+            operator_id: entity_browser_bundle_op
+            label: 'Entity Browser Target Bundles'
+            description: null
+            use_operator: false
+            operator: entity_browser_bundle_op
+            identifier: entity_browser_bundle
+            required: false
+            remember: false
+            multiple: false
+            remember_roles:
+              authenticated: authenticated
+            reduce: false
+          is_grouped: false
+          group_info:
+            label: ''
+            description: ''
+            identifier: ''
+            optional: true
+            widget: select
+            multiple: false
+            remember: false
+            default_group: All
+            default_group_multiple: {  }
+            group_items: {  }
+          entity_type: node
+          plugin_id: entity_browser_bundle
+      sorts:
+        created:
+          id: created
+          table: node_field_data
+          field: created
+          relationship: none
+          group_type: group
+          admin_label: ''
+          order: DESC
+          exposed: true
+          expose:
+            label: 'Authored on'
+          granularity: second
+          entity_type: node
+          entity_field: created
+          plugin_id: date
+      header: {  }
+      footer: {  }
+      empty: {  }
+      relationships: {  }
+      arguments: {  }
+      display_extenders: {  }
+      filter_groups:
+        operator: AND
+        groups: {  }
+      use_ajax: true
+    cache_metadata:
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url
+        - url.query_args
+        - 'url.query_args:sort_by'
+        - 'url.query_args:sort_order'
+        - 'user.node_grants:view'
+        - user.permissions
+      cacheable: false
+      max-age: -1
+      tags: {  }
+  entity_browser_1:
+    display_plugin: entity_browser
+    id: entity_browser_1
+    display_title: 'Entity browser'
+    position: 1
+    display_options:
+      display_extenders: {  }
+    cache_metadata:
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url
+        - url.query_args
+        - 'url.query_args:sort_by'
+        - 'url.query_args:sort_order'
+        - 'user.node_grants:view'
+        - user.permissions
+      cacheable: false
+      max-age: -1
+      tags: {  }
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.bundle_filter_exposed.yml b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.bundle_filter_exposed.yml
new file mode 100644
index 0000000000000000000000000000000000000000..1358ac4a7a6fb3ab437d556646dbf40526d5d292
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.bundle_filter_exposed.yml
@@ -0,0 +1,514 @@
+langcode: en
+status: true
+dependencies:
+  enforced:
+    module:
+      - entity_browser_test
+  module:
+    - entity_browser
+    - node
+    - user
+id: bundle_filter_exposed
+label: 'Bundle Filter Exposed Test'
+module: views
+description: ''
+tag: ''
+base_table: node_field_data
+base_field: nid
+core: 8.x
+display:
+  default:
+    display_plugin: default
+    id: default
+    display_title: Master
+    position: 0
+    display_options:
+      access:
+        type: perm
+        options:
+          perm: 'access content'
+      cache:
+        type: none
+        options: {  }
+      query:
+        type: views_query
+        options:
+          disable_sql_rewrite: false
+          distinct: false
+          replica: false
+          query_comment: ''
+          query_tags: {  }
+      exposed_form:
+        type: basic
+        options:
+          submit_button: Apply
+          reset_button: false
+          reset_button_label: Reset
+          exposed_sorts_label: 'Sort by'
+          expose_sort_order: true
+          sort_asc_label: Asc
+          sort_desc_label: Desc
+      pager:
+        type: full
+        options:
+          items_per_page: 10
+          offset: 0
+          id: 0
+          total_pages: null
+          expose:
+            items_per_page: false
+            items_per_page_label: 'Items per page'
+            items_per_page_options: '5, 10, 25, 50'
+            items_per_page_options_all: false
+            items_per_page_options_all_label: '- All -'
+            offset: false
+            offset_label: Offset
+          tags:
+            previous: '‹ previous'
+            next: 'next ›'
+            first: '« first'
+            last: 'last »'
+          quantity: 9
+      style:
+        type: table
+        options:
+          grouping: {  }
+          row_class: ''
+          default_row_class: true
+          override: true
+          sticky: false
+          caption: ''
+          summary: ''
+          description: ''
+          columns:
+            title: title
+          info:
+            title:
+              sortable: false
+              default_sort_order: asc
+              align: ''
+              separator: ''
+              empty_column: false
+              responsive: ''
+          default: '-1'
+          empty_table: false
+      row:
+        type: fields
+        options:
+          inline: {  }
+          separator: ''
+          hide_empty: false
+          default_field_elements: true
+      fields:
+        entity_browser_select:
+          id: entity_browser_select
+          table: node
+          field: entity_browser_select
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: ''
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: false
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          entity_type: node
+          plugin_id: entity_browser_select
+        title:
+          id: title
+          table: node_field_data
+          field: title
+          entity_type: node
+          entity_field: title
+          label: ''
+          alter:
+            alter_text: false
+            make_link: false
+            absolute: false
+            trim: false
+            word_boundary: false
+            ellipsis: false
+            strip_tags: false
+            html: false
+          hide_empty: false
+          empty_zero: false
+          settings:
+            link_to_entity: true
+          plugin_id: field
+          relationship: none
+          group_type: group
+          admin_label: ''
+          exclude: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_alter_empty: true
+          click_sort_column: value
+          type: string
+          group_column: value
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+        created:
+          id: created
+          table: node_field_data
+          field: created
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: 'Created on'
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          date_format: medium
+          custom_date_format: ''
+          timezone: ''
+          entity_type: node
+          entity_field: created
+          plugin_id: date
+        status:
+          id: status
+          table: node_field_data
+          field: status
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Status
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: value
+          type: boolean
+          settings:
+            format: yes-no
+            format_custom_true: ''
+            format_custom_false: ''
+          group_column: value
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+          entity_type: node
+          entity_field: status
+          plugin_id: field
+        type:
+          id: type
+          table: node_field_data
+          field: type
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Type
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          entity_type: node
+          entity_field: type
+          plugin_id: node_type
+      filters:
+        title:
+          id: title
+          table: node_field_data
+          field: title
+          relationship: none
+          group_type: group
+          admin_label: ''
+          operator: word
+          value: ''
+          group: 1
+          exposed: true
+          expose:
+            operator_id: title_op
+            label: Title
+            description: ''
+            use_operator: false
+            operator: title_op
+            identifier: title
+            required: false
+            remember: false
+            multiple: false
+            remember_roles:
+              authenticated: authenticated
+              anonymous: '0'
+              administrator: '0'
+          is_grouped: false
+          group_info:
+            label: ''
+            description: ''
+            identifier: ''
+            optional: true
+            widget: select
+            multiple: false
+            remember: false
+            default_group: All
+            default_group_multiple: {  }
+            group_items: {  }
+          entity_type: node
+          entity_field: title
+          plugin_id: string
+        entity_browser_bundle:
+          id: entity_browser_bundle
+          table: node
+          field: entity_browser_bundle
+          relationship: none
+          group_type: group
+          admin_label: ''
+          operator: in
+          value:
+            all: all
+            article: article
+            jet: jet
+            shark: shark
+          group: 1
+          exposed: true
+          expose:
+            operator_id: entity_browser_bundle_op
+            label: 'Type'
+            description: ''
+            use_operator: false
+            operator: entity_browser_bundle_op
+            identifier: type
+            required: false
+            remember: false
+            multiple: false
+            remember_roles:
+              authenticated: authenticated
+              anonymous: '0'
+            reduce: false
+          is_grouped: false
+          group_info:
+            label: ''
+            description: ''
+            identifier: ''
+            optional: true
+            widget: select
+            multiple: false
+            remember: false
+            default_group: All
+            default_group_multiple: {  }
+            group_items: {  }
+          entity_type: node
+          plugin_id: entity_browser_bundle
+      sorts:
+        created:
+          id: created
+          table: node_field_data
+          field: created
+          relationship: none
+          group_type: group
+          admin_label: ''
+          order: DESC
+          exposed: true
+          expose:
+            label: 'Authored on'
+          granularity: second
+          entity_type: node
+          entity_field: created
+          plugin_id: date
+      header: {  }
+      footer: {  }
+      empty: {  }
+      relationships: {  }
+      arguments: {  }
+      display_extenders: {  }
+      filter_groups:
+        operator: AND
+        groups: {  }
+      use_ajax: true
+    cache_metadata:
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url
+        - url.query_args
+        - 'url.query_args:sort_by'
+        - 'url.query_args:sort_order'
+        - 'user.node_grants:view'
+        - user.permissions
+      cacheable: false
+      max-age: -1
+      tags: {  }
+  entity_browser_1:
+    display_plugin: entity_browser
+    id: entity_browser_1
+    display_title: 'Entity browser'
+    position: 1
+    display_options:
+      display_extenders: {  }
+    cache_metadata:
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url
+        - url.query_args
+        - 'url.query_args:sort_by'
+        - 'url.query_args:sort_order'
+        - 'user.node_grants:view'
+        - user.permissions
+      cacheable: false
+      max-age: -1
+      tags: {  }
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.double__underscore.yml b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.double__underscore.yml
new file mode 100644
index 0000000000000000000000000000000000000000..923393500b09ac52372bb2c58d85086fe4a0259d
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.double__underscore.yml
@@ -0,0 +1,468 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - entity_browser
+    - node
+    - user
+id: double__underscore
+label: double__underscore
+module: views
+description: ''
+tag: ''
+base_table: node_field_data
+base_field: nid
+core: 8.x
+display:
+  default:
+    display_plugin: default
+    id: default
+    display_title: Master
+    position: 0
+    display_options:
+      access:
+        type: perm
+        options:
+          perm: 'access content'
+      cache:
+        type: none
+        options: {  }
+      query:
+        type: views_query
+        options:
+          disable_sql_rewrite: false
+          distinct: false
+          replica: false
+          query_comment: ''
+          query_tags: {  }
+      exposed_form:
+        type: basic
+        options:
+          submit_button: Apply
+          reset_button: false
+          reset_button_label: Reset
+          exposed_sorts_label: 'Sort by'
+          expose_sort_order: true
+          sort_asc_label: Asc
+          sort_desc_label: Desc
+      pager:
+        type: full
+        options:
+          items_per_page: 10
+          offset: 0
+          id: 0
+          total_pages: null
+          expose:
+            items_per_page: false
+            items_per_page_label: 'Items per page'
+            items_per_page_options: '5, 10, 25, 50'
+            items_per_page_options_all: false
+            items_per_page_options_all_label: '- All -'
+            offset: false
+            offset_label: Offset
+          tags:
+            previous: '‹ previous'
+            next: 'next ›'
+            first: '« first'
+            last: 'last »'
+          quantity: 9
+      style:
+        type: table
+        options:
+          grouping: {  }
+          row_class: ''
+          default_row_class: true
+          override: true
+          sticky: false
+          caption: ''
+          summary: ''
+          description: ''
+          columns:
+            title: title
+          info:
+            title:
+              sortable: false
+              default_sort_order: asc
+              align: ''
+              separator: ''
+              empty_column: false
+              responsive: ''
+          default: '-1'
+          empty_table: false
+      row:
+        type: fields
+        options:
+          inline: {  }
+          separator: ''
+          hide_empty: false
+          default_field_elements: true
+      fields:
+        entity_browser_select:
+          id: entity_browser_select
+          table: node
+          field: entity_browser_select
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: ''
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: false
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          entity_type: node
+          plugin_id: entity_browser_select
+        title:
+          id: title
+          table: node_field_data
+          field: title
+          entity_type: node
+          entity_field: title
+          label: ''
+          alter:
+            alter_text: false
+            make_link: false
+            absolute: false
+            trim: false
+            word_boundary: false
+            ellipsis: false
+            strip_tags: false
+            html: false
+          hide_empty: false
+          empty_zero: false
+          settings:
+            link_to_entity: true
+          plugin_id: field
+          relationship: none
+          group_type: group
+          admin_label: ''
+          exclude: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_alter_empty: true
+          click_sort_column: value
+          type: string
+          group_column: value
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+        created:
+          id: created
+          table: node_field_data
+          field: created
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: 'Created on'
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          date_format: medium
+          custom_date_format: ''
+          timezone: ''
+          entity_type: node
+          entity_field: created
+          plugin_id: date
+        status:
+          id: status
+          table: node_field_data
+          field: status
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Status
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: value
+          type: boolean
+          settings:
+            format: yes-no
+            format_custom_true: ''
+            format_custom_false: ''
+          group_column: value
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+          entity_type: node
+          entity_field: status
+          plugin_id: field
+        type:
+          id: type
+          table: node_field_data
+          field: type
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Type
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          entity_type: node
+          entity_field: type
+          plugin_id: node_type
+      filters:
+        title:
+          id: title
+          table: node_field_data
+          field: title
+          relationship: none
+          group_type: group
+          admin_label: ''
+          operator: word
+          value: ''
+          group: 1
+          exposed: true
+          expose:
+            operator_id: title_op
+            label: Title
+            description: ''
+            use_operator: false
+            operator: title_op
+            identifier: title
+            required: false
+            remember: false
+            multiple: false
+            remember_roles:
+              authenticated: authenticated
+              anonymous: '0'
+              administrator: '0'
+          is_grouped: false
+          group_info:
+            label: ''
+            description: ''
+            identifier: ''
+            optional: true
+            widget: select
+            multiple: false
+            remember: false
+            default_group: All
+            default_group_multiple: {  }
+            group_items: {  }
+          entity_type: node
+          entity_field: title
+          plugin_id: string
+      sorts:
+        created:
+          id: created
+          table: node_field_data
+          field: created
+          relationship: none
+          group_type: group
+          admin_label: ''
+          order: DESC
+          exposed: true
+          expose:
+            label: 'Authored on'
+          granularity: second
+          entity_type: node
+          entity_field: created
+          plugin_id: date
+      header: {  }
+      footer: {  }
+      empty: {  }
+      relationships: {  }
+      arguments: {  }
+      display_extenders: {  }
+      filter_groups:
+        operator: AND
+        groups: {  }
+      use_ajax: true
+    cache_metadata:
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url
+        - url.query_args
+        - 'url.query_args:sort_by'
+        - 'url.query_args:sort_order'
+        - 'user.node_grants:view'
+        - user.permissions
+      cacheable: false
+      max-age: -1
+      tags: {  }
+  entity_browser_1:
+    display_plugin: entity_browser
+    id: entity_browser_1
+    display_title: 'Entity browser'
+    position: 1
+    display_options:
+      display_extenders: {  }
+    cache_metadata:
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url
+        - url.query_args
+        - 'url.query_args:sort_by'
+        - 'url.query_args:sort_order'
+        - 'user.node_grants:view'
+        - user.permissions
+      cacheable: false
+      max-age: -1
+      tags: {  }
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.files_entity_browser.yml b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.files_entity_browser.yml
index 9351d532059d683a27df5cef77ab6170f636c861..efff872a1a0f12b64c83e9b058c809bc78e38cc4 100644
--- a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.files_entity_browser.yml
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.files_entity_browser.yml
@@ -149,6 +149,7 @@ display:
           empty_zero: false
           hide_alter_empty: true
           entity_type: file
+          use_field_cardinality: false
           plugin_id: entity_browser_select
         filename:
           id: filename
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.files_entity_browser_grid.yml b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.files_entity_browser_grid.yml
index 4610a12f2590c5206acd743d7aafbec35db38696..cb4dcd9ecb08cd4168827fde2c695e02477f182b 100644
--- a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.files_entity_browser_grid.yml
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.files_entity_browser_grid.yml
@@ -131,6 +131,7 @@ display:
           empty_zero: false
           hide_alter_empty: true
           entity_type: file
+          use_field_cardinality: false
           plugin_id: entity_browser_select
         filename:
           id: filename
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.files_entity_browser_html.yml b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.files_entity_browser_html.yml
index 7a1586d7fac3d1722f251a1b9f3a8956c385c0ce..bd30b7e293f20c660480435de9dcbfd6c5c15cbb 100644
--- a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.files_entity_browser_html.yml
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.files_entity_browser_html.yml
@@ -129,6 +129,7 @@ display:
           empty_zero: false
           hide_alter_empty: true
           entity_type: file
+          use_field_cardinality: false
           plugin_id: entity_browser_select
         filename:
           id: filename
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.files_entity_browser_unformatted.yml b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.files_entity_browser_unformatted.yml
index 7792d65c5b624cdea5e6bedb5ac83dbd6804ee77..1afcd59a4e915b8da320022924fbce154ba865ee 100644
--- a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.files_entity_browser_unformatted.yml
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.files_entity_browser_unformatted.yml
@@ -126,6 +126,7 @@ display:
           empty_zero: false
           hide_alter_empty: true
           entity_type: file
+          use_field_cardinality: false
           plugin_id: entity_browser_select
         filename:
           id: filename
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.test_deprecated_field.yml b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.test_deprecated_field.yml
index 629bcadf0d9e80ad63c27e7420928d2db2ed9856..cbfab7bf5c8df7665764dbb549e9d9dd75b90808 100644
--- a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.test_deprecated_field.yml
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.test_deprecated_field.yml
@@ -174,6 +174,7 @@ display:
           empty_zero: false
           hide_alter_empty: true
           entity_type: node
+          use_field_cardinality: false
           plugin_id: entity_browser_select
       filters:
         status:
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.test_entity_reference_widget_view.yml b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.test_entity_reference_widget_view.yml
index 15d5baf40b4e915e200fccdd617a3e192af7f0a7..21b09d2ee793f7c86654517c325ef0afc48825d6 100644
--- a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.test_entity_reference_widget_view.yml
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.test_entity_reference_widget_view.yml
@@ -149,6 +149,7 @@ display:
           empty_zero: false
           hide_alter_empty: true
           entity_type: node
+          use_field_cardinality: false
           plugin_id: entity_browser_select
         title:
           id: title
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.widget_context_default_value.yml b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.widget_context_default_value.yml
new file mode 100644
index 0000000000000000000000000000000000000000..4de66a538b6de7565943deb6ae514689632a15ce
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test/config/install/views.view.widget_context_default_value.yml
@@ -0,0 +1,514 @@
+langcode: en
+status: true
+dependencies:
+  enforced:
+    module:
+      - entity_browser_test
+  module:
+    - entity_browser
+    - node
+    - user
+id: widget_context_default_value
+label: 'Widget Context Default Value'
+module: views
+description: ''
+tag: ''
+base_table: node_field_data
+base_field: nid
+core: 8.x
+display:
+  default:
+    display_plugin: default
+    id: default
+    display_title: Master
+    position: 0
+    display_options:
+      access:
+        type: perm
+        options:
+          perm: 'access content'
+      cache:
+        type: none
+        options: {  }
+      query:
+        type: views_query
+        options:
+          disable_sql_rewrite: false
+          distinct: false
+          replica: false
+          query_comment: ''
+          query_tags: {  }
+      exposed_form:
+        type: basic
+        options:
+          submit_button: Apply
+          reset_button: false
+          reset_button_label: Reset
+          exposed_sorts_label: 'Sort by'
+          expose_sort_order: true
+          sort_asc_label: Asc
+          sort_desc_label: Desc
+      pager:
+        type: full
+        options:
+          items_per_page: 10
+          offset: 0
+          id: 0
+          total_pages: null
+          expose:
+            items_per_page: false
+            items_per_page_label: 'Items per page'
+            items_per_page_options: '5, 10, 25, 50'
+            items_per_page_options_all: false
+            items_per_page_options_all_label: '- All -'
+            offset: false
+            offset_label: Offset
+          tags:
+            previous: '‹ previous'
+            next: 'next ›'
+            first: '« first'
+            last: 'last »'
+          quantity: 9
+      style:
+        type: table
+        options:
+          grouping: {  }
+          row_class: ''
+          default_row_class: true
+          override: true
+          sticky: false
+          caption: ''
+          summary: ''
+          description: ''
+          columns:
+            title: title
+          info:
+            title:
+              sortable: false
+              default_sort_order: asc
+              align: ''
+              separator: ''
+              empty_column: false
+              responsive: ''
+          default: '-1'
+          empty_table: false
+      row:
+        type: fields
+        options:
+          inline: {  }
+          separator: ''
+          hide_empty: false
+          default_field_elements: true
+      fields:
+        entity_browser_select:
+          id: entity_browser_select
+          table: node
+          field: entity_browser_select
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: ''
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: false
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          entity_type: node
+          plugin_id: entity_browser_select
+        title:
+          id: title
+          table: node_field_data
+          field: title
+          entity_type: node
+          entity_field: title
+          label: ''
+          alter:
+            alter_text: false
+            make_link: false
+            absolute: false
+            trim: false
+            word_boundary: false
+            ellipsis: false
+            strip_tags: false
+            html: false
+          hide_empty: false
+          empty_zero: false
+          settings:
+            link_to_entity: true
+          plugin_id: field
+          relationship: none
+          group_type: group
+          admin_label: ''
+          exclude: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_alter_empty: true
+          click_sort_column: value
+          type: string
+          group_column: value
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+        created:
+          id: created
+          table: node_field_data
+          field: created
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: 'Created on'
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          date_format: medium
+          custom_date_format: ''
+          timezone: ''
+          entity_type: node
+          entity_field: created
+          plugin_id: date
+        status:
+          id: status
+          table: node_field_data
+          field: status
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Status
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: value
+          type: boolean
+          settings:
+            format: yes-no
+            format_custom_true: ''
+            format_custom_false: ''
+          group_column: value
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+          entity_type: node
+          entity_field: status
+          plugin_id: field
+        type:
+          id: type
+          table: node_field_data
+          field: type
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Type
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          entity_type: node
+          entity_field: type
+          plugin_id: node_type
+      filters:
+        title:
+          id: title
+          table: node_field_data
+          field: title
+          relationship: none
+          group_type: group
+          admin_label: ''
+          operator: word
+          value: ''
+          group: 1
+          exposed: true
+          expose:
+            operator_id: title_op
+            label: Title
+            description: ''
+            use_operator: false
+            operator: title_op
+            identifier: title
+            required: false
+            remember: false
+            multiple: false
+            remember_roles:
+              authenticated: authenticated
+              anonymous: '0'
+              administrator: '0'
+          is_grouped: false
+          group_info:
+            label: ''
+            description: ''
+            identifier: ''
+            optional: true
+            widget: select
+            multiple: false
+            remember: false
+            default_group: All
+            default_group_multiple: {  }
+            group_items: {  }
+          entity_type: node
+          entity_field: title
+          plugin_id: string
+      sorts:
+        created:
+          id: created
+          table: node_field_data
+          field: created
+          relationship: none
+          group_type: group
+          admin_label: ''
+          order: DESC
+          exposed: true
+          expose:
+            label: 'Authored on'
+          granularity: second
+          entity_type: node
+          entity_field: created
+          plugin_id: date
+      header: {  }
+      footer: {  }
+      empty: {  }
+      relationships: {  }
+      arguments:
+        type:
+          id: type
+          table: node_field_data
+          field: type
+          relationship: none
+          group_type: group
+          admin_label: ''
+          default_action: default
+          exception:
+            value: all
+            title_enable: false
+            title: All
+          title_enable: false
+          title: ''
+          default_argument_type: entity_browser_widget_context
+          default_argument_options:
+            context_key: target_bundles
+            fallback: all
+            multiple: or
+          default_argument_skip_url: false
+          summary_options:
+            base_path: ''
+            count: true
+            items_per_page: 25
+            override: false
+          summary:
+            sort_order: asc
+            number_of_records: 0
+            format: default_summary
+          specify_validation: false
+          validate:
+            type: none
+            fail: 'not found'
+          validate_options: {  }
+          glossary: false
+          limit: 0
+          case: none
+          path_case: none
+          transform_dash: false
+          break_phrase: true
+          entity_type: node
+          entity_field: type
+          plugin_id: node_type
+      display_extenders: {  }
+      filter_groups:
+        operator: AND
+        groups: {  }
+      use_ajax: true
+    cache_metadata:
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url
+        - url.query_args
+        - 'url.query_args:sort_by'
+        - 'url.query_args:sort_order'
+        - 'user.node_grants:view'
+        - user.permissions
+      cacheable: false
+      max-age: -1
+      tags: {  }
+  entity_browser_1:
+    display_plugin: entity_browser
+    id: entity_browser_1
+    display_title: 'Entity browser'
+    position: 1
+    display_options:
+      display_extenders: {  }
+    cache_metadata:
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url
+        - url.query_args
+        - 'url.query_args:sort_by'
+        - 'url.query_args:sort_order'
+        - 'user.node_grants:view'
+        - user.permissions
+      cacheable: false
+      max-age: -1
+      tags: {  }
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test/entity_browser_test.info.yml b/web/modules/entity_browser/tests/modules/entity_browser_test/entity_browser_test.info.yml
index 97dfafe3d832aab8c16a25d6d64cc7115f976aa1..6f46268d696fff3786b7f5997fa98bf3258b2c5a 100644
--- a/web/modules/entity_browser/tests/modules/entity_browser_test/entity_browser_test.info.yml
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test/entity_browser_test.info.yml
@@ -1,17 +1,16 @@
 name: 'Entity browser test'
 type: module
 description: 'Support module for the Entity browser module tests.'
-# core: 8.x
+core_version_requirement: ^8.7.7 || ^9
 package: Testing
-# version: VERSION
 dependencies:
-  - entity_browser
-  - file
-  - node
-  - views
+  - entity_browser:entity_browser
+  - drupal:file
+  - drupal:user
+  - drupal:node
+  - drupal:views
 
-# Information added by Drupal.org packaging script on 2017-11-30
-version: '8.x-1.4'
-core: '8.x'
+# Information added by Drupal.org packaging script on 2020-01-20
+version: '8.x-1.10'
 project: 'entity_browser'
-datestamp: 1512033788
+datestamp: 1579563796
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test/entity_browser_test.services.yml b/web/modules/entity_browser/tests/modules/entity_browser_test/entity_browser_test.services.yml
new file mode 100644
index 0000000000000000000000000000000000000000..17e1f17d62380ea5e752117dc2b8f7fa25afd051
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test/entity_browser_test.services.yml
@@ -0,0 +1,5 @@
+services:
+  cache_context.eb_dummy:
+    class: Drupal\entity_browser_test\Cache\Context\DummyCacheContext
+    tags:
+      - { name: cache.context}
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test/src/Cache/Context/DummyCacheContext.php b/web/modules/entity_browser/tests/modules/entity_browser_test/src/Cache/Context/DummyCacheContext.php
new file mode 100644
index 0000000000000000000000000000000000000000..ee539059d73bd24dd2a24eb388fc5a5461c48bfd
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test/src/Cache/Context/DummyCacheContext.php
@@ -0,0 +1,36 @@
+<?php
+
+namespace Drupal\entity_browser_test\Cache\Context;
+
+use Drupal\Core\Cache\CacheableMetadata;
+use Drupal\Core\Cache\Context\CacheContextInterface;
+
+/**
+ * Dummy cache context for Entity browser test purposes.
+ *
+ * Cache context ID: 'eb_dummy'.
+ */
+class DummyCacheContext implements CacheContextInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getLabel() {
+    return t('Dummy context');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getContext() {
+    return "dummy";
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheableMetadata() {
+    return new CacheableMetadata();
+  }
+
+}
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test/src/Form/FormElementTest.php b/web/modules/entity_browser/tests/modules/entity_browser_test/src/Form/FormElementTest.php
index 4a089474fde9d0092af2f71a1a3b37a78dad99a3..cdd09bb052c4414de1b8e0e20fd5adf1908eb42b 100644
--- a/web/modules/entity_browser/tests/modules/entity_browser_test/src/Form/FormElementTest.php
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test/src/Form/FormElementTest.php
@@ -59,7 +59,7 @@ function (EntityInterface $item) {
       },
       $entities
     ));
-    drupal_set_message($message);
+    $this->messenger()->addMessage($message);
   }
 
 }
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test/src/Plugin/EntityBrowser/Widget/DummyWidget.php b/web/modules/entity_browser/tests/modules/entity_browser_test/src/Plugin/EntityBrowser/Widget/DummyWidget.php
index 7d19edfd8c05bbcae512f78db4ea7c923adfd1ba..820d27149cb6d76378ec63d5279074c4ba6fcddd 100644
--- a/web/modules/entity_browser/tests/modules/entity_browser_test/src/Plugin/EntityBrowser/Widget/DummyWidget.php
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test/src/Plugin/EntityBrowser/Widget/DummyWidget.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\entity_browser_test\Plugin\EntityBrowser\Widget;
 
+use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\entity_browser\WidgetBase;
 
@@ -55,4 +56,19 @@ protected function prepareEntities(array $form, FormStateInterface $form_state)
     return $form_state->getValue('dummy_entities', []);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function access() {
+    if (\Drupal::state()->get('eb_test_dummy_widget_access', TRUE)) {
+      $access = AccessResult::allowed();
+      $access->addCacheContexts(['eb_dummy']);
+    }
+    else {
+      $access = AccessResult::forbidden();
+      $access->addCacheContexts(['eb_dummy']);
+    }
+    return $access;
+  }
+
 }
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test_configuration/config/install/views.view.nodes_entity_browser.yml b/web/modules/entity_browser/tests/modules/entity_browser_test_configuration/config/install/views.view.nodes_entity_browser.yml
new file mode 100644
index 0000000000000000000000000000000000000000..3be9988b3d9875bdb13894d95d002d5f7daee1f9
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test_configuration/config/install/views.view.nodes_entity_browser.yml
@@ -0,0 +1,469 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - views
+    - entity_browser
+    - node
+    - user
+id: nodes_entity_browser
+label: 'Nodes entity browser'
+module: views
+description: ''
+tag: ''
+base_table: node_field_data
+base_field: nid
+core: 8.x
+display:
+  default:
+    display_plugin: default
+    id: default
+    display_title: Master
+    position: 0
+    display_options:
+      access:
+        type: perm
+        options:
+          perm: 'access content'
+      cache:
+        type: none
+        options: {  }
+      query:
+        type: views_query
+        options:
+          disable_sql_rewrite: false
+          distinct: false
+          replica: false
+          query_comment: ''
+          query_tags: {  }
+      exposed_form:
+        type: basic
+        options:
+          submit_button: Apply
+          reset_button: false
+          reset_button_label: Reset
+          exposed_sorts_label: 'Sort by'
+          expose_sort_order: true
+          sort_asc_label: Asc
+          sort_desc_label: Desc
+      pager:
+        type: full
+        options:
+          items_per_page: 10
+          offset: 0
+          id: 0
+          total_pages: null
+          expose:
+            items_per_page: false
+            items_per_page_label: 'Items per page'
+            items_per_page_options: '5, 10, 25, 50'
+            items_per_page_options_all: false
+            items_per_page_options_all_label: '- All -'
+            offset: false
+            offset_label: Offset
+          tags:
+            previous: '‹ previous'
+            next: 'next ›'
+            first: '« first'
+            last: 'last »'
+          quantity: 9
+      style:
+        type: table
+        options:
+          grouping: {  }
+          row_class: ''
+          default_row_class: true
+          override: true
+          sticky: false
+          caption: ''
+          summary: ''
+          description: ''
+          columns:
+            title: title
+          info:
+            title:
+              sortable: false
+              default_sort_order: asc
+              align: ''
+              separator: ''
+              empty_column: false
+              responsive: ''
+          default: '-1'
+          empty_table: false
+      row:
+        type: fields
+        options:
+          inline: {  }
+          separator: ''
+          hide_empty: false
+          default_field_elements: true
+      fields:
+        entity_browser_select:
+          id: entity_browser_select
+          table: node
+          field: entity_browser_select
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: ''
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: false
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          entity_type: node
+          plugin_id: entity_browser_select
+        title:
+          id: title
+          table: node_field_data
+          field: title
+          entity_type: node
+          entity_field: title
+          label: ''
+          alter:
+            alter_text: false
+            make_link: false
+            absolute: false
+            trim: false
+            word_boundary: false
+            ellipsis: false
+            strip_tags: false
+            html: false
+          hide_empty: false
+          empty_zero: false
+          settings:
+            link_to_entity: true
+          plugin_id: field
+          relationship: none
+          group_type: group
+          admin_label: ''
+          exclude: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_alter_empty: true
+          click_sort_column: value
+          type: string
+          group_column: value
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+        created:
+          id: created
+          table: node_field_data
+          field: created
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: 'Created on'
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          date_format: medium
+          custom_date_format: ''
+          timezone: ''
+          entity_type: node
+          entity_field: created
+          plugin_id: date
+        status:
+          id: status
+          table: node_field_data
+          field: status
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Status
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: value
+          type: boolean
+          settings:
+            format: yes-no
+            format_custom_true: ''
+            format_custom_false: ''
+          group_column: value
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+          entity_type: node
+          entity_field: status
+          plugin_id: field
+        type:
+          id: type
+          table: node_field_data
+          field: type
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Type
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          entity_type: node
+          entity_field: type
+          plugin_id: node_type
+      filters:
+        title:
+          id: title
+          table: node_field_data
+          field: title
+          relationship: none
+          group_type: group
+          admin_label: ''
+          operator: word
+          value: ''
+          group: 1
+          exposed: true
+          expose:
+            operator_id: title_op
+            label: Title
+            description: ''
+            use_operator: false
+            operator: title_op
+            identifier: title
+            required: false
+            remember: false
+            multiple: false
+            remember_roles:
+              authenticated: authenticated
+              anonymous: '0'
+              administrator: '0'
+          is_grouped: false
+          group_info:
+            label: ''
+            description: ''
+            identifier: ''
+            optional: true
+            widget: select
+            multiple: false
+            remember: false
+            default_group: All
+            default_group_multiple: {  }
+            group_items: {  }
+          entity_type: node
+          entity_field: title
+          plugin_id: string
+      sorts:
+        created:
+          id: created
+          table: node_field_data
+          field: created
+          relationship: none
+          group_type: group
+          admin_label: ''
+          order: DESC
+          exposed: true
+          expose:
+            label: 'Authored on'
+          granularity: second
+          entity_type: node
+          entity_field: created
+          plugin_id: date
+      header: {  }
+      footer: {  }
+      empty: {  }
+      relationships: {  }
+      arguments: {  }
+      display_extenders: {  }
+      filter_groups:
+        operator: AND
+        groups: {  }
+      use_ajax: true
+    cache_metadata:
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url
+        - url.query_args
+        - 'url.query_args:sort_by'
+        - 'url.query_args:sort_order'
+        - 'user.node_grants:view'
+        - user.permissions
+      cacheable: false
+      max-age: 0
+      tags: {  }
+  entity_browser_1:
+    display_plugin: entity_browser
+    id: entity_browser_1
+    display_title: 'Entity browser'
+    position: 1
+    display_options:
+      display_extenders: {  }
+    cache_metadata:
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url
+        - url.query_args
+        - 'url.query_args:sort_by'
+        - 'url.query_args:sort_order'
+        - 'user.node_grants:view'
+        - user.permissions
+      cacheable: false
+      max-age: 0
+      tags: {  }
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test_configuration/entity_browser_test_configuration.info.yml b/web/modules/entity_browser/tests/modules/entity_browser_test_configuration/entity_browser_test_configuration.info.yml
new file mode 100644
index 0000000000000000000000000000000000000000..cca2b7b136bfa83dfbe08878e1523053ad8a6a19
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test_configuration/entity_browser_test_configuration.info.yml
@@ -0,0 +1,16 @@
+name: 'Entity browser test configuration'
+type: module
+description: 'Test Configuration Forms.'
+core_version_requirement: ^8.7.7 || ^9
+package: Testing
+dependencies:
+  - entity_browser:entity_browser
+  - drupal:node
+  - drupal:path
+  - drupal:views
+  - drupal:user
+
+# Information added by Drupal.org packaging script on 2020-01-20
+version: '8.x-1.10'
+project: 'entity_browser'
+datestamp: 1579563796
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test_entityqueue/config/install/core.entity_form_display.entity_subqueue.nodes.default.yml b/web/modules/entity_browser/tests/modules/entity_browser_test_entityqueue/config/install/core.entity_form_display.entity_subqueue.nodes.default.yml
new file mode 100644
index 0000000000000000000000000000000000000000..e9c75d648ae3a94556586891db8d2c8799a5bfbc
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test_entityqueue/config/install/core.entity_form_display.entity_subqueue.nodes.default.yml
@@ -0,0 +1,38 @@
+uuid: cd2a6cf4-5051-475d-9381-726b78c9dc3a
+langcode: en
+status: true
+dependencies:
+  config:
+    - entity_browser.browser.widget_context_default_value
+    - entityqueue.entity_queue.nodes
+  module:
+    - entity_browser
+    - entity_browser_test
+id: entity_subqueue.nodes.default
+targetEntityType: entity_subqueue
+bundle: nodes
+mode: default
+content:
+  items:
+    type: entity_browser_entity_reference
+    weight: 5
+    settings:
+      entity_browser: widget_context_default_value
+      field_widget_display: label
+      field_widget_edit: true
+      field_widget_remove: true
+      selection_mode: selection_append
+      field_widget_replace: false
+      open: false
+      field_widget_display_settings: {  }
+    region: content
+    third_party_settings: {  }
+  title:
+    type: string_textfield
+    weight: -10
+    region: content
+    settings:
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+hidden: {  }
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test_entityqueue/config/install/entityqueue.entity_queue.nodes.yml b/web/modules/entity_browser/tests/modules/entity_browser_test_entityqueue/config/install/entityqueue.entity_queue.nodes.yml
new file mode 100644
index 0000000000000000000000000000000000000000..748929857470eb0569f1223f5c854a4d13b11e0b
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test_entityqueue/config/install/entityqueue.entity_queue.nodes.yml
@@ -0,0 +1,27 @@
+uuid: edb7539d-66d9-423e-bc59-d6d62502e01b
+langcode: en
+status: true
+dependencies:
+  module:
+    - node
+id: nodes
+label: nodes
+handler: simple
+handler_configuration: {  }
+entity_settings:
+  target_type: node
+  handler: 'default:node'
+  handler_settings:
+    target_bundles:
+      article: article
+      page: page
+      entity_browser_test: entity_browser_test
+    sort:
+      field: _none
+    auto_create: false
+    auto_create_bundle: article
+queue_settings:
+  min_size: 0
+  max_size: 0
+  act_as_queue: false
+  reverse_in_admin: false
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test_entityqueue/entity_browser_test_entityqueue.info.yml b/web/modules/entity_browser/tests/modules/entity_browser_test_entityqueue/entity_browser_test_entityqueue.info.yml
new file mode 100644
index 0000000000000000000000000000000000000000..2588f92c43b6dbc88a3ded3b1356ab12f7e10a20
--- /dev/null
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test_entityqueue/entity_browser_test_entityqueue.info.yml
@@ -0,0 +1,16 @@
+name: 'Entity browser entityqueue integration test'
+type: module
+description: 'Support module for Entity browser entityqueue integration test.'
+core_version_requirement: ^8.7.7 || ^9
+package: Testing
+dependencies:
+  - drupal:node
+  - drupal:views
+  - entityqueue:entityqueue
+  - entity_browser:entity_browser
+  - entity_browser_test:entity_browser_test
+
+# Information added by Drupal.org packaging script on 2020-01-20
+version: '8.x-1.10'
+project: 'entity_browser'
+datestamp: 1579563796
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test_paragraphs/config/install/core.entity_form_display.paragraph.content_embed.default.yml b/web/modules/entity_browser/tests/modules/entity_browser_test_paragraphs/config/install/core.entity_form_display.paragraph.content_embed.default.yml
index 5732c92eae7f7f924e1b02c20e4ff3ab4c173443..d09edbbd84bab2857e4e9cb0164a9438b1608636 100644
--- a/web/modules/entity_browser/tests/modules/entity_browser_test_paragraphs/config/install/core.entity_form_display.paragraph.content_embed.default.yml
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test_paragraphs/config/install/core.entity_form_display.paragraph.content_embed.default.yml
@@ -20,6 +20,7 @@ content:
       field_widget_display: label
       field_widget_edit: true
       field_widget_remove: true
+      field_widget_replace: false
       selection_mode: selection_append
       open: true
       field_widget_display_settings: {  }
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test_paragraphs/config/install/core.entity_form_display.paragraph.nested_paragrah.default.yml b/web/modules/entity_browser/tests/modules/entity_browser_test_paragraphs/config/install/core.entity_form_display.paragraph.nested_paragraph.default.yml
similarity index 95%
rename from web/modules/entity_browser/tests/modules/entity_browser_test_paragraphs/config/install/core.entity_form_display.paragraph.nested_paragrah.default.yml
rename to web/modules/entity_browser/tests/modules/entity_browser_test_paragraphs/config/install/core.entity_form_display.paragraph.nested_paragraph.default.yml
index 50848f71ca1db2dbe86c2ef7bfa59b4af1daa238..2a817a9c42443d100847c93adfe6efdd81f2def0 100644
--- a/web/modules/entity_browser/tests/modules/entity_browser_test_paragraphs/config/install/core.entity_form_display.paragraph.nested_paragrah.default.yml
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test_paragraphs/config/install/core.entity_form_display.paragraph.nested_paragraph.default.yml
@@ -19,6 +19,7 @@ content:
       field_widget_display: label
       field_widget_edit: true
       field_widget_remove: true
+      field_widget_replace: false
       selection_mode: selection_append
       open: true
       field_widget_display_settings: {  }
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test_paragraphs/config/install/views.view.nodes_entity_browser.yml b/web/modules/entity_browser/tests/modules/entity_browser_test_paragraphs/config/install/views.view.nodes_entity_browser.yml
index 3be9988b3d9875bdb13894d95d002d5f7daee1f9..01ec7581f12c0e8f83e2fd34180e473024394f59 100644
--- a/web/modules/entity_browser/tests/modules/entity_browser_test_paragraphs/config/install/views.view.nodes_entity_browser.yml
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test_paragraphs/config/install/views.view.nodes_entity_browser.yml
@@ -147,6 +147,7 @@ display:
           empty_zero: false
           hide_alter_empty: true
           entity_type: node
+          use_field_cardinality: false
           plugin_id: entity_browser_select
         title:
           id: title
diff --git a/web/modules/entity_browser/tests/modules/entity_browser_test_paragraphs/entity_browser_test_paragraphs.info.yml b/web/modules/entity_browser/tests/modules/entity_browser_test_paragraphs/entity_browser_test_paragraphs.info.yml
index 11882bebaf8a4a2d91502ea405fe63ba36a4ed6b..715fb75db6a4640e96d04a9f548a5b401bb80e18 100644
--- a/web/modules/entity_browser/tests/modules/entity_browser_test_paragraphs/entity_browser_test_paragraphs.info.yml
+++ b/web/modules/entity_browser/tests/modules/entity_browser_test_paragraphs/entity_browser_test_paragraphs.info.yml
@@ -1,21 +1,19 @@
 name: 'Entity browser test paragraphs'
 type: module
 description: 'Test Paragraphs Integration.'
-# core: 8.x
+core_version_requirement: ^8.7.7 || ^9
 package: Testing
-# version: VERSION
 dependencies:
-  - entity_reference_revisions
-  - entity_browser
-  - menu_ui
-  - node
-  - paragraphs
-  - path
-  - views
-  - user
+  - entity_reference_revisions:entity_reference_revisions
+  - entity_browser:entity_browser
+  - drupal:menu_ui
+  - drupal:node
+  - paragraphs:paragraphs
+  - drupal:path
+  - drupal:views
+  - drupal:user
 
-# Information added by Drupal.org packaging script on 2017-11-30
-version: '8.x-1.4'
-core: '8.x'
+# Information added by Drupal.org packaging script on 2020-01-20
+version: '8.x-1.10'
 project: 'entity_browser'
-datestamp: 1512033788
+datestamp: 1579563796
diff --git a/web/modules/entity_browser/tests/src/Functional/ConfigAccessTest.php b/web/modules/entity_browser/tests/src/Functional/ConfigAccessTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..cab07600c3b12ea6ccbbd3735632aea20c92ae82
--- /dev/null
+++ b/web/modules/entity_browser/tests/src/Functional/ConfigAccessTest.php
@@ -0,0 +1,93 @@
+<?php
+
+namespace Drupal\Tests\entity_browser\Functional;
+
+use Drupal\Tests\BrowserTestBase;
+
+/**
+ * Tests the config UI for adding and editing entity browsers.
+ *
+ * @group entity_browser
+ *
+ * @package Drupal\Tests\entity_browser\FunctionalJavascript
+ */
+class ConfigAccessTest extends BrowserTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  protected static $modules = [
+    'entity_browser',
+    'block',
+    'node',
+    'taxonomy',
+    'views',
+  ];
+
+  /**
+   * The test administrative user.
+   *
+   * @var \Drupal\user\UserInterface
+   */
+  protected $adminUser;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'stark';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->drupalPlaceBlock('local_tasks_block');
+    $this->drupalPlaceBlock('local_actions_block');
+
+    $this->adminUser = $this->drupalCreateUser([
+      'administer entity browsers',
+    ]);
+
+  }
+
+  /**
+   * Tests Access to EntityBrowserEditForm.
+   */
+  public function testEntityBrowserEditFormAccess() {
+    // Test that anonymous user can't access admin pages.
+    $this->drupalGet('/admin/config/content/entity_browser');
+    $this->assertSession()->statusCodeEquals(403, "Anonymous user can't access entity browser listing page.");
+    $this->drupalGet('/admin/config/content/entity_browser/add');
+    $this->assertSession()->statusCodeEquals(403, "Anonymous user can't access entity browser add form.");
+
+    // Test that user with "administer entity browsers" permission can access
+    // admin pages.
+    $this->drupalLogin($this->adminUser);
+    $this->drupalGet('/admin/config/content/entity_browser');
+    $this->assertSession()->statusCodeEquals(200, 'Admin user is able to navigate to the entity browser listing page.');
+    $this->assertSession()->responseContains('There are no entity browser entities yet.');
+
+    $this->clickLink('Add Entity browser');
+    $this->assertSession()->fieldExists('label')->setValue('Test entity browser');
+    $this->assertSession()->fieldExists('name')->setValue('test_entity_browser');
+    $this->assertSession()->buttonExists('Save')->press();
+    $this->assertSession()->addressEquals('/admin/config/content/entity_browser/test_entity_browser/widgets');
+
+    $this->drupalLogout();
+    $this->drupalGet('/admin/config/content/entity_browser/test_entity_browser');
+    $this->assertSession()->statusCodeEquals(404, "Anonymous user can't access entity browser edit form.");
+
+    $this->drupalLogin($this->adminUser);
+    $this->drupalGet('/admin/config/content/entity_browser');
+    $this->clickLink('Delete');
+    $this->assertSession()->responseContains('This action cannot be undone.', 'Delete question found.');
+    $this->drupalPostForm(NULL, [], 'Delete Entity Browser');
+
+    $this->assertSession()->responseContains('Entity browser <em class="placeholder">Test entity browser</em> was deleted.', 'Confirmation message found.');
+    $this->assertSession()->responseContains('There are no entity browser entities yet.', 'Entity browsers table is empty.');
+    $this->drupalLogout();
+  }
+
+}
diff --git a/web/modules/entity_browser/src/Tests/EntityBrowserUITest.php b/web/modules/entity_browser/tests/src/Functional/EntityBrowserUITest.php
similarity index 70%
rename from web/modules/entity_browser/src/Tests/EntityBrowserUITest.php
rename to web/modules/entity_browser/tests/src/Functional/EntityBrowserUITest.php
index 5e45754638b29c4a8ecee1eb0341ff8063052eb6..efa5d4de06c167b26fe000874b881640786dc142 100644
--- a/web/modules/entity_browser/src/Tests/EntityBrowserUITest.php
+++ b/web/modules/entity_browser/tests/src/Functional/EntityBrowserUITest.php
@@ -1,16 +1,19 @@
 <?php
 
-namespace Drupal\entity_browser\Tests;
+namespace Drupal\Tests\entity_browser\Functional;
 
 use Drupal\file\Entity\File;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
+use Drupal\Tests\TestFileCreationTrait;
 
 /**
  * Tests the entity browser UI.
  *
  * @group entity_browser
  */
-class EntityBrowserUITest extends WebTestBase {
+class EntityBrowserUITest extends BrowserTestBase {
+
+  use TestFileCreationTrait;
 
   /**
    * Modules to enable.
@@ -19,11 +22,15 @@ class EntityBrowserUITest extends WebTestBase {
    */
   public static $modules = [
     'entity_browser_test',
-    'ctools',
     'views',
     'block',
   ];
 
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'stark';
+
   /**
    * Tests entity browser UI.
    */
@@ -35,14 +42,14 @@ public function testEntityBrowserUI() {
     $this->drupalLogin($account);
     // Go to the entity browser iframe link.
     $this->drupalGet('/entity-browser/iframe/test_entity_browser_iframe');
-    $this->assertRaw('Select');
+    $this->assertSession()->responseContains('Select');
     $this->drupalGet('/admin/config/content/entity_browser/test_entity_browser_iframe/widgets');
     $edit = [
       'table[871dbf77-012e-41cb-b32a-ada353d2de35][form][submit_text]' => 'Different',
     ];
-    $this->drupalPostForm(NULL, $edit, 'Finish');
+    $this->submitForm($edit, 'Save');
     $this->drupalGet('/entity-browser/iframe/test_entity_browser_iframe');
-    $this->assertRaw('Different');
+    $this->assertSession()->responseContains('Different');
   }
 
   /**
@@ -56,16 +63,16 @@ public function testEntityBrowserToken() {
     $this->drupalLogin($account);
     // Go to the entity browser iframe link.
     $this->drupalGet('/entity-browser/iframe/test_entity_browser_token');
-    $image = current($this->drupalGetTestFiles('image'));
+    $image = current($this->getTestFiles('image'));
     $edit = [
       'files[upload][]' => $this->container->get('file_system')->realpath($image->uri),
     ];
-    $this->drupalPostForm(NULL, $edit, 'Select files');
+    $this->submitForm($edit, 'Select files');
 
     $file = File::load(1);
     // Test entity browser token that has upload location configured to
     // public://[current-user:account-name]/.
-    $this->assertEqual($file->getFileUri(), 'public://' . $account->getUsername() . '/' . $file->getFilename(), 'Image has the correct uri.');
+    $this->assertEquals($file->getFileUri(), 'public://' . $account->getAccountName() . '/' . $file->getFilename(), 'Image has the correct uri.');
   }
 
 }
diff --git a/web/modules/entity_browser/src/Tests/EntityBrowserUpdateHookTest.php b/web/modules/entity_browser/tests/src/Functional/EntityBrowserUpdateHookTest.php
similarity index 62%
rename from web/modules/entity_browser/src/Tests/EntityBrowserUpdateHookTest.php
rename to web/modules/entity_browser/tests/src/Functional/EntityBrowserUpdateHookTest.php
index e33ac1498d347f7bbff75bf225d0adad8da22c92..8851bd6bb25a59b3f6fc0c1be7ecd891b8f0cbfa 100644
--- a/web/modules/entity_browser/src/Tests/EntityBrowserUpdateHookTest.php
+++ b/web/modules/entity_browser/tests/src/Functional/EntityBrowserUpdateHookTest.php
@@ -1,8 +1,8 @@
 <?php
 
-namespace Drupal\entity_browser\Tests;
+namespace Drupal\Tests\entity_browser\Functional;
 
-use Drupal\system\Tests\Update\UpdatePathTestBase;
+use Drupal\FunctionalTests\Update\UpdatePathTestBase;
 
 /**
  * Tests the update hooks in entity_browser module.
@@ -11,13 +11,18 @@
  */
 class EntityBrowserUpdateHookTest extends UpdatePathTestBase {
 
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'stark';
+
   /**
    * Set database dump files to be used.
    */
   protected function setDatabaseDumpFiles() {
     $this->databaseDumpFiles = [
       DRUPAL_ROOT . '/core/modules/system/tests/fixtures/update/drupal-8.bare.standard.php.gz',
-      __DIR__ . '/../../tests/fixtures/update/entity_browser.update-hook-test.php',
+      __DIR__ . '/../../fixtures/update/entity_browser.update-hook-test.php',
     ];
   }
 
@@ -40,8 +45,8 @@ protected function setUp() {
    */
   protected function doSelectionTest() {
     parent::doSelectionTest();
-    $this->assertRaw('8001 -   Updates submit text for existing Entity browsers.');
-    $this->assertRaw('8002 -   Migrates duplicated Views entity_browser_select fields.');
+    $this->assertSession()->responseContains('8001 -   Updates submit text for existing Entity browsers.');
+    $this->assertSession()->responseContains('8002 -   Migrates duplicated Views entity_browser_select fields.');
   }
 
   /**
@@ -53,7 +58,7 @@ public function testSubmitTextUpdate() {
       ->get('entity_browser.browser.test_update');
 
     $this->assertNull($browser->get('submit_text'), 'Old submit text is gone');
-    $this->assertEqual($browser->get('widgets.a4ad947c-9669-497c-9988-24351955a02f.settings.submit_text'), 'All animals are created equal','New submit text appears on the widget.');
+    $this->assertEquals('All animals are created equal', $browser->get('widgets.a4ad947c-9669-497c-9988-24351955a02f.settings.submit_text'), 'New submit text appears on the widget.');
   }
 
   /**
@@ -64,7 +69,7 @@ public function testViewsFieldUpdate() {
     $view = $this->container->get('config.factory')
       ->get('views.view.test_deprecated_field');
 
-    $this->assertEqual($view->get('display.default.display_options.fields.entity_browser_select.table'), 'node', 'Data table in "entity_browser_select" replaced with data field.');
+    $this->assertEquals('node', $view->get('display.default.display_options.fields.entity_browser_select.table'), 'Data table in "entity_browser_select" replaced with data field.');
   }
 
 }
diff --git a/web/modules/entity_browser/tests/src/Functional/FormElementTest.php b/web/modules/entity_browser/tests/src/Functional/FormElementTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..ca840af4552f17d5e5477199c3ac4dfd4d277984
--- /dev/null
+++ b/web/modules/entity_browser/tests/src/Functional/FormElementTest.php
@@ -0,0 +1,86 @@
+<?php
+
+namespace Drupal\Tests\entity_browser\Functional;
+
+use Drupal\entity_browser\Element\EntityBrowserElement;
+use Drupal\Tests\BrowserTestBase;
+
+/**
+ * Tests the entity browser form element.
+ *
+ * @group entity_browser
+ */
+class FormElementTest extends BrowserTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['entity_browser_test', 'node', 'views'];
+
+  /**
+   * Test nodes.
+   *
+   * @var \Drupal\node\NodeInterface[]
+   */
+  protected $nodes;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'stark';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->container
+      ->get('entity_type.manager')
+      ->getStorage('node_type')
+      ->create([
+        'type' => 'page',
+        'name' => 'page',
+      ])->save();
+
+    $this->nodes[] = $this->drupalCreateNode();
+    $this->nodes[] = $this->drupalCreateNode();
+  }
+
+  /**
+   * Tests the Entity browser form element.
+   */
+  public function testFormElement() {
+    // See \Drupal\entity_browser_test\Form\FormElementTest.
+    $this->drupalGet('/test-element');
+    $this->assertSession()->linkExists('Select entities', 0, 'Trigger link found.');
+
+    $ids = [
+      $this->nodes[0]->getEntityTypeId() . ':' . $this->nodes[0]->id(),
+      $this->nodes[1]->getEntityTypeId() . ':' . $this->nodes[1]->id(),
+    ];
+
+    $ids = implode(' ', $ids);
+
+    $this->assertSession()->hiddenFieldExists("fancy_entity_browser[entity_ids]")->setValue($ids);
+
+    $this->assertSession()->buttonExists('Submit')->press();
+    $expected = 'Selected entities: ' . $this->nodes[0]->label() . ', ' . $this->nodes[1]->label();
+    $this->assertSession()->responseContains($expected, 'Selected entities detected.');
+
+    $default_entity = $this->nodes[0]->getEntityTypeId() . ':' . $this->nodes[0]->id();
+    $this->drupalGet('/test-element', ['query' => ['default_entity' => $default_entity, 'selection_mode' => EntityBrowserElement::SELECTION_MODE_EDIT]]);
+    $this->assertSession()->linkExists('Select entities', 0, 'Trigger link found.');
+
+    $this->assertSession()->hiddenFieldValueEquals("fancy_entity_browser[entity_ids]", $default_entity);
+    $hidden_field = $this->assertSession()->hiddenFieldExists("fancy_entity_browser[entity_ids]");
+    $new_value = 'node:' . $this->nodes[1]->id() . ' node:' . $this->nodes[0]->id();
+    $hidden_field->setValue($new_value);
+
+    $this->submitForm([], 'Submit');
+    $expected = 'Selected entities: ' . $this->nodes[1]->label() . ', ' . $this->nodes[0]->label();
+    $this->assertSession()->responseContains($expected, 'Selected entities detected.');
+  }
+
+}
diff --git a/web/modules/entity_browser/tests/src/FunctionalJavascript/CardinalityTest.php b/web/modules/entity_browser/tests/src/FunctionalJavascript/CardinalityTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..59ef388cd86acff6417323a8687b5e67e41f7ea2
--- /dev/null
+++ b/web/modules/entity_browser/tests/src/FunctionalJavascript/CardinalityTest.php
@@ -0,0 +1,377 @@
+<?php
+
+namespace Drupal\Tests\entity_browser\FunctionalJavascript;
+
+use Drupal\Core\Field\FieldStorageDefinitionInterface;
+use Drupal\entity_browser\Element\EntityBrowserElement;
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\Entity\FieldStorageConfig;
+use Drupal\user\Entity\Role;
+
+/**
+ * Tests the Cardinality handling.
+ *
+ * @group entity_browser
+ */
+class CardinalityTest extends EntityBrowserWebDriverTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = [
+    'entity_browser_test',
+    'embed',
+    'entity_embed',
+    'entity_browser_entity_embed_test',
+    'inline_entity_form',
+    'entity_browser_ief_test',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+
+    /** @var \Drupal\user\RoleInterface $role */
+    $role = Role::load('authenticated');
+    $this->grantPermissions($role, [
+      'access cardinality entity browser pages',
+      'bypass node access',
+      'administer node form display',
+      'access content',
+    ]);
+  }
+
+  /**
+   * Tests Entity Reference widget.
+   */
+  public function testEntityReferenceWidget() {
+
+    // Create an entity_reference field to test the widget.
+    $field_storage = FieldStorageConfig::create([
+      'field_name' => 'field_fellowship',
+      'type' => 'entity_reference',
+      'entity_type' => 'node',
+      'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
+      'settings' => [
+        'target_type' => 'node',
+      ],
+    ]);
+    $field_storage->save();
+
+    $field = FieldConfig::create([
+      'field_name' => 'field_fellowship',
+      'entity_type' => 'node',
+      'bundle' => 'article',
+      'label' => 'Referenced articles',
+      'settings' => [
+        'handler' => 'default:node',
+        'handler_settings' => [
+          'target_bundles' => [
+            'article' => 'article',
+            'shark' => 'shark',
+            'jet' => 'jet',
+          ],
+        ],
+      ],
+    ]);
+    $field->save();
+
+    /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
+    $form_display = $this->container->get('entity_type.manager')
+      ->getStorage('entity_form_display')
+      ->load('node.article.default');
+
+    $form_display->setComponent('field_fellowship', [
+      'type' => 'entity_browser_entity_reference',
+      'settings' => [
+        'entity_browser' => 'cardinality',
+        'open' => TRUE,
+        'field_widget_edit' => TRUE,
+        'field_widget_remove' => TRUE,
+        'field_widget_replace' => TRUE,
+        'selection_mode' => EntityBrowserElement::SELECTION_MODE_APPEND,
+        'field_widget_display' => 'label',
+        'field_widget_display_settings' => [],
+      ],
+    ])->save();
+
+    $gollum = $this->createNode(['type' => 'shark', 'title' => 'Gollum']);
+    $aragorn = $this->createNode(['type' => 'jet', 'title' => 'Aragorn']);
+    $gandolf = $this->createNode(['type' => 'article', 'title' => 'Gandolf']);
+    $legolas = $this->createNode(['type' => 'article', 'title' => 'Legolas']);
+    $boromir = $this->createNode(['type' => 'article', 'title' => 'Boromir']);
+
+    // Test the cardinality handling.
+    $role = Role::load('authenticated');
+    $this->grantPermissions($role, [
+      'access cardinality entity browser pages',
+      'bypass node access',
+      'administer node form display',
+    ]);
+    FieldStorageConfig::load('node.field_fellowship')
+      ->setCardinality(2)
+      ->save();
+    // Without using field cardinality, the view should contain checkboxes.
+    // Set view to use field cardinality.
+    $this->config('views.view.bundle_filter_exposed')
+      ->set('display.default.display_options.fields.entity_browser_select.use_field_cardinality', FALSE)
+      ->save();
+    $this->drupalGet('/node/add/article');
+    $this->assertSession()->fieldExists('title[0][value]')->setValue('Le Seigneur des anneaux');
+
+    $this->openIframe();
+    $gollum_checkbox = $this->assertCheckboxExistsByValue('node:' . $gollum->id());
+    $gollum_checkbox->check();
+    $aragorn_checkbox = $this->assertCheckboxExistsByValue('node:' . $aragorn->id());
+    $aragorn_checkbox->check();
+    $this->assertTrue($gollum_checkbox->isChecked());
+    $this->assertTrue($aragorn_checkbox->isChecked());
+    // If using field cardinality and field cardinality is greater than 1 then
+    // there should be still checkboxes.
+    $this->config('views.view.bundle_filter_exposed')
+      ->set('display.default.display_options.fields.entity_browser_select.use_field_cardinality', TRUE)
+      ->save();
+    $this->drupalGet('/node/add/article');
+    $this->openIframe();
+    $gollum_checkbox = $this->assertCheckboxExistsByValue('node:' . $gollum->id());
+    $aragorn_checkbox = $this->assertCheckboxExistsByValue('node:' . $aragorn->id());
+    $gandolf_checkbox = $this->assertCheckboxExistsByValue('node:' . $gandolf->id());
+    $this->assertCheckboxExistsByValue('node:' . $legolas->id());
+    $this->assertCheckboxExistsByValue('node:' . $boromir->id());
+    // If we attempt to select 3 nodes, Entity Browser should prevent it and
+    // return an error message.
+    $gollum_checkbox->check();
+    $aragorn_checkbox->check();
+    $gandolf_checkbox->check();
+    $this->assertSession()->buttonExists('Select entities')->press();
+    $this->waitForAjaxToFinish();
+    $this->assertSession()->pageTextContains('You can only select up to 2 items');
+    // If we change the cardinality to 1, we should have radios.
+    FieldStorageConfig::load('node.field_fellowship')
+      ->setCardinality(1)
+      ->save();
+    $this->drupalGet('/node/add/article');
+    $this->openIframe();
+    $gollum_radio = $this->assertRadioExistsByValue('node:' . $gollum->id());
+    $gollum_radio->click();
+    $this->assertSession()->buttonExists('Select entities')->press();
+    $this->getSession()->switchToIFrame();
+    $this->waitForAjaxToFinish();
+    // Assert the selected entity.
+    $this->assertSession()->pageTextContains('Gollum');
+    // Attempt to select more than one element.
+    $this->assertSession()->buttonExists('Replace')->press();
+    $this->waitForAjaxToFinish();
+    $this->getSession()->switchToIFrame('entity_browser_iframe_cardinality');
+    $this->waitForAjaxToFinish();
+    $gollum_radio = $this->assertRadioExistsByValue('node:' . $gollum->id());
+    $gollum_radio->click();
+    $gandolf_radio = $this->assertRadioExistsByValue('node:' . $gandolf->id());
+    $gandolf_radio->click();
+    $this->assertFalse($gollum_radio->isSelected());
+    $this->assertTrue($gandolf_radio->isSelected());
+    $this->assertSession()->buttonExists('Select entities')->press();
+    $this->getSession()->switchToIFrame();
+    $this->waitForAjaxToFinish();
+    // Assert the selected entity.
+    $this->assertSession()->pageTextContains('Gandolf');
+    $this->assertSession()->pageTextNotContains('Gollum');
+
+    $this->assertSession()->buttonExists('Replace')->press();
+    $this->waitForAjaxToFinish();
+    $this->getSession()->switchToIFrame('entity_browser_iframe_cardinality');
+    $this->waitForAjaxToFinish();
+
+    // Test that cardinality setting persists when using exposed filters form,
+    // When applying the exposed filters, the radios should persist.
+    $this->assertSession()->selectExists('Type')->selectOption('jet');
+    $this->assertSession()->buttonExists('Apply')->press();
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    $this->assertRadioExistsByValue('node:' . $aragorn->id());
+    $this->assertRadioNotExistsByValue('node:' . $legolas->id());
+
+    $this->assertSession()->selectExists('Type')->selectOption('shark');
+    $this->assertSession()->buttonExists('Apply')->press();
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    $this->assertRadioExistsByValue('node:' . $gollum->id());
+    $this->assertRadioNotExistsByValue('node:' . $aragorn->id());
+
+  }
+
+  /**
+   * Tests cardinality functionality using Entity Embed button.
+   */
+  public function testEntityEmbed() {
+
+    $this->config('entity_browser.browser.bundle_filter')
+      ->set('widgets.b882a89d-9ce4-4dfe-9802-62df93af232a.settings.view', 'bundle_filter_exposed')
+      ->save();
+
+    $role = Role::load('authenticated');
+    $this->grantPermissions($role, [
+      'access content',
+      'use text format full_html',
+      'create test_entity_embed content',
+      'access bundle_filter entity browser pages',
+    ]);
+
+    FieldStorageConfig::load('node.field_nodes')
+      ->setCardinality(1)
+      ->save();
+
+    $westley = $this->createNode(['type' => 'shark', 'title' => 'Westley']);
+    $buttercup = $this->createNode(['type' => 'jet', 'title' => 'Buttercup']);
+    $humperdinck = $this->createNode(['type' => 'article', 'title' => 'Humperdinck']);
+
+    $this->drupalGet('/node/add/test_entity_embed');
+    $this->assertSession()->waitForElement('css', 'a.cke_button__bundle_filter_test')->click();
+    $this->assertSession()->waitForElementVisible('xpath', "//iframe[contains(@name, 'entity_browser_iframe_bundle_filter')]", 3000);
+    $this->getSession()->switchToIFrame('entity_browser_iframe_bundle_filter');
+    $this->assertSession()->waitForElementVisible('xpath', "//div[contains(@class, 'views-exposed-form')]");
+
+    // Without use_field_cardinality set, there should be checkboxes, the default.
+    $this->assertCheckBoxExistsByValue('node:' . $westley->id());
+    $this->assertCheckBoxExistsByValue('node:' . $buttercup->id());
+    $this->assertCheckBoxNotExistsByValue('node:' . $humperdinck->id());
+
+    // Set view to use field cardinality.
+    $this->config('views.view.bundle_filter_exposed')
+      ->set('display.default.display_options.fields.entity_browser_select.use_field_cardinality', TRUE)
+      ->save();
+
+    $this->drupalGet('/node/add/test_entity_embed');
+    $this->assertSession()->waitForElement('css', 'a.cke_button__bundle_filter_test')->click();
+    $this->assertSession()->waitForElementVisible('xpath', "//iframe[contains(@name, 'entity_browser_iframe_bundle_filter')]", 3000);
+    $this->getSession()->switchToIFrame('entity_browser_iframe_bundle_filter');
+    $this->assertSession()->waitForElementVisible('xpath', "//div[contains(@class, 'views-exposed-form')]");
+
+    // With use_field_cardinality set to true, there should be radios, since
+    // cardinality on entity embed is always 1.
+    $this->assertRadioExistsByValue('node:' . $westley->id());
+    $this->assertRadioExistsByValue('node:' . $buttercup->id());
+    $this->assertRadioNotExistsByValue('node:' . $humperdinck->id());
+
+    // Test that cardinality setting persists when using exposed filters form.
+    // When applying the exposed filters, the radios should persist.
+    $this->assertSession()->selectExists('Type')->selectOption('jet');
+    $this->assertSession()->buttonExists('Apply')->press();
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    $this->assertRadioNotExistsByValue('node:' . $westley->id());
+    $this->assertRadioExistsByValue('node:' . $buttercup->id());
+    $this->assertRadioNotExistsByValue('node:' . $humperdinck->id());
+
+    $this->assertSession()->selectExists('Type')->selectOption('shark');
+    $this->assertSession()->buttonExists('Apply')->press();
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    $this->assertRadioExistsByValue('node:' . $westley->id());
+    $this->assertRadioNotExistsByValue('node:' . $buttercup->id());
+    $this->assertRadioNotExistsByValue('node:' . $humperdinck->id());
+
+  }
+
+  /**
+   * Tests cardinality functionality using Inline Entity Form.
+   */
+  public function testInlineEntityForm() {
+
+    /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
+    $form_display = $this->container->get('entity_type.manager')
+      ->getStorage('entity_form_display')
+      ->load('node.ief_content.default');
+
+    $field_nodes = $form_display->getComponent('field_nodes');
+    $field_nodes['third_party_settings']['entity_browser_entity_form']['entity_browser_id'] = 'cardinality';
+    $form_display->setComponent('field_nodes', $field_nodes);
+    $form_display->save();
+
+    // Set auto open to TRUE on the entity browser.
+    $entity_browser = $this->container->get('entity_type.manager')
+      ->getStorage('entity_browser')
+      ->load('cardinality');
+    $display_configuration = $entity_browser->get('display_configuration');
+    $display_configuration['auto_open'] = TRUE;
+    $entity_browser->set('display_configuration', $display_configuration);
+    $entity_browser->save();
+
+    $vizzini = $this->createNode(['type' => 'shark', 'title' => 'Vizzini']);
+    $inigo = $this->createNode(['type' => 'jet', 'title' => 'Inigo']);
+    $miracle_max = $this->createNode(['type' => 'article', 'title' => 'Miracle Max']);
+
+    $this->drupalGet('node/add/ief_content');
+    $page = $this->getSession()->getPage();
+
+    $page->pressButton('Add existing node');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->getSession()->switchToIFrame('entity_browser_iframe_cardinality');
+
+    // Without use_field_cardinality set, there should be checkboxes, the default.
+    $this->assertCheckBoxExistsByValue('node:' . $vizzini->id());
+    $this->assertCheckBoxExistsByValue('node:' . $inigo->id());
+    $this->assertCheckBoxNotExistsByValue('node:' . $miracle_max->id());
+
+    $view = $this->config('views.view.bundle_filter_exposed');
+    $field = $view->get('display.default.display_options.fields.entity_browser_select', TRUE);
+    $field['use_field_cardinality'] = TRUE;
+    $view->set('display.default.display_options.fields.entity_browser_select', $field);
+    $view->save();
+
+    FieldStorageConfig::load('node.field_nodes')
+      ->setCardinality(1)
+      ->save();
+
+    $this->drupalGet('node/add/ief_content');
+    $page = $this->getSession()->getPage();
+
+    $page->pressButton('Add existing node');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->getSession()->switchToIFrame('entity_browser_iframe_cardinality');
+
+    // With use_field_cardinality set to true, and cardinality set to 1,
+    // there should be radios.
+    $this->assertRadioExistsByValue('node:' . $vizzini->id());
+    $this->assertRadioExistsByValue('node:' . $inigo->id());
+    $this->assertRadioNotExistsByValue('node:' . $miracle_max->id());
+
+    // Test that cardinality setting persists when using exposed filters form.
+    // When applying the exposed filters, the radios should persist.
+    $this->assertSession()->selectExists('Type')->selectOption('jet');
+    $this->assertSession()->buttonExists('Apply')->press();
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    $this->assertRadioNotExistsByValue('node:' . $vizzini->id());
+    $this->assertRadioExistsByValue('node:' . $inigo->id());
+    $this->assertRadioNotExistsByValue('node:' . $miracle_max->id());
+
+    $this->assertSession()->selectExists('Type')->selectOption('shark');
+    $this->assertSession()->buttonExists('Apply')->press();
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    $this->assertRadioExistsByValue('node:' . $vizzini->id());
+    $this->assertRadioNotExistsByValue('node:' . $inigo->id());
+    $this->assertRadioNotExistsByValue('node:' . $miracle_max->id());
+
+  }
+
+  /**
+   * Helper function for repetitive task.
+   *
+   * @throws \Behat\Mink\Exception\ElementNotFoundException
+   */
+  protected function openIframe() {
+    $open_iframe_link = $this->assertSession()
+      ->elementExists('css', 'a[data-drupal-selector="edit-field-fellowship-entity-browser-entity-browser-link"]');
+    $open_iframe_link->click();
+    $this->waitForAjaxToFinish();
+    $this->getSession()->switchToIFrame('entity_browser_iframe_cardinality');
+    $this->waitForAjaxToFinish();
+  }
+
+}
diff --git a/web/modules/entity_browser/tests/src/FunctionalJavascript/ConfigurationTest.php b/web/modules/entity_browser/tests/src/FunctionalJavascript/ConfigurationTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..a18abaf74aedcf8336311dc00017ab3581a41a16
--- /dev/null
+++ b/web/modules/entity_browser/tests/src/FunctionalJavascript/ConfigurationTest.php
@@ -0,0 +1,350 @@
+<?php
+
+namespace Drupal\Tests\entity_browser\FunctionalJavascript;
+
+use Drupal\entity_browser\Entity\EntityBrowser;
+use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
+
+/**
+ * Tests the config UI for adding and editing entity browsers.
+ *
+ * @group entity_browser
+ *
+ * @package Drupal\Tests\entity_browser\FunctionalJavascript
+ */
+class ConfigurationTest extends WebDriverTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  protected static $modules = [
+    'entity_browser',
+    'entity_browser_entity_form',
+    'entity_browser_test_configuration',
+    'block',
+    'node',
+    'taxonomy',
+    'views',
+    'token',
+  ];
+
+  /**
+   * The test administrative user.
+   *
+   * @var \Drupal\user\UserInterface
+   */
+  protected $adminUser;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'stark';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->drupalPlaceBlock('local_tasks_block');
+    $this->drupalPlaceBlock('local_actions_block');
+
+    $this->drupalCreateContentType(['type' => 'foo', 'name' => 'Foo']);
+
+    $this->adminUser = $this->drupalCreateUser([
+      'administer entity browsers',
+    ]);
+
+  }
+
+  /**
+   * Tests EntityBrowserEditForm.
+   */
+  public function testEntityBrowserEditForm() {
+
+    $this->drupalLogin($this->adminUser);
+    $this->drupalGet('/admin/config/content/entity_browser');
+    $this->assertSession()->responseNotContains('Access denied. You must log in to view this page.');
+    $this->assertSession()->responseContains('There are no entity browser entities yet.');
+
+    $this->clickLink('Add Entity browser');
+    $this->assertSession()->fieldExists('label')->setValue('Test entity browser');
+    $this->getSession()->executeScript("jQuery('.visually-hidden').removeClass('visually-hidden');");
+    $this->assertSession()->fieldExists('name')->setValue('test_entity_browser');
+    $this->assertSession()->selectExists('display')->selectOption('modal');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    // Make sure fields in details elements are visible.
+    $this->getSession()->executeScript("jQuery('details').attr('open', 'open');");
+    $this->assertSession()->fieldExists('display_configuration[width]')->setValue('700');
+    $this->assertSession()->fieldExists('display_configuration[height]')->setValue('300');
+    $this->assertSession()->fieldExists('display_configuration[link_text]')->setValue('Select some entities');
+    $this->assertSession()->selectExists('widget_selector')->selectOption('tabs');
+    $this->assertSession()->selectExists('selection_display')->selectOption('no_display');
+    $this->drupalPostForm(NULL, [], 'Save');
+    $this->assertSession()->pageTextContains('The entity browser Test entity browser has been added. Now you may configure the widgets you would like to use.');
+
+    $this->assertSession()->addressEquals('/admin/config/content/entity_browser/test_entity_browser/widgets');
+    $this->assertSession()->selectExists('widget');
+
+    $this->clickLink('General Settings');
+    $this->assertSession()->addressEquals('/admin/config/content/entity_browser/test_entity_browser/edit');
+
+    $entity_browser = EntityBrowser::load('test_entity_browser');
+
+    $this->assertEquals('modal', $entity_browser->display);
+    $this->assertEquals('tabs', $entity_browser->widget_selector);
+    $this->assertEquals('no_display', $entity_browser->selection_display);
+
+    $display_configuration = $entity_browser->getDisplay()->getConfiguration();
+
+    $this->assertEquals('700', $display_configuration['width']);
+    $this->assertEquals('300', $display_configuration['height']);
+    $this->assertEquals('Select some entities', $display_configuration['link_text']);
+
+    $this->assertSession()->fieldValueEquals('display_configuration[width]', '700');
+    $this->assertSession()->fieldValueEquals('display_configuration[height]', '300');
+    $this->assertSession()->fieldValueEquals('display_configuration[link_text]', 'Select some entities');
+
+    $this->assertSession()->selectExists('display')->selectOption('iframe');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->assertSession()->fieldExists('display_configuration[auto_open]')->check();
+    $this->assertSession()->fieldExists('display_configuration[width]')->setValue('100');
+    $this->assertSession()->fieldExists('display_configuration[height]')->setValue('100');
+    $this->assertSession()->fieldExists('display_configuration[link_text]')->setValue('All animals are created equal');
+    $this->drupalPostForm(NULL, [], 'Save');
+    $this->assertSession()->addressEquals('/admin/config/content/entity_browser/test_entity_browser/edit');
+    $this->assertSession()->pageTextContains('The entity browser Test entity browser has been updated.');
+
+    $entity_browser = EntityBrowser::load('test_entity_browser');
+
+    $this->assertEquals('iframe', $entity_browser->display);
+    $this->assertEquals('tabs', $entity_browser->widget_selector);
+    $this->assertEquals('no_display', $entity_browser->selection_display);
+
+    $display_configuration = $entity_browser->getDisplay()->getConfiguration();
+
+    $this->assertEquals('100', $display_configuration['width']);
+    $this->assertEquals('100', $display_configuration['height']);
+    $this->assertEquals('All animals are created equal', $display_configuration['link_text']);
+    $this->assertEquals(TRUE, $display_configuration['auto_open']);
+    $this->assertSession()->fieldExists('display_configuration[width]');
+    $this->assertSession()->fieldValueEquals('display_configuration[width]', '100');
+    $this->assertSession()->fieldValueEquals('display_configuration[height]', '100');
+    $this->assertSession()->fieldValueEquals('display_configuration[link_text]', 'All animals are created equal');
+    $this->assertSession()->checkboxChecked('display_configuration[auto_open]');
+
+    $this->assertSession()->selectExists('display')->selectOption('standalone');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->assertSession()->fieldExists('display_configuration[path]')->setValue('/all-animals');
+    $this->drupalPostForm(NULL, [], 'Save');
+    $this->assertSession()->addressEquals('/admin/config/content/entity_browser/test_entity_browser/edit');
+    $this->assertSession()->pageTextContains('The entity browser Test entity browser has been updated.');
+    $this->clickLink('General Settings');
+    $this->assertSession()->addressEquals('/admin/config/content/entity_browser/test_entity_browser/edit');
+    $this->getSession()->executeScript("jQuery('details').attr('open', 'open');");
+
+    $entity_browser = EntityBrowser::load('test_entity_browser');
+
+    $this->assertEquals('standalone', $entity_browser->display);
+
+    $display_configuration = $entity_browser->getDisplay()->getConfiguration();
+
+    $this->assertEquals('/all-animals', $display_configuration['path']);
+    $this->assertSession()->fieldValueEquals('display_configuration[path]', '/all-animals');
+
+    // Test validation of leading forward slash.
+    $this->assertSession()->fieldExists('display_configuration[path]')->setValue('no-forward-slash');
+    $this->drupalPostForm(NULL, [], 'Save');
+    $this->assertSession()->responseContains('The Path field must begin with a forward slash.');
+    $this->assertSession()->fieldExists('display_configuration[path]')->setValue('/all-animals');
+    $this->drupalPostForm(NULL, [], 'Save');
+    $this->assertSession()->pageTextContains('The entity browser Test entity browser has been updated.');
+    $this->getSession()->executeScript("jQuery('details').attr('open', 'open');");
+
+    // Test ajax update of display settings.
+    $this->assertSession()->selectExists('display')->selectOption('iframe');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->assertSession()->fieldExists('display_configuration[width]');
+    $this->assertSession()->responseContains('Width of the iFrame', 'iFrame Display config form present');
+
+    $this->assertSession()->selectExists('display')->selectOption('standalone');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->assertSession()->fieldExists('display_configuration[path]');
+    $this->assertSession()->responseContains('The path at which the browser will be accessible.', 'Standalone Display config form present');
+
+    $this->assertSession()->selectExists('display')->selectOption('modal');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->assertSession()->fieldExists('display_configuration[width]');
+    $this->assertSession()->responseContains('Width of the modal', 'iFrame Display config form present');
+
+    // Test ajax update of Selection display plugin settings.
+    $this->assertSession()->selectExists('selection_display')->selectOption('multi_step_display');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->assertSession()->fieldExists('selection_display_configuration[select_text]');
+    $this->assertSession()->fieldExists('selection_display_configuration[selection_hidden]');
+    $this->assertSession()->selectExists('selection_display_configuration[entity_type]');
+    $this->assertSession()->selectExists('selection_display_configuration[display]')->selectOption('rendered_entity');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->assertSession()->fieldExists('selection_display_configuration[display_settings][view_mode]');
+    $this->assertSession()->responseContains('Select view mode to be used when rendering entities.');
+
+    // Test ajax update of Multi step selection display "Entity display plugin".
+    $this->assertSession()->selectExists('selection_display_configuration[display]')->selectOption('label');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->assertSession()->fieldNotExists('selection_display_configuration[display_settings][view_mode]');
+    $this->assertSession()->selectExists('selection_display_configuration[display]')->selectOption('rendered_entity');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->assertSession()->fieldExists('selection_display_configuration[display_settings][view_mode]');
+    $this->assertSession()->responseContains('Select view mode to be used when rendering entities.');
+
+    // Test ajax update of Multi step selection display "Entity type".
+    $entity_type = $this->assertSession()->selectExists('selection_display_configuration[entity_type]')->selectOption('taxonomy_term');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->assertSession()->optionExists('selection_display_configuration[display_settings][view_mode]', 'default');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->assertSession()->optionExists('selection_display_configuration[display_settings][view_mode]', 'full');
+
+    // Test view selection display.
+    $this->assertSession()->selectExists('selection_display')->selectOption('view');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->assertSession()->optionExists('selection_display_configuration[view]', 'content.default');
+    $this->assertSession()->responseContains('View display to use for displaying currently selected items.');
+
+    $this->assertSession()->selectExists('selection_display')->selectOption('no_display');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->assertSession()->elementContains('css', 'details[data-drupal-selector="edit-selection-display-configuration"]', 'This plugin has no configuration options');
+
+  }
+
+  /**
+   * Tests WidgetsConfig form.
+   */
+  public function testWidgetsConfig() {
+
+    $this->drupalLogin($this->adminUser);
+    $this->drupalGet('/admin/config/content/entity_browser');
+    $this->clickLink('Add Entity browser');
+    $this->assertSession()->fieldExists('label')->setValue('Test entity browser');
+    $this->getSession()->executeScript("jQuery('.visually-hidden').removeClass('visually-hidden');");
+    $this->assertSession()->fieldExists('name')->setValue('test_entity_browser');
+    // Use defaults and save to go to WidgetsConfig form.
+    $this->drupalPostForm(NULL, [], 'Save');
+    $this->assertSession()->addressEquals('/admin/config/content/entity_browser/test_entity_browser/widgets');
+    $this->assertSession()->pageTextContains('The entity browser Test entity browser has been added. Now you may configure the widgets you would like to use.');
+    $widgetSelect = $this->assertSession()->selectExists('widget');
+
+    $this->assertSession()->responseContains('The available plugins are:');
+    $this->assertSession()->responseContains("<strong>Upload:</strong> Adds an upload field browser's widget.");
+    $this->assertSession()->responseContains("<strong>View:</strong> Uses a view to provide entity listing in a browser's widget.");
+    $this->assertSession()->responseContains("<strong>Entity form:</strong> Provides entity form widget.");
+
+    // Test adding and removing entity form widget.
+    $widgetSelect->selectOption('entity_form');
+    $selector = $this->assertSession()
+      ->waitforElementVisible('css', 'tr.draggable')
+      ->getAttribute('data-drupal-selector');
+    $uuid = str_replace('edit-table-', '', $selector);
+    $this->assertSession()->fieldExists("table[$uuid][label]");
+    $this->assertSession()->fieldExists("table[$uuid][form][submit_text]");
+    $this->assertSession()->selectExists("table[$uuid][form][entity_type]")->selectOption('node');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->assertSession()->selectExists("table[$uuid][form][bundle][select]")->selectOption('foo');
+    $this->assertSession()->selectExists("table[$uuid][form][form_mode][form_select]");
+    $this->drupalPostForm(NULL, [], 'Save');
+    $this->assertSession()->addressEquals('/admin/config/content/entity_browser/test_entity_browser/widgets');
+    $this->assertSession()->pageTextContains('The entity browser Test entity browser has been updated.');
+
+    $entity_browser = EntityBrowser::load('test_entity_browser');
+    $widget = $entity_browser->getWidget($uuid);
+    $widgetSettings = $widget->getConfiguration()['settings'];
+
+    $this->assertEquals([
+      'submit_text' => 'Save entity',
+      'entity_type' => 'node',
+      'bundle' => 'foo',
+      'form_mode' => 'default',
+    ], $widgetSettings, 'Entity browser widget configuration was correctly saved.');
+
+    $this->assertSession()->buttonExists("edit-table-$uuid-remove")->press();
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->assertSession()->elementNotExists('css', 'tr[data-drupal-selector="edit-table-' . $uuid . '"]');
+    // There should be no widgets now.
+    $this->assertSession()->elementNotExists('css', 'tr.draggable');
+
+    // Test adding and removing view widget.
+    $widgetSelect->selectOption('view');
+    $selector = $this->assertSession()
+      ->waitforElementVisible('css', 'tr.draggable')
+      ->getAttribute('data-drupal-selector');
+    $uuid = str_replace('edit-table-', '', $selector);
+    $this->assertSession()->fieldExists("table[$uuid][label]");
+    $this->assertSession()->fieldExists("table[$uuid][form][submit_text]");
+    $this->assertSession()->fieldExists("table[$uuid][form][auto_select]")->check();
+    $this->assertSession()->selectExists("table[$uuid][form][view]")->selectOption('nodes_entity_browser.entity_browser_1');
+    $this->drupalPostForm(NULL, [], 'Save');
+    $this->assertSession()->addressEquals('/admin/config/content/entity_browser/test_entity_browser/widgets');
+    $this->assertSession()->pageTextContains('The entity browser Test entity browser has been updated.');
+
+    $entity_browser = EntityBrowser::load('test_entity_browser');
+    $widget = $entity_browser->getWidget($uuid);
+    $widgetSettings = $widget->getConfiguration()['settings'];
+
+    $this->assertEquals([
+      'view' => 'nodes_entity_browser',
+      'view_display' => 'entity_browser_1',
+      'submit_text' => 'Select entities',
+      'auto_select' => TRUE,
+    ], $widgetSettings, 'Entity browser widget configuration was correctly saved.');
+
+    $this->assertSession()->buttonExists("edit-table-$uuid-remove")->press();
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->assertSession()->elementNotExists('css', 'tr[data-drupal-selector="edit-table-' . $uuid . '"]');
+    // There should be no widgets now.
+    $this->assertSession()->elementNotExists('css', 'tr.draggable');
+
+    // Test adding and removing upload widget.
+    $widgetSelect->selectOption('upload');
+    $selector = $this->assertSession()
+      ->waitforElementVisible('css', 'tr.draggable')
+      ->getAttribute('data-drupal-selector');
+    $uuid = str_replace('edit-table-', '', $selector);
+    $this->assertSession()->fieldExists("table[$uuid][label]");
+    $this->assertSession()->fieldExists("table[$uuid][form][submit_text]");
+    $this->assertSession()->fieldExists("table[$uuid][form][upload_location]");
+    $this->assertSession()->fieldExists("table[$uuid][form][multiple]");
+    $this->assertSession()->fieldExists("table[$uuid][form][upload_location]");
+    $this->assertSession()->elementExists('css', 'a.token-dialog.use-ajax');
+    $this->drupalPostForm(NULL, [], 'Save');
+    $this->assertSession()->addressEquals('/admin/config/content/entity_browser/test_entity_browser/widgets');
+    $this->assertSession()->pageTextContains('The entity browser Test entity browser has been updated.');
+
+    $entity_browser = EntityBrowser::load('test_entity_browser');
+    $widget = $entity_browser->getWidget($uuid);
+    $widgetSettings = $widget->getConfiguration()['settings'];
+
+    $this->assertEquals([
+      'upload_location' => 'public://',
+      'multiple' => TRUE,
+      'submit_text' => 'Select files',
+      'extensions' => 'jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp',
+    ], $widgetSettings, 'Entity browser widget configuration was correctly saved.');
+
+    $this->assertSession()->buttonExists("edit-table-$uuid-remove")->press();
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->assertSession()->elementNotExists('css', 'tr[data-drupal-selector="edit-table-' . $uuid . '"]');
+    // There should be no widgets now.
+    $this->assertSession()->elementNotExists('css', 'tr.draggable');
+
+    // Go back to listing page.
+    $this->drupalGet('/admin/config/content/entity_browser');
+    $this->assertSession()->responseContains('admin/config/content/entity_browser/test_entity_browser/edit');
+
+    // Test that removing widget without saving doesn't remove it permanently.
+    $entity_browser = EntityBrowser::load('test_entity_browser');
+    $widget = $entity_browser->getWidget($uuid);
+    $this->assertNotEmpty($widget);
+
+  }
+
+}
diff --git a/web/modules/entity_browser/tests/src/FunctionalJavascript/EntityBrowserJavascriptTestBase.php b/web/modules/entity_browser/tests/src/FunctionalJavascript/EntityBrowserJavascriptTestBase.php
index 568a595cf046a81d3ea01d093527d605288e6673..bece7379b66d4c285e45664258456af8778f0caf 100644
--- a/web/modules/entity_browser/tests/src/FunctionalJavascript/EntityBrowserJavascriptTestBase.php
+++ b/web/modules/entity_browser/tests/src/FunctionalJavascript/EntityBrowserJavascriptTestBase.php
@@ -13,6 +13,11 @@
  * Base class for Entity browser Javascript functional tests.
  *
  * @package Drupal\Tests\entity_browser\FunctionalJavascript
+ *
+ * @deprecated in Drupal 8.6.x, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Tests\entity_browser\FunctionalJavascript\EntityBrowserWebDriverTestBase instead
+ *
+ * @see \Drupal\FunctionalJavascriptTests\JavascriptTestBase for more info.
  */
 abstract class EntityBrowserJavascriptTestBase extends JavascriptTestBase {
 
@@ -23,7 +28,6 @@ abstract class EntityBrowserJavascriptTestBase extends JavascriptTestBase {
    */
   public static $modules = [
     'entity_browser_test',
-    'ctools',
     'views',
     'block',
     'node',
@@ -51,8 +55,6 @@ abstract class EntityBrowserJavascriptTestBase extends JavascriptTestBase {
   protected function setUp() {
     parent::setUp();
 
-    $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']);
-
     FieldStorageConfig::create([
       'field_name' => 'field_reference',
       'type' => 'entity_reference',
diff --git a/web/modules/entity_browser/tests/src/FunctionalJavascript/EntityBrowserTest.php b/web/modules/entity_browser/tests/src/FunctionalJavascript/EntityBrowserTest.php
index e8add2cefc7480b27e3426777593ea88b53483f7..e32d35d2f30e7a1e7db65f01626f85ab3d6ebbe8 100644
--- a/web/modules/entity_browser/tests/src/FunctionalJavascript/EntityBrowserTest.php
+++ b/web/modules/entity_browser/tests/src/FunctionalJavascript/EntityBrowserTest.php
@@ -7,7 +7,7 @@
  *
  * @group entity_browser
  */
-class EntityBrowserTest extends EntityBrowserJavascriptTestBase {
+class EntityBrowserTest extends EntityBrowserWebDriverTestBase {
 
   /**
    * Tests single widget selector.
@@ -50,6 +50,76 @@ public function testSingleWidgetSelector() {
     $this->assertSession()->linkExists('Select entities');
   }
 
+  /**
+   * Tests the field widget with a single-cardinality field.
+   */
+  public function testSingleCardinalityField() {
+    $this->container->get('entity_type.manager')
+      ->getStorage('field_storage_config')
+      ->load('node.field_reference')
+      ->setCardinality(1)
+      ->save();
+
+    // Create a file.
+    $image = $this->createFile('llama');
+
+    $this->drupalGet('node/add/article');
+
+    $this->assertSession()->linkExists('Select entities');
+    $this->assertSession()->pageTextContains('You can select one file.');
+    $this->getSession()->getPage()->clickLink('Select entities');
+
+    $this->getSession()->switchToIFrame('entity_browser_iframe_test_entity_browser_file');
+
+    $this->getSession()->getPage()->checkField('entity_browser_select[file:' . $image->id() . ']');
+    $this->getSession()->getPage()->pressButton('Select entities');
+
+    // Switch back to the main page.
+    $this->getSession()->switchToIFrame();
+    $this->waitForAjaxToFinish();
+    // A selection has been made, so the message is no longer necessary.
+    $this->assertSession()->pageTextNotContains('You can select one file.');
+  }
+
+  /**
+   * Tests the field widget with a multi-cardinality field.
+   */
+  public function testMultiCardinalityField() {
+    $assert_session = $this->assertSession();
+    $session = $this->getSession();
+    $page = $session->getPage();
+
+    $this->container->get('entity_type.manager')
+      ->getStorage('field_storage_config')
+      ->load('node.field_reference')
+      ->setCardinality(3)
+      ->save();
+
+    // Create a few files to choose.
+    $images = [];
+    array_push($images, $this->createFile('llama'));
+    array_push($images, $this->createFile('sloth'));
+    array_push($images, $this->createFile('puppy'));
+
+    $this->drupalGet('node/add/article');
+
+    $assert_session->linkExists('Select entities');
+    $assert_session->pageTextContains('You can select up to 3 files (3 left).');
+    $page->clickLink('Select entities');
+
+    $session->switchToIFrame('entity_browser_iframe_test_entity_browser_file');
+
+    $page->checkField('entity_browser_select[file:' . $images[0]->id() . ']');
+    $page->checkField('entity_browser_select[file:' . $images[1]->id() . ']');
+    $page->pressButton('Select entities');
+
+    // Switch back to the main page.
+    $session->switchToIFrame();
+    $this->waitForAjaxToFinish();
+    // Selections have been made, so the message should be different.
+    $assert_session->pageTextContains('You can select up to 3 files (1 left).');
+  }
+
   /**
    * Tests tabs widget selector.
    */
@@ -78,6 +148,7 @@ public function testTabsWidgetSelector() {
 
     $this->getSession()->switchToIFrame('entity_browser_iframe_test_entity_browser_file');
 
+    $this->assertSession()->linkExists('dummy');
     $this->assertSession()->linkExists('view');
     $this->assertSession()->linkExists('upload');
 
@@ -98,10 +169,34 @@ public function testTabsWidgetSelector() {
     // This is producing an error. Still investigating
     // InvalidStateError: DOM Exception 11: An attempt was made to use an object
     // that is not, or is no longer, usable.
-    //$edit = [
-    //  'files[upload][]' => $this->container->get('file_system')->realpath($image2->getFileUri()),
-    //];
+    // $uri = $this->container
+    // ->get('file_system')
+    // ->realpath($image2->getFileUri());
+    // $edit = [
+    // 'files[upload][]' => $uri,
+    // ];
     // $this->drupalPostForm(NULL, $edit, 'Select files');.
+    \Drupal::state()->set('eb_test_dummy_widget_access', FALSE);
+    $this->drupalGet('entity-browser/iframe/test_entity_browser_file');
+    $this->assertSession()->linkNotExists('dummy');
+    $this->assertSession()->linkExists('view');
+    $this->assertSession()->linkExists('upload');
+
+    // Commenting out header checks for now:
+    // Behat\Mink\Exception\UnsupportedDriverActionException: Response headers are not available
+    // from Drupal\FunctionalJavascriptTests\DrupalSelenium2Driver
+    // $this->assertHeader('X-Drupal-Cache-Contexts', 'eb_dummy');
+    // Move dummy widget to the first place and make sure it does not appear.
+    $browser = $this->container->get('entity_type.manager')
+      ->getStorage('entity_browser')
+      ->load('test_entity_browser_file');
+    $browser->getWidget('cbc59500-04ab-4395-b063-c561f0e3bf80')->setWeight(-15);
+    $browser->save();
+    $this->drupalGet('entity-browser/iframe/test_entity_browser_file');
+    $this->assertSession()->linkNotExists('dummy');
+    $this->assertSession()->linkExists('view');
+    $this->assertSession()->linkExists('upload');
+    $this->assertSession()->pageTextNotContains('This is dummy widget.');
   }
 
   /**
@@ -130,6 +225,12 @@ public function testDropdownWidgetSelector() {
     $this->getSession()->switchToIFrame('entity_browser_iframe_test_entity_browser_file');
 
     $this->assertSession()->selectExists('widget');
+    // Dummy.
+    $this->assertSession()->optionExists('widget', 'cbc59500-04ab-4395-b063-c561f0e3bf80');
+    // Upload.
+    $this->assertSession()->optionExists('widget', '2dc1ab07-2f8f-42c9-aab7-7eef7f8b7d87');
+    // View.
+    $this->assertSession()->optionExists('widget', '774798f1-5ec5-4b63-84bd-124cd51ec07d');
     // Selects the view widget.
     $this->getSession()->getPage()->selectFieldOption('widget', '774798f1-5ec5-4b63-84bd-124cd51ec07d');
 
@@ -147,11 +248,35 @@ public function testDropdownWidgetSelector() {
 
     // Causes a fatal.
     // Selects the upload widget.
-    // $this->getSession()->getPage()->selectFieldOption('widget', '2dc1ab07-2f8f-42c9-aab7-7eef7f8b7d87');.
+    // $this->getSession()
+    // ->getPage()
+    // ->selectFieldOption('widget', '2dc1ab07-2f8f-42c9-aab7-7eef7f8b7d87');.
+    \Drupal::state()->set('eb_test_dummy_widget_access', FALSE);
+    $this->drupalGet('entity-browser/iframe/test_entity_browser_file');
+    // Dummy.
+    $this->assertSession()->optionNotExists('widget', 'cbc59500-04ab-4395-b063-c561f0e3bf80');
+    // Upload.
+    $this->assertSession()->optionExists('widget', '2dc1ab07-2f8f-42c9-aab7-7eef7f8b7d87');
+    // View.
+    $this->assertSession()->optionExists('widget', '774798f1-5ec5-4b63-84bd-124cd51ec07d');
+    // Move dummy widget to the first place and make sure it does not appear.
+    $browser = $this->container->get('entity_type.manager')
+      ->getStorage('entity_browser')
+      ->load('test_entity_browser_file');
+    $browser->getWidget('cbc59500-04ab-4395-b063-c561f0e3bf80')->setWeight(-15);
+    $browser->save();
+    $this->drupalGet('entity-browser/iframe/test_entity_browser_file');
+    // Dummy.
+    $this->assertSession()->optionNotExists('widget', 'cbc59500-04ab-4395-b063-c561f0e3bf80');
+    // Upload.
+    $this->assertSession()->optionExists('widget', '2dc1ab07-2f8f-42c9-aab7-7eef7f8b7d87');
+    // View.
+    $this->assertSession()->optionExists('widget', '774798f1-5ec5-4b63-84bd-124cd51ec07d');
+    $this->assertSession()->pageTextNotContains('This is dummy widget.');
   }
 
   /**
-   * Tests wievs selection display.
+   * Tests views selection display.
    */
   public function testViewsSelectionDisplayWidget() {
 
@@ -210,4 +335,301 @@ public function testNoDisplaySelectionDisplay() {
     $this->assertSession()->buttonNotExists('Second submit button');
   }
 
+  /**
+   * Tests the EntityBrowserWidgetContext default argument plugin.
+   */
+  public function testEntityBrowserWidgetContext() {
+    $this->createNode(['type' => 'shark', 'title' => 'Luke']);
+    $this->createNode(['type' => 'jet', 'title' => 'Leia']);
+    $this->createNode(['type' => 'article', 'title' => 'Darth']);
+
+    /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
+    $form_display = $this->container->get('entity_type.manager')
+      ->getStorage('entity_form_display')
+      ->load('node.article.default');
+
+    $form_display->setComponent('field_reference', [
+      'type' => 'entity_browser_entity_reference',
+      'settings' => [
+        'entity_browser' => 'widget_context_default_value',
+        'field_widget_display' => 'label',
+        'open' => TRUE,
+      ],
+    ])->save();
+
+    /** @var \Drupal\Core\Field\FieldConfigInterface $field_config */
+    $field_config = $this->container->get('entity_type.manager')
+      ->getStorage('field_config')
+      ->load('node.article.field_reference');
+    $handler_settings = $field_config->getSetting('handler_settings');
+    $handler_settings['target_bundles'] = [
+      'shark' => 'shark',
+      'jet' => 'jet',
+    ];
+    $field_config->setSetting('handler_settings', $handler_settings);
+    $field_config->save();
+
+    // Set auto open to false on the entity browser.
+    $entity_browser = $this->container->get('entity_type.manager')
+      ->getStorage('entity_browser')
+      ->load('widget_context_default_value');
+
+    $display_configuration = $entity_browser->get('display_configuration');
+    $display_configuration['auto_open'] = FALSE;
+    $entity_browser->set('display_configuration', $display_configuration);
+    $entity_browser->save();
+
+    $account = $this->drupalCreateUser([
+      'access widget_context_default_value entity browser pages',
+      'create article content',
+      'access content',
+    ]);
+    $this->drupalLogin($account);
+
+    $this->drupalGet('node/add/article');
+
+    // Open the entity browser widget form.
+    $this->getSession()->getPage()->clickLink('Select entities');
+    $this->getSession()->switchToIFrame('entity_browser_iframe_widget_context_default_value');
+
+    // Check that only nodes of an allowed type are listed.
+    $this->assertSession()->pageTextContains('Luke');
+    $this->assertSession()->pageTextContains('Leia');
+    $this->assertSession()->pageTextNotContains('Darth');
+
+    /** @var \Drupal\Core\Field\FieldConfigInterface $field_config */
+    $field_config = $this->container->get('entity_type.manager')
+      ->getStorage('field_config')
+      ->load('node.article.field_reference');
+    $handler_settings = $field_config->getSetting('handler_settings');
+    $handler_settings['target_bundles'] = [
+      'article' => 'article',
+    ];
+    $field_config->setSetting('handler_settings', $handler_settings);
+    $field_config->save();
+
+    $this->drupalGet('node/add/article');
+
+    // Open the entity browser widget form.
+    $this->getSession()->getPage()->clickLink('Select entities');
+    $this->waitForAjaxToFinish();
+    $this->getSession()->switchToIFrame('entity_browser_iframe_widget_context_default_value');
+
+    // Check that only nodes of an allowed type are listed.
+    $this->assertSession()->pageTextNotContains('Luke');
+    $this->assertSession()->pageTextNotContains('Leia');
+    $this->assertSession()->pageTextContains('Darth');
+
+  }
+
+  /**
+   * Tests the ContextualBundle filter plugin.
+   */
+  public function testContextualBundle() {
+
+    $this->createNode(['type' => 'shark', 'title' => 'Luke']);
+    $this->createNode(['type' => 'jet', 'title' => 'Leia']);
+    $this->createNode(['type' => 'article', 'title' => 'Darth']);
+
+    /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
+    $form_display = $this->container->get('entity_type.manager')
+      ->getStorage('entity_form_display')
+      ->load('node.article.default');
+
+    $form_display->setComponent('field_reference', [
+      'type' => 'entity_browser_entity_reference',
+      'settings' => [
+        'entity_browser' => 'bundle_filter',
+        'field_widget_display' => 'label',
+        'open' => TRUE,
+      ],
+    ])->save();
+
+    /** @var \Drupal\Core\Field\FieldConfigInterface $field_config */
+    $field_config = $this->container->get('entity_type.manager')
+      ->getStorage('field_config')
+      ->load('node.article.field_reference');
+    $handler_settings = $field_config->getSetting('handler_settings');
+    $handler_settings['target_bundles'] = [
+      'shark' => 'shark',
+      'jet' => 'jet',
+    ];
+    $field_config->setSetting('handler_settings', $handler_settings);
+    $field_config->save();
+
+    // Set auto open to false on the entity browser.
+    $entity_browser = $this->container->get('entity_type.manager')
+      ->getStorage('entity_browser')
+      ->load('bundle_filter');
+
+    $display_configuration = $entity_browser->get('display_configuration');
+    $display_configuration['auto_open'] = FALSE;
+    $entity_browser->set('display_configuration', $display_configuration);
+    $entity_browser->save();
+
+    $account = $this->drupalCreateUser([
+      'access bundle_filter entity browser pages',
+      'create article content',
+      'access content',
+    ]);
+    $this->drupalLogin($account);
+
+    $this->drupalGet('node/add/article');
+
+    // Open the entity browser widget form.
+    $this->getSession()->getPage()->clickLink('Select entities');
+    $this->getSession()->switchToIFrame('entity_browser_iframe_bundle_filter');
+
+    // Check that only nodes of an allowed type are listed.
+    $this->assertSession()->pageTextContains('Luke');
+    $this->assertSession()->pageTextContains('Leia');
+    $this->assertSession()->pageTextNotContains('Darth');
+
+    /** @var \Drupal\Core\Field\FieldConfigInterface $field_config */
+    $field_config = $this->container->get('entity_type.manager')
+      ->getStorage('field_config')
+      ->load('node.article.field_reference');
+    $handler_settings = $field_config->getSetting('handler_settings');
+    $handler_settings['target_bundles'] = [
+      'article' => 'article',
+    ];
+    $field_config->setSetting('handler_settings', $handler_settings);
+    $field_config->save();
+
+    $this->drupalGet('node/add/article');
+
+    // Open the entity browser widget form.
+    $this->getSession()->getPage()->clickLink('Select entities');
+    $this->getSession()->switchToIFrame('entity_browser_iframe_bundle_filter');
+
+    // Check that only nodes of an allowed type are listed.
+    $this->assertSession()->pageTextNotContains('Luke');
+    $this->assertSession()->pageTextNotContains('Leia');
+    $this->assertSession()->pageTextContains('Darth');
+
+  }
+
+  /**
+   * Tests the ContextualBundle filter plugin with exposed option.
+   */
+  public function testContextualBundleExposed() {
+
+    $this->config('entity_browser.browser.bundle_filter')
+      ->set('widgets.b882a89d-9ce4-4dfe-9802-62df93af232a.settings.view', 'bundle_filter_exposed')
+      ->save();
+
+    $this->createNode(['type' => 'shark', 'title' => 'Luke']);
+    $this->createNode(['type' => 'jet', 'title' => 'Leia']);
+    $this->createNode(['type' => 'article', 'title' => 'Darth']);
+
+    /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
+    $form_display = $this->container->get('entity_type.manager')
+      ->getStorage('entity_form_display')
+      ->load('node.article.default');
+
+    $form_display->setComponent('field_reference', [
+      'type' => 'entity_browser_entity_reference',
+      'settings' => [
+        'entity_browser' => 'bundle_filter',
+        'field_widget_display' => 'label',
+        'open' => TRUE,
+      ],
+    ])->save();
+
+    /** @var \Drupal\Core\Field\FieldConfigInterface $field_config */
+    $field_config = $this->container->get('entity_type.manager')
+      ->getStorage('field_config')
+      ->load('node.article.field_reference');
+    $handler_settings = $field_config->getSetting('handler_settings');
+    $handler_settings['target_bundles'] = [
+      'shark' => 'shark',
+      'jet' => 'jet',
+    ];
+    $field_config->setSetting('handler_settings', $handler_settings);
+    $field_config->save();
+
+    // Set auto open to false on the entity browser.
+    $entity_browser = $this->container->get('entity_type.manager')
+      ->getStorage('entity_browser')
+      ->load('bundle_filter');
+
+    $display_configuration = $entity_browser->get('display_configuration');
+    $display_configuration['auto_open'] = FALSE;
+    $entity_browser->set('display_configuration', $display_configuration);
+    $entity_browser->save();
+
+    $account = $this->drupalCreateUser([
+      'access bundle_filter entity browser pages',
+      'create article content',
+      'access content',
+    ]);
+    $this->drupalLogin($account);
+
+    $this->drupalGet('node/add/article');
+
+    // Open the entity browser widget form.
+    $this->getSession()->getPage()->clickLink('Select entities');
+    $this->getSession()->switchToIFrame('entity_browser_iframe_bundle_filter');
+
+    // Check that only nodes of an allowed type are listed.
+    $this->assertSession()->pageTextContains('Luke');
+    $this->assertSession()->pageTextContains('Leia');
+    $this->assertSession()->pageTextNotContains('Darth');
+
+    // Test exposed form type filter.
+    $this->assertSession()->selectExists('Type')->selectOption('jet');
+    $this->assertSession()->buttonExists('Apply')->press();
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    // Check that only nodes of the type selected in the exposed filter display.
+    $this->assertSession()->pageTextNotContains('Luke');
+    $this->assertSession()->pageTextContains('Leia');
+    $this->assertSession()->pageTextNotContains('Darth');
+
+    $this->assertSession()->selectExists('Type')->selectOption('shark');
+    $this->assertSession()->buttonExists('Apply')->press();
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    // Check that only nodes of the type selected in the exposed filter display.
+    $this->assertSession()->pageTextContains('Luke');
+    $this->assertSession()->pageTextNotContains('Leia');
+    $this->assertSession()->pageTextNotContains('Darth');
+
+    $this->assertSession()->selectExists('Type')->selectOption('All');
+    $this->assertSession()->buttonExists('Apply')->press();
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    // Check that only nodes of the type selected in the exposed filter display.
+    $this->assertSession()->pageTextContains('Luke');
+    $this->assertSession()->pageTextContains('Leia');
+    $this->assertSession()->pageTextNotContains('Darth');
+
+    /** @var \Drupal\Core\Field\FieldConfigInterface $field_config */
+    $field_config = $this->container->get('entity_type.manager')
+      ->getStorage('field_config')
+      ->load('node.article.field_reference');
+    $handler_settings = $field_config->getSetting('handler_settings');
+    $handler_settings['target_bundles'] = [
+      'article' => 'article',
+    ];
+    $field_config->setSetting('handler_settings', $handler_settings);
+    $field_config->save();
+
+    $this->drupalGet('node/add/article');
+
+    // Open the entity browser widget form.
+    $this->getSession()->getPage()->clickLink('Select entities');
+    $this->getSession()->switchToIFrame('entity_browser_iframe_bundle_filter');
+
+    // Check that only nodes of an allowed type are listed.
+    $this->assertSession()->pageTextNotContains('Luke');
+    $this->assertSession()->pageTextNotContains('Leia');
+    $this->assertSession()->pageTextContains('Darth');
+
+    // If there is just one target_bundle, the contextual filter
+    // should not be visible.
+    $this->assertSession()->fieldNotExists('Type');
+
+  }
+
 }
diff --git a/web/modules/entity_browser/tests/src/FunctionalJavascript/EntityBrowserViewsWidgetTest.php b/web/modules/entity_browser/tests/src/FunctionalJavascript/EntityBrowserViewsWidgetTest.php
index f6e8d6d31c996d4b87a168d3deb7b0bcee4300a7..23f2297e630a1f04174118241e39ea60c2fcf776 100644
--- a/web/modules/entity_browser/tests/src/FunctionalJavascript/EntityBrowserViewsWidgetTest.php
+++ b/web/modules/entity_browser/tests/src/FunctionalJavascript/EntityBrowserViewsWidgetTest.php
@@ -3,6 +3,10 @@
 namespace Drupal\Tests\entity_browser\FunctionalJavascript;
 
 use Drupal\file\Entity\File;
+use Drupal\Core\Field\FieldStorageDefinitionInterface;
+use Drupal\entity_browser\Element\EntityBrowserElement;
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\Entity\FieldStorageConfig;
 
 /**
  * Entity Browser views widget tests.
@@ -10,7 +14,7 @@
  * @group entity_browser
  * @see \Drupal\entity_browser\Plugin\EntityBrowser\Widget\View
  */
-class EntityBrowserViewsWidgetTest extends EntityBrowserJavascriptTestBase {
+class EntityBrowserViewsWidgetTest extends EntityBrowserWebDriverTestBase {
 
   /**
    * Modules to enable.
@@ -31,6 +35,8 @@ protected function setUp() {
 
     $user = $this->drupalCreateUser([
       'access test_entity_browser_file entity browser pages',
+      'access test_double_underscore entity browser pages',
+      'bypass node access',
     ]);
     $this->drupalLogin($user);
   }
@@ -40,7 +46,7 @@ protected function setUp() {
    */
   public function testViewsWidget() {
     // Create a file so that our test View isn't empty.
-    file_unmanaged_copy(\Drupal::root() . '/core/misc/druplicon.png', 'public://example.jpg');
+    \Drupal::service('file_system')->copy(\Drupal::root() . '/core/misc/druplicon.png', 'public://example.jpg');
     /** @var \Drupal\file\FileInterface $file */
     $file = File::create([
       'uri' => 'public://example.jpg',
@@ -63,16 +69,25 @@ public function testViewsWidget() {
     $this->getSession()->getPage()->pressButton('Apply');
     $this->waitForAjaxToFinish();
     $this->assertSession()->pageTextContains('example.jpg');
-    $this->assertSession()->fieldExists($field);
-
-    // Test selection.
-    $this->submitForm([
-      $field => 1,
-    ], t('Select entities'));
-    $this->assertSession()->pageTextContains($file->getFilename());
+    $this->assertSession()->fieldExists($field)->check();
+    $this->assertSession()->buttonExists('Select entities')->press();
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->assertSession()->responseNotContains('HTTP/1.0 200 OK');
+    $this->assertSession()->responseNotContains('Cache-Control: no-cache, private');
+    // Test that the response contains the selected entity.
+    $script = "return drupalSettings.entity_browser.iframe.entities[0];";
+    $result = $this->getSession()
+      ->getDriver()
+      ->getWebDriverSession()
+      ->execute([
+        'script' => $script,
+        'args' => [],
+      ]);
+    $this->assertEquals($file->id(), $result[0]);
+    $this->assertEquals('file', $result[2]);
 
     // Create another file to test bulk select form.
-    file_unmanaged_copy(\Drupal::root() . '/core/misc/druplicon.png', 'public://example_1.jpg');
+    \Drupal::service('file_system')->copy(\Drupal::root() . '/core/misc/druplicon.png', 'public://example_1.jpg');
     /** @var \Drupal\file\FileInterface $file */
     $new_file = File::create([
       'uri' => 'public://example_1.jpg',
@@ -86,6 +101,93 @@ public function testViewsWidget() {
     $check_new = $this->assertSession()->fieldExists($new_field);
     // Compare value attributes of checkboxes and assert they not equal.
     $this->assertNotEquals($check_old->getAttribute('value'), $check_new->getAttribute('value'));
+
+    $uuid = \Drupal::service('uuid')->generate();
+    \Drupal::service('entity_browser.selection_storage')->setWithExpire(
+      $uuid,
+      ['validators' => ['cardinality' => ['cardinality' => 1]]],
+      21600
+    );
+    $this->drupalGet('/entity-browser/iframe/test_entity_browser_file', ['query' => ['uuid' => $uuid]]);
+    $this->getSession()->getPage()->fillField('entity_browser_select[file:1]', TRUE);
+    $this->getSession()->getPage()->fillField('entity_browser_select[file:2]', TRUE);
+    $this->getSession()->getPage()->pressButton('Select entities');
+
+    $this->assertSession()->pageTextContains('You can only select one item.');
+    $this->assertSession()->checkboxNotChecked('entity_browser_select[file:1]');
+    $this->assertSession()->checkboxNotChecked('entity_browser_select[file:2]');
+
+    // Test entity_browser.view.js adding AJAX to exposed forms.
+    $field_storage = FieldStorageConfig::create([
+      'field_name' => 'field_alderaan',
+      'type' => 'entity_reference',
+      'entity_type' => 'node',
+      'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
+      'settings' => [
+        'target_type' => 'node',
+      ],
+    ]);
+    $field_storage->save();
+
+    $field = FieldConfig::create([
+      'field_name' => 'field_alderaan',
+      'entity_type' => 'node',
+      'bundle' => 'article',
+      'label' => 'Referenced articles',
+      'settings' => [],
+    ]);
+    $field->save();
+
+    /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
+    $form_display = $this->container->get('entity_type.manager')
+      ->getStorage('entity_form_display')
+      ->load('node.article.default');
+
+    $form_display->setComponent('field_alderaan', [
+      'type' => 'entity_browser_entity_reference',
+      'settings' => [
+        'entity_browser' => 'test_double_underscore',
+        'open' => TRUE,
+        'field_widget_edit' => TRUE,
+        'field_widget_remove' => TRUE,
+        'field_widget_replace' => FALSE,
+        'selection_mode' => EntityBrowserElement::SELECTION_MODE_APPEND,
+        'field_widget_display' => 'label',
+        'field_widget_display_settings' => [],
+      ],
+    ])->save();
+
+    $nodes = [
+      'Happy families are all alike',
+      'Call me Ishmael',
+    ];
+
+    foreach ($nodes as $title) {
+      $this->createNode([
+        'title' => $title,
+        'type' => 'article',
+      ]);
+    }
+
+    $this->drupalGet('/node/add/article');
+    $this->assertSession()->waitForElementVisible('css', '#entity-browser-test-double-underscore-form');
+
+    $this->getSession()->switchToIFrame('entity_browser_iframe_test_double_underscore');
+    foreach ($nodes as $title) {
+      $this->assertSession()->pageTextContains($title);
+    }
+
+    $this->assertSession()->fieldExists('title')->setValue('Ishmael');
+    $this->assertSession()->buttonExists('Apply')->press();
+    $this->waitForAjaxToFinish();
+    $this->assertSession()->pageTextContains('Call me Ishmael');
+    $this->assertSession()->pageTextNotContains('Happy families are all alike');
+    $this->assertSession()->fieldExists('title')->setValue('families');
+    $this->assertSession()->buttonExists('Apply')->press();
+    $this->waitForAjaxToFinish();
+    $this->assertSession()->pageTextNotContains('Call me Ishmael');
+    $this->assertSession()->pageTextContains('Happy families are all alike');
+
   }
 
 }
diff --git a/web/modules/entity_browser/tests/src/FunctionalJavascript/EntityBrowserWebDriverTestBase.php b/web/modules/entity_browser/tests/src/FunctionalJavascript/EntityBrowserWebDriverTestBase.php
new file mode 100644
index 0000000000000000000000000000000000000000..bd40f3e6f3b6ef8cd691f88b2a9bc12f91d9c374
--- /dev/null
+++ b/web/modules/entity_browser/tests/src/FunctionalJavascript/EntityBrowserWebDriverTestBase.php
@@ -0,0 +1,304 @@
+<?php
+
+namespace Drupal\Tests\entity_browser\FunctionalJavascript;
+
+use Drupal\Component\Utility\NestedArray;
+use Drupal\Core\Field\FieldStorageDefinitionInterface;
+use Drupal\file\Entity\File;
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\Entity\FieldStorageConfig;
+use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
+use Behat\Mink\Element\NodeElement;
+use Drupal\language\Entity\ConfigurableLanguage;
+
+/**
+ * Base class for Entity browser Javascript functional tests.
+ *
+ * @package Drupal\Tests\entity_browser\FunctionalJavascript
+ */
+abstract class EntityBrowserWebDriverTestBase extends WebDriverTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'stark';
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = [
+    'entity_browser_test',
+    'contextual',
+    'views',
+    'block',
+    'node',
+    'file',
+    'image',
+    'field_ui',
+    'views_ui',
+    'system',
+    'language',
+  ];
+
+  /**
+   * Permissions for user that will be logged-in for test.
+   *
+   * @var array
+   */
+  protected static $userPermissions = [
+    'access test_entity_browser_file entity browser pages',
+    'create article content',
+    'access content',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    FieldStorageConfig::create([
+      'field_name' => 'field_reference',
+      'type' => 'entity_reference',
+      'entity_type' => 'node',
+      'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
+      'settings' => [
+        'target_type' => 'file',
+      ],
+    ])->save();
+
+    FieldConfig::create([
+      'field_name' => 'field_reference',
+      'entity_type' => 'node',
+      'bundle' => 'article',
+      'label' => 'Reference',
+      'settings' => [],
+    ])->save();
+
+    /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
+    $form_display = $this->container->get('entity_type.manager')
+      ->getStorage('entity_form_display')
+      ->load('node.article.default');
+
+    $form_display->setComponent('field_reference', [
+      'type' => 'entity_browser_entity_reference',
+      'settings' => [
+        'entity_browser' => 'test_entity_browser_file',
+        'field_widget_display' => 'label',
+        'open' => TRUE,
+      ],
+    ])->save();
+
+    ConfigurableLanguage::createFromLangcode('fr')->save();
+
+    $account = $this->drupalCreateUser(static::$userPermissions);
+    $this->drupalLogin($account);
+  }
+
+  /**
+   * Return an entity browser if it exists or creates a new one.
+   *
+   * @param string $browser_name
+   *   The entity browser name.
+   * @param string $display_id
+   *   The display plugin id.
+   * @param string $widget_selector_id
+   *   The widget selector id.
+   * @param string $selection_display_id
+   *   The selection display id.
+   * @param array $display_configuration
+   *   The display plugin configuration.
+   * @param array $widget_selector_configuration
+   *   The widget selector configuration.
+   * @param array $selection_display_configuration
+   *   The selection display configuration.
+   * @param array $widget_configurations
+   *   Widget configurations. Have be provided with widget UUIDs.
+   *
+   * @return \Drupal\entity_browser\EntityBrowserInterface
+   *   Returns an Entity Browser.
+   */
+  protected function getEntityBrowser($browser_name, $display_id, $widget_selector_id, $selection_display_id, array $display_configuration = [], array $widget_selector_configuration = [], array $selection_display_configuration = [], array $widget_configurations = []) {
+    /** @var \Drupal\Core\Entity\EntityStorageInterface $storage */
+    $storage = $this->container->get('entity_type.manager')
+      ->getStorage('entity_browser');
+
+    /** @var \Drupal\entity_browser\EntityBrowserInterface $browser */
+    $browser = $storage->load($browser_name) ?: $storage->create(['name' => $browser_name]);
+
+    $browser->setDisplay($display_id);
+    if ($display_configuration) {
+      $browser->getDisplay()->setConfiguration($display_configuration);
+    }
+
+    $browser->setWidgetSelector($widget_selector_id);
+    if ($widget_selector_configuration) {
+      $browser->getSelectionDisplay()
+        ->setConfiguration($widget_selector_configuration);
+    }
+
+    $browser->setSelectionDisplay($selection_display_id);
+    if ($selection_display_configuration) {
+      $browser->getSelectionDisplay()
+        ->setConfiguration($selection_display_configuration);
+    }
+
+    // Apply custom widget configurations.
+    if ($widget_configurations) {
+      foreach ($widget_configurations as $widget_uuid => $widget_config) {
+        $view_widget = $browser->getWidget($widget_uuid);
+        $view_widget->setConfiguration(NestedArray::mergeDeep($view_widget->getConfiguration(), $widget_config));
+      }
+    }
+
+    $browser->save();
+
+    // Clear caches after new browser is saved to remove old cached states.
+    drupal_flush_all_caches();
+
+    return $browser;
+  }
+
+  /**
+   * Creates an image.
+   *
+   * @param string $name
+   *   The name of the image.
+   * @param string $extension
+   *   File extension.
+   *
+   * @return \Drupal\file\FileInterface
+   *   Returns an image.
+   */
+  protected function createFile($name, $extension = 'jpg') {
+    file_put_contents('public://' . $name . '.' . $extension, $this->randomMachineName());
+
+    $image = File::create([
+      'filename' => $name . '.' . $extension,
+      'uri' => 'public://' . $name . '.' . $extension,
+    ]);
+    $image->setPermanent();
+    $image->save();
+
+    return $image;
+  }
+
+  /**
+   * Waits for jQuery to become ready and animations to complete.
+   */
+  protected function waitForAjaxToFinish() {
+    $this->assertSession()->assertWaitOnAjaxRequest();
+  }
+
+  /**
+   * Drag element in document with defined offset position.
+   *
+   * @param \Behat\Mink\Element\NodeElement $element
+   *   Element that will be dragged.
+   * @param int $offsetX
+   *   Vertical offset for element drag in pixels.
+   * @param int $offsetY
+   *   Horizontal offset for element drag in pixels.
+   */
+  protected function dragDropElement(NodeElement $element, $offsetX, $offsetY) {
+
+    $elemXpath = $element->getXpath();
+
+    $jsCode = "var fireMouseEvent = function (type, element, x, y) {
+      var event = document.createEvent('MouseEvents');
+      event.initMouseEvent(type, true, (type !== 'mousemove'), window, 0, 0, 0, x, y, false, false, false, false, 0, element);
+      element.dispatchEvent(event); };";
+
+    // XPath provided by getXpath uses single quote (') to encapsulate strings,
+    // that's why xpath has to be quited with double quites in javascript code.
+    $jsCode .= "(function() {
+      var dragElement = document.evaluate(\"{$elemXpath}\", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
+      var pos = dragElement.getBoundingClientRect();
+      var centerX = Math.floor((pos.left + pos.right) / 2);
+      var centerY = Math.floor((pos.top + pos.bottom) / 2);
+      fireMouseEvent('mousedown', dragElement, centerX, centerY);
+      var xOffset = {$offsetX};
+      var yOffset = {$offsetY};
+      var moves = 3;
+	    for (i = 0 ; i < moves ; i++ ) {
+			  centerX += xOffset / moves;
+			  centerY += yOffset / moves;
+		    fireMouseEvent('mousemove', dragElement, Math.round(centerX), Math.round(centerY));
+		  }
+      fireMouseEvent('mouseup', dragElement, centerX, centerY);
+    })();";
+
+    $this->getSession()->executeScript($jsCode);
+  }
+
+  /**
+   * Checks that a specific radio input element exists on the current page.
+   *
+   * @param string $value
+   *   The string value of the radio element.
+   *
+   * @return \Behat\Mink\Element\NodeElement
+   *   The radio input form element.
+   *
+   * @throws \Behat\Mink\Exception\ElementNotFoundException
+   */
+  protected function assertRadioExistsByValue($value) {
+    $value = (string) $value;
+    return $this->assertSession()
+      ->elementExists('xpath', "//input[contains(@type, 'radio') and contains(@value, '" . $value . "')]");
+  }
+
+  /**
+   * Checks that a specific radio input element does not exist on the current page.
+   *
+   * @param string $value
+   *   The string value of the radio element.
+   *
+   * @return \Behat\Mink\Element\NodeElement
+   *   The radio input form element.
+   *
+   * @throws \Behat\Mink\Exception\ElementNotFoundException
+   */
+  protected function assertRadioNotExistsByValue($value) {
+    $value = (string) $value;
+    return $this->assertSession()
+      ->elementNotExists('xpath', "//input[contains(@type, 'radio') and contains(@value, '" . $value . "')]");
+  }
+
+  /**
+   * Checks that a specific checkbox input element exists on the current page.
+   *
+   * @param string $value
+   *   The string value of the radio element.
+   *
+   * @return \Behat\Mink\Element\NodeElement
+   *   The radio input form element.
+   *
+   * @throws \Behat\Mink\Exception\ElementNotFoundException
+   */
+  protected function assertCheckboxExistsByValue($value) {
+    $value = (string) $value;
+    return $this->assertSession()
+      ->elementExists('xpath', "//input[contains(@type, 'checkbox') and contains(@value, '" . $value . "')]");
+  }
+
+  /**
+   * Checks that a specific checkbox input element does not exist on the current page.
+   *
+   * @param string $value
+   *   The string value of the radio element.
+   *
+   * @return \Behat\Mink\Element\NodeElement
+   *   The radio input form element.
+   *
+   * @throws \Behat\Mink\Exception\ElementNotFoundException
+   */
+  protected function assertCheckboxNotExistsByValue($value) {
+    $value = (string) $value;
+    return $this->assertSession()
+      ->elementNotExists('xpath', "//input[contains(@type, 'checkbox') and contains(@value, '" . $value . "')]");
+  }
+
+}
diff --git a/web/modules/entity_browser/tests/src/FunctionalJavascript/EntityEmbedTest.php b/web/modules/entity_browser/tests/src/FunctionalJavascript/EntityEmbedTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..5bdbb4087571307bcbe2fab445c89cf8bf149f42
--- /dev/null
+++ b/web/modules/entity_browser/tests/src/FunctionalJavascript/EntityEmbedTest.php
@@ -0,0 +1,233 @@
+<?php
+
+namespace Drupal\Tests\entity_browser\FunctionalJavascript;
+
+use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
+
+/**
+ * Tests entity browser within entity embed.
+ *
+ * @group entity_browser
+ *
+ * @package Drupal\Tests\entity_browser\FunctionalJavascript
+ */
+class EntityEmbedTest extends WebDriverTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  protected static $modules = [
+    'entity_browser',
+    'entity_browser_test',
+    'embed',
+    'entity_embed',
+    'entity_browser_entity_embed_test',
+  ];
+
+  /**
+   * The test administrative user.
+   *
+   * @var \Drupal\user\UserInterface
+   */
+  protected $adminUser;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'stark';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->adminUser = $this->drupalCreateUser([
+      'access content',
+      'use text format full_html',
+      'create test_entity_embed content',
+      'access widget_context_default_value entity browser pages',
+      'access bundle_filter entity browser pages',
+    ]);
+  }
+
+  /**
+   * Tests the EntityBrowserWidgetContext default argument plugin.
+   */
+  public function testEntityBrowserWidgetContext() {
+
+    $this->drupalLogin($this->adminUser);
+
+    $this->createNode(['type' => 'shark', 'title' => 'Luke']);
+    $this->createNode(['type' => 'jet', 'title' => 'Leia']);
+    $this->createNode(['type' => 'article', 'title' => 'Darth']);
+
+    $this->drupalGet('/node/add/test_entity_embed');
+    $this->assertSession()->waitForElement('css', 'a.cke_button__jet_shark_embed')->click();
+    $this->assertSession()->waitForId('views-exposed-form-widget-context-default-value-entity-browser-1');
+
+    $this->getSession()->switchToIFrame('entity_browser_iframe_widget_context_default_value');
+
+    // Check that only nodes of an allowed type are listed.
+    $this->assertSession()->responseContains('Luke');
+    $this->assertSession()->responseContains('Leia');
+    $this->assertSession()->responseNotContains('Darth');
+
+    // Change the allowed bundles on the entity embed.
+    $embed_button = $this->container->get('entity_type.manager')
+      ->getStorage('embed_button')
+      ->load('jet_shark_embed');
+    $type_settings = $embed_button->getTypeSettings();
+    $type_settings['bundles'] = [
+      'article' => 'article',
+    ];
+    $embed_button->set('type_settings', $type_settings);
+    $embed_button->save();
+
+    // Test the new bundle settings are affecting what is visible in the view.
+    $this->drupalGet('/node/add/test_entity_embed');
+    $this->assertSession()->waitForElement('css', 'a.cke_button__jet_shark_embed')->click();
+    $this->assertSession()->waitForId('views-exposed-form-widget-context-default-value-entity-browser-1');
+
+    $this->getSession()->switchToIFrame('entity_browser_iframe_widget_context_default_value');
+
+    // Check that only nodes of an allowed type are listed.
+    $this->assertSession()->responseNotContains('Luke');
+    $this->assertSession()->responseNotContains('Leia');
+    $this->assertSession()->responseContains('Darth');
+
+  }
+
+  /**
+   * Tests the ContextualBundle filter plugin.
+   */
+  public function testContextualBundle() {
+
+    $this->drupalLogin($this->adminUser);
+
+    $this->createNode(['type' => 'shark', 'title' => 'Luke']);
+    $this->createNode(['type' => 'jet', 'title' => 'Leia']);
+    $this->createNode(['type' => 'article', 'title' => 'Darth']);
+
+    $this->drupalGet('/node/add/test_entity_embed');
+    $this->assertSession()->waitForElement('css', 'a.cke_button__bundle_filter_test')->click();
+    $this->assertSession()->waitForId('views-exposed-form-bundle-filter-entity-browser-1');
+
+    $this->getSession()->switchToIFrame('entity_browser_iframe_bundle_filter');
+
+    // Check that only nodes of an allowed type are listed.
+    $this->assertSession()->responseContains('Luke');
+    $this->assertSession()->responseContains('Leia');
+    $this->assertSession()->responseNotContains('Darth');
+
+    // Change the allowed bundles on the entity embed.
+    $embed_button = $this->container->get('entity_type.manager')
+      ->getStorage('embed_button')
+      ->load('bundle_filter_test');
+    $type_settings = $embed_button->getTypeSettings();
+    $type_settings['bundles'] = [
+      'article' => 'article',
+    ];
+    $embed_button->set('type_settings', $type_settings);
+    $embed_button->save();
+
+    // Test the new bundle settings are affecting what is visible in the view.
+    $this->drupalGet('/node/add/test_entity_embed');
+    $this->assertSession()->waitForElement('css', 'a.cke_button__bundle_filter_test')->click();
+    $this->assertSession()->waitForId('views-exposed-form-bundle-filter-entity-browser-1');
+
+    $this->getSession()->switchToIFrame('entity_browser_iframe_bundle_filter');
+
+    // Check that only nodes of an allowed type are listed.
+    $this->assertSession()->responseNotContains('Luke');
+    $this->assertSession()->responseNotContains('Leia');
+    $this->assertSession()->responseContains('Darth');
+
+  }
+
+  /**
+   * Tests the ContextualBundle filter plugin with exposed option.
+   */
+  public function testContextualBundleExposed() {
+
+    $this->config('entity_browser.browser.bundle_filter')
+      ->set('widgets.b882a89d-9ce4-4dfe-9802-62df93af232a.settings.view', 'bundle_filter_exposed')
+      ->save();
+
+    $this->drupalLogin($this->adminUser);
+
+    $this->createNode(['type' => 'shark', 'title' => 'Luke']);
+    $this->createNode(['type' => 'jet', 'title' => 'Leia']);
+    $this->createNode(['type' => 'article', 'title' => 'Darth']);
+
+    $this->drupalGet('/node/add/test_entity_embed');
+    $this->assertSession()->waitForElement('css', 'a.cke_button__bundle_filter_test')->click();
+    $this->assertSession()->waitForId('views-exposed-form-bundle-filter-entity-browser-1');
+
+    $this->getSession()->switchToIFrame('entity_browser_iframe_bundle_filter');
+
+    // Check that only nodes of an allowed type are listed.
+    $this->assertSession()->responseContains('Luke');
+    $this->assertSession()->responseContains('Leia');
+    $this->assertSession()->responseNotContains('Darth');
+
+    // Test exposed form type filter.
+    $this->assertSession()->selectExists('Type')->selectOption('jet');
+    $this->assertSession()->buttonExists('Apply')->press();
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    // Check that only nodes of the type selected in the exposed filter display.
+    $this->assertSession()->pageTextNotContains('Luke');
+    $this->assertSession()->pageTextContains('Leia');
+    $this->assertSession()->pageTextNotContains('Darth');
+
+    $this->assertSession()->selectExists('Type')->selectOption('shark');
+    $this->assertSession()->buttonExists('Apply')->press();
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    // Check that only nodes of the type selected in the exposed filter display.
+    $this->assertSession()->pageTextContains('Luke');
+    $this->assertSession()->pageTextNotContains('Leia');
+    $this->assertSession()->pageTextNotContains('Darth');
+
+    $this->assertSession()->selectExists('Type')->selectOption('All');
+    $this->assertSession()->buttonExists('Apply')->press();
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    // Check that only nodes of the type selected in the exposed filter display.
+    $this->assertSession()->pageTextContains('Luke');
+    $this->assertSession()->pageTextContains('Leia');
+    $this->assertSession()->pageTextNotContains('Darth');
+
+    // Change the allowed bundles on the entity embed.
+    $embed_button = $this->container->get('entity_type.manager')
+      ->getStorage('embed_button')
+      ->load('bundle_filter_test');
+    $type_settings = $embed_button->getTypeSettings();
+    $type_settings['bundles'] = [
+      'article' => 'article',
+    ];
+    $embed_button->set('type_settings', $type_settings);
+    $embed_button->save();
+
+    // Test the new bundle settings are affecting what is visible in the view.
+    $this->drupalGet('/node/add/test_entity_embed');
+    $this->assertSession()->waitForElement('css', 'a.cke_button__bundle_filter_test')->click();
+    $this->assertSession()->waitForId('views-exposed-form-bundle-filter-entity-browser-1');
+
+    $this->getSession()->switchToIFrame('entity_browser_iframe_bundle_filter');
+
+    // Check that only nodes of an allowed type are listed.
+    $this->assertSession()->responseNotContains('Luke');
+    $this->assertSession()->responseNotContains('Leia');
+    $this->assertSession()->responseContains('Darth');
+
+    // If there is just one target_bundle, the contextual filter
+    // should not be visible.
+    $this->assertSession()->fieldNotExists('Type');
+
+  }
+
+}
diff --git a/web/modules/entity_browser/tests/src/FunctionalJavascript/EntityQueueTest.php b/web/modules/entity_browser/tests/src/FunctionalJavascript/EntityQueueTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..88bca00ae272ed062f5d519dc0e90e4d78b6141e
--- /dev/null
+++ b/web/modules/entity_browser/tests/src/FunctionalJavascript/EntityQueueTest.php
@@ -0,0 +1,103 @@
+<?php
+
+namespace Drupal\Tests\entity_browser\FunctionalJavascript;
+
+use Drupal\entityqueue\Entity\EntitySubqueue;
+use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
+
+/**
+ * Tests entity browser used to manipulate EntitySubqueue.
+ *
+ * @group entity_browser
+ *
+ * @package Drupal\Tests\entity_browser\FunctionalJavascript
+ */
+class EntityQueueTest extends WebDriverTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  protected static $modules = [
+    'entity_browser',
+    'entity_browser_test',
+    'entityqueue',
+    'entity_browser_test_entityqueue',
+  ];
+
+  /**
+   * The test administrative user.
+   *
+   * @var \Drupal\user\UserInterface
+   */
+  protected $adminUser;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'stark';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->adminUser = $this->drupalCreateUser([
+      'access content',
+      'access widget_context_default_value entity browser pages',
+      'manipulate all entityqueues',
+    ]);
+  }
+
+  /**
+   * Tests entityqueue buttons.
+   */
+  public function testEntityQueueButtons() {
+
+    $this->drupalLogin($this->adminUser);
+
+    $article1 = $this->createNode(['type' => 'article', 'title' => 'Article 1']);
+    $article2 = $this->createNode(['type' => 'article', 'title' => 'Article 2']);
+    $article3 = $this->createNode(['type' => 'article', 'title' => 'Article 3']);
+
+    $subqueue = EntitySubqueue::load('nodes');
+
+    $subqueue->items->setValue([$article1, $article2, $article3]);
+
+    $subqueue->save();
+
+    $this->drupalGet('/admin/structure/entityqueue/nodes/nodes');
+
+    $correct_order = [
+      1 => 'Article 1',
+      2 => 'Article 2',
+      3 => 'Article 3',
+    ];
+    foreach ($correct_order as $key => $value) {
+      $this->assertSession()
+        ->elementContains('xpath', "(//div[contains(@class, 'item-container')])[" . $key . "]", $value);
+    }
+
+    $this->assertSession()->buttonExists('Reverse')->press();
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    $correct_order = [
+      1 => 'Article 3',
+      2 => 'Article 2',
+      3 => 'Article 1',
+    ];
+    foreach ($correct_order as $key => $value) {
+      $this->assertSession()
+        ->elementContains('xpath', "(//div[contains(@class, 'item-container')])[" . $key . "]", $value);
+    }
+
+    $this->assertSession()->buttonExists('Clear')->press();
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    $this->assertSession()
+      ->elementNotExists('xpath', "//div[contains(@class, 'item-container')]");
+  }
+
+}
diff --git a/web/modules/entity_browser/tests/src/FunctionalJavascript/EntityReferenceWidgetTest.php b/web/modules/entity_browser/tests/src/FunctionalJavascript/EntityReferenceWidgetTest.php
index c760cce7d762026455e5265eec7c264f6e4646da..9129e090601f7be4305c914b4de8c3be7d41e35c 100644
--- a/web/modules/entity_browser/tests/src/FunctionalJavascript/EntityReferenceWidgetTest.php
+++ b/web/modules/entity_browser/tests/src/FunctionalJavascript/EntityReferenceWidgetTest.php
@@ -14,7 +14,7 @@
  *
  * @group entity_browser
  */
-class EntityReferenceWidgetTest extends EntityBrowserJavascriptTestBase {
+class EntityReferenceWidgetTest extends EntityBrowserWebDriverTestBase {
 
   /**
    * {@inheritdoc}
@@ -24,8 +24,12 @@ public function setUp() {
 
     /** @var \Drupal\user\RoleInterface $role */
     $role = Role::load('authenticated');
-    $this->grantPermissions($role, ['access test_entity_browser_iframe_node_view entity browser pages']);
-    $this->grantPermissions($role, ['bypass node access']);
+    $this->grantPermissions($role, [
+      'access test_entity_browser_iframe_node_view entity browser pages',
+      'bypass node access',
+      'administer node form display',
+      'access contextual links',
+    ]);
 
   }
 
@@ -34,11 +38,8 @@ public function setUp() {
    */
   public function testEntityReferenceWidget() {
 
-    $page = $this->getSession()->getPage();
-    $assert_session = $this->assertSession();
-
     // Create an entity_reference field to test the widget.
-    FieldStorageConfig::create([
+    $field_storage = FieldStorageConfig::create([
       'field_name' => 'field_entity_reference1',
       'type' => 'entity_reference',
       'entity_type' => 'node',
@@ -46,15 +47,17 @@ public function testEntityReferenceWidget() {
       'settings' => [
         'target_type' => 'node',
       ],
-    ])->save();
+    ]);
+    $field_storage->save();
 
-    FieldConfig::create([
+    $field = FieldConfig::create([
       'field_name' => 'field_entity_reference1',
       'entity_type' => 'node',
       'bundle' => 'article',
       'label' => 'Referenced articles',
       'settings' => [],
-    ])->save();
+    ]);
+    $field->save();
 
     /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
     $form_display = $this->container->get('entity_type.manager')
@@ -68,38 +71,66 @@ public function testEntityReferenceWidget() {
         'open' => TRUE,
         'field_widget_edit' => TRUE,
         'field_widget_remove' => TRUE,
+        'field_widget_replace' => FALSE,
         'selection_mode' => EntityBrowserElement::SELECTION_MODE_APPEND,
-        'field_widget_display' => 'label',
-        'field_widget_display_settings' => [],
+        'field_widget_display' => 'rendered_entity',
+        'field_widget_display_settings' => [
+          'view_mode' => 'teaser',
+        ],
       ],
     ])->save();
 
     // Create a dummy node that will be used as target.
     $target_node = Node::create([
-      'title' => 'Target example node 1',
+      'title' => 'Walrus',
       'type' => 'article',
     ]);
     $target_node->save();
 
+    $target_node_translation = $target_node->addTranslation('fr', $target_node->toArray());
+    $target_node_translation->setTitle('le Morse');
+    $target_node_translation->save();
+
     $this->drupalGet('/node/add/article');
-    $page->fillField('title[0][value]', 'Referencing node 1');
+    $this->assertSession()->fieldExists('title[0][value]')->setValue('Referencing node 1');
     $this->getSession()->switchToIFrame('entity_browser_iframe_test_entity_browser_iframe_node_view');
     $this->waitForAjaxToFinish();
-    $page->checkField('edit-entity-browser-select-node1');
-    $page->pressButton('Select entities');
+    $this->assertSession()->fieldExists('entity_browser_select[node:1]')->check();
+    $this->assertSession()->buttonExists('Select entities')->press();
     $this->getSession()->switchToIFrame();
-    $this->waitForAjaxToFinish();
-    $page->pressButton('Save');
+    $this->assertTrue($this->assertSession()->waitForText('Walrus'));
+    $this->assertSession()->buttonExists('Save')->press();
 
-    $assert_session->pageTextContains('Article Referencing node 1 has been created.');
+    $this->assertSession()->pageTextContains('Article Referencing node 1 has been created.');
     $nid = $this->container->get('entity.query')->get('node')->condition('title', 'Referencing node 1')->execute();
     $nid = reset($nid);
 
+    // Assert correct translation appears.
+    // @see Drupal\entity_browser\Plugin\EntityBrowser\FieldWidgetDisplay\EntityLabel
+    $this->drupalGet('fr/node/' . $nid . '/edit');
+    $this->assertSession()->pageTextContains('le Morse');
     $this->drupalGet('node/' . $nid . '/edit');
-    $assert_session->pageTextContains('Target example node 1');
+    $this->assertSession()->pageTextContains('Walrus');
+
     // Make sure both "Edit" and "Remove" buttons are visible.
-    $assert_session->buttonExists('edit-field-entity-reference1-current-items-0-remove-button');
-    $assert_session->buttonExists('edit-field-entity-reference1-current-items-0-edit-button');
+    $this->assertSession()->buttonExists('edit-field-entity-reference1-current-items-0-remove-button');
+    $this->assertSession()->buttonExists('edit-field-entity-reference1-current-items-0-edit-button')->press();
+    // Make sure the contextual links are not present.
+    $this->assertSession()->elementNotExists('css', '.contextual-links');
+
+    // Test edit dialog by changing title of referenced entity.
+    $edit_dialog = $this->assertSession()->waitForElement('xpath', '//div[contains(@id, "node-' . $target_node->id() . '-edit-dialog")]');
+    $title_field = $edit_dialog->findField('title[0][value]');
+    $title = $title_field->getValue();
+    $this->assertEquals('Walrus', $title);
+    $title_field->setValue('Alpaca');
+    $this->assertSession()
+      ->elementExists('css', '.ui-dialog-buttonset.form-actions .form-submit')
+      ->press();
+    $this->waitForAjaxToFinish();
+    // Check that new title is displayed.
+    $this->assertSession()->pageTextNotContains('Walrus');
+    $this->assertSession()->pageTextContains('Alpaca');
 
     // Test whether changing these definitions on the browser config effectively
     // change the visibility of the buttons.
@@ -110,14 +141,15 @@ public function testEntityReferenceWidget() {
         'open' => TRUE,
         'field_widget_edit' => FALSE,
         'field_widget_remove' => FALSE,
+        'field_widget_replace' => FALSE,
         'selection_mode' => EntityBrowserElement::SELECTION_MODE_APPEND,
         'field_widget_display' => 'label',
         'field_widget_display_settings' => [],
       ],
     ])->save();
     $this->drupalGet('node/' . $nid . '/edit');
-    $assert_session->buttonNotExists('edit-field-entity-reference1-current-items-0-remove-button');
-    $assert_session->buttonNotExists('edit-field-entity-reference1-current-items-0-edit-button');
+    $this->assertSession()->buttonNotExists('edit-field-entity-reference1-current-items-0-remove-button');
+    $this->assertSession()->buttonNotExists('edit-field-entity-reference1-current-items-0-edit-button');
 
     // Set them to visible again.
     $form_display->setComponent('field_entity_reference1', [
@@ -127,19 +159,161 @@ public function testEntityReferenceWidget() {
         'open' => TRUE,
         'field_widget_edit' => TRUE,
         'field_widget_remove' => TRUE,
+        'field_widget_replace' => FALSE,
         'selection_mode' => EntityBrowserElement::SELECTION_MODE_APPEND,
         'field_widget_display' => 'label',
         'field_widget_display_settings' => [],
       ],
     ])->save();
     $this->drupalGet('node/' . $nid . '/edit');
-    $assert_session->buttonExists('edit-field-entity-reference1-current-items-0-remove-button');
-    $assert_session->buttonExists('edit-field-entity-reference1-current-items-0-edit-button');
+    $remove_button = $this->assertSession()->buttonExists('edit-field-entity-reference1-current-items-0-remove-button');
+    $this->assertEquals('Remove', $remove_button->getValue());
+    $this->assertTrue($remove_button->hasClass('remove-button'));
+    $edit_button = $this->assertSession()->buttonExists('edit-field-entity-reference1-current-items-0-edit-button');
+    $this->assertEquals('Edit', $edit_button->getValue());
+    $this->assertTrue($edit_button->hasClass('edit-button'));
+    // Make sure the "Replace" button is not there.
+    $this->assertSession()->buttonNotExists('edit-field-entity-reference1-current-items-0-replace-button');
 
     // Test the "Remove" button on the widget works.
-    $page->pressButton('Remove');
+    $this->assertSession()->buttonExists('Remove')->press();
     $this->waitForAjaxToFinish();
-    $assert_session->pageTextNotContains('Target example node 1');
+    $this->assertSession()->pageTextNotContains('Alpaca');
+
+    // Test the "Replace" button functionality.
+    $form_display->setComponent('field_entity_reference1', [
+      'type' => 'entity_browser_entity_reference',
+      'settings' => [
+        'entity_browser' => 'test_entity_browser_iframe_node_view',
+        'open' => TRUE,
+        'field_widget_edit' => TRUE,
+        'field_widget_remove' => TRUE,
+        'field_widget_replace' => TRUE,
+        'selection_mode' => EntityBrowserElement::SELECTION_MODE_APPEND,
+        'field_widget_display' => 'label',
+        'field_widget_display_settings' => [],
+      ],
+    ])->save();
+    // In order to ensure the replace button opens the browser, it needs to be
+    // closed.
+    /** @var \Drupal\entity_browser\EntityBrowserInterface $browser */
+    $browser = $this->container->get('entity_type.manager')
+      ->getStorage('entity_browser')
+      ->load('test_entity_browser_iframe_node_view');
+    $browser->getDisplay()
+      ->setConfiguration([
+        'width' => 650,
+        'height' => 500,
+        'link_text' => 'Select entities',
+        'auto_open' => FALSE,
+      ]);
+    $browser->save();
+    // We'll need a third node to be able to make a new selection.
+    $target_node2 = Node::create([
+      'title' => 'Target example node 2',
+      'type' => 'article',
+    ]);
+    $target_node2->save();
+    $this->drupalGet('node/' . $nid . '/edit');
+    // If there is only one entity in the current selection the button should
+    // show up.
+    $replace_button = $this->assertSession()->buttonExists('edit-field-entity-reference1-current-items-0-replace-button');
+    $this->assertEquals('Replace', $replace_button->getValue());
+    $this->assertTrue($replace_button->hasClass('replace-button'));
+    // Clicking on the button should empty the selection and automatically
+    // open the browser again.
+    $replace_button->click();
+    $this->waitForAjaxToFinish();
+    $this->getSession()->switchToIFrame('entity_browser_iframe_test_entity_browser_iframe_node_view');
+    $this->waitForAjaxToFinish();
+    $this->assertSession()->fieldExists('entity_browser_select[node:3]')->check();
+    $this->assertSession()->buttonExists('Select entities')->press();
+    $this->getSession()->wait(1000);
+    $this->getSession()->switchToIFrame();
+    $this->waitForAjaxToFinish();
+    // Even in the AJAX-built markup for the newly selected element, the replace
+    // button should be there.
+    $this->assertSession()->elementExists('css', 'input[data-drupal-selector="edit-field-entity-reference1-current-items-0-replace-button"]');
+    // Adding a new node to the selection, however, should make it disappear.
+    $open_iframe_link = $this->assertSession()->elementExists('css', 'a[data-drupal-selector="edit-field-entity-reference1-entity-browser-entity-browser-link"]');
+    $open_iframe_link->click();
+    $this->waitForAjaxToFinish();
+    $this->getSession()->switchToIFrame('entity_browser_iframe_test_entity_browser_iframe_node_view');
+    $this->waitForAjaxToFinish();
+    $this->assertSession()->fieldExists('entity_browser_select[node:1]')->check();
+    $this->assertSession()->buttonExists('Select entities')->press();
+    $this->getSession()->wait(1000);
+    $this->getSession()->switchToIFrame();
+    $this->waitForAjaxToFinish();
+    $this->assertSession()->elementNotExists('css', 'input[data-drupal-selector="edit-field-entity-reference1-current-items-0-replace-button"]');
+    $this->assertSession()->buttonExists('Save')->press();
+    $this->assertSession()->pageTextContains('Article Referencing node 1 has been updated.');
+
+    // Test the replace button again with different field cardinalities.
+    FieldStorageConfig::load('node.field_entity_reference1')->setCardinality(1)->save();
+    $this->drupalGet('/node/add/article');
+    $this->assertSession()->fieldExists('title[0][value]')->setValue('Referencing node 2');
+    $open_iframe_link = $this->assertSession()->elementExists('css', 'a[data-drupal-selector="edit-field-entity-reference1-entity-browser-entity-browser-link"]');
+    $open_iframe_link->click();
+    $this->waitForAjaxToFinish();
+    $this->getSession()->switchToIFrame('entity_browser_iframe_test_entity_browser_iframe_node_view');
+    $this->waitForAjaxToFinish();
+    $this->assertSession()->fieldExists('entity_browser_select[node:1]')->check();
+    $this->assertSession()->buttonExists('Select entities')->press();
+    $this->getSession()->wait(1000);
+    $this->getSession()->switchToIFrame();
+    $this->waitForAjaxToFinish();
+    $this->assertSession()->elementContains('css', '#edit-field-entity-reference1-wrapper', 'Alpaca');
+    // All three buttons should be visible.
+    $this->assertSession()->elementExists('css', 'input[data-drupal-selector="edit-field-entity-reference1-current-items-0-remove-button"]');
+    $this->assertSession()->elementExists('css', 'input[data-drupal-selector="edit-field-entity-reference1-current-items-0-edit-button"]');
+    $replace_button = $this->assertSession()->elementExists('css', 'input[data-drupal-selector="edit-field-entity-reference1-current-items-0-replace-button"]');
+    // Clicking on the button should empty the selection and automatically
+    // open the browser again.
+    $replace_button->click();
+    $this->waitForAjaxToFinish();
+    $this->getSession()->switchToIFrame('entity_browser_iframe_test_entity_browser_iframe_node_view');
+    $this->waitForAjaxToFinish();
+    $this->assertSession()->fieldExists('entity_browser_select[node:2]')->check();
+    $this->assertSession()->buttonExists('Select entities')->press();
+    $this->getSession()->wait(1000);
+    $this->getSession()->switchToIFrame();
+    $this->waitForAjaxToFinish();
+    $this->assertSession()->elementContains('css', '#edit-field-entity-reference1-wrapper', 'Referencing node 1');
+
+    // Do the same as above but now with cardinality 2.
+    FieldStorageConfig::load('node.field_entity_reference1')
+      ->setCardinality(2)
+      ->save();
+    $this->drupalGet('/node/add/article');
+    $this->assertSession()->fieldExists('title[0][value]')->setValue('Referencing node 3');
+    $open_iframe_link = $this->assertSession()->elementExists('css', 'a[data-drupal-selector="edit-field-entity-reference1-entity-browser-entity-browser-link"]');
+    $open_iframe_link->click();
+    $this->waitForAjaxToFinish();
+    $this->getSession()->switchToIFrame('entity_browser_iframe_test_entity_browser_iframe_node_view');
+    $this->waitForAjaxToFinish();
+    $this->assertSession()->fieldExists('entity_browser_select[node:1]')->check();
+    $this->assertSession()->buttonExists('Select entities')->press();
+    $this->getSession()->wait(1000);
+    $this->getSession()->switchToIFrame();
+    $this->waitForAjaxToFinish();
+    $this->assertSession()->elementContains('css', '#edit-field-entity-reference1-wrapper', 'Alpaca');
+    // All three buttons should be visible.
+    $this->assertSession()->elementExists('css', 'input[data-drupal-selector="edit-field-entity-reference1-current-items-0-remove-button"]');
+    $this->assertSession()->elementExists('css', 'input[data-drupal-selector="edit-field-entity-reference1-current-items-0-edit-button"]');
+    $replace_button = $this->assertSession()->elementExists('css', 'input[data-drupal-selector="edit-field-entity-reference1-current-items-0-replace-button"]');
+    // Clicking on the button should empty the selection and automatically
+    // open the browser again.
+    $replace_button->click();
+    $this->waitForAjaxToFinish();
+    $this->getSession()->switchToIFrame('entity_browser_iframe_test_entity_browser_iframe_node_view');
+    $this->waitForAjaxToFinish();
+    $this->assertSession()->fieldExists('entity_browser_select[node:2]')->check();
+    $this->assertSession()->buttonExists('Select entities')->press();
+    $this->getSession()->wait(1000);
+    $this->getSession()->switchToIFrame();
+    $this->waitForAjaxToFinish();
+    $this->assertSession()->elementContains('css', '#edit-field-entity-reference1-wrapper', 'Referencing node 1');
 
     // Verify that if the user cannot edit the entity, the "Edit" button does
     // not show up, even if configured to.
@@ -147,14 +321,227 @@ public function testEntityReferenceWidget() {
     $role = Role::load('authenticated');
     $role->revokePermission('bypass node access')->trustData()->save();
     $this->drupalGet('node/add/article');
+    $open_iframe_link = $this->assertSession()->elementExists('css', 'a[data-drupal-selector="edit-field-entity-reference1-entity-browser-entity-browser-link"]');
+    $open_iframe_link->click();
+    $this->waitForAjaxToFinish();
     $this->getSession()->switchToIFrame('entity_browser_iframe_test_entity_browser_iframe_node_view');
     $this->waitForAjaxToFinish();
-    $page->checkField('edit-entity-browser-select-node1');
-    $page->pressButton('Select entities');
+    $this->assertSession()->fieldExists('entity_browser_select[node:1]')->check();
+    $this->assertSession()->buttonExists('Select entities')->press();
     $this->getSession()->switchToIFrame();
     $this->waitForAjaxToFinish();
-    $assert_session->buttonNotExists('edit-field-entity-reference1-current-items-0-edit-button');
+    $this->assertSession()->buttonNotExists('edit-field-entity-reference1-current-items-0-edit-button');
+  }
+
+  /**
+   * Tests that drag and drop functions properly.
+   */
+  public function testDragAndDrop() {
+
+    $gatsby = $this->createNode(['type' => 'shark', 'title' => 'Gatsby']);
+    $daisy = $this->createNode(['type' => 'jet', 'title' => 'Daisy']);
+    $nick = $this->createNode(['type' => 'article', 'title' => 'Nick']);
+
+    $santa = $this->createNode(['type' => 'shark', 'title' => 'Santa Claus']);
+    $easter_bunny = $this->createNode(['type' => 'jet', 'title' => 'Easter Bunny']);
+    $pumpkin_king = $this->createNode(['type' => 'article', 'title' => 'Pumpkin King']);
+
+    $field1_storage_config = [
+      'field_name' => 'field_east_egg',
+      'type' => 'entity_reference',
+      'entity_type' => 'node',
+      'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
+      'settings' => [
+        'target_type' => 'node',
+      ],
+    ];
+
+    $field2_storage_config = [
+      'field_name' => 'field_east_egg2',
+    ] + $field1_storage_config;
+
+    $field_storage = FieldStorageConfig::create($field1_storage_config);
+    $field_storage->save();
+
+    $field_storage2 = FieldStorageConfig::create($field2_storage_config);
+    $field_storage2->save();
+
+    $field1_config = [
+      'field_name' => 'field_east_egg',
+      'entity_type' => 'node',
+      'bundle' => 'article',
+      'label' => 'East Eggers',
+      'settings' => [
+        'handler_settings' => [
+          'target_bundles' => [
+            'shark' => 'shark',
+            'jet' => 'jet',
+            'article' => 'article',
+          ],
+        ],
+      ],
+    ];
+
+    $field2_config = [
+      'field_name' => 'field_east_egg2',
+      'label' => 'Easter Eggs',
+    ] + $field1_config;
+
+    $field = FieldConfig::create($field1_config);
+    $field->save();
+
+    $field2 = FieldConfig::create($field2_config);
+    $field2->save();
+
+    /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
+    $form_display = $this->container->get('entity_type.manager')
+      ->getStorage('entity_form_display')
+      ->load('node.article.default');
+
+    $form_display->removeComponent('field_reference');
+
+    $field_widget_config = [
+      'type' => 'entity_browser_entity_reference',
+      'settings' => [
+        'entity_browser' => 'widget_context_default_value',
+        'table_settings' => [
+          'status_column' => TRUE,
+          'bundle_column' => TRUE,
+          'label_column' => FALSE,
+        ],
+        'open' => FALSE,
+        'field_widget_edit' => TRUE,
+        'field_widget_remove' => TRUE,
+        'field_widget_replace' => FALSE,
+        'selection_mode' => EntityBrowserElement::SELECTION_MODE_APPEND,
+        'field_widget_display' => 'label',
+        'field_widget_display_settings' => [],
+      ],
+    ];
+
+    $form_display->setComponent('field_east_egg', $field_widget_config)->save();
+    $form_display->setComponent('field_east_egg2', $field_widget_config)->save();
+
+    // Set auto open to false on the entity browser.
+    $entity_browser = $this->container->get('entity_type.manager')
+      ->getStorage('entity_browser')
+      ->load('widget_context_default_value');
+
+    $display_configuration = $entity_browser->get('display_configuration');
+    $display_configuration['auto_open'] = FALSE;
+    $entity_browser->set('display_configuration', $display_configuration);
+    $entity_browser->save();
+
+    $account = $this->drupalCreateUser([
+      'access widget_context_default_value entity browser pages',
+      'create article content',
+      'access content',
+    ]);
+    $this->drupalLogin($account);
+
+    $this->drupalGet('node/add/article');
+
+    $this->assertSession()->elementExists('xpath', '(//summary)[1]')->click();
+
+    // Open the entity browser widget form.
+    $this->getSession()->getPage()->clickLink('Select entities');
+    $this->getSession()->switchToIFrame('entity_browser_iframe_widget_context_default_value');
+    $this->assertSession()->fieldExists('entity_browser_select[node:' . $gatsby->id() . ']')->check();
+    $this->assertSession()->fieldExists('entity_browser_select[node:' . $daisy->id() . ']')->check();
+    $this->assertSession()->fieldExists('entity_browser_select[node:' . $nick->id() . ']')->check();
+    $this->assertSession()->buttonExists('Select entities')->press();
+    $this->waitForAjaxToFinish();
+    $this->assertSession()->buttonExists('Use selected')->press();
+    $this->waitForAjaxToFinish();
+    $this->getSession()->switchToIFrame();
+    $this->waitForAjaxToFinish();
+
+    $correct_order = [
+      1 => 'Gatsby',
+      2 => 'Daisy',
+      3 => 'Nick',
+    ];
+    foreach ($correct_order as $key => $value) {
+      $this->assertSession()
+        ->elementContains('xpath', "(//div[contains(@class, 'item-container')])[" . $key . "]", $value);
+    }
+
+    // Close details 1.
+    $this->assertSession()->elementExists('xpath', '(//summary)[1]')->click();
+    // Open details 2.
+    $this->assertSession()->elementExists('xpath', '(//summary)[2]')->click();
+
+    // Open the entity browser widget form.
+    $this->assertSession()->elementExists('xpath', "(//a[contains(text(), 'Select entities')])[2]")->click();
+    $this->getSession()->switchToIFrame('entity_browser_iframe_widget_context_default_value');
+
+    $this->assertSession()->fieldExists('entity_browser_select[node:' . $santa->id() . ']')->check();
+    $this->assertSession()->fieldExists('entity_browser_select[node:' . $easter_bunny->id() . ']')->check();
+    $this->assertSession()->fieldExists('entity_browser_select[node:' . $pumpkin_king->id() . ']')->check();
+    $this->assertSession()->buttonExists('Select entities')->press();
+    $this->waitForAjaxToFinish();
+    $this->assertSession()->buttonExists('Use selected')->press();
+    $this->waitForAjaxToFinish();
+    $this->getSession()->switchToIFrame();
+    $this->waitForAjaxToFinish();
+
+    // Close details 2.
+    $this->assertSession()->elementExists('xpath', '(//summary)[2]')->click();
+    // Open details 1.
+    $this->assertSession()->elementExists('xpath', '(//summary)[1]')->click();
+
+    $first_item = $this->assertSession()->elementExists('xpath', "(//div[contains(@class, 'item-container')])[1]");
+    $this->dragDropElement($first_item, 160, 0);
+    $this->waitForAjaxToFinish();
+
+    $this->assertSession()->fieldExists('title[0][value]')->setValue('Hello World');
+
+    $this->assertSession()->buttonExists('Save')->press();
+
+    $this->drupalGet('node/7/edit');
+
+    $correct_order = [
+      1 => 'Daisy',
+      2 => 'Gatsby',
+      3 => 'Nick',
+      4 => 'Santa Claus',
+      5 => 'Easter Bunny',
+      6 => 'Pumpkin King',
+    ];
+    foreach ($correct_order as $key => $value) {
+      $this->assertSession()
+        ->elementContains('xpath', "(//div[contains(@class, 'item-container')])[" . $key . "]", $value);
+    }
+
+    $fourth = $this->assertSession()->elementExists('xpath', "(//div[contains(@class, 'item-container')])[4]");
+    $this->dragDropElement($fourth, 160, 0);
+
+    $correct_order = [
+      4 => 'Easter Bunny',
+      5 => 'Santa Claus',
+      6 => 'Pumpkin King',
+    ];
+    foreach ($correct_order as $key => $value) {
+      $this->assertSession()
+        ->elementContains('xpath', "(//div[contains(@class, 'item-container')])[" . $key . "]", $value);
+    }
+
+    // Test that order is preserved after removing item.
+    $this->assertSession()
+      ->elementExists('xpath', '(//input[contains(@class, "remove-button")])[5]')
+      ->press();
+
+    $this->waitForAjaxToFinish();
+
+    $correct_order = [
+      4 => 'Easter Bunny',
+      5 => 'Pumpkin King',
+    ];
 
+    foreach ($correct_order as $key => $value) {
+      $this->assertSession()
+        ->elementContains('xpath', "(//div[contains(@class, 'item-container')])[" . $key . "]", $value);
+    }
   }
 
 }
diff --git a/web/modules/entity_browser/tests/src/FunctionalJavascript/FieldWidgetConfigTest.php b/web/modules/entity_browser/tests/src/FunctionalJavascript/FieldWidgetConfigTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d1dd9d81c65fe0d6ca607fe2d94cf12fd4bcea14
--- /dev/null
+++ b/web/modules/entity_browser/tests/src/FunctionalJavascript/FieldWidgetConfigTest.php
@@ -0,0 +1,229 @@
+<?php
+
+namespace Drupal\Tests\entity_browser\FunctionalJavascript;
+
+use Drupal\Core\Field\FieldStorageDefinitionInterface;
+use Drupal\entity_browser\Entity\EntityBrowser;
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\Entity\FieldStorageConfig;
+use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
+use Drupal\entity_browser\Element\EntityBrowserElement;
+
+/**
+ * Tests the config UI for adding and editing entity browsers.
+ *
+ * @group entity_browser
+ *
+ * @package Drupal\Tests\entity_browser\FunctionalJavascript
+ */
+class FieldWidgetConfigTest extends WebDriverTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'stark';
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  protected static $modules = [
+    'entity_browser',
+    'entity_browser_test',
+    'block',
+    'node',
+    'taxonomy',
+    'views',
+    'token',
+    'field_ui',
+  ];
+
+  /**
+   * The test administrative user.
+   *
+   * @var \Drupal\user\UserInterface
+   */
+  protected $adminUser;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->drupalPlaceBlock('local_tasks_block');
+    $this->drupalPlaceBlock('local_actions_block');
+
+    $this->adminUser = $this->drupalCreateUser([
+      'administer entity browsers',
+      'access administration pages',
+      'administer node fields',
+      'administer node display',
+      'administer nodes',
+      'administer node form display',
+      'create article content',
+    ]);
+
+    $this->drupalLogin($this->adminUser);
+  }
+
+  /**
+   * Test ajax for display plugin setting.
+   */
+  public function testAjax() {
+
+    // Create an entity_reference field to test the widget.
+    $field_storage = FieldStorageConfig::create([
+      'field_name' => 'field_humperdinck',
+      'type' => 'entity_reference',
+      'entity_type' => 'node',
+      'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
+      'settings' => [
+        'target_type' => 'node',
+      ],
+    ]);
+    $field_storage->save();
+
+    $field = FieldConfig::create([
+      'field_name' => 'field_humperdinck',
+      'entity_type' => 'node',
+      'bundle' => 'article',
+      'label' => 'Prince of Florin',
+      'settings' => [
+        'handler' => 'default:node',
+        'handler_settings' => [
+          'target_bundles' => [
+            'article' => 'article',
+          ],
+        ],
+      ],
+    ]);
+    $field->save();
+
+    /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
+    $form_display = $this->container->get('entity_type.manager')
+      ->getStorage('entity_form_display')
+      ->load('node.article.default');
+
+    $form_display->setComponent('field_humperdinck', [
+      'type' => 'entity_browser_entity_reference',
+      'settings' => [
+        'entity_browser' => 'test_entity_browser_iframe_node_view',
+        'open' => TRUE,
+        'field_widget_edit' => TRUE,
+        'field_widget_remove' => TRUE,
+        'field_widget_replace' => FALSE,
+        'selection_mode' => EntityBrowserElement::SELECTION_MODE_APPEND,
+        'field_widget_display' => 'label',
+        'field_widget_display_settings' => [],
+      ],
+    ])->save();
+
+    $this->drupalGet('/admin/structure/types/manage/article/form-display');
+
+    $this->assertSession()->waitforButton('field_humperdinck_settings_edit')->press();
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    $form_prefix = 'fields[field_humperdinck][settings_edit_form][settings]';
+
+    $display = $this->assertSession()->fieldExists($form_prefix . '[field_widget_display]');
+
+    $this->assertEquals('label', $display->getValue());
+
+    $details_selector = 'details[data-drupal-selector="edit-fields-field-humperdinck-settings-edit-form-settings-field-widget-display-settings"]';
+
+    // Test that switching display plugin returns appropriate plugin
+    // settings form.
+    $options = [
+      'rendered_entity' => 'Select view mode to be used when rendering entities.',
+      'label' => 'This plugin has no configuration options.',
+    ];
+
+    for ($i = 0; $i < 3; $i++) {
+      foreach ($options as $option => $target_text) {
+        $display->setValue($option);
+        $this->assertSession()->assertWaitOnAjaxRequest();
+        $this->assertSession()
+          ->elementContains('css', $details_selector, $target_text);
+      }
+    }
+  }
+
+  /**
+   * Tests 'selection_edit' validation on field widget form and warning message on content entity forms.
+   */
+  public function testSelectionModeValidation() {
+
+    // Create an entity_reference field to test the widget.
+    $field_storage = FieldStorageConfig::create([
+      'field_name' => 'field_dalek',
+      'type' => 'entity_reference',
+      'entity_type' => 'node',
+      'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
+      'settings' => [
+        'target_type' => 'node',
+      ],
+    ]);
+    $field_storage->save();
+
+    $field = FieldConfig::create([
+      'field_name' => 'field_dalek',
+      'entity_type' => 'node',
+      'bundle' => 'article',
+      'label' => 'Seek! Locate! Exterminate!',
+      'settings' => [],
+    ]);
+    $field->save();
+
+    $this->drupalGet('/admin/structure/types/manage/article/form-display');
+    // Drag to enabled.
+    $target = $this->assertSession()
+      ->elementExists('css', '#title');
+    $this->assertSession()
+      ->elementExists('css', '#field-dalek')
+      ->find('css', '.handle')
+      ->dragTo($target);
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    // Set to Entity Browser Widget.
+    $this->assertSession()->selectExists('fields[field_dalek][type]')->selectOption('entity_browser_entity_reference');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    // Open settings form.
+    $this->assertSession()->waitforButton('field_dalek_settings_edit')->press();
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    $form_prefix = 'fields[field_dalek][settings_edit_form][settings]';
+
+    // Select entity browser with "no_selection" selection display.
+    $this->assertSession()->selectExists($form_prefix . '[entity_browser]')->selectOption('test_entity_browser_iframe_node_view');
+    $this->assertSession()->selectExists($form_prefix . '[selection_mode]')->selectOption('selection_edit');
+    $this->assertSession()->buttonExists('field_dalek_plugin_settings_update')->press();
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    $this->assertSession()->selectExists($form_prefix . '[entity_browser]')->hasClass('error');
+    $this->assertSession()->selectExists($form_prefix . '[selection_mode]')->hasClass('error');
+
+    $error_message = 'The selection mode Edit selection requires an entity browser with a selection display plugin that supports preselection. Either change the selection mode or update the Test entity browser iframe with view widget for nodes entity browser to use a selection display plugin that supports preselection.';
+
+    $this->assertSession()->pageTextContains($error_message);
+
+    // Switch to an entity browser that supports preselection.
+    $this->assertSession()->selectExists($form_prefix . '[entity_browser]')->selectOption('test_entity_browser_iframe_view');
+
+    $this->assertSession()->buttonExists('field_dalek_plugin_settings_update')->press();
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    $this->assertSession()->responseNotContains($error_message);
+
+    $this->assertSession()->buttonExists('Save')->press();
+
+    // Update selected entity browser so it will trigger a warning.
+    $entity_browser = EntityBrowser::load('test_entity_browser_iframe_view');
+    $entity_browser->setSelectionDisplay('no_display');
+    $entity_browser->save();
+
+    $this->drupalGet('/node/add/article');
+    // Error message should be shown.
+    $this->assertSession()->pageTextContains('There is a configuration problem with field "Seek! Locate! Exterminate!". The selection mode Edit selection requires an entity browser with a selection display plugin that supports preselection. Either change the selection mode or update the Test entity browser iframe with view widget entity browser to use a selection display plugin that supports preselection.');
+  }
+
+}
diff --git a/web/modules/entity_browser/tests/src/FunctionalJavascript/ImageFieldTest.php b/web/modules/entity_browser/tests/src/FunctionalJavascript/ImageFieldTest.php
index a08781a4859a5335a1f40efb777baf0d2c1178cf..03cd9e1b7950f808e2975a2d3fef7f9cebc3c63f 100644
--- a/web/modules/entity_browser/tests/src/FunctionalJavascript/ImageFieldTest.php
+++ b/web/modules/entity_browser/tests/src/FunctionalJavascript/ImageFieldTest.php
@@ -8,13 +8,16 @@
 use Drupal\field\Entity\FieldStorageConfig;
 use Drupal\file\Entity\File;
 use Drupal\node\Entity\Node;
+use Drupal\Tests\TestFileCreationTrait;
 
 /**
  * Tests the image field widget.
  *
  * @group entity_browser
  */
-class ImageFieldTest extends EntityBrowserJavascriptTestBase {
+class ImageFieldTest extends EntityBrowserWebDriverTestBase {
+
+  use TestFileCreationTrait;
 
   /**
    * Created file entity.
@@ -49,7 +52,15 @@ public function setUp() {
       ],
     ])->save();
 
-    file_unmanaged_copy(\Drupal::root() . '/core/modules/simpletest/files/image-test.jpg', 'public://example.jpg');
+    $test_files = $this->getTestFiles('image');
+    foreach ($test_files as $test_file) {
+      if ($test_file->filename === 'image-test.jpg') {
+        break;
+      }
+    }
+
+    $file_system = $this->container->get('file_system');
+    $file_system->copy($file_system->realpath($test_file->uri), 'public://example.jpg');
     $this->image = File::create([
       'uri' => 'public://example.jpg',
     ]);
@@ -70,6 +81,7 @@ public function setUp() {
         'open' => TRUE,
         'field_widget_edit' => FALSE,
         'field_widget_remove' => TRUE,
+        'field_widget_replace' => TRUE,
         'selection_mode' => EntityBrowserElement::SELECTION_MODE_APPEND,
         'view_mode' => 'default',
         'preview_image_style' => 'thumbnail',
@@ -119,13 +131,17 @@ public function testImageFieldUsage() {
     $this->getSession()->switchToIFrame('entity_browser_iframe_test_entity_browser_iframe_view');
     $this->getSession()->getPage()->checkField('entity_browser_select[file:' . $this->image->id() . ']');
     $this->getSession()->getPage()->pressButton('Select entities');
-    $this->getSession()->getPage()->pressButton('Use selected');
+    $this->waitForAjaxToFinish();
+    $button = $this->assertSession()->waitForButton('Use selected');
     $this->assertSession()->pageTextContains('example.jpg');
+    $button->press();
+
     // Switch back to the main page.
     $this->getSession()->switchToIFrame();
     $this->waitForAjaxToFinish();
     // Check if the image thumbnail exists.
-    $this->assertSession()->elementExists('xpath', '//*[@data-drupal-selector="edit-field-image-current-' . $this->image->id() . '-display"]');
+    $this->assertSession()
+      ->waitForElementVisible('xpath', '//tr[@data-drupal-selector="edit-field-image-current-1"]');
     // Test if the image filename is present.
     $this->assertSession()->pageTextContains('example.jpg');
     // Test specifying Alt and Title texts and saving the node.
@@ -149,6 +165,32 @@ public function testImageFieldUsage() {
     // Image filename should not be present.
     $this->assertSession()->pageTextNotContains('example.jpg');
     $this->assertSession()->linkExists('Select entities');
+    // Test the Replace functionality.
+    $test_files = $this->getTestFiles('image');
+    foreach ($test_files as $test_file) {
+      if ($test_file->filename === 'image-test.jpg') {
+        break;
+      }
+    }
+    $file_system = $this->container->get('file_system');
+    $file_system->copy($file_system->realpath($test_file->uri), 'public://example2.jpg');
+    $image2 = File::create(['uri' => 'public://example2.jpg']);
+    $image2->save();
+    \Drupal::service('file.usage')->add($image2, 'entity_browser', 'test', '1');
+    $this->drupalGet('node/1/edit');
+    $this->assertSession()->buttonExists('Replace');
+    $this->getSession()->getPage()->pressButton('Replace');
+    $this->waitForAjaxToFinish();
+    $this->getSession()->switchToIFrame('entity_browser_iframe_test_entity_browser_iframe_view');
+    $this->getSession()->getPage()->checkField('entity_browser_select[file:' . $image2->id() . ']');
+    $this->getSession()->getPage()->pressButton('Select entities');
+    $this->getSession()->getPage()->pressButton('Use selected');
+    $this->getSession()->wait(1000);
+    $this->getSession()->switchToIFrame();
+    $this->waitForAjaxToFinish();
+    // Initial image should not be present, the new one should be there instead.
+    $this->assertSession()->pageTextNotContains('example.jpg');
+    $this->assertSession()->pageTextContains('example2.jpg');
   }
 
   /**
@@ -157,8 +199,18 @@ public function testImageFieldUsage() {
   public function testImageFieldSettings() {
     $root = \Drupal::root();
     $file_wrong_type = $root . '/core/misc/druplicon.png';
-    $file_too_big = $root . '/core/modules/simpletest/files/image-2.jpg';
-    $file_just_right = $root . '/core/modules/simpletest/files/image-test.jpg';
+
+    $test_files = $this->getTestFiles('image');
+    $file_system = $this->container->get('file_system');
+    foreach ($test_files as $test_file) {
+      if ($test_file->filename === 'image-test.jpg') {
+        $file_just_right = $file_system->realpath($test_file->uri);
+      }
+      elseif ($test_file->filename === 'image-2.jpg') {
+        $file_too_big = $file_system->realpath($test_file->uri);
+      }
+    }
+
     $this->drupalGet('node/add/article');
     $this->assertSession()->linkExists('Select images');
     $this->getSession()->getPage()->clickLink('Select images');
@@ -170,8 +222,14 @@ public function testImageFieldSettings() {
     // expect the field to override the widget.
     $this->getSession()->getPage()->attachFileToField('files[upload][]', $file_wrong_type);
     $this->waitForAjaxToFinish();
-    $this->assertSession()->pageTextContains('Only files with the following extensions are allowed: jpg');
-    $this->assertSession()->pageTextContains('The specified file druplicon.png could not be uploaded');
+    if (version_compare(\Drupal::VERSION, '8.7', '>=')) {
+      $this->assertSession()->responseContains('Only files with the following extensions are allowed: <em class="placeholder">jpg</em>.');
+      $this->assertSession()->responseContains('The selected file <em class="placeholder">druplicon.png</em> cannot be uploaded.');
+    }
+    else {
+      $this->assertSession()->pageTextContains('Only files with the following extensions are allowed: jpg');
+      $this->assertSession()->pageTextContains('The specified file druplicon.png could not be uploaded');
+    }
     // Upload an image bigger than the field widget's configured max size.
     $this->getSession()->getPage()->attachFileToField('files[upload][]', $file_too_big);
     $this->waitForAjaxToFinish();
@@ -180,8 +238,11 @@ public function testImageFieldSettings() {
     $this->getSession()->getPage()->attachFileToField('files[upload][]', $file_just_right);
     $this->waitForAjaxToFinish();
     $this->getSession()->getPage()->pressButton('Select files');
-    $this->getSession()->getPage()->pressButton('Use selected');
+    $this->waitForAjaxToFinish();
+    $button = $this->assertSession()->waitForButton('Use selected');
     $this->assertSession()->pageTextContains('image-test.jpg');
+    $button->press();
+    $this->waitForAjaxToFinish();
     // Check that the file has uploaded to the correct sub-directory.
     $this->getSession()->switchToIFrame();
     $this->waitForAjaxToFinish();
diff --git a/web/modules/entity_browser/tests/src/FunctionalJavascript/InlineEntityFormTest.php b/web/modules/entity_browser/tests/src/FunctionalJavascript/InlineEntityFormTest.php
index 259e0f8a2ed7fa1a31db9f90f637fd398f45d2db..c2f36352c48a9de65f9ca8eb80602d337656da05 100644
--- a/web/modules/entity_browser/tests/src/FunctionalJavascript/InlineEntityFormTest.php
+++ b/web/modules/entity_browser/tests/src/FunctionalJavascript/InlineEntityFormTest.php
@@ -2,8 +2,6 @@
 
 namespace Drupal\Tests\entity_browser\FunctionalJavascript;
 
-use Behat\Mink\Element\NodeElement;
-
 /**
  * Test for integration of entity browser and inline entity form.
  *
@@ -11,13 +9,17 @@
  *
  * @package Drupal\Tests\entity_browser\FunctionalJavascript
  */
-class InlineEntityFormTest extends EntityBrowserJavascriptTestBase {
+class InlineEntityFormTest extends EntityBrowserWebDriverTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'classy';
 
   /**
    * {@inheritdoc}
    */
   public static $modules = [
-    'ctools',
     'views',
     'block',
     'node',
@@ -28,7 +30,7 @@ class InlineEntityFormTest extends EntityBrowserJavascriptTestBase {
     'system',
     'node',
     'inline_entity_form',
-    'entity',
+    'entity_browser_test',
     'entity_browser_ief_test',
   ];
 
@@ -40,44 +42,15 @@ class InlineEntityFormTest extends EntityBrowserJavascriptTestBase {
     'update media',
     'access ief_entity_browser_file entity browser pages',
     'access ief_entity_browser_file_modal entity browser pages',
+    'access widget_context_default_value entity browser pages',
+    'access bundle_filter entity browser pages',
     'access content',
     'create ief_content content',
+    'create shark content',
+    'create jet content',
     'edit any ief_content content',
   ];
 
-  /**
-   * Drag element in document with defined offset position.
-   *
-   * @param \Behat\Mink\Element\NodeElement $element
-   *   Element that will be dragged.
-   * @param int $offsetX
-   *   Vertical offset for element drag in pixels.
-   * @param int $offsetY
-   *   Horizontal offset for element drag in pixels.
-   */
-  protected function dragDropElement(NodeElement $element, $offsetX, $offsetY) {
-    $elemXpath = $element->getXpath();
-
-    $jsCode = "var fireMouseEvent = function (type, element, x, y) {"
-      . "  var event = document.createEvent('MouseEvents');"
-      . "  event.initMouseEvent(type, true, (type !== 'mousemove'), window, 0, 0, 0, x, y, false, false, false, false, 0, element);"
-      . "  element.dispatchEvent(event); };";
-
-    // XPath provided by getXpath uses single quote (') to encapsulate strings,
-    // that's why xpath has to be quited with double quites in javascript code.
-    $jsCode .= "(function() {" .
-      "  var dragElement = document.evaluate(\"{$elemXpath}\", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;" .
-      "  var pos = dragElement.getBoundingClientRect();" .
-      "  var centerX = Math.floor((pos.left + pos.right) / 2);" .
-      "  var centerY = Math.floor((pos.top + pos.bottom) / 2);" .
-      "  fireMouseEvent('mousedown', dragElement, centerX, centerY);" .
-      "  fireMouseEvent('mousemove', document, centerX + {$offsetX}, centerY + {$offsetY});" .
-      "  fireMouseEvent('mouseup', dragElement, centerX + {$offsetX}, centerY + {$offsetY});" .
-      "})();";
-
-    $this->getSession()->executeScript($jsCode);
-  }
-
   /**
    * Check that selection state in entity browser Inline Entity Form.
    */
@@ -255,6 +228,187 @@ public function testModalAutoOpenInsideInlineEntityForm() {
     $this->getSession()
       ->switchToIFrame('entity_browser_iframe_ief_entity_browser_file_modal');
 
-    $this->assertSession()->pageTextContains('Test entity browser file modal');
+    $this->assertSession()->waitForElementVisible('css', 'ief-entity-browser-file-modal-form');
+
+    $this->assertSession()->responseContains('Test entity browser file modal');
   }
+
+  /**
+   * Tests the EntityBrowserWidgetContext argument_default views plugin.
+   */
+  public function testContextualFilter() {
+    $this->createNode(['type' => 'shark', 'title' => 'Luke']);
+    $this->createNode(['type' => 'jet', 'title' => 'Leia']);
+    $this->createNode(['type' => 'ief_content', 'title' => 'Darth']);
+
+    $this->drupalGet('node/add/ief_content');
+    $page = $this->getSession()->getPage();
+
+    $page->fillField('Title', 'Test IEF Title');
+    $page->pressButton('Add existing node');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->getSession()->switchToIFrame('entity_browser_iframe_widget_context_default_value');
+
+    // Check that only nodes of an allowed type are listed.
+    $this->assertSession()->pageTextContains('Luke');
+    $this->assertSession()->pageTextContains('Leia');
+    $this->assertSession()->pageTextNotContains('Darth');
+
+    /** @var \Drupal\Core\Field\FieldConfigInterface $field_config */
+    $field_config = $this->container->get('entity_type.manager')
+      ->getStorage('field_config')
+      ->load('node.ief_content.field_nodes');
+    $handler_settings = $field_config->getSetting('handler_settings');
+    $handler_settings['target_bundles'] = [
+      'ief_content' => 'ief_content',
+    ];
+    $field_config->setSetting('handler_settings', $handler_settings);
+    $field_config->save();
+
+    $this->drupalGet('node/add/ief_content');
+    $page = $this->getSession()->getPage();
+
+    $page->fillField('Title', 'Test IEF Title');
+    $page->pressButton('Add existing node');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->getSession()->switchToIFrame('entity_browser_iframe_widget_context_default_value');
+
+    // Check that only nodes of an allowed type are listed.
+    $this->assertSession()->pageTextNotContains('Luke');
+    $this->assertSession()->pageTextNotContains('Leia');
+    $this->assertSession()->pageTextContains('Darth');
+  }
+
+  /**
+   * Tests the ContextualBundle filter plugin with exposed option.
+   */
+  public function testContextualBundleExposed() {
+
+    $this->config('core.entity_form_display.node.ief_content.default')
+      ->set('content.field_nodes.third_party_settings.entity_browser_entity_form.entity_browser_id', 'bundle_filter')
+      ->save();
+
+    $this->config('entity_browser.browser.bundle_filter')
+      ->set('widgets.b882a89d-9ce4-4dfe-9802-62df93af232a.settings.view', 'bundle_filter_exposed')
+      ->save();
+
+    $this->createNode(['type' => 'shark', 'title' => 'Luke']);
+    $this->createNode(['type' => 'jet', 'title' => 'Leia']);
+    $this->createNode(['type' => 'ief_content', 'title' => 'Darth']);
+
+    $this->drupalGet('node/add/ief_content');
+    $page = $this->getSession()->getPage();
+
+    $page->fillField('Title', 'Test IEF Title');
+    $page->pressButton('Add existing node');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->getSession()->switchToIFrame('entity_browser_iframe_bundle_filter');
+
+    // Check that only nodes of an allowed type are listed.
+    $this->assertSession()->pageTextContains('Luke');
+    $this->assertSession()->pageTextContains('Leia');
+    $this->assertSession()->pageTextNotContains('Darth');
+
+    // Test exposed form type filter.
+    $this->assertSession()->selectExists('Type')->selectOption('jet');
+    $this->assertSession()->buttonExists('Apply')->press();
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    // Check that only nodes of the type selected in the exposed filter display.
+    $this->assertSession()->pageTextNotContains('Luke');
+    $this->assertSession()->pageTextContains('Leia');
+    $this->assertSession()->pageTextNotContains('Darth');
+
+    $this->assertSession()->selectExists('Type')->selectOption('shark');
+    $this->assertSession()->buttonExists('Apply')->press();
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    // Check that only nodes of the type selected in the exposed filter display.
+    $this->assertSession()->pageTextContains('Luke');
+    $this->assertSession()->pageTextNotContains('Leia');
+    $this->assertSession()->pageTextNotContains('Darth');
+
+    $this->assertSession()->selectExists('Type')->selectOption('All');
+    $this->assertSession()->buttonExists('Apply')->press();
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    // Check that only nodes of the type selected in the exposed filter display.
+    $this->assertSession()->pageTextContains('Luke');
+    $this->assertSession()->pageTextContains('Leia');
+    $this->assertSession()->pageTextNotContains('Darth');
+
+    /** @var \Drupal\Core\Field\FieldConfigInterface $field_config */
+    $field_config = $this->container->get('entity_type.manager')
+      ->getStorage('field_config')
+      ->load('node.ief_content.field_nodes');
+    $handler_settings = $field_config->getSetting('handler_settings');
+    $handler_settings['target_bundles'] = [
+      'ief_content' => 'ief_content',
+    ];
+    $field_config->setSetting('handler_settings', $handler_settings);
+    $field_config->save();
+
+    $this->drupalGet('node/add/ief_content');
+    $page = $this->getSession()->getPage();
+
+    $page->fillField('Title', 'Test IEF Title');
+    $page->pressButton('Add existing node');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->getSession()->switchToIFrame('entity_browser_iframe_bundle_filter');
+
+    // Check that only nodes of an allowed type are listed.
+    $this->assertSession()->pageTextNotContains('Luke');
+    $this->assertSession()->pageTextNotContains('Leia');
+    $this->assertSession()->pageTextContains('Darth');
+
+    // If there is just one target_bundle, the contextual filter
+    // should not be visible.
+    $this->assertSession()->fieldNotExists('Type');
+
+  }
+
+  /**
+   * Tests entity_browser_entity_form_reference_form_validate.
+   */
+  public function testEntityFormReferenceFormValidate() {
+    $boxer = $this->createNode(['type' => 'shark', 'title' => 'Boxer']);
+    $napoleon = $this->createNode(['type' => 'jet', 'title' => 'Napoleon']);
+
+    $this->drupalGet('node/add/ief_content');
+    $page = $this->getSession()->getPage();
+
+    $page->fillField('Title', 'Test IEF Title');
+
+    // Select the same node twice.
+    for ($i = 0; $i < 2; $i++) {
+      $this->assertSession()->buttonExists('Add existing node')->press();
+      $this->assertSession()->assertWaitOnAjaxRequest();
+      $this->getSession()->switchToIFrame('entity_browser_iframe_widget_context_default_value');
+      $this->assertSession()->fieldExists('entity_browser_select[node:' . $boxer->id() . ']')->check();
+      $this->assertSession()->buttonExists('Select entities')->press();
+      $this->assertSession()->assertWaitOnAjaxRequest();
+      $this->assertSession()->buttonExists('Use selected')->press();
+      $this->getSession()->switchToIFrame();
+      $this->assertSession()->assertWaitOnAjaxRequest();
+    }
+
+    $this->assertSession()->pageTextContains('The selected node has already been added.');
+
+    // Select a different node.
+    $this->getSession()->switchToIFrame('entity_browser_iframe_widget_context_default_value');
+    $this->assertSession()->fieldExists('entity_browser_select[node:' . $napoleon->id() . ']')->check();
+    $this->assertSession()->buttonExists('Select entities')->press();
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->assertSession()->buttonExists('Use selected')->press();
+    $this->getSession()->switchToIFrame();
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    $this->assertSession()->pageTextNotContains('The selected node has already been added.');
+
+    $ief_table = $this->assertSession()->elementExists('xpath', '//table[contains(@id, "ief-entity-table-edit-field-nodes-entities")]');
+    $table_text = $ief_table->getText();
+    $this->assertContains('Boxer', $table_text);
+    $this->assertContains('Napoleon', $table_text);
+  }
+
 }
diff --git a/web/modules/entity_browser/tests/src/FunctionalJavascript/MultiStepSelectionDisplayTest.php b/web/modules/entity_browser/tests/src/FunctionalJavascript/MultiStepSelectionDisplayTest.php
index bfbd06a349442c37329d6d85187463d94a90f722..9f3162c647dbe1839cb0a081072cc069494b5a3e 100644
--- a/web/modules/entity_browser/tests/src/FunctionalJavascript/MultiStepSelectionDisplayTest.php
+++ b/web/modules/entity_browser/tests/src/FunctionalJavascript/MultiStepSelectionDisplayTest.php
@@ -11,7 +11,7 @@
  *
  * @package Drupal\Tests\entity_browser\FunctionalJavascript
  */
-class MultiStepSelectionDisplayTest extends EntityBrowserJavascriptTestBase {
+class MultiStepSelectionDisplayTest extends EntityBrowserWebDriverTestBase {
 
   /**
    * Open iframe entity browser and change scope to iframe.
@@ -27,7 +27,7 @@ protected function openEntityBrowser() {
    * Close iframe entity browser and change scope to base page.
    */
   protected function closeEntityBrowser() {
-    $this->clickXpathSelector('//*[@data-drupal-selector="edit-use-selected"]');
+    $this->assertSession()->elementExists('xpath', '//*[@data-drupal-selector="edit-use-selected"]')->press();
     $this->getSession()->switchToIFrame();
     $this->waitForAjaxToFinish();
   }
@@ -41,7 +41,7 @@ protected function closeEntityBrowser() {
   protected function clickViewEntity($entityId) {
     $xpathViewRow = '//*[./*[contains(@class, "views-field-entity-browser-select") and .//input[@name="entity_browser_select[' . $entityId . ']"]]]';
 
-    $this->clickXpathSelector($xpathViewRow, FALSE);
+    $this->assertSession()->elementExists('xpath', $xpathViewRow)->press();
   }
 
   /**
@@ -117,7 +117,7 @@ public function testAjaxCommands() {
       ->elementExists('xpath', '//*[@data-drupal-selector="edit-show-selection"]');
 
     // Click on first entity Remove button.
-    $this->clickXpathSelector('//input[@data-row-id="0"]');
+    $this->assertSession()->elementExists('xpath', '//input[@data-row-id="0"]')->press();
     $this->waitSelectionDisplayAjaxCommands();
 
     // Check that action buttons are not there.
@@ -158,7 +158,7 @@ public function testAjaxCommands() {
 
     // Quickly remove all 5 entities.
     foreach (array_keys($entitiesToAdd) as $entityIndex) {
-      $this->clickXpathSelector('//input[@data-row-id="' . $entityIndex . '"]');
+      $this->assertSession()->elementExists('xpath', '//input[@data-row-id="' . $entityIndex . '"]')->press();
     }
     $this->waitSelectionDisplayAjaxCommands();
 
@@ -240,7 +240,7 @@ public function testAjaxCommands() {
     $this->openEntityBrowser();
 
     // Click on first entity Remove button.
-    $this->clickXpathSelector('//input[@data-row-id="0"]');
+    $this->assertSession()->elementExists('xpath', '//input[@data-row-id="0"]')->press();
     $this->waitSelectionDisplayAjaxCommands();
 
     $this->closeEntityBrowser();
diff --git a/web/modules/entity_browser/tests/src/FunctionalJavascript/PagerElementTest.php b/web/modules/entity_browser/tests/src/FunctionalJavascript/PagerElementTest.php
index 5e51f4a4c6121f2b348d21f5a483e7ac7026ade7..2569846b57d86f652a3a0f714050ee7d1c5a5696 100644
--- a/web/modules/entity_browser/tests/src/FunctionalJavascript/PagerElementTest.php
+++ b/web/modules/entity_browser/tests/src/FunctionalJavascript/PagerElementTest.php
@@ -11,7 +11,7 @@
  *
  * @group entity_browser
  */
-class PagerElementTest extends EntityBrowserJavascriptTestBase {
+class PagerElementTest extends EntityBrowserWebDriverTestBase {
 
   /**
    * Modules to enable.
@@ -44,7 +44,6 @@ protected function setUp() {
       ],
     ])->save();
 
-
     FieldConfig::create([
       'field_name' => 'field_reference_pager',
       'entity_type' => 'node',
diff --git a/web/modules/entity_browser/tests/src/FunctionalJavascript/ParagraphsTest.php b/web/modules/entity_browser/tests/src/FunctionalJavascript/ParagraphsTest.php
index f3d503647255ccd9578b50391b20988d94e616ca..1331801c4cf4ef56749df306e3fbf0c5609d8e69 100644
--- a/web/modules/entity_browser/tests/src/FunctionalJavascript/ParagraphsTest.php
+++ b/web/modules/entity_browser/tests/src/FunctionalJavascript/ParagraphsTest.php
@@ -7,13 +7,17 @@
  *
  * @group entity_browser
  */
-class ParagraphsTest extends EntityBrowserJavascriptTestBase {
+class ParagraphsTest extends EntityBrowserWebDriverTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'classy';
 
   /**
    * {@inheritdoc}
    */
   public static $modules = [
-    'ctools',
     'views',
     'block',
     'node',
diff --git a/web/modules/entity_browser/tests/src/FunctionalJavascript/PluginsTest.php b/web/modules/entity_browser/tests/src/FunctionalJavascript/PluginsTest.php
index d94946c8164f6b8ff4b7f9961a52c61cd6cb5827..1c8155d37da0c8a77ea700b806318754b8bffa36 100644
--- a/web/modules/entity_browser/tests/src/FunctionalJavascript/PluginsTest.php
+++ b/web/modules/entity_browser/tests/src/FunctionalJavascript/PluginsTest.php
@@ -2,12 +2,14 @@
 
 namespace Drupal\Tests\entity_browser\FunctionalJavascript;
 
+use Drupal\Core\Entity\Sql\SqlContentEntityStorageException;
+
 /**
  * Tests the entity_browser plugins.
  *
  * @group entity_browser
  */
-class PluginsTest extends EntityBrowserJavascriptTestBase {
+class PluginsTest extends EntityBrowserWebDriverTestBase {
 
   /**
    * Tests the Entity browser iframe display plugin.
@@ -26,7 +28,7 @@ public function testIframeDisplayPlugin() {
     $this->getSession()->getPage()->checkField('entity_browser_select[file:' . $image->id() . ']');
     $this->getSession()->getPage()->pressButton('Select entities');
     $this->getSession()->switchToIFrame();
-    $this->waitUntilVisible('.field--type-entity-reference .button');
+    $this->assertSession()->waitForElement('css', '.field--type-entity-reference .button');
     $this->assertSession()->pageTextContains('lama.jpg');
 
     // Tests upload widget on single display. Gets the upload widget and sets
@@ -43,7 +45,7 @@ public function testIframeDisplayPlugin() {
     $this->getSession()->getPage()->checkField('entity_browser_select[file:' . $image->id() . ']');
     $this->getSession()->getPage()->pressButton('Select entities');
     $this->getSession()->switchToIFrame();
-    $this->waitUntilVisible('.field--type-entity-reference .button');
+    $this->assertSession()->waitForElement('css', '.field--type-entity-reference .button');
     $this->assertSession()->pageTextContains('lama.jpg');
 
     // Tests view tab with tabs widget selector.
@@ -60,7 +62,7 @@ public function testIframeDisplayPlugin() {
     $this->getSession()->getPage()->checkField('entity_browser_select[file:' . $image->id() . ']');
     $this->getSession()->getPage()->pressButton('Select entities');
     $this->getSession()->switchToIFrame();
-    $this->waitUntilVisible('.field--type-entity-reference .button');
+    $this->assertSession()->waitForElement('css', '.field--type-entity-reference .button');
     $this->assertSession()->pageTextContains('lama.jpg');
 
     // Tests upload tab with tabs widget selector.
@@ -69,12 +71,14 @@ public function testIframeDisplayPlugin() {
     $this->getSession()->switchToIFrame('entity_browser_iframe_test_entity_browser_file');
     $this->clickLink('upload');
     $this->getSession()->getPage()->attachFileToField('edit-upload-upload', $this->container->get('file_system')->realpath($image->getFileUri()));
-    $this->waitForAjaxToFinish();
-    $this->getSession()->getPage()->checkField('upload[file_2][selected]');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $image2 = $this->getLastUploadedFile();
+    $this->assertEquals('lama_0.jpg', $image2->label());
+    $this->getSession()->getPage()->checkField('upload[file_' . $image2->id() . '][selected]');
     $this->getSession()->getPage()->pressButton('Select files');
     $this->getSession()->switchToIFrame();
-    $this->waitForAjaxToFinish();
-    $this->assertSession()->pageTextContains('lama.jpg');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->assertSession()->pageTextContains('lama_0.jpg');
     // Tests view widget with drop down widget selector.
     $this->getEntityBrowser('test_entity_browser_file', 'iframe', 'drop_down', 'no_display');
 
@@ -94,24 +98,25 @@ public function testIframeDisplayPlugin() {
     $this->getSession()->getPage()->checkField('entity_browser_select[file:' . $image->id() . ']');
     $this->getSession()->getPage()->pressButton('Select entities');
     $this->getSession()->switchToIFrame();
-    $this->waitUntilVisible('.field--type-entity-reference .button');
+    $this->assertSession()->waitForElement('css', '.field--type-entity-reference .button');
     $this->assertSession()->pageTextContains('lama.jpg');
 
-    // Tests upload vidget with drop down widget selector.
+    // Tests upload widget with drop down widget selector.
     $this->drupalGet('node/add/article');
 
     $this->getSession()->getPage()->clickLink('Select entities');
     $this->getSession()->switchToIFrame('entity_browser_iframe_test_entity_browser_file');
     $this->getSession()->getPage()->selectFieldOption('edit-widget', '2dc1ab07-2f8f-42c9-aab7-7eef7f8b7d87');
-    $this->waitForAjaxToFinish();
+    $this->assertSession()->assertWaitOnAjaxRequest();
     $this->getSession()->getPage()->attachFileToField('files[upload][]', $this->container->get('file_system')->realpath($image->getFileUri()));
-    $this->waitForAjaxToFinish();
-    $this->getSession()->getPage()->checkField('upload[file_3][selected]');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $image3 = $this->getLastUploadedFile();
+    $this->getSession()->getPage()->checkField('upload[file_' . $image3->id() . '][selected]');
     $this->getSession()->getPage()->pressButton('Select files');
     $this->getSession()->switchToIFrame();
-    $this->waitForAjaxToFinish();
+    $this->assertSession()->assertWaitOnAjaxRequest();
     // In iframe I get page not found, so this fails.
-    $this->assertSession()->pageTextContains('lama.jpg');
+    $this->assertSession()->pageTextContains($image3->label());
     // Tests view selection display.
     $view_configuration = [
       'view' => 'test_selection_display_view',
@@ -124,8 +129,8 @@ public function testIframeDisplayPlugin() {
     $this->getSession()->switchToIFrame('entity_browser_iframe_test_entity_browser_file');
 
     // Tests multistep selection display.
-    $image1 = $this->createFile('first_file');
-    $image2 = $this->createFile('second_file');
+    $dragon_image = $this->createFile('dragon');
+    $unicorn_image = $this->createFile('unicorn');
 
     $upload_widget = $browser->getWidget('2dc1ab07-2f8f-42c9-aab7-7eef7f8b7d87');
     $upload_widget->setWeight(-9);
@@ -148,25 +153,30 @@ public function testIframeDisplayPlugin() {
     $this->getSession()->getPage()->clickLink('Select entities');
     $this->getSession()->switchToIFrame('entity_browser_iframe_test_entity_browser_file');
 
-    $this->getSession()->getPage()->attachFileToField('files[upload][]', $this->container->get('file_system')->realpath($image1->getFileUri()));
-    $this->waitForAjaxToFinish();
+    $this->getSession()->getPage()->attachFileToField('files[upload][]', $this->container->get('file_system')->realpath($dragon_image->getFileUri()));
+    $this->assertSession()->assertWaitOnAjaxRequest();
     $this->getSession()->getPage()->pressButton('Select files');
 
-    $this->assertSession()->pageTextContains('first_file.jpg');
-    $this->assertSession()->pageTextNotContains('second_file.jpg');
+    $image4 = $this->getLastUploadedFile();
+    $this->assertEquals('dragon_0.jpg', $image4->label());
+
+    $this->assertSession()->pageTextContains('dragon_0.jpg');
+    $this->assertSession()->pageTextNotContains('unicorn.jpg');
 
     $this->getSession()->getPage()->clickLink('view');
-    // This shows page not found, which is caused by https://www.drupal.org/node/2771547
-    // Uncomment this hunk when a fix for that problem lands.
-    //$this->getSession()->getPage()->checkField('entity_browser_select[file:' . $image2->id() . ']');
-    //$this->getSession()->getPage()->pressButton('Select entities');
-    //$this->assertSession()->responseContains('edit-selected-items-2-1-remove-button');
-    //$this->assertSession()->responseContains('edit-selected-items-1-0-remove-button');
-    //$this->getSession()->getPage()->pressButton('Use selected');
-    //$this->getSession()->switchToIFrame();
-    //$this->waitForAjaxToFinish();
-    //$this->assertSession()->pageTextContains('first_file.jpg');
-    //$this->assertSession()->pageTextContains('second_file.jpg');
+
+    $this->assertSession()->waitForField('entity_browser_select[file:' . $unicorn_image->id() . ']')->check();
+    $this->getSession()->getPage()->pressButton('Select entities');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->assertSession()
+      ->waitForElement('css', '#edit-selected-items-2-1-remove-button');
+    $this->assertSession()
+      ->waitForElement('css', '#edit-selected-items-1-0-remove-button');
+    $this->getSession()->getPage()->pressButton('Use selected');
+    $this->getSession()->switchToIFrame();
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->assertSession()->pageTextContains('dragon_0.jpg');
+    $this->assertSession()->pageTextContains('unicorn.jpg');
   }
 
   /**
@@ -185,14 +195,15 @@ public function testModalDisplay() {
     $this->drupalGet('node/add/article');
     $this->assertSession()->buttonExists('Select entities');
     $this->getSession()->getPage()->pressButton('Select entities');
+    $this->assertSession()->assertWaitOnAjaxRequest();
     $this->getSession()->switchToIFrame('entity_browser_iframe_test_entity_browser_file');
 
     $this->getSession()->getPage()->checkField('entity_browser_select[file:' . $image->id() . ']');
     $this->getSession()->getPage()->pressButton('Select entities');
     $this->getSession()->switchToIFrame();
-    $this->waitForAjaxToFinish();
+    $this->assertSession()->assertWaitOnAjaxRequest();
 
-    $this->assertSession()->pageTextContains('lama.jpg');
+    $this->assertSession()->pageTextContains('lama');
   }
 
   /**
@@ -218,4 +229,31 @@ public function testStandaloneDisplay() {
     // subscriber that displays a message or something along those lines.
   }
 
+  /**
+   * Get the most recently uploaded file.
+   *
+   * @return \Drupal\file\FileInterface
+   *   File entity.
+   *
+   * @throws \Drupal\Core\Entity\Sql\SqlContentEntityStorageException
+   *   Thrown if no results from query.
+   */
+  protected function getLastUploadedFile() {
+
+    $entity_type_manager = \Drupal::service('entity_type.manager');
+
+    $results = $entity_type_manager
+      ->getStorage('file')->getQuery()
+      ->range(0, 1)
+      ->sort('fid', 'DESC')
+      ->execute();
+
+    if (!empty($results)) {
+      return $entity_type_manager->getStorage('file')->load(reset($results));
+    }
+    else {
+      throw new SqlContentEntityStorageException('File not found');
+    }
+  }
+
 }
diff --git a/web/modules/entity_browser/tests/src/FunctionalJavascript/UploadWidgetTest.php b/web/modules/entity_browser/tests/src/FunctionalJavascript/UploadWidgetTest.php
index b7bf839328f5b96cb0abc24c66433a4fa8c6ac72..6bf058510f87b787476866bea624ac0ccd4029f5 100644
--- a/web/modules/entity_browser/tests/src/FunctionalJavascript/UploadWidgetTest.php
+++ b/web/modules/entity_browser/tests/src/FunctionalJavascript/UploadWidgetTest.php
@@ -9,7 +9,7 @@
  *
  * @group entity_browser
  */
-class UploadWidgetTest extends EntityBrowserJavascriptTestBase {
+class UploadWidgetTest extends EntityBrowserWebDriverTestBase {
 
   /**
    * {@inheritdoc}
@@ -45,7 +45,6 @@ public function testUploadWidget() {
     $this->waitForAjaxToFinish();
     $this->assertSession()->fieldExists('druplicon.png');
     $page->pressButton('Select files');
-    $this->assertSession()->statusCodeEquals(200);
 
     // Check if the file was correctly uploaded to the EB destination.
     $this->assertFileExists('public://druplicon.png');
@@ -63,7 +62,6 @@ public function testUploadWidget() {
     $this->waitForAjaxToFinish();
     $this->assertSession()->fieldExists('druplicon.png');
     $page->pressButton('Fancy submit');
-    $this->assertSession()->statusCodeEquals(200);
 
     // Check if the file was correctly uploaded to the EB destination.
     $this->assertFileExists('public://some_location/druplicon.png');
diff --git a/web/modules/entity_browser/tests/src/Kernel/Extension/EntityBrowserTest.php b/web/modules/entity_browser/tests/src/Kernel/Extension/EntityBrowserTest.php
index d737f04e8149de1553c13e41804176e7014268c5..fbc4d105ce46e019135a31fb6e14b2ed6a6995f2 100644
--- a/web/modules/entity_browser/tests/src/Kernel/Extension/EntityBrowserTest.php
+++ b/web/modules/entity_browser/tests/src/Kernel/Extension/EntityBrowserTest.php
@@ -65,7 +65,7 @@ protected function setUp() {
     FileCacheFactory::setPrefix($this->randomString(4));
     parent::setUp();
 
-    $this->controller = $this->container->get('entity.manager')->getStorage('entity_browser');
+    $this->controller = $this->container->get('entity_type.manager')->getStorage('entity_browser');
     $this->widgetUUID = $this->container->get('uuid')->generate();
     $this->routeProvider = $this->container->get('router.route_provider');
 
@@ -127,7 +127,7 @@ protected function createTests() {
         $this->fail('An entity browser without required ' . $plugin_type . ' created with no exception thrown.');
       }
       catch (PluginException $e) {
-        $this->assertEquals('The "" plugin does not exist.', $e->getMessage(), 'An exception was thrown when an entity_browser was created without a ' . $plugin_type . ' plugin.');
+        $this->assertContains('The "" plugin does not exist.', $e->getMessage(), 'An exception was thrown when an entity_browser was created without a ' . $plugin_type . ' plugin.');
       }
     }
 
@@ -467,4 +467,41 @@ public function testValidators() {
     $this->assertEmpty($form_state->getErrors(), t('Validation succeeded where expected'));
   }
 
+  /**
+   * Tests view widget access.
+   */
+  public function testViewWidgetAccess() {
+    $this->installConfig(['entity_browser_test']);
+    $this->installEntitySchema('user');
+    $this->installEntitySchema('user_role');
+
+    /** @var \Drupal\entity_browser\EntityBrowserInterface $entity */
+    $entity = $this->controller->load('test_entity_browser_file');
+
+    $this->assertFalse($entity->getWidget('774798f1-5ec5-4b63-84bd-124cd51ec07d')->access()->isAllowed());
+
+    // Create a user that has permission to access the view and try with it.
+    /** @var \Drupal\user\RoleInterface $role */
+    $role = $this->container->get('entity_type.manager')
+      ->getStorage('user_role')
+      ->create([
+        'name' => $this->randomString(),
+        'id' => $this->randomMachineName(),
+      ]);
+    $role->grantPermission('access content');
+    $role->save();
+
+    $user = $this->container->get('entity_type.manager')
+      ->getStorage('user')
+      ->create([
+        'name' => $this->randomString(),
+        'mail' => 'info@example.com',
+        'roles' => $role->id(),
+      ]);
+    $user->save();
+    \Drupal::currentUser()->setAccount($user);
+
+    $this->assertTrue($entity->getWidget('774798f1-5ec5-4b63-84bd-124cd51ec07d')->access()->isAllowed());
+  }
+
 }