diff --git a/core/modules/field/config/schema/field.source.schema.yml b/core/modules/field/config/schema/field.source.schema.yml
index 6ebe95b..8976ce1 100644
--- a/core/modules/field/config/schema/field.source.schema.yml
+++ b/core/modules/field/config/schema/field.source.schema.yml
@@ -37,3 +37,35 @@ migrate.source.d6_field_instance_per_view_mode:
     constants:
       type: migrate_entity_constant
       label: 'Constants'
+
+migrate.source.d7_field:
+  type: migrate_source_sql
+  label: 'Drupal 7 field'
+  mapping:
+    constants:
+      type: migrate_entity_constant
+      label: 'Constants'
+
+migrate.source.d7_field_instance:
+  type: migrate_source_sql
+  label: 'Drupal 7 field instance'
+  mapping:
+    constants:
+      type: migrate_entity_constant
+      label: 'Constants'
+
+migrate.source.d7_field_instance_per_form_display:
+  type: migrate_source_sql
+  label: 'Drupal 7 field instance per form display'
+  mapping:
+    constants:
+      type: migrate_entity_constant
+      label: 'Constants'
+
+migrate.source.d7_field_instance_per_view_mode:
+  type: migrate_source_sql
+  label: 'Drupal 7 field instance per view mode'
+  mapping:
+    constants:
+      type: migrate_entity_constant
+      label: 'Constants'
diff --git a/core/modules/field/migration_templates/d7_field.yml b/core/modules/field/migration_templates/d7_field.yml
new file mode 100755
index 0000000..44ea36d
--- /dev/null
+++ b/core/modules/field/migration_templates/d7_field.yml
@@ -0,0 +1,42 @@
+id: d7_field
+label: Drupal 7 field configuration
+migration_tags:
+  - Drupal 7
+source:
+  plugin: d7_field
+  constants:
+    status: true
+    langcode: und
+process:
+  entity_type: entity_type
+  status: 'constants/status'
+  langcode: 'constants/langcode'
+  field_name: field_name
+  type:
+    plugin: static_map
+    source: type
+    map:
+      date: datetime
+      datestamp: datetime
+      datetime: datetime
+      email: email
+      file: file
+      image: image
+      link_field: link
+      list_boolean: boolean
+      list_integer: list_integer
+      list_text: list_string
+      number_integer: integer
+      number_decimal: decimal
+      number_float: float
+      phone: telephone
+      taxonomy_term_reference: entity_reference
+      text: text
+      text_long: text_long
+      text_with_summary: text_with_summary
+  translatable: translatable
+  cardinality: cardinality
+  settings:
+    plugin: d7_field_settings
+destination:
+  plugin: entity:field_storage_config
diff --git a/core/modules/field/migration_templates/d7_field_formatter_settings.yml b/core/modules/field/migration_templates/d7_field_formatter_settings.yml
new file mode 100644
index 0000000..1171ec3
--- /dev/null
+++ b/core/modules/field/migration_templates/d7_field_formatter_settings.yml
@@ -0,0 +1,72 @@
+id: d7_field_formatter_settings
+label: Drupal 7 field formatter configuration
+migration_tags:
+  - Drupal 7
+source:
+  plugin: d7_field_instance_per_view_mode
+  constants:
+    third_party_settings: { }
+process:
+  # We skip field types that don't exist because they weren't migrated by the
+  # field migration.
+  field_type_exists:
+    -
+      plugin: migration
+      migration: d7_field
+      source:
+        - field_name
+        - entity_type
+    -
+      plugin: extract
+      index:
+        - 0
+    -
+      plugin: skip_on_empty
+      method: row
+  entity_type: entity_type
+  bundle: bundle
+  view_mode:
+    -
+      plugin: migration
+      migration: d7_view_modes
+      source:
+        - entity_type
+        - view_mode
+    -
+      plugin: extract
+      index:
+        - 1
+    -
+      plugin: static_map
+      bypass: true
+      map:
+        full: default
+  field_name: field_name
+  "options/label": label
+  "options/weight": weight
+  # The formatter to use.
+  "options/type":
+    -
+      plugin: static_map
+      bypass: true
+      source: type
+      map:
+        date_default: datetime_default
+        email_default: email_mailto
+        # 0 should cause the row to be skipped by the next plugin in the
+        # pipeline.
+        hidden: 0
+        link_default: link
+        phone: basic_string
+        taxonomy_term_reference_link: entity_reference_label
+    -
+      plugin: skip_on_empty
+      method: row
+  "options/settings": settings
+  "options/third_party_settings": 'constants/third_party_settings'
+destination:
+  plugin: component_entity_display
+migration_dependencies:
+  required:
+    - d7_field_instance
+    - d7_view_modes
diff --git a/core/modules/field/migration_templates/d7_field_instance.yml b/core/modules/field/migration_templates/d7_field_instance.yml
new file mode 100755
index 0000000..d0b3d2e
--- /dev/null
+++ b/core/modules/field/migration_templates/d7_field_instance.yml
@@ -0,0 +1,31 @@
+id: d7_field_instance
+migration_tags:
+  - Drupal 7
+source:
+  plugin: d7_field_instance
+  constants:
+    status: true
+process:
+  entity_type: entity_type
+  field_name: field_name
+  bundle: bundle
+  label: label
+  description: description
+  required: required
+  status: 'constants/status'
+  settings:
+    plugin: d7_field_instance_settings
+    source:
+      - instance_settings
+      - widget_settings
+  default_value_function: ''
+  default_value:
+    plugin: d7_field_instance_defaults
+    source:
+      - default_value
+      - widget_settings
+destination:
+  plugin: entity:field_config
+migration_dependencies:
+  required:
+    - d7_field
diff --git a/core/modules/field/migration_templates/d7_field_instance_widget_settings.yml b/core/modules/field/migration_templates/d7_field_instance_widget_settings.yml
new file mode 100755
index 0000000..e75285d
--- /dev/null
+++ b/core/modules/field/migration_templates/d7_field_instance_widget_settings.yml
@@ -0,0 +1,57 @@
+id: d7_field_instance_widget_settings
+label: Drupal 7 field instance widget configuration
+migration_tags:
+  - Drupal 7
+source:
+  plugin: d7_field_instance_per_form_display
+  constants:
+    form_mode: default
+    third_party_settings: { }
+process:
+  # We skip field types that don't exist because they weren't migrated by the
+  # field migration.
+  field_type_exists:
+    -
+      plugin: migration
+      migration: d7_field
+      source:
+        - entity_type
+        - field_name
+    -
+      plugin: extract
+      index:
+        - 1
+    -
+      plugin: skip_on_empty
+      method: row
+  bundle: bundle
+  form_mode: 'constants/form_mode'
+  field_name: field_name
+  entity_type: entity_type
+  'options/weight': 'widget/weight'
+  'options/type':
+    type:
+      plugin: static_map
+      bypass: true
+      source: 'widget/type'
+      map:
+        link_field: link_default
+        email_textfield: email_default
+        date_select: datetime_default
+        date_text: datetime_default
+        date_popup: datetime_default
+        media_generic: file_generic
+        phone_textfield: telephone_default
+        options_onoff: boolean_checkbox
+        entityreference_autocomplete: entity_reference_autocomplete
+  'options/settings':
+    plugin: field_instance_widget_settings
+    source:
+      - 'widget/type'
+      - widget_settings
+  'options/third_party_settings': 'constants/third_party_settings'
+destination:
+  plugin: component_entity_form_display
+migration_dependencies:
+  required:
+    - d7_field_instance
diff --git a/core/modules/field/migration_templates/d7_view_modes.yml b/core/modules/field/migration_templates/d7_view_modes.yml
new file mode 100644
index 0000000..0f34088
--- /dev/null
+++ b/core/modules/field/migration_templates/d7_view_modes.yml
@@ -0,0 +1,27 @@
+id: d7_view_modes
+label: Drupal 7 view modes
+migration_tags:
+  - Drupal 7
+source:
+  plugin: d7_view_mode
+process:
+  mode:
+    plugin: static_map
+    source: view_mode
+    bypass: true
+    map:
+      default: full
+  label:
+    plugin: static_map
+    source: view_mode
+    map:
+      search_index: "Search index"
+      search_result: "Search result"
+      rss: "RSS"
+      print: "Print"
+      teaser: "Teaser"
+      full: "Full"
+      default: "Full"
+  targetEntityType: entity_type
+destination:
+  plugin: entity:entity_view_mode
diff --git a/core/modules/field/src/Plugin/migrate/process/d7/FieldInstanceDefaults.php b/core/modules/field/src/Plugin/migrate/process/d7/FieldInstanceDefaults.php
new file mode 100755
index 0000000..d1015c4
--- /dev/null
+++ b/core/modules/field/src/Plugin/migrate/process/d7/FieldInstanceDefaults.php
@@ -0,0 +1,41 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\field\Plugin\migrate\process\d7\FieldInstanceDefaults.
+ */
+
+namespace Drupal\field\Plugin\migrate\process\d7;
+
+use Drupal\migrate\MigrateExecutableInterface;
+use Drupal\migrate\ProcessPluginBase;
+use Drupal\migrate\Row;
+
+/**
+ * @MigrateProcessPlugin(
+ *   id = "d7_field_instance_defaults"
+ * )
+ */
+class FieldInstanceDefaults extends ProcessPluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
+    list($default_value, $widget_settings) = $value;
+    $widget_type = $widget_settings['type'];
+
+    $default = array();
+
+    foreach ($default_value as $item) {
+      switch ($widget_type) {
+        // Add special processing here if needed.
+        default:
+          $default[] = $item;
+      }
+    }
+
+    return $default;
+  }
+
+}
diff --git a/core/modules/field/src/Plugin/migrate/process/d7/FieldInstanceSettings.php b/core/modules/field/src/Plugin/migrate/process/d7/FieldInstanceSettings.php
new file mode 100755
index 0000000..cee5fbf
--- /dev/null
+++ b/core/modules/field/src/Plugin/migrate/process/d7/FieldInstanceSettings.php
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\field\Plugin\migrate\process\d7\FieldInstanceSettings.
+ */
+
+namespace Drupal\field\Plugin\migrate\process\d7;
+
+use Drupal\migrate\MigrateExecutableInterface;
+use Drupal\migrate\ProcessPluginBase;
+use Drupal\migrate\Row;
+
+/**
+ * @MigrateProcessPlugin(
+ *   id = "d7_field_instance_settings"
+ * )
+ */
+class FieldInstanceSettings extends ProcessPluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
+    list($instance_settings, $widget_settings) = $value;
+    $widget_type = $widget_settings['type'];
+
+    switch ($widget_type) {
+      case 'image_image':
+        $settings = $instance_settings;
+        if (!isset($settings['default_image'])) {
+          $settings['default_image'] = array();
+        }
+        $settings['default_image'] += array(
+          'alt' => '',
+          'title' => '',
+          'width' => NULL,
+          'height' => NULL,
+          'uuid' => '',
+        );
+        break;
+
+      default:
+        $settings = $instance_settings;
+    }
+
+    return $settings;
+  }
+
+}
diff --git a/core/modules/field/src/Plugin/migrate/process/d7/FieldSettings.php b/core/modules/field/src/Plugin/migrate/process/d7/FieldSettings.php
new file mode 100755
index 0000000..97ad3b8
--- /dev/null
+++ b/core/modules/field/src/Plugin/migrate/process/d7/FieldSettings.php
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\field\Plugin\migrate\process\d7\FieldSettings.
+ */
+
+namespace Drupal\field\Plugin\migrate\process\d7;
+
+use Drupal\migrate\MigrateExecutableInterface;
+use Drupal\migrate\ProcessPluginBase;
+use Drupal\migrate\Row;
+
+/**
+ * @MigrateProcessPlugin(
+ *   id = "d7_field_settings"
+ * )
+ */
+class FieldSettings extends ProcessPluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
+    $value = $row->getSourceProperty('settings');
+
+    if ($row->getSourceProperty('type') == 'image' && !is_array($value['default_image'])) {
+      $value['default_image'] = array(
+        'uuid' => '',
+      );
+    }
+
+    return $value;
+  }
+
+}
diff --git a/core/modules/field/src/Plugin/migrate/source/d7/Field.php b/core/modules/field/src/Plugin/migrate/source/d7/Field.php
new file mode 100755
index 0000000..77c9b82
--- /dev/null
+++ b/core/modules/field/src/Plugin/migrate/source/d7/Field.php
@@ -0,0 +1,77 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\field\Plugin\migrate\source\d7\Field.
+ */
+
+namespace Drupal\field\Plugin\migrate\source\d7;
+
+use Drupal\migrate\Row;
+use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
+
+/**
+ * Drupal 7 field source from database.
+ *
+ * @MigrateSource(
+ *   id = "d7_field"
+ * )
+ */
+class Field extends DrupalSqlBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+    $query = $this->select('field_config', 'fc')
+      ->fields('fc')
+      ->fields('fci', array('entity_type'))
+      ->condition('fc.active', 1)
+      ->condition('fc.deleted', 0)
+      ->condition('fc.storage_active', 1);
+    $query->join('field_config_instance', 'fci', 'fc.id = fci.field_id');
+
+    return $query;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fields() {
+    return array(
+      'field_name' => $this->t('The name of this field.'),
+      'type' => $this->t('The type of this field.'),
+      'module' => $this->t('The module that implements the field type.'),
+      'storage' => $this->t('The field storage.'),
+      'locked' => $this->t('Locked'),
+      'cardinality' => $this->t('Cardinality'),
+      'translatable' => $this->t('Translatable'),
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function prepareRow(Row $row, $keep = TRUE) {
+    foreach (unserialize($row->getSourceProperty('data')) as $key => $value) {
+      $row->setSourceProperty($key, $value);
+    }
+    return parent::prepareRow($row);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    return array(
+      'field_name' => array(
+        'type' => 'string',
+        'alias' => 'fc',
+      ),
+      'entity_type' => array(
+        'type' => 'string',
+        'alias' => 'fci',
+      ),
+    );
+  }
+}
diff --git a/core/modules/field/src/Plugin/migrate/source/d7/FieldInstance.php b/core/modules/field/src/Plugin/migrate/source/d7/FieldInstance.php
new file mode 100755
index 0000000..2b5238c
--- /dev/null
+++ b/core/modules/field/src/Plugin/migrate/source/d7/FieldInstance.php
@@ -0,0 +1,96 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\field\Plugin\migrate\source\d7\FieldInstance.
+ */
+
+namespace Drupal\field\Plugin\migrate\source\d7;
+
+use Drupal\migrate\Row;
+use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
+
+/**
+ * Drupal 7 field instances source from database.
+ *
+ * @MigrateSource(
+ *   id = "d7_field_instance",
+ * )
+ */
+class FieldInstance extends DrupalSqlBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+    $query = $this->select('field_config_instance', 'fci')
+      ->fields('fci')
+      ->condition('fci.deleted', 0)
+      ->condition('fc.active', 1)
+      ->condition('fc.deleted', 0)
+      ->condition('fc.storage_active', 1);
+    $query->innerJoin('field_config', 'fc', 'fci.field_id = fc.id');
+
+    return $query;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fields() {
+    return array(
+      'field_name' => $this->t('The machine name of field.'),
+      'entity_type' => $this->t('The entity type.'),
+      'bundle' => $this->t('The entity bundle.'),
+      'default_value' => $this->t('Default value'),
+      'instance_settings' => $this->t('Field instance settings.'),
+      'widget_settings' => $this->t('Widget settings.'),
+      'display_settings' => $this->t('Display settings.'),
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function prepareRow(Row $row) {
+    $data = unserialize($row->getSourceProperty('data'));
+
+    $row->setSourceProperty('label', $data['label']);
+    $row->setSourceProperty('description', $data['description']);
+    $row->setSourceProperty('required', $data['required']);
+
+    $default_value = !empty($data['default_value']) ? $data['default_value'] : array();
+    if ($data['widget']['type'] == 'email_textfield' && $default_value) {
+      $default_value[0]['value'] = $default_value[0]['email'];
+      unset($default_value[0]['email']);
+    }
+    $row->setSourceProperty('default_value', $default_value);
+
+    // Settings.
+    $row->setSourceProperty('instance_settings', $data['settings']);
+    $row->setSourceProperty('widget_settings', $data['widget']);
+    $row->setSourceProperty('display_settings', $data['display']);
+
+    return parent::prepareRow($row);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    return array(
+      'entity_type' => array(
+        'type' => 'string',
+        'alias' => 'fci',
+      ),
+      'bundle' => array(
+        'type' => 'string',
+        'alias' => 'fci',
+      ),
+      'field_name' => array(
+        'type' => 'string',
+        'alias' => 'fci',
+      ),
+    );
+  }
+}
diff --git a/core/modules/field/src/Plugin/migrate/source/d7/FieldInstancePerFormDisplay.php b/core/modules/field/src/Plugin/migrate/source/d7/FieldInstancePerFormDisplay.php
new file mode 100755
index 0000000..2be9223
--- /dev/null
+++ b/core/modules/field/src/Plugin/migrate/source/d7/FieldInstancePerFormDisplay.php
@@ -0,0 +1,79 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\field\Plugin\migrate\source\d7\FieldInstancePerFormDisplay.
+ */
+
+namespace Drupal\field\Plugin\migrate\source\d7;
+
+use Drupal\migrate\Row;
+use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
+
+/**
+ * The field instance per form display source class.
+ *
+ * @MigrateSource(
+ *   id = "d7_field_instance_per_form_display"
+ * )
+ */
+class FieldInstancePerFormDisplay extends DrupalSqlBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+    $query = $this->select('field_config_instance', 'fci')
+      ->fields('fci', array(
+        'field_name',
+        'bundle',
+        'data',
+        'entity_type'
+      ))
+      ->fields('fc', array(
+        'type',
+        'module',
+      ))
+      ->condition('fci.entity_type','node');
+    $query->join('field_config', 'fc', 'fci.field_id = fc.id');
+    return $query;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function prepareRow(Row $row) {
+    $data = unserialize($row->getSourceProperty('data'));
+    $row->setSourceProperty('widget', $data['widget']);
+    $row->setSourceProperty('widget_settings', $data['widget']['settings']);
+    return parent::prepareRow($row);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fields() {
+    return array(
+      'field_name' => $this->t('The machine name of field.'),
+      'bundle' => $this->t('Content type where this field is used.'),
+      'data' => $this->t('Field configuration data.'),
+      'entity_type' => $this->t('The entity type.'),
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    return array(
+      'bundle' => array(
+        'type' => 'string',
+      ),
+      'field_name' => array(
+        'type' => 'string',
+        'alias' => 'fci',
+      ),
+    );
+  }
+
+}
diff --git a/core/modules/field/src/Plugin/migrate/source/d7/FieldInstancePerViewMode.php b/core/modules/field/src/Plugin/migrate/source/d7/FieldInstancePerViewMode.php
new file mode 100644
index 0000000..d8c108f
--- /dev/null
+++ b/core/modules/field/src/Plugin/migrate/source/d7/FieldInstancePerViewMode.php
@@ -0,0 +1,91 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\field\Plugin\migrate\source\d7\FieldInstancePerViewMode.
+ */
+
+namespace Drupal\field\Plugin\migrate\source\d7;
+
+use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
+
+/**
+ * The field instance per view mode source class.
+ *
+ * @MigrateSource(
+ *   id = "d7_field_instance_per_view_mode",
+ *   source_provider = "field"
+ * )
+ */
+class FieldInstancePerViewMode extends DrupalSqlBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function initializeIterator() {
+    $rows = array();
+    $result = $this->prepareQuery()->execute();
+    foreach ($result as $field_instance) {
+      $data = unserialize($field_instance['data']);
+      // We don't need to include the serialized data in the returned rows.
+      unset($field_instance['data']);
+      foreach ($data['display'] as $view_mode => $info) {
+        $rows[] = array_merge($field_instance, $info, array('view_mode' => $view_mode));
+      }
+    }
+    return new \ArrayIterator($rows);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+    return $this->select('field_config_instance', 'fci')
+      ->fields('fci', array('entity_type', 'bundle', 'field_name', 'data'));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fields() {
+    return array(
+      'entity_type' => $this->t('The entity type ID.'),
+      'bundle' => $this->t('The bundle ID.'),
+      'field_name' => $this->t('Machine name of the field.'),
+      'view_mode' => $this->t('The original machine name of the view mode.'),
+      'label' => $this->t('The display label of the field.'),
+      'type' => $this->t('The formatter ID.'),
+      'settings' => $this->t('Array of formatter-specific settings.'),
+      'module' => $this->t('The module providing the formatter.'),
+      'weight' => $this->t('Display weight of the field.'),
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    return array(
+      'entity_type' => array(
+        'type' => 'string',
+      ),
+      'bundle' => array(
+        'type' => 'string',
+      ),
+      'view_mode' => array(
+        'type' => 'string',
+      ),
+      'field_name' => array(
+        'type' => 'string',
+      ),
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function count() {
+    return $this->initializeIterator()->count();
+  }
+
+}
diff --git a/core/modules/field/src/Plugin/migrate/source/d7/ViewMode.php b/core/modules/field/src/Plugin/migrate/source/d7/ViewMode.php
new file mode 100644
index 0000000..89bdc78
--- /dev/null
+++ b/core/modules/field/src/Plugin/migrate/source/d7/ViewMode.php
@@ -0,0 +1,78 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\field\Plugin\migrate\source\d7\ViewMode.
+ */
+
+namespace Drupal\field\Plugin\migrate\source\d7;
+
+use Drupal\migrate\Annotation\MigrateSource;
+use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
+
+/**
+ * @MigrateSource(
+ *  id = "d7_view_mode"
+ * )
+ */
+class ViewMode extends DrupalSqlBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function initializeIterator() {
+    $rows = [];
+    $result = $this->prepareQuery()->execute();
+    foreach ($result as $field_instance) {
+      $data = unserialize($field_instance['data']);
+      foreach (array_keys($data['display']) as $view_mode) {
+        $key = $field_instance['entity_type'] . '.' . $view_mode;
+        $rows[$key] = [
+          'entity_type' => $field_instance['entity_type'],
+          'view_mode' => $view_mode,
+        ];
+      }
+    }
+    return new \ArrayIterator($rows);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fields() {
+    return [
+      'view_mode' => $this->t('The view mode ID.'),
+      'entity_type' => $this->t('The entity type ID.'),
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+    return $this->select('field_config_instance', 'fci')
+      ->fields('fci', ['entity_type', 'data']);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    return [
+      'entity_type' => [
+        'type' => 'string',
+      ],
+      'view_mode' => [
+        'type' => 'string',
+      ],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function count() {
+    return $this->initializeIterator()->count();
+  }
+
+}
diff --git a/core/modules/field/src/Tests/Migrate/d7/MigrateFieldFormatterSettingsTest.php b/core/modules/field/src/Tests/Migrate/d7/MigrateFieldFormatterSettingsTest.php
new file mode 100644
index 0000000..74c0e17
--- /dev/null
+++ b/core/modules/field/src/Tests/Migrate/d7/MigrateFieldFormatterSettingsTest.php
@@ -0,0 +1,225 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\field\Tests\Migrate\d7\MigrateFieldFormatterSettingsTest.
+ */
+
+namespace Drupal\field\Tests\Migrate\d7;
+
+use Drupal\comment\Entity\CommentType;
+use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
+use Drupal\Core\Entity\Entity\EntityViewDisplay;
+use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
+use Drupal\node\Entity\NodeType;
+
+/**
+ * Tests migration of D7 field formatter settings.
+ *
+ * @group field
+ */
+class MigrateFieldFormatterSettingsTest extends MigrateDrupal7TestBase {
+
+  public static $modules = [
+    'comment',
+    'datetime',
+    'entity_reference',
+    'file',
+    'image',
+    'link',
+    'node',
+    'telephone',
+    'text',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->installEntitySchema('comment');
+    CommentType::create([
+      'id' => 'comment_node_page',
+      'label' => $this->randomMachineName(),
+    ])->save();
+    CommentType::create([
+      'id' => 'comment_node_article',
+      'label' => $this->randomMachineName(),
+    ])->save();
+    CommentType::create([
+      'id' => 'comment_node_blog',
+      'label' => $this->randomMachineName(),
+    ])->save();
+    CommentType::create([
+      'id' => 'comment_node_book',
+      'label' => $this->randomMachineName(),
+    ])->save();
+    CommentType::create([
+      'id' => 'comment_node_forum',
+      'label' => $this->randomMachineName(),
+    ])->save();
+    CommentType::create([
+      'id' => 'comment_node_test_content_type',
+      'label' => $this->randomMachineName(),
+    ])->save();
+
+    $this->installEntitySchema('node');
+    NodeType::create([
+      'type' => 'page',
+      'label' => $this->randomMachineName(),
+    ])->save();
+    NodeType::create([
+      'type' => 'article',
+      'label' => $this->randomMachineName(),
+    ])->save();
+    NodeType::create([
+      'type' => 'blog',
+      'label' => $this->randomMachineName(),
+    ])->save();
+    NodeType::create([
+      'type' => 'book',
+      'label' => $this->randomMachineName(),
+    ])->save();
+    NodeType::create([
+      'type' => 'forum',
+      'label' => $this->randomMachineName(),
+    ])->save();
+    NodeType::create([
+      'type' => 'test_content_type',
+      'label' => $this->randomMachineName(),
+    ])->save();
+
+    $this->executeMigration('d7_field');
+    $this->executeMigration('d7_field_instance');
+    $this->executeMigration('d7_view_modes');
+    $this->executeMigration('d7_field_formatter_settings');
+  }
+
+  /**
+   * Asserts various aspects of a view display.
+   *
+   * @param string $id
+   *   The view display ID.
+   */
+  protected function assertEntity($id) {
+    $display = EntityViewDisplay::load($id);
+    $this->assertTrue($display instanceof EntityViewDisplayInterface);
+  }
+
+  /**
+   * Asserts various aspects of a particular component of a view display.
+   *
+   * @param string $display_id
+   *   The view display ID.
+   * @param string $component_id
+   *   The component ID.
+   * @param string $type
+   *   The expected component type (formatter plugin ID).
+   * @param string $label
+   *   The expected label of the component.
+   * @param int $weight
+   *   The expected weight of the component.
+   */
+  protected function assertComponent($display_id, $component_id, $type, $label, $weight) {
+    $component = EntityViewDisplay::load($display_id)->getComponent($component_id);
+    $this->assertTrue(is_array($component));
+    $this->assertIdentical($type, $component['type']);
+    $this->assertIdentical($label, $component['label']);
+    $this->assertIdentical($weight, $component['weight']);
+  }
+
+  /**
+   * Asserts that a particular component is NOT included in a display.
+   *
+   * @param string $display_id
+   *   The display ID.
+   * @param string $component_id
+   *   The component ID.
+   */
+  protected function assertComponentNotExists($display_id, $component_id) {
+    $component = EntityViewDisplay::load($display_id)->getComponent($component_id);
+    $this->assertTrue(is_null($component));
+  }
+
+  /**
+   * Tests migration of D7 field formatter settings.
+   */
+  public function testMigration() {
+    $this->assertEntity('comment.comment_node_article.default');
+    $this->assertComponent('comment.comment_node_article.default', 'comment_body', 'text_default', 'hidden', 0);
+
+    $this->assertEntity('comment.comment_node_blog.default');
+    $this->assertComponent('comment.comment_node_blog.default', 'comment_body', 'text_default', 'hidden', 0);
+
+    $this->assertEntity('comment.comment_node_book.default');
+    $this->assertComponent('comment.comment_node_book.default', 'comment_body', 'text_default', 'hidden', 0);
+
+    $this->assertEntity('comment.comment_node_forum.default');
+    $this->assertComponent('comment.comment_node_forum.default', 'comment_body', 'text_default', 'hidden', 0);
+
+    $this->assertEntity('comment.comment_node_page.default');
+    $this->assertComponent('comment.comment_node_page.default', 'comment_body', 'text_default', 'hidden', 0);
+
+    $this->assertEntity('comment.comment_node_test_content_type.default');
+    $this->assertComponent('comment.comment_node_test_content_type.default', 'comment_body', 'text_default', 'hidden', 0);
+    $this->assertComponent('comment.comment_node_test_content_type.default', 'field_integer', 'number_integer', 'above', 1);
+
+    $this->assertEntity('node.article.default');
+    $this->assertComponent('node.article.default', 'body', 'text_default', 'hidden', 0);
+    $this->assertComponent('node.article.default', 'field_tags', 'entity_reference_label', 'above', 10);
+    $this->assertComponent('node.article.default', 'field_image', 'image', 'hidden', -1);
+
+    $this->assertEntity('node.article.teaser');
+    $this->assertComponent('node.article.teaser', 'body', 'text_summary_or_trimmed', 'hidden', 0);
+    $this->assertComponent('node.article.teaser', 'field_tags', 'entity_reference_label', 'above', 10);
+    $this->assertComponent('node.article.teaser', 'field_image', 'image', 'hidden', -1);
+
+    $this->assertEntity('node.blog.default');
+    $this->assertComponent('node.blog.default', 'body', 'text_default', 'hidden', 0);
+
+    $this->assertEntity('node.blog.teaser');
+    $this->assertComponent('node.blog.teaser', 'body', 'text_summary_or_trimmed', 'hidden', 0);
+
+    $this->assertEntity('node.book.default');
+    $this->assertComponent('node.book.default', 'body', 'text_default', 'hidden', 0);
+
+    $this->assertEntity('node.book.teaser');
+    $this->assertComponent('node.book.teaser', 'body', 'text_summary_or_trimmed', 'hidden', 0);
+
+    $this->assertEntity('node.forum.default');
+    $this->assertComponent('node.forum.default', 'body', 'text_default', 'hidden', 11);
+    $this->assertComponent('node.forum.default', 'taxonomy_forums', 'entity_reference_label', 'above', 10);
+
+    $this->assertEntity('node.forum.teaser');
+    $this->assertComponent('node.forum.teaser', 'body', 'text_summary_or_trimmed', 'hidden', 11);
+    $this->assertComponent('node.forum.teaser', 'taxonomy_forums', 'entity_reference_label', 'above', 10);
+
+    $this->assertEntity('node.page.default');
+    $this->assertComponent('node.page.default', 'body', 'text_default', 'hidden', 0);
+
+    $this->assertEntity('node.page.teaser');
+    $this->assertComponent('node.page.teaser', 'body', 'text_summary_or_trimmed', 'hidden', 0);
+
+    $this->assertEntity('node.test_content_type.default');
+    $this->assertComponent('node.test_content_type.default', 'field_boolean', 'list_default', 'above', 0);
+    $this->assertComponent('node.test_content_type.default', 'field_email', 'email_mailto', 'above', 1);
+    // Phone formatters are not mapped and should default to basic_string.
+    $this->assertComponent('node.test_content_type.default', 'field_phone', 'basic_string', 'above', 2);
+    $this->assertComponent('node.test_content_type.default', 'field_date', 'datetime_default', 'above', 3);
+    $this->assertComponent('node.test_content_type.default', 'field_date_with_end_time', 'datetime_default', 'above', 4);
+    $this->assertComponent('node.test_content_type.default', 'field_file', 'file_default', 'above', 5);
+    $this->assertComponent('node.test_content_type.default', 'field_float', 'number_decimal', 'above', 6);
+    $this->assertComponent('node.test_content_type.default', 'field_images', 'image', 'above', 7);
+    $this->assertComponent('node.test_content_type.default', 'field_integer', 'number_integer', 'above', 8);
+    $this->assertComponent('node.test_content_type.default', 'field_link', 'link', 'above', 9);
+    $this->assertComponent('node.test_content_type.default', 'field_text_list', 'list_default', 'above', 10);
+    $this->assertComponent('node.test_content_type.default', 'field_integer_list', 'list_default', 'above', 11);
+    $this->assertComponent('node.test_content_type.default', 'field_long_text', 'text_default', 'above', 12);
+    $this->assertComponentNotExists('node.test_content_type.default', 'field_term_reference');
+    $this->assertComponentNotExists('node.test_content_type.default', 'field_text');
+
+    $this->assertEntity('user.user.default');
+    $this->assertComponent('user.user.default', 'field_file', 'file_default', 'above', 0);
+  }
+
+}
diff --git a/core/modules/field/src/Tests/Migrate/d7/MigrateFieldInstanceTest.php b/core/modules/field/src/Tests/Migrate/d7/MigrateFieldInstanceTest.php
new file mode 100644
index 0000000..1845fa4
--- /dev/null
+++ b/core/modules/field/src/Tests/Migrate/d7/MigrateFieldInstanceTest.php
@@ -0,0 +1,141 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\field\Tests\Migrate\d7\MigrateFieldInstanceTest.
+ */
+
+namespace Drupal\field\Tests\Migrate\d7;
+
+use Drupal\comment\Entity\CommentType;
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\FieldConfigInterface;
+use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
+use Drupal\node\Entity\NodeType;
+
+/**
+ * Migrates Drupal 7 field instances.
+ *
+ * @group field
+ */
+class MigrateFieldInstanceTest extends MigrateDrupal7TestBase {
+
+  /**
+   * The modules to be enabled during the test.
+   *
+   * @var array
+   */
+  static $modules = array(
+    'comment',
+    'datetime',
+    'entity_reference',
+    'file',
+    'image',
+    'link',
+    'node',
+    'system',
+    'taxonomy',
+    'telephone',
+    'text',
+  );
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->installConfig(static::$modules);
+    $this->createType('page');
+    $this->createType('article');
+    $this->createType('blog');
+    $this->createType('book');
+    $this->createType('forum');
+    $this->createType('test_content_type');
+    $this->executeMigration('d7_field');
+    $this->executeMigration('d7_field_instance');
+  }
+
+  /**
+   * Creates a node type with a corresponding comment type.
+   *
+   * @param string $id
+   *   The node type ID.
+   */
+  protected function createType($id) {
+    NodeType::create(array(
+      'type' => $id,
+      'label' => $this->randomString(),
+    ))->save();
+
+    CommentType::create(array(
+      'id' => 'comment_node_' . $id,
+      'label' => $this->randomString(),
+      'target_entity_type_id' => 'node',
+    ))->save();
+  }
+
+  /**
+   * Asserts various aspects of a field config entity.
+   *
+   * @param string $id
+   *   The entity ID in the form ENTITY_TYPE.BUNDLE.FIELD_NAME.
+   * @param string $expected_label
+   *   The expected field label.
+   * @param string $expected_field_type
+   *   The expected field type.
+   * @param boolean $is_required
+   *   Whether or not the field is required.
+   */
+  protected function assertEntity($id, $expected_label, $expected_field_type, $is_required) {
+    list ($expected_entity_type, $expected_bundle, $expected_name) = explode('.', $id);
+
+    /** @var \Drupal\field\FieldConfigInterface $field */
+    $field = FieldConfig::load($id);
+    $this->assertTrue($field instanceof FieldConfigInterface);
+    $this->assertIdentical($expected_label, $field->label());
+    $this->assertIdentical($expected_field_type, $field->getType());
+    $this->assertIdentical($expected_entity_type, $field->getTargetEntityTypeId());
+    $this->assertIdentical($expected_bundle, $field->getTargetBundle());
+    $this->assertIdentical($expected_name, $field->getName());
+    $this->assertEqual($is_required, $field->isRequired());
+    $this->assertIdentical($expected_entity_type . '.' . $expected_name, $field->getFieldStorageDefinition()->id());
+  }
+
+  /**
+   * Tests migrating D7 field instances to field_config entities.
+   */
+  public function testFieldInstances() {
+    $this->assertEntity('comment.comment_node_page.comment_body', 'Comment', 'text_long', TRUE);
+    $this->assertEntity('node.page.body', 'Body', 'text_with_summary', FALSE);
+    $this->assertEntity('comment.comment_node_article.comment_body', 'Comment', 'text_long', TRUE);
+    $this->assertEntity('node.article.body', 'Body', 'text_with_summary', FALSE);
+    $this->assertEntity('node.article.field_tags', 'Tags', 'entity_reference', FALSE);
+    $this->assertEntity('node.article.field_image', 'Image', 'image', FALSE);
+    $this->assertEntity('comment.comment_node_blog.comment_body', 'Comment', 'text_long', TRUE);
+    $this->assertEntity('node.blog.body', 'Body', 'text_with_summary', FALSE);
+    $this->assertEntity('comment.comment_node_book.comment_body', 'Comment', 'text_long', TRUE);
+    $this->assertEntity('node.book.body', 'Body', 'text_with_summary', FALSE);
+    $this->assertEntity('node.forum.taxonomy_forums', 'Forums', 'entity_reference', TRUE);
+    $this->assertEntity('comment.comment_node_forum.comment_body', 'Comment', 'text_long', TRUE);
+    $this->assertEntity('node.forum.body', 'Body', 'text_with_summary', FALSE);
+    $this->assertEntity('comment.comment_node_test_content_type.comment_body', 'Comment', 'text_long', TRUE);
+    $this->assertEntity('node.test_content_type.field_boolean', 'Boolean', 'boolean', FALSE);
+    $this->assertEntity('node.test_content_type.field_email', 'Email', 'email', FALSE);
+    $this->assertEntity('node.test_content_type.field_phone', 'Phone', 'telephone', TRUE);
+    $this->assertEntity('node.test_content_type.field_date', 'Date', 'datetime', FALSE);
+    $this->assertEntity('node.test_content_type.field_date_with_end_time', 'Date With End Time', 'datetime', FALSE);
+    $this->assertEntity('node.test_content_type.field_file', 'File', 'file', FALSE);
+    $this->assertEntity('node.test_content_type.field_float', 'Float', 'float', FALSE);
+    $this->assertEntity('node.test_content_type.field_images', 'Images', 'image', TRUE);
+    $this->assertEntity('node.test_content_type.field_integer', 'Integer', 'integer', TRUE);
+    $this->assertEntity('node.test_content_type.field_link', 'Link', 'link', FALSE);
+    $this->assertEntity('node.test_content_type.field_text_list', 'Text List', 'list_string', FALSE);
+    $this->assertEntity('node.test_content_type.field_integer_list', 'Integer List', 'list_integer', FALSE);
+    $this->assertEntity('node.test_content_type.field_long_text', 'Long text', 'text_with_summary', FALSE);
+    $this->assertEntity('node.test_content_type.field_term_reference', 'Term Reference', 'entity_reference', FALSE);
+    $this->assertEntity('node.test_content_type.field_text', 'Text', 'text', FALSE);
+    $this->assertEntity('comment.comment_node_test_content_type.field_integer', 'Integer', 'integer', FALSE);
+    $this->assertEntity('user.user.field_file', 'File', 'file', FALSE);
+  }
+
+}
diff --git a/core/modules/field/src/Tests/Migrate/d7/MigrateFieldInstanceWidgetSettingsTest.php b/core/modules/field/src/Tests/Migrate/d7/MigrateFieldInstanceWidgetSettingsTest.php
new file mode 100644
index 0000000..1161f79
--- /dev/null
+++ b/core/modules/field/src/Tests/Migrate/d7/MigrateFieldInstanceWidgetSettingsTest.php
@@ -0,0 +1,177 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\field\Tests\Migrate\d7\MigrateFieldInstanceWidgetSettingsTest.
+ */
+
+namespace Drupal\field\Tests\Migrate\d7;
+
+use Drupal\Core\Entity\Display\EntityFormDisplayInterface;
+use Drupal\Core\Entity\Entity\EntityFormDisplay;
+use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
+use Drupal\node\Entity\NodeType;
+
+/**
+ * Migrate field widget settings.
+ *
+ * @group field
+ */
+class MigrateFieldInstanceWidgetSettingsTest extends MigrateDrupal7TestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array(
+    'field',
+    'telephone',
+    'link',
+    'file',
+    'image',
+    'datetime',
+    'node',
+    'text',
+  );
+
+  /**
+   * Creates a node type.
+   *
+   * @param string $id
+   *   The node type ID.
+   */
+  protected function createNodeType($id) {
+    NodeType::create(array(
+      'type' => $id,
+      'label' => $this->randomString(),
+    ))->save();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->installEntitySchema('node');
+
+    $this->createNodeType('page');
+    $this->createNodeType('article');
+    $this->createNodeType('blog');
+    $this->createNodeType('book');
+    $this->createNodeType('forum');
+    $this->createNodeType('test_content_type');
+
+    // Add some id mappings for the dependent migrations.
+    $id_mappings = [
+      'd7_field' => [
+        [['comment', 'comment_body'], ['comment', 'comment_body']],
+        [['node', 'body'], ['node', 'body']],
+        [['node', 'field_tags'], ['node', 'field_tags']],
+        [['node', 'field_image'], ['node', 'field_image']],
+        [['node', 'taxonomy_forums'], ['node', 'taxonomy_forums']],
+        [['node', 'field_boolean'], ['node', 'field_boolean']],
+        [['node', 'field_email'], ['node', 'field_email']],
+        [['node', 'field_phone'], ['node', 'field_phone']],
+        [['node', 'field_date'], ['node', 'field_date']],
+        [['node', 'field_date_with_end_time'], ['node', 'field_date_with_end_time']],
+        [['node', 'field_file'], ['node', 'field_file']],
+        [['node', 'field_float'], ['node', 'field_float']],
+        [['node', 'field_images'], ['node', 'field_images']],
+        [['node', 'field_integer'], ['node', 'field_integer']],
+        [['node', 'field_link'], ['node', 'field_link']],
+        [['node', 'field_text_list'], ['node', 'field_text_list']],
+        [['node', 'field_integer_list'], ['node', 'field_integer_list']],
+        [['node', 'field_long_text'], ['node', 'field_long_text']],
+        [['node', 'field_term_reference'], ['node', 'field_term_reference']],
+        [['node', 'field_text'], ['node', 'field_text']],
+        [['node', 'field_integer'], ['node', 'field_integer']],
+        [['user', 'field_file'], ['user', 'field_file']],
+      ],
+      // We don't actually need any ID lookups from the d7_field_instance
+      // migration -- it's merely a sensible dependency.
+      'd7_field_instance' => [],
+    ];
+    $this->prepareMigrations($id_mappings);
+    $this->executeMigration('d7_field_instance_widget_settings');
+  }
+
+  /**
+   * Asserts various aspects of a form display entity.
+   *
+   * @param string $id
+   *   The entity ID.
+   * @param string $expected_entity_type
+   *   The expected entity type to which the display settings are attached.
+   * @param string $expected_bundle
+   *   The expected bundle to which the display settings are attached.
+   */
+  protected function assertEntity($id, $expected_entity_type, $expected_bundle) {
+    /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $entity */
+    $entity = EntityFormDisplay::load($id);
+    $this->assertTrue($entity instanceof EntityFormDisplayInterface);
+    $this->assertIdentical($expected_entity_type, $entity->getTargetEntityTypeId());
+    $this->assertIdentical($expected_bundle, $entity->getTargetBundle());
+  }
+
+  /**
+   * Asserts various aspects of a particular component of a form display.
+   *
+   * @param string $display_id
+   *   The form display ID.
+   * @param string $component_id
+   *   The component ID.
+   * @param string $widget_type
+   *   The expected widget type.
+   * @param string $weight
+   *   The expected weight of the component.
+   */
+  protected function assertComponent($display_id, $component_id, $widget_type, $weight) {
+    $component = EntityFormDisplay::load($display_id)->getComponent($component_id);
+    $this->assertTrue(is_array($component));
+    $this->assertIdentical($widget_type, $component['type']);
+    $this->assertIdentical($weight, $component['weight']);
+  }
+
+  /**
+   * Test that migrated view modes can be loaded using D8 APIs.
+   */
+  public function testWidgetSettings() {
+    $this->assertEntity('node.page.default', 'node', 'page');
+    $this->assertComponent('node.page.default', 'body', 'text_textarea_with_summary', -4);
+
+    $this->assertEntity('node.article.default', 'node', 'article');
+    $this->assertComponent('node.article.default', 'body', 'text_textarea_with_summary', -4);
+    $this->assertComponent('node.article.default', 'field_tags', 'taxonomy_autocomplete', -4);
+    $this->assertComponent('node.article.default', 'field_image', 'image_image', -1);
+
+    $this->assertEntity('node.blog.default', 'node', 'blog');
+    $this->assertComponent('node.blog.default', 'body', 'text_textarea_with_summary', -4);
+
+    $this->assertEntity('node.book.default', 'node', 'book');
+    $this->assertComponent('node.book.default', 'body', 'text_textarea_with_summary', -4);
+
+    $this->assertEntity('node.forum.default', 'node', 'forum');
+    $this->assertComponent('node.forum.default', 'body', 'text_textarea_with_summary', 1);
+    $this->assertComponent('node.forum.default', 'taxonomy_forums', 'options_select', 0);
+
+    $this->assertEntity('node.test_content_type.default', 'node', 'test_content_type');
+    $this->assertComponent('node.test_content_type.default', 'field_boolean', 'boolean_checkbox', 1);
+    $this->assertComponent('node.test_content_type.default', 'field_date', 'datetime_default', 2);
+    $this->assertComponent('node.test_content_type.default', 'field_date_with_end_time', 'datetime_default', 3);
+    $this->assertComponent('node.test_content_type.default', 'field_email', 'email_default', 4);
+    $this->assertComponent('node.test_content_type.default', 'field_file', 'file_generic', 5);
+    $this->assertComponent('node.test_content_type.default', 'field_float', 'number', 7);
+    $this->assertComponent('node.test_content_type.default', 'field_images', 'image_image', 8);
+    $this->assertComponent('node.test_content_type.default', 'field_integer', 'number', 9);
+    $this->assertComponent('node.test_content_type.default', 'field_link', 'link_default', 10);
+    $this->assertComponent('node.test_content_type.default', 'field_integer_list', 'options_buttons', 12);
+    $this->assertComponent('node.test_content_type.default', 'field_long_text', 'text_textarea_with_summary', 13);
+    $this->assertComponent('node.test_content_type.default', 'field_phone', 'telephone_default', 6);
+    $this->assertComponent('node.test_content_type.default', 'field_term_reference', 'taxonomy_autocomplete', 14);
+    $this->assertComponent('node.test_content_type.default', 'field_text', 'text_textfield', 15);
+    $this->assertComponent('node.test_content_type.default', 'field_text_list', 'options_select', 11);
+  }
+
+}
diff --git a/core/modules/field/src/Tests/Migrate/d7/MigrateFieldTest.php b/core/modules/field/src/Tests/Migrate/d7/MigrateFieldTest.php
new file mode 100644
index 0000000..ac94d8a
--- /dev/null
+++ b/core/modules/field/src/Tests/Migrate/d7/MigrateFieldTest.php
@@ -0,0 +1,111 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\field\Tests\Migrate\d7\MigrateFieldTest.
+ */
+
+namespace Drupal\field\Tests\Migrate\d7;
+
+use Drupal\field\Entity\FieldStorageConfig;
+use Drupal\field\FieldStorageConfigInterface;
+use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
+
+/**
+ * Migrates Drupal 7 fields.
+ *
+ * @group field
+ */
+class MigrateFieldTest extends MigrateDrupal7TestBase {
+
+  /**
+   * The modules to be enabled during the test.
+   *
+   * @var array
+   */
+  static $modules = array(
+    'comment',
+    'datetime',
+    'entity_reference',
+    'file',
+    'image',
+    'link',
+    'node',
+    'system',
+    'taxonomy',
+    'telephone',
+    'text',
+  );
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->installConfig(static::$modules);
+    $this->executeMigration('d7_field');
+  }
+
+  /**
+   * Asserts various aspects of a field_storage_config entity.
+   *
+   * @param string $id
+   *   The entity ID in the form ENTITY_TYPE.FIELD_NAME.
+   * @param string $expected_type
+   *   The expected field type.
+   * @param boolean $expected_translatable
+   *   Whether or not the field is expected to be translatable.
+   * @param integer $expected_cardinality
+   *   The expected cardinality of the field.
+   */
+  protected function assertEntity($id, $expected_type, $expected_translatable, $expected_cardinality) {
+    list ($expected_entity_type, $expected_name) = explode('.', $id);
+
+    /** @var \Drupal\field\FieldStorageConfigInterface $field */
+    $field = FieldStorageConfig::load($id);
+    $this->assertTrue($field instanceof FieldStorageConfigInterface);
+    $this->assertIdentical($expected_name, $field->getName());
+    $this->assertIdentical($expected_type, $field->getType());
+    // FieldStorageConfig::$translatable is TRUE by default, so it is useful
+    // to test for FALSE here.
+    $this->assertEqual($expected_translatable, $field->isTranslatable());
+    $this->assertIdentical($expected_entity_type, $field->getTargetEntityTypeId());
+
+    if ($expected_cardinality === 1) {
+      $this->assertFalse($field->isMultiple());
+    }
+    else {
+      $this->assertTrue($field->isMultiple());
+    }
+    $this->assertIdentical($expected_cardinality, $field->getCardinality());
+  }
+
+  /**
+   * Tests migrating D7 fields to field_storage_config entities.
+   */
+  public function testFields() {
+    $this->assertEntity('node.body', 'text_with_summary', FALSE, 1);
+    $this->assertEntity('node.field_long_text', 'text_with_summary', FALSE, 1);
+    $this->assertEntity('comment.comment_body', 'text_long', FALSE, 1);
+    $this->assertEntity('node.field_file', 'file', FALSE, 1);
+    $this->assertEntity('user.field_file', 'file', FALSE, 1);
+    $this->assertEntity('node.field_float', 'float', FALSE, 1);
+    $this->assertEntity('node.field_image', 'image', FALSE, 1);
+    $this->assertEntity('node.field_images', 'image', FALSE, 1);
+    $this->assertEntity('node.field_integer', 'integer', FALSE, 1);
+    $this->assertEntity('comment.field_integer', 'integer', FALSE, 1);
+    $this->assertEntity('node.field_integer_list', 'list_integer', FALSE, 1);
+    $this->assertEntity('node.field_link', 'link', FALSE, 1);
+    $this->assertEntity('node.field_tags', 'entity_reference', FALSE, -1);
+    $this->assertEntity('node.field_term_reference', 'entity_reference', FALSE, 1);
+    $this->assertEntity('node.taxonomy_forums', 'entity_reference', FALSE, 1);
+    $this->assertEntity('node.field_text', 'text', FALSE, 1);
+    $this->assertEntity('node.field_text_list', 'list_string', FALSE, 3);
+    $this->assertEntity('node.field_boolean', 'boolean', FALSE, 1);
+    $this->assertEntity('node.field_email', 'email', FALSE, -1);
+    $this->assertEntity('node.field_phone', 'telephone', FALSE, 1);
+    $this->assertEntity('node.field_date', 'datetime', FALSE, 1);
+    $this->assertEntity('node.field_date_with_end_time', 'datetime', FALSE, 1);
+  }
+
+}
diff --git a/core/modules/field/src/Tests/Migrate/d7/MigrateViewModesTest.php b/core/modules/field/src/Tests/Migrate/d7/MigrateViewModesTest.php
new file mode 100644
index 0000000..04062a7
--- /dev/null
+++ b/core/modules/field/src/Tests/Migrate/d7/MigrateViewModesTest.php
@@ -0,0 +1,63 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\field\Tests\Migrate\d7\MigrateViewModesTest.
+ */
+
+namespace Drupal\field\Tests\Migrate\d7;
+
+use Drupal\Core\Entity\Entity\EntityViewMode;
+use Drupal\Core\Entity\EntityViewModeInterface;
+use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
+
+/**
+ * Tests migration of D7 view modes.
+ *
+ * @group field
+ */
+class MigrateViewModesTest extends MigrateDrupal7TestBase {
+
+  public static $modules = ['comment', 'node'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->installEntitySchema('comment');
+    $this->installEntitySchema('node');
+    $this->executeMigration('d7_view_modes');
+  }
+
+  /**
+   * Asserts various aspects of a view mode entity.
+   *
+   * @param string $id
+   *   The entity ID.
+   * @param string $label
+   *   The expected label of the view mode.
+   * @param string $entity_type
+   *   The expected entity type ID which owns the view mode.
+   * @param bool $status
+   *   The expected status of the view mode.
+   */
+  protected function assertEntity($id, $label, $entity_type) {
+    /** @var \Drupal\Core\Entity\EntityViewModeInterface $view_mode */
+    $view_mode = EntityViewMode::load($id);
+    $this->assertTrue($view_mode instanceof EntityViewModeInterface);
+    $this->assertIdentical($label, $view_mode->label());
+    $this->assertIdentical($entity_type, $view_mode->getTargetType());
+  }
+
+  /**
+   * Tests migration of D7 view mode variables to D8 config entities.
+   */
+  public function testMigration() {
+    $this->assertEntity('comment.full', 'Full', 'comment');
+    $this->assertEntity('node.teaser', 'Teaser', 'node');
+    $this->assertEntity('node.full', 'Full', 'node');
+    $this->assertEntity('user.full', 'Full', 'user');
+  }
+
+}
diff --git a/core/modules/field/tests/src/Unit/Plugin/migrate/process/d7/FieldInstanceSettingsTest.php b/core/modules/field/tests/src/Unit/Plugin/migrate/process/d7/FieldInstanceSettingsTest.php
new file mode 100644
index 0000000..5bec59e
--- /dev/null
+++ b/core/modules/field/tests/src/Unit/Plugin/migrate/process/d7/FieldInstanceSettingsTest.php
@@ -0,0 +1,45 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\field\Unit\Plugin\migrate\process\d7\FieldInstanceSettingsTest.
+ */
+
+namespace Drupal\Tests\field\Unit\Plugin\migrate\process\d7;
+
+use Drupal\field\Plugin\migrate\process\d7\FieldInstanceSettings;
+use Drupal\migrate\Entity\MigrationInterface;
+use Drupal\migrate\MigrateExecutableInterface;
+use Drupal\migrate\Row;
+use Drupal\Tests\migrate\Unit\MigrateTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\field\Plugin\migrate\process\d7\FieldInstanceSettings
+ * @group field
+ */
+class FieldInstanceSettingsTest extends MigrateTestCase {
+
+  /**
+   * Tests transformation of image field settings.
+   *
+   * @covers ::transform
+   */
+  public function testTransformImageSettings() {
+    $migration = $this->getMock(MigrationInterface::class);
+    $plugin = new FieldInstanceSettings([], 'd7_field_instance_settings', [], $migration);
+
+    $executable = $this->getMock(MigrateExecutableInterface::class);
+    $row = $this->getMockBuilder(Row::class)
+      ->disableOriginalConstructor()
+      ->getMock();
+
+    $value = $plugin->transform([[], ['type' => 'image_image']], $executable, $row, 'foo');
+    $this->assertInternalType('array', $value['default_image']);
+    $this->assertSame('', $value['default_image']['alt']);
+    $this->assertSame('', $value['default_image']['title']);
+    $this->assertNull($value['default_image']['width']);
+    $this->assertNull($value['default_image']['height']);
+    $this->assertSame('', $value['default_image']['uuid']);
+  }
+
+}
diff --git a/core/modules/field/tests/src/Unit/Plugin/migrate/process/d7/FieldSettingsTest.php b/core/modules/field/tests/src/Unit/Plugin/migrate/process/d7/FieldSettingsTest.php
new file mode 100644
index 0000000..ca1b937
--- /dev/null
+++ b/core/modules/field/tests/src/Unit/Plugin/migrate/process/d7/FieldSettingsTest.php
@@ -0,0 +1,48 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\field\Unit\Plugin\migrate\process\d7\FieldInstanceSettingsTest.
+ */
+
+namespace Drupal\Tests\field\Unit\Plugin\migrate\process\d7;
+
+use Drupal\field\Plugin\migrate\process\d7\FieldSettings;
+use Drupal\migrate\Entity\MigrationInterface;
+use Drupal\migrate\MigrateExecutableInterface;
+use Drupal\migrate\Row;
+use Drupal\Tests\migrate\Unit\MigrateTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\field\Plugin\migrate\process\d7\FieldSettings
+ * @group field
+ */
+class FieldSettingsTest extends MigrateTestCase {
+
+  /**
+   * Tests transformation of image field settings.
+   *
+   * @covers ::transform
+   */
+  public function testTransformImageSettings() {
+    $migration = $this->getMock(MigrationInterface::class);
+    $plugin = new FieldSettings([], 'd7_field_settings', [], $migration);
+
+    $executable = $this->getMock(MigrateExecutableInterface::class);
+    $row = $this->getMockBuilder(Row::class)
+      ->disableOriginalConstructor()
+      ->getMock();
+
+    $row->expects($this->atLeastOnce())
+      ->method('getSourceProperty')
+      ->willReturnMap([
+        ['settings', ['default_image' => NULL]],
+        ['type', 'image'],
+      ]);
+
+    $value = $plugin->transform([], $executable, $row, 'foo');
+    $this->assertInternalType('array', $value);
+    $this->assertSame('', $value['default_image']['uuid']);
+  }
+
+}
diff --git a/core/modules/field/tests/src/Unit/Plugin/migrate/source/d7/FieldInstancePerFormDisplayTest.php b/core/modules/field/tests/src/Unit/Plugin/migrate/source/d7/FieldInstancePerFormDisplayTest.php
new file mode 100644
index 0000000..00d3e94
--- /dev/null
+++ b/core/modules/field/tests/src/Unit/Plugin/migrate/source/d7/FieldInstancePerFormDisplayTest.php
@@ -0,0 +1,81 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\field\Unit\Plugin\migrate\source\d7\FieldInstancePerFormDisplayTest.
+ */
+
+namespace Drupal\Tests\field\Unit\Plugin\migrate\source\d7;
+
+use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
+
+/**
+ * Tests D7 field instance per form display source plugin.
+ *
+ * @group field
+ */
+class FieldInstancePerFormDisplayTest extends MigrateSqlSourceTestCase {
+
+  const PLUGIN_CLASS = 'Drupal\field\Plugin\migrate\source\d7\FieldInstancePerFormDisplay';
+
+  protected $migrationConfiguration = array(
+    'id' => 'test_fieldinstance',
+    'source' => array(
+      'plugin' => 'd7_field_instance_per_form_display',
+    ),
+  );
+
+  // We need to set up the database contents; it's easier to do that below.
+  // These are sample result queries.
+  protected $expectedResults = array(
+    array(
+      'field_name' => 'body',
+      'entity_type' => 'node',
+      'bundle' => 'page',
+      'widget_settings' => array(
+      ),
+      'display_settings' => array(
+      ),
+      'description' => '',
+      'required' => FALSE,
+      'global_settings' => array(),
+    ),
+  );
+
+  /**
+   * Prepopulate contents with results.
+   */
+  protected function setUp() {
+    $this->databaseContents['field_config_instance'] = array(
+      array(
+        'id' => '2',
+        'field_id' => '2',
+        'field_name' => 'body',
+        'entity_type' => 'node',
+        'bundle' => 'page',
+        'data' => 'a:6:{s:5:"label";s:4:"Body";s:6:"widget";a:4:{s:4:"type";s:26:"text_textarea_with_summary";s:8:"settings";a:2:{s:4:"rows";i:20;s:12:"summary_rows";i:5;}s:6:"weight";i:-4;s:6:"module";s:4:"text";}s:8:"settings";a:3:{s:15:"display_summary";b:1;s:15:"text_processing";i:1;s:18:"user_register_form";b:0;}s:7:"display";a:2:{s:7:"default";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:0;}s:6:"teaser";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:23:"text_summary_or_trimmed";s:8:"settings";a:1:{s:11:"trim_length";i:600;}s:6:"module";s:4:"text";s:6:"weight";i:0;}}s:8:"required";b:0;s:11:"description";s:0:"";}',
+        'deleted' => '0',
+      ),
+    );
+    $this->databaseContents['field_config'] = array(
+      array(
+        'id' => '2',
+        'field_name' => 'body',
+        'type' => 'text_with_summary',
+        'module' => 'text',
+        'active' => '1',
+        'storage_type' => 'field_sql_storage',
+        'storage_module' => 'field_sql_storage',
+        'storage_active' => '1',
+        'locked' => '0',
+        'data' => 'a:6:{s:12:"entity_types";a:1:{i:0;s:4:"node";}s:12:"translatable";b:0;s:8:"settings";a:0:{}s:7:"storage";a:4:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";i:1;}s:12:"foreign keys";a:1:{s:6:"format";a:2:{s:5:"table";s:13:"filter_format";s:7:"columns";a:1:{s:6:"format";s:6:"format";}}}s:7:"indexes";a:1:{s:6:"format";a:1:{i:0;s:6:"format";}}}',
+        'cardinality' => '1',
+        'translatable' => '0',
+        'deleted' => '0',
+      ),
+    );
+
+    parent::setUp();
+  }
+
+}
diff --git a/core/modules/field/tests/src/Unit/Plugin/migrate/source/d7/FieldInstancePerViewModeTest.php b/core/modules/field/tests/src/Unit/Plugin/migrate/source/d7/FieldInstancePerViewModeTest.php
new file mode 100644
index 0000000..a0db671
--- /dev/null
+++ b/core/modules/field/tests/src/Unit/Plugin/migrate/source/d7/FieldInstancePerViewModeTest.php
@@ -0,0 +1,73 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\field\Unit\Plugin\migrate\source\d7\FieldInstancePerViewModeTest.
+ */
+
+namespace Drupal\Tests\field\Unit\Plugin\migrate\source\d7;
+
+use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
+
+/**
+ * Tests D7 field instance per view mode source plugin.
+ *
+ * @group field
+ */
+class FieldInstancePerViewModeTest extends MigrateSqlSourceTestCase {
+
+  const PLUGIN_CLASS = 'Drupal\field\Plugin\migrate\source\d7\FieldInstancePerViewMode';
+
+  protected $migrationConfiguration = array(
+    'id' => 'test',
+    'source' => array(
+      'plugin' => 'd7_field_instance_per_view_mode',
+    ),
+  );
+
+  protected $expectedResults = array(
+    array(
+      'entity_type' => 'node',
+      'bundle' => 'page',
+      'field_name' => 'body',
+      'label' => 'hidden',
+      'type' => 'text_default',
+      'settings' => array(),
+      'module' => 'text',
+      'weight' => 0,
+      'view_mode' => 'default',
+    ),
+    array(
+      'entity_type' => 'node',
+      'bundle' => 'page',
+      'field_name' => 'body',
+      'label' => 'hidden',
+      'type' => 'text_summary_or_trimmed',
+      'settings' => array(
+        'trim_length' => 600,
+      ),
+      'module' => 'text',
+      'weight' => 0,
+      'view_mode' => 'teaser',
+    ),
+  );
+
+  /**
+   * Prepopulate contents with results.
+   */
+  protected function setUp() {
+    $this->databaseContents['field_config_instance'] = array(
+      array(
+        'id' => '2',
+        'field_id' => '2',
+        'field_name' => 'body',
+        'entity_type' => 'node',
+        'bundle' => 'page',
+        'data' => 'a:6:{s:5:"label";s:4:"Body";s:6:"widget";a:4:{s:4:"type";s:26:"text_textarea_with_summary";s:8:"settings";a:2:{s:4:"rows";i:20;s:12:"summary_rows";i:5;}s:6:"weight";i:-4;s:6:"module";s:4:"text";}s:8:"settings";a:3:{s:15:"display_summary";b:1;s:15:"text_processing";i:1;s:18:"user_register_form";b:0;}s:7:"display";a:2:{s:7:"default";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:0;}s:6:"teaser";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:23:"text_summary_or_trimmed";s:8:"settings";a:1:{s:11:"trim_length";i:600;}s:6:"module";s:4:"text";s:6:"weight";i:0;}}s:8:"required";b:0;s:11:"description";s:0:"";}',
+        'deleted' => '0',
+      ),
+    );
+    parent::setUp();
+  }
+
+}
diff --git a/core/modules/field/tests/src/Unit/Plugin/migrate/source/d7/FieldInstanceTest.php b/core/modules/field/tests/src/Unit/Plugin/migrate/source/d7/FieldInstanceTest.php
new file mode 100644
index 0000000..c51773d
--- /dev/null
+++ b/core/modules/field/tests/src/Unit/Plugin/migrate/source/d7/FieldInstanceTest.php
@@ -0,0 +1,81 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\field\Unit\Plugin\migrate\source\d7\FieldInstanceTest.
+ */
+
+namespace Drupal\Tests\field\Unit\Plugin\migrate\source\d7;
+
+use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
+
+/**
+ * Tests D7 field instance source plugin.
+ *
+ * @group field
+ */
+class FieldInstanceTest extends MigrateSqlSourceTestCase {
+
+  const PLUGIN_CLASS = 'Drupal\field\Plugin\migrate\source\d7\FieldInstance';
+
+  protected $migrationConfiguration = array(
+    'id' => 'test_fieldinstance',
+    'source' => array(
+      'plugin' => 'd7_field_instance',
+    ),
+  );
+
+  protected $expectedResults = array(
+    array(
+      'field_name' => 'body',
+      'entity_type' => 'node',
+      'bundle' => 'page',
+      'label' => 'Body',
+      'widget_settings' => array(
+        'type' => 'text_textarea_with_summary',
+      ),
+      'display_settings' => array(
+      ),
+      'description' => '',
+      'required' => FALSE,
+      'global_settings' => array(),
+    ),
+  );
+
+  /**
+   * Prepopulate contents with results.
+   */
+  protected function setUp() {
+    $this->databaseContents['field_config_instance'] = array(
+      array(
+        'id' => '2',
+        'field_id' => '2',
+        'field_name' => 'body',
+        'entity_type' => 'node',
+        'bundle' => 'page',
+        'data' => 'a:6:{s:5:"label";s:4:"Body";s:6:"widget";a:4:{s:4:"type";s:26:"text_textarea_with_summary";s:8:"settings";a:2:{s:4:"rows";i:20;s:12:"summary_rows";i:5;}s:6:"weight";i:-4;s:6:"module";s:4:"text";}s:8:"settings";a:3:{s:15:"display_summary";b:1;s:15:"text_processing";i:1;s:18:"user_register_form";b:0;}s:7:"display";a:2:{s:7:"default";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:0;}s:6:"teaser";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:23:"text_summary_or_trimmed";s:8:"settings";a:1:{s:11:"trim_length";i:600;}s:6:"module";s:4:"text";s:6:"weight";i:0;}}s:8:"required";b:0;s:11:"description";s:0:"";}',
+        'deleted' => '0',
+      ),
+    );
+    $this->databaseContents['field_config'] = array(
+      array(
+        'id' => '2',
+        'field_name' => 'body',
+        'type' => 'text_with_summary',
+        'module' => 'text',
+        'active' => '1',
+        'storage_type' => 'field_sql_storage',
+        'storage_module' => 'field_sql_storage',
+        'storage_active' => '1',
+        'locked' => '0',
+        'data' => 'a:6:{s:12:"entity_types";a:1:{i:0;s:4:"node";}s:12:"translatable";b:0;s:8:"settings";a:0:{}s:7:"storage";a:4:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";i:1;}s:12:"foreign keys";a:1:{s:6:"format";a:2:{s:5:"table";s:13:"filter_format";s:7:"columns";a:1:{s:6:"format";s:6:"format";}}}s:7:"indexes";a:1:{s:6:"format";a:1:{i:0;s:6:"format";}}}',
+        'cardinality' => '1',
+        'translatable' => '0',
+        'deleted' => '0',
+      ),
+    );
+
+    parent::setUp();
+  }
+
+}
diff --git a/core/modules/field/tests/src/Unit/Plugin/migrate/source/d7/FieldTest.php b/core/modules/field/tests/src/Unit/Plugin/migrate/source/d7/FieldTest.php
new file mode 100644
index 0000000..82aa662
--- /dev/null
+++ b/core/modules/field/tests/src/Unit/Plugin/migrate/source/d7/FieldTest.php
@@ -0,0 +1,101 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\field\Unit\Plugin\migrate\source\d7\FieldTest.
+ */
+
+namespace Drupal\Tests\field\Unit\Plugin\migrate\source\d7;
+
+use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
+
+/**
+ * Tests D7 field source plugin.
+ *
+ * @group field
+ */
+class FieldTest extends MigrateSqlSourceTestCase {
+
+  const PLUGIN_CLASS = 'Drupal\field\Plugin\migrate\source\d7\Field';
+
+  protected $migrationConfiguration = array(
+    'id' => 'test_field',
+    'source' => array(
+      'plugin' => 'd7_field',
+    ),
+  );
+
+  protected $expectedResults = array(
+    array(
+      'field_name' => 'field_file',
+      'type' => 'file',
+      'global_settings' => '',
+      'storage' => array(
+        'type' => 'field_sql_storage',
+        'module' => 'field_sql_storage',
+      ),
+      'module' => 'file',
+      'db_columns' => '',
+      'locked' => 0,
+      'entity_type' => 'node',
+    ),
+    array(
+      'field_name' => 'field_file',
+      'type' => 'file',
+      'global_settings' => '',
+      'storage' => array(
+        'type' => 'field_sql_storage',
+        'module' => 'field_sql_storage',
+      ),
+      'module' => 'file',
+      'db_columns' => '',
+      'locked' => 0,
+      'entity_type' => 'user',
+    ),
+  );
+
+  /**
+   * Prepopulate contents with results.
+   */
+  protected function setUp() {
+    $this->databaseContents['field_config'] = array(
+      array(
+        'id' => '11',
+        'field_name' => 'field_file',
+        'type' => 'file',
+        'module' => 'file',
+        'active' => '1',
+        'storage_type' => 'field_sql_storage',
+        'storage_module' => 'field_sql_storage',
+        'storage_active' => '1',
+        'locked' => '0',
+        'data' => 'a:7:{s:12:"translatable";s:1:"0";s:12:"entity_types";a:0:{}s:8:"settings";a:3:{s:13:"display_field";i:0;s:15:"display_default";i:0;s:10:"uri_scheme";s:6:"public";}s:7:"storage";a:5:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";s:1:"1";s:7:"details";a:1:{s:3:"sql";a:2:{s:18:"FIELD_LOAD_CURRENT";a:1:{s:21:"field_data_field_file";a:3:{s:3:"fid";s:14:"field_file_fid";s:7:"display";s:18:"field_file_display";s:11:"description";s:22:"field_file_description";}}s:19:"FIELD_LOAD_REVISION";a:1:{s:25:"field_revision_field_file";a:3:{s:3:"fid";s:14:"field_file_fid";s:7:"display";s:18:"field_file_display";s:11:"description";s:22:"field_file_description";}}}}}s:12:"foreign keys";a:1:{s:3:"fid";a:2:{s:5:"table";s:12:"file_managed";s:7:"columns";a:1:{s:3:"fid";s:3:"fid";}}}s:7:"indexes";a:1:{s:3:"fid";a:1:{i:0;s:3:"fid";}}s:2:"id";s:2:"11";}',
+        'cardinality' => '1',
+        'translatable' => '0',
+        'deleted' => '0',
+      ),
+    );
+    $this->databaseContents['field_config_instance'] = array(
+      array(
+        'id' => '33',
+        'field_id' => '11',
+        'field_name' => 'field_file',
+        'entity_type' => 'user',
+        'bundle' => 'user',
+        'data' => 'a:6:{s:5:"label";s:4:"File";s:6:"widget";a:5:{s:6:"weight";s:1:"8";s:4:"type";s:12:"file_generic";s:6:"module";s:4:"file";s:6:"active";i:1;s:8:"settings";a:1:{s:18:"progress_indicator";s:8:"throbber";}}s:8:"settings";a:5:{s:14:"file_directory";s:0:"";s:15:"file_extensions";s:3:"txt";s:12:"max_filesize";s:0:"";s:17:"description_field";i:0;s:18:"user_register_form";i:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"file_default";s:8:"settings";a:0:{}s:6:"module";s:4:"file";s:6:"weight";i:0;}}s:8:"required";i:0;s:11:"description";s:0:"";}',
+        'deleted' => '0',
+      ),
+      array(
+        'id' => '21',
+        'field_id' => '11',
+        'field_name' => 'field_file',
+        'entity_type' => 'node',
+        'bundle' => 'test_content_type',
+        'data' => 'a:6:{s:5:"label";s:4:"File";s:6:"widget";a:5:{s:6:"weight";s:1:"5";s:4:"type";s:12:"file_generic";s:6:"module";s:4:"file";s:6:"active";i:1;s:8:"settings";a:1:{s:18:"progress_indicator";s:8:"throbber";}}s:8:"settings";a:5:{s:14:"file_directory";s:0:"";s:15:"file_extensions";s:15:"txt pdf ods odf";s:12:"max_filesize";s:5:"10 MB";s:17:"description_field";i:1;s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"file_default";s:6:"weight";s:1:"5";s:8:"settings";a:0:{}s:6:"module";s:4:"file";}}s:8:"required";i:0;s:11:"description";s:0:"";}',
+        'deleted' => '0',
+      ),
+    );
+    parent::setUp();
+  }
+
+}
diff --git a/core/modules/field/tests/src/Unit/Plugin/migrate/source/d7/ViewModeTest.php b/core/modules/field/tests/src/Unit/Plugin/migrate/source/d7/ViewModeTest.php
new file mode 100644
index 0000000..1dd982f
--- /dev/null
+++ b/core/modules/field/tests/src/Unit/Plugin/migrate/source/d7/ViewModeTest.php
@@ -0,0 +1,83 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\field\Unit\Plugin\migrate\source\d7\ViewModeTest.
+ */
+
+namespace Drupal\Tests\field\Unit\Plugin\migrate\source\d7;
+
+use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
+
+/**
+ * Tests D7 view mode source plugin.
+ *
+ * @group field
+ */
+class ViewModeTest extends MigrateSqlSourceTestCase {
+
+  const PLUGIN_CLASS = 'Drupal\field\Plugin\migrate\source\d7\ViewMode';
+
+  protected $migrationConfiguration = array(
+    'id' => 'test',
+    'source' => array(
+      'plugin' => 'd7_view_mode',
+    ),
+  );
+
+  protected $expectedResults = array(
+    array(
+      'entity_type' => 'node',
+      'view_mode' => 'default',
+    ),
+    array(
+      'entity_type' => 'node',
+      'view_mode' => 'teaser',
+    ),
+    array(
+      'entity_type' => 'user',
+      'view_mode' => 'default',
+    ),
+    array(
+      'entity_type' => 'comment',
+      'view_mode' => 'default',
+    ),
+  );
+
+  /**
+   * Prepopulate contents with results.
+   */
+  protected function setUp() {
+    $this->databaseContents['field_config_instance'] = array(
+      array(
+        'id' => '13',
+        'field_id' => '2',
+        'field_name' => 'body',
+        'entity_type' => 'node',
+        'bundle' => 'forum',
+        'data' => 'a:6:{s:5:"label";s:4:"Body";s:6:"widget";a:4:{s:4:"type";s:26:"text_textarea_with_summary";s:8:"settings";a:2:{s:4:"rows";i:20;s:12:"summary_rows";i:5;}s:6:"weight";i:1;s:6:"module";s:4:"text";}s:8:"settings";a:3:{s:15:"display_summary";b:1;s:15:"text_processing";i:1;s:18:"user_register_form";b:0;}s:7:"display";a:2:{s:7:"default";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:11;}s:6:"teaser";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:23:"text_summary_or_trimmed";s:8:"settings";a:1:{s:11:"trim_length";i:600;}s:6:"module";s:4:"text";s:6:"weight";i:11;}}s:8:"required";b:0;s:11:"description";s:0:"";}',
+        'deleted' => '0',
+      ),
+      array(
+        'id' => '33',
+        'field_id' => '11',
+        'field_name' => 'field_file',
+        'entity_type' => 'user',
+        'bundle' => 'user',
+        'data' => 'a:6:{s:5:"label";s:4:"File";s:6:"widget";a:5:{s:6:"weight";s:1:"8";s:4:"type";s:12:"file_generic";s:6:"module";s:4:"file";s:6:"active";i:1;s:8:"settings";a:1:{s:18:"progress_indicator";s:8:"throbber";}}s:8:"settings";a:5:{s:14:"file_directory";s:0:"";s:15:"file_extensions";s:3:"txt";s:12:"max_filesize";s:0:"";s:17:"description_field";i:0;s:18:"user_register_form";i:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"file_default";s:8:"settings";a:0:{}s:6:"module";s:4:"file";s:6:"weight";i:0;}}s:8:"required";i:0;s:11:"description";s:0:"";}',
+        'deleted' => '0',
+      ),
+      array(
+        'id' => '12',
+        'field_id' => '1',
+        'field_name' => 'comment_body',
+        'entity_type' => 'comment',
+        'bundle' => 'comment_node_forum',
+        'data' => 'a:6:{s:5:"label";s:7:"Comment";s:8:"settings";a:2:{s:15:"text_processing";i:1;s:18:"user_register_form";b:0;}s:8:"required";b:1;s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:12:"text_default";s:6:"weight";i:0;s:8:"settings";a:0:{}s:6:"module";s:4:"text";}}s:6:"widget";a:4:{s:4:"type";s:13:"text_textarea";s:8:"settings";a:1:{s:4:"rows";i:5;}s:6:"weight";i:0;s:6:"module";s:4:"text";}s:11:"description";s:0:"";}',
+        'deleted' => '0',
+      ),
+    );
+    parent::setUp();
+  }
+
+}
diff --git a/core/modules/migrate_drupal/config/schema/migrate_drupal.source.schema.yml b/core/modules/migrate_drupal/config/schema/migrate_drupal.source.schema.yml
index 86e801e..6152f9e 100644
--- a/core/modules/migrate_drupal/config/schema/migrate_drupal.source.schema.yml
+++ b/core/modules/migrate_drupal/config/schema/migrate_drupal.source.schema.yml
@@ -144,6 +144,9 @@ migrate_entity_constant:
     auto_create:
       type: boolean
       label: 'Entity reference selection setting: Auto-create new entities'
+    status:
+      type: boolean
+      label: 'Status'
 
 migrate.source.md_empty:
   type: migrate.source.empty
diff --git a/core/modules/node/migration_templates/d6_view_modes.yml b/core/modules/node/migration_templates/d6_view_modes.yml
index e2e0c8f..62eb6c8 100644
--- a/core/modules/node/migration_templates/d6_view_modes.yml
+++ b/core/modules/node/migration_templates/d6_view_modes.yml
@@ -7,7 +7,6 @@ source:
   constants:
     targetEntityType: node
     status: true
-
 process:
   mode:
     plugin: static_map
