diff --git a/config/optional/field.storage.node.comment.yml b/config/optional/field.storage.node.comment.yml
new file mode 100644
index 0000000..4713148
--- /dev/null
+++ b/config/optional/field.storage.node.comment.yml
@@ -0,0 +1,18 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - comment
+    - node
+id: node.comment
+field_name: comment
+entity_type: node
+type: comment
+settings:
+  comment_type: comment
+module: comment
+locked: false
+cardinality: 1
+translatable: true
+indexes: {  }
+persist_with_no_fields: false
diff --git a/config/optional/field.storage.node.field_image.yml b/config/optional/field.storage.node.field_image.yml
new file mode 100644
index 0000000..eb40f37
--- /dev/null
+++ b/config/optional/field.storage.node.field_image.yml
@@ -0,0 +1,26 @@
+id: node.field_image
+field_name: field_image
+entity_type: node
+type: image
+module: image
+settings:
+  uri_scheme: public
+  default_image:
+    uuid: null
+    alt: ''
+    title: ''
+    width: null
+    height: null
+locked: false
+cardinality: 1
+translatable: true
+indexes:
+  target_id:
+    - target_id
+status: true
+langcode: en
+dependencies:
+  module:
+    - node
+    - image
+persist_with_no_fields: false
diff --git a/config/optional/field.storage.node.field_tags.yml b/config/optional/field.storage.node.field_tags.yml
new file mode 100644
index 0000000..71e0425
--- /dev/null
+++ b/config/optional/field.storage.node.field_tags.yml
@@ -0,0 +1,17 @@
+id: node.field_tags
+field_name: field_tags
+entity_type: node
+type: entity_reference
+module: taxonomy
+settings:
+  target_type: taxonomy_term
+locked: false
+cardinality: -1
+translatable: true
+status: true
+langcode: en
+dependencies:
+  module:
+    - node
+    - taxonomy
+persist_with_no_fields: false
diff --git a/config/schema/collect.schema.yml b/config/schema/collect.schema.yml
index 616ace4..b0c9c26 100644
--- a/config/schema/collect.schema.yml
+++ b/config/schema/collect.schema.yml
@@ -109,3 +109,8 @@ collect.relation_type.*:
     plugin_id:
       type: string
       label: Relation plugin ID
+
+"search_api.datasource.plugin.collect:*":
+  type: mapping
+  label: 'Collect datasource configuration'
+  mapping: { }
diff --git a/crm/config/schema/collect_crm.schema.yml b/crm/config/schema/collect_crm.schema.yml
index 2a1d480..2861b95 100644
--- a/crm/config/schema/collect_crm.schema.yml
+++ b/crm/config/schema/collect_crm.schema.yml
@@ -1,3 +1,21 @@
+collect.processor.contact_matcher_mail:
+  type: collect.processor
+  label: Contact matcher processor settings
+  mapping:
+    relation:
+      type: string
+      label: Relation name
+    contact_type:
+      type: string
+      label: Contact type to match or create
+    fields:
+      type: sequence
+      label: Mapping from contact fields to model properties
+      sequence:
+        # Contact field names are keys.
+        type: string
+        label: Model property
+
 collect.processor.contact_matcher:
   type: collect.processor
   label: Contact matcher processor settings
diff --git a/demo/collect_demo.info.yml b/demo/collect_demo.info.yml
index 11f6fab..a64d3b0 100644
--- a/demo/collect_demo.info.yml
+++ b/demo/collect_demo.info.yml
@@ -10,3 +10,9 @@ dependencies:
   - node
   - search_api_db
   - views
