diff --git a/core/modules/field/src/Plugin/migrate/process/FieldType.php b/core/modules/field/src/Plugin/migrate/process/FieldType.php
index 7874f9c..b9af082 100644
--- a/core/modules/field/src/Plugin/migrate/process/FieldType.php
+++ b/core/modules/field/src/Plugin/migrate/process/FieldType.php
@@ -9,6 +9,7 @@
 use Drupal\migrate\Plugin\migrate\process\StaticMap;
 use Drupal\migrate\Row;
 use Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManagerInterface;
+use Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -26,6 +27,13 @@ class FieldType extends StaticMap implements ContainerFactoryPluginInterface {
   protected $cckPluginManager;
 
   /**
+   * The field plugin manager.
+   *
+   * @var \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface
+   */
+  protected $fieldPluginManager;
+
+  /**
    * The migration object.
    *
    * @var \Drupal\migrate\Plugin\MigrationInterface
@@ -43,12 +51,15 @@ class FieldType extends StaticMap implements ContainerFactoryPluginInterface {
    *   The plugin definition.
    * @param \Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManagerInterface $cck_plugin_manager
    *   The cckfield plugin manager.
+   * @param \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface $field_plugin_manager
+   *   The field plugin manager.
    * @param \Drupal\migrate\Plugin\MigrationInterface $migration
    *   The migration being run.
    */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrateCckFieldPluginManagerInterface $cck_plugin_manager, MigrationInterface $migration = NULL) {
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrateCckFieldPluginManagerInterface $cck_plugin_manager, MigrateFieldPluginManagerInterface $field_plugin_manager, MigrationInterface $migration = NULL) {
     parent::__construct($configuration, $plugin_id, $plugin_definition);
     $this->cckPluginManager = $cck_plugin_manager;
+    $this->fieldPluginManager = $field_plugin_manager;
     $this->migration = $migration;
   }
 
@@ -61,6 +72,7 @@ public static function create(ContainerInterface $container, array $configuratio
       $plugin_id,
       $plugin_definition,
       $container->get('plugin.manager.migrate.cckfield'),
+      $container->get('plugin.manager.migrate.field'),
       $migration
     );
   }
@@ -70,13 +82,18 @@ public static function create(ContainerInterface $container, array $configuratio
    */
   public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
     $field_type = is_array($value) ? $value[0] : $value;
-
     try {
-      $plugin_id = $this->cckPluginManager->getPluginIdFromFieldType($field_type, [], $this->migration);
-      return $this->cckPluginManager->createInstance($plugin_id, [], $this->migration)->getFieldType($row);
+      $plugin_id = $this->fieldPluginManager->getPluginIdFromFieldType($field_type, [], $this->migration);
+      return $this->fieldPluginManager->createInstance($plugin_id, [], $this->migration)->getFieldType($row);
     }
     catch (PluginNotFoundException $e) {
-      return parent::transform($value, $migrate_executable, $row, $destination_property);
+      try {
+        $plugin_id = $this->cckPluginManager->getPluginIdFromFieldType($field_type, [], $this->migration);
+        return $this->cckPluginManager->createInstance($plugin_id, [], $this->migration)->getFieldType($row);
+      }
+      catch (PluginNotFoundException $e) {
+        return parent::transform($value, $migrate_executable, $row, $destination_property);
+      }
     }
   }
 
diff --git a/core/modules/link/src/Plugin/migrate/cckfield/LinkField.php b/core/modules/link/src/Plugin/migrate/field/d6/LinkField.php
similarity index 63%
rename from core/modules/link/src/Plugin/migrate/cckfield/LinkField.php
rename to core/modules/link/src/Plugin/migrate/field/d6/LinkField.php
index 314e8df..0d03656 100644
--- a/core/modules/link/src/Plugin/migrate/cckfield/LinkField.php
+++ b/core/modules/link/src/Plugin/migrate/field/d6/LinkField.php
@@ -1,12 +1,12 @@
 <?php
 
-namespace Drupal\link\Plugin\migrate\cckfield;
+namespace Drupal\link\Plugin\migrate\field\d6;
 
 use Drupal\migrate\Plugin\MigrationInterface;
-use Drupal\migrate_drupal\Plugin\migrate\cckfield\CckFieldPluginBase;
+use Drupal\migrate_drupal\Plugin\migrate\field\FieldPluginBase;
 
 /**
- * @MigrateCckField(
+ * @MigrateField(
  *   id = "link",
  *   core = {6},
  *   type_map = {
@@ -14,13 +14,13 @@
  *   }
  * )
  */
