diff --git a/.opts.yml b/.opts.yml
index cdd0a544b2c5b8e454235963e9471fbe2735c74e..a4e61a67e6feee8922f7a873e368db88a4d2b3dc 100644
--- a/.opts.yml
+++ b/.opts.yml
@@ -9,13 +9,15 @@ upgrade_commands:
 
     # BEGIN: Remove in ISAICP-8376
     - vendor/bin/drush rdf_sync:synchronize node --bundle=solution,collection
-    # END: Remove in ISAICP-8376
-
     - vendor/bin/drush search-api:reset-tracker --yes
+    - vendor/bin/drush cr
+    - vendor/bin/drush search-api:index
+    # END: Remove in ISAICP-8376
     - vendor/bin/drush joinup:node-access-rebuild
     - vendor/bin/drush joinup:search-api-tasks
     - vendor/bin/drush joinup:unpublish-alert --category
-    - scripts/check_status_report.php
+    # TODO: Re-enable in ISAICP-9191.
+    # - scripts/check_status_report.php
   append:
     acceptance:
       - vendor/bin/drush joinup:acc
diff --git a/composer.json b/composer.json
index 0b470bba3c38e5ce91ec98f590e37c821a33e414..839c0f8aaa093ff9cbbf7a28671c14647136c927 100644
--- a/composer.json
+++ b/composer.json
@@ -351,6 +351,9 @@
                 "Populate link fields only with URI if value is a string @see https://github.com/jhedstrom/DrupalDriver/pull/267": "resources/patch/php/drupal/drupal-driver/267.diff",
                 "Update Datetime field handler to support both date and datetime fields @see https://github.com/jhedstrom/DrupalDriver/pull/235": "resources/patch/php/drupal/drupal-driver/235.patch"
             },
+            "drupal/dynamic_entity_reference": {
+                "Undefined array key on dependency removal @see https://www.drupal.org/i/3099176": "resources/patch/php/drupal/dynamic_entity_reference/3099176-3.x-16.diff"
+            },
             "drupal/embed_block": {
                 "Add support for Ckeditor 5. @see https://www.drupal.org/i/3316336": "resources/patch/php/drupal/embed_block/3316336.patch"
             },