+  - path
+  - image
+  - text
+  - comment
+  - collect
+  - taxonomy
diff --git a/demo/collect_demo.install b/demo/collect_demo.install
index c11274d..3e35e2b 100644
--- a/demo/collect_demo.install
+++ b/demo/collect_demo.install
@@ -40,7 +40,7 @@ function collect_demo_install() {
   // Override default host property in the model configuration and replace it
   // with current host.
   $schema_uri = 'http://schema.md-systems.ch/collect/0.0.1/collectjson/' . \Drupal::request()->getHost() . '/entity';
-  \Drupal::configFactory()->getEditable('collect.model.article')->set('uri_pattern', "$schema_uri/node/article")->save();
+  \Drupal::configFactory()->getEditable('collect.model.collect_demo')->set('uri_pattern', "$schema_uri/node/collect_demo")->save();
   \Drupal::configFactory()->getEditable('collect.model.user')->set('uri_pattern', "$schema_uri/user")->save();
 
   // Create a user.
@@ -54,7 +54,7 @@ function collect_demo_install() {
   // Create a node that will be automatically captured.
   $node = Node::create([
     'title' => t('Collect Demo'),
-    'type' => 'article',
+    'type' => 'collect_demo',
     'uid' => $user->id(),
     'body' => [
       'value' => '<p>' . t('Welcome to the Collect Demo module!') . '</p>'
diff --git a/demo/config/optional/collect.model.article.yml b/demo/config/optional/collect.model.collect_demo.yml
similarity index 98%
rename from demo/config/optional/collect.model.article.yml
rename to demo/config/optional/collect.model.collect_demo.yml
index bf76291..0571bfd 100644
--- a/demo/config/optional/collect.model.article.yml
+++ b/demo/config/optional/collect.model.collect_demo.yml
@@ -8,9 +8,9 @@ dependencies:
     - image
     - path
     - text
-id: article
-label: Article
-uri_pattern: 'http://schema.md-systems.ch/collect/0.0.1/collectjson/HOST/entity/node/article'
+id: collect_demo
+label: collect_demo
+uri_pattern: 'http://schema.md-systems.ch/collect/0.0.1/collectjson/HOST/entity/node/collect_demo'
 plugin_id: collectjson
 locked: false
 container_revision: true
@@ -444,7 +444,7 @@ properties:
       field_type: text_with_summary
       field_name: body
       entity_type: node
-      bundle: article
+      bundle: collect_demo
       label: Body
       description: ''
       required: false
@@ -468,7 +468,7 @@ properties:
       field_type: comment
       field_name: comment
       entity_type: node
-      bundle: article
+      bundle: collect_demo
       label: Comments
       description: ''
       required: true
@@ -493,7 +493,7 @@ properties:
       field_type: image
       field_name: field_image
       entity_type: node
-      bundle: article
+      bundle: collect_demo
       label: Image
       description: ''
       required: false
@@ -534,7 +534,7 @@ properties:
       field_type: entity_reference
       field_name: field_tags
       entity_type: node
-      bundle: article
+      bundle: collect_demo
       label: Tags
       description: 'Enter a comma-separated list. For example: Amsterdam, Mexico City, "Cleveland, Ohio"'
       required: false
diff --git a/demo/config/optional/core.entity_form_display.node.collect_demo.default.yml b/demo/config/optional/core.entity_form_display.node.collect_demo.default.yml
new file mode 100644
index 0000000..596122f
--- /dev/null
+++ b/demo/config/optional/core.entity_form_display.node.collect_demo.default.yml
@@ -0,0 +1,85 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - field.field.node.collect_demo.body
+    - field.field.node.collect_demo.comment
+    - field.field.node.collect_demo.field_image
+    - field.field.node.collect_demo.field_tags
+    - node.type.collect_demo
+  module:
+    - comment
+    - entity_reference
+    - image
+    - path
+    - taxonomy
+    - text
+id: node.collect_demo.default
+targetEntityType: node
+bundle: collect_demo
+mode: default
+content:
+  title:
+    type: string_textfield
+    weight: 0
+    settings:
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+  body:
+    type: text_textarea_with_summary
+    weight: 1
+    settings:
+      rows: 9
+      summary_rows: 3
+      placeholder: ''
+    third_party_settings: {  }
+  field_tags:
+    type: entity_reference_autocomplete_tags
+    weight: 3
+    settings: {  }
+    third_party_settings: {  }
+  field_image:
+    type: image_image
+    weight: 4
+    settings:
+      progress_indicator: throbber
+      preview_image_style: thumbnail
+    third_party_settings: {  }
+  uid:
+    type: entity_reference_autocomplete
+    weight: 5
+    settings:
+      match_operator: CONTAINS
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+  created:
+    type: datetime_timestamp
+    weight: 10
+    settings: {  }
+    third_party_settings: {  }
+  promote:
+    type: boolean_checkbox
+    settings:
+      display_label: true
+    weight: 15
+    third_party_settings: {  }
+  sticky:
+    type: boolean_checkbox
+    settings:
+      display_label: true
+    weight: 16
+    third_party_settings: {  }
+  comment:
+    type: comment_default
+    weight: 20
+    settings: {  }
+    third_party_settings: {  }
+  path:
+    type: path
+    weight: 30
+    settings: {  }
+    third_party_settings: {  }
+hidden: {  }
+third_party_settings: {  }
diff --git a/demo/config/optional/core.entity_view_display.node.collect_demo.default.yml b/demo/config/optional/core.entity_view_display.node.collect_demo.default.yml
new file mode 100644
index 0000000..a68e8dc
--- /dev/null
+++ b/demo/config/optional/core.entity_view_display.node.collect_demo.default.yml
@@ -0,0 +1,55 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - field.field.node.collect_demo.body
+    - field.field.node.collect_demo.comment
+    - field.field.node.collect_demo.field_image
+    - field.field.node.collect_demo.field_tags
+    - node.type.collect_demo
+  module:
+    - comment
+    - image
+    - taxonomy
+    - text
+    - user
+id: node.collect_demo.default
+targetEntityType: node
+bundle: collect_demo
+mode: default
+content:
+  field_image:
+    type: image
+    weight: -1
+    settings:
+      image_style: large
+      image_link: ''
+    third_party_settings: {  }
+    label: hidden
+  body:
+    type: text_default
+    weight: 0
+    settings: {  }
+    third_party_settings: {  }
+    label: hidden
+  field_tags:
+    type: entity_reference_label
+    weight: 10
+    label: above
+    settings:
+      link: true
+    third_party_settings: {  }
+  comment:
+    label: above
+    type: comment_default
+    weight: 20
+    settings:
+      pager_id: 0
+    third_party_settings: {  }
+  links:
+    weight: 100
+hidden:
+  langcode: true
+  field_image: true
+  field_tags: true
+third_party_settings: {  }
diff --git a/demo/config/optional/core.entity_view_display.node.collect_demo.rss.yml b/demo/config/optional/core.entity_view_display.node.collect_demo.rss.yml
new file mode 100644
index 0000000..345748a
--- /dev/null
+++ b/demo/config/optional/core.entity_view_display.node.collect_demo.rss.yml
@@ -0,0 +1,26 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - core.entity_view_mode.node.rss
+    - field.field.node.collect_demo.body
+    - field.field.node.collect_demo.comment
+    - field.field.node.collect_demo.field_image
+    - field.field.node.collect_demo.field_tags
+    - node.type.collect_demo
+  module:
+    - user
+id: node.collect_demo.rss
+targetEntityType: node
+bundle: collect_demo
+mode: rss
+content:
+  links:
+    weight: 100
+hidden:
+  langcode: true
+  body: true
+  comment: true
+  field_image: true
+  field_tags: true
+third_party_settings: {  }
diff --git a/demo/config/optional/core.entity_view_display.node.collect_demo.teaser.yml b/demo/config/optional/core.entity_view_display.node.collect_demo.teaser.yml
new file mode 100644
index 0000000..97bb628
--- /dev/null
+++ b/demo/config/optional/core.entity_view_display.node.collect_demo.teaser.yml
@@ -0,0 +1,50 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - core.entity_view_mode.node.teaser
+    - field.field.node.collect_demo.body
+    - field.field.node.collect_demo.comment
+    - field.field.node.collect_demo.field_image
+    - field.field.node.collect_demo.field_tags
+    - node.type.collect_demo
+  module:
+    - image
+    - taxonomy
+    - text
+    - user
+id: node.collect_demo.teaser
+targetEntityType: node
+bundle: collect_demo
+mode: teaser
+content:
+  field_image:
+    type: image
+    weight: -1
+    settings:
+      image_style: medium
+      image_link: content
+    third_party_settings: {  }
+    label: hidden
+  body:
+    type: text_summary_or_trimmed
+    weight: 0
+    settings:
+      trim_length: 600
+    third_party_settings: {  }
+    label: hidden
+  field_tags:
+    type: entity_reference_label
+    weight: 10
+    settings:
+      link: true
+    third_party_settings: {  }
+    label: above
+  links:
+    weight: 100
+hidden:
+  langcode: true
+  field_image: true
+  field_tags: true
+  comment: true
+third_party_settings: {  }
diff --git a/demo/config/optional/field.field.node.collect_demo.body.yml b/demo/config/optional/field.field.node.collect_demo.body.yml
new file mode 100644
index 0000000..5c20562
--- /dev/null
+++ b/demo/config/optional/field.field.node.collect_demo.body.yml
@@ -0,0 +1,22 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - field.storage.node.body
+    - node.type.collect_demo
+  module:
+    - text
+id: node.collect_demo.body
+field_name: body
+entity_type: node
+bundle: collect_demo
+label: Body
+description: ''
+required: false
+translatable: true
+default_value: {  }
+default_value_callback: ''
+settings:
+  display_summary: true
+third_party_settings: {  }
+field_type: text_with_summary
diff --git a/demo/config/optional/field.field.node.collect_demo.comment.yml b/demo/config/optional/field.field.node.collect_demo.comment.yml
new file mode 100644
index 0000000..f108df5
--- /dev/null
+++ b/demo/config/optional/field.field.node.collect_demo.comment.yml
@@ -0,0 +1,33 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - field.storage.node.comment
+    - node.type.collect_demo
+  module:
+    - comment
+id: node.collect_demo.comment
+field_name: comment
+entity_type: node
+bundle: collect_demo
+label: Comments
+description: ''
+required: true
+translatable: true
+default_value:
+  -
+    status: 2
+    cid: 0
+    last_comment_name: null
+    last_comment_timestamp: 0
+    last_comment_uid: 0
+    comment_count: 0
+default_value_callback: ''
+settings:
+  default_mode: 1
+  per_page: 50
+  form_location: true
+  anonymous: 0
+  preview: 1
+third_party_settings: {  }
+field_type: comment
diff --git a/demo/config/optional/field.field.node.collect_demo.field_image.yml b/demo/config/optional/field.field.node.collect_demo.field_image.yml
new file mode 100644
index 0000000..bbc0f02
--- /dev/null
+++ b/demo/config/optional/field.field.node.collect_demo.field_image.yml
@@ -0,0 +1,32 @@
+id: node.collect_demo.field_image
+entity_type: node
+bundle: collect_demo
+field_name: field_image
+label: Image
+description: ''
+required: false
+default_value: {  }
+default_value_callback: ''
+settings:
+  file_directory: field/image
+  file_extensions: 'png gif jpg jpeg'
+  max_filesize: ''
+  max_resolution: ''
+  min_resolution: ''
+  alt_field: true
+  title_field: false
+  alt_field_required: true
+  title_field_required: false
+  default_image:
+    uuid: null
+    alt: ''
+    title: ''
+    width: null
+    height: null
+status: true
+langcode: en
+field_type: image
+dependencies:
+  config:
+    - field.storage.node.field_image
+    - node.type.collect_demo
diff --git a/demo/config/optional/field.field.node.collect_demo.field_tags.yml b/demo/config/optional/field.field.node.collect_demo.field_tags.yml
new file mode 100644
index 0000000..9b95cde
--- /dev/null
+++ b/demo/config/optional/field.field.node.collect_demo.field_tags.yml
@@ -0,0 +1,26 @@
+id: node.collect_demo.field_tags
+entity_type: node
+bundle: collect_demo
+field_name: field_tags
+field_type: entity_reference
+label: Tags
+description: 'Enter a comma-separated list. For example: Amsterdam, Mexico City, "Cleveland, Ohio"'
+required: false
+default_value: {  }
+default_value_callback: ''
+settings:
+  handler: default
+  handler_settings:
+    target_bundles:
+      tags: tags
+    sort:
+      field: _none
+    auto_create: true
+status: true
+langcode: en
+dependencies:
+  config:
+    - field.storage.node.field_tags
+    - node.type.collect_demo
+  module:
+    - entity_reference
diff --git a/demo/config/optional/filter.format.full_html.yml b/demo/config/optional/filter.format.full_html.yml
new file mode 100644
index 0000000..cfdf9e2
--- /dev/null
+++ b/demo/config/optional/filter.format.full_html.yml
@@ -0,0 +1,35 @@
+format: full_html
+name: 'Full HTML'
+status: true
+weight: 1
+roles:
+  - administrator
+filters:
+  filter_align:
+    id: filter_align
+    provider: filter
+    status: true
+    weight: 8
+    settings: {  }
+  filter_caption:
+    id: filter_caption
+    provider: filter
+    status: true
+    weight: 9
+    settings: {  }
+  filter_htmlcorrector:
+    id: filter_htmlcorrector
+    provider: filter
+    status: true
+    weight: 10
+    settings: {  }
+  editor_file_reference:
+    id: editor_file_reference
+    provider: editor
+    status: true
+    weight: 11
+    settings: {  }
+langcode: en
+dependencies:
+  module:
+    - editor
diff --git a/demo/config/optional/node.type.collect_demo.yml b/demo/config/optional/node.type.collect_demo.yml
new file mode 100644
index 0000000..35fcdbe
--- /dev/null
+++ b/demo/config/optional/node.type.collect_demo.yml
@@ -0,0 +1,9 @@
+type: collect_demo
+name: collect_demo
+description: 'Use <em>Collect Content</em> for time-sensitive content like news, press releases or blog posts.'
+help: ''
+new_revision: false
+preview_mode: 1
+display_submitted: true
+status: true
+langcode: en
diff --git a/demo/config/optional/search_api.index.collect_demo.yml b/demo/config/optional/search_api.index.collect_demo.yml
index 1415342..b52f7f3 100644
--- a/demo/config/optional/search_api.index.collect_demo.yml
+++ b/demo/config/optional/search_api.index.collect_demo.yml
@@ -11,9 +11,9 @@ options:
       weights: {  }
       settings: {  }
   fields:
-    'collect:article/body:summary_processed':
+    'collect:collect_demo/body:summary_processed':
       type: text
-    'collect:article/body:processed':
+    'collect:collect_demo/body:processed':
       type: text
     'collect:email_message/body':
       type: text
@@ -23,18 +23,18 @@ options:
       type: text
     'collect:user/mail':
       type: text
-    'collect:article/title':
+    'collect:collect_demo/title':
       type: text
   'additional fields':
-    'collect:article/body': 'collect:article/body'
+    'collect:collect_demo/body': 'collect:collect_demo/body'
 datasources:
-  - 'collect:article'
+  - 'collect:collect_demo'
   - 'collect:collectjson_definition'
   - 'collect:email_message'
   - 'collect:user'
   - 'collect:web_resource'
 datasource_configs:
-  'collect:article': {  }
+  'collect:collect_demo': {  }
   'collect:collectjson_definition': {  }
   'collect:email_message': {  }
   'collect:user': {  }
@@ -49,3 +49,4 @@ dependencies:
     - search_api.server.collect_demo
   module:
     - collect
+    - inmail_collect
diff --git a/demo/config/optional/search_api.server.collect_demo.yml b/demo/config/optional/search_api.server.collect_demo.yml
index fe005d7..4a17d74 100644
--- a/demo/config/optional/search_api.server.collect_demo.yml
+++ b/demo/config/optional/search_api.server.collect_demo.yml
@@ -5,7 +5,6 @@ status: true
 backend: search_api_db
 backend_config:
   database: 'default:default'
-  database_text: ''
   min_chars: 1
   autocomplete:
     suggest_suffix: true
@@ -14,3 +13,5 @@ langcode: en
 dependencies:
   module:
     - search_api_db
+    - collect
+    - inmail
diff --git a/demo/config/optional/views.view.collect_demo.yml b/demo/config/optional/views.view.collect_demo.yml
index 088eb68..ae13e5d 100644
--- a/demo/config/optional/views.view.collect_demo.yml
+++ b/demo/config/optional/views.view.collect_demo.yml
@@ -3,6 +3,7 @@ status: true
 dependencies:
   module:
     - search_api
+    - search_api_db_defaults
     - user
   config:
     - search_api.index.collect_demo
diff --git a/src/Plugin/search_api/datasource/CollectDatasource.php b/src/Plugin/search_api/datasource/CollectDatasource.php
index 85594bd..d5fff91 100644
--- a/src/Plugin/search_api/datasource/CollectDatasource.php
+++ b/src/Plugin/search_api/datasource/CollectDatasource.php
@@ -161,4 +161,13 @@ class CollectDatasource extends DatasourcePluginBase {
     return $this->schema->buildTeaser($item);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function calculateDependencies() {
+    $this->dependencies += parent::calculateDependencies();
+    $this->addDependency('module', $this->getPluginDefinition()['provider']);
+    return $this->dependencies;
+  }
+
 }