-class LinkField extends CckFieldPluginBase {
+class LinkField extends FieldPluginBase {
 
   /**
    * {@inheritdoc}
    */
   public function getFieldFormatterMap() {
-    // See d6_field_formatter_settings.yml and CckFieldPluginBase
+    // See d6_field_formatter_settings.yml and FieldPluginBase
     // processFieldFormatter().
     return [
       'default' => 'link',
@@ -37,9 +37,9 @@ public function getFieldFormatterMap() {
   /**
    * {@inheritdoc}
    */
-  public function processCckFieldValues(MigrationInterface $migration, $field_name, $data) {
+  public function processFieldValues(MigrationInterface $migration, $field_name, $data) {
     $process = [
-      'plugin' => 'd6_cck_link',
+      'plugin' => 'd6_field_link',
       'source' => $field_name,
     ];
     $migration->mergeProcessOfProperty($field_name, $process);
diff --git a/core/modules/link/src/Plugin/migrate/cckfield/d7/LinkField.php b/core/modules/link/src/Plugin/migrate/field/d7/LinkField.php
similarity index 88%
rename from core/modules/link/src/Plugin/migrate/cckfield/d7/LinkField.php
rename to core/modules/link/src/Plugin/migrate/field/d7/LinkField.php
index 5de568d..4e78ee5 100644
--- a/core/modules/link/src/Plugin/migrate/cckfield/d7/LinkField.php
+++ b/core/modules/link/src/Plugin/migrate/field/d7/LinkField.php
@@ -1,12 +1,12 @@
 <?php
 
-namespace Drupal\link\Plugin\migrate\cckfield\d7;
+namespace Drupal\link\Plugin\migrate\field\d7;
 
-use Drupal\link\Plugin\migrate\cckfield\LinkField as D6LinkField;
+use Drupal\link\Plugin\migrate\field\d6\LinkField as D6LinkField;
 use Drupal\migrate\Plugin\MigrationInterface;
 
 /**
- * @MigrateCckField(
+ * @MigrateField(
  *   id = "link_field",
  *   core = {7},
  *   type_map = {
diff --git a/core/modules/link/src/Plugin/migrate/process/d6/CckLink.php b/core/modules/link/src/Plugin/migrate/process/d6/CckLink.php
index 2c03412..d1e9be3 100644
--- a/core/modules/link/src/Plugin/migrate/process/d6/CckLink.php
+++ b/core/modules/link/src/Plugin/migrate/process/d6/CckLink.php
@@ -2,85 +2,12 @@
 
 namespace Drupal\link\Plugin\migrate\process\d6;
 
-use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
-use Drupal\migrate\Plugin\MigrationInterface;
-use Drupal\migrate\MigrateExecutableInterface;
-use Drupal\migrate\ProcessPluginBase;
-use Drupal\migrate\Row;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
 /**
  * @MigrateProcessPlugin(
  *   id = "d6_cck_link"
  * )
+ *
+ * @deprecated in Drupal 8.3.x, to be removed before Drupal 9.0.x. Use
+ * \Drupal\link\Plugin\migrate\process\d6\FieldLink instead.
  */
-class CckLink extends ProcessPluginBase implements ContainerFactoryPluginInterface {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition);
-    $this->migration = $migration;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
-    return new static(
-      $configuration,
-      $plugin_id,
-      $plugin_definition,
-      $migration
-    );
-  }
-
-  /**
-   * Turn a Drupal 6 URI into a Drupal 8-compatible format.
-   *
-   * @param string $uri
-   *   The 'url' value from Drupal 6.
-   *
-   * @return string
-   *   The Drupal 8-compatible URI.
-   *
-   * @see \Drupal\link\Plugin\Field\FieldWidget\LinkWidget::getUserEnteredStringAsUri()
-   */
-  protected function canonicalizeUri($uri) {
-    // If we already have a scheme, we're fine.
-    if (empty($uri) || !is_null(parse_url($uri, PHP_URL_SCHEME))) {
-      return $uri;
-    }
-
-    // Remove the <front> component of the URL.
-    if (strpos($uri, '<front>') === 0) {
-      $uri = substr($uri, strlen('<front>'));
-    }
-
-    // Add the internal: scheme and ensure a leading slash.
-    return 'internal:/' . ltrim($uri, '/');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
-    $attributes = unserialize($value['attributes']);
-    // Drupal 6 link attributes might be double serialized.
-    if (!is_array($attributes)) {
-      $attributes = unserialize($attributes);
-    }
-
-    if (!$attributes) {
-      $attributes = [];
-    }
-
-    // Massage the values into the correct form for the link.
-    $route['uri'] = $this->canonicalizeUri($value['url']);
-    $route['options']['attributes'] = $attributes;
-    $route['title'] = $value['title'];
-    return $route;
-  }
-
-}
+class CckLink extends FieldLink { }
diff --git a/core/modules/link/src/Plugin/migrate/process/d6/FieldLink.php b/core/modules/link/src/Plugin/migrate/process/d6/FieldLink.php
new file mode 100644
index 0000000..4badcb6
--- /dev/null
+++ b/core/modules/link/src/Plugin/migrate/process/d6/FieldLink.php
@@ -0,0 +1,86 @@
+<?php
+
+namespace Drupal\link\Plugin\migrate\process\d6;
+
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\migrate\Plugin\MigrationInterface;
+use Drupal\migrate\MigrateExecutableInterface;
+use Drupal\migrate\ProcessPluginBase;
+use Drupal\migrate\Row;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * @MigrateProcessPlugin(
+ *   id = "d6_field_link"
+ * )
+ */
+class FieldLink extends ProcessPluginBase implements ContainerFactoryPluginInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+    $this->migration = $migration;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $migration
+    );
+  }
+
+  /**
+   * Turn a Drupal 6 URI into a Drupal 8-compatible format.
+   *
+   * @param string $uri
+   *   The 'url' value from Drupal 6.
+   *
+   * @return string
+   *   The Drupal 8-compatible URI.
+   *
+   * @see \Drupal\link\Plugin\Field\FieldWidget\LinkWidget::getUserEnteredStringAsUri()
+   */
+  protected function canonicalizeUri($uri) {
+    // If we already have a scheme, we're fine.
+    if (empty($uri) || !is_null(parse_url($uri, PHP_URL_SCHEME))) {
+      return $uri;
+    }
+
+    // Remove the <front> component of the URL.
+    if (strpos($uri, '<front>') === 0) {
+      $uri = substr($uri, strlen('<front>'));
+    }
+
+    // Add the internal: scheme and ensure a leading slash.
+    return 'internal:/' . ltrim($uri, '/');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
+    $attributes = unserialize($value['attributes']);
+    // Drupal 6 link attributes might be double serialized.
+    if (!is_array($attributes)) {
+      $attributes = unserialize($attributes);
+    }
+
+    if (!$attributes) {
+      $attributes = [];
+    }
+
+    // Massage the values into the correct form for the link.
+    $route['uri'] = $this->canonicalizeUri($value['url']);
+    $route['options']['attributes'] = $attributes;
+    $route['title'] = $value['title'];
+    return $route;
+  }
+
+}
diff --git a/core/modules/link/tests/src/Unit/Plugin/migrate/process/d6/CckLinkTest.php b/core/modules/link/tests/src/Unit/Plugin/migrate/process/d6/FieldLinkTest.php
similarity index 81%
rename from core/modules/link/tests/src/Unit/Plugin/migrate/process/d6/CckLinkTest.php
rename to core/modules/link/tests/src/Unit/Plugin/migrate/process/d6/FieldLinkTest.php
index a96287a..4b4eda2 100644
--- a/core/modules/link/tests/src/Unit/Plugin/migrate/process/d6/CckLinkTest.php
+++ b/core/modules/link/tests/src/Unit/Plugin/migrate/process/d6/FieldLinkTest.php
@@ -2,21 +2,21 @@
 
 namespace Drupal\Tests\link\Unit\Plugin\migrate\process\d6;
 
-use Drupal\link\Plugin\migrate\process\d6\CckLink;
+use Drupal\link\Plugin\migrate\process\d6\FieldLink;
 use Drupal\Tests\UnitTestCase;
 
 /**
  * @group Link
  */
-class CckLinkTest extends UnitTestCase {
+class FieldLinkTest extends UnitTestCase {
 
   /**
-   * Test the url transformations in the CckLink process plugin.
+   * Test the url transformations in the FieldLink process plugin.
    *
    * @dataProvider canonicalizeUriDataProvider
    */
   public function testCanonicalizeUri($url, $expected) {
-    $link_plugin = new CckLink([], '', [], $this->getMock('\Drupal\migrate\Plugin\MigrationInterface'));
+    $link_plugin = new FieldLink([], '', [], $this->getMock('\Drupal\migrate\Plugin\MigrationInterface'));
     $transformed = $link_plugin->transform([
       'url' => $url,
       'title' => '',
diff --git a/core/modules/migrate_drupal/migrate_drupal.services.yml b/core/modules/migrate_drupal/migrate_drupal.services.yml
index 71a0b27..23b3492 100644
--- a/core/modules/migrate_drupal/migrate_drupal.services.yml
+++ b/core/modules/migrate_drupal/migrate_drupal.services.yml
@@ -1,4 +1,12 @@
 services:
+  plugin.manager.migrate.field:
+    class: Drupal\migrate_drupal\Plugin\MigrateFieldPluginManager
+    arguments:
+      - field
+      - '@container.namespaces'
+      - '@cache.discovery'
+      - '@module_handler'
+      - '\Drupal\migrate_drupal\Annotation\MigrateField'
   plugin.manager.migrate.cckfield:
     class: Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManager
     arguments:
@@ -7,3 +15,4 @@ services:
       - '@cache.discovery'
       - '@module_handler'
       - '\Drupal\migrate_drupal\Annotation\MigrateCckField'
+    deprecated: The "%service_id%" service is deprecated. You should use the 'plugin.manager.migrate.field' service instead. See https://www.drupal.org/node/2751897
diff --git a/core/modules/migrate_drupal/src/Annotation/MigrateCckField.php b/core/modules/migrate_drupal/src/Annotation/MigrateCckField.php
index 5e5a500..d7873e3 100644
--- a/core/modules/migrate_drupal/src/Annotation/MigrateCckField.php
+++ b/core/modules/migrate_drupal/src/Annotation/MigrateCckField.php
@@ -2,53 +2,20 @@
 
 namespace Drupal\migrate_drupal\Annotation;
 
-use Drupal\Component\Annotation\Plugin;
+@trigger_error('MigrateCckField is deprecated in Drupal 8.3.x and will be
+removed before Drupal 9.0.x. Use  \Drupal\migrate_drupal\Annotation\MigrateField
+instead.', E_USER_DEPRECATED);
 
 /**
- * Defines a cckfield plugin annotation object.
+ * Deprecated: Defines a cckfield plugin annotation object.
  *
- * cckfield plugins are variously responsible for handling the migration of
- * CCK fields from Drupal 6 to Drupal 8, and Field API fields from Drupal 7
- * to Drupal 8. They are allowed to alter CCK-related migrations when migrations
- * are being generated, and can compute destination field types for individual
- * fields during the actual migration process.
+ * @deprecated in Drupal 8.2.x, to be removed before Drupal 9.0.x. Use
+ * \Drupal\migrate_drupal\Annotation\MigrateField instead.
  *
  * Plugin Namespace: Plugin\migrate\cckfield
  *
  * @Annotation
  */
-class MigrateCckField extends Plugin {
-
-  /**
-   * @inheritdoc
-   */
-  public function __construct($values) {
-    parent::__construct($values);
-    // Provide default value for core property, in case it's missing.
-    if (empty($this->definition['core'])) {
-      $this->definition['core'] = [6];
-    }
-  }
-
-  /**
-   * The plugin ID.
-   *
-   * @var string
-   */
-  public $id;
-
-  /**
-   * Map of D6 and D7 field types to D8 field type plugin IDs.
-   *
-   * @var string[]
-   */
-  public $type_map = [];
-
-  /**
-   * The Drupal core version(s) this plugin applies to.
-   *
-   * @var int[]
-   */
-  public $core = [];
+class MigrateCckField extends MigrateField {
 
 }
diff --git a/core/modules/migrate_drupal/src/Annotation/MigrateField.php b/core/modules/migrate_drupal/src/Annotation/MigrateField.php
new file mode 100644
index 0000000..ad78bc9
--- /dev/null
+++ b/core/modules/migrate_drupal/src/Annotation/MigrateField.php
@@ -0,0 +1,54 @@
+<?php
+
+namespace Drupal\migrate_drupal\Annotation;
+
+use Drupal\Component\Annotation\Plugin;
+
+/**
+ * Defines a field plugin annotation object.
+ *
+ * Field plugins are responsible for handling the migration of custom fields
+ * (provided by CCK in Drupal 6 and Field API in Drupal 7) to Drupal 8. They are
+ * allowed to alter fieldable entity migrations when these migrations are being
+ * generated, and can compute destination field types for individual fields
+ * during the actual migration process.
+ *
+ * Plugin Namespace: Plugin\migrate\field
+ *
+ * @Annotation
+ */
+class MigrateField extends Plugin {
+
+  /**
+   * @inheritdoc
+   */
+  public function __construct($values) {
+    parent::__construct($values);
+    // Provide default value for core property, in case it's missing.
+    if (empty($this->definition['core'])) {
+      $this->definition['core'] = [6];
+    }
+  }
+
+  /**
+   * The plugin ID.
+   *
+   * @var string
+   */
+  public $id;
+
+  /**
+   * Map of D6 and D7 field types to D8 field type plugin IDs.
+   *
+   * @var string[]
+   */
+  public $type_map = [];
+
+  /**
+   * The Drupal core version(s) this plugin applies to.
+   *
+   * @var int[]
+   */
+  public $core = [];
+
+}
diff --git a/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldInterface.php b/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldInterface.php
index b30b2b8..2748aa4 100644
--- a/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldInterface.php
+++ b/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldInterface.php
@@ -2,64 +2,19 @@
 
 namespace Drupal\migrate_drupal\Plugin;
 
-use Drupal\Component\Plugin\PluginInspectionInterface;
+@trigger_error('MigrateCckFieldInterface is deprecated in Drupal 8.3.x and will
+be removed before Drupal 9.0.x. Use  \Drupal\migrate_drupal\Annotation\MigrateField
+instead.', E_USER_DEPRECATED);
+
 use Drupal\migrate\Plugin\MigrationInterface;
-use Drupal\migrate\Row;
 
 /**
  * Provides an interface for all CCK field type plugins.
+ *
+ * @deprecated in Drupal 8.3.x, to be removed before Drupal 9.0.x. Use
+ *   \Drupal\migrate_drupal\Annotation\MigrateField instead.
  */
-interface MigrateCckFieldInterface extends PluginInspectionInterface {
-
-  /**
-   * Apply any custom processing to the field migration.
-   *
-   * @param \Drupal\migrate\Plugin\MigrationInterface $migration
-   *   The migration entity.
-   */
-  public function processField(MigrationInterface $migration);
-
-  /**
-   * Apply any custom processing to the field instance migration.
-   *
-   * @param \Drupal\migrate\Plugin\MigrationInterface $migration
-   *   The migration entity.
-   */
-  public function processFieldInstance(MigrationInterface $migration);
-
-  /**
-   * Apply any custom processing to the field widget migration.
-   *
-   * @param \Drupal\migrate\Plugin\MigrationInterface $migration
-   *   The migration entity.
-   */
-  public function processFieldWidget(MigrationInterface $migration);
-
-  /**
-   * Apply any custom processing to the field formatter migration.
-   *
-   * @param \Drupal\migrate\Plugin\MigrationInterface $migration
-   *   The migration entity.
-   */
-  public function processFieldFormatter(MigrationInterface $migration);
-
-  /**
-   * Get a map between D6 formatters and D8 formatters for this field type.
-   *
-   * This is used by static::processFieldFormatter() in the base class.
-   *
-   * @return array
-   *   The keys are D6 formatters and the values are D8 formatters.
-   */
-  public function getFieldFormatterMap();
-
-  /**
-   * Get a map between D6 and D8 widgets for this field type.
-   *
-   * @return array
-   *   The keys are D6 field widget types and the values D8 widgets.
-   */
-  public function getFieldWidgetMap();
+interface MigrateCckFieldInterface extends MigrateFieldInterface {
 
   /**
    * Apply any custom processing to the cck bundle migrations.
@@ -73,15 +28,4 @@ public function getFieldWidgetMap();
    */
   public function processCckFieldValues(MigrationInterface $migration, $field_name, $data);
 
-  /**
-   * Computes the destination type of a migrated field.
-   *
-   * @param \Drupal\migrate\Row $row
-   *   The field being migrated.
-   *
-   * @return string
-   *   The destination field type.
-   */
-  public function getFieldType(Row $row);
-
 }
diff --git a/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldPluginManager.php b/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldPluginManager.php
index 56c7b5b..ce51907 100644
--- a/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldPluginManager.php
+++ b/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldPluginManager.php
@@ -2,54 +2,16 @@
 
 namespace Drupal\migrate_drupal\Plugin;
 
-use Drupal\Component\Plugin\Exception\PluginNotFoundException;
-use Drupal\migrate\Plugin\MigratePluginManager;
-use Drupal\migrate\Plugin\MigrationInterface;
+@trigger_error('MigrateCckFieldPluginManager is deprecated in Drupal 8.3.x and will
+be removed before Drupal 9.0.x. Use  \Drupal\migrate_drupal\Annotation\MigrateFieldPluginManager
+instead.', E_USER_DEPRECATED);
 
 /**
- * Plugin manager for migrate cckfield plugins.
+ * Deprecated: Plugin manager for migrate field plugins.
  *
- * @see \Drupal\migrate_drupal\Plugin\MigrateCckFieldInterface
- * @see \Drupal\migrate\Annotation\MigrateCckField
- * @see plugin_api
+ * @deprecated in Drupal 8.3.x, to be removed before Drupal 9.0.x. Use
+ *   \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManager instead.
  *
  * @ingroup migration
  */
-class MigrateCckFieldPluginManager extends MigratePluginManager implements MigrateCckFieldPluginManagerInterface {
-
-  /**
-   * The default version of core to use for cck field plugins.
-   *
-   * These plugins were initially only built and used for Drupal 6 fields.
-   * Having been extended for Drupal 7 with a "core" annotation, we fall back to
-   * Drupal 6 where none exists.
-   */
-  const DEFAULT_CORE_VERSION = 6;
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getPluginIdFromFieldType($field_type, array $configuration = [], MigrationInterface $migration = NULL) {
-    $core = static::DEFAULT_CORE_VERSION;
-    if (!empty($configuration['core'])) {
-      $core = $configuration['core'];
-    }
-    elseif (!empty($migration->getPluginDefinition()['migration_tags'])) {
-      foreach ($migration->getPluginDefinition()['migration_tags'] as $tag) {
-        if ($tag == 'Drupal 7') {
-          $core = 7;
-        }
-      }
-    }
-
-    foreach ($this->getDefinitions() as $plugin_id => $definition) {
-      if (in_array($core, $definition['core'])) {
-        if (array_key_exists($field_type, $definition['type_map']) || $field_type === $plugin_id) {
-          return $plugin_id;
-        }
-      }
-    }
-    throw new PluginNotFoundException($field_type);
-  }
-
-}
+class MigrateCckFieldPluginManager extends MigrateFieldPluginManager implements MigrateCckFieldPluginManagerInterface { }
diff --git a/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldPluginManagerInterface.php b/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldPluginManagerInterface.php
index a5371b9..c9e145e 100644
--- a/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldPluginManagerInterface.php
+++ b/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldPluginManagerInterface.php
@@ -2,27 +2,14 @@
 
 namespace Drupal\migrate_drupal\Plugin;
 
-use Drupal\migrate\Plugin\MigratePluginManagerInterface;
-use Drupal\migrate\Plugin\MigrationInterface;
-
-interface MigrateCckFieldPluginManagerInterface extends MigratePluginManagerInterface {
-
-  /**
-   * Get the plugin ID from the field type.
-   *
-   * @param string $field_type
-   *   The field type being migrated.
-   * @param array $configuration
-   *   (optional) An array of configuration relevant to the plugin instance.
-   * @param \Drupal\migrate\Plugin\MigrationInterface|null $migration
-   *   (optional) The current migration instance.
-   *
-   * @return string
-   *   The ID of the plugin for the field_type if available.
-   *
-   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
-   *   If the plugin cannot be determined, such as if the field type is invalid.
-   */
-  public function getPluginIdFromFieldType($field_type, array $configuration = [], MigrationInterface $migration = NULL);
-
-}
+@trigger_error('MigrateCckFieldPluginManagerInterface is deprecated in Drupal 8.3.x
+and will be removed before Drupal 9.0.x. Use  \Drupal\migrate_drupal\Annotation\MigrateFieldPluginManagerInterface
+instead.', E_USER_DEPRECATED);
+
+/**
+ * Provides an interface for cck field plugin manager.
+ *
+ * @deprecated in Drupal 8.3.x, to be removed before Drupal 9.0.x. Use
+ *   \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface instead.
+ */
+interface MigrateCckFieldPluginManagerInterface extends MigrateFieldPluginManagerInterface { }
diff --git a/core/modules/migrate_drupal/src/Plugin/MigrateFieldInterface.php b/core/modules/migrate_drupal/src/Plugin/MigrateFieldInterface.php
new file mode 100644
index 0000000..c8cecad
--- /dev/null
+++ b/core/modules/migrate_drupal/src/Plugin/MigrateFieldInterface.php
@@ -0,0 +1,87 @@
+<?php
+
+namespace Drupal\migrate_drupal\Plugin;
+
+use Drupal\Component\Plugin\PluginInspectionInterface;
+use Drupal\migrate\Plugin\MigrationInterface;
+use Drupal\migrate\Row;
+
+/**
+ * Provides an interface for all field type plugins.
+ */
+interface MigrateFieldInterface extends PluginInspectionInterface {
+
+  /**
+   * Apply any custom processing to the field migration.
+   *
+   * @param \Drupal\migrate\Plugin\MigrationInterface $migration
+   *   The migration entity.
+   */
+  public function processField(MigrationInterface $migration);
+
+  /**
+   * Apply any custom processing to the field instance migration.
+   *
+   * @param \Drupal\migrate\Plugin\MigrationInterface $migration
+   *   The migration entity.
+   */
+  public function processFieldInstance(MigrationInterface $migration);
+
+  /**
+   * Apply any custom processing to the field widget migration.
+   *
+   * @param \Drupal\migrate\Plugin\MigrationInterface $migration
+   *   The migration entity.
+   */
+  public function processFieldWidget(MigrationInterface $migration);
+
+  /**
+   * Apply any custom processing to the field formatter migration.
+   *
+   * @param \Drupal\migrate\Plugin\MigrationInterface $migration
+   *   The migration entity.
+   */
+  public function processFieldFormatter(MigrationInterface $migration);
+
+  /**
+   * Get a map between D6 formatters and D8 formatters for this field type.
+   *
+   * This is used by static::processFieldFormatter() in the base class.
+   *
+   * @return array
+   *   The keys are D6 formatters and the values are D8 formatters.
+   */
+  public function getFieldFormatterMap();
+
+  /**
+   * Get a map between D6 and D8 widgets for this field type.
+   *
+   * @return array
+   *   The keys are D6 field widget types and the values D8 widgets.
+   */
+  public function getFieldWidgetMap();
+
+  /**
+   * Apply any custom processing to the field bundle migrations.
+   *
+   * @param \Drupal\migrate\Plugin\MigrationInterface $migration
+   *   The migration entity.
+   * @param string $field_name
+   *   The field name we're processing the value for.
+   * @param array $data
+   *   The array of field data from FieldValues::fieldData().
+   */
+  public function processFieldValues(MigrationInterface $migration, $field_name, $data);
+
+  /**
+   * Computes the destination type of a migrated field.
+   *
+   * @param \Drupal\migrate\Row $row
+   *   The field being migrated.
+   *
+   * @return string
+   *   The destination field type.
+   */
+  public function getFieldType(Row $row);
+
+}
diff --git a/core/modules/migrate_drupal/src/Plugin/MigrateFieldPluginManager.php b/core/modules/migrate_drupal/src/Plugin/MigrateFieldPluginManager.php
new file mode 100644
index 0000000..6065157
--- /dev/null
+++ b/core/modules/migrate_drupal/src/Plugin/MigrateFieldPluginManager.php
@@ -0,0 +1,56 @@
+<?php
+
+namespace Drupal\migrate_drupal\Plugin;
+
+use Drupal\Component\Plugin\Exception\PluginNotFoundException;
+use Drupal\migrate\Plugin\MigratePluginManager;
+use Drupal\migrate\Plugin\MigrationInterface;
+
+/**
+ * Plugin manager for migrate cckfield plugins.
+ *
+ * @see \Drupal\migrate_drupal\Plugin\MigrateFieldInterface
+ * @see \Drupal\migrate\Annotation\MigrateField
+ * @see plugin_api
+ *
+ * @ingroup migration
+ */
+class MigrateFieldPluginManager extends MigratePluginManager implements MigrateFieldPluginManagerInterface {
+
+  /**
+   * The default version of core to use for field plugins.
+   *
+   * These plugins were initially only built and used for Drupal 6 fields.
+   * Having been extended for Drupal 7 with a "core" annotation, we fall back to
+   * Drupal 6 where none exists.
+   */
+  const DEFAULT_CORE_VERSION = 6;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPluginIdFromFieldType($field_type, array $configuration = [], MigrationInterface $migration = NULL) {
+    $core = static::DEFAULT_CORE_VERSION;
+    if (!empty($configuration['core'])) {
+      $core = $configuration['core'];
+    }
+    elseif (!empty($migration->getPluginDefinition()['migration_tags'])) {
+      foreach ($migration->getPluginDefinition()['migration_tags'] as $tag) {
+        if ($tag == 'Drupal 7') {
+          $core = 7;
+        }
+      }
+    }
+
+    $definitions = $this->getDefinitions();
+    foreach ($definitions as $plugin_id => $definition) {
+      if (in_array($core, $definition['core'])) {
+        if (array_key_exists($field_type, $definition['type_map']) || $field_type === $plugin_id) {
+          return $plugin_id;
+        }
+      }
+    }
+    throw new PluginNotFoundException($field_type);
+  }
+
+}
diff --git a/core/modules/migrate_drupal/src/Plugin/MigrateFieldPluginManagerInterface.php b/core/modules/migrate_drupal/src/Plugin/MigrateFieldPluginManagerInterface.php
new file mode 100644
index 0000000..7219c2b
--- /dev/null
+++ b/core/modules/migrate_drupal/src/Plugin/MigrateFieldPluginManagerInterface.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace Drupal\migrate_drupal\Plugin;
+
+use Drupal\migrate\Plugin\MigratePluginManagerInterface;
+use Drupal\migrate\Plugin\MigrationInterface;
+
+interface MigrateFieldPluginManagerInterface extends MigratePluginManagerInterface {
+
+  /**
+   * Get the plugin ID from the field type.
+   *
+   * @param string $field_type
+   *   The field type being migrated.
+   * @param array $configuration
+   *   (optional) An array of configuration relevant to the plugin instance.
+   * @param \Drupal\migrate\Plugin\MigrationInterface|null $migration
+   *   (optional) The current migration instance.
+   *
+   * @return string
+   *   The ID of the plugin for the field_type if available.
+   *
+   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
+   *   If the plugin cannot be determined, such as if the field type is invalid.
+   */
+  public function getPluginIdFromFieldType($field_type, array $configuration = [], MigrationInterface $migration = NULL);
+
+}
diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/CckMigration.php b/core/modules/migrate_drupal/src/Plugin/migrate/CckMigration.php
index 017b7e7..ca4b531 100644
--- a/core/modules/migrate_drupal/src/Plugin/migrate/CckMigration.php
+++ b/core/modules/migrate_drupal/src/Plugin/migrate/CckMigration.php
@@ -2,131 +2,17 @@
 
 namespace Drupal\migrate_drupal\Plugin\migrate;
 
-use Drupal\Component\Plugin\Exception\PluginNotFoundException;
-use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
-use Drupal\migrate\Exception\RequirementsException;
-use Drupal\migrate\Plugin\MigrateDestinationPluginManager;
-use Drupal\migrate\Plugin\MigratePluginManagerInterface;
-use Drupal\migrate\Plugin\Migration;
-use Drupal\migrate\Plugin\MigrationPluginManagerInterface;
-use Drupal\migrate\Plugin\RequirementsInterface;
-use Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManagerInterface;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
 /**
  * Migration plugin class for migrations dealing with CCK field values.
+ *
+ * @deprecated in Drupal 8.3.x, to be removed before Drupal 9.0.x. Use
+ * \Drupal\migrate_drupal\Plugin\migrate\FieldMigration instead.
  */
-class CckMigration extends Migration implements ContainerFactoryPluginInterface {
-
-  /**
-   * Flag indicating whether the CCK data has been filled already.
-   *
-   * @var bool
-   */
-  protected $init = FALSE;
-
-  /**
-   * List of cckfield plugin IDs which have already run.
-   *
-   * @var string[]
-   */
-  protected $processedFieldTypes = [];
-
-  /**
-   * Already-instantiated cckfield plugins, keyed by ID.
-   *
-   * @var \Drupal\migrate_drupal\Plugin\MigrateCckFieldInterface[]
-   */
-  protected $cckPluginCache;
-
-  /**
-   * The cckfield plugin manager.
-   *
-   * @var \Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManagerInterface
-   */
-  protected $cckPluginManager;
-
-  /**
-   * Constructs a CckMigration.
-   *
-   * @param array $configuration
-   *   Plugin configuration.
-   * @param string $plugin_id
-   *   The plugin ID.
-   * @param mixed $plugin_definition
-   *   The plugin definition.
-   * @param \Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManagerInterface $cck_manager
-   *   The cckfield plugin manager.
-   * @param \Drupal\migrate\Plugin\MigrationPluginManagerInterface $migration_plugin_manager
-   *   The migration plugin manager.
-   * @param \Drupal\migrate\Plugin\MigratePluginManagerInterface $source_plugin_manager
-   *   The source migration plugin manager.
-   * @param \Drupal\migrate\Plugin\MigratePluginManagerInterface $process_plugin_manager
-   *   The process migration plugin manager.
-   * @param \Drupal\migrate\Plugin\MigrateDestinationPluginManager $destination_plugin_manager
-   *   The destination migration plugin manager.
-   * @param \Drupal\migrate\Plugin\MigratePluginManagerInterface $idmap_plugin_manager
-   *   The ID map migration plugin manager.
-   */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrateCckFieldPluginManagerInterface $cck_manager, MigrationPluginManagerInterface $migration_plugin_manager, MigratePluginManagerInterface $source_plugin_manager, MigratePluginManagerInterface $process_plugin_manager, MigrateDestinationPluginManager $destination_plugin_manager, MigratePluginManagerInterface $idmap_plugin_manager) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition, $migration_plugin_manager, $source_plugin_manager, $process_plugin_manager, $destination_plugin_manager, $idmap_plugin_manager);
-    $this->cckPluginManager = $cck_manager;
-  }
+class CckMigration extends FieldMigration {
 
   /**
    * {@inheritdoc}
    */
-  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static(
-      $configuration,
-      $plugin_id,
-      $plugin_definition,
-      $container->get('plugin.manager.migrate.cckfield'),
-      $container->get('plugin.manager.migration'),
-      $container->get('plugin.manager.migrate.source'),
-      $container->get('plugin.manager.migrate.process'),
-      $container->get('plugin.manager.migrate.destination'),
-      $container->get('plugin.manager.migrate.id_map')
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getProcess() {
-    if (!$this->init) {
-      $this->init = TRUE;
-      $source_plugin = $this->migrationPluginManager->createInstance($this->pluginId)->getSourcePlugin();
-      if ($source_plugin instanceof RequirementsInterface) {
-        try {
-          $source_plugin->checkRequirements();
-        }
-        catch (RequirementsException $e) {
-          // Kill the rest of the method.
-          $source_plugin = [];
-        }
-      }
-      foreach ($source_plugin as $row) {
-        $field_type = $row->getSourceProperty('type');
-        try {
-          $plugin_id = $this->cckPluginManager->getPluginIdFromFieldType($field_type, [], $this);
-        }
-        catch (PluginNotFoundException $ex) {
-          continue;
-        }
-
-        if (!isset($this->processedFieldTypes[$field_type])) {
-          $this->processedFieldTypes[$field_type] = TRUE;
-          // Allow the cckfield plugin to alter the migration as necessary so
-          // that it knows how to handle fields of this type.
-          if (!isset($this->cckPluginCache[$field_type])) {
-            $this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($plugin_id, [], $this);
-          }
-          call_user_func([$this->cckPluginCache[$field_type], $this->pluginDefinition['cck_plugin_method']], $this);
-        }
-      }
-    }
-    return parent::getProcess();
-  }
+  const PLUGIN_METHOD = 'cck_plugin_method';
 
 }
diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/FieldMigration.php b/core/modules/migrate_drupal/src/Plugin/migrate/FieldMigration.php
new file mode 100644
index 0000000..c7aaa2d
--- /dev/null
+++ b/core/modules/migrate_drupal/src/Plugin/migrate/FieldMigration.php
@@ -0,0 +1,171 @@
+<?php
+
+namespace Drupal\migrate_drupal\Plugin\migrate;
+
+use Drupal\Component\Plugin\Exception\PluginNotFoundException;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\migrate\Exception\RequirementsException;
+use Drupal\migrate\Plugin\MigrateDestinationPluginManager;
+use Drupal\migrate\Plugin\MigratePluginManager;
+use Drupal\migrate\Plugin\Migration;
+use Drupal\migrate\Plugin\MigrationPluginManagerInterface;
+use Drupal\migrate\Plugin\RequirementsInterface;
+use Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManagerInterface;
+use Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Migration plugin class for migrations dealing with field config and values.
+ */
+class FieldMigration extends Migration implements ContainerFactoryPluginInterface {
+
+  /**
+   * Defines which configuration option has the migration processing function.
+   *
+   * Default method is 'field_plugin_method'. For backwards compatibility,
+   * this constant is overridden in the CckMigration class, in order to
+   * fallback to the old 'cck_plugin_method'.
+   *
+   * @const string
+   */
+  const PLUGIN_METHOD = 'field_plugin_method';
+
+  /**
+   * Flag indicating whether the field data has been filled already.
+   *
+   * @var bool
+   */
+  protected $init = FALSE;
+
+  /**
+   * List of field plugin IDs which have already run.
+   *
+   * @var string[]
+   */
+  protected $processedFieldTypes = [];
+
+  /**
+   * Already-instantiated field plugins, keyed by ID.
+   *
+   * @var \Drupal\migrate_drupal\Plugin\MigrateFieldInterface[]
+   */
+  protected $fieldPluginCache;
+
+  /**
+   * The field plugin manager.
+   *
+   * @var \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface
+   */
+  protected $fieldPluginManager;
+
+  /**
+   * Already-instantiated cckfield plugins, keyed by ID.
+   *
+   * @var \Drupal\migrate_drupal\Plugin\MigrateCckFieldInterface[]
+   */
+  protected $cckPluginCache;
+
+  /**
+   * The cckfield plugin manager.
+   *
+   * @var \Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManagerInterface
+   */
+  protected $cckPluginManager;
+
+  /**
+   * Constructs a FieldMigration.
+   *
+   * @param array $configuration
+   *   Plugin configuration.
+   * @param string $plugin_id
+   *   The plugin ID.
+   * @param mixed $plugin_definition
+   *   The plugin definition.
+   * @param \Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManagerInterface $cck_manager
+   *   The cckfield plugin manager.
+   * @param \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface $field_manager
+   *   The field plugin manager.
+   * @param \Drupal\migrate\Plugin\MigrationPluginManagerInterface $migration_plugin_manager
+   *   The migration plugin manager.
+   * @param \Drupal\migrate\Plugin\MigratePluginManager $source_plugin_manager
+   *   The source migration plugin manager.
+   * @param \Drupal\migrate\Plugin\MigratePluginManager $process_plugin_manager
+   *   The process migration plugin manager.
+   * @param \Drupal\migrate\Plugin\MigrateDestinationPluginManager $destination_plugin_manager
+   *   The destination migration plugin manager.
+   * @param \Drupal\migrate\Plugin\MigratePluginManager $idmap_plugin_manager
+   *   The ID map migration plugin manager.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrateCckFieldPluginManagerInterface $cck_manager, MigrateFieldPluginManagerInterface $field_manager, MigrationPluginManagerInterface $migration_plugin_manager, MigratePluginManager $source_plugin_manager, MigratePluginManager $process_plugin_manager, MigrateDestinationPluginManager $destination_plugin_manager, MigratePluginManager $idmap_plugin_manager) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $migration_plugin_manager, $source_plugin_manager, $process_plugin_manager, $destination_plugin_manager, $idmap_plugin_manager);
+    $this->cckPluginManager = $cck_manager;
+    $this->fieldPluginManager = $field_manager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('plugin.manager.migrate.cckfield'),
+      $container->get('plugin.manager.migrate.field'),
+      $container->get('plugin.manager.migration'),
+      $container->get('plugin.manager.migrate.source'),
+      $container->get('plugin.manager.migrate.process'),
+      $container->get('plugin.manager.migrate.destination'),
+      $container->get('plugin.manager.migrate.id_map')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getProcess() {
+    if (!$this->init) {
+      $this->init = TRUE;
+      $source_plugin = $this->migrationPluginManager->createInstance($this->pluginId)->getSourcePlugin();
+      if ($source_plugin instanceof RequirementsInterface) {
+        try {
+          $source_plugin->checkRequirements();
+        }
+        catch (RequirementsException $e) {
+          // Kill the rest of the method.
+          $source_plugin = [];
+        }
+      }
+      foreach ($source_plugin as $row) {
+        $field_type = $row->getSourceProperty('type');
+
+        try {
+          $plugin_id = $this->cckPluginManager->getPluginIdFromFieldType($field_type, [], $this);
+          $Manager = $this->cckPluginManager;
+        }
+        catch (PluginNotFoundException $ex) {
+          try {
+            $plugin_id = $this->fieldPluginManager->getPluginIdFromFieldType($field_type, [], $this);
+            $Manager = $this->fieldPluginManager;
+          }
+          catch (PluginNotFoundException $ex) {
+            continue;
+          }
+        }
+
+        if (!isset($this->processedFieldTypes[$field_type]) && $Manager->hasDefinition($plugin_id)) {
+          $this->processedFieldTypes[$field_type] = TRUE;
+          // Allow the field plugin to alter the migration as necessary so that
+          // it knows how to handle fields of this type.
+          if (!isset($this->fieldPluginCache[$field_type])) {
+            $this->fieldPluginCache[$field_type] = $Manager->createInstance($plugin_id, [], $this);
+          }
+        }
+        $method = $this->pluginDefinition[static::PLUGIN_METHOD];
+        call_user_func([$this->fieldPluginCache[$field_type], $method], $this);
+      }
+    }
+    return parent::getProcess();
+  }
+
+}
diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/cckfield/CckFieldPluginBase.php b/core/modules/migrate_drupal/src/Plugin/migrate/cckfield/CckFieldPluginBase.php
index d942bce..0d61c90 100644
--- a/core/modules/migrate_drupal/src/Plugin/migrate/cckfield/CckFieldPluginBase.php
+++ b/core/modules/migrate_drupal/src/Plugin/migrate/cckfield/CckFieldPluginBase.php
@@ -2,82 +2,49 @@
 
 namespace Drupal\migrate_drupal\Plugin\migrate\cckfield;
 
-use Drupal\Core\Plugin\PluginBase;
+@trigger_error('CckFieldPluginBase is deprecated in Drupal 8.3.x and will be
+be removed before Drupal 9.0.x. Use  \Drupal\migrate_drupal\Plugin\migrate\field\FieldPluginBase
+instead.', E_USER_DEPRECATED);
+
 use Drupal\migrate\Plugin\MigrationInterface;
-use Drupal\migrate\Row;
-use Drupal\migrate_drupal\Plugin\MigrateCckFieldInterface;
+use Drupal\migrate_drupal\Plugin\migrate\field\FieldPluginBase;
 
 /**
- * The base class for all cck field plugins.
+ * The base class for all field plugins.
  *
- * @see \Drupal\migrate\Plugin\MigratePluginManager
- * @see \Drupal\migrate_drupal\Annotation\MigrateCckField
- * @see \Drupal\migrate_drupal\Plugin\MigrateCckFieldInterface
- * @see plugin_api
+ * @deprecated in Drupal 8.3.x, to be removed before Drupal 9.0.x. Use
+ * \Drupal\migrate_drupal\Plugin\migrate\field\FieldPluginBase instead.
  *
  * @ingroup migration
  */
-abstract class CckFieldPluginBase extends PluginBase implements MigrateCckFieldInterface {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function processField(MigrationInterface $migration) {
-    $process[0]['map'][$this->pluginId][$this->pluginId] = $this->pluginId;
-    $migration->mergeProcessOfProperty('type', $process);
-  }
+abstract class CckFieldPluginBase extends FieldPluginBase {
 
   /**
-   * {@inheritdoc}
+   * Apply any custom processing to the field bundle migrations.
+   *
+   * @param \Drupal\migrate\Plugin\MigrationInterface $migration
+   *   The migration entity.
+   * @param string $field_name
+   *   The field name we're processing the value for.
+   * @param array $data
+   *   The array of field data from FieldValues::fieldData().
    */
-  public function processFieldInstance(MigrationInterface $migration) {
-    // Nothing to do by default with field instances.
+  public function processFieldValues(MigrationInterface $migration, $field_name, $data) {
+    // Provide a bridge to the old method declared on the interface and now an
+    // abstract method in this class.
+    return $this->processCckFieldValues($migration, $field_name, $data);
   }
 
   /**
-   * {@inheritdoc}
+   * Apply any custom processing to the field bundle migrations.
+   *
+   * @param \Drupal\migrate\Plugin\MigrationInterface $migration
+   *   The migration entity.
+   * @param string $field_name
+   *   The field name we're processing the value for.
+   * @param array $data
+   *   The array of field data from FieldValues::fieldData().
    */
-  public function processFieldWidget(MigrationInterface $migration) {
-    $process = [];
-    foreach ($this->getFieldWidgetMap() as $source_widget => $destination_widget) {
-      $process['type']['map'][$source_widget] = $destination_widget;
-    }
-    $migration->mergeProcessOfProperty('options/type', $process);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFieldWidgetMap() {
-    // By default, use the plugin ID for the widget types.
-    return [
-      $this->pluginId => $this->pluginId . '_default',
-    ];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function processFieldFormatter(MigrationInterface $migration) {
-    $process = [];
-    foreach ($this->getFieldFormatterMap() as $source_format => $destination_format) {
-      $process[0]['map'][$this->pluginId][$source_format] = $destination_format;
-    }
-    $migration->mergeProcessOfProperty('options/type', $process);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFieldType(Row $row) {
-    $field_type = $row->getSourceProperty('type');
-
-    if (isset($this->pluginDefinition['type_map'][$field_type])) {
-      return $this->pluginDefinition['type_map'][$field_type];
-    }
-    else {
-      return $field_type;
-    }
-  }
+  abstract public function processCckFieldValues(MigrationInterface $migration, $field_name, $data);
 
 }
diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/field/FieldPluginBase.php b/core/modules/migrate_drupal/src/Plugin/migrate/field/FieldPluginBase.php
new file mode 100644
index 0000000..852c6ca
--- /dev/null
+++ b/core/modules/migrate_drupal/src/Plugin/migrate/field/FieldPluginBase.php
@@ -0,0 +1,83 @@
+<?php
+
+namespace Drupal\migrate_drupal\Plugin\migrate\field;
+
+use Drupal\Core\Plugin\PluginBase;
+use Drupal\migrate\Plugin\MigrationInterface;
+use Drupal\migrate\Row;
+use Drupal\migrate_drupal\Plugin\MigrateFieldInterface;
+
+/**
+ * The base class for all field plugins.
+ *
+ * @see \Drupal\migrate\Plugin\MigratePluginManager
+ * @see \Drupal\migrate_drupal\Annotation\MigrateField
+ * @see \Drupal\migrate_drupal\Plugin\MigrateFieldInterface
+ * @see plugin_api
+ *
+ * @ingroup migration
+ */
+abstract class FieldPluginBase extends PluginBase implements MigrateFieldInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function processField(MigrationInterface $migration) {
+    $process[0]['map'][$this->pluginId][$this->pluginId] = $this->pluginId;
+    $migration->mergeProcessOfProperty('type', $process);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function processFieldInstance(MigrationInterface $migration) {
+    // Nothing to do by default with field instances.
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function processFieldWidget(MigrationInterface $migration) {
+    $process = [];
+    foreach ($this->getFieldWidgetMap() as $source_widget => $destination_widget) {
+      $process['type']['map'][$source_widget] = $destination_widget;
+    }
+    $migration->mergeProcessOfProperty('options/type', $process);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFieldWidgetMap() {
+    // By default, use the plugin ID for the widget types.
+    return [
+      $this->pluginId => $this->pluginId . '_default',
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function processFieldFormatter(MigrationInterface $migration) {
+    $process = [];
+    foreach ($this->getFieldFormatterMap() as $source_format => $destination_format) {
+      $process[0]['map'][$this->pluginId][$source_format] = $destination_format;
+    }
+    $migration->mergeProcessOfProperty('options/type', $process);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFieldType(Row $row) {
+    $field_type = $row->getSourceProperty('type');
+
+    if (isset($this->pluginDefinition['type_map'][$field_type])) {
+      return $this->pluginDefinition['type_map'][$field_type];
+    }
+    else {
+      return $field_type;
+    }
+  }
+
+}
diff --git a/core/modules/migrate_drupal/tests/modules/migrate_field_plugin_manager_test/migrate_field_plugin_manager_test.info.yml b/core/modules/migrate_drupal/tests/modules/migrate_field_plugin_manager_test/migrate_field_plugin_manager_test.info.yml
new file mode 100644
index 0000000..db67a4f
--- /dev/null
+++ b/core/modules/migrate_drupal/tests/modules/migrate_field_plugin_manager_test/migrate_field_plugin_manager_test.info.yml
@@ -0,0 +1,6 @@
+name: 'Migrate field plugin manager test'
+type: module
+description: 'Example module demonstrating the field plugin manager in the Migrate API.'
+package: Testing
+version: VERSION
+core: 8.x
diff --git a/core/modules/migrate_drupal/tests/modules/migrate_field_plugin_manager_test/migrate_field_plugin_manager_test.module b/core/modules/migrate_drupal/tests/modules/migrate_field_plugin_manager_test/migrate_field_plugin_manager_test.module
new file mode 100644
index 0000000..9f9da0d
--- /dev/null
+++ b/core/modules/migrate_drupal/tests/modules/migrate_field_plugin_manager_test/migrate_field_plugin_manager_test.module
@@ -0,0 +1,14 @@
+<?php
+
+/**
+ * @file
+ * Module for Migrate Field Plugin Manager testing.
+ */
+
+use Drupal\migrate_field_plugin_manager_test\Plugin\migrate\cckfield\d6\FileField;
+
+function migrate_field_plugin_manager_test_migrate_field_info_alter(array &$definitions) {
+  if (isset($definitions['filefield'])) {
+    $definitions['filefield']['class'] = FileField::class;
+  }
+}
diff --git a/core/modules/migrate_drupal/tests/modules/migrate_field_plugin_manager_test/src/Plugin/migrate/cckfield/d6/FileField.php b/core/modules/migrate_drupal/tests/modules/migrate_field_plugin_manager_test/src/Plugin/migrate/cckfield/d6/FileField.php
new file mode 100644
index 0000000..903c7e8
--- /dev/null
+++ b/core/modules/migrate_drupal/tests/modules/migrate_field_plugin_manager_test/src/Plugin/migrate/cckfield/d6/FileField.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace Drupal\migrate_field_plugin_manager_test\Plugin\migrate\cckfield\d6;
+
+use Drupal\migrate\Plugin\MigrationInterface;
+use Drupal\migrate_drupal\Plugin\migrate\cckfield\CckFieldPluginBase;
+
+/**
+ * @MigrateCckField(
+ *   id = "filefield",
+ *   core = {6}
+ * )
+ */
+class FileField extends CckFieldPluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFieldFormatterMap() {
+    return [];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function processCckFieldValues(MigrationInterface $migration, $field_name, $data) {
+    $migration->mergeProcessOfProperty($field_name, [
+      'class' => __CLASS__,
+    ]);
+  }
+
+}
diff --git a/core/modules/migrate_drupal/tests/modules/migrate_field_plugin_manager_test/src/Plugin/migrate/field/D6FileField.php b/core/modules/migrate_drupal/tests/modules/migrate_field_plugin_manager_test/src/Plugin/migrate/field/D6FileField.php
new file mode 100644
index 0000000..08ca88c
--- /dev/null
+++ b/core/modules/migrate_drupal/tests/modules/migrate_field_plugin_manager_test/src/Plugin/migrate/field/D6FileField.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace Drupal\migrate_field_plugin_manager_test\Plugin\migrate\field;
+
+use Drupal\migrate_drupal\Plugin\migrate\field\FieldPluginBase;
+use Drupal\migrate\Plugin\MigrationInterface;
+
+/**
+ * @MigrateField(
+ *   id = "d6_file",
+ *   core = {6},
+ *   type_map = {
+ *     "file" = "file"
+ *   }
+ * )
+ */
+class D6FileField extends FieldPluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFieldFormatterMap() {
+    return [];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function processFieldValues(MigrationInterface $migration, $field_name, $data) {}
+
+}
diff --git a/core/modules/migrate_drupal/tests/modules/migrate_field_plugin_manager_test/src/Plugin/migrate/field/D6NoCoreVersionSpecified.php b/core/modules/migrate_drupal/tests/modules/migrate_field_plugin_manager_test/src/Plugin/migrate/field/D6NoCoreVersionSpecified.php
new file mode 100644
index 0000000..224388b
--- /dev/null
+++ b/core/modules/migrate_drupal/tests/modules/migrate_field_plugin_manager_test/src/Plugin/migrate/field/D6NoCoreVersionSpecified.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace Drupal\migrate_field_plugin_manager_test\Plugin\migrate\field;
+
+use Drupal\migrate_drupal\Plugin\migrate\field\FieldPluginBase;
+use Drupal\migrate\Plugin\MigrationInterface;
+
+/**
+ * @MigrateField(
+ *   id = "d6_no_core_version_specified"
+ * )
+ */
+class D6NoCoreVersionSpecified extends FieldPluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFieldFormatterMap() {
+    return [];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function processFieldValues(MigrationInterface $migration, $field_name, $data) {}
+
+}
diff --git a/core/modules/migrate_drupal/tests/src/Kernel/CckFieldBackwardsCompatibilityTest.php b/core/modules/migrate_drupal/tests/src/Kernel/CckFieldBackwardsCompatibilityTest.php
new file mode 100644
index 0000000..11dceec
--- /dev/null
+++ b/core/modules/migrate_drupal/tests/src/Kernel/CckFieldBackwardsCompatibilityTest.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace Drupal\Tests\migrate_drupal\Kernel;
+
+use Drupal\migrate_field_plugin_manager_test\Plugin\migrate\cckfield\d6\FileField;
+use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
+
+/**
+ * @group migrate_drupal
+ */
+class CckFieldBackwardsCompatibilityTest extends MigrateDrupal6TestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['file', 'migrate_field_plugin_manager_test'];
+
+  /**
+   * Ensures that the cckfield backwards compatibility layer is invoked.
+   */
+  public function testBackwardsCompatibility() {
+    $migration = $this->container
+      ->get('plugin.manager.migration')
+      ->getDefinition('d6_node:story');
+
+    $this->assertSame(FileField::class, $migration['process']['field_test_filefield']['class']);
+  }
+
+}
diff --git a/core/modules/migrate_drupal/tests/src/Kernel/MigrateFieldPluginManagerTest.php b/core/modules/migrate_drupal/tests/src/Kernel/MigrateFieldPluginManagerTest.php
new file mode 100644
index 0000000..7c3c5a4
--- /dev/null
+++ b/core/modules/migrate_drupal/tests/src/Kernel/MigrateFieldPluginManagerTest.php
@@ -0,0 +1,51 @@
+<?php
+
+namespace Drupal\Tests\migrate_drupal\Kernel;
+
+use Drupal\Component\Plugin\Exception\PluginNotFoundException;
+
+/**
+ * Tests the field plugin manager.
+ *
+ * @group migrate_drupal
+ */
+class MigrateFieldPluginManagerTest extends MigrateDrupalTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['system', 'user', 'field', 'migrate_drupal', 'options', 'file', 'text', 'migrate_field_plugin_manager_test'];
+
+  /**
+   * Tests that the correct MigrateField plugins are used.
+   */
+  public function testPluginSelection() {
+    $plugin_manager = $this->container->get('plugin.manager.migrate.field');
+
+    try {
+      // If this test passes, getPluginIdFromFieldType will raise a
+      // PluginNotFoundException and we'll never reach fail().
+      $plugin_manager->getPluginIdFromFieldType('filefield', ['core' => 7]);
+      $this->fail('Expected Drupal\Component\Plugin\Exception\PluginNotFoundException.');
+    }
+    catch (PluginNotFoundException $e) {
+      $this->assertIdentical($e->getMessage(), "Plugin ID 'filefield' was not found.");
+    }
+
+    $this->assertIdentical('d6_file', $plugin_manager->getPluginIdFromFieldType('file', ['core' => 6]));
+
+    // Test fallback when no core version is specified.
+    $this->assertIdentical('d6_no_core_version_specified', $plugin_manager->getPluginIdFromFieldType('d6_no_core_version_specified', ['core' => 6]));
+
+    try {
+      // If this test passes, getPluginIdFromFieldType will raise a
+      // PluginNotFoundException and we'll never reach fail().
+      $plugin_manager->getPluginIdFromFieldType('d6_no_core_version_specified', ['core' => 7]);
+      $this->fail('Expected Drupal\Component\Plugin\Exception\PluginNotFoundException.');
+    }
+    catch (PluginNotFoundException $e) {
+      $this->assertIdentical($e->getMessage(), "Plugin ID 'd6_no_core_version_specified' was not found.");
+    }
+  }
+
+}
diff --git a/core/modules/node/src/Plugin/migrate/D6NodeDeriver.php b/core/modules/node/src/Plugin/migrate/D6NodeDeriver.php
index 6d9b67a..536303e 100644
--- a/core/modules/node/src/Plugin/migrate/D6NodeDeriver.php
+++ b/core/modules/node/src/Plugin/migrate/D6NodeDeriver.php
@@ -9,6 +9,7 @@
 use Drupal\migrate\Exception\RequirementsException;
 use Drupal\migrate\Plugin\MigrationDeriverTrait;
 use Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManagerInterface;
+use Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -39,6 +40,20 @@ class D6NodeDeriver extends DeriverBase implements ContainerDeriverInterface {
   protected $cckPluginManager;
 
   /**
+   * Already-instantiated field plugins, keyed by ID.
+   *
+   * @var \Drupal\migrate_drupal\Plugin\MigrateFieldInterface[]
+   */
+  protected $fieldPluginCache;
+
+  /**
+   * The field plugin manager.
+   *
+   * @var \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface
+   */
+  protected $fieldPluginManager;
+
+  /**
    * Whether or not to include translations.
    *
    * @var bool
@@ -52,12 +67,15 @@ class D6NodeDeriver extends DeriverBase implements ContainerDeriverInterface {
    *   The base plugin ID for the plugin ID.
    * @param \Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManagerInterface $cck_manager
    *   The CCK plugin manager.
+   * @param \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface $field_manager
+   *   The field plugin manager.
    * @param bool $translations
    *   Whether or not to include translations.
    */
-  public function __construct($base_plugin_id, MigrateCckFieldPluginManagerInterface $cck_manager, $translations) {
+  public function __construct($base_plugin_id, MigrateCckFieldPluginManagerInterface $cck_manager, MigrateFieldPluginManagerInterface $field_manager, $translations) {
     $this->basePluginId = $base_plugin_id;
     $this->cckPluginManager = $cck_manager;
+    $this->fieldPluginManager = $field_manager;
     $this->includeTranslations = $translations;
   }
 
@@ -69,6 +87,7 @@ public static function create(ContainerInterface $container, $base_plugin_id) {
     return new static(
       $base_plugin_id,
       $container->get('plugin.manager.migrate.cckfield'),
+      $container->get('plugin.manager.migrate.field'),
       $container->get('module_handler')->moduleExists('content_translation')
     );
   }
@@ -100,7 +119,7 @@ public function getDerivativeDefinitions($base_plugin_definition) {
       return $this->derivatives;
     }
 
-    // Read all CCK field instance definitions in the source database.
+    // Read all field instance definitions in the source database.
     $fields = [];
     try {
       $source_plugin = static::getSourcePlugin('d6_field_instance');
@@ -112,7 +131,7 @@ public function getDerivativeDefinitions($base_plugin_definition) {
     }
     catch (RequirementsException $e) {
       // If checkRequirements() failed then the content module did not exist and
-      // we do not have any CCK fields. Therefore, $fields will be empty and
+      // we do not have any fields. Therefore, $fields will be empty and
       // below we'll create a migration just for the node properties.
     }
 
@@ -135,20 +154,31 @@ public function getDerivativeDefinitions($base_plugin_definition) {
           $values['migration_dependencies']['required'][] = 'd6_node:' . $node_type;
         }
 
+        /** @var \Drupal\migrate\Plugin\Migration $migration */
         $migration = \Drupal::service('plugin.manager.migration')->createStubMigration($values);
         if (isset($fields[$node_type])) {
           foreach ($fields[$node_type] as $field_name => $info) {
             $field_type = $info['type'];
             try {
-              $plugin_id = $this->cckPluginManager->getPluginIdFromFieldType($field_type, ['core' => 6], $migration);
-              if (!isset($this->cckPluginCache[$field_type])) {
-                $this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($plugin_id, ['core' => 6], $migration);
+              $plugin_id = $this->fieldPluginManager->getPluginIdFromFieldType($field_type, ['core' => 6], $migration);
+              if (!isset($this->fieldPluginCache[$field_type])) {
+                $this->fieldPluginCache[$field_type] = $this->fieldPluginManager->createInstance($plugin_id, ['core' => 6], $migration);
               }
-              $this->cckPluginCache[$field_type]
-                ->processCckFieldValues($migration, $field_name, $info);
+              $this->fieldPluginCache[$field_type]
+                ->processFieldValues($migration, $field_name, $info);
             }
             catch (PluginNotFoundException $ex) {
-              $migration->setProcessOfProperty($field_name, $field_name);
+              try {
+                $plugin_id = $this->cckPluginManager->getPluginIdFromFieldType($field_type, ['core' => 6], $migration);
+                if (!isset($this->cckPluginCache[$field_type])) {
+                  $this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($plugin_id, ['core' => 6], $migration);
+                }
+                $this->cckPluginCache[$field_type]
+                  ->processCckFieldValues($migration, $field_name, $info);
+              }
+              catch (PluginNotFoundException $ex) {
+                $migration->setProcessOfProperty($field_name, $field_name);
+              }
             }
           }
         }
diff --git a/core/modules/node/src/Plugin/migrate/D7NodeDeriver.php b/core/modules/node/src/Plugin/migrate/D7NodeDeriver.php
index a35c376..da01c70 100644
--- a/core/modules/node/src/Plugin/migrate/D7NodeDeriver.php
+++ b/core/modules/node/src/Plugin/migrate/D7NodeDeriver.php
@@ -9,6 +9,7 @@
 use Drupal\migrate\Exception\RequirementsException;
 use Drupal\migrate\Plugin\MigrationDeriverTrait;
 use Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManagerInterface;
+use Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -39,6 +40,20 @@ class D7NodeDeriver extends DeriverBase implements ContainerDeriverInterface {
   protected $cckPluginManager;
 
   /**
+   * Already-instantiated field plugins, keyed by ID.
+   *
+   * @var \Drupal\migrate_drupal\Plugin\MigrateFieldInterface[]
+   */
+  protected $fieldPluginCache;
+
+  /**
+   * The field plugin manager.
+   *
+   * @var \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface
+   */
+  protected $fieldPluginManager;
+
+  /**
    * Whether or not to include translations.
    *
    * @var bool
@@ -52,12 +67,15 @@ class D7NodeDeriver extends DeriverBase implements ContainerDeriverInterface {
    *   The base plugin ID for the plugin ID.
    * @param \Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManagerInterface $cck_manager
    *   The CCK plugin manager.
+   * @param \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface $field_manager
+   *   The field plugin manager.
    * @param bool $translations
    *   Whether or not to include translations.
    */
-  public function __construct($base_plugin_id, MigrateCckFieldPluginManagerInterface $cck_manager, $translations) {
+  public function __construct($base_plugin_id, MigrateCckFieldPluginManagerInterface $cck_manager, MigrateFieldPluginManagerInterface $field_manager, $translations) {
     $this->basePluginId = $base_plugin_id;
     $this->cckPluginManager = $cck_manager;
+    $this->fieldPluginManager = $field_manager;
     $this->includeTranslations = $translations;
   }
 
@@ -69,6 +87,7 @@ public static function create(ContainerInterface $container, $base_plugin_id) {
     return new static(
       $base_plugin_id,
       $container->get('plugin.manager.migrate.cckfield'),
+      $container->get('plugin.manager.migrate.field'),
       $container->get('module_handler')->moduleExists('content_translation')
     );
   }
@@ -134,15 +153,25 @@ public function getDerivativeDefinitions($base_plugin_definition) {
           foreach ($fields[$node_type] as $field_name => $info) {
             $field_type = $info['type'];
             try {
-              $plugin_id = $this->cckPluginManager->getPluginIdFromFieldType($field_type, ['core' => 7], $migration);
-              if (!isset($this->cckPluginCache[$field_type])) {
-                $this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($plugin_id, ['core' => 7], $migration);
+              $plugin_id = $this->fieldPluginManager->getPluginIdFromFieldType($field_type, ['core' => 7], $migration);
+              if (!isset($this->fieldPluginCache[$field_type])) {
+                $this->fieldPluginCache[$field_type] = $this->fieldPluginManager->createInstance($plugin_id, ['core' => 7], $migration);
               }
-              $this->cckPluginCache[$field_type]
-                ->processCckFieldValues($migration, $field_name, $info);
+              $this->fieldPluginCache[$field_type]
+                ->processFieldValues($migration, $field_name, $info);
             }
             catch (PluginNotFoundException $ex) {
-              $migration->setProcessOfProperty($field_name, $field_name);
+              try {
+                $plugin_id = $this->cckPluginManager->getPluginIdFromFieldType($field_type, ['core' => 7], $migration);
+                if (!isset($this->cckPluginCache[$field_type])) {
+                  $this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($plugin_id, ['core' => 7], $migration);
+                }
+                $this->cckPluginCache[$field_type]
+                  ->processCckFieldValues($migration, $field_name, $info);
+              }
+              catch (PluginNotFoundException $ex) {
+                $migration->setProcessOfProperty($field_name, $field_name);
+              }
             }
           }
         }
diff --git a/core/modules/taxonomy/src/Plugin/migrate/D7TaxonomyTermDeriver.php b/core/modules/taxonomy/src/Plugin/migrate/D7TaxonomyTermDeriver.php
index b66a5cf..561a9af 100644
--- a/core/modules/taxonomy/src/Plugin/migrate/D7TaxonomyTermDeriver.php
+++ b/core/modules/taxonomy/src/Plugin/migrate/D7TaxonomyTermDeriver.php
@@ -9,12 +9,14 @@
 use Drupal\migrate\Exception\RequirementsException;
 use Drupal\migrate\Plugin\MigrationDeriverTrait;
 use Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManagerInterface;
+use Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Deriver for Drupal 7 taxonomy term migrations based on vocabularies.
  */
 class D7TaxonomyTermDeriver extends DeriverBase implements ContainerDeriverInterface {
+
   use MigrationDeriverTrait;
 
   /**
@@ -39,16 +41,33 @@ class D7TaxonomyTermDeriver extends DeriverBase implements ContainerDeriverInter
   protected $cckPluginManager;
 
   /**
+   * Already-instantiated field plugins, keyed by ID.
+   *
+   * @var \Drupal\migrate_drupal\Plugin\MigrateFieldInterface[]
+   */
+  protected $fieldPluginCache;
+
+  /**
+   * The field plugin manager.
+   *
+   * @var \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface
+   */
+  protected $fieldPluginManager;
+
+  /**
    * D7TaxonomyTermDeriver constructor.
    *
    * @param string $base_plugin_id
    *   The base plugin ID for the plugin ID.
    * @param \Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManagerInterface $cck_manager
    *   The CCK plugin manager.
+   * @param \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface $field_manager
+   *   The field plugin manager.
    */
-  public function __construct($base_plugin_id, MigrateCckFieldPluginManagerInterface $cck_manager) {
+  public function __construct($base_plugin_id, MigrateCckFieldPluginManagerInterface $cck_manager, MigrateFieldPluginManagerInterface $field_manager) {
     $this->basePluginId = $base_plugin_id;
     $this->cckPluginManager = $cck_manager;
+    $this->fieldPluginManager = $field_manager;
   }
 
   /**
@@ -57,7 +76,8 @@ public function __construct($base_plugin_id, MigrateCckFieldPluginManagerInterfa
   public static function create(ContainerInterface $container, $base_plugin_id) {
     return new static(
       $base_plugin_id,
-      $container->get('plugin.manager.migrate.cckfield')
+      $container->get('plugin.manager.migrate.cckfield'),
+      $container->get('plugin.manager.migrate.field')
     );
   }
 
@@ -112,15 +132,25 @@ public function getDerivativeDefinitions($base_plugin_definition) {
           foreach ($fields[$bundle] as $field_name => $info) {
             $field_type = $info['type'];
             try {
-              $plugin_id = $this->cckPluginManager->getPluginIdFromFieldType($field_type, ['core' => 7], $migration);
-              if (!isset($this->cckPluginCache[$field_type])) {
-                $this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($plugin_id, ['core' => 7], $migration);
+              $plugin_id = $this->fieldPluginManager->getPluginIdFromFieldType($field_type, ['core' => 7], $migration);
+              if (!isset($this->fieldPluginCache[$field_type])) {
+                $this->fieldPluginCache[$field_type] = $this->fieldPluginManager->createInstance($plugin_id, ['core' => 7], $migration);
               }
-              $this->cckPluginCache[$field_type]
-                ->processCckFieldValues($migration, $field_name, $info);
+              $this->fieldPluginCache[$field_type]
+                ->processFieldValues($migration, $field_name, $info);
             }
             catch (PluginNotFoundException $ex) {
-              $migration->setProcessOfProperty($field_name, $field_name);
+              try {
+                $plugin_id = $this->cckPluginManager->getPluginIdFromFieldType($field_type, ['core' => 7], $migration);
+                if (!isset($this->cckPluginCache[$field_type])) {
+                  $this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($plugin_id, ['core' => 7], $migration);
+                }
+                $this->cckPluginCache[$field_type]
+                  ->processCckFieldValues($migration, $field_name, $info);
+              }
+              catch (PluginNotFoundException $ex) {
+                $migration->setProcessOfProperty($field_name, $field_name);
+              }
             }
           }
         }
diff --git a/core/modules/user/src/Plugin/migrate/User.php b/core/modules/user/src/Plugin/migrate/User.php
index d89787c..0605443 100644
--- a/core/modules/user/src/Plugin/migrate/User.php
+++ b/core/modules/user/src/Plugin/migrate/User.php
@@ -3,12 +3,12 @@
 namespace Drupal\user\Plugin\migrate;
 
 use Drupal\migrate\Exception\RequirementsException;
-use Drupal\migrate_drupal\Plugin\migrate\CckMigration;
+use Drupal\migrate_drupal\Plugin\migrate\FieldMigration;
 
 /**
  * Plugin class for Drupal 7 user migrations dealing with fields and profiles.
  */
-class User extends CckMigration {
+class User extends FieldMigration {
 
   /**
    * {@inheritdoc}
@@ -30,16 +30,26 @@ public function getProcess() {
           if (empty($field_type)) {
             continue;
           }
-          if ($this->cckPluginManager->hasDefinition($field_type)) {
-            if (!isset($this->cckPluginCache[$field_type])) {
-              $this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($field_type, [], $this);
+          if ($this->fieldPluginManager->hasDefinition($field_type)) {
+            if (!isset($this->fieldPluginCache[$field_type])) {
+              $this->fieldPluginCache[$field_type] = $this->fieldPluginManager->createInstance($field_type, [], $this);
             }
             $info = $row->getSource();
-            $this->cckPluginCache[$field_type]
-              ->processCckFieldValues($this, $field_name, $info);
+            $this->fieldPluginCache[$field_type]
+              ->processFieldValues($this, $field_name, $info);
           }
           else {
-            $this->process[$field_name] = $field_name;
+            if ($this->cckPluginManager->hasDefinition($field_type)) {
+              if (!isset($this->cckPluginCache[$field_type])) {
+                $this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($field_type, [], $this);
+              }
+              $info = $row->getSource();
+              $this->cckPluginCache[$field_type]
+                ->processCckFieldValues($this, $field_name, $info);
+            }
+            else {
+              $this->process[$field_name] = $field_name;
+            }
           }
         }
       }