diff --git a/composer.lock b/composer.lock
index d8cf273b2809e8fd5b61f43a8ac3486cf194f6c7..e7f9e469ae5c2800d3b946ce0d457bcc3af2b4c4 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": "70d4803e5a6ca475758c6bd3c84892ce",
+    "content-hash": "af7232c55db99ceff5b937afc56d875d",
     "packages": [
         {
             "name": "asm89/stack-cors",
diff --git a/config/sync/core.entity_form_display.message.group_content_subscription.default.yml b/config/sync/core.entity_form_display.message.group_content_subscription.default.yml
new file mode 100644
index 0000000000000000000000000000000000000000..90122cfc108abaf2c58e2d7d35b56c32d05d3a3b
--- /dev/null
+++ b/config/sync/core.entity_form_display.message.group_content_subscription.default.yml
@@ -0,0 +1,23 @@
+uuid: 5d66376f-c7f5-4892-91fa-e44987845724
+langcode: en
+status: true
+dependencies:
+  config:
+    - field.field.message.group_content_subscription.group_content
+    - message.template.group_content_subscription
+id: message.group_content_subscription.default
+targetEntityType: message
+bundle: group_content_subscription
+mode: default
+content:
+  group_content:
+    type: entity_reference_autocomplete
+    weight: 0
+    region: content
+    settings:
+      match_operator: CONTAINS
+      match_limit: 10
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+hidden: {  }
diff --git a/config/sync/core.entity_form_display.meta_entity.solution_settings.default.yml b/config/sync/core.entity_form_display.meta_entity.solution_settings.default.yml
index 77ea2ddc71eadfebfba117de4c57e9d5f7e35134..e5b6a627a9121ab536c53b36940962246b8d068d 100644
--- a/config/sync/core.entity_form_display.meta_entity.solution_settings.default.yml
+++ b/config/sync/core.entity_form_display.meta_entity.solution_settings.default.yml
@@ -4,7 +4,6 @@ status: true
 dependencies:
   config:
     - field.field.meta_entity.solution_settings.announcements_enabled
-    - field.field.meta_entity.solution_settings.field_ss_related_solutions
     - field.field.meta_entity.solution_settings.landing_page
     - field.field.meta_entity.solution_settings.metadata_banner_disabled
     - meta_entity.type.solution_settings
@@ -34,7 +33,6 @@ content:
       display_label: true
     third_party_settings: {  }
 hidden:
-  field_ss_related_solutions: true
   label: true
   path: true
   target: true
diff --git a/config/sync/core.entity_form_display.node.custom_page.default.yml b/config/sync/core.entity_form_display.node.custom_page.default.yml
index 8f445b7c7f4cd181ceb085468a78a02d514f5613..adacc8bcbd9513e974f21551c2494881b2aeab4c 100644
--- a/config/sync/core.entity_form_display.node.custom_page.default.yml
+++ b/config/sync/core.entity_form_display.node.custom_page.default.yml
@@ -3,6 +3,7 @@ langcode: en
 status: true
 dependencies:
   config:
+    - field.field.node.custom_page.abstract
     - field.field.node.custom_page.field_attachment
     - field.field.node.custom_page.field_custom_page_logo
     - field.field.node.custom_page.field_hide_title
@@ -25,16 +26,24 @@ targetEntityType: node
 bundle: custom_page
 mode: default
 content:
+  abstract:
+    type: string_textfield
+    weight: 1
+    region: content
+    settings:
+      size: 255
+      placeholder: ''
+    third_party_settings: {  }
   field_attachment:
     type: file_generic
-    weight: 7
+    weight: 8
     region: content
     settings:
       progress_indicator: throbber
     third_party_settings: {  }
   field_custom_page_logo:
     type: image_image
-    weight: 6
+    weight: 7
     region: content
     settings:
       progress_indicator: throbber
@@ -42,7 +51,7 @@ content:
     third_party_settings: {  }
   field_hide_title:
     type: boolean_checkbox
-    weight: 1
+    weight: 2
     region: content
     settings:
       display_label: true
@@ -51,7 +60,7 @@ content:
         switch: true
   field_keywords:
     type: string_textfield
-    weight: 5
+    weight: 6
     region: content
     settings:
       size: 60
@@ -59,42 +68,44 @@ content:
     third_party_settings: {  }
   field_paragraphs_body:
     type: layout_paragraphs
-    weight: 3
+    weight: 4
     region: content
     settings:
+      view_mode: default
       preview_view_mode: preview
+      form_display_mode: default
       nesting_depth: 0
       require_layouts: 1
       empty_message: ''
     third_party_settings: {  }
   field_state:
     type: state_machine_buttons
-    weight: 10
+    weight: 11
     region: content
     settings:
       use_transition_label: 1
     third_party_settings: {  }
   field_topic:
     type: options_select
-    weight: 4
+    weight: 5
     region: content
     settings: {  }
     third_party_settings: {  }
   langcode:
     type: language_select
-    weight: 2
+    weight: 3
     region: content
     settings:
       include_locked: true
     third_party_settings: {  }
   path:
     type: path
-    weight: 9
+    weight: 10
     region: content
     settings: {  }
     third_party_settings: {  }
   simple_sitemap:
-    weight: 11
+    weight: 12
     region: content
     settings: {  }
     third_party_settings: {  }
@@ -107,7 +118,7 @@ content:
       placeholder: ''
     third_party_settings: {  }
   url_redirects:
-    weight: 8
+    weight: 9
     region: content
     settings: {  }
     third_party_settings: {  }
diff --git a/config/sync/core.entity_view_display.message.group_content_subscription.default.yml b/config/sync/core.entity_view_display.message.group_content_subscription.default.yml
new file mode 100644
index 0000000000000000000000000000000000000000..32a8b0853b089c7f06db14397779afd122821f7d
--- /dev/null
+++ b/config/sync/core.entity_view_display.message.group_content_subscription.default.yml
@@ -0,0 +1,27 @@
+uuid: 2ae2b99e-ba6d-483f-bcb4-9afe6f0479e5
+langcode: en
+status: true
+dependencies:
+  config:
+    - field.field.message.group_content_subscription.group_content
+    - message.template.group_content_subscription
+id: message.group_content_subscription.default
+targetEntityType: message
+bundle: group_content_subscription
+mode: default
+content:
+  group_content:
+    type: entity_reference_label
+    label: above
+    settings:
+      link: true
+    third_party_settings: {  }
+    weight: 1
+    region: content
+  partial_0:
+    settings: {  }
+    third_party_settings: {  }
+    weight: 0
+    region: content
+hidden:
+  search_api_excerpt: true
diff --git a/config/sync/core.entity_view_display.message.group_content_subscription.mail_body.yml b/config/sync/core.entity_view_display.message.group_content_subscription.mail_body.yml
index 94b040f963b08a397b199dd4c2de39cde8e7624f..567c85cb07d57dc51c460b66b0105ef8f71a0c5c 100644
--- a/config/sync/core.entity_view_display.message.group_content_subscription.mail_body.yml
+++ b/config/sync/core.entity_view_display.message.group_content_subscription.mail_body.yml
@@ -4,80 +4,38 @@ status: true
 dependencies:
   config:
     - core.entity_view_mode.message.mail_body
-    - field.field.message.group_content_subscription.field_group_content
+    - field.field.message.group_content_subscription.group_content
     - message.template.group_content_subscription
   module:
-    - dynamic_entity_reference
-    - joinup
+    - field_delimiter
+    - field_formatter_range
+    - joinup_slick
+    - template_suggestion
 id: message.group_content_subscription.mail_body
 targetEntityType: message
 bundle: group_content_subscription
 mode: mail_body
 content:
-  field_group_content:
-    type: dynamic_entity_reference_entity_view
-    label: hidden
+  group_content:
+    type: entity_reference_entity_view
+    label: above
     settings:
-      node:
-        view_mode: digest_message
-      comment:
-        view_mode: default
-        link: false
-      menu_link_content:
-        view_mode: default
-        link: false
-      download_event:
-        view_mode: default
-        link: false
-      file:
-        view_mode: default
-        link: false
-      flagging:
-        view_mode: default
-        link: false
-      invitation:
-        view_mode: default
-        link: false
-      entity_legal_document_acceptance:
-        view_mode: default
-        link: false
-      entity_legal_document_version:
-        view_mode: default
-        link: false
-      message:
-        view_mode: default
-        link: false
-      meta_entity:
-        view_mode: default
-        link: false
-      ogmenu_instance:
-        view_mode: default
-        link: false
-      og_membership:
-        view_mode: default
-        link: false
-      redirect:
-        view_mode: default
-        link: false
-      remote_file:
-        view_mode: default
-        link: false
-      search_api_task:
-        view_mode: default
-        link: false
-      taxonomy_term:
-        view_mode: default
-        link: false
-      path_alias:
-        view_mode: default
-        link: false
-      user:
-        view_mode: default
-        link: false
+      view_mode: digest_message
+      link: false
     third_party_settings:
+      field_delimiter:
+        delimiter: ''
+      field_formatter_range:
+        order: 0
+        limit: 0
+        offset: 0
+      joinup_slick:
+        preset: ''
+        field_label: true
+        custom_label: ''
       template_suggestion:
         template_suggestion: bare
-    weight: 0
+    weight: 1
     region: content
   partial_1:
     weight: 0
diff --git a/config/sync/core.entity_view_display.message.group_content_subscription.mail_subject.yml b/config/sync/core.entity_view_display.message.group_content_subscription.mail_subject.yml
index c1c1bbd70e102e2c8bbf650874814a956fdcf2bd..1abb8935ebf280a719c2857d1efbb62d6e4de5a2 100644
--- a/config/sync/core.entity_view_display.message.group_content_subscription.mail_subject.yml
+++ b/config/sync/core.entity_view_display.message.group_content_subscription.mail_subject.yml
@@ -4,7 +4,7 @@ status: true
 dependencies:
   config:
     - core.entity_view_mode.message.mail_subject
-    - field.field.message.group_content_subscription.field_group_content
+    - field.field.message.group_content_subscription.group_content
     - message.template.group_content_subscription
 id: message.group_content_subscription.mail_subject
 targetEntityType: message
@@ -12,7 +12,7 @@ bundle: group_content_subscription
 mode: mail_subject
 content: {  }
 hidden:
-  field_group_content: true
+  group_content: true
   partial_0: true
   partial_1: true
   search_api_excerpt: true
diff --git a/config/sync/core.entity_view_display.meta_entity.solution_settings.default.yml b/config/sync/core.entity_view_display.meta_entity.solution_settings.default.yml
index ba9aa6164a74d82aabed455daeeb5a04fdce9c82..ab4aca2e077d5248ed149ec334051a96bf60216b 100644
--- a/config/sync/core.entity_view_display.meta_entity.solution_settings.default.yml
+++ b/config/sync/core.entity_view_display.meta_entity.solution_settings.default.yml
@@ -4,7 +4,6 @@ status: true
 dependencies:
   config:
     - field.field.meta_entity.solution_settings.announcements_enabled
-    - field.field.meta_entity.solution_settings.field_ss_related_solutions
     - field.field.meta_entity.solution_settings.landing_page
     - field.field.meta_entity.solution_settings.metadata_banner_disabled
     - meta_entity.type.solution_settings
@@ -71,7 +70,6 @@ content:
     region: content
 hidden:
   announcements_enabled: true
-  field_ss_related_solutions: true
   landing_page: true
   search_api_excerpt: true
   target: true
diff --git a/config/sync/core.entity_view_display.node.collection.default.yml b/config/sync/core.entity_view_display.node.collection.default.yml
index 78f0dc8a1d4bb4ad2ab8fe1b714cd03a2478895e..5da8665d7f39206d28c1fbd8f511e43617cbc670 100644
--- a/config/sync/core.entity_view_display.node.collection.default.yml
+++ b/config/sync/core.entity_view_display.node.collection.default.yml
@@ -196,41 +196,6 @@ third_party_settings:
                 entity: layout_builder.entity
             weight: 2
             additional: {  }
-          4839e041-a927-4fb3-9e5e-17a55224f6d4:
-            uuid: 4839e041-a927-4fb3-9e5e-17a55224f6d4
-            region: main
-            configuration:
-              id: 'field_block:node:collection:report'
-              label_display: '0'
-              context_mapping:
-                entity: layout_builder.entity
-              formatter:
-                type: link
-                label: hidden
-                settings:
-                  trim_length: 80
-                  url_only: false
-                  url_plain: false
-                  rel: ''
-                  target: ''
-                third_party_settings: {  }
-            weight: 3
-            additional: {  }
-          bf50413b-d9a3-43a9-a3b5-6067065e2f7a:
-            uuid: bf50413b-d9a3-43a9-a3b5-6067065e2f7a
-            region: main
-            configuration:
-              id: 'field_block:node:collection:og_group'
-              label_display: '0'
-              context_mapping:
-                entity: layout_builder.entity
-              formatter:
-                type: og_group_subscribe
-                label: above
-                settings: {  }
-                third_party_settings: {  }
-            weight: 4
-            additional: {  }
         third_party_settings: {  }
       -
         layout_id: layout_onecol
@@ -246,7 +211,7 @@ third_party_settings:
             content:
               region_id: null
               region_class_choose: null
-              region_classes: ''
+              region_classes: joinup-group--description
               region_styles: null
               region_data: null
         components:
diff --git a/config/sync/core.entity_view_display.node.custom_page.carousel.yml b/config/sync/core.entity_view_display.node.custom_page.carousel.yml
index 86a74706101dcb8749227f904984065f03bc9415..3cc0235e6a29957222d01d38407acf649d045e38 100644
--- a/config/sync/core.entity_view_display.node.custom_page.carousel.yml
+++ b/config/sync/core.entity_view_display.node.custom_page.carousel.yml
@@ -4,6 +4,7 @@ status: true
 dependencies:
   config:
     - core.entity_view_mode.node.carousel
+    - field.field.node.custom_page.abstract
     - field.field.node.custom_page.field_attachment
     - field.field.node.custom_page.field_custom_page_logo
     - field.field.node.custom_page.field_hide_title
@@ -16,8 +17,10 @@ dependencies:
     - responsive_image.styles.tile
   module:
     - field_delimiter
+    - field_fallback_formatter
     - field_formatter_range
     - field_group
+    - joinup_core
     - layout_builder
     - layout_paragraphs
     - link
@@ -53,6 +56,27 @@ targetEntityType: node
 bundle: custom_page
 mode: carousel
 content:
+  abstract:
+    type: field_fallback_formatter
+    label: hidden
+    settings:
+      main_field_formatter_id: string
+      main_field_formatter_settings:
+        link_to_entity: false
+      fallback_field_id: field_paragraphs_body
+      fallback_field_formatter_id: filtered_entity_reference_bundles
+      fallback_field_formatter_settings:
+        view_mode: tile
+        filtered_entity_bundles:
+          - simple_paragraph
+          - text
+        trim_length: 200
+        trim_chars: ...
+    third_party_settings:
+      template_suggestion:
+        template_suggestion: ''
+    weight: 2
+    region: content
   field_custom_page_logo:
     type: responsive_image
     label: hidden
diff --git a/config/sync/core.entity_view_display.node.custom_page.default.yml b/config/sync/core.entity_view_display.node.custom_page.default.yml
index 9e3e71922a0df3e5e5b4c0fbac7d866af6d21443..8d03527243da7fabf79bb19e3128979cc27eee0c 100644
--- a/config/sync/core.entity_view_display.node.custom_page.default.yml
+++ b/config/sync/core.entity_view_display.node.custom_page.default.yml
@@ -3,6 +3,7 @@ langcode: en
 status: true
 dependencies:
   config:
+    - field.field.node.custom_page.abstract
     - field.field.node.custom_page.field_attachment
     - field.field.node.custom_page.field_custom_page_logo
     - field.field.node.custom_page.field_hide_title
@@ -97,6 +98,7 @@ content:
     weight: 5
     region: content
 hidden:
+  abstract: true
   field_custom_page_logo: true
   field_hide_title: true
   field_keywords: true
diff --git a/config/sync/core.entity_view_display.node.custom_page.digest_message.yml b/config/sync/core.entity_view_display.node.custom_page.digest_message.yml
new file mode 100644
index 0000000000000000000000000000000000000000..0e123c11a0966a84a60c07abe1e122b7c5ed0d13
--- /dev/null
+++ b/config/sync/core.entity_view_display.node.custom_page.digest_message.yml
@@ -0,0 +1,83 @@
+uuid: 8551a877-e510-4cce-a7f5-1adc6ff20bd3
+langcode: en
+status: true
+dependencies:
+  config:
+    - core.entity_view_mode.node.digest_message
+    - field.field.node.custom_page.abstract
+    - field.field.node.custom_page.field_attachment
+    - field.field.node.custom_page.field_custom_page_logo
+    - field.field.node.custom_page.field_hide_title
+    - field.field.node.custom_page.field_keywords
+    - field.field.node.custom_page.field_paragraphs_body
+    - field.field.node.custom_page.field_state
+    - field.field.node.custom_page.field_topic
+    - field.field.node.custom_page.og_audience
+    - node.type.custom_page
+  module:
+    - field_fallback_formatter
+    - joinup_core
+    - link
+    - template_suggestion
+    - user
+id: node.custom_page.digest_message
+targetEntityType: node
+bundle: custom_page
+mode: digest_message
+content:
+  abstract:
+    type: field_fallback_formatter
+    label: hidden
+    settings:
+      main_field_formatter_id: string
+      main_field_formatter_settings:
+        link_to_entity: false
+      fallback_field_id: field_paragraphs_body
+      fallback_field_formatter_id: filtered_entity_reference_bundles
+      fallback_field_formatter_settings:
+        view_mode: message_digest
+        filtered_entity_bundles:
+          - simple_paragraph
+          - text
+        trim_length: 200
+        trim_chars: ...
+    third_party_settings:
+      template_suggestion:
+        template_suggestion: ''
+    weight: 1
+    region: content
+  flag_like:
+    settings: {  }
+    third_party_settings: {  }
+    weight: 10
+    region: content
+  links:
+    settings: {  }
+    third_party_settings: {  }
+    weight: 100
+    region: content
+  report:
+    type: link
+    label: hidden
+    settings:
+      trim_length: 80
+      url_only: false
+      url_plain: false
+      rel: ''
+      target: ''
+    third_party_settings: {  }
+    weight: 50
+    region: content
+hidden:
+  field_attachment: true
+  field_custom_page_logo: true
+  field_hide_title: true
+  field_keywords: true
+  field_paragraphs_body: true
+  field_state: true
+  field_topic: true
+  langcode: true
+  og_audience: true
+  published_at: true
+  search_api_excerpt: true
+  share_link: true
diff --git a/config/sync/core.entity_view_display.node.custom_page.highlighted.yml b/config/sync/core.entity_view_display.node.custom_page.highlighted.yml
new file mode 100644
index 0000000000000000000000000000000000000000..5d4e53ad4bf89cf5aea3bde03bcd337beba06559
--- /dev/null
+++ b/config/sync/core.entity_view_display.node.custom_page.highlighted.yml
@@ -0,0 +1,83 @@
+uuid: 0d0a3168-3657-461f-ac8e-a2efca96a2b1
+langcode: en
+status: true
+dependencies:
+  config:
+    - core.entity_view_mode.node.highlighted
+    - field.field.node.custom_page.abstract
+    - field.field.node.custom_page.field_attachment
+    - field.field.node.custom_page.field_custom_page_logo
+    - field.field.node.custom_page.field_hide_title
+    - field.field.node.custom_page.field_keywords
+    - field.field.node.custom_page.field_paragraphs_body
+    - field.field.node.custom_page.field_state
+    - field.field.node.custom_page.field_topic
+    - field.field.node.custom_page.og_audience
+    - node.type.custom_page
+  module:
+    - field_fallback_formatter
+    - joinup_core
+    - link
+    - template_suggestion
+    - user
+id: node.custom_page.highlighted
+targetEntityType: node
+bundle: custom_page
+mode: highlighted
+content:
+  abstract:
+    type: field_fallback_formatter
+    label: visually_hidden
+    settings:
+      main_field_formatter_id: string
+      main_field_formatter_settings:
+        link_to_entity: false
+      fallback_field_id: field_paragraphs_body
+      fallback_field_formatter_id: filtered_entity_reference_bundles
+      fallback_field_formatter_settings:
+        view_mode: tile
+        filtered_entity_bundles:
+          - simple_paragraph
+          - text
+        trim_length: 200
+        trim_chars: ...
+    third_party_settings:
+      template_suggestion:
+        template_suggestion: ''
+    weight: 1
+    region: content
+  flag_like:
+    settings: {  }
+    third_party_settings: {  }
+    weight: 10
+    region: content
+  links:
+    settings: {  }
+    third_party_settings: {  }
+    weight: 100
+    region: content
+  report:
+    type: link
+    label: hidden
+    settings:
+      trim_length: 80
+      url_only: false
+      url_plain: false
+      rel: ''
+      target: ''
+    third_party_settings: {  }
+    weight: 50
+    region: content
+hidden:
+  field_attachment: true
+  field_custom_page_logo: true
+  field_hide_title: true
+  field_keywords: true
+  field_paragraphs_body: true
+  field_state: true
+  field_topic: true
+  langcode: true
+  og_audience: true
+  published_at: true
+  search_api_excerpt: true
+  share_link: true
diff --git a/config/sync/core.entity_view_display.node.custom_page.moderation.yml b/config/sync/core.entity_view_display.node.custom_page.moderation.yml
new file mode 100644
index 0000000000000000000000000000000000000000..669a73d74b76e19612da7a800230687c1bba22fd
--- /dev/null
+++ b/config/sync/core.entity_view_display.node.custom_page.moderation.yml
@@ -0,0 +1,83 @@
+uuid: d82b9f89-be8b-4552-9642-75f4741457bb
+langcode: en
+status: true
+dependencies:
+  config:
+    - core.entity_view_mode.node.moderation
+    - field.field.node.custom_page.abstract
+    - field.field.node.custom_page.field_attachment
+    - field.field.node.custom_page.field_custom_page_logo
+    - field.field.node.custom_page.field_hide_title
+    - field.field.node.custom_page.field_keywords
+    - field.field.node.custom_page.field_paragraphs_body
+    - field.field.node.custom_page.field_state
+    - field.field.node.custom_page.field_topic
+    - field.field.node.custom_page.og_audience
+    - node.type.custom_page
+  module:
+    - field_fallback_formatter
+    - joinup_core
+    - link
+    - template_suggestion
+    - user
+id: node.custom_page.moderation
+targetEntityType: node
+bundle: custom_page
+mode: moderation
+content:
+  abstract:
+    type: field_fallback_formatter
+    label: hidden
+    settings:
+      main_field_formatter_id: string
+      main_field_formatter_settings:
+        link_to_entity: false
+      fallback_field_id: field_paragraphs_body
+      fallback_field_formatter_id: filtered_entity_reference_bundles
+      fallback_field_formatter_settings:
+        view_mode: tile
+        filtered_entity_bundles:
+          - simple_paragraph
+          - text
+        trim_length: 200
+        trim_chars: ...
+    third_party_settings:
+      template_suggestion:
+        template_suggestion: ''
+    weight: 1
+    region: content
+  flag_like:
+    settings: {  }
+    third_party_settings: {  }
+    weight: 10
+    region: content
+  links:
+    settings: {  }
+    third_party_settings: {  }
+    weight: 100
+    region: content
+  report:
+    type: link
+    label: hidden
+    settings:
+      trim_length: 80
+      url_only: false
+      url_plain: false
+      rel: ''
+      target: ''
+    third_party_settings: {  }
+    weight: 50
+    region: content
+hidden:
+  field_attachment: true
+  field_custom_page_logo: true
+  field_hide_title: true
+  field_keywords: true
+  field_paragraphs_body: true
+  field_state: true
+  field_topic: true
+  langcode: true
+  og_audience: true
+  published_at: true
+  search_api_excerpt: true
+  share_link: true
diff --git a/config/sync/core.entity_view_display.node.custom_page.view_mode_tile.yml b/config/sync/core.entity_view_display.node.custom_page.view_mode_tile.yml
index b470e0084caa85d178e8a3088a165ccadc912137..3635c84acc61bb38abf86486465da9c1d170c2d0 100644
--- a/config/sync/core.entity_view_display.node.custom_page.view_mode_tile.yml
+++ b/config/sync/core.entity_view_display.node.custom_page.view_mode_tile.yml
@@ -4,6 +4,7 @@ status: true
 dependencies:
   config:
     - core.entity_view_mode.node.view_mode_tile
+    - field.field.node.custom_page.abstract
     - field.field.node.custom_page.field_attachment
     - field.field.node.custom_page.field_custom_page_logo
     - field.field.node.custom_page.field_hide_title
@@ -16,6 +17,7 @@ dependencies:
     - responsive_image.styles.tile
   module:
     - field_delimiter
+    - field_fallback_formatter
     - field_formatter_range
     - joinup_core
     - responsive_image
@@ -28,6 +30,27 @@ targetEntityType: node
 bundle: custom_page
 mode: view_mode_tile
 content:
+  abstract:
+    type: field_fallback_formatter
+    label: hidden
+    settings:
+      main_field_formatter_id: string
+      main_field_formatter_settings:
+        link_to_entity: false
+      fallback_field_id: field_paragraphs_body
+      fallback_field_formatter_id: filtered_entity_reference_bundles
+      fallback_field_formatter_settings:
+        view_mode: tile
+        filtered_entity_bundles:
+          - simple_paragraph
+          - text
+        trim_length: 200
+        trim_chars: ...
+    third_party_settings:
+      template_suggestion:
+        template_suggestion: ''
+    weight: 1
+    region: content
   field_custom_page_logo:
     type: responsive_image
     label: hidden
diff --git a/config/sync/core.entity_view_display.node.custom_page.view_mode_tile_horizontal.yml b/config/sync/core.entity_view_display.node.custom_page.view_mode_tile_horizontal.yml
index 51be1429920651684b737840f9ccc826dd0aa191..525d15d14ed4b33789d895a99615074f9e4acac9 100644
--- a/config/sync/core.entity_view_display.node.custom_page.view_mode_tile_horizontal.yml
+++ b/config/sync/core.entity_view_display.node.custom_page.view_mode_tile_horizontal.yml
@@ -4,6 +4,7 @@ status: true
 dependencies:
   config:
     - core.entity_view_mode.node.view_mode_tile_horizontal
+    - field.field.node.custom_page.abstract
     - field.field.node.custom_page.field_attachment
     - field.field.node.custom_page.field_custom_page_logo
     - field.field.node.custom_page.field_hide_title
@@ -16,6 +17,7 @@ dependencies:
     - responsive_image.styles.tile
   module:
     - field_delimiter
+    - field_fallback_formatter
     - field_formatter_range
     - field_group
     - joinup_core
@@ -52,6 +54,27 @@ targetEntityType: node
 bundle: custom_page
 mode: view_mode_tile_horizontal
 content:
+  abstract:
+    type: field_fallback_formatter
+    label: hidden
+    settings:
+      main_field_formatter_id: string
+      main_field_formatter_settings:
+        link_to_entity: false
+      fallback_field_id: field_paragraphs_body
+      fallback_field_formatter_id: filtered_entity_reference_bundles
+      fallback_field_formatter_settings:
+        view_mode: tile
+        filtered_entity_bundles:
+          - simple_paragraph
+          - text
+        trim_length: 200
+        trim_chars: ...
+    third_party_settings:
+      template_suggestion:
+        template_suggestion: ''
+    weight: 1
+    region: content
   field_custom_page_logo:
     type: responsive_image
     label: hidden
diff --git a/config/sync/core.entity_view_display.node.solution.default.yml b/config/sync/core.entity_view_display.node.solution.default.yml
index ab65141baa6a7a996d63f5722e45731c145c2934..d767024957f7fc0f804c3ed7a6002369f210f432 100644
--- a/config/sync/core.entity_view_display.node.solution.default.yml
+++ b/config/sync/core.entity_view_display.node.solution.default.yml
@@ -36,7 +36,6 @@ dependencies:
     - custom_markup_block
     - joinup_group
     - joinup_layout
-    - joinup_solution
     - layout_builder
     - layout_discovery
     - link
@@ -264,6 +263,588 @@ third_party_settings:
                 third_party_settings: {  }
             weight: 6
             additional: {  }
+          14a4d72e-529d-4229-bd23-c3a0d7e43e99:
+            uuid: 14a4d72e-529d-4229-bd23-c3a0d7e43e99
+            region: content
+            configuration:
+              id: 'field_block:node:solution:distributions'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+              formatter:
+                type: entity_reference_entity_view
+                label: hidden
+                settings:
+                  view_mode: default
+                  link: false
+                third_party_settings: {  }
+            weight: 7
+            additional: {  }
+          8b2ed21f-680b-4936-8d1b-eee9b8911827:
+            uuid: 8b2ed21f-680b-4936-8d1b-eee9b8911827
+            region: content
+            configuration:
+              id: 'field_block:node:solution:og_group'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+              formatter:
+                type: og_group_subscribe
+                label: above
+                settings: {  }
+                third_party_settings: {  }
+            weight: 8
+            additional: {  }
+          dee50d99-1041-489a-9174-b6bbfeb9ee95:
+            uuid: dee50d99-1041-489a-9174-b6bbfeb9ee95
+            region: content
+            configuration:
+              id: 'extra_field_block:node:solution:flag_interoperability'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+            weight: 9
+            additional: {  }
+          023f2883-4560-4c0c-8998-298008c7715e:
+            uuid: 023f2883-4560-4c0c-8998-298008c7715e
+            region: content
+            configuration:
+              id: 'extra_field_block:node:solution:flag_like'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+            weight: 10
+            additional: {  }
+          acb8b906-f0f3-4a91-8694-4d0360455b65:
+            uuid: acb8b906-f0f3-4a91-8694-4d0360455b65
+            region: content
+            configuration:
+              id: 'field_block:node:solution:report'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+              formatter:
+                type: link
+                label: hidden
+                settings:
+                  trim_length: 80
+                  url_only: false
+                  url_plain: false
+                  rel: ''
+                  target: ''
+                third_party_settings: {  }
+            weight: 11
+            additional: {  }
+          189fc1e6-75d6-471f-9a50-351bb20f78d5:
+            uuid: 189fc1e6-75d6-471f-9a50-351bb20f78d5
+            region: content
+            configuration:
+              id: 'extra_field_block:node:solution:links'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+            weight: 12
+            additional: {  }
+          12cbfa01-3b56-4813-90c7-a7e9e484f202:
+            uuid: 12cbfa01-3b56-4813-90c7-a7e9e484f202
+            region: content
+            configuration:
+              id: 'field_block:node:solution:body'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+              formatter:
+                type: text_default
+                label: hidden
+                settings: {  }
+                third_party_settings: {  }
+            weight: 13
+            additional: {  }
+          834bd3b8-603d-40e6-948c-2b01da4f009a:
+            uuid: 834bd3b8-603d-40e6-948c-2b01da4f009a
+            region: content
+            configuration:
+              id: 'field_block:node:solution:distributions'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+              formatter:
+                type: entity_reference_entity_view
+                label: hidden
+                settings:
+                  view_mode: default
+                  link: false
+                third_party_settings: {  }
+            weight: 14
+            additional: {  }
+          bad82f52-ffda-4cf8-834e-0038230b97d0:
+            uuid: bad82f52-ffda-4cf8-834e-0038230b97d0
+            region: content
+            configuration:
+              id: 'field_block:node:solution:og_group'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+              formatter:
+                type: og_group_subscribe
+                label: above
+                settings: {  }
+                third_party_settings: {  }
+            weight: 15
+            additional: {  }
+          ef172e7d-6da5-4c6a-b554-497e1188805a:
+            uuid: ef172e7d-6da5-4c6a-b554-497e1188805a
+            region: content
+            configuration:
+              id: 'extra_field_block:node:solution:flag_interoperability'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+            weight: 16
+            additional: {  }
+          b353e8f2-7ad3-47b5-aaa1-337b488167d9:
+            uuid: b353e8f2-7ad3-47b5-aaa1-337b488167d9
+            region: content
+            configuration:
+              id: 'extra_field_block:node:solution:flag_like'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+            weight: 17
+            additional: {  }
+          cc91a22d-f683-4cff-a92d-3509c53c1f1b:
+            uuid: cc91a22d-f683-4cff-a92d-3509c53c1f1b
+            region: content
+            configuration:
+              id: 'field_block:node:solution:report'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+              formatter:
+                type: link
+                label: hidden
+                settings:
+                  trim_length: 80
+                  url_only: false
+                  url_plain: false
+                  rel: ''
+                  target: ''
+                third_party_settings: {  }
+            weight: 18
+            additional: {  }
+          6624d55e-79c6-4665-b12c-924c1f3f4ff5:
+            uuid: 6624d55e-79c6-4665-b12c-924c1f3f4ff5
+            region: content
+            configuration:
+              id: 'extra_field_block:node:solution:links'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+            weight: 19
+            additional: {  }
+          23ac6adf-4e6d-44e3-b199-261e6339c449:
+            uuid: 23ac6adf-4e6d-44e3-b199-261e6339c449
+            region: content
+            configuration:
+              id: 'field_block:node:solution:body'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+              formatter:
+                type: text_default
+                label: hidden
+                settings: {  }
+                third_party_settings: {  }
+            weight: 20
+            additional: {  }
+          d6055141-de81-4e91-99ad-0a35a89881ca:
+            uuid: d6055141-de81-4e91-99ad-0a35a89881ca
+            region: content
+            configuration:
+              id: 'field_block:node:solution:distributions'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+              formatter:
+                type: entity_reference_entity_view
+                label: hidden
+                settings:
+                  view_mode: default
+                  link: false
+                third_party_settings: {  }
+            weight: 21
+            additional: {  }
+          a9c53846-9e9d-40e3-89e4-e2f553740cc2:
+            uuid: a9c53846-9e9d-40e3-89e4-e2f553740cc2
+            region: content
+            configuration:
+              id: 'field_block:node:solution:og_group'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+              formatter:
+                type: og_group_subscribe
+                label: above
+                settings: {  }
+                third_party_settings: {  }
+            weight: 22
+            additional: {  }
+          96609ced-d2d2-40f6-b6ac-472405e55b05:
+            uuid: 96609ced-d2d2-40f6-b6ac-472405e55b05
+            region: content
+            configuration:
+              id: 'extra_field_block:node:solution:flag_interoperability'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+            weight: 23
+            additional: {  }
+          4a6b2fd3-a471-4387-85b9-6056e6d017a0:
+            uuid: 4a6b2fd3-a471-4387-85b9-6056e6d017a0
+            region: content
+            configuration:
+              id: 'extra_field_block:node:solution:flag_like'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+            weight: 24
+            additional: {  }
+          bd056cdb-bb31-4e10-b1f4-367c349101b7:
+            uuid: bd056cdb-bb31-4e10-b1f4-367c349101b7
+            region: content
+            configuration:
+              id: 'field_block:node:solution:report'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+              formatter:
+                type: link
+                label: hidden
+                settings:
+                  trim_length: 80
+                  url_only: false
+                  url_plain: false
+                  rel: ''
+                  target: ''
+                third_party_settings: {  }
+            weight: 25
+            additional: {  }
+          86230802-c674-41ac-9d5c-29779bc00fb5:
+            uuid: 86230802-c674-41ac-9d5c-29779bc00fb5
+            region: content
+            configuration:
+              id: 'extra_field_block:node:solution:links'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+            weight: 26
+            additional: {  }
+          7f4bf789-cde9-4f6e-a9e9-4054cd843f68:
+            uuid: 7f4bf789-cde9-4f6e-a9e9-4054cd843f68
+            region: content
+            configuration:
+              id: 'field_block:node:solution:body'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+              formatter:
+                type: text_default
+                label: hidden
+                settings: {  }
+                third_party_settings: {  }
+            weight: 27
+            additional: {  }
+          c8909e14-697f-445f-8f0c-22d3669ad822:
+            uuid: c8909e14-697f-445f-8f0c-22d3669ad822
+            region: content
+            configuration:
+              id: 'field_block:node:solution:distributions'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+              formatter:
+                type: entity_reference_entity_view
+                label: hidden
+                settings:
+                  view_mode: default
+                  link: false
+                third_party_settings: {  }
+            weight: 28
+            additional: {  }
+          e0f2b900-0797-49d2-9dd7-4d9e114b1b74:
+            uuid: e0f2b900-0797-49d2-9dd7-4d9e114b1b74
+            region: content
+            configuration:
+              id: 'field_block:node:solution:og_group'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+              formatter:
+                type: og_group_subscribe
+                label: above
+                settings: {  }
+                third_party_settings: {  }
+            weight: 29
+            additional: {  }
+          390b1c71-47b9-4268-b5a3-2dfccf963034:
+            uuid: 390b1c71-47b9-4268-b5a3-2dfccf963034
+            region: content
+            configuration:
+              id: 'extra_field_block:node:solution:flag_interoperability'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+            weight: 30
+            additional: {  }
+          f57e29aa-3ece-4d54-bdfd-8f1600579a33:
+            uuid: f57e29aa-3ece-4d54-bdfd-8f1600579a33
+            region: content
+            configuration:
+              id: 'extra_field_block:node:solution:flag_like'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+            weight: 31
+            additional: {  }
+          96cd163a-2569-4120-975f-d86137a99bde:
+            uuid: 96cd163a-2569-4120-975f-d86137a99bde
+            region: content
+            configuration:
+              id: 'field_block:node:solution:report'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+              formatter:
+                type: link
+                label: hidden
+                settings:
+                  trim_length: 80
+                  url_only: false
+                  url_plain: false
+                  rel: ''
+                  target: ''
+                third_party_settings: {  }
+            weight: 32
+            additional: {  }
+          1752c407-61f3-4235-af2a-e10959dcf971:
+            uuid: 1752c407-61f3-4235-af2a-e10959dcf971
+            region: content
+            configuration:
+              id: 'extra_field_block:node:solution:links'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+            weight: 33
+            additional: {  }
+          cf9048b9-8f1c-40a6-952b-0820d7fb24c1:
+            uuid: cf9048b9-8f1c-40a6-952b-0820d7fb24c1
+            region: content
+            configuration:
+              id: 'field_block:node:solution:body'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+              formatter:
+                type: text_default
+                label: hidden
+                settings: {  }
+                third_party_settings: {  }
+            weight: 34
+            additional: {  }
+          df1a66dd-c335-42d0-82c7-a16ca7bc5add:
+            uuid: df1a66dd-c335-42d0-82c7-a16ca7bc5add
+            region: content
+            configuration:
+              id: 'field_block:node:solution:distributions'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+              formatter:
+                type: entity_reference_entity_view
+                label: hidden
+                settings:
+                  view_mode: default
+                  link: false
+                third_party_settings: {  }
+            weight: 35
+            additional: {  }
+          982267e6-4ff5-42b3-b11a-6f1f8f78b651:
+            uuid: 982267e6-4ff5-42b3-b11a-6f1f8f78b651
+            region: content
+            configuration:
+              id: 'field_block:node:solution:og_group'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+              formatter:
+                type: og_group_subscribe
+                label: above
+                settings: {  }
+                third_party_settings: {  }
+            weight: 36
+            additional: {  }
+          cc842f3c-b39c-434e-ab5f-3ce611056acf:
+            uuid: cc842f3c-b39c-434e-ab5f-3ce611056acf
+            region: content
+            configuration:
+              id: 'extra_field_block:node:solution:flag_interoperability'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+            weight: 37
+            additional: {  }
+          df7f8469-73b4-4b86-8a8f-78700f39f342:
+            uuid: df7f8469-73b4-4b86-8a8f-78700f39f342
+            region: content
+            configuration:
+              id: 'extra_field_block:node:solution:flag_like'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+            weight: 38
+            additional: {  }
+          cb445585-c83e-4080-94eb-fa790543a55e:
+            uuid: cb445585-c83e-4080-94eb-fa790543a55e
+            region: content
+            configuration:
+              id: 'field_block:node:solution:report'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+              formatter:
+                type: link
+                label: hidden
+                settings:
+                  trim_length: 80
+                  url_only: false
+                  url_plain: false
+                  rel: ''
+                  target: ''
+                third_party_settings: {  }
+            weight: 39
+            additional: {  }
+          57184583-0b80-448f-b2ac-70e62ef39e58:
+            uuid: 57184583-0b80-448f-b2ac-70e62ef39e58
+            region: content
+            configuration:
+              id: 'extra_field_block:node:solution:links'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+            weight: 40
+            additional: {  }
+          b080faf6-9415-4cc3-9f1d-7f3613b8d9f6:
+            uuid: b080faf6-9415-4cc3-9f1d-7f3613b8d9f6
+            region: content
+            configuration:
+              id: 'field_block:node:solution:body'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+              formatter:
+                type: text_default
+                label: hidden
+                settings: {  }
+                third_party_settings: {  }
+            weight: 41
+            additional: {  }
+          0d0e26dc-6faf-4acb-8dab-409c853e40c7:
+            uuid: 0d0e26dc-6faf-4acb-8dab-409c853e40c7
+            region: content
+            configuration:
+              id: 'field_block:node:solution:distributions'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+              formatter:
+                type: entity_reference_entity_view
+                label: hidden
+                settings:
+                  view_mode: default
+                  link: false
+                third_party_settings: {  }
+            weight: 42
+            additional: {  }
+          83aa1113-c4a9-4236-92c8-db0ac935afa8:
+            uuid: 83aa1113-c4a9-4236-92c8-db0ac935afa8
+            region: content
+            configuration:
+              id: 'field_block:node:solution:og_group'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+              formatter:
+                type: og_group_subscribe
+                label: above
+                settings: {  }
+                third_party_settings: {  }
+            weight: 43
+            additional: {  }
+          d7142848-3709-4066-8398-6612953b3d55:
+            uuid: d7142848-3709-4066-8398-6612953b3d55
+            region: content
+            configuration:
+              id: 'extra_field_block:node:solution:flag_interoperability'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+            weight: 44
+            additional: {  }
+          04e5f5bd-e44e-45b5-9cef-7d1120b9613f:
+            uuid: 04e5f5bd-e44e-45b5-9cef-7d1120b9613f
+            region: content
+            configuration:
+              id: 'extra_field_block:node:solution:flag_like'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+            weight: 45
+            additional: {  }
+          fd54982c-31a9-4e86-9f1b-aa1ebf79a55c:
+            uuid: fd54982c-31a9-4e86-9f1b-aa1ebf79a55c
+            region: content
+            configuration:
+              id: 'field_block:node:solution:report'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+              formatter:
+                type: link
+                label: hidden
+                settings:
+                  trim_length: 80
+                  url_only: false
+                  url_plain: false
+                  rel: ''
+                  target: ''
+                third_party_settings: {  }
+            weight: 46
+            additional: {  }
+          d7aad59a-8d37-48a6-b366-c912439cc40d:
+            uuid: d7aad59a-8d37-48a6-b366-c912439cc40d
+            region: content
+            configuration:
+              id: 'extra_field_block:node:solution:links'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+            weight: 47
+            additional: {  }
+          926a410e-66ff-4350-8cb5-a0dbcec4d16e:
+            uuid: 926a410e-66ff-4350-8cb5-a0dbcec4d16e
+            region: content
+            configuration:
+              id: 'field_block:node:solution:body'
+              label_display: '0'
+              context_mapping:
+                entity: layout_builder.entity
+              formatter:
+                type: text_default
+                label: hidden
+                settings: {  }
+                third_party_settings: {  }
+            weight: 48
+            additional: {  }
         third_party_settings: {  }
       -
         layout_id: layout_onecol
@@ -698,33 +1279,6 @@ third_party_settings:
                   class: ''
                   style: ''
                   data: ''
-          f4851cf0-344c-45bd-b61a-dd69097ee30d:
-            uuid: f4851cf0-344c-45bd-b61a-dd69097ee30d
-            region: content
-            configuration:
-              id: solution_release_date
-              label: 'Release date'
-              label_display: '0'
-              provider: joinup_solution
-              context_mapping: {  }
-            weight: 10
-            additional:
-              component_attributes:
-                block_attributes:
-                  id: ''
-                  class: 'pe-5 pb-4'
-                  style: ''
-                  data: ''
-                block_title_attributes:
-                  id: ''
-                  class: ''
-                  style: ''
-                  data: ''
-                block_content_attributes:
-                  id: ''
-                  class: ''
-                  style: ''
-                  data: ''
           62807d5d-f198-4b51-9b19-926f89c108d5:
             uuid: 62807d5d-f198-4b51-9b19-926f89c108d5
             region: content
@@ -905,7 +1459,23 @@ third_party_settings:
                 settings: {  }
                 third_party_settings: {  }
             weight: 0
-            additional: {  }
+            additional:
+              component_attributes:
+                block_attributes:
+                  id: ''
+                  class: 'd-flex justify-content-end'
+                  style: ''
+                  data: ''
+                block_title_attributes:
+                  id: ''
+                  class: ''
+                  style: ''
+                  data: ''
+                block_content_attributes:
+                  id: ''
+                  class: ''
+                  style: ''
+                  data: ''
         third_party_settings: {  }
 id: node.solution.default
 targetEntityType: node
diff --git a/config/sync/core.entity_view_display.paragraph.iframe.default.yml b/config/sync/core.entity_view_display.paragraph.iframe.default.yml
index 10b8ff598904081f4d12e99c5bf24af9d78f08d6..396f1dfc30d863c45abd0bbf732d7462b8480df0 100644
--- a/config/sync/core.entity_view_display.paragraph.iframe.default.yml
+++ b/config/sync/core.entity_view_display.paragraph.iframe.default.yml
@@ -6,7 +6,7 @@ dependencies:
     - field.field.paragraph.iframe.field_iframe
     - paragraphs.paragraphs_type.iframe
   module:
-    - iframe
+    - joinup_core
     - template_suggestion
 id: paragraph.iframe.default
 targetEntityType: paragraph
@@ -14,11 +14,12 @@ bundle: iframe
 mode: default
 content:
   field_iframe:
-    type: iframe_only
+    type: iframe_with_consent_declaration
     label: hidden
     settings:
       url: ''
       title: ''
+      headerlevel: '3'
       class: ''
       frameborder: '0'
       scrolling: ''
diff --git a/config/sync/field.field.message.group_content_subscription.field_group_content.yml b/config/sync/field.field.message.group_content_subscription.field_group_content.yml
deleted file mode 100644
index bc61bda5f6cd661e559b986054913c2c761318b8..0000000000000000000000000000000000000000
--- a/config/sync/field.field.message.group_content_subscription.field_group_content.yml
+++ /dev/null
@@ -1,325 +0,0 @@
-uuid: 694783ee-9f36-41ed-8fd9-51696b1bcd94
-langcode: en
-status: true
-dependencies:
-  config:
-    - field.storage.message.field_group_content
-    - message.template.group_content_subscription
-    - node.type.discussion
-    - node.type.document
-    - node.type.event
-    - node.type.news
-    - node.type.solution
-  module:
-    - dynamic_entity_reference
-id: message.group_content_subscription.field_group_content
-field_name: field_group_content
-entity_type: message
-bundle: group_content_subscription
-label: 'Group content'
-description: ''
-required: true
-translatable: false
-default_value: {  }
-default_value_callback: ''
-settings:
-  node:
-    handler: 'default:node'
-    handler_settings:
-      target_bundles:
-        discussion: discussion
-        document: document
-        event: event
-        news: news
-        solution: solution
-      sort:
-        field: _none
-        direction: ASC
-      auto_create: false
-      auto_create_bundle: discussion
-  block:
-    handler: 'default:block'
-    handler_settings: {  }
-  comment:
-    handler: 'default:comment'
-    handler_settings: {  }
-  comment_type:
-    handler: 'default:comment_type'
-    handler_settings: {  }
-  editor:
-    handler: 'default:editor'
-    handler_settings: {  }
-  email_confirmer_confirmation:
-    handler: 'default:email_confirmer_confirmation'
-    handler_settings: {  }
-  email_confirmer_message:
-    handler: 'default:email_confirmer_message'
-    handler_settings: {  }
-  entity_legal_document_acceptance:
-    handler: 'default:entity_legal_document_acceptance'
-    handler_settings: {  }
-  entity_legal_document:
-    handler: 'default:entity_legal_document'
-    handler_settings: {  }
-  entity_legal_document_version:
-    handler: 'default:entity_legal_document_version'
-    handler_settings: {  }
-  entity_queue:
-    handler: 'default:entity_queue'
-    handler_settings: {  }
-  entity_subqueue:
-    handler: 'default:entity_subqueue'
-    handler_settings: {  }
-  hosting_platform:
-    handler: 'default:hosting_platform'
-    handler_settings: {  }
-  facets_facet:
-    handler: 'default:facets_facet'
-    handler_settings: {  }
-  facets_facet_source:
-    handler: 'default:facets_facet_source'
-    handler_settings: {  }
-  facets_summary:
-    handler: 'default:facets_summary'
-    handler_settings: {  }
-  field_config:
-    handler: 'default:field_config'
-    handler_settings: {  }
-  field_storage_config:
-    handler: 'default:field_storage_config'
-    handler_settings: {  }
-  file:
-    handler: 'default:file'
-    handler_settings: {  }
-  remote_file:
-    handler: 'default:remote_file'
-    handler_settings: {  }
-  filter_format:
-    handler: 'default:filter_format'
-    handler_settings: {  }
-  flagging:
-    handler: 'default:flagging'
-    handler_settings: {  }
-  flag:
-    handler: 'default:flag'
-    handler_settings: {  }
-  geocoder_provider:
-    handler: 'default:geocoder_provider'
-    handler_settings: {  }
-  image_style:
-    handler: 'default:image_style'
-    handler_settings: {  }
-  download_event:
-    handler: 'default:download_event'
-    handler_settings: {  }
-  invitation:
-    handler: 'default:invitation'
-    handler_settings: {  }
-  invitation_type:
-    handler: 'default:invitation_type'
-    handler_settings: {  }
-  compatibility_document:
-    handler: 'default:compatibility_document'
-    handler_settings: {  }
-  joinup_log:
-    handler: 'default:joinup_log'
-    handler_settings: {  }
-  language_content_settings:
-    handler: 'default:language_content_settings'
-    handler_settings: {  }
-  configurable_language:
-    handler: 'default:configurable_language'
-    handler_settings: {  }
-  linkit_profile:
-    handler: 'default:linkit_profile'
-    handler_settings: {  }
-  media:
-    handler: 'default:media'
-    handler_settings: {  }
-  media_type:
-    handler: 'default:media_type'
-    handler_settings: {  }
-  message:
-    handler: 'default:message'
-    handler_settings: {  }
-  message_template:
-    handler: 'default:message_template'
-    handler_settings: {  }
-  message_digest_interval:
-    handler: 'default:message_digest_interval'
-    handler_settings: {  }
-  meta_entity_type:
-    handler: 'default:meta_entity_type'
-    handler_settings: {  }
-  meta_entity:
-    handler: 'default:meta_entity'
-    handler_settings: {  }
-  metatag_defaults:
-    handler: 'default:metatag_defaults'
-    handler_settings: {  }
-  node_type:
-    handler: 'default:node_type'
-    handler_settings: {  }
-  og_role:
-    handler: 'default:og_role'
-    handler_settings: {  }
-  og_membership_type:
-    handler: 'default:og_membership_type'
-    handler_settings: {  }
-  og_membership:
-    handler: 'default:og_membership'
-    handler_settings: {  }
-  ogmenu_instance:
-    handler: 'default:ogmenu_instance'
-    handler_settings: {  }
-  ogmenu:
-    handler: 'default:ogmenu'
-    handler_settings: {  }
-  page:
-    handler: 'default:page'
-    handler_settings: {  }
-  page_variant:
-    handler: 'default:page_variant'
-    handler_settings: {  }
-  path_alias:
-    handler: 'default:path_alias'
-    handler_settings: {  }
-  poll:
-    handler: 'default:poll'
-    handler_settings: {  }
-  poll_choice:
-    handler: 'default:poll_choice'
-    handler_settings: {  }
-  redirect:
-    handler: 'default:redirect'
-    handler_settings: {  }
-  responsive_image_style:
-    handler: 'default:responsive_image_style'
-    handler_settings: {  }
-  rest_resource_config:
-    handler: 'default:rest_resource_config'
-    handler_settings: {  }
-  search_api_server:
-    handler: 'default:search_api_server'
-    handler_settings: {  }
-  search_api_index:
-    handler: 'default:search_api_index'
-    handler_settings: {  }
-  search_api_task:
-    handler: 'default:search_api_task'
-    handler_settings: {  }
-  search_api_autocomplete_search:
-    handler: 'default:search_api_autocomplete_search'
-    handler_settings: {  }
-  solr_request_handler:
-    handler: 'default:solr_request_handler'
-    handler_settings: {  }
-  solr_request_dispatcher:
-    handler: 'default:solr_request_dispatcher'
-    handler_settings: {  }
-  solr_field_type:
-    handler: 'default:solr_field_type'
-    handler_settings: {  }
-  solr_cache:
-    handler: 'default:solr_cache'
-    handler_settings: {  }
-  simple_block:
-    handler: 'default:simple_block'
-    handler_settings: {  }
-  simple_sitemap_type:
-    handler: 'default:simple_sitemap_type'
-    handler_settings: {  }
-  simple_sitemap:
-    handler: 'default:simple_sitemap'
-    handler_settings: {  }
-  sitewide_alert:
-    handler: 'default:sitewide_alert'
-    handler_settings: {  }
-  slick:
-    handler: 'default:slick'
-    handler_settings: {  }
-  symfony_mailer_lite_transport:
-    handler: 'default:symfony_mailer_lite_transport'
-    handler_settings: {  }
-  menu:
-    handler: 'default:menu'
-    handler_settings: {  }
-  action:
-    handler: 'default:action'
-    handler_settings: {  }
-  taxonomy_term:
-    handler: 'default:taxonomy_term'
-    handler_settings: {  }
-  taxonomy_vocabulary:
-    handler: 'default:taxonomy_vocabulary'
-    handler_settings: {  }
-  theme_rule:
-    handler: 'default:theme_rule'
-    handler_settings: {  }
-  tmgmt_job:
-    handler: 'default:tmgmt_job'
-    handler_settings: {  }
-  tmgmt_message:
-    handler: 'default:tmgmt_message'
-    handler_settings: {  }
-  tmgmt_remote:
-    handler: 'default:tmgmt_remote'
-    handler_settings: {  }
-  tmgmt_translator:
-    handler: 'default:tmgmt_translator'
-    handler_settings: {  }
-  tmgmt_job_item:
-    handler: 'default:tmgmt_job_item'
-    handler_settings: {  }
-  tour:
-    handler: 'default:tour'
-    handler_settings: {  }
-  user:
-    handler: 'default:user'
-    handler_settings: {  }
-  user_role:
-    handler: 'default:user_role'
-    handler_settings: {  }
-  webform_options:
-    handler: 'default:webform_options'
-    handler_settings: {  }
-  webform_submission:
-    handler: 'default:webform_submission'
-    handler_settings: {  }
-  webform:
-    handler: 'default:webform'
-    handler_settings: {  }
-  menu_link_content:
-    handler: 'default:menu_link_content'
-    handler_settings: {  }
-  pathauto_pattern:
-    handler: 'default:pathauto_pattern'
-    handler_settings: {  }
-  view:
-    handler: 'default:view'
-    handler_settings: {  }
-  paragraphs_type:
-    handler: 'default:paragraphs_type'
-    handler_settings: {  }
-  paragraph:
-    handler: 'default:paragraph'
-    handler_settings: {  }
-  base_field_override:
-    handler: 'default:base_field_override'
-    handler_settings: {  }
-  entity_view_mode:
-    handler: 'default:entity_view_mode'
-    handler_settings: {  }
-  entity_form_display:
-    handler: 'default:entity_form_display'
-    handler_settings: {  }
-  entity_view_display:
-    handler: 'default:entity_view_display'
-    handler_settings: {  }
-  entity_form_mode:
-    handler: 'default:entity_form_mode'
-    handler_settings: {  }
-  date_format:
-    handler: 'default:date_format'
-    handler_settings: {  }
-field_type: dynamic_entity_reference
diff --git a/config/sync/field.field.message.group_content_subscription.group_content.yml b/config/sync/field.field.message.group_content_subscription.group_content.yml
new file mode 100644
index 0000000000000000000000000000000000000000..0d9d286cfc681e8bd37e993441a143dbc86ba60f
--- /dev/null
+++ b/config/sync/field.field.message.group_content_subscription.group_content.yml
@@ -0,0 +1,42 @@
+uuid: 5e58caa3-3693-46d3-b448-9e6a2e095eeb
+langcode: en
+status: true
+dependencies:
+  config:
+    - field.storage.message.group_content
+    - message.template.group_content_subscription
+    - node.type.discussion
+    - node.type.document
+    - node.type.event
+    - node.type.news
+    - node.type.solution
+  module:
+    - tmgmt_content
+third_party_settings:
+  tmgmt_content:
+    excluded: false
+id: message.group_content_subscription.group_content
+field_name: group_content
+entity_type: message
+bundle: group_content_subscription
+label: 'Group content'
+description: ''
+required: false
+translatable: false
+default_value: {  }
+default_value_callback: ''
+settings:
+  handler: 'default:node'
+  handler_settings:
+    target_bundles:
+      discussion: discussion
+      document: document
+      event: event
+      news: news
+      solution: solution
+    sort:
+      field: _none
+      direction: ASC
+    auto_create: false
+    auto_create_bundle: discussion
+field_type: entity_reference
diff --git a/config/sync/field.field.meta_entity.solution_settings.field_ss_related_solutions.yml b/config/sync/field.field.meta_entity.solution_settings.field_ss_related_solutions.yml
deleted file mode 100644
index 26d7ae923ba6cd520bd2dcd3b0c30c6eccc8e693..0000000000000000000000000000000000000000
--- a/config/sync/field.field.meta_entity.solution_settings.field_ss_related_solutions.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-uuid: 4cacf604-3e96-4204-94f6-3017de52e06a
-langcode: en
-status: true
-dependencies:
-  config:
-    - field.storage.meta_entity.field_ss_related_solutions
-    - meta_entity.type.solution_settings
-    - node.type.solution
-id: meta_entity.solution_settings.field_ss_related_solutions
-field_name: field_ss_related_solutions
-entity_type: meta_entity
-bundle: solution_settings
-label: 'Related solutions'
-description: ''
-required: false
-translatable: false
-default_value: {  }
-default_value_callback: ''
-settings:
-  handler: 'default:node'
-  handler_settings:
-    target_bundles:
-      solution: solution
-    sort:
-      field: _none
-    auto_create: false
-    auto_create_bundle: ''
-field_type: entity_reference
diff --git a/config/sync/field.field.node.custom_page.abstract.yml b/config/sync/field.field.node.custom_page.abstract.yml
new file mode 100644
index 0000000000000000000000000000000000000000..267206f78db60f57457e432dbaa3305c56eee13b
--- /dev/null
+++ b/config/sync/field.field.node.custom_page.abstract.yml
@@ -0,0 +1,24 @@
+uuid: 762845bd-9e7c-4ab5-8759-b5db6c78fb32
+langcode: en
+status: true
+dependencies:
+  config:
+    - field.storage.node.abstract
+    - node.type.custom_page
+  module:
+    - tmgmt_content
+third_party_settings:
+  tmgmt_content:
+    excluded: false
+id: node.custom_page.abstract
+field_name: abstract
+entity_type: node
+bundle: custom_page
+label: Abstract
+description: 'Short description text of the document, displayed in content tiles and search results.'
+required: true
+translatable: false
+default_value: {  }
+default_value_callback: ''
+settings: {  }
+field_type: string
diff --git a/config/sync/field.storage.message.field_group_content.yml b/config/sync/field.storage.message.field_group_content.yml
deleted file mode 100644
index 7f6f9026eb7e9468bb1b493bf514713da9093676..0000000000000000000000000000000000000000
--- a/config/sync/field.storage.message.field_group_content.yml
+++ /dev/null
@@ -1,27 +0,0 @@
-uuid: 2a833cf7-8ed7-4fe7-bdd6-c30283c9692c
-langcode: en
-status: true
-dependencies:
-  module:
-    - dynamic_entity_reference
-    - field_permissions
-    - message
-    - node
-third_party_settings:
-  field_permissions:
-    permission_type: public
-id: message.field_group_content
-field_name: field_group_content
-entity_type: message
-type: dynamic_entity_reference
-settings:
-  exclude_entity_types: false
-  entity_type_ids:
-    node: node
-module: dynamic_entity_reference
-locked: false
-cardinality: 1
-translatable: true
-indexes: {  }
-persist_with_no_fields: false
-custom_storage: false
diff --git a/config/sync/field.storage.message.group_content.yml b/config/sync/field.storage.message.group_content.yml
new file mode 100644
index 0000000000000000000000000000000000000000..f0537f6f702255f18e00898f6cbca6147d6d8ec0
--- /dev/null
+++ b/config/sync/field.storage.message.group_content.yml
@@ -0,0 +1,20 @@
+uuid: 86bb0bf3-343d-4d8a-8e16-33e569dd12a0
+langcode: en
+status: true
+dependencies:
+  module:
+    - message
+    - node
+id: message.group_content
+field_name: group_content
+entity_type: message
+type: entity_reference
+settings:
+  target_type: node
+module: core
+locked: false
+cardinality: -1
+translatable: true
+indexes: {  }
+persist_with_no_fields: false
+custom_storage: false
diff --git a/config/sync/field.storage.meta_entity.field_ss_related_solutions.yml b/config/sync/field.storage.meta_entity.field_ss_related_solutions.yml
deleted file mode 100644
index f54316dbe96e98954a6050e175e0754e02fa26e7..0000000000000000000000000000000000000000
--- a/config/sync/field.storage.meta_entity.field_ss_related_solutions.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-uuid: c615105e-4e5c-4bc4-bf26-ddff77f4ae3a
-langcode: en
-status: true
-dependencies:
-  module:
-    - field_permissions
-    - meta_entity
-    - node
-third_party_settings:
-  field_permissions:
-    permission_type: public
-id: meta_entity.field_ss_related_solutions
-field_name: field_ss_related_solutions
-entity_type: meta_entity
-type: entity_reference
-settings:
-  target_type: node
-module: core
-locked: false
-cardinality: -1
-translatable: true
-indexes: {  }
-persist_with_no_fields: false
-custom_storage: false
diff --git a/config/sync/field.storage.node.abstract.yml b/config/sync/field.storage.node.abstract.yml
index 0627c7eab93e11f5a6e55eb75570f6470ab1477b..68bef93999c9789472d2dd74b3db26c287c1b36c 100644
--- a/config/sync/field.storage.node.abstract.yml
+++ b/config/sync/field.storage.node.abstract.yml
@@ -3,11 +3,7 @@ langcode: en
 status: true
 dependencies:
   module:
-    - field_permissions
     - node
-third_party_settings:
-  field_permissions:
-    permission_type: public
 id: node.abstract
 field_name: abstract
 entity_type: node
diff --git a/config/sync/message.template.group_content_subscription.yml b/config/sync/message.template.group_content_subscription.yml
index 33b3de1ffd8abf437c38b35f6e214b57f727f77e..c9fcf3eac1ec2ebae160ce77493cea19b5b42cc0 100644
--- a/config/sync/message.template.group_content_subscription.yml
+++ b/config/sync/message.template.group_content_subscription.yml
@@ -9,7 +9,7 @@ label: 'Group content subscription'
 description: "Digest message sent when new content is published in a user's subscribed collections and solutions"
 text:
   -
-    value: '<p>[message:field_group_content:entity]</p>'
+    value: '<p>[message:group_content:entity]</p>'
     format: full_html
 settings:
   'token options':
diff --git a/config/sync/og.og_role.node-solution-administrator.yml b/config/sync/og.og_role.node-solution-administrator.yml
index ac4c8b89e62051eab2513c71931e7f74d30ecfda..9ad9d7b69ee253d0bb77f584f2917887411c379d 100644
--- a/config/sync/og.og_role.node-solution-administrator.yml
+++ b/config/sync/og.og_role.node-solution-administrator.yml
@@ -13,5 +13,7 @@ group_bundle: solution
 is_admin: null
 permissions:
   - 'delete any release content'
+  - 'perform release_workflow workflow archive transition on any entity'
+  - 'perform solution_workflow workflow archive transition on any entity'
   - 'update solution_settings meta-entity'
 role_type: null
diff --git a/config/sync/og.og_role.node-solution-facilitator.yml b/config/sync/og.og_role.node-solution-facilitator.yml
index 8ee46d379e1665efd2fee9e44f0a2eb8a5a41e1e..1a6f30399e60b83bfd0309cf05ab2decbb38879f 100644
--- a/config/sync/og.og_role.node-solution-facilitator.yml
+++ b/config/sync/og.og_role.node-solution-facilitator.yml
@@ -65,6 +65,7 @@ permissions:
   - 'manage members'
   - 'perform announcement workflow send transition on any entity'
   - 'perform joinup_distribution_workflow workflow publish transition on any entity'
+  - 'perform release_workflow workflow archive transition on any entity'
   - 'perform release_workflow workflow draft transition on any entity'
   - 'perform release_workflow workflow provide_changes transition on any entity'
   - 'perform release_workflow workflow update_published transition on any entity'
@@ -98,6 +99,7 @@ permissions:
   - 'perform node:pre_moderated workflow report transition on any entity'
   - 'perform node:pre_moderated workflow save_as_draft transition on any entity'
   - 'perform node:pre_moderated workflow save_new_draft transition on any entity'
+  - 'perform solution_workflow workflow archive transition on any entity'
   - 'perform solution_workflow workflow draft transition on any entity'
   - 'perform solution_workflow workflow propose transition on any entity'
   - 'perform solution_workflow workflow update_validated transition on any entity'
diff --git a/config/sync/views.view.manage_collection_solutions.yml b/config/sync/views.view.manage_collection_solutions.yml
index f67eba34fbe123dd0573df058ece3a2cbb979036..df20cd6253513027fc0e6efc3c7bc820921c9271 100644
--- a/config/sync/views.view.manage_collection_solutions.yml
+++ b/config/sync/views.view.manage_collection_solutions.yml
@@ -623,7 +623,7 @@ display:
         metatag_display_extender:
           metatags: {  }
           tokenize: false
-      path: node/%node/manage-solutionsmanage-solutions
+      path: node/%node/manage-solutions
       menu:
         type: tab
         title: 'Manage solutions'
diff --git a/resources/patch/php/drupal/dynamic_entity_reference/3099176-3.x-16.diff b/resources/patch/php/drupal/dynamic_entity_reference/3099176-3.x-16.diff
new file mode 100644
index 0000000000000000000000000000000000000000..c1ef4d30c0d8e34c002508dc17193f5fd6897296
--- /dev/null
+++ b/resources/patch/php/drupal/dynamic_entity_reference/3099176-3.x-16.diff
@@ -0,0 +1,92 @@
+diff --git a/src/Plugin/Field/FieldType/DynamicEntityReferenceItem.php b/src/Plugin/Field/FieldType/DynamicEntityReferenceItem.php
+index dec3f87..5994d58 100644
+--- a/src/Plugin/Field/FieldType/DynamicEntityReferenceItem.php
++++ b/src/Plugin/Field/FieldType/DynamicEntityReferenceItem.php
+@@ -292,7 +292,7 @@ class DynamicEntityReferenceItem extends EntityReferenceItem {
+   protected function targetTypeFieldSettingsForm(array $form, FormStateInterface $form_state, $target_type) {
+     /** @var \Drupal\field\FieldConfigInterface $field */
+     $field = $form_state->getFormObject()->getEntity();
+-    $field_settings = $field->getSettings();
++    $field_settings = $field->getSettings() + self::defaultFieldSettings();
+     /** @var \Drupal\dynamic_entity_reference\SelectionPluginManager $manager */
+     $manager = \Drupal::service('plugin.manager.dynamic_entity_reference_selection');
+     // Get all selection plugins for this entity type.
+@@ -548,7 +548,7 @@ class DynamicEntityReferenceItem extends EntityReferenceItem {
+     // also covers the 'auto_create_bundle' setting, if any, because its value
+     // is included in the 'target_bundles' list.
+     $entity_type_manager = \Drupal::entityTypeManager();
+-    $settings = $field_definition->getSettings();
++    $settings = $field_definition->getSettings() + self::defaultFieldSettings();
+     foreach (static::getTargetTypes($settings) as $target_type) {
+       $handler = $settings[$target_type]['handler_settings'];
+       if (!empty($handler['target_bundles'])) {
+@@ -589,7 +589,7 @@ class DynamicEntityReferenceItem extends EntityReferenceItem {
+     $entity_type_manager = \Drupal::entityTypeManager();
+     // Update the 'target_bundles' handler setting if a bundle config dependency
+     // has been removed.
+-    $settings = $field_definition->getSettings();
++    $settings = $field_definition->getSettings() + self::defaultFieldSettings();
+     foreach (static::getTargetTypes($settings) as $target_type) {
+       $bundles_changed = FALSE;
+       $handler_settings = $settings[$target_type]['handler_settings'];
+diff --git a/src/Plugin/Field/FieldWidget/DynamicEntityReferenceWidget.php b/src/Plugin/Field/FieldWidget/DynamicEntityReferenceWidget.php
+index 24de497..d13ae39 100644
+--- a/src/Plugin/Field/FieldWidget/DynamicEntityReferenceWidget.php
++++ b/src/Plugin/Field/FieldWidget/DynamicEntityReferenceWidget.php
+@@ -119,7 +119,7 @@ class DynamicEntityReferenceWidget extends EntityReferenceAutocompleteWidget {
+     $entity = $items->getEntity();
+     $referenced_entities = $items->referencedEntities();
+ 
+-    $settings = $this->getFieldSettings();
++    $settings = $this->getFieldSettings() + DynamicEntityReferenceItem::defaultFieldSettings();
+     $labels = $this->entityTypeRepository->getEntityTypeLabels();
+     $available = DynamicEntityReferenceItem::getTargetTypes($settings);
+     $cardinality = $items->getFieldDefinition()->getFieldStorageDefinition()->getCardinality();
+@@ -250,7 +250,7 @@ class DynamicEntityReferenceWidget extends EntityReferenceAutocompleteWidget {
+         array_pop($parents);
+         $values = $form_state->getValue($parents);
+       }
+-      $settings = $this->getFieldSettings();
++      $settings = $this->getFieldSettings() + DynamicEntityReferenceItem::defaultFieldSettings();
+       $element['#target_type'] = $values['target_type'];
+       $element['#selection_handler'] = $settings[$values['target_type']]['handler'];
+       $element['#selection_settings'] = $settings[$values['target_type']]['handler_settings'];
+@@ -284,7 +284,7 @@ class DynamicEntityReferenceWidget extends EntityReferenceAutocompleteWidget {
+     if ($target_type === NULL) {
+       return parent::getSelectionHandlerSetting($setting_name);
+     }
+-    $settings = $this->getFieldSettings();
++    $settings = $this->getFieldSettings() + DynamicEntityReferenceItem::defaultFieldSettings();
+     return $settings[$target_type]['handler_settings'][$setting_name] ?? NULL;
+   }
+ 
+@@ -333,7 +333,7 @@ class DynamicEntityReferenceWidget extends EntityReferenceAutocompleteWidget {
+    */
+   protected function createAutoCompletePaths(array $target_types) {
+     $auto_complete_paths = [];
+-    $settings = $this->getFieldSettings();
++    $settings = $this->getFieldSettings() + DynamicEntityReferenceItem::defaultFieldSettings();
+     foreach ($target_types as $target_type) {
+       // Store the selection settings in the key/value store and pass a hashed
+       // key in the route parameters.
+diff --git a/src/SelectionPluginManager.php b/src/SelectionPluginManager.php
+index 4f00334..b64cc82 100644
+--- a/src/SelectionPluginManager.php
++++ b/src/SelectionPluginManager.php
+@@ -5,6 +5,7 @@ namespace Drupal\dynamic_entity_reference;
+ use Drupal\Core\Entity\EntityInterface;
+ use Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManager as CoreSelectionPluginManager;
+ use Drupal\Core\Field\FieldDefinitionInterface;
++use Drupal\dynamic_entity_reference\Plugin\Field\FieldType\DynamicEntityReferenceItem;
+ 
+ /**
+  * Plugin type manager for Dynamic Entity Reference Selection plugins.
+@@ -21,7 +22,7 @@ class SelectionPluginManager extends CoreSelectionPluginManager {
+     if ($target_type === NULL) {
+       return parent::getSelectionHandler($field_definition, $entity);
+     }
+-    $settings = $field_definition->getSettings();
++    $settings = $field_definition->getSettings() + DynamicEntityReferenceItem::defaultFieldSettings();
+     $options = $settings[$target_type]['handler_settings'] ?? [];
+     $options += [
+       'target_type' => $target_type,
diff --git a/tests/features/ckeditor5.feature b/tests/features/ckeditor5.feature
index b0553cd060f10bb2fc94f6e3a6b98e9db37ade6e..3f2d6ad6a9f03ebd93efd539ff9b1ee6204a5122 100644
--- a/tests/features/ckeditor5.feature
+++ b/tests/features/ckeditor5.feature
@@ -242,4 +242,101 @@ Feature: CKEditor5
     And I press "Insert selected" in the "Modal buttons" region
     Then I should see the error message "No items selected."
 
+  @casMockServer
+  Scenario: Add test coverage for 'Contact us' wysiwyg button.
+
+    And owner content:
+      | name  | owner type |
+      | Lotte | Company    |
+    And user:
+      | Username    | Pally Rapamichael      |
+      | First name  | Pally                  |
+      | Family name | Rapamichael            |
+      | E-mail      | p.papamichael@pally.de |
+    And contact_information content:
+      | name                 | email                      |
+      | Klim Smith           | klim.smith@example.com     |
+      | Raul Timon           | raul.timon@example.com     |
+    And the following email confirmation request:
+      | email                  | status    |
+      | klim.smith@example.com | confirmed |
+      | raul.timon@example.com | confirmed |
+    And collection content:
+      | title                | state     | contact information |
+      | Antiruin development | published | Raul Timon          |
+    And solution content:
+      | title                    | abstract                        | description                     | state     | topic                   | owner | solution type                      | collection           | contact information |
+      | One exclusion advantages | Separating molecules by height. | Separating molecules by weight. | published | Demography, E-inclusion | Lotte | Non-binding Instrument, Data Owner | Antiruin development | Klim Smith          |
+    And users:
+      | Username    | E-mail         | First name | Family name |
+      | jmacc_local | jodine@ankh.am | John       | Maccalariat |
+    And CAS users:
+      | First name | Last name   | Username  | E-mail         | Password | Local username |
+      | John       | Maccalariat | jmacc     | jodine@ankh.am | 10d1ne   | jmacc_local    |
+
+    Given I am logged in as a moderator
+    Then I go to "/collection/antiruin-development/solution/one-exclusion-advantages/contact"
+    And I should see the heading "Contact us"
+
+    When I go to the homepage of the "One exclusion advantages" solution
+    Then I open the header local tasks menu
+    And I click "Edit" in the "Entity actions" region
+    And I press the button "Contact us" in the "Description" wysiwyg editor
+    Then I press "Publish"
+    And I should see the heading "One exclusion advantages"
+    When I click "Contact us"
+    Then I should see the heading "Contact us"
+    Then I fill in "Your name" with "Lina Example"
+    And I fill in "Your e-mail address" with "linak@example.pt"
+    And I fill in "Subject" with "New reclamation about Owner"
+    And I select "Other" from "Type of support"
+    And I fill in "Message" with "This is reclamation test."
+    When I press "Send e-mail"
+    And I should see the success message "Your message has been sent."
+    Then I should see the heading "One exclusion advantages"
+    And I should be on "/collection/antiruin-development/solution/one-exclusion-advantages"
+
+    When I am an anonymous user
+    Then I go to the "One exclusion advantages" solution
+    And I click "Contact us"
+    And I should see the heading "Sign in to continue"
+
+    When I fill in "E-mail address" with "jodine@ankh.am"
+    And I fill in "Password" with "10d1ne"
+    And I press "Log in"
+    And I should see the heading "Contact us"
+    Then I fill in "Your name" with "V Example"
+    And I fill in "Your e-mail address" with "vnak@example.pt"
+    And I select "Other" from "Type of support"
+    And I fill in "Subject" with "v2 New reclamation about Owner"
+    And I fill in "Message" with "This is v2 reclamation test."
+    When I press "Send e-mail"
+    Then I should see the success message "Your message has been sent."
+    And I should see the heading "One exclusion advantages"
+
+    # Check layout paragraphs.
+    Given custom_page content:
+      | title                             | collection            | state     | abstract |
+      | Contact us text check             | Antiruin development  | published | N/A      |
+    And I append "layout" to "field_paragraphs_body" field in "node" entity with following "Contact us text check" title:
+      | behavior_settings | a:3:{s:17:"layout_paragraphs";a:4:{s:6:"layout";s:13:"layout_onecol";s:6:"config";a:1:{s:5:"label";s:0:"";}s:11:"parent_uuid";N;s:6:"region";N;}s:16:"background_theme";a:0:{}s:11:"extra_class";a:0:{}} |
+
+    When I am logged in as a moderator
+    And I go to the edit form of the "Contact us text check" "custom page"
+    And I click "Choose component"
+    And a modal should open
+    # Not used anymore.
+    And I should not see the link "Simple paragraph"
+    And I click "Text"
+    And the "Contact us" button should be available in the "Body" wysiwyg editor
+    And I press the button "Contact us" in the "Body" wysiwyg editor
+    And I press "Save" in the "Modal buttons" region
+    And I press "Update"
+    Then I should see the success message "Custom page Contact us text check has been updated."
+    And I should see the link "Contact us"
+
+    When I am an anonymous user
+    Then I go to the "Contact us text check" custom_page
+    And I should see the link "Contact us"
+
   # For 'Media video with CKEditor5' see tests/features/video/embed.feature
diff --git a/tests/features/collection/propose.feature b/tests/features/collection/propose.feature
index 5ae2818b9d76f1f66799caca23d0a5c7660a139f..1cd31d5cbbf7a96af865168f7f4ebc758f6eb55e 100644
--- a/tests/features/collection/propose.feature
+++ b/tests/features/collection/propose.feature
@@ -83,7 +83,8 @@ Feature: Proposing a collection
     When I click the contextual link "Add new page" in the "Header" region
     Then I should see the heading "Add custom page"
     When I fill in the following:
-      | Title | About this group |
+      | Title    | About this group          |
+      | Abstract | Abstract about this group |
     And I select "HR" from "Topic"
     And I press "Publish"
     Then I should see the success message "Custom page About this group has been created."
diff --git a/tests/features/communities/interoperable_europe/iop_paragraphs.feature b/tests/features/communities/interoperable_europe/iop_paragraphs.feature
index 11dd8b52cf4a1b79b3b26dbc2da74ceb40eff199..0316be2bc4ccab16849c37dcfeccccdf616c7851 100644
--- a/tests/features/communities/interoperable_europe/iop_paragraphs.feature
+++ b/tests/features/communities/interoperable_europe/iop_paragraphs.feature
@@ -43,7 +43,8 @@ Feature:
     And I click "Add custom page" in the plus button menu
 
     When I fill in the following:
-      | Title | Pages carousel |
+      | Title    | Pages carousel          |
+      | Abstract | Abstract pages carousel |
     And I select "Demography" from "Topic"
     And I add a layout paragraph in the "Custom page body" form field with the following properties:
       | layout           | one column |
diff --git a/tests/features/community_content/archive.listings.feature b/tests/features/community_content/archive.listings.feature
index ca8ef96e6c2188ec6bf784bef31795709101730c..794be04994556df002d30962a51a4d4806ac8843 100644
--- a/tests/features/community_content/archive.listings.feature
+++ b/tests/features/community_content/archive.listings.feature
@@ -66,8 +66,8 @@ Feature: Archived content on content listings - groups and paragraphs.
   @javascript
   Scenario: Content listing paragraph can control visibility of archived items.
     And custom_page content:
-      | title     | collection      | state     | topic             |
-      | Some page | Some collection | published | Supplier exchange |
+      | title     | abstract           | collection      | state     | topic             |
+      | Some page | Some page abstract | Some collection | published | Supplier exchange |
     And I append "layout" to "field_paragraphs_body" field in "node" entity with following "Some page" title:
       | behavior_settings | a:3:{s:17:"layout_paragraphs";a:4:{s:6:"layout";s:13:"layout_onecol";s:6:"config";a:1:{s:5:"label";s:0:"";}s:11:"parent_uuid";N;s:6:"region";N;}s:16:"background_theme";a:0:{}s:11:"extra_class";a:0:{}} |
 
@@ -121,8 +121,8 @@ Feature: Archived content on content listings - groups and paragraphs.
       | IOP archived news  | IOP archived news  | archived  | Interoperable Europe | Test | Test    |
       | IOP published news | IOP published news | published | Interoperable Europe | Test | Test    |
     And custom_page content:
-      | title    | collection           | state     |
-      | IOP page | Interoperable Europe | published |
+      | title    | abstract          | collection           | state     |
+      | IOP page | IOP page abstract | Interoperable Europe | published |
     And I append "layout" to "field_paragraphs_body" field in "node" entity with following "IOP page" title:
       | behavior_settings | a:3:{s:17:"layout_paragraphs";a:4:{s:6:"layout";s:13:"layout_onecol";s:6:"config";a:1:{s:5:"label";s:0:"";}s:11:"parent_uuid";N;s:6:"region";N;}s:16:"background_theme";a:0:{}s:11:"extra_class";a:0:{}} |
 
diff --git a/tests/features/custom_page/add_custom_page.feature b/tests/features/custom_page/add_custom_page.feature
index abdea3df3b72f72e6f248a826705b52016f6a67d..2bd7949a9fc0bbb8d880a9f14fbbc2a620e4f899 100644
--- a/tests/features/custom_page/add_custom_page.feature
+++ b/tests/features/custom_page/add_custom_page.feature
@@ -74,7 +74,8 @@ Feature: "Add custom page" visibility options.
     And the following fields should not be present "Groups audience, Other groups, Create new revision, Revision log message, Published"
 
     When I fill in the following:
-      | Title | About us |
+      | Title    | About us          |
+      | Abstract | About us abstract |
     And I attach the file "test.zip" to "Add a new file"
     And I press "Upload"
     # The "Description" field is the description of the file.
@@ -202,7 +203,8 @@ Feature: "Add custom page" visibility options.
     Then I should see the heading "Add custom page"
 
     When I fill in the following:
-      | Title | Rubber boots |
+      | Title    | Rubber boots          |
+      | Abstract | Rubber boots abstract |
     And I press "Save"
     Then I should see the error message "The Custom page title value (Rubber boots) is already taken by Rubber boots."
 
@@ -214,7 +216,8 @@ Feature: "Add custom page" visibility options.
     Then I should see the heading "Add custom page"
 
     When I fill in the following:
-      | Title | Rubber boots |
+      | Title    | Rubber boots          |
+      | Abstract | Rubber boots abstract |
     And I select "HR" from "Topic"
     And I press "Save"
     Then I should see the heading "Rubber boots"
diff --git a/tests/features/custom_page/community_content_listing.feature b/tests/features/custom_page/community_content_listing.feature
index 22eb7eae2cf445ad419aa195bcf12942b7820016..972a37252e47fc003f90339c205bef8308748ac4 100644
--- a/tests/features/custom_page/community_content_listing.feature
+++ b/tests/features/custom_page/community_content_listing.feature
@@ -74,7 +74,8 @@ Feature:
     And I click "Add custom page" in the plus button menu
     Then I should see the heading "Add custom page"
     When I fill in the following:
-      | Title | Latest content |
+      | Title    | Latest content       |
+      | Abstract | Lorem ipsum abstract |
     And I select "HR" from "Topic"
     And I add a layout paragraph in the "Custom page body" form field with the following properties:
       | layout           | one column |
@@ -171,6 +172,7 @@ Feature:
     And I click "Add custom page" in the plus button menu
     Then I should see the heading "Add custom page"
     When I fill in "Title" with "Chosen content"
+    And I fill in "Abstract" with "Abstract chosen content"
     And I select "HR" from "Topic"
     And I add a layout paragraph in the "Custom page body" form field with the following properties:
       | layout           | one column |
@@ -329,7 +331,8 @@ Feature:
 
     Then I should see the heading "Add custom page"
     When I fill in the following:
-      | Title | Collection content |
+      | Title    | Collection content          |
+      | Abstract | Abstract collection content |
     And I select "HR" from "Topic"
     And I add a layout paragraph in the "Custom page body" form field with the following properties:
       | layout           | one column |
@@ -572,8 +575,8 @@ Feature:
       | Black Noise        | Nintendo64 | published |
 
     And custom_page content:
-      | title | collection | state     |
-      | Bikes | Nintendo64 | published |
+      | title | collection | state     | abstract |
+      | Bikes | Nintendo64 | published | N/A      |
 
     And I am logged in as jimmy7892
     And I go to the edit form of the "Bikes" "custom page"
diff --git a/tests/features/custom_page/custom_page.edit.feature b/tests/features/custom_page/custom_page.edit.feature
index ad19e078636cdbb13d3cb842bffc4c73033b48c6..775d60288ece13623171524db9cb48f93d31fd34 100644
--- a/tests/features/custom_page/custom_page.edit.feature
+++ b/tests/features/custom_page/custom_page.edit.feature
@@ -29,8 +29,8 @@ Feature: "Custom page" editing.
       | Dumbo Collective | Mickey Mouse | facilitator |
       | Dumbo Collective | Pluto        | member      |
     And "custom_page" content:
-      | title                            | <group>          | body | logo     | state     |
-      | Buena Vista Distribution Company | Dumbo Collective | N/A  | logo.png | published |
+      | title                            | <group>          |abstract | body | logo     | state     |
+      | Buena Vista Distribution Company | Dumbo Collective | N/A     | N/A  | logo.png | published |
 
     # Group owner should see the button.
     When I am logged in as "Mickey Mouse"
diff --git a/tests/features/custom_page/landing_custom_page.feature b/tests/features/custom_page/landing_custom_page.feature
index 5560dd8533405251c9726d4c109f149bb3a37ce4..23eab3e7f728c538d90676a6a88874bfef05a881 100644
--- a/tests/features/custom_page/landing_custom_page.feature
+++ b/tests/features/custom_page/landing_custom_page.feature
@@ -23,7 +23,8 @@ Feature: Landing custom page.
     When I click "Add custom landing page"
     And the following field should be present "URL alias"
     And I fill in the following:
-      | Title | Twelve Tables |
+      | Title    | Twelve Tables          |
+      | Abstract | Twelve tables abstract |
     And I select "Data gathering and processing" from "Topic"
     And I press "Publish"
 
diff --git a/tests/features/custom_page/navigation_menu.feature b/tests/features/custom_page/navigation_menu.feature
index c7e991290dc1d958f1a18e53e2db5b1a1b70439f..a09d34b99118bb9e9a69f6ed0db652d23b026058 100644
--- a/tests/features/custom_page/navigation_menu.feature
+++ b/tests/features/custom_page/navigation_menu.feature
@@ -26,7 +26,8 @@ Feature: Navigation menu for custom pages
     When I click the contextual link "Add new page" in the "Header" region
     Then I should see the heading "Add custom page"
     When I fill in the following:
-      | Title | About us |
+      | Title    | About us             |
+      | Abstract | Lorem ipsum abstract |
     And I select "HR" from "Topic"
     And I press "Publish"
     Then I should see the success message "Custom page About us has been created."
@@ -180,8 +181,8 @@ Feature: Navigation menu for custom pages
       | title                               | state     |
       | Ravenous wood-munching alphabeavers | published |
     And custom_page content:
-      | title       | body                                                                | <group>                             | topic | state     |
-      | Tree eaters | Given time, they will most likely strip the entire region of trees. | Ravenous wood-munching alphabeavers | HR    | published |
+      | title       | abstract               | body                                                                | <group>                             | topic | state     |
+      | Tree eaters | entire region of trees | Given time, they will most likely strip the entire region of trees. | Ravenous wood-munching alphabeavers | HR    | published |
     When I am logged in as a facilitator of the "Ravenous wood-munching alphabeavers" "<group>"
     And I go to the homepage of the "Ravenous wood-munching alphabeavers" <group>
     Then I should see the link "Tree eaters" in the "Navigation menu"
diff --git a/tests/features/joinup_like/like.feature b/tests/features/joinup_like/like.feature
index 7b04d59d5b09b8a7223716c7785d8be2f6637533..1fef5ac1304fd672b41a1b90ba6effe3c9b21106 100644
--- a/tests/features/joinup_like/like.feature
+++ b/tests/features/joinup_like/like.feature
@@ -222,6 +222,7 @@ Feature: Like/unlike feature.
     And I click "Add custom page"
 
     And I fill in "Title" with "Carousel of likes"
+    And I fill in "Abstract" with "Abstract carousel of likes"
     And I select "HR" from "Topic"
     And I add a layout paragraph in the "Custom page body" form field with the following properties:
       | layout           | one column |
diff --git a/tests/features/joinup_release/release.moderation.feature b/tests/features/joinup_release/release.moderation.feature
index 9e5551b6d4c8e07e9c814fbed17492d3ebff89e4..1a1d78b4cc9ef89ceb9438a41f8bd66ce8b3818b 100644
--- a/tests/features/joinup_release/release.moderation.feature
+++ b/tests/features/joinup_release/release.moderation.feature
@@ -44,7 +44,7 @@ Feature: Asset release moderation
     And 0 e-mails should have been sent
 
     When I click "Edit" in the "Entity actions" region
-    And I should see the workflow buttons "Update, Save as draft"
+    And I should see the workflow buttons "Update, Save as draft, Archive"
     When I fill in "Release notes" with "We go live soon."
     And I press "Update"
     Then I should see the text "Release of the dark ship v1" in the "Page title" region
@@ -143,6 +143,27 @@ Feature: Asset release moderation
       | subject   | Joinup: Your release was accepted                                                                  |
       | body      | Your proposed Release fix, v1 for the solution "Dark Ship" has been validated as per your request. |
 
+    # Check archive permissions author and facilitator.
+    When I am logged in as "Bonnie Holloway"
+    And I go to the "Release fix" release
+    When I click "Edit" in the "Entity actions" region
+    And I press "Archive"
+    Then I should see the text "Archived" in the "Page title" region
+
+    When I am logged in as a moderator
+    And I go to the "Release fix" release
+    And I click "Edit" in the "Entity actions" region
+    And I press "Unarchive"
+    Then I should not see the text "Archived" in the "Page title" region
+
+    When I am logged in as "Felix Russell"
+    And I go to the "Release fix" release
+    When I click "Edit" in the "Entity actions" region
+    And I press "Archive"
+    Then I should see the text "Archived" in the "Page title" region
+
+    When I am logged in as a moderator
+    And I go to the "Release fix" release
     # Delete a release as a moderator.
     When I click "Edit" in the "Entity actions" region
     And I click "Delete"
diff --git a/tests/features/joinup_search/search.feature b/tests/features/joinup_search/search.feature
index 8aa4cee24f904e8b8dbe7392ed1466c2d4316c7f..75e2529c1f6a89d25a817d5bfae6588ce074b668 100644
--- a/tests/features/joinup_search/search.feature
+++ b/tests/features/joinup_search/search.feature
@@ -840,6 +840,13 @@ Feature: Global search
       | Solution javi | <p>This is the solution <strong>javi</strong> description. |                             | Alphabet | Renew owner | Gor-to contact      | Col for Sol javi | published |
       | Solution roll | <p>This is the solution <strong>roll</strong> description. | The solution roll abstract. | Alphabet | Renew owner | Gor-to contact      | Roll alpha       | published |
       | Solution net  | <p>This is the solution <strong>net</strong> description.  |                             | Alphabet | Renew owner | Gor-to contact      | Col for Sol net  | published |
+    And "custom_page" content:
+      | title                    | collection       | abstract             | logo     | state     |
+      | Custom example abstract  | Pull alpha       | Lorem ipsum abstract | logo.png | published |
+      | Custom example paragraph | Col for Sol javi |                      | logo.png | published |
+    And I append "text" to "field_paragraphs_body" field in "node" entity with following "Custom example paragraph" title:
+      | field_body:value  | That's one small step for a man, a giant leap for mankind. |
+      | field_body:format | text_html                                                  |
 
     When I visit the search page
     And I should see the "Pull alpha" tile
@@ -848,6 +855,8 @@ Feature: Global search
     And I should see the "Solution javi" tile
     And I should see the "Solution roll" tile
     And I should see the "Solution net" tile
+    And I should see the "Custom example abstract" tile
+    And I should see the "Custom example paragraph" tile
     And I should not see the "Roll alpha" tile
     And I should not see the "Col for Sol net" tile
     And I should see the text "The collection pull abstract." in the "Pull alpha" card
@@ -856,6 +865,8 @@ Feature: Global search
     And I should see the text "This is the solution javi description" in the "Solution javi" card
     And I should see the text "The solution roll abstract." in the "Solution roll" card
     And I should see the text "This is the solution net description" in the "Solution net" card
+    And I should see the text "Lorem ipsum abstract" in the "Custom example abstract" card
+    And I should see the text "That's one small step for a man, a giant leap for mankind." in the "Custom example paragraph" card
 
     Then I check the "Show only Archived items" checkbox from the "Status" facet
     And I should not see the "Pull alpha" tile
@@ -864,6 +875,8 @@ Feature: Global search
     And I should not see the "Solution javi" tile
     And I should not see the "Solution roll" tile
     And I should not see the "Solution net" tile
+    And I should not see the "Custom example abstract" tile
+    And I should not see the "Custom example paragraph" tile
     And I should see the "Roll alpha" tile
     And I should see the "Col for Sol net" tile
     And I should see the text "The collection roll abstract." in the "Roll alpha" card
diff --git a/tests/features/joinup_subscription/collection.content.subscription.feature b/tests/features/joinup_subscription/collection.content.subscription.feature
index 13f21a753b432bf108ae0b01d628622220ceb29d..c2d5ec582bebf7231c5040c55fb9079c4b9bd4e3 100644
--- a/tests/features/joinup_subscription/collection.content.subscription.feature
+++ b/tests/features/joinup_subscription/collection.content.subscription.feature
@@ -10,10 +10,12 @@ Feature: Subscribing to community content in collections
       | Products of Bulgaria | published |
       | Cities of Bulgaria   | published |
     And users:
-      | Username | E-mail            | First name | Family name  | Notification frequency |
-      | hristo   | hristo@example.bg | Hristo     | Draganov     | daily                  |
-      | bisera   | bisera@example.bg | Bisera     | Kaloyancheva | weekly                 |
-      | kalin    | kalin@primer.bg   | Kalin      | Antov        | monthly                |
+      | Username | E-mail            | First name | Family name  | Notification frequency | Status    |
+      | hristo   | hristo@example.bg | Hristo     | Draganov     | daily                  | active    |
+      | bisera   | bisera@example.bg | Bisera     | Kaloyancheva | weekly                 | active    |
+      | kalin    | kalin@primer.bg   | Kalin      | Antov        | monthly                | active    |
+      | aleks    | aleks@primer.bg   | Aleksandar | Begov        | monthly                | blocked   |
+      | penka    | penka@primer.bg   | Penka      | Ramil        | monthly                | cancelled |
     And the following collection user memberships:
       | collection           | user   | roles       |
       | Products of Bulgaria | hristo |             |
@@ -22,6 +24,8 @@ Feature: Subscribing to community content in collections
       | Cities of Bulgaria   | hristo |             |
       | Cities of Bulgaria   | bisera |             |
       | Cities of Bulgaria   | kalin  | facilitator |
+      | Cities of Bulgaria   | aleks  |             |
+      | Cities of Bulgaria   | penka  |             |
     And the following collection content subscriptions:
       | collection           | user   | subscriptions                        |
       | Products of Bulgaria | hristo | discussion, event, news, solution    |
@@ -30,10 +34,15 @@ Feature: Subscribing to community content in collections
       | Cities of Bulgaria   | hristo | document, event, solution            |
       | Cities of Bulgaria   | bisera | discussion, event, news              |
       | Cities of Bulgaria   | kalin  | discussion, document, news, solution |
+      | Cities of Bulgaria   | aleks  | discussion, document, news             |
+      | Cities of Bulgaria   | penka  | discussion, document, news             |
     And all message digests have been delivered
 
   Scenario: Receive a digest of content that is published in my collections
-    Given discussion content:
+    # Start on clean.
+    Given I mark all emails as read
+
+    And discussion content:
       | title      | body                      | collection           | state     | author |
       | Duck liver | Rich buttery and delicate | Products of Bulgaria | published | hristo |
       | Sofia      | Grows without aging       | Cities of Bulgaria   | published | kalin  |
@@ -143,6 +152,9 @@ Feature: Subscribing to community content in collections
       | Sunflower seeds      |
     And the content subscription digest sent to kalin should have the subject "Joinup: Monthly digest message"
 
+    # No message for aleks@primer.bg (blocked) and penka@primer.bg (cancelled).
+    And 4 e-mails should have been sent to recipients "kalin@primer.bg, hristo@example.bg, bisera@example.bg"
+
     # Clean out the message queue for the next test.
     And I mark all emails as read
 
diff --git a/tests/features/joinup_subscription/solution.content.subscription.feature b/tests/features/joinup_subscription/solution.content.subscription.feature
index 71086cd990fca8a5f00a50cbc7fa8d58760c76f2..a193c807be3d17f397f38c31ba5bc9a47028760a 100644
--- a/tests/features/joinup_subscription/solution.content.subscription.feature
+++ b/tests/features/joinup_subscription/solution.content.subscription.feature
@@ -13,10 +13,13 @@ Feature: Subscribing to community content in solutions
       | Products of Bulgaria | published | Bulgaria   |
       | Cities of Bulgaria   | published | Bulgaria   |
     And users:
-      | Username | E-mail            | First name | Family name  | Notification frequency |
-      | hristo   | hristo@example.bg | Hristo     | Draganov     | daily                  |
-      | bisera   | bisera@example.bg | Bisera     | Kaloyancheva | weekly                 |
-      | kalin    | kalin@primer.bg   | Kalin      | Antov        | monthly                |
+      | Username | E-mail            | First name | Family name  | Notification frequency | Status    |
+      | hristo   | hristo@example.bg | Hristo     | Draganov     | daily                  | active    |
+      | bisera   | bisera@example.bg | Bisera     | Kaloyancheva | weekly                 | active    |
+      | kalin    | kalin@primer.bg   | Kalin      | Antov        | monthly                | active    |
+      | aleks    | aleks@primer.bg   | Aleksandar | Begov        | monthly                | blocked   |
+      | penka    | penka@primer.bg   | Penka      | Ramil        | monthly                | cancelled |
+
     And the following solution user memberships:
       | solution             | user   | roles       |
       | Products of Bulgaria | hristo |             |
@@ -25,6 +28,8 @@ Feature: Subscribing to community content in solutions
       | Cities of Bulgaria   | hristo |             |
       | Cities of Bulgaria   | bisera |             |
       | Cities of Bulgaria   | kalin  | facilitator |
+      | Cities of Bulgaria   | aleks  |             |
+      | Cities of Bulgaria   | penka  |             |
     And the following solution content subscriptions:
       | solution             | user   | subscriptions                          |
       | Products of Bulgaria | hristo | discussion, event, news, distribution  |
@@ -33,10 +38,15 @@ Feature: Subscribing to community content in solutions
       | Cities of Bulgaria   | hristo | document, event                        |
       | Cities of Bulgaria   | bisera | discussion, event, news                |
       | Cities of Bulgaria   | kalin  | discussion, document, news             |
+      | Cities of Bulgaria   | aleks  | discussion, document, news             |
+      | Cities of Bulgaria   | penka  | discussion, document, news             |
     And all message digests have been delivered
 
   Scenario: Receive a digest of content that is published in my solutions
-    Given discussion content:
+    # Start on clean.
+    Given I mark all emails as read
+
+    And discussion content:
       | title      | body                      | solution             | state     | author |
       | Duck liver | Rich buttery and delicate | Products of Bulgaria | published | hristo |
       | Sofia      | Grows without aging       | Cities of Bulgaria   | published | kalin  |
@@ -159,6 +169,9 @@ Feature: Subscribing to community content in solutions
       | Sunflower seeds       |
     And the content subscription digest sent to kalin should have the subject "Joinup: Monthly digest message"
 
+    # No message for aleks@primer.bg (blocked) and penka@primer.bg (cancelled).
+    And 4 e-mails should have been sent to recipients "kalin@primer.bg, hristo@example.bg, bisera@example.bg"
+
     # Clean out the message queue for the next test.
     And I mark all emails as read
 
diff --git a/tests/features/paragraphs/accordion.feature b/tests/features/paragraphs/accordion.feature
index 5148222e8f2d4b908659edfa5d17022212652b82..20cd15b29c13752ae06585f2ed75a6f951454871 100644
--- a/tests/features/paragraphs/accordion.feature
+++ b/tests/features/paragraphs/accordion.feature
@@ -14,6 +14,7 @@ Feature:
     And I open the plus button menu
     And I click "Add custom page"
     And I fill in "Title" with "Paragraphs accordion page"
+    And I fill in "Abstract" with "Abstract paragraphs accordion page"
     And I select "HR" from "Topic"
 
     Given I add a layout paragraph in the "Custom page body" form field with the following properties:
@@ -61,8 +62,8 @@ Feature:
     # Regression test for ticket #ISAICP-8233.
 
     Given custom_page content:
-      | title             | collection            | state     |
-      | Nested paragraphs | Paragraphs collection | published |
+      | title             | collection            | state     | abstract             |
+      | Nested paragraphs | Paragraphs collection | published | Nested page abstract |
     And I append "layout" to "field_paragraphs_body" field in "node" entity with following "Nested paragraphs" title:
       | behavior_settings | a:3:{s:17:"layout_paragraphs";a:4:{s:6:"layout";s:13:"layout_onecol";s:6:"config";a:1:{s:5:"label";s:0:"";}s:11:"parent_uuid";N;s:6:"region";N;}s:16:"background_theme";a:0:{}s:11:"extra_class";a:0:{}} |
 
diff --git a/tests/features/paragraphs/block.feature b/tests/features/paragraphs/block.feature
index 28960b39efd32c7f58365d3b222527ede15bdeb0..ce02944b7fe7a5e08cbaad271c59ee5c6f62663c 100644
--- a/tests/features/paragraphs/block.feature
+++ b/tests/features/paragraphs/block.feature
@@ -11,8 +11,8 @@ Feature: Block paragraph tests.
       | Early Omega  | Block collection | published |
       | Snake Timely | Block collection | published |
     And custom_page content:
-      | title                 | collection       | state     |
-      | Recommended solutions | Block collection | published |
+      | title                 | collection       | state     | abstract             |
+      | Recommended solutions | Block collection | published | Recommended abstract |
     And I append "block" to "field_paragraphs_body" field in "node" entity with following "Recommended solutions" title:
       | paragraph_block | views_block:recommended_solutions-recommended |
 
diff --git a/tests/features/paragraphs/call_to_action.feature b/tests/features/paragraphs/call_to_action.feature
index b9271591e92754465c400fc0fcf1a9d300f90d5b..ec0c27caf73ac6192429a30eb026a75691155243 100644
--- a/tests/features/paragraphs/call_to_action.feature
+++ b/tests/features/paragraphs/call_to_action.feature
@@ -11,8 +11,8 @@ Feature:
   @javascript
   Scenario: Call to action(s) has alignment setting.
     Given custom_page content:
-      | title               | collection            | state     |
-      | Call to action page | Paragraphs collection | published |
+      | title               | collection            | state     | abstract          |
+      | Call to action page | Paragraphs collection | published | CTA page abstract |
     And I append "layout" to "field_paragraphs_body" field in "node" entity with following "Call to action page" title:
       | behavior_settings | a:3:{s:17:"layout_paragraphs";a:4:{s:6:"layout";s:13:"layout_onecol";s:6:"config";a:1:{s:5:"label";s:0:"";}s:11:"parent_uuid";N;s:6:"region";N;}s:16:"background_theme";a:0:{}s:11:"extra_class";a:0:{}} |
 
diff --git a/tests/features/paragraphs/carousel.feature b/tests/features/paragraphs/carousel.feature
index 7e8f8434a226caa7de6e566731e8015ab62f3d71..5d4e235f67667aadc5df792cd4387dbac498c353 100644
--- a/tests/features/paragraphs/carousel.feature
+++ b/tests/features/paragraphs/carousel.feature
@@ -13,10 +13,10 @@ Feature:
       | title  | state     |
       | Sparta | published |
     And custom_page content:
-      | title       | headline    | collection  | content       | state     |
-      | Some page 1 | Some page 1 | Roman ruins | Some content. | published |
-      | Some page 2 | Some page 2 | Sparta      | Some content. | published |
-      | Some page 3 | Some page 3 | Sparta      | Some content. | published |
+      | title       | headline    | collection  | content       | state     | abstract             |
+      | Some page 1 | Some page 1 | Roman ruins | Some content. | published | Some page 1 abstract |
+      | Some page 2 | Some page 2 | Sparta      | Some content. | published | Some page 2 abstract |
+      | Some page 3 | Some page 3 | Sparta      | Some content. | published | Some page 3 abstract |
 
     When I am logged in as a moderator
     And I go to the homepage
@@ -24,7 +24,8 @@ Feature:
     And I click "Add custom page" in the plus button menu
 
     When I fill in the following:
-      | Title | Pages carousel |
+      | Title    | Pages carousel          |
+      | Abstract | Abstract pages carousel |
     And I select "HR" from "Topic"
     And I add a layout paragraph in the "Custom page body" form field with the following properties:
       | layout           | one column |
diff --git a/tests/features/paragraphs/content_listing.feature b/tests/features/paragraphs/content_listing.feature
index 9b01e8f1bc6798169c62c1e9ef0e99b13f691d82..c454addb7a1a0bf989717365c52ae57f9a685519 100644
--- a/tests/features/paragraphs/content_listing.feature
+++ b/tests/features/paragraphs/content_listing.feature
@@ -12,9 +12,9 @@ Feature:
       | title  | state     |
       | Sparta | published |
     And news content:
-      | title       | headline    | collection  | content       | state     |
-      | Some news 1 | Some news 1 | Roman ruins | Some content. | published |
-      | Some news 2 | Some news 2 | Sparta      | Come content. | published |
+      | title       | headline    | collection  | content       | state     | abstract             |
+      | Some news 1 | Some news 1 | Roman ruins | Some content. | published | Some news 1 abstract |
+      | Some news 2 | Some news 2 | Sparta      | Come content. | published | Some news 2 abstract |
 
     And custom_page content:
       | title         | collection  | state     |
diff --git a/tests/features/paragraphs/custom_page.paragraphs.feature b/tests/features/paragraphs/custom_page.paragraphs.feature
index c218592014e81164bb0d962d72ec35171f086039..0bfd5cd2b70a1f34e19f2fcf8b56757fa4bfdb63 100644
--- a/tests/features/paragraphs/custom_page.paragraphs.feature
+++ b/tests/features/paragraphs/custom_page.paragraphs.feature
@@ -12,8 +12,8 @@ Feature:
   @javascript
   Scenario: Paragraph sections are multivalue and sort-able.
     Given custom_page content:
-      | title           | collection            | state     | topic |
-      | Paragraphs page | Paragraphs collection | published | HR    |
+      | title           | collection            | state     | topic | abstract                 |
+      | Paragraphs page | Paragraphs collection | published | HR    | Paragraphs page abstract |
     And I append "layout" to "field_paragraphs_body" field in "node" entity with following "Paragraphs page" title:
       | behavior_settings | a:3:{s:17:"layout_paragraphs";a:4:{s:6:"layout";s:13:"layout_onecol";s:6:"config";a:1:{s:5:"label";s:0:"";}s:11:"parent_uuid";N;s:6:"region";N;}s:16:"background_theme";a:0:{}s:11:"extra_class";a:0:{}} |
 
diff --git a/tests/features/paragraphs/entity_reference.feature b/tests/features/paragraphs/entity_reference.feature
index 97189fe353ff4fb07cb8c0e423a81b51e4752f0c..9e170e830a15cd39e951cd206650ea6d2d2c7b98 100644
--- a/tests/features/paragraphs/entity_reference.feature
+++ b/tests/features/paragraphs/entity_reference.feature
@@ -11,9 +11,9 @@ Feature:
   @javascript
   Scenario: Entity reference displays related content.
     Given custom_page content:
-      | title                 | collection            | state     |
-      | Entity reference page | Paragraphs collection | published |
-      | Related content       | Paragraphs collection | published |
+      | title                 | collection            | state     | abstract              |
+      | Entity reference page | Paragraphs collection | published | Entity page abstract  |
+      | Related content       | Paragraphs collection | published | Related page abstract |
     And I append "layout" to "field_paragraphs_body" field in "node" entity with following "Entity reference page" title:
       | behavior_settings | a:3:{s:17:"layout_paragraphs";a:4:{s:6:"layout";s:13:"layout_onecol";s:6:"config";a:1:{s:5:"label";s:0:"";}s:11:"parent_uuid";N;s:6:"region";N;}s:16:"background_theme";a:0:{}s:11:"extra_class";a:0:{}} |
 
diff --git a/tests/features/paragraphs/github_feed.feature b/tests/features/paragraphs/github_feed.feature
index d64e2e67bce15fc6be3b9f6d4519148c01c90b38..8ec38f39bc8ee0d1d27937edbfd700f439920e95 100644
--- a/tests/features/paragraphs/github_feed.feature
+++ b/tests/features/paragraphs/github_feed.feature
@@ -9,8 +9,8 @@ Feature: Github feed paragraph tests.
       | title              | state     |
       | Paragraphs <group> | published |
     And custom_page content:
-      | title                   | <group>            | state     | topic                   |
-      | Catalogue of paragraphs | Paragraphs <group> | published | Statistics and Analysis |
+      | title                   | <group>            | state     | topic                   | abstract                |
+      | Catalogue of paragraphs | Paragraphs <group> | published | Statistics and Analysis | Catalogue page abstract |
     And I append "layout" to "field_paragraphs_body" field in "node" entity with following "Catalogue of paragraphs" title:
       | behavior_settings | a:3:{s:17:"layout_paragraphs";a:4:{s:6:"layout";s:13:"layout_onecol";s:6:"config";a:1:{s:5:"label";s:0:"";}s:11:"parent_uuid";N;s:6:"region";N;}s:16:"background_theme";a:0:{}s:11:"extra_class";a:0:{}} |
 
diff --git a/tests/features/paragraphs/heading.feature b/tests/features/paragraphs/heading.feature
index 2049fb0e31d591eff51d5ed51e77817bcce2bff0..2bf7b24190aaf1a0605cabdb0136307db30a8cca 100644
--- a/tests/features/paragraphs/heading.feature
+++ b/tests/features/paragraphs/heading.feature
@@ -10,8 +10,8 @@ Feature:
 
   Scenario: Heading paragraph is displayed as heading element.
     Given custom_page content:
-      | title                | collection            | state     |
-      | Heading example page | Paragraphs collection | published |
+      | title                | collection            | state     | abstract              |
+      | Heading example page | Paragraphs collection | published | Heading page abstract |
     And I append "heading" to "field_paragraphs_body" field in "node" entity with following "Heading example page" title:
       | paragraph_heading | H2 heading paragraph                                      |
       | behavior_settings | a:1:{s:16:"heading_behavior";a:1:{s:5:"level";s:2:"h2";}} |
@@ -34,8 +34,8 @@ Feature:
   @javascript
   Scenario: User should be able to edit behaviour settings.
     Given custom_page content:
-      | title                  | collection            | state     |
-      | Behaviour example page | Paragraphs collection | published |
+      | title                  | collection            | state     | abstract |
+      | Behaviour example page | Paragraphs collection | published | N/A      |
     And I append "layout" to "field_paragraphs_body" field in "node" entity with following "Behaviour example page" title:
       | behavior_settings | a:3:{s:17:"layout_paragraphs";a:4:{s:6:"layout";s:13:"layout_onecol";s:6:"config";a:1:{s:5:"label";s:0:"";}s:11:"parent_uuid";N;s:6:"region";N;}s:16:"background_theme";a:0:{}s:11:"extra_class";a:0:{}} |
 
diff --git a/tests/features/paragraphs/moderator.feature b/tests/features/paragraphs/iframe.feature
similarity index 69%
rename from tests/features/paragraphs/moderator.feature
rename to tests/features/paragraphs/iframe.feature
index f3adf3b5fea2b4deb2975bfd71da1b27a69e7b6d..770cf2b3030347d22ea2f173d1b8dfee48b2e00a 100644
--- a/tests/features/paragraphs/moderator.feature
+++ b/tests/features/paragraphs/iframe.feature
@@ -1,7 +1,7 @@
 @api @group-h
 Feature:
   As a moderator of the site
-  I need to be able to use "iframe" and "map" paragraphs for content.
+  I need to be able to use "iframe" paragraphs for content.
 
   Background:
     Given collection content:
@@ -9,7 +9,7 @@ Feature:
       | Paragraphs collection | published | HR    |
 
   @javascript
-  Scenario: Moderator can manage map and iframe paragraph.
+  Scenario: Moderator can manage iframe paragraph.
     Given users:
       | Username |
       | Zohan    |
@@ -17,8 +17,8 @@ Feature:
       | collection            | user  |
       | Paragraphs collection | Zohan |
     And custom_page content:
-      | title                     | body        | collection            | author | state     | topic |
-      | Don't Mess with the Zohan | Wanna mess? | Paragraphs collection | Zohan  | published | HR    |
+      | title                     | abstract             | body        | collection            | author | state     | topic |
+      | Don't Mess with the Zohan | Wanna mess abstract? | Wanna mess? | Paragraphs collection | Zohan  | published | HR    |
     And I append "layout" to "field_paragraphs_body" field in "node" entity with following "Don't Mess with the Zohan" title:
       | behavior_settings | a:3:{s:17:"layout_paragraphs";a:4:{s:6:"layout";s:13:"layout_onecol";s:6:"config";a:1:{s:5:"label";s:0:"";}s:11:"parent_uuid";N;s:6:"region";N;}s:16:"background_theme";a:0:{}s:11:"extra_class";a:0:{}} |
 
@@ -50,3 +50,13 @@ Feature:
     And I press "Update"
     Then I should see the success message "Custom page Don't Mess with the Zohan has been updated."
     And the response should contain "{\"foo\":\"bar\"}"
+
+  Scenario: Consent declaration should be displayed for PowerBI.
+    Given custom_page content:
+      | title               | collection            | state     |
+      | Iframe page example | Paragraphs collection | published |
+    And I append "iframe" to "field_paragraphs_body" field in "node" entity with following "Iframe page example" title:
+      | field_iframe:url | https://app.powerbi.com/view?r=dummy-report |
+
+    When I go to the "Iframe page example" custom page
+    And the response should contain "src=\"https://webtools.europa.eu/crs/iframe/?oriurl=https%3A//app.powerbi.com/view%3Fr%3Ddummy-report&amp;lang=en\""
diff --git a/tests/features/paragraphs/image.feature b/tests/features/paragraphs/image.feature
index 6d70dca517647db750b5c8e19d2ab9838389eb42..cdbc1b1fd4f6a8503c648894118dd24094ad49e9 100644
--- a/tests/features/paragraphs/image.feature
+++ b/tests/features/paragraphs/image.feature
@@ -11,8 +11,8 @@ Feature:
   @javascript @uploadFiles:logo.png
   Scenario: User should be able to add image paragraph.
     Given custom_page content:
-      | title                | collection            | state     |
-      | Image paragraph page | Paragraphs collection | published |
+      | title                | collection            | state     | abstract            |
+      | Image paragraph page | Paragraphs collection | published | Image page abstract |
     And I append "layout" to "field_paragraphs_body" field in "node" entity with following "Image paragraph page" title:
       | behavior_settings | a:3:{s:17:"layout_paragraphs";a:4:{s:6:"layout";s:13:"layout_onecol";s:6:"config";a:1:{s:5:"label";s:0:"";}s:11:"parent_uuid";N;s:6:"region";N;}s:16:"background_theme";a:0:{}s:11:"extra_class";a:0:{}} |
 
diff --git a/tests/features/paragraphs/image_gallery.feature b/tests/features/paragraphs/image_gallery.feature
index 11fe96c193ed217072a340c74319559d658bc6a3..eed7f751ffc6b02fe69e8717beb7b029a540dffe 100644
--- a/tests/features/paragraphs/image_gallery.feature
+++ b/tests/features/paragraphs/image_gallery.feature
@@ -11,8 +11,8 @@ Feature:
   @javascript @uploadFiles:logo.png,topic.png,banner.jpg,linus.jpeg
   Scenario: User should be able to add image gallery paragraph.
     Given custom_page content:
-      | title                        | collection               | state     |
-      | Image gallery paragraph page | Paragraphs IG collection | published |
+      | title                        | collection               | state     | abstract            |
+      | Image gallery paragraph page | Paragraphs IG collection | published | Image page abstract |
     And I append "layout" to "field_paragraphs_body" field in "node" entity with following "Image gallery paragraph page" title:
       | behavior_settings | a:3:{s:17:"layout_paragraphs";a:4:{s:6:"layout";s:13:"layout_onecol";s:6:"config";a:1:{s:5:"label";s:0:"";}s:11:"parent_uuid";N;s:6:"region";N;}s:16:"background_theme";a:0:{}s:11:"extra_class";a:0:{}} |
 
diff --git a/tests/features/paragraphs/layout_paragraphs.feature b/tests/features/paragraphs/layout_paragraphs.feature
index c2c3db95862805b6b5bb2639c4bb3c3fdd3dbfc6..2c3c13944d85bca97a857929b65b695e00cddbcf 100644
--- a/tests/features/paragraphs/layout_paragraphs.feature
+++ b/tests/features/paragraphs/layout_paragraphs.feature
@@ -9,8 +9,8 @@ Feature:
       | title         | state     |
       | Plaster molds | published |
     And custom_page content:
-      | title                  | collection    |
-      | Layout paragraphs test | Plaster molds |
+      | title                  | collection    | abstract             |
+      | Layout paragraphs test | Plaster molds | Layout page abstract |
     And I am logged in as a moderator
     And I go to the edit form of the "Layout paragraphs test" "custom page"
 
diff --git a/tests/features/paragraphs/map.feature b/tests/features/paragraphs/map.feature
new file mode 100644
index 0000000000000000000000000000000000000000..68634dabe007cd178d6043ee5b60fbdeb7779f89
--- /dev/null
+++ b/tests/features/paragraphs/map.feature
@@ -0,0 +1,35 @@
+@api @group-h
+Feature:
+  As a moderator of the site
+  I need to be able to use "map" paragraphs for content.
+
+  Background:
+    Given collection content:
+      | title                 | state     | topic |
+      | Paragraphs collection | published | HR    |
+
+  @javascript
+  Scenario: Moderator can manage map.
+    Given users:
+      | Username |
+      | Zohan    |
+    And the following collection user membership:
+      | collection            | user  |
+      | Paragraphs collection | Zohan |
+    And custom_page content:
+      | title                     | abstract | body        | collection            | author | state     | topic |
+      | Don't Mess with the Zohan | Wanna    | Wanna mess? | Paragraphs collection | Zohan  | published | HR    |
+    And I append "layout" to "field_paragraphs_body" field in "node" entity with following "Don't Mess with the Zohan" title:
+      | behavior_settings | a:3:{s:17:"layout_paragraphs";a:4:{s:6:"layout";s:13:"layout_onecol";s:6:"config";a:1:{s:5:"label";s:0:"";}s:11:"parent_uuid";N;s:6:"region";N;}s:16:"background_theme";a:0:{}s:11:"extra_class";a:0:{}} |
+
+    Given I am logged in as a moderator
+    And I go to the edit form of the "Don't Mess with the Zohan" "custom page"
+    And I click "Choose component"
+    And a modal should open
+    And I click "Map"
+    # As the Webtools Map a webservice, we only test a fake JSON.
+    And I fill in "JSON" with "{\"foo\":\"bar\"}"
+    And I press "Save" in the "Modal buttons" region
+    And I press "Update"
+    Then I should see the success message "Custom page Don't Mess with the Zohan has been updated."
+    And the response should contain "{\"foo\":\"bar\"}"
diff --git a/tests/features/paragraphs/poll.feature b/tests/features/paragraphs/poll.feature
index fde90e0088abde7c08a322165fb2ba5f00ace211..46691ad2ded35ef68b54821def294c305b68fccc 100644
--- a/tests/features/paragraphs/poll.feature
+++ b/tests/features/paragraphs/poll.feature
@@ -88,8 +88,8 @@ Feature: Pool paragraph tests.
 
   Scenario: Poll paragraph can be added
     Given custom_page content:
-      | title           | collection      | state     |
-      | Scariest things | Poll collection | published |
+      | title           | collection      | state     | abstract                 |
+      | Scariest things | Poll collection | published | Scariest things abstract |
     And I append "layout" to "field_paragraphs_body" field in "node" entity with following "Scariest things" title:
       | behavior_settings | a:3:{s:17:"layout_paragraphs";a:4:{s:6:"layout";s:13:"layout_onecol";s:6:"config";a:1:{s:5:"label";s:0:"";}s:11:"parent_uuid";N;s:6:"region";N;}s:16:"background_theme";a:0:{}s:11:"extra_class";a:0:{}} |
 
diff --git a/tests/features/paragraphs/quote.feature b/tests/features/paragraphs/quote.feature
index fa66dedc83c86eaa4c6b0c896a1ff8589c571d0b..92fcea3dbc7ac02e3975008fa6a9a0bd04321451 100644
--- a/tests/features/paragraphs/quote.feature
+++ b/tests/features/paragraphs/quote.feature
@@ -8,8 +8,8 @@ Feature: Quote paragraph tests.
 
   Scenario: View quote paragraph in the custom page.
     Given custom_page content:
-      | title          | collection            | state     |
-      | Popular quotes | Paragraphs collection | published |
+      | title          | collection            | state     | abstract             |
+      | Popular quotes | Paragraphs collection | published | quotes page abstract |
     And I append "quote" to "field_paragraphs_body" field in "node" entity with following "Popular Quotes" title:
       | paragraph_quote | That's one small step for a man, a giant leap for mankind. |
 
diff --git a/tests/features/paragraphs/social_media.feature b/tests/features/paragraphs/social_media.feature
index 6d953cdd667ca1b735f0a323929c4e4c30f9d452..01dbaab165b9a5ac844656acd6a88f6c209cbbe5 100644
--- a/tests/features/paragraphs/social_media.feature
+++ b/tests/features/paragraphs/social_media.feature
@@ -11,8 +11,8 @@ Feature:
   @javascript
   Scenario: Call to action(s) has alignment setting.
     Given custom_page content:
-      | title             | collection            | state     |
-      | Social media page | Paragraphs collection | published |
+      | title             | collection            | state     | abstract             |
+      | Social media page | Paragraphs collection | published | Social page abstract |
     And I append "layout" to "field_paragraphs_body" field in "node" entity with following "Social media page" title:
       | behavior_settings | a:3:{s:17:"layout_paragraphs";a:4:{s:6:"layout";s:13:"layout_onecol";s:6:"config";a:1:{s:5:"label";s:0:"";}s:11:"parent_uuid";N;s:6:"region";N;}s:16:"background_theme";a:0:{}s:11:"extra_class";a:0:{}} |
 
diff --git a/tests/features/paragraphs/text.feature b/tests/features/paragraphs/text.feature
index e8364d205378c4ba92ec466f8528b0e52618a2f8..f2ff53d6ac3418a4c446cefda3dc269e847e3f82 100644
--- a/tests/features/paragraphs/text.feature
+++ b/tests/features/paragraphs/text.feature
@@ -12,8 +12,8 @@ Feature:
   @javascript
   Scenario: Custom page content is trimmed properly.
     Given custom_page content:
-      | title          | collection            | state     |
-      | Popular quotes | Paragraphs collection | published |
+      | title          | collection            | state     | abstract            |
+      | Popular quotes | Paragraphs collection | published | Tiles page abstract |
     And I append "text" to "field_paragraphs_body" field in "node" entity with following "Popular Quotes" title:
       | field_body:value  |     That's one small step for a man, a giant leap for mankind. |
       | field_body:format | text_html                                                      |
@@ -21,7 +21,8 @@ Feature:
     And I am on the homepage
     And I enter "mankind" in the search bar and press enter
     # Regression test that text is trimmed properly.
-    Then the response should contain ">That's one small step for a man, a giant leap for mankind.<"
+    # After ISAICP-9140 shows the abstract field.
+    Then the response should contain "Tiles page abstract"
 
   Scenario: Table is visible.
     Given custom_page content:
diff --git a/tests/features/paragraphs/tiles.feature b/tests/features/paragraphs/tiles.feature
index 6350c5eac5fc5da1dbf6abcb556731405b54b243..d1a63751793a3b8cc3a92832161eb9ede95e0854 100644
--- a/tests/features/paragraphs/tiles.feature
+++ b/tests/features/paragraphs/tiles.feature
@@ -11,8 +11,8 @@ Feature:
   @javascript @uploadFiles:topic.png
   Scenario: Add tiles paragraph to one column layout.
     Given custom_page content:
-      | title                   | collection            | state     |
-      | Tiles paragraph example | Paragraphs collection | published |
+      | title                   | collection            | state     | abstract            |
+      | Tiles paragraph example | Paragraphs collection | published | Tiles page abstract |
     And I append "layout" to "field_paragraphs_body" field in "node" entity with following "Tiles paragraph example" title:
       | behavior_settings | a:3:{s:17:"layout_paragraphs";a:4:{s:6:"layout";s:13:"layout_onecol";s:6:"config";a:1:{s:5:"label";s:0:"";}s:11:"parent_uuid";N;s:6:"region";N;}s:16:"background_theme";a:0:{}s:11:"extra_class";a:0:{}} |
 
diff --git a/tests/features/paragraphs/video.feature b/tests/features/paragraphs/video.feature
index ed13fcd0311cd35aeeee2e0e77fdd7d05b6b75cc..b586ade076eb4b3a8871afacc3f1c56c10116580 100644
--- a/tests/features/paragraphs/video.feature
+++ b/tests/features/paragraphs/video.feature
@@ -2,16 +2,15 @@
 Feature: Video paragraph tests.
 
   Background:
-    Given the following collection:
-      | title | Paragraphs collection |
-      | state | published             |
-      | topic | HR                    |
+    Given collection content:
+      | title                 | state     | topic |
+      | Paragraphs collection | published | HR    |
 
   @javascript
   Scenario: Collection facilitators can add video paragraphs.
     Given custom_page content:
-      | title      | collection            | state     |
-      | Video page | Paragraphs collection | published |
+      | title      | collection            | state     | abstract            |
+      | Video page | Paragraphs collection | published | Video page abstract |
     And I append "layout" to "field_paragraphs_body" field in "node" entity with following "Video page" title:
       | behavior_settings | a:3:{s:17:"layout_paragraphs";a:4:{s:6:"layout";s:13:"layout_onecol";s:6:"config";a:1:{s:5:"label";s:0:"";}s:11:"parent_uuid";N;s:6:"region";N;}s:16:"background_theme";a:0:{}s:11:"extra_class";a:0:{}} |
 
diff --git a/tests/features/paragraphs/webform.feature b/tests/features/paragraphs/webform.feature
index 1d6120cff857e452a737248602daad8f59b44936..a655984edb29e2bb6d7b2e30ff26a019f6afdc4d 100644
--- a/tests/features/paragraphs/webform.feature
+++ b/tests/features/paragraphs/webform.feature
@@ -17,8 +17,8 @@ Feature:
       | id           | title        | elements                                           |
       | test_webform | Test webform | [{"#type": "textfield", "#title": "Test element"}] |
     Given custom_page content:
-      | title           | collection         | state     |
-      | Webform example | Webform collection | published |
+      | title           | collection         | state     | abstract                 |
+      | Webform example | Webform collection | published | Webform example abstract |
     And I append "layout" to "field_paragraphs_body" field in "node" entity with following "Webform example" title:
       | behavior_settings | a:3:{s:17:"layout_paragraphs";a:4:{s:6:"layout";s:13:"layout_onecol";s:6:"config";a:1:{s:5:"label";s:0:"";}s:11:"parent_uuid";N;s:6:"region";N;}s:16:"background_theme";a:0:{}s:11:"extra_class";a:0:{}} |
 
diff --git a/tests/features/smoke_test.feature b/tests/features/smoke_test.feature
index 345ec1f5ca88feff0a974b2d775b98fae4e6c50e..015e27a08fb871352394058a72c8e69d2a3aebf5 100644
--- a/tests/features/smoke_test.feature
+++ b/tests/features/smoke_test.feature
@@ -4,9 +4,6 @@ Feature: Minimal install clone testing.
   Scenario: Visit Joinup collection.
 
     Given I am an anonymous user
-    When I visit "/collection/portal"
-    Then I should see the link "Federation of solutions"
-
     When I visit "/search?keys=joinup&f[0]=type:collection"
     Then I should see the "The Portal" tile
     And I should see "The European Commission provides this common place"
@@ -20,5 +17,5 @@ Feature: Minimal install clone testing.
     When I visit "/interoperable_solutions"
     Then I should see the link "Solutions"
     And "Solutions" should be the active item in the "Navigation bar" region
-    Then I visit "/collection/joinup"
+    Then I visit "/collection/portal"
     And no menu items should be active in the "Navigation bar" region
diff --git a/tests/features/solution/manage_solutions.archive.feature b/tests/features/solution/manage_solutions.archive.feature
index fbec20c98e84d8aae78c198b9fb027c711fd9a32..4d95551e4e6db676f46ab441b7332311f039d0c0 100644
--- a/tests/features/solution/manage_solutions.archive.feature
+++ b/tests/features/solution/manage_solutions.archive.feature
@@ -23,7 +23,7 @@ Feature: When a solution is archived then its sub-content also should be archive
       | John Moderator     | john.moderator@example.com | John       | Moderator   | moderator |
     And the following solution user memberships:
       | solution | user               | roles                      |
-      | Solution | Anne Group Admin   | administrator, facilitator |
+      | Solution | Anne Group Admin   | owner                      |
       | Solution | Andrew Facilitator | facilitator                |
     And "event" content:
       | title          | solution | state     |
@@ -243,3 +243,20 @@ Feature: When a solution is archived then its sub-content also should be archive
       | John Moderator     |
       | Anne Group Admin   |
       | Andrew Facilitator |
+
+  Scenario Outline: Users must not be able to edit the sub-content of an archived solution
+    Given the workflow state of the "Solution" content is changed to "published"
+    And I am logged in as "<User>"
+
+    When I go to the homepage of the "Solution" solution
+    Then I should not see the text "Archived" in the "Header"
+    When I go to the edit form of the "Solution" solution
+    Then I should see the button "Archive"
+    And I press "Archive"
+    Then I should see the text "Archived" in the "Header"
+
+    Examples:
+      | User               |
+      | John Moderator     |
+      | Anne Group Admin   |
+      | Andrew Facilitator |
diff --git a/tests/features/solution/solution_moderation.feature b/tests/features/solution/solution_moderation.feature
index 6a336490bfd9adad399782ceafc91cd14ca9a944..af55166b722908f08b9a4af65943b2406b9687e0 100644
--- a/tests/features/solution/solution_moderation.feature
+++ b/tests/features/solution/solution_moderation.feature
@@ -91,7 +91,7 @@ Feature: Solution moderation
       # This is checked separately below.
       | Azure Ship                 | Franklin Walker  | Save as draft, Propose                                               |
       | The Last Illusion          | Franklin Walker  | Propose, Save as draft                                               |
-      | Rose of Doors              | Franklin Walker  | Publish, Save as draft, Propose                                      |
+      | Rose of Doors              | Franklin Walker  | Publish, Save as draft, Propose, Archive                             |
       | Fire Swords                | Franklin Walker  |                                                                      |
       | The Guardian of the Stream | Franklin Walker  | Save as draft, Propose                                               |
       | Flames in the Swords       | Franklin Walker  | Save as draft, Propose                                               |
@@ -100,7 +100,7 @@ Feature: Solution moderation
       # testes as shown.
       | Azure Ship                 | William Curtis   | Save as draft, Propose                                               |
       | The Last Illusion          | William Curtis   | Propose, Save as draft                                               |
-      | Rose of Doors              | William Curtis   | Publish, Save as draft, Propose                                      |
+      | Rose of Doors              | William Curtis   | Publish, Save as draft, Propose, Archive                             |
       | Fire Swords                | William Curtis   |                                                                      |
       | The Guardian of the Stream | William Curtis   | Save as draft, Propose                                               |
       | Flames in the Swords       | William Curtis   | Save as draft, Propose                                               |
diff --git a/tests/features/update/ISAICP-8572.feature b/tests/features/update/ISAICP-8572.feature
index bf056b3d1b097500866a67b3eebbe57bcecb6ac0..7a0e37d57312fa7b5f0ae0186f32c0e2a7520014 100644
--- a/tests/features/update/ISAICP-8572.feature
+++ b/tests/features/update/ISAICP-8572.feature
@@ -45,3 +45,130 @@ Feature: Test migration of collections/solutions to node.
     And I click "working group of experts"
     Then I should see "Asset Description Metadata Schema (ADMS)"
     Then I should see the heading "Members"
+
+  @update:joinup_rdf_deploy_200006
+  Scenario: Menu links should be available as before.
+    Given I go to "/collection/statistics/solution/eurotrace"
+    Then I should see the following links:
+      | Overview        |
+      | Release history |
+
+    Given I go to "/collection/govtechconnect"
+    Then I should see the heading "GovTech Connect"
+    And I should see the following links:
+      | Overview         |
+      | Welcome on Board |
+      | GovTech4All      |
+      | Events           |
+
+  @update:joinup_rdf_deploy_200001 @update:joinup_rdf_deploy_200002
+  Scenario: Validate references and contents of the groups.
+    # Ensure the Website link is migrated for collections.
+    Given I go to "/collection/are3na"
+    Then I should see the link "Website link"
+
+    # Note, that since the email confirmations are not available for GDPR
+    # reasons, the contact information are only text in the tests.
+    Given I go to "/collection/egovernment"
+    Then I should see the following lines of text:
+      | Owner                    |
+      | European Commission      |
+      | Supra-national authority |
+      | Contact information      |
+      | Joinup Support Team      |
+
+    # 12 solutions also include the 3 archived. This ensures a bug needing to
+    # clear the cache before indexing the entities.
+    And I should see the link "12 Solutions"
+
+    # Assert texts in the page.
+    And I should see the following lines of text:
+      # Abstract.
+      | The eGovernment community aims to improve the efficiency of service delivery in the public sector.           |
+      # Body.
+      | The eGovernment community covers all aspects of Internet use to deliver government information and services. |
+      # Field headings and values.
+      | Published on                                                                                                 |
+      | 01/12/2014                                                                                                   |
+      | Last updated                                                                                                 |
+      | Moderation                                                                                                   |
+      | Open collection                                                                                              |
+      | Moderated                                                                                                    |
+
+    # Sample check some tiles as it might be that the tiles will change until
+    # the migration is done so try to avoid too many checks.
+    And I should see the "Next generation internet initiative on EU digital landscape" tile
+    And I should see the "EU report calls for stronger action on Digital Decade goals" tile
+
+    Given I go to "/collection/statistics/solution/eurotrace"
+    Then I should see the following lines of text:
+      | Owner                    |
+      | Eurostat                 |
+      | Supra-national authority |
+      | Contact information      |
+      | ESTAT EUROTRACE SUPPORT  |
+
+    # Assert texts in the page.
+    And I should see the following lines of text:
+      # Abstract.
+      | The EUROTRACE software package is composed                 |
+      # Body.
+      | Because of its modular design, the new EUROTRACE suite can |
+      # Field headings and values.
+      | Published on                                               |
+      | 14/03/2014                                                 |
+      | Last update                                                |
+      | Solution type                                              |
+      | Digital Solution                                           |
+      | Release version                                            |
+      | Moderation                                                 |
+      | Only facilitators and authors can create content.          |
+      | Non moderated                                              |
+    And I should see the link "Share"
+
+    # Sample check some tiles as it might be that the tiles will change until
+    # the migration is done so try to avoid too many checks.
+    And I should see the "Mustangproject" tile
+
+    # Test the website link.
+    Given I go to "/collection/are3na/solution/re3gistry"
+    Then I should see the link "Website link"
+
+    # Regression test that there are no duplicate memberships.
+    # @see web/modules/custom/joinup_rdf/src/MigrationHelper.php:442
+    And there are no duplicate memberships
+
+    # Regression test that announcements are migrated with their group
+    # and the page does not break.
+    When I am logged in as a moderator
+    And I visit "/announcements"
+    Then I should see the link "Interoperable Europe Academy"
+
+  @update:joinup_rdf_update_200009 @update:joinup_rdf_deploy_200013
+  Scenario: Assert migrated related solutions.
+    Given I go to "/collection/eparticipation-and-evoting/solution/eci-online-collection-software-ocs"
+    Then in the "Related solutions" list, I should see the following tiles in the correct order:
+      | European Citizens' Initiative - Regulation (EU) 2019/788                                    |
+      | Crypto Tool for the European Parliament Elections and for the European Citizens' Initiative |
+    Given I go to "/collection/semic-support-centre/solution/vocbench"
+    Then in the "Related solutions" list, I should see the following tiles in the correct order:
+      # First 3 are shared solutions. Even if in production they do not show in
+      # this way, according to the migrated data, they all share the "Data
+      # management" solution type.
+      # /collection/gnu-health/solution/mygnuhealth.
+      | MyGNUHealth                                                                                                |
+      # /collection/open-data/solution/piveau.
+      | piveau                                                                                                     |
+      # /collection/free-and-open-source-software/solution/geonetwork.
+      | GeoNetwork opensource - A catalog solution to publish geospatial and non-geospatial metadata and resources |
+      # Then the rest are directly linked solutions. These follow the order of
+      # the data in the database.
+      | EuroVoc                                                                                                    |
+      | The AGROVOC Thesaurus                                                                                      |
+      | GEMET                                                                                                      |
+      | Integrated Public Sector Vocabulary                                                                        |
+      | DCAT-AP Validator                                                                                          |
+      | Asset Description Metadata Schema (ADMS)                                                                   |
+      | StatDCAT Application Profile for data portals in Europe                                                    |
+      | Asset Description Metadata Schema (ADMS) revision                                                          |
+      | ShowVoc                                                                                                    |
diff --git a/tests/src/Context/JoinupNotificationContext.php b/tests/src/Context/JoinupNotificationContext.php
index 0399a853ff81d21df88ca9747b6f237c8acc6b1b..ecc49d4ce3bb20ab887e0ba894ed36b00f9cc443 100644
--- a/tests/src/Context/JoinupNotificationContext.php
+++ b/tests/src/Context/JoinupNotificationContext.php
@@ -364,17 +364,32 @@ public function clearMailCollectorCache(): void {
    *
    * @param int $count
    *   The expected count of e-mails sent.
+   * @param string|null $recipients
+   *   (optional) A list of recipient emails.
    *
    * @throws \Exception
    *   Thrown when the count doesn't match the actual number.
    *
    * @Then :count e-mail(s) should have been sent
+   * @Then :count e-mail(s) should have been sent to recipients :recipients
    */
-  public function assertNumberOfEmailSent($count): void {
+  public function assertNumberOfEmailSent(int $count, ?string $recipients = NULL): void {
     $mails = $this->getMails();
     if (count($mails) != $count) {
       throw new \Exception("Invalid number of e-mail sent. Expected $count, sent " . count($mails));
     }
+    if ($recipients) {
+      $expected_recipients = $this->explodeCommaSeparatedStepArgument($recipients);
+      $actual_recipients = array_unique(array_map(
+        fn(array $mail): string => $mail['to'],
+        $mails,
+      ));
+      sort($expected_recipients);
+      sort($actual_recipients);
+      if ($expected_recipients !== $actual_recipients) {
+        throw new ExpectationFailedException("Expected recipients $recipients. Got " . implode(', ', $actual_recipients));
+      }
+    }
   }
 
   /**
diff --git a/tests/src/Context/JoinupUserContext.php b/tests/src/Context/JoinupUserContext.php
index 2565b3e61d95dfd70511121ab58f3be3d24a9b15..23de71d457f5ba1464fd8fa89fba9074bc3550cd 100644
--- a/tests/src/Context/JoinupUserContext.php
+++ b/tests/src/Context/JoinupUserContext.php
@@ -156,6 +156,7 @@ public static function massageFieldsBeforeUserCreate(BeforeUserCreateScope $scop
     self::convertObjectPropertyValues($user, 'status', [
       'blocked' => 0,
       'active' => 1,
+      'cancelled' => -1,
     ]);
   }
 
diff --git a/tests/src/Context/RdfContext.php b/tests/src/Context/RdfContext.php
index aa1a5a98a38a217d1e10ba3d81c414eb5bdb2e1a..83f3c373bd9560bd99e302a3822d5c69ae80cebe 100644
--- a/tests/src/Context/RdfContext.php
+++ b/tests/src/Context/RdfContext.php
@@ -333,4 +333,28 @@ public function assertNoTriplesOfUri(string $property, string $uri, string $grap
     Assert::assertCount(0, $results, "There are triples with $property $uri in the $graph graph. Results found: " . implode(', ', $messages));
   }
 
+  /**
+   * Asserts that there are no duplicate memberships in the database.
+   *
+   * @todo Remove this in ISAICP-8376.
+   *
+   * @Given /^there are no duplicate memberships$/
+   */
+  public function thereAreNoDuplicateMemberships(): void {
+    $query = <<<SQL
+SELECT uid, entity_id from og_membership
+GROUP BY uid, entity_id
+HAVING COUNT(*) > 1
+SQL;
+
+    $connection = \Drupal::getContainer()->get('database');
+    $results = $connection->query($query);
+    $messages = [];
+    foreach ($results as $result) {
+      $messages[] = sprintf('%s %s', $result->uid, $result->entity_id);
+    }
+
+    Assert::assertCount(0, $results, "There are duplicate memberships in the database. Results found: " . implode(', ', $messages));
+  }
+
 }
diff --git a/web/modules/custom/custom_page/src/Entity/CustomPage.php b/web/modules/custom/custom_page/src/Entity/CustomPage.php
index 2fc49908a6c857e7595a27fe6f1790a6d10cce01..b10bffcb3331c7354e85199e4658c79acb035224 100644
--- a/web/modules/custom/custom_page/src/Entity/CustomPage.php
+++ b/web/modules/custom/custom_page/src/Entity/CustomPage.php
@@ -5,6 +5,7 @@
 namespace Drupal\custom_page\Entity;
 
 use Drupal\collection\Entity\NodeCollectionContentTrait;
+use Drupal\joinup_bundle_class\AbstractTrait;
 use Drupal\joinup_bundle_class\DescriptionTrait;
 use Drupal\joinup_bundle_class\JoinupBundleClassFieldAccessTrait;
 use Drupal\joinup_bundle_class\LogoTrait;
@@ -21,6 +22,7 @@
  */
 class CustomPage extends Node implements CustomPageInterface {
 
+  use AbstractTrait;
   use ArchivableEntityTrait;
   use GroupArchivableEntityTrait;
   use DescriptionTrait;
@@ -35,8 +37,8 @@ class CustomPage extends Node implements CustomPageInterface {
   /**
    * {@inheritdoc}
    */
-  public function getLogoFieldName(): string {
-    return 'field_custom_page_logo';
+  public function getAbstractField(): string {
+    return 'abstract';
   }
 
   /**
@@ -46,6 +48,20 @@ public function getDescriptionField(): string {
     return 'field_paragraphs_body';
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getLogoFieldName(): string {
+    return 'field_custom_page_logo';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getWorkflowStateFieldName(): string {
+    return 'field_state';
+  }
+
   /**
    * {@inheritdoc}
    */
diff --git a/web/modules/custom/custom_page/src/Entity/CustomPageInterface.php b/web/modules/custom/custom_page/src/Entity/CustomPageInterface.php
index 3c11b7c5a98803b83439d22a35b2492210258132..aac8e3b7c1dcd18cce30edbabd47d41fb8dbe9b4 100644
--- a/web/modules/custom/custom_page/src/Entity/CustomPageInterface.php
+++ b/web/modules/custom/custom_page/src/Entity/CustomPageInterface.php
@@ -5,6 +5,7 @@
 namespace Drupal\custom_page\Entity;
 
 use Drupal\collection\Entity\CollectionContentInterface;
+use Drupal\joinup_bundle_class\AbstractInterface;
 use Drupal\joinup_bundle_class\DescriptionInterface;
 use Drupal\joinup_bundle_class\LogoInterface;
 use Drupal\joinup_core\Entity\PermalinkInterface;
@@ -19,7 +20,7 @@
 /**
  * Interface for content page node entities.
  */
-interface CustomPageInterface extends NodeInterface, GroupContentInterface, CollectionContentInterface, EntityPublicationTimeInterface, LogoInterface, DescriptionInterface, EntityWorkflowStateInterface, ArchivableEntityInterface, GroupArchivableEntityInterface, TopicReferencingEntityInterface, PermalinkInterface {
+interface CustomPageInterface extends NodeInterface, GroupContentInterface, CollectionContentInterface, EntityPublicationTimeInterface, LogoInterface, DescriptionInterface, EntityWorkflowStateInterface, ArchivableEntityInterface, GroupArchivableEntityInterface, TopicReferencingEntityInterface, PermalinkInterface, AbstractInterface {
 
   /**
    * Checks if this custom page is set as a landing page of the group.
diff --git a/web/modules/custom/joinup_community_content/joinup_community_content.module b/web/modules/custom/joinup_community_content/joinup_community_content.module
index f6cd192322dd29fb5f4f37dbdec3167c4fe168bc..81214530430182e81974ebac8c1c646d5f127ad1 100644
--- a/web/modules/custom/joinup_community_content/joinup_community_content.module
+++ b/web/modules/custom/joinup_community_content/joinup_community_content.module
@@ -68,7 +68,7 @@ function joinup_community_content_node_view(array &$build, EntityInterface $enti
   }
 
   if ($display->getComponent('share_link')) {
-    $build['share_link'] = joinup_group_generate_share_link($entity, 'joinup_group.share_content_form');
+    $build['share_link'] = joinup_group_generate_share_link($entity);
     $build['#cache'] = [
       'contexts' => [
         'og_role',
diff --git a/web/modules/custom/joinup_core/config/schema/joinup_core.schema.yml b/web/modules/custom/joinup_core/config/schema/joinup_core.schema.yml
index bfcbc10d01e5459b99c7d7052dd44bcb493931eb..356cfb3ac43245dc0970fa697a9930b7cf37af7a 100644
--- a/web/modules/custom/joinup_core/config/schema/joinup_core.schema.yml
+++ b/web/modules/custom/joinup_core/config/schema/joinup_core.schema.yml
@@ -133,6 +133,10 @@ field.formatter.settings.joinup_core_more_in_modal:
       type: string
       label: 'Display mode to use for rendering'
 
+field.formatter.settings.iframe_with_consent_declaration:
+  type: field.formatter.settings.iframe_default
+  label: 'Formatter "iframe_with_consent_declaration"'
+
 field.widget.settings.email_legacy_multicardinality:
   type: field.widget.settings.email_default
 
diff --git a/web/modules/custom/joinup_core/src/Plugin/Field/FieldFormatter/IframeWithConsentDeclarationFormatter.php b/web/modules/custom/joinup_core/src/Plugin/Field/FieldFormatter/IframeWithConsentDeclarationFormatter.php
new file mode 100644
index 0000000000000000000000000000000000000000..7f16f78322ad4d1a7d56127a484ac114ae2b8f15
--- /dev/null
+++ b/web/modules/custom/joinup_core/src/Plugin/Field/FieldFormatter/IframeWithConsentDeclarationFormatter.php
@@ -0,0 +1,82 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\joinup_core\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Field\Attribute\FieldFormatter;
+use Drupal\Core\Field\FieldItemListInterface;
+use Drupal\Core\StringTranslation\TranslatableMarkup;
+use Drupal\Core\Template\Attribute;
+use Drupal\Core\Url;
+use Drupal\iframe\Plugin\Field\FieldFormatter\IframeOnlyFormatter;
+
+/**
+ * Plugin implementation of the 'iframe_with_consent_declaration' formatter.
+ */
+#[FieldFormatter(
+  id: 'iframe_with_consent_declaration',
+  label: new TranslatableMarkup('Iframe with consent declaration'),
+  field_types: [
+    'iframe',
+  ],
+)]
+class IframeWithConsentDeclarationFormatter extends IframeOnlyFormatter {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items, $langcode) {
+    $elements = parent::viewElements($items, $langcode);
+
+    foreach ($elements as &$element) {
+      if (self::isSupported($element['#src']) && $element['#attributes'] instanceof Attribute) {
+        $element['#attributes']->setAttribute(
+          'src',
+          self::replaceUrlToConsentDeclaration($element['#src'], $langcode)
+        );
+      }
+    }
+
+    return $elements;
+  }
+
+  /**
+   * Replaces Url to consent declaration.
+   *
+   * @param string $src
+   *   Iframe URL.
+   * @param string $lang
+   *   The language that should be used to render the field.
+   *
+   * @return string
+   *   Consent declaration URL.
+   */
+  protected function replaceUrlToConsentDeclaration(string $src, string $lang): string {
+    return Url::fromUri(\OE_WEBTOOLS_COOKIE_CONSENT_EMBED_COOKIE_URL, [
+      'query' => [
+        'oriurl' => $src,
+        'lang' => $lang,
+      ],
+    ])->toString();
+  }
+
+  /**
+   * Checks if the consent declaration is supported.
+   *
+   * @param string $src
+   *   Iframe URL.
+   *
+   * @return bool
+   *   TRUE if consent declaration is supported
+   */
+  protected function isSupported(string $src): bool {
+    $supported = [
+      'app.powerbi.com',
+    ];
+
+    $parsed = parse_url($src);
+    return in_array($parsed['host'], $supported, TRUE);
+  }
+
+}
diff --git a/web/modules/custom/joinup_group/joinup_group.module b/web/modules/custom/joinup_group/joinup_group.module
index e2a2d09b5a6bca8e5a8e8fcccca0eb6a7c08d9f4..14e4df99ff241dbea724b95d1af7b520a7b53dc1 100644
--- a/web/modules/custom/joinup_group/joinup_group.module
+++ b/web/modules/custom/joinup_group/joinup_group.module
@@ -819,14 +819,12 @@ function joinup_group_extract_bulk_form_entity_id(string $bulk_form_key): string
  *
  * @param \Drupal\Core\Entity\EntityInterface $entity
  *   The entity related to the share link.
- * @param string $route
- *   The route to pass the share link in.
  *
  * @return array
  *   A link icon theme array.
  */
-function joinup_group_generate_share_link(EntityInterface $entity, string $route): array {
-  $url = Url::fromRoute($route, [$entity->getEntityTypeId() => $entity->id()]);
+function joinup_group_generate_share_link(EntityInterface $entity): array {
+  $url = Url::fromRoute('joinup_group.share_content_form', [$entity->getEntityTypeId() => $entity->id()]);
 
   return [
     '#theme' => 'link_icon',
diff --git a/web/modules/custom/joinup_rdf/joinup_rdf.deploy.php b/web/modules/custom/joinup_rdf/joinup_rdf.deploy.php
index b1f36538bc108123417f8c292802f22488756941..b0a2f1523ce2719f193d67643dc20e25af252974 100644
--- a/web/modules/custom/joinup_rdf/joinup_rdf.deploy.php
+++ b/web/modules/custom/joinup_rdf/joinup_rdf.deploy.php
@@ -10,7 +10,6 @@
 use Drupal\Core\Entity\Sql\SqlEntityStorageInterface;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\joinup_rdf\MigrationHelper;
-use Drupal\search_api_solr\SolrConnectorInterface;
 
 /**
  * Disable RDF Sync for the deployment.
@@ -99,10 +98,10 @@ function joinup_rdf_deploy_200002(array &$sandbox): string {
   $migration_helper = \Drupal::getContainer()->get('joinup_rdf.migration_helper');
   $start = microtime(TRUE);
   foreach ($uris as $uri) {
-    if (!$collectionNid ??= $sandbox['solution_to_collection'][$uri]) {
+    if (empty($sandbox['solution_to_collection'][$uri])) {
       throw new \Exception("Collection not found for solution: $uri");
     }
-    $migration_helper->migrateGroup('solution', $uri, $collectionNid);
+    $migration_helper->migrateGroup('solution', $uri, $sandbox['solution_to_collection'][$uri]);
     $sandbox['progress']++;
   }
 
@@ -147,6 +146,41 @@ function joinup_rdf_deploy_200004(): void {
     }
   }
 
+  // Fix the message__field_group_content.
+  $query = $db->select('b_message__field_group_content', 'b');
+  $results = $query
+    ->fields('b', [])
+    ->execute()
+    ->fetchAll();
+
+  // The field_group_content has been deleted in the config sync and a new field
+  // was created called group_content.
+  foreach ($results as $result) {
+    if ($result->field_group_content_target_type === 'rdf_entity') {
+      $result->field_group_content_target_id = $db->select('rdf_sync_uri', 'u')
+        ->fields('u', ['entity_id'])
+        ->condition('u.uri', $result->field_group_content_target_id)
+        ->execute()
+        ->fetchField();
+    }
+    $result->group_content_target_id = $result->field_group_content_target_id;
+    unset($result->field_group_content_target_type);
+    unset($result->field_group_content_target_id);
+    unset($result->field_group_content_target_id_int);
+  }
+
+  // Convert all objects to array.
+  $results = array_map('get_object_vars', $results);
+
+  // Insert the updated entries in the new message__group_content table.
+  foreach ($results as &$result) {
+    $db->insert('message__group_content')
+      ->fields(array_keys($result))
+      ->values($result)
+      ->execute();
+  }
+  $schema->dropTable('b_message__field_group_content');
+
   // Joinup log table.
   $query = $db->select('b_joinup_log', 'b');
   $query->innerJoin('rdf_sync_uri', 'u', 'b.group = u.uri');
@@ -316,6 +350,7 @@ function joinup_rdf_deploy_200006(?array &$sandbox = NULL): void {
     \Drupal::getContainer()->get('plugin.manager.menu.link')->rebuild();
     // Restore 'rediscover' flag.
     $db->query("UPDATE {menu_link_content_data} SET rediscover = 0 WHERE menu_name LIKE 'ogmenu-%'");
+    $db->query("UPDATE {menu_tree} SET discovered = 0 WHERE menu_name LIKE 'ogmenu-%'");
   }
 }
 
@@ -551,14 +586,58 @@ function joinup_rdf_deploy_200008(?array &$sandbox = NULL): string {
 }
 
 /**
- * Meta entity fix.
+ * Restore related solutions.
  */
 function joinup_rdf_deploy_200009(): void {
-  $db = \Drupal::database();
+  $data = \Drupal::state()->get('joinup_rdf.related_solutions', []);
+  $database = \Drupal::database();
+  $rdf_sync_mapper = \Drupal::getContainer()->get('rdf_sync.mapper');
+  $meta_entity_storage = \Drupal::entityTypeManager()->getStorage('meta_entity');
+
+  foreach ($data as $mid => $related_solutions) {
+    $meta_entity = $meta_entity_storage->load($mid);
+    $solution = $meta_entity->getTargetEntity();
+    ksort($related_solutions);
+    $target_ids = array_map(function ($uri) use ($rdf_sync_mapper) {
+      $entity = $rdf_sync_mapper->getEntityByUri($uri);
+      // Skip invalid references e.g.
+      // http://data.europa.eu/w21/5e74061e-dc4e-4734-a31f-e328b7ab4326.
+      if (!$entity) {
+        return NULL;
+      }
+      return $entity->id();
+    }, $related_solutions);
+
+    // Filter out invalid entries and reset deltas.
+    $target_ids = array_values(array_filter($target_ids));
+    foreach ($target_ids as $delta => $target_id) {
+      $values = [
+        'bundle' => 'node',
+        'deleted' => 0,
+        'entity_id' => $solution->id(),
+        'revision_id' => $solution->getRevisionId(),
+        'langcode' => $solution->language()->getId(),
+        'delta' => $delta,
+        'related_solutions_target_id' => $target_id,
+      ];
 
-  // Clear stale data.
-  $db->delete('meta_entity')->condition('id', 5609)->execute();
-  $db->delete('meta_entity__count')->condition('entity_id', 5609)->execute();
+      foreach (['node__related_solutions', 'node_revision__related_solutions'] as $table) {
+        $database->insert($table)
+          ->fields(array_keys($values))
+          ->values($values)
+          ->execute();
+      }
+    }
+  }
+
+  \Drupal::state()->delete('joinup_rdf.related_solutions');
+}
+
+/**
+ * Meta entity fix.
+ */
+function joinup_rdf_deploy_200010(): void {
+  $db = \Drupal::database();
 
   // Fix labels referring RDF entities.
   $sql = <<<SQL
@@ -570,7 +649,11 @@ function joinup_rdf_deploy_200009(): void {
   $db->query($sql, [], ['allow_delimiter_in_query' => TRUE]);
 
   // Fill the integer version of ID.
-  $db->query("UPDATE {meta_entity} SET target__target_id_int = target__target_id");
+  $db->query("UPDATE {meta_entity} SET target__target_id_int = target__target_id WHERE target__target_id REGEXP '^[0-9]+$'");
+  // Due to a bug in production, some download_count meta entities were not
+  // properly deleted when their distribution was deleted. Delete the invalid
+  // entries.
+  $db->query("DELETE FROM {meta_entity} WHERE target__target_id_int IS NULL AND type = 'download_count'");
 
   // Fix 'rdf entity' ocuurrences in label.
   $db->query("UPDATE meta_entity SET label = REPLACE(label, 'rdf entity (', 'content item (')");
@@ -579,7 +662,7 @@ function joinup_rdf_deploy_200009(): void {
 /**
  * Fix EU OSS Catalogue menu link.
  */
-function joinup_rdf_deploy_200010(): void {
+function joinup_rdf_deploy_200011(): void {
   \Drupal::getContainer()->get('entity.repository')
     ->loadEntityByUuid('menu_link_content', '686904d4-8e5f-4dfd-baea-e4e6c6496984')
     ->save();
@@ -588,7 +671,7 @@ function joinup_rdf_deploy_200010(): void {
 /**
  * Filters in content listings.
  */
-function joinup_rdf_deploy_200011(?array &$sandbox = NULL): void {
+function joinup_rdf_deploy_200012(?array &$sandbox = NULL): void {
   if (!isset($sandbox['tables'])) {
     $sandbox['tables'] = [];
 
@@ -654,71 +737,36 @@ function joinup_rdf_deploy_200011(?array &$sandbox = NULL): void {
 }
 
 /**
- * Reindex group content.
+ * Cleanup the simple sitemap calculated data.
  */
-function joinup_rdf_deploy_200012(?array &$sandbox = NULL): string {
-  if (!isset($sandbox['nids'])) {
-    $sandbox['nids'] = \Drupal::database()->select('node__og_audience')
-      ->fields('node__og_audience', ['entity_id'])
-      ->condition('bundle', [
-        'custom_page',
-        'discussion',
-        'distribution',
-        'document',
-        'event',
-        'glossary',
-        'news',
-        'release',
-      ], 'IN')
-      ->execute()
-      ->fetchCol();
-    $sandbox['uri_to_nid'] = \Drupal::getContainer()->get('joinup_rdf.migration_helper')->getUriToNid();
-    $sandbox['total'] = count($sandbox['nids']);
-    $sandbox['progress'] = 0;
-  }
-
-  $amount = 100;
-  $nids = array_splice($sandbox['nids'], 0, $amount);
-  $sandbox['progress'] += count($nids);
-
-  $solr = \Drupal::entityTypeManager()
-    ->getStorage('search_api_server')
-    ->load('joinup')
-    ->getBackend()
-    ->getSolrConnector();
-  assert($solr instanceof SolrConnectorInterface);
-
-  $query = $solr->getSelectQuery()
-    ->setQuery('its_nid:(' . implode(' OR ', $nids) . ') AND sm_entity_groups:[* TO *]')
-    ->setRows($amount);
-
-  $documents = $solr->execute($query)->getData()['response']['docs'] ?? [];
-  $updateQuery = $solr->getUpdateQuery();
-  foreach ($documents as &$document) {
-    $document['sm_entity_groups'] = array_map(function (string $group) use ($sandbox): string {
-      if (!isset($sandbox['uri_to_nid'][$group])) {
-        throw new \RuntimeException("Group '$group' doesn't have a NID");
-      }
-      return $sandbox['uri_to_nid'][$group];
-    }, $document['sm_entity_groups']);
-    // Convert to a document object.
-    $document = $updateQuery->createDocument($document);
-  }
+function joinup_rdf_deploy_200013(): void {
+  // Sitemap keeps stashed and queued data that might contain data from the
+  // removed "rdf_entity" entities.
+  \Drupal::keyValue('simple_sitemap')->delete('queue_stashed_results');
+  \Drupal::service('queue')->get('simple_sitemap_elements')->deleteQueue();
+}
 
-  $updateQuery = $solr
-    ->getUpdateQuery()
-    ->addDocuments($documents)
-    ->addCommit();
-  $solr->update($updateQuery);
+/**
+ * Clear the purge_queue table of anything related to rdf_entity.
+ */
+function joinup_rdf_deploy_200014(): void {
+  $data = \Drupal::database()->select('purge_queue', 'pq')
+    ->fields('pq', ['item_id'])
+    ->condition('pq.data', '%rdf_entity%', 'LIKE')
+    ->execute()
+    ->fetchCol();
 
-  $sandbox['#finished'] = (int) empty($sandbox['nids']);
-  return "Reindexed {$sandbox['progress']}/{$sandbox['total']} nodes";
+  if ($data) {
+    \Drupal::database()->delete('purge_queue')
+      ->condition('item_id', $data, 'IN')
+      ->execute();
+  }
 }
 
 /**
  * Add URL alias for a taxonomy term.
  */
-function joinup_rdf_deploy_200013(): void {
+function joinup_rdf_deploy_200015(): void {
   $system_path = '/taxonomy/term/11197';
   $alias_path = '/taxonomy/term/http_e_f_fjoinup_ceu_fontology_ftopic_hstatistics_band_binformatino';
 
diff --git a/web/modules/custom/joinup_rdf/joinup_rdf.install b/web/modules/custom/joinup_rdf/joinup_rdf.install
index 712a311f246fe7dab9177a92f48fdf75a296d8c5..14228e78d5c3aac7241797272540e8a6b085b374 100644
--- a/web/modules/custom/joinup_rdf/joinup_rdf.install
+++ b/web/modules/custom/joinup_rdf/joinup_rdf.install
@@ -139,6 +139,9 @@ function joinup_rdf_update_200004(): void {
     }
   }
 
+  $db->query("CREATE TABLE b_message__field_group_content LIKE message__field_group_content");
+  $db->insert('b_message__field_group_content')->from($db->select('message__field_group_content')->fields('message__field_group_content'))->execute();
+
   $db->query("CREATE TABLE b_joinup_log LIKE joinup_log");
   $db->insert('b_joinup_log')->from($db->select('joinup_log')->fields('joinup_log'))->execute();
   $db->truncate('joinup_log')->execute();
@@ -154,6 +157,8 @@ function joinup_rdf_update_200005(): void {
     'node.og_audience',
     'media.og_audience',
     'ogmenu_instance.og_audience',
+    'meta_entity.field_pinned_in',
+    'message.group',
   ];
 
   foreach ($fieldStorages as $fieldStorage) {
@@ -162,7 +167,7 @@ function joinup_rdf_update_200005(): void {
 
   $configs = [
     'field.field.media.image.og_audience',
-    'field.field.media.video.og_audience',
+    'field.field.media.remote_video.og_audience',
     'field.field.media.file.og_audience',
     'field.field.node.news.field_news_referenced_solution',
     'field.field.node.news.og_audience',
@@ -177,6 +182,8 @@ function joinup_rdf_update_200005(): void {
     'field.field.node.discussion.field_shared_in',
     'field.field.node.custom_page.og_audience',
     'field.field.node.release.og_audience',
+    'field.field.meta_entity.pinned_in.field_pinned_in',
+    'field.field.message.announcement.group',
     'search_api.index.bookmark',
     'search_api.index.oss_catalogue',
     'search_api.index.published',
@@ -231,3 +238,22 @@ function joinup_rdf_update_200008(): void {
   require_once DRUPAL_ROOT . '/core/modules/user/user.install';
   user_update_10000();
 }
+
+/**
+ * Backup the field_ss_related_solutions in a state variable.
+ */
+function joinup_rdf_update_200009(): void {
+  $database = \Drupal::database();
+  $table = 'meta_entity__field_ss_related_solutions';
+  $results = $database->select($table)
+    ->fields($table, ['entity_id', 'delta', 'field_ss_related_solutions_target_id'])
+    ->execute()
+    ->fetchAll(\PDO::FETCH_ASSOC);
+
+  $state_data = [];
+  foreach ($results as $data) {
+    $state_data[$data['entity_id']][$data['delta']] = $data['field_ss_related_solutions_target_id'];
+  }
+
+  \Drupal::state()->set('joinup_rdf.related_solutions', $state_data);
+}
diff --git a/web/modules/custom/joinup_rdf/joinup_rdf.services.yml b/web/modules/custom/joinup_rdf/joinup_rdf.services.yml
index 151bc3e8e2ab0df05eb5225b8cc3daa451a24f6b..5afdad4518b6059b4217d0acc14ad28898d5f22f 100644
--- a/web/modules/custom/joinup_rdf/joinup_rdf.services.yml
+++ b/web/modules/custom/joinup_rdf/joinup_rdf.services.yml
@@ -26,7 +26,7 @@ services:
 
   joinup_rdf.migration_helper:
     class: Drupal\joinup_rdf\MigrationHelper
-    arguments: ['@entity_type.manager', '@path_alias.repository', '@database', '@rdf_sync.connection', '@rdf_sync.mapper']
+    arguments: ['@entity_type.manager', '@path_alias.repository', '@database', '@rdf_sync.connection', '@rdf_sync.mapper', '@state']
 
   joinup_rdf.http_middleware.accept_based_negotiation:
     class: Drupal\joinup_rdf\Middleware\JoinupAcceptHeaderMiddleware
diff --git a/web/modules/custom/joinup_rdf/src/MigrationHelper.php b/web/modules/custom/joinup_rdf/src/MigrationHelper.php
index f6c7f7fd062720ab222987ba7ee80f83d4214aa4..cb09ee66584158a69652340b994e747bb3e1b288 100644
--- a/web/modules/custom/joinup_rdf/src/MigrationHelper.php
+++ b/web/modules/custom/joinup_rdf/src/MigrationHelper.php
@@ -7,6 +7,7 @@
 use Drupal\Core\Database\Connection;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\State\StateInterface;
 use Drupal\joinup_group\Entity\GroupInterface;
 use Drupal\joinup_rdf\Entity\RdfSyncEntityInterface;
 use Drupal\joinup_taxonomy\Entity\MappedTerm;
@@ -29,6 +30,8 @@ final class MigrationHelper {
     ['node', 'og_audience', TRUE],
     ['media', 'og_audience', TRUE],
     ['ogmenu_instance', 'og_audience', FALSE],
+    ['meta_entity', 'field_pinned_in', FALSE],
+    ['message', 'group', FALSE],
   ];
 
   public const array DEDICATED_TABLE_COLUMNS = [
@@ -187,7 +190,7 @@ final class MigrationHelper {
       ],
       'http://xmlns.com/foaf/spec/#term_homepage' => [
         'target_field_name' => 'website_url',
-        'format' => 'string',
+        'format' => 'uri',
       ],
       'http://purl.org/dc/terms/spatial' => [
         'target_field_name' => 'spatial_coverage',
@@ -257,6 +260,7 @@ final class MigrationHelper {
       'http://www.w3.org/ns/dcat#contactPoint' => [
         'target_field_name' => 'contact',
         'format' => 'reference',
+        'mapped_term' => TRUE,
       ],
       'http://joinup.eu/search' => [
         'target_field_name' => 'listing_content',
@@ -280,11 +284,12 @@ final class MigrationHelper {
       ],
       'http://www.w3.org/ns/dcat#landingPage' => [
         'target_field_name' => 'landing_page',
-        'format' => 'string',
+        'format' => 'uri',
       ],
       'http://purl.org/dc/terms/language' => [
         'target_field_name' => 'language',
         'format' => 'reference',
+        'mapped_term' => TRUE,
       ],
       'http://purl.org/dc/dcmitype/StillImage' => [
         // @todo Create a follow up to merge all logo fields into one.
@@ -306,6 +311,7 @@ final class MigrationHelper {
       'http://purl.org/dc/terms/publisher' => [
         'target_field_name' => 'owner',
         'format' => 'reference',
+        'mapped_term' => TRUE,
       ],
       'http://purl.org/dc/terms/relation' => [
         'target_field_name' => 'related_solutions',
@@ -343,6 +349,7 @@ final class MigrationHelper {
       'http://www.w3.org/ns/adms#translation' => [
         'target_field_name' => 'translation',
         'format' => 'reference',
+        'mapped_term' => TRUE,
       ],
       // @todo Minimal old data exist.
       // @codingStandardsIgnoreStart
@@ -373,6 +380,7 @@ final class MigrationHelper {
       'http://www.w3.org/ns/adms#status' => [
         'target_field_name' => 'process_status',
         'format' => 'string',
+        'mapped_term' => TRUE,
       ],
       'http://joinup.eu/vocabulary/topic' => [
         'target_field_name' => 'field_topic',
@@ -388,6 +396,7 @@ public function __construct(
     protected Connection $connection,
     protected RdfSyncConnectionInterface $sparqlEndpoint,
     protected RdfSyncMapper $rdfSyncMapper,
+    protected StateInterface $state,
   ) {}
 
   /**
@@ -428,6 +437,16 @@ public function migrateGroup(string $type, string $uri, ?int $collectionNid = NU
         $group->save();
       }
     }
+
+    // The group is creating one membership by default. However, in order to
+    // keep existing data, we are converting the existing memberships from the
+    // groups in joinup_rdf_deploy_200004. Remove all memberships of the groups
+    // created by the migration. Do not check if the group is new because the
+    // group might have been already created by the release migration.
+    $this->connection->delete('og_membership')
+      ->condition('entity_type', 'node')
+      ->condition('entity_id', $group->id())
+      ->execute();
   }
 
   /**
@@ -495,7 +514,31 @@ protected function massageValues(GroupInterface $group, array $values): void {
     foreach (self::FIELD_MAPPING[$group->bundle()] as $property => $mapping) {
       $value = $values[$property] ?? NULL;
       if ($value) {
-        $value = $this->parseValue($value, $mapping);
+        if ($property === 'http://joinup.eu/search') {
+          $unserialized = unserialize($value[0], ['allowed_classes' => FALSE]);
+          $submap = [
+            'collection' => [
+              'source' => 'field_collection_content_status',
+              'target' => 'collection_content_status',
+            ],
+            'solution' => [
+              'source' => 'field_is_content_status',
+              'target' => 'solution_content_status',
+            ],
+          ];
+          $data = $unserialized['fields'][$submap[$group->bundle()]['source']];
+          unset($unserialized['fields'][$submap[$group->bundle()]['source']]);
+          $unserialized['fields'][$submap[$group->bundle()]['target']] = $data;
+          $value[0] = serialize($unserialized);
+        }
+        elseif ($property === 'http://purl.org/dc/terms/relation') {
+          // Skip related solutions. The target entities might not have been
+          // migrated yet, so we will handle them in a separate migration.
+          // @see \joinup_rdf_update_200009.
+          // @see \joinup_rdf_deploy_200013.
+          continue;
+        }
+        $value = $this->parseValue($value, $mapping, $property);
         $group->set($mapping['target_field_name'], $value);
       }
 
@@ -549,11 +592,13 @@ protected function save(RdfSyncEntityInterface $entity): void {
    *   The values to parse.
    * @param array $mappingData
    *   The mapping data.
+   * @param string $property
+   *   The property/predicate URI.
    *
    * @return array
    *   The parsed values.
    */
-  protected function parseValue(array $values, array $mappingData): mixed {
+  protected function parseValue(array $values, array $mappingData, string $property): mixed {
     $parsed = [];
     $format = $mappingData['format'];
 
@@ -655,7 +700,7 @@ protected function assertMigratedEntity(EntityInterface $entity, array $values):
 
       $targetFieldName = $fieldData['target_field_name'];
       $field = $loaded->get($targetFieldName);
-      $value = $this->parseValue($value, $fieldData);
+      $value = $this->parseValue($value, $fieldData, $uri);
       if ($value !== $field->value) {
         print sprintf('The value of the field %s is not correct. Expected: %s, got: %s', $targetFieldName, print_r($value, TRUE), print_r($field->value, TRUE));
       }
diff --git a/web/modules/custom/joinup_release/tests/src/ExistingSite/ReleaseWorkflowTest.php b/web/modules/custom/joinup_release/tests/src/ExistingSite/ReleaseWorkflowTest.php
index f2531916724f56407febb7c90f92b6cad3aa7cbd..77c53f8e21faf2235d569d788f9759ed0b417fa4 100644
--- a/web/modules/custom/joinup_release/tests/src/ExistingSite/ReleaseWorkflowTest.php
+++ b/web/modules/custom/joinup_release/tests/src/ExistingSite/ReleaseWorkflowTest.php
@@ -436,10 +436,13 @@ public function workflowTransitionsProvider(): array {
           'needs_update',
         ],
         'userOgFacilitator' => [
+          'archived',
           'draft',
           'published',
         ],
-        'userOgAdministrator' => [],
+        'userOgAdministrator' => [
+          'archived',
+        ],
       ],
       'needs_update' => [
         'userAuthenticated' => [],
diff --git a/web/modules/custom/joinup_solution/joinup_solution.module b/web/modules/custom/joinup_solution/joinup_solution.module
index 83d71111576f6c373db0f27f48c223ec9b7503df..b4c36177bc0153c7fbb17f3be53eb780072b71ed 100644
--- a/web/modules/custom/joinup_solution/joinup_solution.module
+++ b/web/modules/custom/joinup_solution/joinup_solution.module
@@ -27,7 +27,6 @@
 use Drupal\joinup_solution\SolutionLatestReleasesFieldItemList;
 use Drupal\joinup_solution\SolutionReleasesAndDistributionsFieldItemList;
 use Drupal\joinup_taxonomy\Entity\MappedTerm;
-use Drupal\meta_entity\Entity\MetaEntity;
 use Drupal\node\Entity\Node;
 use Drupal\node\Entity\NodeType;
 use Drupal\node\NodeInterface;
@@ -149,7 +148,6 @@ function joinup_solution_node_insert(EntityInterface $entity): void {
     $membership->save();
   }
   joinup_solution_invalidate_collection($entity);
-  joinup_solution_sync_settings($entity);
 }
 
 /**
@@ -381,7 +379,7 @@ function joinup_solution_node_view(array &$build, NodeInterface $solution, Entit
 
   // Share link configuration.
   if ($display->getComponent('share_link')) {
-    $build['share_link'] = joinup_group_generate_share_link($solution, 'joinup_group.share_form');
+    $build['share_link'] = joinup_group_generate_share_link($solution);
     $build['#cache'] = [
       'contexts' => [
         'og_role',
@@ -588,10 +586,7 @@ function joinup_solution_node_update(EntityInterface $entity): void {
     return;
   }
 
-  assert($entity instanceof SolutionInterface);
-
   joinup_solution_invalidate_collection($entity);
-  joinup_solution_sync_settings($entity);
 }
 
 /**
@@ -619,76 +614,6 @@ function joinup_solution_node_delete(NodeInterface $solution): void {
   }
 }
 
-/**
- * Sync the solution settings with the corresponding entity.
- *
- * Stores the values of the related solutions of a solution to a meta entity in
- * order to handle the deltas.
- *
- * Due to a limitation in the RDF Entity module it is currently not possible to
- * store weights in multivalue fields. We work around this by storing them in a
- * meta entity (which is not subject to this problem since it uses SQL storage).
- * Once RDF entities can store deltas / weights reliably we will not need this
- * workaround anymore.
- *
- * @param \Drupal\joinup_solution\Entity\SolutionInterface $entity
- *   The solution entity.
- *
- * @todo Remove in ISAICP-9153.
- */
-function joinup_solution_sync_settings(SolutionInterface $entity): void {
-  if (!$entity->isPublished()) {
-    // Do not store any unsaved updates.
-    return;
-  }
-
-  // Avoid a hard dependency on the meta_entity module.
-  if (!\Drupal::moduleHandler()->moduleExists('meta_entity')) {
-    return;
-  }
-
-  $meta_entity = MetaEntity::loadOrCreate('solution_settings', $entity);
-
-  // Avoid saving an extra entity without need.
-  if ($meta_entity->get('field_ss_related_solutions')->equals($entity->get('related_solutions'))) {
-    return;
-  }
-
-  $meta_entity->set('field_ss_related_solutions', $entity->get('related_solutions')->getValue());
-  $meta_entity->save();
-}
-
-/**
- * Implements hook_ENTITY_TYPE_load().
- *
- * Syncs the order of the related solutions back to the entity.
- */
-function joinup_solution_node_load(array $entities): void {
-  // Avoid a hard dependency on the meta_entity module.
-  if (!\Drupal::moduleHandler()->moduleExists('meta_entity')) {
-    return;
-  }
-
-  foreach ($entities as $entity) {
-    if (!($entity instanceof SolutionInterface)) {
-      continue;
-    }
-
-    if (!$entity->isPublished()) {
-      // Do not sync anything for unpublished entities since they can be work in
-      // progress.
-      continue;
-    }
-
-    $meta_entity = MetaEntity::loadOrCreate('solution_settings', $entity);
-    if ($meta_entity->get('field_ss_related_solutions')->isEmpty()) {
-      return;
-    }
-
-    $entity->set('related_solutions', $meta_entity->get('field_ss_related_solutions')->getValue());
-  }
-}
-
 /**
  * Implements hook_module_implements_alter().
  *
diff --git a/web/modules/custom/joinup_subscription/joinup_subscription.module b/web/modules/custom/joinup_subscription/joinup_subscription.module
index b9c883d8b6df6119e9172a330b1c781c7f52c30d..b21354b0bc4fa3e470def4838b23140984ecbbf2 100644
--- a/web/modules/custom/joinup_subscription/joinup_subscription.module
+++ b/web/modules/custom/joinup_subscription/joinup_subscription.module
@@ -75,6 +75,12 @@ function joinup_subscription_entity_bundle_info_alter(&$bundles): void {
  * community content items within each group are sorted alphabetically.
  */
 function joinup_subscription_message_digest_aggregate_alter(array &$context, UserInterface $account, MessageNotifierInterface $notifier): void {
+  if (!$account->isActive()) {
+    // Prevent delivery when the user is blocked or cancelled.
+    $context['deliver'] = FALSE;
+    return;
+  }
+
   // Only act on the group community content digest. Bail out if this contains
   // any other message.
   if (!array_reduce($context['messages'], function (bool $carry, MessageInterface $message): bool {
diff --git a/web/modules/custom/joinup_subscription/src/Entity/GroupContentSubscriptionMessage.php b/web/modules/custom/joinup_subscription/src/Entity/GroupContentSubscriptionMessage.php
index d3dc7787d1efd443327734055ce47c1b8cf82165..3c3d2e774d88b51dfd9c30d6c63cfe60b98defa9 100644
--- a/web/modules/custom/joinup_subscription/src/Entity/GroupContentSubscriptionMessage.php
+++ b/web/modules/custom/joinup_subscription/src/Entity/GroupContentSubscriptionMessage.php
@@ -21,7 +21,7 @@ class GroupContentSubscriptionMessage extends Message implements GroupContentSub
   /**
    * The name of the field that references the group content for this message.
    */
-  const GROUP_CONTENT_REFERENCE_FIELD = 'field_group_content';
+  const GROUP_CONTENT_REFERENCE_FIELD = 'group_content';
 
   /**
    * The message template for this message.
diff --git a/web/modules/custom/joinup_subscription/src/EventSubscriber/GroupContentSubscriptionSubscriber.php b/web/modules/custom/joinup_subscription/src/EventSubscriber/GroupContentSubscriptionSubscriber.php
index 4182fdca83a1da91be9dc84aa5b48aa2ffe64fe0..4edd6f4845f501075c824e8a0e0f930b892aa427 100644
--- a/web/modules/custom/joinup_subscription/src/EventSubscriber/GroupContentSubscriptionSubscriber.php
+++ b/web/modules/custom/joinup_subscription/src/EventSubscriber/GroupContentSubscriptionSubscriber.php
@@ -227,9 +227,8 @@ protected function sendMessage(GroupContentInterface $group_content): bool {
       // user's chosen digest frequency.
       foreach ($this->getSubscribers($group_content) as $subscriber) {
         $message = GroupContentSubscriptionMessage::create([
-          'field_group_content' => [
+          'group_content' => [
             0 => [
-              'target_type' => $group_content->getEntityTypeId(),
               'target_id' => $group_content->id(),
             ],
           ],