diff --git a/core/modules/comment/migrations/d6_comment.yml b/core/modules/comment/migrations/d6_comment.yml
index e6b4e1295f..7f8e727aa4 100644
--- a/core/modules/comment/migrations/d6_comment.yml
+++ b/core/modules/comment/migrations/d6_comment.yml
@@ -24,9 +24,12 @@ process:
     -
       plugin: migration_lookup
       migration:
+        - d6_node_complete
         - d6_node
         - d6_node_translation
       source: nid
+    -
+      plugin: node_complete_node_lookup
     -
       plugin: skip_on_empty
       method: row
diff --git a/core/modules/comment/migrations/d7_comment.yml b/core/modules/comment/migrations/d7_comment.yml
index eafa8e36ec..a27523f565 100644
--- a/core/modules/comment/migrations/d7_comment.yml
+++ b/core/modules/comment/migrations/d7_comment.yml
@@ -25,9 +25,12 @@ process:
     -
       plugin: migration_lookup
       migration:
+        - d7_node_complete
         - d7_node
         - d7_node_translation
       source: nid
+    -
+      plugin: node_complete_node_lookup
     -
       plugin: skip_on_empty
       method: row
diff --git a/core/modules/content_translation/migrations/d6_entity_reference_translation.yml b/core/modules/content_translation/migrations/d6_entity_reference_translation.yml
index 87150ec395..945b2fa9d2 100644
--- a/core/modules/content_translation/migrations/d6_entity_reference_translation.yml
+++ b/core/modules/content_translation/migrations/d6_entity_reference_translation.yml
@@ -14,6 +14,7 @@ provider:
 target_types:
   node:
     - d6_node_translation
+    - d6_node_complete
 # The source plugin will be set by the deriver.
 source:
   plugin: empty
diff --git a/core/modules/content_translation/migrations/d6_term_node_translation.yml b/core/modules/content_translation/migrations/d6_term_node_translation.yml
index 8ce46e5e5d..9894b75e38 100644
--- a/core/modules/content_translation/migrations/d6_term_node_translation.yml
+++ b/core/modules/content_translation/migrations/d6_term_node_translation.yml
@@ -11,8 +11,12 @@ process:
   dest_nid:
     -
       plugin: migration_lookup
-      migration: d6_node_translation
+      migration:
+        - d6_node_complete
+        - d6_node_translation
       source: nid
+    -
+      plugin: node_complete_node_translation_lookup
     -
       plugin: skip_on_empty
       method: row
diff --git a/core/modules/content_translation/migrations/d7_entity_reference_translation.yml b/core/modules/content_translation/migrations/d7_entity_reference_translation.yml
index 2e8d548f0a..0856caf488 100644
--- a/core/modules/content_translation/migrations/d7_entity_reference_translation.yml
+++ b/core/modules/content_translation/migrations/d7_entity_reference_translation.yml
@@ -14,6 +14,7 @@ provider:
 target_types:
   node:
     - d7_node_translation
+    - d7_node_complete
 # The source plugin will be set by the deriver.
 source:
   plugin: empty
diff --git a/core/modules/content_translation/migrations/node_translation_menu_links.yml b/core/modules/content_translation/migrations/node_translation_menu_links.yml
index 466ed39931..d6809f8fa6 100644
--- a/core/modules/content_translation/migrations/node_translation_menu_links.yml
+++ b/core/modules/content_translation/migrations/node_translation_menu_links.yml
@@ -61,6 +61,8 @@ process:
       # d7_node_translation mapping tables to find the new node ID.
       plugin: migration_lookup
       migration:
+        - d6_node_complete
+        - d7_node_complete
         - d6_node_translation
         - d7_node_translation
       no_stub: true
diff --git a/core/modules/content_translation/migrations/state/content_translation.migrate_drupal.yml b/core/modules/content_translation/migrations/state/content_translation.migrate_drupal.yml
index 85a9914073..4e21859fcb 100644
--- a/core/modules/content_translation/migrations/state/content_translation.migrate_drupal.yml
+++ b/core/modules/content_translation/migrations/state/content_translation.migrate_drupal.yml
@@ -9,6 +9,8 @@ finished:
       - menu_link_content
     locale: content_translation
     menu: content_translation
+  # Node revision translations.
+    node: content_translation
     statistics: statistics
     taxonomy: content_translation
   7:
@@ -20,7 +22,8 @@ finished:
     locale: content_translation
     menu: content_translation
     statistics: statistics
-
+    # Node revision translations.
+    node: content_translation
 not_finished:
   # Also D6 and D7 node revision translations.
   6:
@@ -29,9 +32,6 @@ not_finished:
     i18n: content_translation
     # Taxonomy term references.
     i18ntaxonomy: content_translation
-    # Node revision translations.
-    # https://www.drupal.org/project/drupal/issues/2746541
-    node: content_translation
   7:
     # @TODO: Move to finished when remaining Drupal 7 i18n issues are resolved.
     # See https://www.drupal.org/project/drupal/issues/2208401
@@ -42,6 +42,3 @@ not_finished:
     # @TODO: Remove when taxonomy term field translations are migrated.
     # See https://www.drupal.org/project/drupal/issues/3073050
     i18n_taxonomy: content_translation
-    # Node revision translations.
-    # https://www.drupal.org/project/drupal/issues/2746541
-    node: content_translation
diff --git a/core/modules/migrate/src/Audit/NodeCompleteIdAuditor.php b/core/modules/migrate/src/Audit/NodeCompleteIdAuditor.php
new file mode 100644
index 0000000000..a955564a78
--- /dev/null
+++ b/core/modules/migrate/src/Audit/NodeCompleteIdAuditor.php
@@ -0,0 +1,88 @@
+<?php
+
+namespace Drupal\migrate\Audit;
+
+use Drupal\migrate\Plugin\MigrationInterface;
+
+/**
+ * Audits the revision ID for the node complete migration.
+ */
+class NodeCompleteIdAuditor {
+
+  /**
+   * Audits complete node migrations.
+   *
+   * @param \Drupal\migrate\Plugin\MigrationInterface[] $migrations
+   *   The migrations to audit.
+   *
+   * @return \Drupal\migrate\Audit\AuditResult[]
+   *   The audit results, keyed by migration ID.
+   */
+  public function auditMultiple(array $migrations) {
+    $results = [];
+    // If dN_node_complete migration is being used, get the audit results for
+    // node revisions manually. We need to do this manually because the node
+    // complete map has the IDs for both nodes and revisions and
+    // Sql::getHighestId() only returns the highest migrated ID of the
+    // destination entity type, which for node_complete is node.
+    $migration_plugin_manager = \Drupal::service('plugin.manager.migration');
+    foreach ($migrations as $migration) {
+      $migration_id = $migration->getPluginId();
+      if (preg_match('/node_complete/', $migration_id) === 1) {
+        $max = static::getHighestMigratedNodeRevisionId($migration);
+
+        // Make a migration based on node_complete but with an entity_revision
+        // destination.
+        $revision_migration = $migration->getPluginDefinition();
+        $revision_migration['id'] = $migration->getPluginId() . '-revision';
+        $revision_migration['destination']['plugin'] = 'entity_revision:node';
+        $revision_migration = $migration_plugin_manager->createStubMigration($revision_migration);
+
+        // Get the highest node revision ID.
+        $destination = $revision_migration->getDestinationPlugin();
+        $highest = $destination->getHighestId();
+
+        if ($highest > $max) {
+          $results[$migration_id . '-revision'] = AuditResult::fail($revision_migration, [
+            t('The destination system contains data which was not created by a migration.'),
+          ]);
+        }
+        else {
+          $results[$migration_id . '-revision'] = AuditResult::pass($revision_migration);
+        }
+      }
+    }
+    return $results;
+  }
+
+  /**
+   * Gets highest migrated node revision ID.
+   *
+   * @param \Drupal\migrate\Plugin\MigrationInterface $migration
+   *   A node_complete migration.
+   *
+   * @return int
+   *   The highest migrated node revision ID.
+   *
+   * @throws \InvalidArgumentException
+   *   Thrown when the ID map table does not exist.
+   */
+  protected static function getHighestMigratedNodeRevisionId(MigrationInterface $migration) : int {
+    $map_table = $migration->getIdMap()->mapTableName();
+
+    $database = \Drupal::database();
+    if (!$database->schema()->tableExists($map_table)) {
+      throw new \InvalidArgumentException();
+    }
+
+    $query = $database->select($map_table, 'map')
+      ->fields('map', ['destid2'])
+      ->range(0, 1)
+      ->orderBy('destid2', 'DESC');
+    $ids[] = $query->execute()->fetchField();
+    $max = (int) (max($ids));
+
+    return $max;
+  }
+
+}
diff --git a/core/modules/migrate/src/Plugin/Derivative/MigrateEntityComplete.php b/core/modules/migrate/src/Plugin/Derivative/MigrateEntityComplete.php
new file mode 100644
index 0000000000..c276a3a7b3
--- /dev/null
+++ b/core/modules/migrate/src/Plugin/Derivative/MigrateEntityComplete.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace Drupal\migrate\Plugin\Derivative;
+
+use Drupal\migrate\Plugin\migrate\destination\EntityContentComplete;
+
+/**
+ * MigrateEntityComplete deriver.
+ */
+class MigrateEntityComplete extends MigrateEntity {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDerivativeDefinitions($base_plugin_definition) {
+    foreach ($this->entityDefinitions as $entity_type => $entity_info) {
+      $this->derivatives[$entity_type] = [
+        'id' => "entity_complete:$entity_type",
+        'class' => EntityContentComplete::class,
+        'requirements_met' => 1,
+        'provider' => $entity_info->getProvider(),
+      ];
+    }
+    return $this->derivatives;
+  }
+
+}
diff --git a/core/modules/migrate/src/Plugin/migrate/destination/EntityContentComplete.php b/core/modules/migrate/src/Plugin/migrate/destination/EntityContentComplete.php
new file mode 100644
index 0000000000..b4baf39ef0
--- /dev/null
+++ b/core/modules/migrate/src/Plugin/migrate/destination/EntityContentComplete.php
@@ -0,0 +1,118 @@
+<?php
+
+namespace Drupal\migrate\Plugin\migrate\destination;
+
+use Drupal\Core\Entity\ContentEntityInterface;
+use Drupal\Core\Entity\EntityChangedInterface;
+use Drupal\migrate\EntityFieldDefinitionTrait;
+use Drupal\migrate\Row;
+
+/**
+ * Provides a node destination for migrating the entire entity revision table.
+ *
+ * @MigrateDestination(
+ *   id = "entity_complete",
+ *   deriver = "Drupal\migrate\Plugin\Derivative\MigrateEntityComplete"
+ * )
+ */
+class EntityContentComplete extends EntityContentBase {
+
+  use EntityFieldDefinitionTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    $ids = [];
+    $id_key = $this->getKey('id');
+    $ids[$id_key] = $this->getDefinitionFromEntity($id_key);
+
+    $revision_key = $this->getKey('revision');
+    if ($revision_key) {
+      $ids[$revision_key] = $this->getDefinitionFromEntity($revision_key);
+    }
+
+    $langcode_key = $this->getKey('langcode');
+    if ($langcode_key) {
+      $ids[$langcode_key] = $this->getDefinitionFromEntity($langcode_key);
+    }
+
+    return $ids;
+  }
+
+  /**
+   * Gets the entity.
+   *
+   * @param \Drupal\migrate\Row $row
+   *   The row object.
+   * @param array $old_destination_id_values
+   *   The old destination IDs.
+   *
+   * @return \Drupal\Core\Entity\EntityInterface
+   *   The entity.
+   */
+  protected function getEntity(Row $row, array $old_destination_id_values) {
+    $revision_id = $old_destination_id_values
+      ? $old_destination_id_values[1]
+      : $row->getDestinationProperty($this->getKey('revision'));
+    // If we are re-running a migration with set revision IDs and the
+    // destination revision ID already exists then do not create a new revision.
+    if (!empty($revision_id) && ($entity = $this->storage->loadRevision($revision_id))) {
+      $entity->setNewRevision(FALSE);
+    }
+    elseif (($entity_id = $row->getDestinationProperty($this->getKey('id'))) && ($entity = $this->storage->load($entity_id))) {
+      // We want to create a new entity. Set enforceIsNew() FALSE is  necessary
+      // to properly save a new entity while setting the ID. Without it, the
+      // system would see that the ID is already set and assume it is an update.
+      $entity->enforceIsNew(FALSE);
+      // Intentionally create a new revision. Setting new revision TRUE here may
+      // not be necessary, it is done for clarity.
+      $entity->setNewRevision(TRUE);
+    }
+    else {
+      // Attempt to set the bundle.
+      if ($bundle = $this->getBundle($row)) {
+        $row->setDestinationProperty($this->getKey('bundle'), $bundle);
+      }
+
+      // Stubs might need some required fields filled in.
+      if ($row->isStub()) {
+        $this->processStubRow($row);
+      }
+      $entity = $this->storage->create($row->getDestination());
+      $entity->enforceIsNew();
+    }
+
+    // We need to update the entity, so that the destination row IDs are
+    // correct.
+    $entity = $this->updateEntity($entity, $row);
+    $entity->isDefaultRevision(TRUE);
+    if ($entity instanceof EntityChangedInterface && $entity instanceof ContentEntityInterface) {
+      // If we updated any untranslatable fields, update the timestamp for the
+      // other translations.
+      /** @var \Drupal\Core\Entity\ContentEntityInterface|\Drupal\Core\Entity\EntityChangedInterface $entity */
+      foreach ($entity->getTranslationLanguages() as $langcode => $language) {
+        // If we updated an untranslated field, then set the changed time for
+        // for all translations to match the current row that we are saving.
+        // In this context, getChangedTime() should return the value we just
+        // set in the updateEntity() call above.
+        if ($entity->getTranslation($langcode)->hasTranslationChanges()) {
+          $entity->getTranslation($langcode)->setChangedTime($entity->getChangedTime());
+        }
+      }
+    }
+    return $entity;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function save(ContentEntityInterface $entity, array $old_destination_id_values = []) {
+    parent::save($entity, $old_destination_id_values);
+    return [
+      $entity->id(),
+      $entity->getRevisionId(),
+    ];
+  }
+
+}
diff --git a/core/modules/migrate_drupal/migrate_drupal.install b/core/modules/migrate_drupal/migrate_drupal.install
index 820bcdc870..d5e6fdefc1 100644
--- a/core/modules/migrate_drupal/migrate_drupal.install
+++ b/core/modules/migrate_drupal/migrate_drupal.install
@@ -5,6 +5,8 @@
  * Contains install and update functions for Migrate Drupal
  */
 
+use Drupal\Core\Database\Database;
+
 /**
  * Creates migrate_drupal.settings config object.
  */
@@ -31,3 +33,56 @@ function migrate_drupal_update_8502() {
 function migrate_drupal_update_8601() {
   \Drupal::service('module_installer')->install(['migrate_drupal_multilingual']);
 }
+
+/**
+ * Add revision ID to entity reference translation migrate_map tables..
+ */
+function migrate_drupal_update_8901(&$sandbox) {
+  $schema = Database::getConnection()->schema();
+  $table_expression = 'migrate_map%entity_reference_translation%node%';
+  $tables = $schema->findTables($table_expression);
+  foreach ($tables as $table) {
+    // Move language code to sourceid3.
+    $spec = [
+      'type' => 'varchar',
+      'length' => 12,
+      'not null' => TRUE,
+    ];
+    $schema->changeField($table, 'sourceid2', 'sourceid3', $spec);
+
+    // Add revision ID.
+    $spec = [
+      'type' => 'int',
+      'unsigned' => TRUE,
+      'not null' => TRUE,
+      'default' => 0,
+    ];
+    $schema->addField($table, 'sourceid2', $spec);
+
+    // Add sourceid2 to index.
+    $spec = [
+      'fields' => [
+        'sourceid1' => [
+          'type' => 'int',
+          'not_null' => TRUE,
+        ],
+        'sourceid2' => [
+          'type' => 'int',
+          'not_null' => TRUE,
+        ],
+        'sourceid3' => [
+          'type' => 'varchar',
+          'length' => 12,
+          'not null' => TRUE,
+        ],
+      ],
+    ];
+    $fields = [
+      'sourceid1',
+      'sourceid2',
+      'sourceid3',
+    ];
+    $schema->dropIndex($table, 'source');
+    $schema->addIndex($table, 'source', $fields, $spec);
+  }
+}
diff --git a/core/modules/migrate_drupal/migrate_drupal.module b/core/modules/migrate_drupal/migrate_drupal.module
index 3f9439dd3b..f9bb4e7ac8 100644
--- a/core/modules/migrate_drupal/migrate_drupal.module
+++ b/core/modules/migrate_drupal/migrate_drupal.module
@@ -46,7 +46,8 @@ function migrate_drupal_migration_plugins_alter(&$definitions) {
       ],
     ];
     $vocabulary_migration = \Drupal::service('plugin.manager.migration')->createStubMigration($vocabulary_migration_definition);
-    $translation_active = \Drupal::service('module_handler')->moduleExists('content_translation');
+    $module_handler = \Drupal::service('module_handler');
+    $translation_active = $module_handler->moduleExists('content_translation');
 
     try {
       $source_plugin = $vocabulary_migration->getSourcePlugin();
@@ -89,6 +90,5 @@ function migrate_drupal_migration_plugins_alter(&$definitions) {
       // When the definitions are loaded it is possible the tables will not
       // exist.
     }
-
   }
 }
diff --git a/core/modules/migrate_drupal/src/MigrationConfigurationTrait.php b/core/modules/migrate_drupal/src/MigrationConfigurationTrait.php
index 8cb60347bc..52937b9a70 100644
--- a/core/modules/migrate_drupal/src/MigrationConfigurationTrait.php
+++ b/core/modules/migrate_drupal/src/MigrationConfigurationTrait.php
@@ -121,8 +121,29 @@ protected function createDatabaseStateSettings(array $database, $drupal_version)
    */
   protected function getMigrations($database_state_key, $drupal_version) {
     $version_tag = 'Drupal ' . $drupal_version;
-    /** @var \Drupal\migrate\Plugin\Migration[] $all_migrations */
+    /** @var \Drupal\migrate\Plugin\MigrationInterface[] $all_migrations */
     $all_migrations = $this->getMigrationPluginManager()->createInstancesByTag($version_tag);
+
+    // Unset the node migrations that should not run based on the type of node
+    // migration. That is, if this is a complete node migration then unset the
+    // classic node migrations and if this is a classic node migration then
+    // unset the complete node migrations.
+    $type = (new NodeMigrateType)->getNodeMigrateType([], $drupal_version);
+    switch ($type) {
+      case NodeMigrateType::NODE_MIGRATE_TYPE_COMPLETE:
+        $patterns = '/(d' . $drupal_version . '_node:)|(d' . $drupal_version . '_node_translation:)|(d' . $drupal_version . '_node_revision:)|(d7_node_entity_translation:)/';
+        break;
+
+      case NodeMigrateType::NODE_MIGRATE_TYPE_CLASSIC:
+        $patterns = '/(d' . $drupal_version . '_node_complete:)/';
+        break;
+    }
+    foreach ($all_migrations as $key => $migrations) {
+      if (preg_match($patterns, $key)) {
+        unset($all_migrations[$key]);
+      }
+    }
+
     $migrations = [];
     foreach ($all_migrations as $migration) {
       // Skip migrations tagged with any of the follow-up migration tags. They
diff --git a/core/modules/migrate_drupal/src/NodeMigrateType.php b/core/modules/migrate_drupal/src/NodeMigrateType.php
new file mode 100644
index 0000000000..ce335fd23e
--- /dev/null
+++ b/core/modules/migrate_drupal/src/NodeMigrateType.php
@@ -0,0 +1,125 @@
+<?php
+
+namespace Drupal\migrate_drupal;
+
+/**
+ * Provides a class to determine the type of migration.
+ */
+final class NodeMigrateType {
+
+  use MigrationConfigurationTrait;
+
+  /**
+   * Only the complete node migration map tables are in use.
+   */
+  const NODE_MIGRATE_TYPE_COMPLETE = 'COMPLETE';
+
+  /**
+   * Only the classic node migration map tables are in use.
+   */
+  const NODE_MIGRATE_TYPE_CLASSIC = 'CLASSIC';
+
+  /**
+   * Determines the type of node migration to be used.
+   *
+   * The node complete migration is the default. It is not used when there
+   * are existing tables for dN_node.
+   *
+   * @param array[] $definitions
+   *   An associative array of migrations. The array is normally keyed by
+   *   migration ID. However, the followup migrations are keyed by
+   *   'entity_type__bundle'. Each value is the migration array, obtained by
+   *   decoding the migration YAML file and enriched with some meta information
+   *   added during discovery phase, like migration 'class', 'provider' or
+   *   '_discovered_file_path'.
+   * @param string $version
+   *   The Drupal version of the source database.
+   *
+   * @return string
+   *   Indicator of the node migration map tables in use.
+   *
+   * @internal
+   *   Only to be used by migrate_drupal_migration_plugins_alter().
+   */
+  public function getNodeMigrateType(array $definitions, $version = NULL) {
+    if (!$version) {
+      // We need to get the version of the source database in order to check
+      // if the classic or complete node tables have been used in a migration.
+      if (isset($definitions['system_site'])) {
+        // Use the source plugin of the system_site migration to get the
+        // database connection.
+        $migration = $definitions['system_site'];
+        /** @var \Drupal\migrate\Plugin\migrate\source\SqlBase $source_plugin */
+        $source_plugin = \Drupal::service('plugin.manager.migration')
+          ->createStubMigration($migration)
+          ->getSourcePlugin();
+        $connection = NULL;
+
+        try {
+          $connection = $source_plugin->getDatabase();
+        }
+        catch (\Exception $e) {
+          // @todo: do something useful.
+        }
+        $version = FALSE;
+
+        if ($connection) {
+          $version = $this->getLegacyDrupalVersion($connection);
+        }
+      }
+    }
+    return $this->migrateType($version);
+  }
+
+  /**
+   * Helper to determine what node migrate map tables have data.
+   *
+   * @param string $version
+   *   The Drupal version of the source database.
+   *
+   * @return string
+   *   The migrate type.
+   */
+  protected function migrateType($version) {
+    $migrate_type = static::NODE_MIGRATE_TYPE_COMPLETE;
+    if ($version) {
+      // Create the variable name, 'node_has_rows' or 'node_complete_exists' and
+      // set it the default value, FALSE.
+      $node_has_rows = FALSE;
+      $node_complete_has_rows = FALSE;
+      $connection = \Drupal::database();
+
+      // Find out what migrate map tables have rows for the node migrations.
+      // It is either the classic, 'dN_node', or the complete,
+      // 'dN_node_complete', or both. This is used to determine which migrations
+      // are run and if migrations using the node migrations in a
+      // migration_lookup are altered.
+      $bases = ['node', 'node_complete'];
+      $tables = $connection->schema()
+        ->findTables('migrate_map_d' . $version . '_node%');
+      foreach ($bases as $base) {
+        $has_rows = $base . '_has_rows';
+        $base_tables = preg_grep('/^migrate_map_d' . $version . '_' . $base . '_{2}.*$/', $tables);
+        // Set the has_rows True when a map table has rows with a positive
+        // count for the matched migration.
+        foreach ($base_tables as $base_table) {
+          if ($connection->schema()->tableExists($base_table)) {
+            $count = $connection->select($base_table)->countQuery()
+              ->execute()->fetchField();
+            if ($count > 0) {
+              $$has_rows = TRUE;
+              break;
+            }
+          }
+        }
+      }
+
+      // Set the node migration type to use.
+      if ($node_has_rows && !$node_complete_has_rows) {
+        $migrate_type = static::NODE_MIGRATE_TYPE_CLASSIC;
+      }
+    }
+    return $migrate_type;
+  }
+
+}
diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/process/NodeCompleteNodeLookup.php b/core/modules/migrate_drupal/src/Plugin/migrate/process/NodeCompleteNodeLookup.php
new file mode 100644
index 0000000000..bd5e5d069d
--- /dev/null
+++ b/core/modules/migrate_drupal/src/Plugin/migrate/process/NodeCompleteNodeLookup.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace Drupal\migrate_drupal\Plugin\migrate\process;
+
+use Drupal\migrate\MigrateExecutableInterface;
+use Drupal\migrate\ProcessPluginBase;
+use Drupal\migrate\Row;
+
+/**
+ * Returns only the nid from migration_lookup on node_complete migration.
+ *
+ * It is possible that migration_lookups that use the classic node migrations
+ * in the migration key have been altered to include the complete node
+ * migration. The classic node migration and complete node migration have a
+ * different number of destination keys. This process plugin will ensure that
+ * when the complete node migration is used in the lookup the nid value is
+ * returned. This keeps the behaviour the same as the classic node migration.
+ *
+ * @see \Drupal\migrate\Plugin\MigrateProcessInterface
+ *
+ * @MigrateProcessPlugin(
+ *   id = "node_complete_node_lookup"
+ * )
+ */
+class NodeCompleteNodeLookup extends ProcessPluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
+    if (is_array($value) && count($value) === 3) {
+      return $value[0];
+    }
+    return $value;
+  }
+
+}
diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/process/NodeCompleteNodeRevisionLookup.php b/core/modules/migrate_drupal/src/Plugin/migrate/process/NodeCompleteNodeRevisionLookup.php
new file mode 100644
index 0000000000..7416e6561a
--- /dev/null
+++ b/core/modules/migrate_drupal/src/Plugin/migrate/process/NodeCompleteNodeRevisionLookup.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace Drupal\migrate_drupal\Plugin\migrate\process;
+
+use Drupal\migrate\MigrateExecutableInterface;
+use Drupal\migrate\ProcessPluginBase;
+use Drupal\migrate\Row;
+
+/**
+ * Returns only the vid from migration_lookup on node_complete migration.
+ *
+ * It is possible that migration_lookups that use the classic node migrations
+ * in the migration key have been altered to include the complete node
+ * migration. The classic node migration and complete node migration have a
+ * different number of destination keys. This process plugin will ensure that
+ * when the complete node migration is used in the lookup the vid value is
+ * returned. This keeps the behaviour the same as the classic node migration.
+ *
+ * @see \Drupal\migrate\Plugin\MigrateProcessInterface
+ *
+ * @MigrateProcessPlugin(
+ *   id = "node_complete_node_revision_lookup"
+ * )
+ */
+class NodeCompleteNodeRevisionLookup extends ProcessPluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
+    if (is_array($value) && count($value) === 3) {
+      return $value[1];
+    }
+    return $value;
+  }
+
+}
diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/process/NodeCompleteNodeTranslationLookup.php b/core/modules/migrate_drupal/src/Plugin/migrate/process/NodeCompleteNodeTranslationLookup.php
new file mode 100644
index 0000000000..671d9fe708
--- /dev/null
+++ b/core/modules/migrate_drupal/src/Plugin/migrate/process/NodeCompleteNodeTranslationLookup.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace Drupal\migrate_drupal\Plugin\migrate\process;
+
+use Drupal\migrate\MigrateExecutableInterface;
+use Drupal\migrate\ProcessPluginBase;
+use Drupal\migrate\Row;
+
+/**
+ * Returns nid and langcode from migration_lookup on node_complete migration.
+ *
+ * It is possible that migration_lookups that use the classic node migrations
+ * in the migration key have been altered to include the complete node
+ * migration. The classic node migration and complete node migration have a
+ * different number of destination keys. This process plugin will ensure that
+ * when the complete node migration is used in the lookup the nid and langcode
+ * values are returned. This keeps the behaviour the same as the classic node
+ * migration.
+ *
+ * @see \Drupal\migrate\Plugin\MigrateProcessInterface
+ *
+ * @MigrateProcessPlugin(
+ *   id = "node_complete_node_translation_lookup"
+ * )
+ */
+class NodeCompleteNodeTranslationLookup extends ProcessPluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
+    if (is_array($value) && count($value) === 3) {
+      unset($value[1]);
+      return array_values($value);
+    }
+    return $value;
+  }
+
+}
diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/ContentEntity.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/ContentEntity.php
index e80de1b7f8..a2f38d180c 100644
--- a/core/modules/migrate_drupal/src/Plugin/migrate/source/ContentEntity.php
+++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/ContentEntity.php
@@ -265,6 +265,10 @@ public function fields() {
   public function getIds() {
     $id_key = $this->entityType->getKey('id');
     $ids[$id_key] = $this->getDefinitionFromEntity($id_key);
+    if ($this->entityType->isRevisionable()) {
+      $revision_key = $this->entityType->getKey('revision');
+      $ids[$revision_key] = $this->getDefinitionFromEntity($revision_key);
+    }
     if ($this->entityType->isTranslatable()) {
       $langcode_key = $this->entityType->getKey('langcode');
       $ids[$langcode_key] = $this->getDefinitionFromEntity($langcode_key);
diff --git a/core/modules/migrate_drupal/tests/fixtures/drupal6.php b/core/modules/migrate_drupal/tests/fixtures/drupal6.php
index ca641233d9..a6e4ab7610 100644
--- a/core/modules/migrate_drupal/tests/fixtures/drupal6.php
+++ b/core/modules/migrate_drupal/tests/fixtures/drupal6.php
@@ -44473,10 +44473,10 @@
   'vid' => '1',
   'type' => 'story',
   'language' => '',
-  'title' => 'Test title',
+  'title' => 'Test title rev 3',
   'uid' => '1',
   'status' => '1',
-  'created' => '1388271197',
+  'created' => '1390095702',
   'changed' => '1420861423',
   'comment' => '0',
   'promote' => '0',
@@ -44507,7 +44507,7 @@
   'vid' => '4',
   'type' => 'test_planet',
   'language' => '',
-  'title' => 'Test planet title 3',
+  'title' => 'Test page title rev 4',
   'uid' => '1',
   'status' => '1',
   'created' => '1388271527',
@@ -44524,7 +44524,7 @@
   'vid' => '6',
   'type' => 'test_planet',
   'language' => '',
-  'title' => '',
+  'title' => 'Node 4',
   'uid' => '1',
   'status' => '1',
   'created' => '1388271527',
@@ -44541,7 +44541,7 @@
   'vid' => '7',
   'type' => 'test_planet',
   'language' => '',
-  'title' => '',
+  'title' => 'Node 5',
   'uid' => '1',
   'status' => '1',
   'created' => '1388271527',
@@ -44558,7 +44558,7 @@
   'vid' => '8',
   'type' => 'test_planet',
   'language' => '',
-  'title' => '',
+  'title' => 'Node 6',
   'uid' => '1',
   'status' => '1',
   'created' => '1388271527',
@@ -44575,7 +44575,7 @@
   'vid' => '9',
   'type' => 'test_planet',
   'language' => '',
-  'title' => '',
+  'title' => 'Node 7',
   'uid' => '1',
   'status' => '1',
   'created' => '1388271527',
@@ -44592,7 +44592,7 @@
   'vid' => '10',
   'type' => 'test_planet',
   'language' => '',
-  'title' => '',
+  'title' => 'Node 8',
   'uid' => '1',
   'status' => '1',
   'created' => '1388271527',
@@ -45288,7 +45288,7 @@
   'body' => 'test',
   'teaser' => 'test',
   'log' => '',
-  'timestamp' => '1420861423',
+  'timestamp' => '1390095702',
   'format' => '1',
 ))
 ->values(array(
@@ -45317,10 +45317,10 @@
   'nid' => '1',
   'vid' => '5',
   'uid' => '1',
-  'title' => 'Test title rev 3',
-  'body' => 'body test rev 3',
-  'teaser' => 'teaser test rev 3',
-  'log' => 'modified rev 3',
+  'title' => 'Test title rev 2',
+  'body' => 'body test rev 2',
+  'teaser' => 'teaser test rev 2',
+  'log' => 'modified rev 2',
   'timestamp' => '1390095703',
   'format' => '1',
 ))
@@ -45526,11 +45526,11 @@
   'nid' => '1',
   'vid' => '2001',
   'uid' => '2',
-  'title' => 'Test title rev 2',
-  'body' => 'body test rev 2',
-  'teaser' => 'teaser test rev 2',
-  'log' => 'modified rev 2',
-  'timestamp' => '1390095702',
+  'title' => 'Test title rev 3',
+  'body' => 'body test rev 3',
+  'teaser' => 'teaser test rev 3',
+  'log' => 'modified rev 3',
+  'timestamp' => '1420861423',
   'format' => '1',
 ))
 ->values(array(
@@ -49670,29 +49670,29 @@
   'value' => 'i:0;',
 ))
 ->values(array(
-  'name' => 'i18n_newnode_current_employee',
+  'name' => 'i18n_lock_node_sponsor',
   'value' => 'i:0;',
 ))
 ->values(array(
-  'name' => 'i18n_node_employee',
-  'value' => 's:1:"1";',
-))
-->values(array(
-  'name' => 'i18n_required_node_employee',
+  'name' => 'i18n_newnode_current_employee',
   'value' => 'i:0;',
 ))
 ->values(array(
-  'name' => 'i18n_lock_node_sponsor',
+  'name' => 'i18n_newnode_current_sponsor',
   'value' => 'i:0;',
 ))
 ->values(array(
-  'name' => 'i18n_newnode_current_sponsor',
-  'value' => 'i:0;',
+  'name' => 'i18n_node_employee',
+  'value' => 's:1:"1";',
 ))
 ->values(array(
   'name' => 'i18n_node_sponsor',
   'value' => 'i:1;',
 ))
+->values(array(
+  'name' => 'i18n_required_node_employee',
+  'value' => 'i:0;',
+))
 ->values(array(
   'name' => 'i18n_required_node_sponsor',
   'value' => 'i:0;',
diff --git a/core/modules/migrate_drupal/tests/fixtures/drupal7.php b/core/modules/migrate_drupal/tests/fixtures/drupal7.php
index f8280495c7..281f584589 100644
--- a/core/modules/migrate_drupal/tests/fixtures/drupal7.php
+++ b/core/modules/migrate_drupal/tests/fixtures/drupal7.php
@@ -3414,6 +3414,42 @@
   'created' => '1531922278',
   'changed' => '1531922279',
 ))
+->values(array(
+  'entity_type' => 'node',
+  'entity_id' => '11',
+  'revision_id' => '18',
+  'language' => 'en',
+  'source' => '',
+  'uid' => '1',
+  'status' => '1',
+  'translate' => '0',
+  'created' => '1568261523',
+  'changed' => '1568261687',
+))
+->values(array(
+  'entity_type' => 'node',
+  'entity_id' => '11',
+  'revision_id' => '18',
+  'language' => 'fr',
+  'source' => 'en',
+  'uid' => '1',
+  'status' => '1',
+  'translate' => '0',
+  'created' => '1568261721',
+  'changed' => '1568261721',
+))
+->values(array(
+  'entity_type' => 'node',
+  'entity_id' => '11',
+  'revision_id' => '18',
+  'language' => 'is',
+  'source' => 'en',
+  'uid' => '1',
+  'status' => '1',
+  'translate' => '0',
+  'created' => '1568261548',
+  'changed' => '1568261548',
+))
 ->execute();
 $connection->schema()->createTable('entity_translation_revision', array(
   'fields' => array(
@@ -3491,6 +3527,128 @@
   'mysql_character_set' => 'utf8',
 ));
 
+$connection->insert('entity_translation_revision')
+->fields(array(
+  'entity_type',
+  'entity_id',
+  'revision_id',
+  'language',
+  'source',
+  'uid',
+  'status',
+  'translate',
+  'created',
+  'changed',
+))
+->values(array(
+  'entity_type' => 'node',
+  'entity_id' => '1',
+  'revision_id' => '1',
+  'language' => 'en',
+  'source' => '',
+  'uid' => '1',
+  'status' => '1',
+  'translate' => '0',
+  'created' => '1529615790',
+  'changed' => '1529615790',
+))
+->values(array(
+  'entity_type' => 'node',
+  'entity_id' => '11',
+  'revision_id' => '15',
+  'language' => 'en',
+  'source' => '',
+  'uid' => '1',
+  'status' => '1',
+  'translate' => '0',
+  'created' => '1568261523',
+  'changed' => '1568261523',
+))
+->values(array(
+  'entity_type' => 'node',
+  'entity_id' => '11',
+  'revision_id' => '16',
+  'language' => 'en',
+  'source' => '',
+  'uid' => '1',
+  'status' => '1',
+  'translate' => '0',
+  'created' => '1568261523',
+  'changed' => '1568261523',
+))
+->values(array(
+  'entity_type' => 'node',
+  'entity_id' => '11',
+  'revision_id' => '17',
+  'language' => 'en',
+  'source' => '',
+  'uid' => '1',
+  'status' => '1',
+  'translate' => '0',
+  'created' => '1568261523',
+  'changed' => '1568261687',
+))
+->values(array(
+  'entity_type' => 'node',
+  'entity_id' => '11',
+  'revision_id' => '18',
+  'language' => 'en',
+  'source' => '',
+  'uid' => '1',
+  'status' => '1',
+  'translate' => '0',
+  'created' => '1568261523',
+  'changed' => '1568261687',
+))
+->values(array(
+  'entity_type' => 'node',
+  'entity_id' => '11',
+  'revision_id' => '18',
+  'language' => 'fr',
+  'source' => 'en',
+  'uid' => '1',
+  'status' => '1',
+  'translate' => '0',
+  'created' => '1568261721',
+  'changed' => '1568261721',
+))
+->values(array(
+  'entity_type' => 'node',
+  'entity_id' => '11',
+  'revision_id' => '16',
+  'language' => 'is',
+  'source' => 'en',
+  'uid' => '1',
+  'status' => '1',
+  'translate' => '0',
+  'created' => '1568261548',
+  'changed' => '1568261548',
+))
+->values(array(
+  'entity_type' => 'node',
+  'entity_id' => '11',
+  'revision_id' => '17',
+  'language' => 'is',
+  'source' => 'en',
+  'uid' => '1',
+  'status' => '1',
+  'translate' => '0',
+  'created' => '1568261548',
+  'changed' => '1568261548',
+))
+->values(array(
+  'entity_type' => 'node',
+  'entity_id' => '11',
+  'revision_id' => '18',
+  'language' => 'is',
+  'source' => 'en',
+  'uid' => '1',
+  'status' => '1',
+  'translate' => '0',
+  'created' => '1568261548',
+  'changed' => '1568261548',
+))
+->execute();
 $connection->schema()->createTable('field_config', array(
   'fields' => array(
     'id' => array(
@@ -4339,6 +4497,21 @@
   'translatable' => '0',
   'deleted' => '0',
 ))
+->values(array(
+  'id' => '53',
+  'field_name' => 'field_tree',
+  'type' => 'text',
+  'module' => 'text',
+  'active' => '1',
+  'storage_type' => 'field_sql_storage',
+  'storage_module' => 'field_sql_storage',
+  'storage_active' => '1',
+  'locked' => '0',
+  'data' => 'a:7:{s:12:"translatable";i:1;s:12:"entity_types";a:0:{}s:8:"settings";a:2:{s:10:"max_length";s:3:"255";s:23:"entity_translation_sync";b:0;}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_tree";a:2:{s:5:"value";s:16:"field_tree_value";s:6:"format";s:17:"field_tree_format";}}s:19:"FIELD_LOAD_REVISION";a:1:{s:25:"field_revision_field_tree";a:2:{s:5:"value";s:16:"field_tree_value";s:6:"format";s:17:"field_tree_format";}}}}}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";}}s:2:"id";s:1:"5";}',
+  'cardinality' => '1',
+  'translatable' => '1',
+  'deleted' => '0',
+))
 ->execute();
 $connection->schema()->createTable('field_config_instance', array(
   'fields' => array(
@@ -5100,6 +5273,15 @@
   'data' => 'a:7:{s:5:"label";s:10:"Chancellor";s:6:"widget";a:5:{s:6:"weight";s:1:"1";s:4:"type";s:14:"text_textfield";s:6:"module";s:4:"text";s:6:"active";i:1;s:8:"settings";a:1:{s:4:"size";s:2:"60";}}s:8:"settings";a:2:{s:15:"text_processing";s:1:"0";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:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:0;}}s:8:"required";i:0;s:11:"description";s:0:"";s:13:"default_value";N;}',
   'deleted' => '0',
 ))
+->values(array(
+  'id' => '82',
+  'field_id' => '53',
+  'field_name' => 'field_tree',
+  'entity_type' => 'node',
+  'bundle' => 'et',
+  'data' => 'a:7:{s:5:"label";s:4:"tree";s:6:"widget";a:5:{s:6:"weight";s:2:"-3";s:4:"type";s:14:"text_textfield";s:6:"module";s:4:"text";s:6:"active";i:1;s:8:"settings";a:1:{s:4:"size";s:2:"60";}}s:8:"settings";a:3:{s:15:"text_processing";s:1:"0";s:18:"user_register_form";b:0;s:23:"entity_translation_sync";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:1;}}s:8:"required";i:0;s:11:"description";s:0:"";s:13:"default_value";N;}',
+  'deleted' => '0',
+))
 ->execute();
 $connection->schema()->createTable('field_data_body', array(
   'fields' => array(
@@ -5189,7 +5371,7 @@
   'bundle' => 'article',
   'deleted' => '0',
   'entity_id' => '2',
-  'revision_id' => '2',
+  'revision_id' => '11',
   'language' => 'und',
   'delta' => '0',
   'body_value' => "...is that it's the absolute best show ever. Trust me, I would know.",
@@ -5201,7 +5383,7 @@
   'bundle' => 'article',
   'deleted' => '0',
   'entity_id' => '3',
-  'revision_id' => '3',
+  'revision_id' => '12',
   'language' => 'und',
   'delta' => '0',
   'body_value' => "is - ...is that it's the absolute best show ever. Trust me, I would know.",
@@ -5244,6 +5426,18 @@
   'body_summary' => '',
   'body_format' => 'filtered_html',
 ))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'et',
+  'deleted' => '0',
+  'entity_id' => '11',
+  'revision_id' => '18',
+  'language' => 'und',
+  'delta' => '0',
+  'body_value' => '2nd',
+  'body_summary' => '',
+  'body_format' => 'filtered_html',
+))
 ->execute();
 $connection->schema()->createTable('field_data_comment_body', array(
   'fields' => array(
@@ -7189,23 +7383,23 @@
   'bundle' => 'article',
   'deleted' => '0',
   'entity_id' => '2',
-  'revision_id' => '2',
+  'revision_id' => '11',
   'language' => 'und',
   'delta' => '0',
   'field_link_url' => '<front>',
-  'field_link_title' => 'Home',
-  'field_link_attributes' => 'a:0:{}',
+  'field_link_title' => NULL,
+  'field_link_attributes' => 'a:1:{s:5:"title";s:0:"";}',
 ))
 ->values(array(
   'entity_type' => 'node',
   'bundle' => 'article',
   'deleted' => '0',
   'entity_id' => '3',
-  'revision_id' => '3',
+  'revision_id' => '12',
   'language' => 'und',
   'delta' => '0',
   'field_link_url' => '<front>',
-  'field_link_title' => 'Home',
+  'field_link_title' => NULL,
   'field_link_attributes' => 'a:1:{s:5:"title";s:0:"";}',
 ))
 ->execute();
@@ -7817,7 +8011,7 @@
   'bundle' => 'article',
   'deleted' => '0',
   'entity_id' => '2',
-  'revision_id' => '2',
+  'revision_id' => '11',
   'language' => 'und',
   'delta' => '0',
   'field_reference_target_id' => '5',
@@ -7827,7 +8021,7 @@
   'bundle' => 'article',
   'deleted' => '0',
   'entity_id' => '3',
-  'revision_id' => '3',
+  'revision_id' => '12',
   'language' => 'und',
   'delta' => '0',
   'field_reference_target_id' => '4',
@@ -7837,7 +8031,7 @@
   'bundle' => 'article',
   'deleted' => '0',
   'entity_id' => '4',
-  'revision_id' => '4',
+  'revision_id' => '13',
   'language' => 'und',
   'delta' => '0',
   'field_reference_target_id' => '3',
@@ -7847,7 +8041,7 @@
   'bundle' => 'article',
   'deleted' => '0',
   'entity_id' => '5',
-  'revision_id' => '5',
+  'revision_id' => '14',
   'language' => 'und',
   'delta' => '0',
   'field_reference_target_id' => '2',
@@ -7953,7 +8147,7 @@
   'bundle' => 'article',
   'deleted' => '0',
   'entity_id' => '2',
-  'revision_id' => '2',
+  'revision_id' => '11',
   'language' => 'und',
   'delta' => '0',
   'field_reference_2_target_id' => '5',
@@ -7963,7 +8157,7 @@
   'bundle' => 'article',
   'deleted' => '0',
   'entity_id' => '3',
-  'revision_id' => '3',
+  'revision_id' => '12',
   'language' => 'und',
   'delta' => '0',
   'field_reference_2_target_id' => '4',
@@ -7973,7 +8167,7 @@
   'bundle' => 'article',
   'deleted' => '0',
   'entity_id' => '4',
-  'revision_id' => '4',
+  'revision_id' => '13',
   'language' => 'und',
   'delta' => '0',
   'field_reference_2_target_id' => '3',
@@ -7983,7 +8177,7 @@
   'bundle' => 'article',
   'deleted' => '0',
   'entity_id' => '5',
-  'revision_id' => '5',
+  'revision_id' => '14',
   'language' => 'und',
   'delta' => '0',
   'field_reference_2_target_id' => '2',
@@ -8178,7 +8372,7 @@
   'bundle' => 'article',
   'deleted' => '0',
   'entity_id' => '2',
-  'revision_id' => '2',
+  'revision_id' => '11',
   'language' => 'und',
   'delta' => '0',
   'field_tags_tid' => '9',
@@ -8188,7 +8382,7 @@
   'bundle' => 'article',
   'deleted' => '0',
   'entity_id' => '3',
-  'revision_id' => '3',
+  'revision_id' => '12',
   'language' => 'und',
   'delta' => '0',
   'field_tags_tid' => '9',
@@ -8198,7 +8392,7 @@
   'bundle' => 'article',
   'deleted' => '0',
   'entity_id' => '2',
-  'revision_id' => '2',
+  'revision_id' => '11',
   'language' => 'und',
   'delta' => '1',
   'field_tags_tid' => '14',
@@ -8208,7 +8402,7 @@
   'bundle' => 'article',
   'deleted' => '0',
   'entity_id' => '3',
-  'revision_id' => '3',
+  'revision_id' => '12',
   'language' => 'und',
   'delta' => '1',
   'field_tags_tid' => '14',
@@ -8218,7 +8412,7 @@
   'bundle' => 'article',
   'deleted' => '0',
   'entity_id' => '2',
-  'revision_id' => '2',
+  'revision_id' => '11',
   'language' => 'und',
   'delta' => '2',
   'field_tags_tid' => '17',
@@ -8228,7 +8422,7 @@
   'bundle' => 'article',
   'deleted' => '0',
   'entity_id' => '3',
-  'revision_id' => '3',
+  'revision_id' => '12',
   'language' => 'und',
   'delta' => '2',
   'field_tags_tid' => '17',
@@ -8886,6 +9080,63 @@
   ),
   'mysql_character_set' => 'utf8',
 ));
+$connection->insert('field_data_field_text_long_plain')
+->fields(array(
+  'entity_type',
+  'bundle',
+  'deleted',
+  'entity_id',
+  'revision_id',
+  'language',
+  'delta',
+  'field_text_long_plain_value',
+  'field_text_long_plain_format',
+))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '2',
+  'revision_id' => '11',
+  'language' => 'und',
+  'delta' => '0',
+  'field_text_long_plain_value' => 'DS9 2nd rev',
+  'field_text_long_plain_format' => NULL,
+))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '3',
+  'revision_id' => '12',
+  'language' => 'und',
+  'delta' => '0',
+  'field_text_long_plain_value' => 'is - DS9 2nd rev',
+  'field_text_long_plain_format' => NULL,
+))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '4',
+  'revision_id' => '13',
+  'language' => 'und',
+  'delta' => '0',
+  'field_text_long_plain_value' => 'is - Firefly 2nd rev',
+  'field_text_long_plain_format' => NULL,
+))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '5',
+  'revision_id' => '14',
+  'language' => 'und',
+  'delta' => '0',
+  'field_text_long_plain_value' => 'Firefly 2nd rev',
+  'field_text_long_plain_format' => NULL,
+))
+->execute();
 
 $connection->schema()->createTable('field_data_field_text_long_plain_filtered', array(
   'fields' => array(
@@ -9086,7 +9337,7 @@
   'bundle' => 'article',
   'deleted' => '0',
   'entity_id' => '2',
-  'revision_id' => '2',
+  'revision_id' => '11',
   'language' => 'und',
   'delta' => '0',
   'field_text_plain_value' => 'Kai Opaka',
@@ -9097,7 +9348,7 @@
   'bundle' => 'article',
   'deleted' => '0',
   'entity_id' => '3',
-  'revision_id' => '3',
+  'revision_id' => '12',
   'language' => 'und',
   'delta' => '0',
   'field_text_plain_value' => 'Kai Opaka',
@@ -9595,7 +9846,7 @@
   'field_training_format' => NULL,
 ))
 ->execute();
-$connection->schema()->createTable('field_data_field_user_entityreference', array(
+$connection->schema()->createTable('field_data_field_tree', array(
   'fields' => array(
     'entity_type' => array(
       'type' => 'varchar',
@@ -9639,11 +9890,15 @@
       'size' => 'normal',
       'unsigned' => TRUE,
     ),
-    'field_user_entityreference_target_id' => array(
-      'type' => 'int',
-      'not null' => TRUE,
-      'size' => 'normal',
-      'unsigned' => TRUE,
+    'field_tree_value' => array(
+      'type' => 'varchar',
+      'not null' => FALSE,
+      'length' => '255',
+    ),
+    'field_tree_format' => array(
+      'type' => 'varchar',
+      'not null' => FALSE,
+      'length' => '255',
     ),
   ),
   'primary key' => array(
@@ -9672,14 +9927,17 @@
     'language' => array(
       'language',
     ),
-    'field_user_entityreference_target_id' => array(
-      'field_user_entityreference_target_id',
+    'field_tree_format' => array(
+      array(
+        'field_tree_format',
+        '191',
+      ),
     ),
   ),
   'mysql_character_set' => 'utf8',
 ));
 
-$connection->insert('field_data_field_user_entityreference')
+$connection->insert('field_data_field_tree')
 ->fields(array(
   'entity_type',
   'bundle',
@@ -9688,20 +9946,44 @@
   'revision_id',
   'language',
   'delta',
-  'field_user_entityreference_target_id',
+  'field_tree_value',
+  'field_tree_format',
 ))
 ->values(array(
   'entity_type' => 'node',
-  'bundle' => 'test_content_type',
+  'bundle' => 'et',
   'deleted' => '0',
-  'entity_id' => '1',
-  'revision_id' => '1',
-  'language' => 'und',
+  'entity_id' => '11',
+  'revision_id' => '18',
+  'language' => 'en',
   'delta' => '0',
-  'field_user_entityreference_target_id' => '2',
+  'field_tree_value' => 'lancewood',
+  'field_tree_format' => NULL,
+))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'et',
+  'deleted' => '0',
+  'entity_id' => '11',
+  'revision_id' => '18',
+  'language' => 'fr',
+  'delta' => '0',
+  'field_tree_value' => 'fr - lancewood',
+  'field_tree_format' => NULL,
+))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'et',
+  'deleted' => '0',
+  'entity_id' => '11',
+  'revision_id' => '18',
+  'language' => 'is',
+  'delta' => '0',
+  'field_tree_value' => 'is - lancewood',
+  'field_tree_format' => NULL,
 ))
 ->execute();
-$connection->schema()->createTable('field_data_field_vocab_fixed', array(
+$connection->schema()->createTable('field_data_field_user_entityreference', array(
   'fields' => array(
     'entity_type' => array(
       'type' => 'varchar',
@@ -9745,9 +10027,9 @@
       'size' => 'normal',
       'unsigned' => TRUE,
     ),
-    'field_vocab_fixed_tid' => array(
+    'field_user_entityreference_target_id' => array(
       'type' => 'int',
-      'not null' => FALSE,
+      'not null' => TRUE,
       'size' => 'normal',
       'unsigned' => TRUE,
     ),
@@ -9778,14 +10060,14 @@
     'language' => array(
       'language',
     ),
-    'field_vocab_fixed_tid' => array(
-      'field_vocab_fixed_tid',
+    'field_user_entityreference_target_id' => array(
+      'field_user_entityreference_target_id',
     ),
   ),
   'mysql_character_set' => 'utf8',
 ));
 
-$connection->insert('field_data_field_vocab_fixed')
+$connection->insert('field_data_field_user_entityreference')
 ->fields(array(
   'entity_type',
   'bundle',
@@ -9794,20 +10076,126 @@
   'revision_id',
   'language',
   'delta',
-  'field_vocab_fixed_tid',
+  'field_user_entityreference_target_id',
 ))
 ->values(array(
   'entity_type' => 'node',
-  'bundle' => 'article',
+  'bundle' => 'test_content_type',
   'deleted' => '0',
-  'entity_id' => '2',
-  'revision_id' => '2',
+  'entity_id' => '1',
+  'revision_id' => '1',
   'language' => 'und',
   'delta' => '0',
-  'field_vocab_fixed_tid' => '24',
+  'field_user_entityreference_target_id' => '2',
 ))
 ->execute();
-$connection->schema()->createTable('field_data_field_vocab_localize', array(
+$connection->schema()->createTable('field_data_field_vocab_fixed', array(
+  'fields' => array(
+    'entity_type' => array(
+      'type' => 'varchar',
+      'not null' => TRUE,
+      'length' => '128',
+      'default' => '',
+    ),
+    'bundle' => array(
+      'type' => 'varchar',
+      'not null' => TRUE,
+      'length' => '128',
+      'default' => '',
+    ),
+    'deleted' => array(
+      'type' => 'int',
+      'not null' => TRUE,
+      'size' => 'tiny',
+      'default' => '0',
+    ),
+    'entity_id' => array(
+      'type' => 'int',
+      'not null' => TRUE,
+      'size' => 'normal',
+      'unsigned' => TRUE,
+    ),
+    'revision_id' => array(
+      'type' => 'int',
+      'not null' => FALSE,
+      'size' => 'normal',
+      'unsigned' => TRUE,
+    ),
+    'language' => array(
+      'type' => 'varchar',
+      'not null' => TRUE,
+      'length' => '32',
+      'default' => '',
+    ),
+    'delta' => array(
+      'type' => 'int',
+      'not null' => TRUE,
+      'size' => 'normal',
+      'unsigned' => TRUE,
+    ),
+    'field_vocab_fixed_tid' => array(
+      'type' => 'int',
+      'not null' => FALSE,
+      'size' => 'normal',
+      'unsigned' => TRUE,
+    ),
+  ),
+  'primary key' => array(
+    'entity_type',
+    'entity_id',
+    'deleted',
+    'delta',
+    'language',
+  ),
+  'indexes' => array(
+    'entity_type' => array(
+      'entity_type',
+    ),
+    'bundle' => array(
+      'bundle',
+    ),
+    'deleted' => array(
+      'deleted',
+    ),
+    'entity_id' => array(
+      'entity_id',
+    ),
+    'revision_id' => array(
+      'revision_id',
+    ),
+    'language' => array(
+      'language',
+    ),
+    'field_vocab_fixed_tid' => array(
+      'field_vocab_fixed_tid',
+    ),
+  ),
+  'mysql_character_set' => 'utf8',
+));
+
+$connection->insert('field_data_field_vocab_fixed')
+->fields(array(
+  'entity_type',
+  'bundle',
+  'deleted',
+  'entity_id',
+  'revision_id',
+  'language',
+  'delta',
+  'field_vocab_fixed_tid',
+))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '2',
+  'revision_id' => '11',
+  'language' => 'und',
+  'delta' => '0',
+  'field_vocab_fixed_tid' => '24',
+))
+->execute();
+$connection->schema()->createTable('field_data_field_vocab_localize', array(
   'fields' => array(
     'entity_type' => array(
       'type' => 'varchar',
@@ -9907,7 +10295,7 @@
   'bundle' => 'article',
   'deleted' => '0',
   'entity_id' => '2',
-  'revision_id' => '2',
+  'revision_id' => '11',
   'language' => 'und',
   'delta' => '0',
   'field_vocab_localize_tid' => '20',
@@ -9917,7 +10305,7 @@
   'bundle' => 'article',
   'deleted' => '0',
   'entity_id' => '3',
-  'revision_id' => '3',
+  'revision_id' => '12',
   'language' => 'und',
   'delta' => '0',
   'field_vocab_localize_tid' => '20',
@@ -10023,7 +10411,7 @@
   'bundle' => 'article',
   'deleted' => '0',
   'entity_id' => '2',
-  'revision_id' => '2',
+  'revision_id' => '11',
   'language' => 'und',
   'delta' => '0',
   'field_vocab_translate_tid' => '21',
@@ -10033,7 +10421,7 @@
   'bundle' => 'article',
   'deleted' => '0',
   'entity_id' => '3',
-  'revision_id' => '3',
+  'revision_id' => '12',
   'language' => 'und',
   'delta' => '0',
   'field_vocab_translate_tid' => '23',
@@ -10694,6 +11082,18 @@
   'body_summary' => '',
   'body_format' => 'filtered_html',
 ))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '2',
+  'revision_id' => '11',
+  'language' => 'und',
+  'delta' => '0',
+  'body_value' => "...is that it's the absolute best show ever. Trust me, I would know.",
+  'body_summary' => '',
+  'body_format' => 'filtered_html',
+))
 ->values(array(
   'entity_type' => 'node',
   'bundle' => 'article',
@@ -10710,11 +11110,11 @@
   'entity_type' => 'node',
   'bundle' => 'article',
   'deleted' => '0',
-  'entity_id' => '4',
-  'revision_id' => '4',
+  'entity_id' => '3',
+  'revision_id' => '12',
   'language' => 'und',
   'delta' => '0',
-  'body_value' => 'is - Is that is it awesome.',
+  'body_value' => "is - ...is that it's the absolute best show ever. Trust me, I would know.",
   'body_summary' => '',
   'body_format' => 'filtered_html',
 ))
@@ -10722,11 +11122,11 @@
   'entity_type' => 'node',
   'bundle' => 'article',
   'deleted' => '0',
-  'entity_id' => '5',
-  'revision_id' => '5',
+  'entity_id' => '4',
+  'revision_id' => '4',
   'language' => 'und',
   'delta' => '0',
-  'body_value' => 'en - Is that is it awesome.',
+  'body_value' => 'is - Is that is it awesome.',
   'body_summary' => '',
   'body_format' => 'filtered_html',
 ))
@@ -10766,6 +11166,54 @@
   'body_summary' => '',
   'body_format' => 'filtered_html',
 ))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'et',
+  'deleted' => '0',
+  'entity_id' => '11',
+  'revision_id' => '15',
+  'language' => 'und',
+  'delta' => '0',
+  'body_value' => '1st',
+  'body_summary' => '',
+  'body_format' => 'filtered_html',
+))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'et',
+  'deleted' => '0',
+  'entity_id' => '11',
+  'revision_id' => '16',
+  'language' => 'und',
+  'delta' => '0',
+  'body_value' => '1st',
+  'body_summary' => '',
+  'body_format' => 'filtered_html',
+))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'et',
+  'deleted' => '0',
+  'entity_id' => '11',
+  'revision_id' => '17',
+  'language' => 'und',
+  'delta' => '0',
+  'body_value' => '2nd',
+  'body_summary' => '',
+  'body_format' => 'filtered_html',
+))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'et',
+  'deleted' => '0',
+  'entity_id' => '11',
+  'revision_id' => '18',
+  'language' => 'und',
+  'delta' => '0',
+  'body_value' => '2nd',
+  'body_summary' => '',
+  'body_format' => 'filtered_html',
+))
 ->execute();
 $connection->schema()->createTable('field_revision_comment_body', array(
   'fields' => array(
@@ -12723,9 +13171,21 @@
   'language' => 'und',
   'delta' => '0',
   'field_link_url' => '<front>',
-  'field_link_title' => 'Home',
+  'field_link_title' => 'Home;',
   'field_link_attributes' => 'a:0:{}',
 ))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '2',
+  'revision_id' => '11',
+  'language' => 'und',
+  'delta' => '0',
+  'field_link_url' => '<front>',
+  'field_link_title' => 'Home',
+  'field_link_attributes' => 'a:1:{s:5:"title";s:0:"";}',
+))
 ->values(array(
   'entity_type' => 'node',
   'bundle' => 'article',
@@ -12738,6 +13198,18 @@
   'field_link_title' => 'Home',
   'field_link_attributes' => 'a:1:{s:5:"title";s:0:"";}',
 ))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '3',
+  'revision_id' => '12',
+  'language' => 'und',
+  'delta' => '0',
+  'field_link_url' => '<front>',
+  'field_link_title' => 'Home',
+  'field_link_attributes' => 'a:1:{s:5:"title";s:0:"";}',
+))
 ->execute();
 $connection->schema()->createTable('field_revision_field_long_text', array(
   'fields' => array(
@@ -13368,6 +13840,16 @@
   'delta' => '0',
   'field_reference_target_id' => '5',
 ))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '2',
+  'revision_id' => '11',
+  'language' => 'und',
+  'delta' => '0',
+  'field_reference_target_id' => '5',
+))
 ->values(array(
   'entity_type' => 'node',
   'bundle' => 'article',
@@ -13378,6 +13860,16 @@
   'delta' => '0',
   'field_reference_target_id' => '4',
 ))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '3',
+  'revision_id' => '12',
+  'language' => 'und',
+  'delta' => '0',
+  'field_reference_target_id' => '4',
+))
 ->values(array(
   'entity_type' => 'node',
   'bundle' => 'article',
@@ -13388,6 +13880,16 @@
   'delta' => '0',
   'field_reference_target_id' => '3',
 ))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '4',
+  'revision_id' => '13',
+  'language' => 'und',
+  'delta' => '0',
+  'field_reference_target_id' => '3',
+))
 ->values(array(
   'entity_type' => 'node',
   'bundle' => 'article',
@@ -13398,6 +13900,16 @@
   'delta' => '0',
   'field_reference_target_id' => '2',
 ))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '5',
+  'revision_id' => '14',
+  'language' => 'und',
+  'delta' => '0',
+  'field_reference_target_id' => '2',
+))
 ->execute();
 $connection->schema()->createTable('field_revision_field_reference_2', array(
   'fields' => array(
@@ -13505,6 +14017,16 @@
   'delta' => '0',
   'field_reference_2_target_id' => '5',
 ))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '2',
+  'revision_id' => '11',
+  'language' => 'und',
+  'delta' => '0',
+  'field_reference_2_target_id' => '5',
+))
 ->values(array(
   'entity_type' => 'node',
   'bundle' => 'article',
@@ -13515,6 +14037,16 @@
   'delta' => '0',
   'field_reference_2_target_id' => '4',
 ))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '3',
+  'revision_id' => '12',
+  'language' => 'und',
+  'delta' => '0',
+  'field_reference_2_target_id' => '4',
+))
 ->values(array(
   'entity_type' => 'node',
   'bundle' => 'article',
@@ -13525,6 +14057,16 @@
   'delta' => '0',
   'field_reference_2_target_id' => '3',
 ))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '4',
+  'revision_id' => '13',
+  'language' => 'und',
+  'delta' => '0',
+  'field_reference_2_target_id' => '3',
+))
 ->values(array(
   'entity_type' => 'node',
   'bundle' => 'article',
@@ -13535,6 +14077,16 @@
   'delta' => '0',
   'field_reference_2_target_id' => '2',
 ))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '5',
+  'revision_id' => '14',
+  'language' => 'und',
+  'delta' => '0',
+  'field_reference_2_target_id' => '2',
+))
 ->execute();
 $connection->schema()->createTable('field_revision_field_sector', array(
   'fields' => array(
@@ -13722,6 +14274,16 @@
   'delta',
   'field_tags_tid',
 ))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '3',
+  'revision_id' => '12',
+  'language' => 'und',
+  'delta' => '0',
+  'field_tags_tid' => '9',
+))
 ->values(array(
   'entity_type' => 'node',
   'bundle' => 'article',
@@ -13732,6 +14294,16 @@
   'delta' => '0',
   'field_tags_tid' => '9',
 ))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '2',
+  'revision_id' => '11',
+  'language' => 'und',
+  'delta' => '0',
+  'field_tags_tid' => '9',
+))
 ->values(array(
   'entity_type' => 'node',
   'bundle' => 'article',
@@ -13742,6 +14314,16 @@
   'delta' => '0',
   'field_tags_tid' => '9',
 ))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '3',
+  'revision_id' => '12',
+  'language' => 'und',
+  'delta' => '1',
+  'field_tags_tid' => '14',
+))
 ->values(array(
   'entity_type' => 'node',
   'bundle' => 'article',
@@ -13752,6 +14334,16 @@
   'delta' => '1',
   'field_tags_tid' => '14',
 ))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '2',
+  'revision_id' => '11',
+  'language' => 'und',
+  'delta' => '1',
+  'field_tags_tid' => '14',
+))
 ->values(array(
   'entity_type' => 'node',
   'bundle' => 'article',
@@ -13772,6 +14364,16 @@
   'delta' => '2',
   'field_tags_tid' => '17',
 ))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '2',
+  'revision_id' => '11',
+  'language' => 'und',
+  'delta' => '2',
+  'field_tags_tid' => '17',
+))
 ->values(array(
   'entity_type' => 'node',
   'bundle' => 'article',
@@ -13782,6 +14384,16 @@
   'delta' => '2',
   'field_tags_tid' => '17',
 ))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '3',
+  'revision_id' => '12',
+  'language' => 'und',
+  'delta' => '2',
+  'field_tags_tid' => '17',
+))
 ->execute();
 $connection->schema()->createTable('field_revision_field_term_entityreference', array(
   'fields' => array(
@@ -14442,6 +15054,96 @@
   ),
   'mysql_character_set' => 'utf8',
 ));
+$connection->insert('field_revision_field_text_long_plain')
+->fields(array(
+  'entity_type',
+  'bundle',
+  'deleted',
+  'entity_id',
+  'revision_id',
+  'language',
+  'delta',
+  'field_text_long_plain_value',
+  'field_text_long_plain_format',
+))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '2',
+  'revision_id' => '2',
+  'language' => 'und',
+  'delta' => '0',
+  'field_text_long_plain_value' => 'DS9 1st rev',
+  'field_text_long_plain_format' => NULL,
+))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '2',
+  'revision_id' => '11',
+  'language' => 'und',
+  'delta' => '0',
+  'field_text_long_plain_value' => 'DS9 2nd rev',
+  'field_text_long_plain_format' => NULL,
+))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '3',
+  'revision_id' => '3',
+  'language' => 'und',
+  'delta' => '0',
+  'field_text_long_plain_value' => 'is - DS9 1st rev',
+  'field_text_long_plain_format' => NULL,
+))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '3',
+  'revision_id' => '12',
+  'language' => 'und',
+  'delta' => '0',
+  'field_text_long_plain_value' => 'is - DS9 2nd rev',
+  'field_text_long_plain_format' => NULL,
+))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '4',
+  'revision_id' => '13',
+  'language' => 'und',
+  'delta' => '0',
+  'field_text_long_plain_value' => 'is - Firefly 2nd rev',
+  'field_text_long_plain_format' => NULL,
+))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '5',
+  'revision_id' => '5',
+  'language' => 'und',
+  'delta' => '0',
+  'field_text_long_plain_value' => 'Firefly 1st rev',
+  'field_text_long_plain_format' => NULL,
+))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '5',
+  'revision_id' => '14',
+  'language' => 'und',
+  'delta' => '0',
+  'field_text_long_plain_value' => 'Firefly 2nd rev',
+  'field_text_long_plain_format' => NULL,
+))
+->execute();
 
 $connection->schema()->createTable('field_revision_field_text_long_plain_filtered', array(
   'fields' => array(
@@ -14644,7 +15346,7 @@
   'bundle' => 'article',
   'deleted' => '0',
   'entity_id' => '2',
-  'revision_id' => '2',
+  'revision_id' => '11',
   'language' => 'und',
   'delta' => '0',
   'field_text_plain_value' => 'Kai Opaka',
@@ -14655,7 +15357,7 @@
   'bundle' => 'article',
   'deleted' => '0',
   'entity_id' => '3',
-  'revision_id' => '3',
+  'revision_id' => '12',
   'language' => 'und',
   'delta' => '0',
   'field_text_plain_value' => 'Kai Opaka',
@@ -15360,6 +16062,16 @@
   'delta' => '0',
   'field_vocab_fixed_tid' => '24',
 ))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '2',
+  'revision_id' => '11',
+  'language' => 'und',
+  'delta' => '0',
+  'field_vocab_fixed_tid' => '24',
+))
 ->execute();
 $connection->schema()->createTable('field_revision_field_vocab_localize', array(
   'fields' => array(
@@ -15467,6 +16179,16 @@
   'delta' => '0',
   'field_vocab_localize_tid' => '20',
 ))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '2',
+  'revision_id' => '11',
+  'language' => 'und',
+  'delta' => '0',
+  'field_vocab_localize_tid' => '20',
+))
 ->values(array(
   'entity_type' => 'node',
   'bundle' => 'article',
@@ -15477,6 +16199,16 @@
   'delta' => '0',
   'field_vocab_localize_tid' => '20',
 ))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '3',
+  'revision_id' => '12',
+  'language' => 'und',
+  'delta' => '0',
+  'field_vocab_localize_tid' => '20',
+))
 ->execute();
 $connection->schema()->createTable('field_revision_field_vocab_translate', array(
   'fields' => array(
@@ -15584,6 +16316,16 @@
   'delta' => '0',
   'field_vocab_translate_tid' => '21',
 ))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '2',
+  'revision_id' => '11',
+  'language' => 'und',
+  'delta' => '0',
+  'field_vocab_translate_tid' => '21',
+))
 ->values(array(
   'entity_type' => 'node',
   'bundle' => 'article',
@@ -15594,6 +16336,16 @@
   'delta' => '0',
   'field_vocab_translate_tid' => '23',
 ))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'article',
+  'deleted' => '0',
+  'entity_id' => '3',
+  'revision_id' => '12',
+  'language' => 'und',
+  'delta' => '0',
+  'field_vocab_translate_tid' => '23',
+))
 ->execute();
 $connection->schema()->createTable('field_revision_name_field', array(
   'fields' => array(
@@ -16158,6 +16910,199 @@
   'title_field_format' => NULL,
 ))
 ->execute();
+$connection->schema()->createTable('field_revision_field_tree', array(
+  'fields' => array(
+    'entity_type' => array(
+      'type' => 'varchar',
+      'not null' => TRUE,
+      'length' => '128',
+      'default' => '',
+    ),
+    'bundle' => array(
+      'type' => 'varchar',
+      'not null' => TRUE,
+      'length' => '128',
+      'default' => '',
+    ),
+    'deleted' => array(
+      'type' => 'int',
+      'not null' => TRUE,
+      'size' => 'tiny',
+      'default' => '0',
+    ),
+    'entity_id' => array(
+      'type' => 'int',
+      'not null' => TRUE,
+      'size' => 'normal',
+      'unsigned' => TRUE,
+    ),
+    'revision_id' => array(
+      'type' => 'int',
+      'not null' => TRUE,
+      'size' => 'normal',
+      'unsigned' => TRUE,
+    ),
+    'language' => array(
+      'type' => 'varchar',
+      'not null' => TRUE,
+      'length' => '32',
+      'default' => '',
+    ),
+    'delta' => array(
+      'type' => 'int',
+      'not null' => TRUE,
+      'size' => 'normal',
+      'unsigned' => TRUE,
+    ),
+    'field_tree_value' => array(
+      'type' => 'varchar',
+      'not null' => FALSE,
+      'length' => '255',
+    ),
+    'field_tree_format' => array(
+      'type' => 'varchar',
+      'not null' => FALSE,
+      'length' => '255',
+    ),
+  ),
+  'primary key' => array(
+    'entity_type',
+    'entity_id',
+    'revision_id',
+    'deleted',
+    'delta',
+    'language',
+  ),
+  'indexes' => array(
+    'entity_type' => array(
+      'entity_type',
+    ),
+    'bundle' => array(
+      'bundle',
+    ),
+    'deleted' => array(
+      'deleted',
+    ),
+    'entity_id' => array(
+      'entity_id',
+    ),
+    'revision_id' => array(
+      'revision_id',
+    ),
+    'language' => array(
+      'language',
+    ),
+    'field_tree_format' => array(
+      array(
+        'field_tree_format',
+        '191',
+      ),
+    ),
+  ),
+  'mysql_character_set' => 'utf8',
+));
+
+$connection->insert('field_revision_field_tree')
+->fields(array(
+  'entity_type',
+  'bundle',
+  'deleted',
+  'entity_id',
+  'revision_id',
+  'language',
+  'delta',
+  'field_tree_value',
+  'field_tree_format',
+))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'et',
+  'deleted' => '0',
+  'entity_id' => '11',
+  'revision_id' => '15',
+  'language' => 'en',
+  'delta' => '0',
+  'field_tree_value' => 'lancewood',
+  'field_tree_format' => NULL,
+))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'et',
+  'deleted' => '0',
+  'entity_id' => '11',
+  'revision_id' => '16',
+  'language' => 'en',
+  'delta' => '0',
+  'field_tree_value' => 'lancewood',
+  'field_tree_format' => NULL,
+))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'et',
+  'deleted' => '0',
+  'entity_id' => '11',
+  'revision_id' => '17',
+  'language' => 'en',
+  'delta' => '0',
+  'field_tree_value' => 'lancewood',
+  'field_tree_format' => NULL,
+))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'et',
+  'deleted' => '0',
+  'entity_id' => '11',
+  'revision_id' => '18',
+  'language' => 'en',
+  'delta' => '0',
+  'field_tree_value' => 'lancewood',
+  'field_tree_format' => NULL,
+))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'et',
+  'deleted' => '0',
+  'entity_id' => '11',
+  'revision_id' => '18',
+  'language' => 'fr',
+  'delta' => '0',
+  'field_tree_value' => 'fr - lancewood',
+  'field_tree_format' => NULL,
+))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'et',
+  'deleted' => '0',
+  'entity_id' => '11',
+  'revision_id' => '16',
+  'language' => 'is',
+  'delta' => '0',
+  'field_tree_value' => 'is - lancewood',
+  'field_tree_format' => NULL,
+))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'et',
+  'deleted' => '0',
+  'entity_id' => '11',
+  'revision_id' => '17',
+  'language' => 'is',
+  'delta' => '0',
+  'field_tree_value' => 'is - lancewood',
+  'field_tree_format' => NULL,
+))
+->values(array(
+  'entity_type' => 'node',
+  'bundle' => 'et',
+  'deleted' => '0',
+  'entity_id' => '11',
+  'revision_id' => '18',
+  'language' => 'is',
+  'delta' => '0',
+  'field_tree_value' => 'is - lancewood',
+  'field_tree_format' => NULL,
+))
+->execute();
 $connection->schema()->createTable('file_managed', array(
   'fields' => array(
     'fid' => array(
@@ -42331,14 +43276,14 @@
 ))
 ->values(array(
   'nid' => '2',
-  'vid' => '2',
+  'vid' => '11',
   'type' => 'article',
   'language' => 'en',
   'title' => 'The thing about Deep Space 9',
   'uid' => '2',
   'status' => '1',
   'created' => '1441306772',
-  'changed' => '1441306832',
+  'changed' => '1564543637',
   'comment' => '2',
   'promote' => '1',
   'sticky' => '0',
@@ -42347,14 +43292,14 @@
 ))
 ->values(array(
   'nid' => '3',
-  'vid' => '3',
+  'vid' => '12',
   'type' => 'article',
   'language' => 'is',
   'title' => 'is - The thing about Deep Space 9',
   'uid' => '1',
   'status' => '1',
   'created' => '1471428152',
-  'changed' => '1471428152',
+  'changed' => '1564543706',
   'comment' => '2',
   'promote' => '1',
   'sticky' => '0',
@@ -42363,14 +43308,14 @@
 ))
 ->values(array(
   'nid' => '4',
-  'vid' => '4',
+  'vid' => '13',
   'type' => 'article',
   'language' => 'is',
   'title' => 'is - The thing about Firefly',
   'uid' => '1',
   'status' => '1',
   'created' => '1478755274',
-  'changed' => '1478755274',
+  'changed' => '1564543810',
   'comment' => '1',
   'promote' => '1',
   'sticky' => '0',
@@ -42379,14 +43324,14 @@
 ))
 ->values(array(
   'nid' => '5',
-  'vid' => '5',
+  'vid' => '14',
   'type' => 'article',
   'language' => 'en',
   'title' => 'en - The thing about Firefly',
   'uid' => '1',
   'status' => '1',
   'created' => '1478755314',
-  'changed' => '1478755314',
+  'changed' => '1564543929',
   'comment' => '1',
   'promote' => '1',
   'sticky' => '0',
@@ -42473,6 +43418,22 @@
   'tnid' => '8',
   'translate' => '0',
 ))
+->values(array(
+  'nid' => '11',
+  'vid' => '18',
+  'type' => 'et',
+  'language' => 'en',
+  'title' => 'Page one',
+  'uid' => '1',
+  'status' => '1',
+  'created' => '1568261523',
+  'changed' => '1568261721',
+  'comment' => '1',
+  'promote' => '0',
+  'sticky' => '0',
+  'tnid' => '0',
+  'translate' => '0',
+))
 ->execute();
 $connection->schema()->createTable('node_access', array(
   'fields' => array(
@@ -42848,9 +43809,9 @@
   'nid' => '2',
   'vid' => '2',
   'uid' => '1',
-  'title' => 'The thing about Deep Space 9',
-  'log' => '',
-  'timestamp' => '1441306832',
+  'title' => 'The thing about Deep Space 9 (1st rev)',
+  'log' => 'DS9 1st rev',
+  'timestamp' => '1564543588',
   'status' => '1',
   'comment' => '2',
   'promote' => '1',
@@ -42860,9 +43821,9 @@
   'nid' => '3',
   'vid' => '3',
   'uid' => '1',
-  'title' => 'is - The thing about Deep Space 9',
-  'log' => '',
-  'timestamp' => '1471428152',
+  'title' => 'is - The thing about Deep Space 9 (1st rev)',
+  'log' => 'is - DS9 1st rev',
+  'timestamp' => '1564543677',
   'status' => '1',
   'comment' => '2',
   'promote' => '1',
@@ -42872,8 +43833,8 @@
   'nid' => '4',
   'vid' => '4',
   'uid' => '1',
-  'title' => 'is - The thing about Firefly',
-  'log' => '',
+  'title' => 'is - The thing about Firefly (1st rev)',
+  'log' => 'is - Firefly 1st rev',
   'timestamp' => '1478755274',
   'status' => '1',
   'comment' => '1',
@@ -42884,9 +43845,9 @@
   'nid' => '5',
   'vid' => '5',
   'uid' => '1',
-  'title' => 'en - The thing about Firefly',
-  'log' => '',
-  'timestamp' => '1478755314',
+  'title' => 'en - The thing about Firefly (1st rev)',
+  'log' => 'Firefly 1st rev',
+  'timestamp' => '1564543887',
   'status' => '1',
   'comment' => '1',
   'promote' => '1',
@@ -42952,6 +43913,102 @@
   'promote' => '1',
   'sticky' => '0',
 ))
+->values(array(
+  'nid' => '2',
+  'vid' => '11',
+  'uid' => '1',
+  'title' => 'The thing about Deep Space 9',
+  'log' => 'DS9 2nd rev',
+  'timestamp' => '1564543637',
+  'status' => '1',
+  'comment' => '2',
+  'promote' => '1',
+  'sticky' => '0',
+))
+->values(array(
+  'nid' => '3',
+  'vid' => '12',
+  'uid' => '1',
+  'title' => 'is - The thing about Deep Space 9',
+  'log' => 'is - DS9 2nd rev',
+  'timestamp' => '1564543706',
+  'status' => '1',
+  'comment' => '2',
+  'promote' => '1',
+  'sticky' => '0',
+))
+->values(array(
+  'nid' => '4',
+  'vid' => '13',
+  'uid' => '1',
+  'title' => 'is - The thing about Firefly',
+  'log' => 'is - Firefly 2nd rev',
+  'timestamp' => '1564543810',
+  'status' => '1',
+  'comment' => '1',
+  'promote' => '1',
+  'sticky' => '0',
+))
+->values(array(
+  'nid' => '5',
+  'vid' => '14',
+  'uid' => '1',
+  'title' => 'en - The thing about Firefly',
+  'log' => 'Firefly 2nd rev',
+  'timestamp' => '1564543929',
+  'status' => '1',
+  'comment' => '1',
+  'promote' => '1',
+  'sticky' => '0',
+))
+->values(array(
+  'nid' => '11',
+  'vid' => '15',
+  'uid' => '1',
+  'title' => 'Page one',
+  'log' => '',
+  'timestamp' => '1568261523',
+  'status' => '1',
+  'comment' => '1',
+  'promote' => '0',
+  'sticky' => '0',
+))
+->values(array(
+  'nid' => '11',
+  'vid' => '16',
+  'uid' => '1',
+  'title' => 'Page one',
+  'log' => '',
+  'timestamp' => '1568261548',
+  'status' => '1',
+  'comment' => '1',
+  'promote' => '0',
+  'sticky' => '0',
+))
+->values(array(
+  'nid' => '11',
+  'vid' => '17',
+  'uid' => '1',
+  'title' => 'Page one',
+  'log' => '2nd',
+  'timestamp' => '1568261687',
+  'status' => '1',
+  'comment' => '1',
+  'promote' => '0',
+  'sticky' => '0',
+))
+->values(array(
+  'nid' => '11',
+  'vid' => '18',
+  'uid' => '1',
+  'title' => 'Page one',
+  'log' => '',
+  'timestamp' => '1568261721',
+  'status' => '1',
+  'comment' => '1',
+  'promote' => '0',
+  'sticky' => '0',
+))
 ->execute();
 $connection->schema()->createTable('node_type', array(
   'fields' => array(
@@ -43141,6 +44198,21 @@
   'disabled' => '0',
   'orig_type' => 'test_content_type',
 ))
+->values(array(
+  'type' => 'et',
+  'name' => 'Entity translation test',
+  'base' => 'node_content',
+  'module' => 'node',
+  'description' => 'Entity translation test',
+  'help' => 'Help text foret pages',
+  'has_title' => '1',
+  'title_label' => 'Title',
+  'custom' => '1',
+  'modified' => '1',
+  'locked' => '0',
+  'disabled' => '0',
+  'orig_type' => 'et',
+))
 ->execute();
 $connection->schema()->createTable('queue', array(
   'fields' => array(
@@ -56613,6 +57685,10 @@
   'name' => 'language_content_type_blog',
   'value' => 's:1:"2";',
 ))
+->values(array(
+  'name' => 'language_content_type_et',
+  'value' => 's:1:"4";',
+))
 ->values(array(
   'name' => 'language_content_type_forum',
   'value' => 's:1:"0";',
diff --git a/core/modules/migrate_drupal/tests/src/Kernel/MigrationPluginAlterTest.php b/core/modules/migrate_drupal/tests/src/Kernel/MigrationPluginAlterTest.php
deleted file mode 100644
index 335c44cab7..0000000000
--- a/core/modules/migrate_drupal/tests/src/Kernel/MigrationPluginAlterTest.php
+++ /dev/null
@@ -1,377 +0,0 @@
-<?php
-
-namespace Drupal\Tests\migrate_drupal\Kernel;
-
-use Drupal\Tests\migrate\Kernel\MigrateTestBase;
-
-/**
- * Tests migrate_drupal_migrations_plugin_alter for d6 term node migrations.
- *
- * @group migrate_drupal
- */
-class MigrationPluginAlterTest extends MigrateTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static $modules = ['migrate_drupal', 'taxonomy'];
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-    $this->setupDb();
-  }
-
-  /**
-   * Tests migrate_drupal_migrations_plugin_alter without content_translation.
-   *
-   * @dataProvider providerMigrationPluginAlter
-   */
-  public function testMigrationPluginAlterNoTranslation($source, $expected) {
-    $definitions = $source;
-    migrate_drupal_migration_plugins_alter($definitions);
-    // Ensure the results have an 'id' key.
-    foreach ($definitions as $definition) {
-      $this->assertArrayHasKey('id', $definition);
-    }
-    $this->assertSame($expected, $definitions);
-  }
-
-  /**
-   * Data provider for testMigrationPluginAlter().
-   */
-  public function providerMigrationPluginAlter() {
-    $tests = [];
-
-    // Test without a d6_taxonomy_vocabulary definition.
-    $tests[0]['source_data'] = [
-      'test' => [
-        'id' => 'test',
-        'process' => [
-          'nid' => 'nid',
-        ],
-      ],
-    ];
-    $tests[0]['expected_data'] = $tests[0]['source_data'];
-
-    // Test with a d6_taxonomy_vocabulary definition.
-    $tests[1]['source_data'] = [
-      'd6_taxonomy_vocabulary' => [
-        'id' => 'd6_taxonomy_vocabulary',
-        'process' => [
-          'vid' => [
-            'plugin' => 'machine_name',
-          ],
-        ],
-      ],
-      'test' => [
-        'id' => 'test',
-        'process' => [
-          'nid' => 'nid',
-        ],
-      ],
-    ];
-    $tests[1]['expected_data'] = $tests[1]['source_data'];
-
-    // Test with a d6_taxonomy_vocabulary and term_node definitions.
-    $tests[2] = $tests[1];
-    $tests[2]['source_data']['d6_term_node:2'] = [
-      'id' => 'd6_term_node:2',
-      'process' => [
-        'vid' => [
-          'plugin' => 'machine_name',
-        ],
-      ],
-    ];
-    $tests[2]['source_data']['d6_term_node_revision:4'] = [
-      'id' => 'd6_term_node_revision:4',
-      'process' => [
-        'vid' => [
-          'plugin' => 'machine_name',
-        ],
-      ],
-    ];
-
-    $tests[2]['expected_data'] = $tests[2]['source_data'];
-    $tests[2]['expected_data']['d6_term_node:2']['process']['taxonomy_forums'] = 'tid';
-    $tests[2]['expected_data']['d6_term_node_revision:4']['process']['field_'] = 'tid';
-
-    // Test with a d6_taxonomy_vocabulary and term_node_translation definition.
-    $tests[3] = $tests[1];
-    $tests[3]['source_data']['d6_term_node_translation:2'] = [
-      'id' => 'd6_term_node_translation:2',
-      'process' => [
-        'vid' => [
-          'plugin' => 'machine_name',
-        ],
-      ],
-    ];
-
-    $tests[3]['expected_data'] = $tests[3]['source_data'];
-    return $tests;
-  }
-
-  /**
-   * Tests migrate_drupal_migrations_plugin_alter.
-   *
-   * @dataProvider providerMigrationPluginAlterTranslation
-   */
-  public function testMigrationPluginAlterTranslation($source, $expected) {
-    /** @var \Drupal\Core\Extension\ModuleInstaller $module_installer */
-    $module_installer = \Drupal::service('module_installer');
-    $module_installer->install(['content_translation']);
-    $definitions = $source;
-    migrate_drupal_migration_plugins_alter($definitions);
-    // Ensure the results have an 'id' key.
-    foreach ($definitions as $definition) {
-      $this->assertArrayHasKey('id', $definition);
-    }
-    $this->assertSame($expected, $definitions);
-
-  }
-
-  /**
-   * Data provider for providerMigrationPluginAlterTranslation().
-   */
-  public function providerMigrationPluginAlterTranslation() {
-    $tests = [];
-
-    // Test with a d6_taxonomy_vocabulary definition and
-    // d6_term_node_translation definitions.
-    $tests[0]['source_data'] = [
-      'd6_taxonomy_vocabulary' => [
-        'id' => 'd6_taxonomy_vocabulary',
-        'process' => [
-          'vid' => [
-            'plugin' => 'machine_name',
-          ],
-        ],
-      ],
-      'test' => [
-        'id' => 'test',
-        'process' => [
-          'nid' => 'nid',
-        ],
-      ],
-      'd6_term_node_translation:2' => [
-        'id' => 'd6_term_node_translation:2',
-        'process' => [
-          'vid' => [
-            'plugin' => 'machine_name',
-          ],
-        ],
-      ],
-      'd6_term_node_translation:4' => [
-        'id' => 'd6_term_node_translation:4',
-        'process' => [
-          'vid' => [
-            'plugin' => 'machine_name',
-          ],
-        ],
-      ],
-    ];
-
-    $tests[0]['expected_data'] = $tests[0]['source_data'];
-    $tests[0]['expected_data']['d6_term_node_translation:2']['process']['taxonomy_forums'] = 'tid';
-    $tests[0]['expected_data']['d6_term_node_translation:4']['process']['field_'] = 'tid';
-    return $tests;
-  }
-
-  /**
-   * Creates data in the source database.
-   */
-  protected function setupDb() {
-    $this->sourceDatabase->schema()->createTable('system', [
-      'fields' => [
-        'name' => [
-          'type' => 'varchar',
-          'not null' => TRUE,
-          'length' => '255',
-          'default' => '',
-        ],
-        'type' => [
-          'type' => 'varchar',
-          'not null' => TRUE,
-          'length' => '255',
-          'default' => '',
-        ],
-        'status' => [
-          'type' => 'int',
-          'not null' => TRUE,
-          'size' => 'normal',
-          'default' => '0',
-        ],
-      ],
-    ]);
-    $this->sourceDatabase->insert('system')
-      ->fields([
-        'name',
-        'type',
-        'status',
-      ])
-      ->values([
-        'name' => 'taxonomy',
-        'type' => 'module',
-        'status' => '1',
-      ])
-      ->execute();
-
-    $this->sourceDatabase->schema()->createTable('variable', [
-      'fields' => [
-        'name' => [
-          'type' => 'varchar',
-          'not null' => TRUE,
-          'length' => '128',
-          'default' => '',
-        ],
-        'value' => [
-          'type' => 'text',
-          'not null' => TRUE,
-          'size' => 'normal',
-        ],
-      ],
-    ]);
-    $this->sourceDatabase->insert('variable')
-      ->fields([
-        'name',
-        'value',
-      ])
-      ->values([
-        'name' => 'forum_nav_vocabulary',
-        'value' => 's:1:"2";',
-      ])
-      ->execute();
-
-    $this->sourceDatabase->schema()->createTable('vocabulary', [
-      'fields' => [
-        'vid' => [
-          'type' => 'serial',
-          'not null' => TRUE,
-          'size' => 'normal',
-          'unsigned' => TRUE,
-        ],
-        'name' => [
-          'type' => 'varchar',
-          'not null' => TRUE,
-          'length' => '255',
-          'default' => '',
-        ],
-        'description' => [
-          'type' => 'text',
-          'not null' => FALSE,
-          'size' => 'normal',
-        ],
-        'help' => [
-          'type' => 'varchar',
-          'not null' => TRUE,
-          'length' => '255',
-          'default' => '',
-        ],
-        'relations' => [
-          'type' => 'int',
-          'not null' => TRUE,
-          'size' => 'normal',
-          'default' => '0',
-          'unsigned' => TRUE,
-        ],
-        'hierarchy' => [
-          'type' => 'int',
-          'not null' => TRUE,
-          'size' => 'normal',
-          'default' => '0',
-          'unsigned' => TRUE,
-        ],
-        'multiple' => [
-          'type' => 'int',
-          'not null' => TRUE,
-          'size' => 'normal',
-          'default' => '0',
-          'unsigned' => TRUE,
-        ],
-        'required' => [
-          'type' => 'int',
-          'not null' => TRUE,
-          'size' => 'normal',
-          'default' => '0',
-          'unsigned' => TRUE,
-        ],
-        'tags' => [
-          'type' => 'int',
-          'not null' => TRUE,
-          'size' => 'normal',
-          'default' => '0',
-          'unsigned' => TRUE,
-        ],
-        'module' => [
-          'type' => 'varchar',
-          'not null' => TRUE,
-          'length' => '255',
-          'default' => '',
-        ],
-        'weight' => [
-          'type' => 'int',
-          'not null' => TRUE,
-          'size' => 'normal',
-          'default' => '0',
-        ],
-      ],
-      'primary key' => ['vid'],
-    ]);
-
-    $this->sourceDatabase->insert('vocabulary')
-      ->fields([
-        'vid',
-        'name',
-      ])
-      ->values([
-        'vid' => '4',
-        'name' => 'Tags',
-      ])
-      ->values([
-        'vid' => '2',
-        'name' => 'Forums',
-      ])
-      ->execute();
-
-    $this->sourceDatabase->schema()->createTable('vocabulary_node_types', [
-      'fields' => [
-        'vid' => [
-          'type' => 'int',
-          'not null' => TRUE,
-          'size' => 'normal',
-          'default' => '0',
-          'unsigned' => TRUE,
-        ],
-        'type' => [
-          'type' => 'varchar',
-          'not null' => TRUE,
-          'length' => '32',
-          'default' => '',
-        ],
-      ],
-      'primary key' => [
-        'vid',
-        'type',
-      ],
-      'mysql_character_set' => 'utf8',
-    ]);
-
-    $this->sourceDatabase->insert('vocabulary_node_types')
-      ->fields([
-        'vid',
-        'type',
-      ])
-      ->values([
-        'vid' => '4',
-        'type' => 'article',
-      ])
-      ->values([
-        'vid' => '2',
-        'type' => 'forum',
-      ])
-      ->execute();
-  }
-
-}
diff --git a/core/modules/migrate_drupal/tests/src/Kernel/Plugin/migrate/source/ContentEntityTest.php b/core/modules/migrate_drupal/tests/src/Kernel/Plugin/migrate/source/ContentEntityTest.php
index 84bb7cae3b..2bcf11ff03 100644
--- a/core/modules/migrate_drupal/tests/src/Kernel/Plugin/migrate/source/ContentEntityTest.php
+++ b/core/modules/migrate_drupal/tests/src/Kernel/Plugin/migrate/source/ContentEntityTest.php
@@ -321,6 +321,7 @@ public function testNodeSource() {
     $values = $node_source->current()->getSource();
     $this->assertEquals($this->bundle, $values['type'][0]['target_id']);
     $this->assertEquals(1, $values['nid']);
+    $this->assertEquals(1, $values['vid']);
     $this->assertEquals('en', $values['langcode']);
     $this->assertEquals(1, $values['status'][0]['value']);
     $this->assertEquals('Apples', $values['title'][0]['value']);
@@ -330,6 +331,7 @@ public function testNodeSource() {
     $values = $node_source->current()->getSource();
     $this->assertEquals($this->bundle, $values['type'][0]['target_id']);
     $this->assertEquals(1, $values['nid']);
+    $this->assertEquals(1, $values['vid']);
     $this->assertEquals('fr', $values['langcode']);
     $this->assertEquals(1, $values['status'][0]['value']);
     $this->assertEquals('Pommes', $values['title'][0]['value']);
@@ -369,11 +371,13 @@ public function testMediaSource() {
     $fields = $media_source->fields();
     $this->assertArrayHasKey('bundle', $fields);
     $this->assertArrayHasKey('mid', $fields);
+    $this->assertArrayHasKey('vid', $fields);
     $this->assertArrayHasKey('name', $fields);
     $this->assertArrayHasKey('status', $fields);
     $media_source->rewind();
     $values = $media_source->current()->getSource();
     $this->assertEquals(1, $values['mid']);
+    $this->assertEquals(1, $values['vid']);
     $this->assertEquals('Foo media', $values['name'][0]['value']);
     $this->assertNull($values['thumbnail'][0]['title']);
     $this->assertEquals(1, $values['uid'][0]['target_id']);
@@ -402,9 +406,11 @@ public function testTermSource() {
     $this->assertEquals(2, $term_source->count());
     $ids = $term_source->getIds();
     $this->assertArrayHasKey('langcode', $ids);
+    $this->assertArrayHasKey('revision_id', $ids);
     $this->assertArrayHasKey('tid', $ids);
     $fields = $term_source->fields();
     $this->assertArrayHasKey('vid', $fields);
+    $this->assertArrayHasKey('revision_id', $fields);
     $this->assertArrayHasKey('tid', $fields);
     $this->assertArrayHasKey('name', $fields);
     $term_source->rewind();
diff --git a/core/modules/migrate_drupal/tests/src/Kernel/d6/FollowUpMigrationsCompleteTest.php b/core/modules/migrate_drupal/tests/src/Kernel/d6/FollowUpMigrationsCompleteTest.php
new file mode 100644
index 0000000000..7e54510c4c
--- /dev/null
+++ b/core/modules/migrate_drupal/tests/src/Kernel/d6/FollowUpMigrationsCompleteTest.php
@@ -0,0 +1,60 @@
+<?php
+
+namespace Drupal\Tests\migrate_drupal\Kernel\d6;
+
+use Drupal\migrate_drupal\NodeMigrateType;
+use Drupal\user\Entity\User;
+
+/**
+ * Tests follow-up migrations.
+ *
+ * @group migrate_drupal
+ */
+class FollowUpMigrationsCompleteTest extends FollowUpMigrationsTest {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = [
+    'content_translation',
+    'language',
+    'menu_ui',
+    // A requirement for d6_node_translation.
+    'migrate_drupal_multilingual',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    MigrateDrupal6TestBase::setUp();
+
+    // Remove the classic node table made in setup.
+    $this->removeNodeMigrateMapTable(NodeMigrateType::NODE_MIGRATE_TYPE_CLASSIC, '7');
+
+    $this->installEntitySchema('node');
+    $this->installConfig(['node']);
+    $this->installSchema('node', ['node_access']);
+    $this->installSchema('system', ['sequences']);
+
+    // Create a new user which needs to have UID 1, because that is expected by
+    // the assertions from
+    // \Drupal\migrate_drupal\Tests\d6\MigrateNodeRevisionTest.
+    User::create([
+      'uid' => 1,
+      'name' => $this->randomMachineName(),
+      'status' => 1,
+    ])->enforceIsNew()->save();
+
+    $this->migrateUsers(FALSE);
+    $this->migrateFields();
+    $this->executeMigration('d6_node_settings');
+
+    $this->executeMigrations([
+      'language',
+      'd6_language_content_settings',
+      'd6_node_complete',
+    ]);
+  }
+
+}
diff --git a/core/modules/migrate_drupal/tests/src/Kernel/d6/MigrateDrupal6AuditIdsTest.php b/core/modules/migrate_drupal/tests/src/Kernel/d6/MigrateDrupal6AuditIdsTest.php
index 3620f0c3bf..d1acc0cc33 100644
--- a/core/modules/migrate_drupal/tests/src/Kernel/d6/MigrateDrupal6AuditIdsTest.php
+++ b/core/modules/migrate_drupal/tests/src/Kernel/d6/MigrateDrupal6AuditIdsTest.php
@@ -138,6 +138,7 @@ function (AuditResult $result) {
       'd6_file',
       'd6_menu_links',
       'd6_node',
+      'd6_node_complete',
       'd6_node_revision',
       'd6_taxonomy_term',
       'd6_term_node_revision',
diff --git a/core/modules/migrate_drupal/tests/src/Kernel/d6/MigrateDrupal6TestBase.php b/core/modules/migrate_drupal/tests/src/Kernel/d6/MigrateDrupal6TestBase.php
index 0b2735c8ea..9bbd93316d 100644
--- a/core/modules/migrate_drupal/tests/src/Kernel/d6/MigrateDrupal6TestBase.php
+++ b/core/modules/migrate_drupal/tests/src/Kernel/d6/MigrateDrupal6TestBase.php
@@ -2,13 +2,16 @@
 
 namespace Drupal\Tests\migrate_drupal\Kernel\d6;
 
+use Drupal\migrate_drupal\NodeMigrateType;
 use Drupal\Tests\migrate_drupal\Kernel\MigrateDrupalTestBase;
+use Drupal\Tests\migrate_drupal\Traits\NodeMigrateTypeTestTrait;
 
 /**
  * Base class for Drupal 6 migration tests.
  */
 abstract class MigrateDrupal6TestBase extends MigrateDrupalTestBase {
 
+  use NodeMigrateTypeTestTrait;
   /**
    * {@inheritdoc}
    */
@@ -28,6 +31,9 @@ abstract class MigrateDrupal6TestBase extends MigrateDrupalTestBase {
    */
   protected function setUp() {
     parent::setUp();
+    // Add a node classic migrate table to the destination site so that tests
+    // run by default with the classic node migrations.
+    $this->makeNodeMigrateMapTable(NodeMigrateType::NODE_MIGRATE_TYPE_CLASSIC, '6');
     $this->loadFixture($this->getFixtureFilePath());
   }
 
diff --git a/core/modules/migrate_drupal/tests/src/Kernel/d7/FieldDiscoveryTest.php b/core/modules/migrate_drupal/tests/src/Kernel/d7/FieldDiscoveryTest.php
index 092b5bf699..0ed4ae9b2e 100644
--- a/core/modules/migrate_drupal/tests/src/Kernel/d7/FieldDiscoveryTest.php
+++ b/core/modules/migrate_drupal/tests/src/Kernel/d7/FieldDiscoveryTest.php
@@ -78,6 +78,7 @@ public function setUp() {
       'article' => 'comment_node_article',
       'blog' => 'comment_node_blog',
       'book' => 'comment_node_book',
+      'et' => 'comment_node_et',
       'forum' => 'comment_forum',
       'test_content_type' => 'comment_node_test_content_type',
     ];
@@ -281,7 +282,7 @@ public function testGetAllFields() {
     $this->assertArrayHasKey('test_vocabulary', $actual_fields['taxonomy_term']);
     $this->assertArrayHasKey('user', $actual_fields['user']);
     $this->assertArrayHasKey('test_content_type', $actual_fields['node']);
-    $this->assertSame(6, count($actual_fields['node']));
+    $this->assertSame(7, count($actual_fields['node']));
     $this->assertSame(6, count($actual_fields['comment']));
     $this->assertSame(22, count($actual_fields['node']['test_content_type']));
     foreach ($actual_fields as $entity_type_id => $bundles) {
diff --git a/core/modules/migrate_drupal/tests/src/Kernel/d7/FollowUpMigrationsCompleteTest.php b/core/modules/migrate_drupal/tests/src/Kernel/d7/FollowUpMigrationsCompleteTest.php
new file mode 100644
index 0000000000..21a1d37353
--- /dev/null
+++ b/core/modules/migrate_drupal/tests/src/Kernel/d7/FollowUpMigrationsCompleteTest.php
@@ -0,0 +1,59 @@
+<?php
+
+namespace Drupal\Tests\migrate_drupal\Kernel\d7;
+
+use Drupal\migrate_drupal\NodeMigrateType;
+use Drupal\Tests\migrate_drupal\Traits\NodeMigrateTypeTestTrait;
+
+/**
+ * Tests follow-up migrations.
+ *
+ * @group migrate_drupal
+ */
+class FollowUpMigrationsCompleteTest extends FollowUpMigrationsTest {
+
+  use NodeMigrateTypeTestTrait;
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = [
+    'content_translation',
+    'comment',
+    'datetime',
+    'image',
+    'language',
+    'link',
+    'menu_ui',
+    // A requirement for translation migrations.
+    'migrate_drupal_multilingual',
+    'node',
+    'taxonomy',
+    'telephone',
+    'text',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    MigrateDrupal7TestBase::setUp();
+
+    // Remove the classic node table made in setup.
+    $this->removeNodeMigrateMapTable(NodeMigrateType::NODE_MIGRATE_TYPE_CLASSIC, '7');
+
+    $this->fileMigrationSetup();
+
+    $this->installEntitySchema('comment');
+    $this->installSchema('node', ['node_access']);
+
+    $this->migrateUsers();
+    $this->migrateFields();
+    $this->executeMigrations([
+      'language',
+      'd7_language_content_settings',
+      'd7_taxonomy_vocabulary',
+      'd7_node_complete',
+    ]);
+  }
+
+}
diff --git a/core/modules/migrate_drupal/tests/src/Kernel/d7/MigrateDrupal7AuditIdsTest.php b/core/modules/migrate_drupal/tests/src/Kernel/d7/MigrateDrupal7AuditIdsTest.php
index b53ffa4d78..79f22739db 100644
--- a/core/modules/migrate_drupal/tests/src/Kernel/d7/MigrateDrupal7AuditIdsTest.php
+++ b/core/modules/migrate_drupal/tests/src/Kernel/d7/MigrateDrupal7AuditIdsTest.php
@@ -138,6 +138,7 @@ function (AuditResult $result) {
       'd7_file_private',
       'd7_menu_links',
       'd7_node',
+      'd7_node_complete',
       'd7_node_revision',
       'd7_taxonomy_term',
       'd7_user',
diff --git a/core/modules/migrate_drupal/tests/src/Kernel/d7/MigrateDrupal7TestBase.php b/core/modules/migrate_drupal/tests/src/Kernel/d7/MigrateDrupal7TestBase.php
index 535421cd84..d3cc3ead90 100644
--- a/core/modules/migrate_drupal/tests/src/Kernel/d7/MigrateDrupal7TestBase.php
+++ b/core/modules/migrate_drupal/tests/src/Kernel/d7/MigrateDrupal7TestBase.php
@@ -2,18 +2,25 @@
 
 namespace Drupal\Tests\migrate_drupal\Kernel\d7;
 
+use Drupal\migrate_drupal\NodeMigrateType;
 use Drupal\Tests\migrate_drupal\Kernel\MigrateDrupalTestBase;
+use Drupal\Tests\migrate_drupal\Traits\NodeMigrateTypeTestTrait;
 
 /**
  * Base class for Drupal 7 migration tests.
  */
 abstract class MigrateDrupal7TestBase extends MigrateDrupalTestBase {
 
+  use NodeMigrateTypeTestTrait;
+
   /**
    * {@inheritdoc}
    */
   protected function setUp() {
     parent::setUp();
+    // Add a node classic migrate table to the destination site so that tests
+    // run by default with the classic node migrations.
+    $this->makeNodeMigrateMapTable(NodeMigrateType::NODE_MIGRATE_TYPE_CLASSIC, '7');
     $this->loadFixture($this->getFixtureFilePath());
   }
 
diff --git a/core/modules/migrate_drupal/tests/src/Traits/NodeMigrateTypeTestTrait.php b/core/modules/migrate_drupal/tests/src/Traits/NodeMigrateTypeTestTrait.php
new file mode 100644
index 0000000000..a5eded5d31
--- /dev/null
+++ b/core/modules/migrate_drupal/tests/src/Traits/NodeMigrateTypeTestTrait.php
@@ -0,0 +1,206 @@
+<?php
+
+namespace Drupal\Tests\migrate_drupal\Traits;
+
+use Drupal\migrate_drupal\NodeMigrateType;
+
+/**
+ * Helper functions to test complete and classic node migrations.
+ */
+trait NodeMigrateTypeTestTrait {
+
+  /**
+   * The migrate_map table name.
+   *
+   * @var string
+   */
+  public $tableName = NULL;
+
+  /**
+   * Gets the numbers of complete and classic node migrate_map tables.
+   *
+   * @param string $version
+   *   The source database version.
+   *
+   * @return array
+   *   An associative array with the total number of complete and classic
+   *   node migrate_map tables.
+   */
+  protected function nodeMigrateMapTableCount($version) {
+    $results = [];
+    $bases = ['node', 'node_complete'];
+    $tables = \Drupal::database()->schema()
+      ->findTables('migrate_map_d' . $version . '_node%');
+
+    foreach ($bases as $base) {
+      $base_tables = preg_grep('/^migrate_map_d' . $version . '_' . $base . '_{2}.*$/', $tables);
+      $results[$base] = count($base_tables);
+    }
+    return $results;
+  }
+
+  /**
+   * Remove the node migrate map table.
+   *
+   * @param string $type
+   *   The type of node migration, 'complete' or 'classic'.
+   * @param string $version
+   *   The source database version.
+   *
+   * @throws \Exception
+   */
+  protected function removeNodeMigrateMapTable($type, $version) {
+    $name = $this->getTableName($type, $version);
+    \Drupal::database()->schema()->dropTable($name);
+  }
+
+  /**
+   * Gets the migrate_map table name.
+   *
+   * @param string $type
+   *   The type of node migration, 'complete' or 'classic'.
+   * @param string $version
+   *   The source database version.
+   *
+   * @return string
+   *   The migrate_map table name.
+   */
+  protected function getTableName($type, $version) {
+    if (!$this->tableName) {
+      $content_type = $this->randomMachineName();
+      $this->tableName = 'migrate_map_d' . $version . '_node_complete__' . $content_type;
+      if ($type == NodeMigrateType::NODE_MIGRATE_TYPE_CLASSIC) {
+        $this->tableName = 'migrate_map_d' . $version . '_node__' . $content_type;
+      }
+    }
+    return $this->tableName;
+  }
+
+  /**
+   * Create a node migrate_map table.
+   *
+   * @param string $type
+   *   The type of node migration, 'complete' or 'classic'.
+   * @param string $version
+   *   The source database version.
+   *
+   * @throws \Exception
+   */
+  protected function makeNodeMigrateMapTable($type, $version) {
+    $name = $this->getTableName($type, $version);
+    $fields = [
+      'source_ids_hash' => [
+        'type' => 'varchar',
+        'not null' => TRUE,
+        'length' => '64',
+      ],
+      'sourceid1' => [
+        'type' => 'int',
+        'not null' => TRUE,
+        'size' => 'normal',
+      ],
+      'sourceid2' => [
+        'type' => 'int',
+        'not null' => TRUE,
+        'size' => 'normal',
+      ],
+      'sourceid3' => [
+        'type' => 'varchar',
+        'not null' => TRUE,
+        'length' => '255',
+      ],
+      'destid1' => [
+        'type' => 'int',
+        'not null' => FALSE,
+        'size' => 'normal',
+        'unsigned' => TRUE,
+      ],
+      'destid2' => [
+        'type' => 'int',
+        'not null' => FALSE,
+        'size' => 'normal',
+        'unsigned' => TRUE,
+      ],
+      'destid3' => [
+        'type' => 'varchar_ascii',
+        'not null' => FALSE,
+        'length' => '12',
+      ],
+      'source_row_status' => [
+        'type' => 'int',
+        'not null' => TRUE,
+        'size' => 'tiny',
+        'default' => '0',
+        'unsigned' => TRUE,
+      ],
+      'rollback_action' => [
+        'type' => 'int',
+        'not null' => TRUE,
+        'size' => 'tiny',
+        'default' => '0',
+        'unsigned' => TRUE,
+      ],
+      'last_imported' => [
+        'type' => 'int',
+        'not null' => TRUE,
+        'size' => 'normal',
+        'default' => '0',
+        'unsigned' => TRUE,
+      ],
+      'hash' => [
+        'type' => 'varchar',
+        'not null' => FALSE,
+        'length' => '64',
+      ],
+    ];
+    $values = [
+      'source_ids_hash' => '123',
+      'sourceid1' => '4242',
+      'sourceid2' => '4242',
+      'sourceid3' => 'en',
+      'destid1' => '4242',
+      'destid2' => '4242',
+      'destid3' => 'en',
+      'source_row_status' => '1',
+      'rollback_action' => '1',
+      'last_imported' => time(),
+      'hash' => 'abc',
+    ];
+    $indexes = [
+      'source' => [
+        'sourceid1',
+        'sourceid2',
+        'sourceid3',
+      ],
+    ];
+
+    // Remove keys not used.
+    if ($type == NodeMigrateType::NODE_MIGRATE_TYPE_CLASSIC) {
+      $keys = ['sourceid2', 'sourceid3', 'destid2', 'destid3'];
+      foreach ($keys as $key) {
+        unset($fields[$key]);
+        unset($values[$key]);
+        if (strstr($key, 'sourceid')) {
+          $index_key = substr($key, -1) - 1;
+          unset($indexes['source'][$index_key]);
+        }
+      }
+    }
+    $connection = \Drupal::database();
+    $connection->schema()->createTable($name, [
+      'fields' => $fields,
+      'primary key' => [
+        'source_ids_hash',
+      ],
+      'indexes' => $indexes,
+      'mysql_character_set' => 'utf8mb4',
+    ]);
+
+    $field_names = array_keys($fields);
+    $connection->insert($name)
+      ->fields($field_names)
+      ->values($values)
+      ->execute();
+  }
+
+}
diff --git a/core/modules/migrate_drupal_ui/src/Form/IdConflictForm.php b/core/modules/migrate_drupal_ui/src/Form/IdConflictForm.php
index ec58b94081..5d326634fe 100644
--- a/core/modules/migrate_drupal_ui/src/Form/IdConflictForm.php
+++ b/core/modules/migrate_drupal_ui/src/Form/IdConflictForm.php
@@ -4,6 +4,7 @@
 
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\migrate\Audit\IdAuditor;
+use Drupal\migrate\Audit\NodeCompleteIdAuditor;
 use Drupal\migrate\Plugin\migrate\destination\EntityContentBase;
 
 /**
@@ -39,6 +40,8 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     $translated_content_conflicts = $content_conflicts = [];
 
     $results = (new IdAuditor())->auditMultiple($migrations);
+    $node_complete_results = (new NodeCompleteIdAuditor())->auditMultiple($migrations);
+    $results += $node_complete_results;
 
     /** @var \Drupal\migrate\Audit\AuditResult $result */
     foreach ($results as $result) {
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeExecuteTestBase.php b/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeExecuteTestBase.php
index 7038e7b378..7cb4ee2743 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeExecuteTestBase.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeExecuteTestBase.php
@@ -112,8 +112,6 @@ public function testMigrateUpgradeExecute() {
       'file',
       'taxonomy_term',
       'user',
-      'comment',
-      'node',
     ];
     $this->assertIdConflict($session, $entity_types);
 
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeTestBase.php b/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeTestBase.php
index db75e036a8..0a406c6850 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeTestBase.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeTestBase.php
@@ -196,12 +196,13 @@ protected function assertReviewPage(WebAssert $session, array $available_paths,
    * @param array $entity_types
    *   An array of entity types
    */
-  protected function assertIdConflict(WebAssert $session, $entity_types) {
+  protected function assertIdConflict(WebAssert $session, array $entity_types) {
     /** @var \Drupal\ $entity_type_manager */
     $entity_type_manager = \Drupal::service('entity_type.manager');
 
     $session->pageTextContains('WARNING: Content may be overwritten on your new site.');
     $session->pageTextContains('There is conflicting content of these types:');
+    $this->assertNotEmpty($entity_types, 'No entity types provided to \Drupal\Tests\migrate_drupal_ui\Functional\MigrateUpgradeTestBase::assertIdConflict()');
     foreach ($entity_types as $entity_type) {
       $label = $entity_type_manager->getDefinition($entity_type)->getPluralLabel();
       $session->pageTextContains($label);
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/NoMultilingualReviewPageTestBase.php b/core/modules/migrate_drupal_ui/tests/src/Functional/NoMultilingualReviewPageTestBase.php
index d5e41ed293..ec51ab9f36 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/NoMultilingualReviewPageTestBase.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/NoMultilingualReviewPageTestBase.php
@@ -23,8 +23,9 @@ public function testMigrateUpgradeReviewPage() {
     $session->pageTextContains('WARNING: Content may be overwritten on your new site.');
     $session->pageTextContains('There is conflicting content of these types:');
     $session->pageTextContains('taxonomy terms');
-    $session->pageTextNotContains('There is translated content of these types:');
-    $session->pageTextNotContains('custom menu links');
+    $session->pageTextContains('There is translated content of these types:');
+    $session->pageTextContains('content item revisions');
+    $session->pageTextContains('content items');
 
     $this->drupalPostForm(NULL, [], t('I acknowledge I may lose data. Continue anyway.'));
     $session->statusCodeEquals(200);
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MultilingualReviewPageTest.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MultilingualReviewPageTest.php
index dc3a6d68eb..5ea6badda6 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MultilingualReviewPageTest.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MultilingualReviewPageTest.php
@@ -109,6 +109,7 @@ protected function getAvailablePaths() {
       'jquery_ui',
       'link',
       'menu',
+      'node',
       'nodeaccess',
       'nodereference',
       'number',
@@ -158,7 +159,6 @@ protected function getMissingPaths() {
       'i18nviews',
       'locale',
       'migrate_status_active_test',
-      'node',
       'views',
     ];
   }
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/NodeClassicTest.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/NodeClassicTest.php
new file mode 100644
index 0000000000..93aed6dbcd
--- /dev/null
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/NodeClassicTest.php
@@ -0,0 +1,131 @@
+<?php
+
+namespace Drupal\Tests\migrate_drupal_ui\Functional\d6;
+
+use Drupal\migrate_drupal\NodeMigrateType;
+use Drupal\Tests\migrate_drupal\Traits\NodeMigrateTypeTestTrait;
+use Drupal\Tests\migrate_drupal_ui\Functional\MigrateUpgradeExecuteTestBase;
+
+/**
+ * Tests the classic node migration runs.
+ *
+ * The classic node migration will run and not the complete node migration
+ * when there is a pre-existing classic node migrate map table.
+ *
+ * @group migrate_drupal_ui
+ */
+class NodeClassicTest extends MigrateUpgradeExecuteTestBase {
+
+  use NodeMigrateTypeTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = [
+    'language',
+    'content_translation',
+    'config_translation',
+    'migrate_drupal_ui',
+    'telephone',
+    'aggregator',
+    'book',
+    'forum',
+    'statistics',
+    // Required for translation migrations.
+    'migrate_drupal_multilingual',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->loadFixture(drupal_get_path('module', 'migrate_drupal') . '/tests/fixtures/drupal6.php');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getSourceBasePath() {
+    return __DIR__ . '/files';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getEntityCounts() {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getEntityCountsIncremental() {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getAvailablePaths() {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getMissingPaths() {
+  }
+
+  /**
+   * Tests ID Conflict form.
+   */
+  public function testMigrateUpgradeExecute() {
+    // Add a node classic migrate table to d8.
+    $this->makeNodeMigrateMapTable(NodeMigrateType::NODE_MIGRATE_TYPE_CLASSIC, '6');
+
+    $connection_options = $this->sourceDatabase->getConnectionOptions();
+    $this->drupalGet('/upgrade');
+    $session = $this->assertSession();
+    $session->responseContains('Upgrade a site by importing its files and the data from its database into a clean and empty new install of Drupal 8.');
+
+    $this->drupalPostForm(NULL, [], t('Continue'));
+    $session->pageTextContains('Provide credentials for the database of the Drupal site you want to upgrade.');
+    $session->fieldExists('mysql[host]');
+
+    $driver = $connection_options['driver'];
+    $connection_options['prefix'] = $connection_options['prefix']['default'];
+
+    // Use the driver connection form to get the correct options out of the
+    // database settings. This supports all of the databases we test against.
+    $drivers = drupal_get_database_types();
+    $form = $drivers[$driver]->getFormOptions($connection_options);
+    $connection_options = array_intersect_key($connection_options, $form + $form['advanced_options']);
+    $version = $this->getLegacyDrupalVersion($this->sourceDatabase);
+    $edit = [
+      $driver => $connection_options,
+      'source_private_file_path' => $this->getSourceBasePath(),
+      'version' => $version,
+    ];
+    $edit['d6_source_base_path'] = $this->getSourceBasePath();
+    if (count($drivers) !== 1) {
+      $edit['driver'] = $driver;
+    }
+    $edits = $this->translatePostValues($edit);
+
+    // Start the upgrade process.
+    $this->drupalGet('/upgrade');
+    $session->responseContains('Upgrade a site by importing its files and the data from its database into a clean and empty new install of Drupal 8.');
+
+    $this->drupalPostForm(NULL, [], t('Continue'));
+    $session->pageTextContains('Provide credentials for the database of the Drupal site you want to upgrade.');
+    $session->fieldExists('mysql[host]');
+
+    // When the Credential form is submitted the migrate map tables are created.
+    $this->drupalPostForm(NULL, $edits, t('Review upgrade'));
+
+    // Confirm there are only classic node migration map tables. This shows
+    // that only the classic migration will run.
+    $results = $this->nodeMigrateMapTableCount('6');
+    $this->assertSame(13, $results['node']);
+    $this->assertSame(0, $results['node_complete']);
+  }
+
+}
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/Upgrade6Test.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/Upgrade6Test.php
index 0731f12aff..b0061da3ff 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/Upgrade6Test.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/Upgrade6Test.php
@@ -37,11 +37,28 @@ class Upgrade6Test extends MigrateUpgradeExecuteTestBase {
     'migrate_drupal_multilingual',
   ];
 
+  /**
+   * The entity storage for node.
+   *
+   * @var \Drupal\Core\Entity\EntityStorageInterface
+   */
+  protected $nodeStorage;
+
   /**
    * {@inheritdoc}
    */
   protected function setUp() {
     parent::setUp();
+
+    // Delete the existing content made to test the ID Conflict form. Migrations
+    // are to be done on a site without content. The test of the ID Conflict
+    // form is being moved to its own issue which will remove the deletion
+    // of the created nodes.
+    // See https://www.drupal.org/project/drupal/issues/3087061.
+    $this->nodeStorage = $this->container->get('entity_type.manager')
+      ->getStorage('node');
+    $this->nodeStorage->delete($this->nodeStorage->loadMultiple());
+
     $this->loadFixture(drupal_get_path('module', 'migrate_drupal') . '/tests/fixtures/drupal6.php');
   }
 
@@ -145,6 +162,7 @@ protected function getAvailablePaths() {
       'imagecache',
       'imagefield',
       'menu',
+      'node',
       'nodereference',
       'optionwidgets',
       'path',
@@ -180,7 +198,6 @@ protected function getMissingPaths() {
       'i18nstrings',
       'i18ntaxonomy',
       'locale',
-      'node',
     ];
   }
 
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MultilingualReviewPageTest.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MultilingualReviewPageTest.php
index b5fdc0239b..c25ec43223 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MultilingualReviewPageTest.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MultilingualReviewPageTest.php
@@ -103,6 +103,7 @@ protected function getAvailablePaths() {
       'locale',
       'menu',
       'number',
+      'node',
       'openid',
       'options',
       'overlay',
@@ -168,7 +169,6 @@ protected function getMissingPaths() {
       'i18n_translation',
       'i18n_user',
       'i18n_variable',
-      'node',
       'picture',
       'migrate_status_active_test',
       'variable',
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7Test.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7Test.php
index 8b99c67112..86600e9ba0 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7Test.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7Test.php
@@ -39,11 +39,28 @@ class Upgrade7Test extends MigrateUpgradeExecuteTestBase {
     'migrate_drupal_multilingual',
   ];
 
+  /**
+   * The entity storage for node.
+   *
+   * @var \Drupal\Core\Entity\EntityStorageInterface
+   */
+  protected $nodeStorage;
+
   /**
    * {@inheritdoc}
    */
   protected function setUp() {
     parent::setUp();
+
+    // Delete the existing content made to test the ID Conflict form. Migrations
+    // are to be done on a site without content. The test of the ID Conflict
+    // form is being moved to its own issue which will remove the deletion
+    // of the created nodes.
+    // See https://www.drupal.org/project/drupal/issues/3087061.
+    $this->nodeStorage = $this->container->get('entity_type.manager')
+      ->getStorage('node');
+    $this->nodeStorage->delete($this->nodeStorage->loadMultiple());
+
     $this->loadFixture(drupal_get_path('module', 'migrate_drupal') . '/tests/fixtures/drupal7.php');
   }
 
@@ -67,21 +84,21 @@ protected function getEntityCounts() {
       'comment' => 4,
       // The 'standard' profile provides the 'comment' comment type, and the
       // migration creates 6 comment types, one per node type.
-      'comment_type' => 7,
+      'comment_type' => 8,
       // Module 'language' comes with 'en', 'und', 'zxx'. Migration adds 'is'
       // and 'fr'.
       'configurable_language' => 5,
       'contact_form' => 3,
       'contact_message' => 0,
       'editor' => 2,
-      'field_config' => 76,
-      'field_storage_config' => 58,
+      'field_config' => 77,
+      'field_storage_config' => 59,
       'file' => 3,
       'filter_format' => 7,
       'image_style' => 6,
       'language_content_settings' => 24,
-      'node' => 6,
-      'node_type' => 6,
+      'node' => 7,
+      'node_type' => 7,
       'rdf_mapping' => 8,
       'search_page' => 2,
       'shortcut' => 6,
@@ -97,9 +114,9 @@ protected function getEntityCounts() {
       'menu_link_content' => 12,
       'view' => 16,
       'date_format' => 11,
-      'entity_form_display' => 20,
+      'entity_form_display' => 22,
       'entity_form_mode' => 1,
-      'entity_view_display' => 31,
+      'entity_view_display' => 33,
       'entity_view_mode' => 14,
       'base_field_override' => 4,
     ];
@@ -149,6 +166,7 @@ protected function getAvailablePaths() {
       'link',
       'list',
       'menu',
+      'node',
       'number',
       'options',
       'path',
@@ -190,7 +208,6 @@ protected function getMissingPaths() {
       'i18n_taxonomy',
       'i18n_translation',
       'locale',
-      'node',
       'variable',
       'variable_realm',
       'variable_store',
diff --git a/core/modules/node/migrations/d6_node_complete.yml b/core/modules/node/migrations/d6_node_complete.yml
new file mode 100644
index 0000000000..84ef465bec
--- /dev/null
+++ b/core/modules/node/migrations/d6_node_complete.yml
@@ -0,0 +1,58 @@
+# Migrates all revisions and all revision translations.
+id: d6_node_complete
+label: Node Complete
+audit: true
+migration_tags:
+  - Drupal 6
+  - Content
+class: Drupal\node\Plugin\migrate\D6NodeTranslation
+deriver: Drupal\node\Plugin\migrate\D6NodeDeriver
+source:
+  plugin: d6_node_complete
+process:
+  # If you are using this file to build a custom migration consider removing
+  # the nid and vid fields to allow incremental migrations.
+  # In D6, nodes always have a tnid, but it's zero for untranslated nodes.
+  # We normalize it to equal the nid in that case.
+  # @see \Drupal\node\Plugin\migrate\source\d6\Node::prepareRow().
+  nid: tnid
+  vid: vid
+  langcode:
+    plugin: default_value
+    source: language
+    default_value: "und"
+  title: title
+  uid: node_uid
+  status: status
+  created: created
+  changed: timestamp
+  promote: promote
+  sticky: sticky
+  'body/format':
+    plugin: migration_lookup
+    migration: d6_filter_format
+    source: format
+  'body/value': body
+  'body/summary': teaser
+  revision_uid: revision_uid
+  revision_log: log
+  revision_timestamp: timestamp
+  content_translation_source: source_langcode
+  #  unmapped d6 fields.
+  #  translate
+  #  moderate
+  #  comment
+destination:
+  plugin: entity_complete:node
+  translations: true
+migration_dependencies:
+  required:
+    - d6_user
+    - d6_node_type
+    - d6_node_settings
+    - d6_filter_format
+    - language
+  optional:
+    - d6_field_instance_widget_settings
+    - d6_field_formatter_settings
+    - d6_upload_field_instance
diff --git a/core/modules/node/migrations/d7_node_complete.yml b/core/modules/node/migrations/d7_node_complete.yml
new file mode 100644
index 0000000000..fb52819d59
--- /dev/null
+++ b/core/modules/node/migrations/d7_node_complete.yml
@@ -0,0 +1,48 @@
+# Migrates all revisions and all revision translations.
+id: d7_node_complete
+label: Node complete
+audit: true
+migration_tags:
+  - Drupal 7
+  - Content
+class: Drupal\node\Plugin\migrate\D7NodeTranslation
+deriver: Drupal\node\Plugin\migrate\D7NodeDeriver
+source:
+  plugin: d7_node_complete
+process:
+  # If you are using this file to build a custom migration consider removing
+  # the nid and vid fields to allow incremental migrations.
+  # In D7, nodes always have a tnid, but it's zero for untranslated nodes.
+  # We normalize it to equal the nid in that case.
+  # @see \Drupal\node\Plugin\migrate\source\d7\Node::prepareRow().
+  nid: tnid
+  vid: vid
+  langcode:
+    plugin: default_value
+    source: language
+    default_value: "und"
+  title: title
+  uid: node_uid
+  status: status
+  created: created
+  changed: timestamp
+  promote: promote
+  sticky: sticky
+  revision_uid: revision_uid
+  revision_log: log
+  revision_timestamp: timestamp
+  content_translation_source: source_langcode
+  #  unmapped d6 fields.
+  #  translate
+  #  comment
+destination:
+  plugin: entity_complete:node
+  translations: true
+migration_dependencies:
+  required:
+    - d7_user
+    - d7_node_type
+    - language
+  optional:
+    - d7_field_instance
+    - d7_comment_field_instance
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 4899ddce67..64d4e6c539 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -26,6 +26,7 @@
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
 use Drupal\language\ConfigurableLanguageInterface;
+use Drupal\migrate_drupal\NodeMigrateType;
 use Drupal\node\Entity\Node;
 use Drupal\node\Entity\NodeType;
 use Drupal\node\NodeInterface;
@@ -1461,3 +1462,30 @@ function node_comment_delete($comment) {
 function node_config_translation_info_alter(&$info) {
   $info['node_type']['class'] = 'Drupal\node\ConfigTranslation\NodeTypeMapper';
 }
+
+/**
+ * Implements hook_migration_plugins_alter().
+ */
+function node_migration_plugins_alter(array &$definitions) {
+  // If this is complete node migration then for of migrations, except the
+  // classic node migrations, replace the dependency on a classic node migration
+  // with a dependency on the complete node migration.
+  if ((new NodeMigrateType)->getNodeMigrateType($definitions, NULL) == NodeMigrateType::NODE_MIGRATE_TYPE_COMPLETE) {
+    // Anonymous function to replace classic node migration plugin IDs with the
+    // node complete plugin ID.
+    $replace_with_complete_migration = function (&$value) {
+      if (is_string($value)) {
+        $value = preg_replace('/d([67])_(node|node_translation|node_revision|node_entity_translation)($|:.*)/', 'd$1_node_complete$3', $value);
+      }
+      return $value;
+    };
+
+    foreach ($definitions as &$definition) {
+      $is_node_classic_migration = preg_match('/d([67])_(node|node_translation|node_revision|node_entity_translation)($|:.*)/', $definition['id']);
+      if (!$is_node_classic_migration && isset($definition['migration_dependencies'])) {
+        array_walk_recursive($definition['migration_dependencies'], $replace_with_complete_migration);
+      }
+    }
+
+  }
+}
diff --git a/core/modules/node/src/Plugin/migrate/source/d6/NodeComplete.php b/core/modules/node/src/Plugin/migrate/source/d6/NodeComplete.php
new file mode 100644
index 0000000000..96d6d29db9
--- /dev/null
+++ b/core/modules/node/src/Plugin/migrate/source/d6/NodeComplete.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace Drupal\node\Plugin\migrate\source\d6;
+
+/**
+ * Gets all node revisions from the source, including translation revisions.
+ *
+ * @MigrateSource(
+ *   id = "d6_node_complete",
+ *   source_module = "node"
+ * )
+ */
+class NodeComplete extends NodeRevision {
+
+  /**
+   * The join options between the node and the node_revisions_table.
+   */
+  const JOIN = 'n.nid = nr.nid';
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+    $query = parent::query();
+    $query->orderBy('nr.vid');
+    return $query;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    return [
+      'nid' => [
+        'type' => 'integer',
+        'alias' => 'n',
+      ],
+      'vid' => [
+        'type' => 'integer',
+        'alias' => 'nr',
+      ],
+      'language' => [
+        'type' => 'string',
+        'alias' => 'n',
+      ],
+    ];
+  }
+
+}
diff --git a/core/modules/node/src/Plugin/migrate/source/d7/Node.php b/core/modules/node/src/Plugin/migrate/source/d7/Node.php
index 4a8cce4408..c96d48330a 100644
--- a/core/modules/node/src/Plugin/migrate/source/d7/Node.php
+++ b/core/modules/node/src/Plugin/migrate/source/d7/Node.php
@@ -115,6 +115,13 @@ public function prepareRow(Row $row) {
     $source_language = $this->getEntityTranslationSourceLanguage('node', $nid);
     $language = $entity_translatable && $source_language ? $source_language : $row->getSourceProperty('language');
 
+    // If this is using d7_node_complete source plugin and this is a node
+    // using entity translation then get the set the language of this revision
+    // to the entity translation language.
+    if ($row->getSourceProperty('etr_created')) {
+      $language = $row->getSourceProperty('language');
+    }
+
     // Get Field API field values.
     foreach ($this->getFields('node', $type) as $field_name => $field) {
       // Ensure we're using the right language if the entity and the field are
diff --git a/core/modules/node/src/Plugin/migrate/source/d7/NodeComplete.php b/core/modules/node/src/Plugin/migrate/source/d7/NodeComplete.php
new file mode 100644
index 0000000000..75fbf52236
--- /dev/null
+++ b/core/modules/node/src/Plugin/migrate/source/d7/NodeComplete.php
@@ -0,0 +1,98 @@
+<?php
+
+namespace Drupal\node\Plugin\migrate\source\d7;
+
+use Drupal\Core\Database\Query\SelectInterface;
+use Drupal\migrate\Row;
+
+/**
+ * Gets all node revisions from the source, including translation revisions.
+ *
+ * @MigrateSource(
+ *   id = "d7_node_complete",
+ *   source_module = "node"
+ * )
+ */
+class NodeComplete extends NodeRevision {
+
+  /**
+   * The join options between the node and the node_revisions_table.
+   */
+  const JOIN = 'n.nid = nr.nid';
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+    $query = parent::query();
+    $query->orderBy('nr.vid');
+
+    // Get any entity translation revision data.
+    if ($this->getDatabase()->schema()
+      ->tableExists('entity_translation_revision')) {
+      $query->leftJoin('entity_translation_revision', 'etr', 'nr.nid = etr.entity_id AND nr.vid=etr.revision_id');
+      $query->fields('etr', [
+        'entity_type',
+        'entity_id',
+        'revision_id',
+        'source',
+        'translate',
+      ]);
+      $conditions = $query->orConditionGroup();
+      $conditions->condition('etr.entity_type', 'node');
+      $conditions->isNull('etr.entity_type');
+      $query->condition($conditions);
+      $query->addExpression("COALESCE(etr.language, n.language)", 'language');
+      $query->addField('etr', 'uid', 'etr_uid');
+      $query->addField('etr', 'status', 'etr_status');
+      $query->addField('etr', 'created', 'etr_created');
+      $query->addField('etr', 'changed', 'etr_changed');
+
+      $query->orderBy('revision_id');
+      $query->orderBy('language');
+    }
+    return $query;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function prepareRow(Row $row) {
+    // Override properties when this is an entity translation revision. The tnid
+    // will be set in d7_node source plugin to the value of 'nid'.
+    if ($row->getSourceProperty('etr_created')) {
+      $row->setSourceProperty('vid', $row->getSourceProperty('revision_id'));
+      $row->setSourceProperty('created', $row->getSourceProperty('etr_created'));
+      $row->setSourceProperty('timestamp', $row->getSourceProperty('etr_changed'));
+      $row->setSourceProperty('revision_uid', $row->getSourceProperty('etr_uid'));
+      $row->setSourceProperty('source_langcode', $row->getSourceProperty('source'));
+    }
+    parent::prepareRow($row);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    return [
+      'nid' => [
+        'type' => 'integer',
+        'alias' => 'n',
+      ],
+      'vid' => [
+        'type' => 'integer',
+        'alias' => 'nr',
+      ],
+      'language' => [
+        'type' => 'string',
+        'alias' => 'n',
+      ],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function handleTranslations(SelectInterface $query) {}
+
+}
diff --git a/core/modules/node/tests/src/Kernel/Migrate/MigrationPluginAlterTest.php b/core/modules/node/tests/src/Kernel/Migrate/MigrationPluginAlterTest.php
new file mode 100644
index 0000000000..c1091c3f68
--- /dev/null
+++ b/core/modules/node/tests/src/Kernel/Migrate/MigrationPluginAlterTest.php
@@ -0,0 +1,168 @@
+<?php
+
+namespace Drupal\Tests\node\Kernel\Migrate;
+
+use Drupal\migrate_drupal\NodeMigrateType;
+use Drupal\Tests\migrate\Kernel\MigrateTestBase;
+use Drupal\Tests\migrate_drupal\Traits\NodeMigrateTypeTestTrait;
+
+/**
+ * Tests node_migrations_plugin_alter.
+ *
+ * @group node
+ */
+class MigrationPluginAlterTest extends MigrateTestBase {
+
+  use NodeMigrateTypeTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['migrate_drupal', 'node'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->setupDb();
+  }
+
+  /**
+   * Tests migrate_drupal_migrations_plugin_alter.
+   *
+   * @param string $type
+   *   The type of node migration, 'classic' or 'complete'.
+   * @param array $migration_definitions
+   *   An array of migration definitions.
+   * @param array $expected
+   *   The expected results.
+   *
+   * @dataProvider providerMigrationPluginAlter
+   */
+  public function testMigrationPluginAlter($type, array $migration_definitions, array $expected) {
+    // Version 6 is used so that term node migrations are tested.
+    $this->makeNodeMigrateMapTable($type, '7');
+    node_migration_plugins_alter($migration_definitions);
+    $this->assertSame($expected, $migration_definitions);
+  }
+
+  /**
+   * Data provider for testMigrationPluginAlter().
+   */
+  public function providerMigrationPluginAlter() {
+    $tests = [];
+
+    $migrations = [
+      // The 'system_site' migration is needed to get the legacy Drupal version.
+      'system_site' => [
+        'id' => 'system_site',
+        'source' => [
+          'plugin' => 'variable',
+          'variables' => [
+            'site_name',
+            'site_mail',
+          ],
+          'source_module' => 'system',
+        ],
+        'process' => [],
+      ],
+      'no_dependencies_not_altered' => [
+        'id' => 'no_dependencies_not_altered',
+        'no_dependencies' => 'test',
+        'process' => [
+          'nid' => 'nid',
+        ],
+      ],
+      'dependencies_altered_if_complete' => [
+        'id' => 'test',
+        'migration_dependencies' => [
+          'required' => [
+            'd7_node',
+          ],
+          'optional' => [
+            'd7_node_translation',
+          ],
+        ],
+      ],
+      'dependencies_not_altered' => [
+        'id' => 'd7_node',
+        'migration_dependencies' => [
+          'required' => [
+            'd7_node',
+          ],
+          'optional' => [
+            'd7_node_translation',
+          ],
+        ],
+      ],
+    ];
+
+    // Test migrations are not altered when classic node migrations is in use.
+    $tests[0]['type'] = NodeMigrateType::NODE_MIGRATE_TYPE_CLASSIC;
+    $tests[0]['migrations'] = $migrations;
+    $tests[0]['expected_data'] = $tests[0]['migrations'];
+
+    // Test migrations are altered when complete node migrations is in use.
+    $tests[1] = $tests[0];
+    $tests[1]['type'] = NodeMigrateType::NODE_MIGRATE_TYPE_COMPLETE;
+    $tests[1]['expected_data']['dependencies_altered_if_complete']['migration_dependencies'] = [
+      'required' => [
+        'd7_node_complete',
+      ],
+      'optional' => [
+        'd7_node_complete',
+      ],
+    ];
+    return $tests;
+  }
+
+  /**
+   * Creates data in the source database.
+   */
+  protected function setupDb() {
+    $this->sourceDatabase->schema()->createTable('system', [
+      'fields' => [
+        'name' => [
+          'type' => 'varchar',
+          'not null' => TRUE,
+          'length' => '255',
+          'default' => '',
+        ],
+        'type' => [
+          'type' => 'varchar',
+          'not null' => TRUE,
+          'length' => '255',
+          'default' => '',
+        ],
+        'status' => [
+          'type' => 'int',
+          'not null' => TRUE,
+          'size' => 'normal',
+          'default' => '0',
+        ],
+        'schema_version' => [
+          'type' => 'int',
+          'not null' => TRUE,
+          'size' => 'normal',
+          'default' => '-1',
+        ],
+      ],
+    ]);
+    $this->sourceDatabase->insert('system')
+      ->fields([
+        'name',
+        'type',
+        'status',
+        'schema_version',
+      ])
+      ->values([
+        'name' => 'system',
+        'type' => 'module',
+        'status' => '1',
+        'schema_version' => '7001',
+      ])
+      ->execute();
+  }
+
+}
diff --git a/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeCompleteTest.php b/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeCompleteTest.php
new file mode 100644
index 0000000000..1e769653c7
--- /dev/null
+++ b/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeCompleteTest.php
@@ -0,0 +1,1252 @@
+<?php
+
+namespace Drupal\Tests\node\Kernel\Migrate\d6;
+
+use Drupal\node\NodeInterface;
+use Drupal\Tests\file\Kernel\Migrate\d6\FileMigrationTestTrait;
+use Drupal\Tests\migrate_drupal\Traits\CreateTestContentEntitiesTrait;
+
+/**
+ * Test class for a complete node migration for Drupal 6.
+ *
+ * @group migrate_drupal_6
+ */
+class MigrateNodeCompleteTest extends MigrateNodeTestBase {
+
+  use FileMigrationTestTrait;
+  use CreateTestContentEntitiesTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = [
+    'language',
+    'content_translation',
+    'menu_ui',
+    // Required for translation migrations.
+    'migrate_drupal_multilingual',
+  ];
+
+  /**
+   * The entity storage for node.
+   *
+   * @var \Drupal\Core\Entity\EntityStorageInterface
+   */
+  protected $nodeStorage;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->setUpMigratedFiles();
+
+    $this->createContent();
+
+    $this->nodeStorage = $this->container->get('entity_type.manager')
+      ->getStorage('node');
+    $this->nodeStorage->delete($this->nodeStorage->loadMultiple());
+
+    $this->installSchema('file', ['file_usage']);
+    $this->executeMigrations([
+      'language',
+      'd6_language_content_settings',
+      'd6_node_complete',
+    ]);
+  }
+
+  /**
+   * Tests the complete node migration.
+   */
+  public function testNodeCompleteMigration() {
+    $db = \Drupal::database();
+    $this->assertEquals($this->expectedNodeFieldRevisionTable(), $db->select('node_field_revision', 'nr')
+      ->fields('nr')
+      ->execute()
+      ->fetchAll(\PDO::FETCH_ASSOC));
+    $this->assertEquals($this->expectedNodeFieldDataTable(), $db->select('node_field_data', 'nr')
+      ->fields('nr')
+      ->execute()
+      ->fetchAll(\PDO::FETCH_ASSOC));
+
+    // Now load and test each revision, including the field 'field_text_plain'
+    // which has text reflecting the revision.
+    $data = $this->expectedRevisionEntityData()[0];
+    foreach ($this->expectedNodeFieldRevisionTable() as $key => $revision) {
+      $this->assertRevision($revision, $data[$key]);
+    }
+  }
+
+  /**
+   * Asserts various aspects of a node revision.
+   *
+   * @param array $revision
+   *   An array of revision data matching a node_field_revision table row.
+   * @param array $data
+   *   An array of revision data.
+   */
+  protected function assertRevision(array $revision, array $data) {
+    /* @var  \Drupal\node\NodeInterface $actual */
+    $actual = $this->nodeStorage->loadRevision($revision['vid'])
+      ->getTranslation($revision['langcode']);
+    $this->assertInstanceOf(NodeInterface::class, $actual);
+    $this->assertSame($revision['title'], $actual->getTitle(), sprintf("Title '%s' does not match actual '%s' for revision '%d' langcode '%s'", $revision['title'], $actual->getTitle(), $revision['vid'], $revision['langcode']));
+    $this->assertSame($revision['revision_translation_affected'], $actual->get('revision_translation_affected')->value, sprintf("revision_translation_affected '%s' does not match actual '%s' for revision '%d' langcode '%s'", $revision['revision_translation_affected'], $actual->get('revision_translation_affected')->value, $revision['vid'], $revision['langcode']));
+
+    $this->assertSame($data['created'], $actual->getRevisionCreationTime(), sprintf("Creation time '%s' does not match actual '%s' for revision '%d' langcode '%s'", $data['created'], $actual->getRevisionCreationTime(), $revision['vid'], $revision['langcode']));
+    $this->assertSame($data['changed'], $actual->getChangedTime(), sprintf("Changed time '%s' does not match actual '%s' for revision '%d' langcode '%s'", $data['changed'], $actual->getChangedTime(), $revision['vid'], $revision['langcode']));
+    $this->assertSame($data['log'], $actual->getRevisionLogMessage(), sprintf("Revision log '%s' does not match actual '%s' for revision '%d' langcode '%s'", var_export($data['log'], TRUE), $actual->getRevisionLogMessage(), $revision['vid'], $revision['langcode']));
+  }
+
+  /**
+   * Provides the expected node_field_data table.
+   *
+   * @return array
+   *   The expected table rows.
+   */
+  protected function expectedNodeFieldDataTable() {
+    return [
+      0 =>
+        [
+          'nid' => '1',
+          'vid' => '2001',
+          'type' => 'story',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Test title rev 3',
+          'created' => '1390095702',
+          'changed' => '1420861423',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      1 =>
+        [
+          'nid' => '2',
+          'vid' => '3',
+          'type' => 'story',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Test title rev 3',
+          'created' => '1388271197',
+          'changed' => '1420718386',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      2 =>
+        [
+          'nid' => '3',
+          'vid' => '4',
+          'type' => 'test_planet',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Test page title rev 4',
+          'created' => '1388271527',
+          'changed' => '1390095701',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      3 =>
+        [
+          'nid' => '4',
+          'vid' => '6',
+          'type' => 'test_planet',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Node 4',
+          'created' => '1388271527',
+          'changed' => '1390095701',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      4 =>
+        [
+          'nid' => '5',
+          'vid' => '7',
+          'type' => 'test_planet',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Node 5',
+          'created' => '1388271527',
+          'changed' => '1390095701',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      5 =>
+        [
+          'nid' => '6',
+          'vid' => '8',
+          'type' => 'test_planet',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Node 6',
+          'created' => '1388271527',
+          'changed' => '1390095701',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      6 =>
+        [
+          'nid' => '7',
+          'vid' => '9',
+          'type' => 'test_planet',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Node 7',
+          'created' => '1388271527',
+          'changed' => '1390095701',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      7 =>
+        [
+          'nid' => '8',
+          'vid' => '10',
+          'type' => 'test_planet',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Node 8',
+          'created' => '1388271527',
+          'changed' => '1390095701',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      8 =>
+        [
+          'nid' => '9',
+          'vid' => '12',
+          'type' => 'story',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Once upon a time',
+          'created' => '1444671588',
+          'changed' => '1444671588',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      9 =>
+        [
+          'nid' => '10',
+          'vid' => '14',
+          'type' => 'page',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'The Real McCoy',
+          'created' => '1444238800',
+          'changed' => '1444238808',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => NULL,
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+      10 =>
+        [
+          'nid' => '10',
+          'vid' => '14',
+          'type' => 'page',
+          'langcode' => 'fr',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Le Vrai McCoy',
+          'created' => '1444239050',
+          'changed' => '1444239050',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '0',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+      11 =>
+        [
+          'nid' => '12',
+          'vid' => '23',
+          'type' => 'page',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'The Zulu People',
+          'created' => '1444239050',
+          'changed' => '1444239050',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '0',
+          'revision_translation_affected' => NULL,
+          'content_translation_source' => 'zu',
+          'content_translation_outdated' => '0',
+        ],
+      12 =>
+        [
+          'nid' => '12',
+          'vid' => '23',
+          'type' => 'page',
+          'langcode' => 'fr',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Le peuple zoulou',
+          'created' => '1520613038',
+          'changed' => '1520613305',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '0',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => 'zu',
+          'content_translation_outdated' => '0',
+        ],
+      13 =>
+        [
+          'nid' => '12',
+          'vid' => '23',
+          'type' => 'page',
+          'langcode' => 'zu',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Abantu zulu',
+          'created' => '1444238800',
+          'changed' => '1444238808',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => NULL,
+          'content_translation_source' => 'zu',
+          'content_translation_outdated' => '0',
+        ],
+      14 =>
+        [
+          'nid' => '14',
+          'vid' => '17',
+          'type' => 'company',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'United Federation of Planets',
+          'created' => '1493066668',
+          'changed' => '1493066668',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      15 =>
+        [
+          'nid' => '15',
+          'vid' => '18',
+          'type' => 'company',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Klingon Empire',
+          'created' => '1493066677',
+          'changed' => '1493066677',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      16 =>
+        [
+          'nid' => '16',
+          'vid' => '19',
+          'type' => 'company',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Romulan Empire',
+          'created' => '1493066684',
+          'changed' => '1493066684',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      17 =>
+        [
+          'nid' => '17',
+          'vid' => '20',
+          'type' => 'company',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Ferengi Commerce Authority',
+          'created' => '1493066693',
+          'changed' => '1493066693',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      18 =>
+        [
+          'nid' => '18',
+          'vid' => '21',
+          'type' => 'employee',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Ambassador Sarek',
+          'created' => '1493066711',
+          'changed' => '1494966544',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      19 =>
+        [
+          'nid' => '19',
+          'vid' => '22',
+          'type' => 'forum',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'New Forum Topic',
+          'created' => '1501955771',
+          'changed' => '1501955771',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      20 =>
+        [
+          'nid' => '21',
+          'vid' => '2003',
+          'type' => 'employee',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'John Smith - EN',
+          'created' => '1534014650',
+          'changed' => '1534014650',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => NULL,
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+      21 =>
+        [
+          'nid' => '21',
+          'vid' => '2003',
+          'type' => 'employee',
+          'langcode' => 'fr',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'John Smith - FR',
+          'created' => '1534014687',
+          'changed' => '1534014687',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '0',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+    ];
+  }
+
+  /**
+   * Provides the expected node_field_revision table.
+   *
+   * @return array
+   *   The table.
+   */
+  protected function expectedNodeFieldRevisionTable() {
+    return [
+      0 =>
+        [
+          'nid' => '1',
+          'vid' => '1',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Test title',
+          'created' => '1390095702',
+          'changed' => '1390095702',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      1 =>
+        [
+          'nid' => '2',
+          'vid' => '3',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Test title rev 3',
+          'created' => '1388271197',
+          'changed' => '1420718386',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      2 =>
+        [
+          'nid' => '3',
+          'vid' => '4',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Test page title rev 4',
+          'created' => '1388271527',
+          'changed' => '1390095701',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      3 =>
+        [
+          'nid' => '1',
+          'vid' => '5',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Test title rev 2',
+          'created' => '1390095702',
+          'changed' => '1390095703',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      4 =>
+        [
+          'nid' => '4',
+          'vid' => '6',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Node 4',
+          'created' => '1388271527',
+          'changed' => '1390095701',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      5 =>
+        [
+          'nid' => '5',
+          'vid' => '7',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Node 5',
+          'created' => '1388271527',
+          'changed' => '1390095701',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      6 =>
+        [
+          'nid' => '6',
+          'vid' => '8',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Node 6',
+          'created' => '1388271527',
+          'changed' => '1390095701',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      7 =>
+        [
+          'nid' => '7',
+          'vid' => '9',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Node 7',
+          'created' => '1388271527',
+          'changed' => '1390095701',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      8 =>
+        [
+          'nid' => '8',
+          'vid' => '10',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Node 8',
+          'created' => '1388271527',
+          'changed' => '1390095701',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      9 =>
+        [
+          'nid' => '9',
+          'vid' => '11',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Node 9',
+          'created' => '1444671588',
+          'changed' => '1390095701',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      10 =>
+        [
+          'nid' => '9',
+          'vid' => '12',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Once upon a time',
+          'created' => '1444671588',
+          'changed' => '1444671588',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      11 =>
+        [
+          'nid' => '10',
+          'vid' => '13',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'The Real McCoy',
+          'created' => '1444238800',
+          'changed' => '1444238808',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+      12 =>
+        [
+          'nid' => '10',
+          'vid' => '14',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'The Real McCoy',
+          'created' => '1444238800',
+          'changed' => '1444238808',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => NULL,
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+      13 =>
+        [
+          'nid' => '10',
+          'vid' => '14',
+          'langcode' => 'fr',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Le Vrai McCoy',
+          'created' => '1444239050',
+          'changed' => '1444239050',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '0',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+      14 =>
+        [
+          'nid' => '12',
+          'vid' => '15',
+          'langcode' => 'zu',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Abantu zulu',
+          'created' => '1444238800',
+          'changed' => '1444238808',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => 'zu',
+          'content_translation_outdated' => '0',
+        ],
+      15 =>
+        [
+          'nid' => '12',
+          'vid' => '16',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'The Zulu People',
+          'created' => '1444239050',
+          'changed' => '1444239050',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '0',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => 'zu',
+          'content_translation_outdated' => '0',
+        ],
+      16 =>
+        [
+          'nid' => '12',
+          'vid' => '16',
+          'langcode' => 'zu',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Abantu zulu',
+          'created' => '1444238800',
+          'changed' => '1444238808',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => NULL,
+          'content_translation_source' => 'zu',
+          'content_translation_outdated' => '0',
+        ],
+      17 =>
+        [
+          'nid' => '14',
+          'vid' => '17',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'United Federation of Planets',
+          'created' => '1493066668',
+          'changed' => '1493066668',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      18 =>
+        [
+          'nid' => '15',
+          'vid' => '18',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Klingon Empire',
+          'created' => '1493066677',
+          'changed' => '1493066677',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      19 =>
+        [
+          'nid' => '16',
+          'vid' => '19',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Romulan Empire',
+          'created' => '1493066684',
+          'changed' => '1493066684',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      20 =>
+        [
+          'nid' => '17',
+          'vid' => '20',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Ferengi Commerce Authority',
+          'created' => '1493066693',
+          'changed' => '1493066693',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      21 =>
+        [
+          'nid' => '18',
+          'vid' => '21',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Ambassador Sarek',
+          'created' => '1493066711',
+          'changed' => '1494966544',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      22 =>
+        [
+          'nid' => '19',
+          'vid' => '22',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'New Forum Topic',
+          'created' => '1501955771',
+          'changed' => '1501955771',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      23 =>
+        [
+          'nid' => '12',
+          'vid' => '23',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'The Zulu People',
+          'created' => '1444239050',
+          'changed' => '1444239050',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '0',
+          'revision_translation_affected' => NULL,
+          'content_translation_source' => 'zu',
+          'content_translation_outdated' => '0',
+        ],
+      24 =>
+        [
+          'nid' => '12',
+          'vid' => '23',
+          'langcode' => 'fr',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Le peuple zoulou',
+          'created' => '1520613038',
+          'changed' => '1520613305',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '0',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => 'zu',
+          'content_translation_outdated' => '0',
+        ],
+      25 =>
+        [
+          'nid' => '12',
+          'vid' => '23',
+          'langcode' => 'zu',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Abantu zulu',
+          'created' => '1444238800',
+          'changed' => '1444238808',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => NULL,
+          'content_translation_source' => 'zu',
+          'content_translation_outdated' => '0',
+        ],
+      26 =>
+        [
+          'nid' => '1',
+          'vid' => '2001',
+          'langcode' => 'und',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Test title rev 3',
+          'created' => '1390095702',
+          'changed' => '1420861423',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      27 =>
+        [
+          'nid' => '21',
+          'vid' => '2002',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'John Smith - EN',
+          'created' => '1534014650',
+          'changed' => '1534014650',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+      28 =>
+        [
+          'nid' => '21',
+          'vid' => '2003',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'John Smith - EN',
+          'created' => '1534014650',
+          'changed' => '1534014650',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => NULL,
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+      29 =>
+        [
+          'nid' => '21',
+          'vid' => '2003',
+          'langcode' => 'fr',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'John Smith - FR',
+          'created' => '1534014687',
+          'changed' => '1534014687',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '0',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+    ];
+  }
+
+  /**
+   * Provides the expected node_field_revision table.
+   *
+   * @return array
+   *   Selected properties and fields on the revision.
+   */
+  protected function expectedRevisionEntityData() {
+    return [
+      $revision_data = [
+        // Node 1, revision 1, und.
+        0 =>
+          [
+            'log' => NULL,
+            'created' => '1390095702',
+            'changed' => '1390095702',
+          ],
+        // Node 2, revision 3, und.
+        1 =>
+          [
+            'log' => NULL,
+            'created' => '1420718386',
+            'changed' => '1420718386',
+          ],
+        // Node 3, revision 4, und.
+        2 =>
+          [
+            'log' => NULL,
+            'created' => '1390095701',
+            'changed' => '1390095701',
+          ],
+        // Node 1, revision 5, und.
+        3 =>
+          [
+            'log' => 'modified rev 2',
+            'created' => '1390095703',
+            'changed' => '1390095703',
+          ],
+        // Node 4, revision 6, und.
+        4 =>
+          [
+            'log' => NULL,
+            'created' => '1390095701',
+            'changed' => '1390095701',
+          ],
+        // Node 5, revision 7, und.
+        5 =>
+          [
+            'log' => NULL,
+            'created' => '1390095701',
+            'changed' => '1390095701',
+          ],
+        // Node 6, revision 8, und.
+        6 =>
+          [
+            'log' => NULL,
+            'created' => '1390095701',
+            'changed' => '1390095701',
+          ],
+        // Node 7, revision 9, und.
+        7 =>
+          [
+            'log' => NULL,
+            'created' => '1390095701',
+            'changed' => '1390095701',
+          ],
+        // Node 8, revision 10, und.
+        8 =>
+          [
+            'log' => NULL,
+            'created' => '1390095701',
+            'changed' => '1390095701',
+          ],
+        // Node 9, revision 11, und.
+        9 =>
+          [
+            'log' => NULL,
+            'created' => '1390095701',
+            'changed' => '1390095701',
+          ],
+        // Node 9, revision 12, und.
+        10 =>
+          [
+            'log' => NULL,
+            'created' => '1444671588',
+            'changed' => '1444671588',
+          ],
+        // Node 10, revision 13, en.
+        11 =>
+          [
+            'log' => NULL,
+            'created' => '1444238808',
+            'changed' => '1444238808',
+          ],
+        // Node 10, revision 14, en.
+        12 =>
+          [
+            'log' => NULL,
+            'created' => '1444239050',
+            'changed' => '1444238808',
+          ],
+        // Node 10, revision 14, fr.
+        13 =>
+          [
+            'log' => NULL,
+            'created' => '1444239050',
+            'changed' => '1444239050',
+          ],
+        // Node 12, revision 15, zu.
+        14 =>
+          [
+            'log' => NULL,
+            'created' => '1444238808',
+            'changed' => '1444238808',
+          ],
+        // Node 12, revision 16, en.
+        15 =>
+          [
+            'log' => NULL,
+            'created' => '1444239050',
+            'changed' => '1444239050',
+          ],
+        // Node 12, revision 16, zu.
+        16 =>
+          [
+            'log' => NULL,
+            'created' => '1444239050',
+            'changed' => '1444238808',
+          ],
+        // Node 14, revision 17, und.
+        17 =>
+          [
+            'log' => NULL,
+            'created' => '1493066668',
+            'changed' => '1493066668',
+          ],
+        // Node 15, revision 18, und.
+        18 =>
+          [
+            'log' => NULL,
+            'created' => '1493066677',
+            'changed' => '1493066677',
+          ],
+        // Node 16, revision 19, und.
+        19 =>
+          [
+            'log' => NULL,
+            'created' => '1493066684',
+            'changed' => '1493066684',
+          ],
+        // Node 17, revision 20, und.
+        20 =>
+          [
+            'log' => NULL,
+            'created' => '1493066693',
+            'changed' => '1493066693',
+          ],
+        // Node 18, revision 21, und.
+        21 =>
+          [
+            'log' => NULL,
+            'created' => '1494966544',
+            'changed' => '1494966544',
+          ],
+        // Node 19, revision 22, und.
+        22 =>
+          [
+            'log' => NULL,
+            'created' => '1501955771',
+            'changed' => '1501955771',
+          ],
+        // Node 12, revision 23, en.
+        23 =>
+          [
+            'log' => NULL,
+            'created' => '1520613305',
+            'changed' => '1444239050',
+          ],
+        // Node 12, revision 23, fr.
+        24 =>
+          [
+            'log' => NULL,
+            'created' => '1520613305',
+            'changed' => '1520613305',
+          ],
+        // Node 12, revision 23, zu.
+        25 =>
+          [
+            'log' => NULL,
+            'created' => '1520613305',
+            'changed' => '1444238808',
+          ],
+        // Node 1, revision 2001, und.
+        26 =>
+          [
+            'log' => 'modified rev 3',
+            'created' => '1420861423',
+            'changed' => '1420861423',
+          ],
+        // Node 21, revision 2002, en.
+        27 =>
+          [
+            'log' => NULL,
+            'created' => '1534014650',
+            'changed' => '1534014650',
+          ],
+        // Node 21, revision 2003, en.
+        28 =>
+          [
+            'log' => NULL,
+            'created' => '1534014687',
+            'changed' => '1534014650',
+          ],
+        // Node 21, revision 2003, fr.
+        29 =>
+          [
+            'log' => NULL,
+            'created' => '1534014687',
+            'changed' => '1534014687',
+          ],
+      ],
+    ];
+  }
+
+}
diff --git a/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeRevisionTest.php b/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeRevisionTest.php
index 9dbfb54126..31571be5cc 100644
--- a/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeRevisionTest.php
+++ b/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeRevisionTest.php
@@ -66,17 +66,17 @@ public function testNodeRevision() {
     $this->assertIdentical('1', $node->id());
     $this->assertIdentical('2001', $node->getRevisionId());
     $this->assertIdentical('und', $node->langcode->value);
-    $this->assertIdentical('Test title rev 2', $node->getTitle());
-    $this->assertIdentical('body test rev 2', $node->body->value);
-    $this->assertIdentical('teaser test rev 2', $node->body->summary);
+    $this->assertIdentical('Test title rev 3', $node->getTitle());
+    $this->assertIdentical('body test rev 3', $node->body->value);
+    $this->assertIdentical('teaser test rev 3', $node->body->summary);
     $this->assertIdentical('2', $node->getRevisionUser()->id());
-    $this->assertIdentical('modified rev 2', $node->revision_log->value);
-    $this->assertIdentical('1390095702', $node->getRevisionCreationTime());
+    $this->assertIdentical('modified rev 3', $node->revision_log->value);
+    $this->assertIdentical('1420861423', $node->getRevisionCreationTime());
 
-    $this->assertRevision(1, 'und', 'Test title', NULL, '1420861423');
+    $this->assertRevision(1, 'und', 'Test title', NULL, '1390095702');
     $this->assertRevision(3, 'und', 'Test title rev 3', NULL, '1420718386');
     $this->assertRevision(4, 'und', 'Test page title rev 4', NULL, '1390095701');
-    $this->assertRevision(5, 'und', 'Test title rev 3', 'modified rev 3', '1390095703');
+    $this->assertRevision(5, 'und', 'Test title rev 2', 'modified rev 2', '1390095703');
     $this->assertRevision(6, 'und', 'Node 4', NULL, '1390095701');
     $this->assertRevision(7, 'und', 'Node 5', NULL, '1390095701');
     $this->assertRevision(8, 'und', 'Node 6', NULL, '1390095701');
@@ -92,7 +92,7 @@ public function testNodeRevision() {
     $this->assertRevision(20, 'und', 'Ferengi Commerce Authority', NULL, '1493066693');
     $this->assertRevision(21, 'und', 'Ambassador Sarek', NULL, '1494966544');
     $this->assertRevision(22, 'und', 'New Forum Topic', NULL, '1501955771');
-    $this->assertRevision(2001, 'und', 'Test title rev 2', 'modified rev 2', '1390095702');
+    $this->assertRevision(2001, 'und', 'Test title rev 3', 'modified rev 3', '1420861423');
     $this->assertRevision(2002, 'en', 'John Smith - EN', NULL, '1534014650');
 
     // Test that the revision translations are not migrated and there should not
@@ -101,6 +101,7 @@ public function testNodeRevision() {
     foreach ($ids as $id) {
       $this->assertNull($this->nodeStorage->loadRevision($id));
     }
+
   }
 
 }
diff --git a/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeTest.php b/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeTest.php
index c390af2db4..4a2ec634d0 100644
--- a/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeTest.php
+++ b/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeTest.php
@@ -46,6 +46,11 @@ protected function setUp() {
    * Test node migration from Drupal 6 to 8.
    */
   public function testNode() {
+    // Confirm there are only classic node migration map tables. This shows
+    // that only the classic migration ran.
+    $results = $this->nodeMigrateMapTableCount('6');
+    $this->assertSame(13, $results['node']);
+    $this->assertSame(0, $results['node_complete']);
     $node = Node::load(1);
     $this->assertIdentical('1', $node->id(), 'Node 1 loaded.');
     $this->assertIdentical('und', $node->langcode->value);
@@ -54,10 +59,10 @@ public function testNode() {
     $this->assertIdentical('filtered_html', $node->body->format);
     $this->assertIdentical('story', $node->getType(), 'Node has the correct bundle.');
     $this->assertIdentical('Test title', $node->getTitle(), 'Node has the correct title.');
-    $this->assertIdentical('1388271197', $node->getCreatedTime(), 'Node has the correct created time.');
+    $this->assertIdentical('1390095702', $node->getCreatedTime(), 'Node has the correct created time.');
     $this->assertIdentical(FALSE, $node->isSticky());
     $this->assertIdentical('1', $node->getOwnerId());
-    $this->assertIdentical('1420861423', $node->getRevisionCreationTime());
+    $this->assertIdentical('1390095702', $node->getRevisionCreationTime());
 
     /** @var \Drupal\node\NodeInterface $node_revision */
     $node_revision = \Drupal::entityTypeManager()->getStorage('node')->loadRevision(1);
diff --git a/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeCompleteTest.php b/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeCompleteTest.php
new file mode 100644
index 0000000000..e9eb2eb0c3
--- /dev/null
+++ b/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeCompleteTest.php
@@ -0,0 +1,1172 @@
+<?php
+
+namespace Drupal\Tests\node\Kernel\Migrate\d7;
+
+use Drupal\migrate_drupal\NodeMigrateType;
+use Drupal\node\NodeInterface;
+use Drupal\Tests\file\Kernel\Migrate\d7\FileMigrationSetupTrait;
+use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
+use Drupal\Tests\migrate_drupal\Traits\CreateTestContentEntitiesTrait;
+use Drupal\Tests\migrate_drupal\Traits\NodeMigrateTypeTestTrait;
+
+/**
+ * Test class for a complete node migration for Drupal 7.
+ *
+ * @group migrate_drupal_7
+ */
+class MigrateNodeCompleteTest extends MigrateDrupal7TestBase {
+
+  use FileMigrationSetupTrait;
+  use CreateTestContentEntitiesTrait;
+  use NodeMigrateTypeTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = [
+    'content_translation',
+    'comment',
+    'datetime',
+    'image',
+    'language',
+    'link',
+    'menu_ui',
+    // Required for translation migrations.
+    'migrate_drupal_multilingual',
+    'node',
+    'taxonomy',
+    'telephone',
+    'text',
+  ];
+
+  /**
+   * The entity storage for node.
+   *
+   * @var \Drupal\Core\Entity\EntityStorageInterface
+   */
+  protected $nodeStorage;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    // Remove the classic node table made in setup.
+    $this->removeNodeMigrateMapTable(NodeMigrateType::NODE_MIGRATE_TYPE_CLASSIC, '7');
+
+    $this->fileMigrationSetup();
+
+    $this->installEntitySchema('comment');
+    $this->installEntitySchema('taxonomy_term');
+    $this->installSchema('comment', ['comment_entity_statistics']);
+    $this->installSchema('node', ['node_access']);
+    $this->installSchema('system', ['sequences']);
+
+    $this->createContent();
+
+    $this->nodeStorage = $this->container->get('entity_type.manager')
+      ->getStorage('node');
+    $this->nodeStorage->delete($this->nodeStorage->loadMultiple());
+
+    $this->migrateUsers();
+    $this->migrateFields();
+    $this->executeMigrations([
+      'language',
+      'd7_language_content_settings',
+      'd7_comment_field',
+      'd7_comment_field_instance',
+      'd7_node_complete',
+    ]);
+    $this->nodeStorage = $this->container->get('entity_type.manager')
+      ->getStorage('node');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getFileMigrationInfo() {
+    return [
+      'path' => 'public://sites/default/files/cube.jpeg',
+      'size' => '3620',
+      'base_path' => 'public://',
+      'plugin_id' => 'd7_file',
+    ];
+  }
+
+  /**
+   * Tests the complete node migration.
+   */
+  public function testNodeCompleteMigration() {
+    // Confirm there are only complete node migration map tables. This shows
+    // that only the complete migration ran.
+    $results = $this->nodeMigrateMapTableCount('7');
+    $this->assertSame(0, $results['node']);
+    $this->assertSame(7, $results['node_complete']);
+
+    $db = \Drupal::database();
+    $this->assertEquals($this->expectedNodeFieldRevisionTable(), $db->select('node_field_revision', 'nr')
+      ->fields('nr')
+      ->execute()
+      ->fetchAll(\PDO::FETCH_ASSOC));
+    $this->assertEquals($this->expectedNodeFieldDataTable(), $db->select('node_field_data', 'nr')
+      ->fields('nr')
+      ->execute()
+      ->fetchAll(\PDO::FETCH_ASSOC));
+
+    // Now load and test each revision,
+    // including the field 'field_text_long_plain' which has text reflecting the
+    // revision. Note that source node 1, uses entity translation which does
+    // not have a migration for revisions of translations.
+    // See https://www.drupal.org/project/drupal/issues/3076447.
+    $data = $this->expectedRevisionEntityData()[0];
+    foreach ($this->expectedNodeFieldRevisionTable() as $key => $revision) {
+      $this->assertRevision($revision, $data[$key]);
+    }
+  }
+
+  /**
+   * Asserts various aspects of a node revision.
+   *
+   * @param array $revision
+   *   An array of revision data matching a node_field_revision table row.
+   * @param array $data
+   *   An array of revision data.
+   */
+  protected function assertRevision(array $revision, array $data) {
+    /* @var  \Drupal\node\NodeInterface $actual */
+    $actual = $this->nodeStorage->loadRevision($revision['vid'])
+      ->getTranslation($revision['langcode']);
+    $this->assertInstanceOf(NodeInterface::class, $actual);
+    $this->assertSame($data['revision_created'], $actual->getRevisionCreationTime(), sprintf("Creation time '%s' does not match actual '%s' for revision '%d' langcode '%s'", $data['revision_created'], $actual->getRevisionCreationTime(), $revision['vid'], $revision['langcode']));
+    $this->assertSame($data['log'], $actual->getRevisionLogMessage(), sprintf("Revision log '%s' does not match actual '%s' for revision '%d' langcode '%s'", var_export($data['log'], TRUE), $actual->getRevisionLogMessage(), $revision['vid'], $revision['langcode']));
+    if (isset($data['field_text_long_plain'])) {
+      $this->assertSame($data['field_text_long_plain'], $actual->field_text_long_plain->value, sprintf("field_text_long_plain value '%s' does not match actual '%s' for revision '%d' langcode '%s'", var_export($data['field_text_long_plain'], TRUE), $actual->field_text_long_plain->value, $revision['vid'], $revision['langcode']));
+    }
+    if (isset($data['field_tree'])) {
+      $this->assertSame($data['field_tree'], $actual->field_tree->value, sprintf("field_tree value '%s' does not match actual '%s' for revision '%d' langcode '%s'", var_export($data['field_tree'], TRUE), $actual->field_tree->value, $revision['vid'], $revision['langcode']));
+    }
+  }
+
+  /**
+   * Provides the expected node_field_data table.
+   *
+   * @return array
+   *   The expected table rows.
+   */
+  protected function expectedNodeFieldDataTable() {
+    return [
+      0 =>
+        [
+          'nid' => '1',
+          'vid' => '1',
+          'type' => 'test_content_type',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '2',
+          'title' => 'An English Node',
+          'created' => '1529615790',
+          'changed' => '1529615790',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      1 =>
+        [
+          'nid' => '2',
+          'vid' => '12',
+          'type' => 'article',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '2',
+          'title' => 'The thing about Deep Space 9',
+          'created' => '1441306772',
+          'changed' => '1564543637',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => NULL,
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+      2 =>
+        [
+          'nid' => '2',
+          'vid' => '12',
+          'type' => 'article',
+          'langcode' => 'is',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'is - The thing about Deep Space 9',
+          'created' => '1471428152',
+          'changed' => '1564543706',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '0',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+      3 =>
+        [
+          'nid' => '4',
+          'vid' => '14',
+          'type' => 'article',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'en - The thing about Firefly',
+          'created' => '1478755314',
+          'changed' => '1564543929',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '0',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => 'is',
+          'content_translation_outdated' => '0',
+        ],
+      4 =>
+        [
+          'nid' => '4',
+          'vid' => '14',
+          'type' => 'article',
+          'langcode' => 'is',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'is - The thing about Firefly',
+          'created' => '1478755274',
+          'changed' => '1564543810',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => NULL,
+          'content_translation_source' => 'is',
+          'content_translation_outdated' => '0',
+        ],
+      5 =>
+        [
+          'nid' => '6',
+          'vid' => '6',
+          'type' => 'forum',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Comments are closed :-(',
+          'created' => '1504715414',
+          'changed' => '1504715414',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      6 =>
+        [
+          'nid' => '7',
+          'vid' => '7',
+          'type' => 'forum',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Comments are open :-)',
+          'created' => '1504715432',
+          'changed' => '1504715432',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      7 =>
+        [
+          'nid' => '8',
+          'vid' => '10',
+          'type' => 'blog',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'The number 47',
+          'created' => '1551000341',
+          'changed' => '1552126247',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => NULL,
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+      8 =>
+        [
+          'nid' => '8',
+          'vid' => '10',
+          'type' => 'blog',
+          'langcode' => 'fr',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'fr - The number 47',
+          'created' => '1552126296',
+          'changed' => '1552126296',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '0',
+          'revision_translation_affected' => NULL,
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+      9 =>
+        [
+          'nid' => '8',
+          'vid' => '10',
+          'type' => 'blog',
+          'langcode' => 'is',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'is - The number 47',
+          'created' => '1552126363',
+          'changed' => '1552126363',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '0',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+      10 =>
+        [
+          'nid' => '11',
+          'vid' => '18',
+          'type' => 'et',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Page one',
+          'created' => '1568261523',
+          'changed' => '1568261687',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => NULL,
+          'content_translation_source' => '',
+          'content_translation_outdated' => '0',
+        ],
+      11 =>
+        [
+          'nid' => '11',
+          'vid' => '18',
+          'type' => 'et',
+          'langcode' => 'fr',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Page one',
+          'created' => '1568261721',
+          'changed' => '1568261721',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '0',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+      12 =>
+        [
+          'nid' => '11',
+          'vid' => '18',
+          'type' => 'et',
+          'langcode' => 'is',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Page one',
+          'created' => '1568261548',
+          'changed' => '1568261548',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '0',
+          'revision_translation_affected' => NULL,
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+    ];
+  }
+
+  /**
+   * Provides the expected node_field_revision table.
+   *
+   * @return array
+   *   The table.
+   */
+  protected function expectedNodeFieldRevisionTable() {
+    return [
+      0 =>
+        [
+          'nid' => '1',
+          'vid' => '1',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '2',
+          'title' => 'An English Node',
+          'created' => '1529615790',
+          'changed' => '1529615790',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      1 =>
+        [
+          'nid' => '2',
+          'vid' => '2',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '2',
+          'title' => 'The thing about Deep Space 9 (1st rev)',
+          'created' => '1441306772',
+          'changed' => '1564543588',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+      2 =>
+        [
+          'nid' => '2',
+          'vid' => '3',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '2',
+          'title' => 'The thing about Deep Space 9 (1st rev)',
+          'created' => '1441306772',
+          'changed' => '1564543588',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => NULL,
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+      3 =>
+        [
+          'nid' => '2',
+          'vid' => '3',
+          'langcode' => 'is',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'is - The thing about Deep Space 9 (1st rev)',
+          'created' => '1471428152',
+          'changed' => '1564543677',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '0',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+      4 =>
+        [
+          'nid' => '4',
+          'vid' => '4',
+          'langcode' => 'is',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'is - The thing about Firefly (1st rev)',
+          'created' => '1478755274',
+          'changed' => '1478755274',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => 'is',
+          'content_translation_outdated' => '0',
+        ],
+      5 =>
+        [
+          'nid' => '4',
+          'vid' => '5',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'en - The thing about Firefly (1st rev)',
+          'created' => '1478755314',
+          'changed' => '1564543887',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '0',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => 'is',
+          'content_translation_outdated' => '0',
+        ],
+      6 =>
+        [
+          'nid' => '4',
+          'vid' => '5',
+          'langcode' => 'is',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'is - The thing about Firefly (1st rev)',
+          'created' => '1478755274',
+          'changed' => '1478755274',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => NULL,
+          'content_translation_source' => 'is',
+          'content_translation_outdated' => '0',
+        ],
+      7 =>
+        [
+          'nid' => '6',
+          'vid' => '6',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Comments are closed :-(',
+          'created' => '1504715414',
+          'changed' => '1504715414',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      8 =>
+        [
+          'nid' => '7',
+          'vid' => '7',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Comments are open :-)',
+          'created' => '1504715432',
+          'changed' => '1504715432',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      9 =>
+        [
+          'nid' => '8',
+          'vid' => '8',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'The number 47',
+          'created' => '1551000341',
+          'changed' => '1552126247',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+      10 =>
+        [
+          'nid' => '8',
+          'vid' => '9',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'The number 47',
+          'created' => '1551000341',
+          'changed' => '1552126247',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => NULL,
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+      11 =>
+        [
+          'nid' => '8',
+          'vid' => '9',
+          'langcode' => 'fr',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'fr - The number 47',
+          'created' => '1552126296',
+          'changed' => '1552126296',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '0',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+      12 =>
+        [
+          'nid' => '8',
+          'vid' => '10',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'The number 47',
+          'created' => '1551000341',
+          'changed' => '1552126247',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => NULL,
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+      13 =>
+        [
+          'nid' => '8',
+          'vid' => '10',
+          'langcode' => 'fr',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'fr - The number 47',
+          'created' => '1552126296',
+          'changed' => '1552126296',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '0',
+          'revision_translation_affected' => NULL,
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+      14 =>
+        [
+          'nid' => '8',
+          'vid' => '10',
+          'langcode' => 'is',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'is - The number 47',
+          'created' => '1552126363',
+          'changed' => '1552126363',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '0',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+      15 =>
+        [
+          'nid' => '2',
+          'vid' => '11',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '2',
+          'title' => 'The thing about Deep Space 9',
+          'created' => '1441306772',
+          'changed' => '1564543637',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+      16 =>
+        [
+          'nid' => '2',
+          'vid' => '11',
+          'langcode' => 'is',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'is - The thing about Deep Space 9 (1st rev)',
+          'created' => '1471428152',
+          'changed' => '1564543637',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '0',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+      17 =>
+        [
+          'nid' => '2',
+          'vid' => '12',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '2',
+          'title' => 'The thing about Deep Space 9',
+          'created' => '1441306772',
+          'changed' => '1564543637',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => NULL,
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+      18 =>
+        [
+          'nid' => '2',
+          'vid' => '12',
+          'langcode' => 'is',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'is - The thing about Deep Space 9',
+          'created' => '1471428152',
+          'changed' => '1564543706',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '0',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+      19 =>
+        [
+          'nid' => '4',
+          'vid' => '13',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'en - The thing about Firefly (1st rev)',
+          'created' => '1478755314',
+          'changed' => '1564543887',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '0',
+          'revision_translation_affected' => NULL,
+          'content_translation_source' => 'is',
+          'content_translation_outdated' => '0',
+        ],
+      20 =>
+        [
+          'nid' => '4',
+          'vid' => '13',
+          'langcode' => 'is',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'is - The thing about Firefly',
+          'created' => '1478755274',
+          'changed' => '1564543810',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => 'is',
+          'content_translation_outdated' => '0',
+        ],
+      21 =>
+        [
+          'nid' => '4',
+          'vid' => '14',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'en - The thing about Firefly',
+          'created' => '1478755314',
+          'changed' => '1564543929',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '0',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => 'is',
+          'content_translation_outdated' => '0',
+        ],
+      22 =>
+        [
+          'nid' => '4',
+          'vid' => '14',
+          'langcode' => 'is',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'is - The thing about Firefly',
+          'created' => '1478755274',
+          'changed' => '1564543810',
+          'promote' => '1',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => NULL,
+          'content_translation_source' => 'is',
+          'content_translation_outdated' => '0',
+        ],
+      23 =>
+        [
+          'nid' => '11',
+          'vid' => '15',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Page one',
+          'created' => '1568261523',
+          'changed' => '1568261523',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => NULL,
+          'content_translation_outdated' => '0',
+        ],
+      24 =>
+        [
+          'nid' => '11',
+          'vid' => '16',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Page one',
+          'created' => '1568261523',
+          'changed' => '1568261523',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => NULL,
+          'content_translation_source' => '',
+          'content_translation_outdated' => '0',
+        ],
+      25 =>
+        [
+          'nid' => '11',
+          'vid' => '16',
+          'langcode' => 'is',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Page one',
+          'created' => '1568261548',
+          'changed' => '1568261548',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '0',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+      26 =>
+        [
+          'nid' => '11',
+          'vid' => '17',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Page one',
+          'created' => '1568261523',
+          'changed' => '1568261687',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => NULL,
+          'content_translation_source' => '',
+          'content_translation_outdated' => '0',
+        ],
+      27 =>
+        [
+          'nid' => '11',
+          'vid' => '17',
+          'langcode' => 'is',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Page one',
+          'created' => '1568261548',
+          'changed' => '1568261548',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '0',
+          'revision_translation_affected' => NULL,
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+      28 =>
+        [
+          'nid' => '11',
+          'vid' => '18',
+          'langcode' => 'en',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Page one',
+          'created' => '1568261523',
+          'changed' => '1568261687',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '1',
+          'revision_translation_affected' => NULL,
+          'content_translation_source' => '',
+          'content_translation_outdated' => '0',
+        ],
+      29 =>
+        [
+          'nid' => '11',
+          'vid' => '18',
+          'langcode' => 'fr',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Page one',
+          'created' => '1568261721',
+          'changed' => '1568261721',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '0',
+          'revision_translation_affected' => '1',
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+      30 =>
+        [
+          'nid' => '11',
+          'vid' => '18',
+          'langcode' => 'is',
+          'status' => '1',
+          'uid' => '1',
+          'title' => 'Page one',
+          'created' => '1568261548',
+          'changed' => '1568261548',
+          'promote' => '0',
+          'sticky' => '0',
+          'default_langcode' => '0',
+          'revision_translation_affected' => NULL,
+          'content_translation_source' => 'en',
+          'content_translation_outdated' => '0',
+        ],
+    ];
+  }
+
+  /**
+   * Provides the expected node_field_revision table.
+   *
+   * @return array
+   *   Selected properties and fields on the revision.
+   */
+  protected function expectedRevisionEntityData() {
+    return [
+      $revision_data = [
+        // Node 1, revision 1, en.
+        0 =>
+          [
+            'log' => NULL,
+            'field_text_long_plain' => NULL,
+            'revision_created' => '1529615790',
+          ],
+        // Node 2, revision 2, en.
+        1 =>
+          [
+            'log' => 'DS9 1st rev',
+            'field_text_long_plain' => 'DS9 1st rev',
+            'revision_created' => '1564543588',
+          ],
+        // Node 2, revision 3, en.
+        2 =>
+          [
+            'log' => 'is - DS9 1st rev',
+            'field_text_long_plain' => 'DS9 1st rev',
+            'revision_created' => '1564543677',
+          ],
+        // Node 2, revision 3, is.
+        3 =>
+          [
+            'log' => 'is - DS9 1st rev',
+            'field_text_long_plain' => 'is - DS9 1st rev',
+            'revision_created' => '1564543677',
+          ],
+        // Node 4, revision 4, is.
+        4 =>
+          [
+            'log' => 'is - Firefly 1st rev',
+            'field_text_long_plain' => NULL,
+            'revision_created' => '1478755274',
+          ],
+        // Node 4, revision 5, en.
+        5 =>
+          [
+            'log' => 'Firefly 1st rev',
+            'field_text_long_plain' => NULL,
+            'revision_created' => '1564543887',
+          ],
+        // Node 4, revision 5, is.
+        6 =>
+          [
+            'log' => 'Firefly 1st rev',
+            'field_text_long_plain' => NULL,
+            'revision_created' => '1564543887',
+          ],
+        // Node 6, revision 6, en.
+        7 =>
+          [
+            'log' => NULL,
+            'field_text_long_plain' => NULL,
+            'revision_created' => '1504715414',
+          ],
+        // Node 7, revision 7, en.
+        8 =>
+          [
+            'log' => NULL,
+            'field_text_long_plain' => NULL,
+            'revision_created' => '1504715432',
+          ],
+        // Node 8, revision 8, en.
+        9 =>
+          [
+            'log' => NULL,
+            'field_text_long_plain' => NULL,
+            'revision_created' => '1552126247',
+          ],
+        // Node 8, revision 9, en.
+        10 =>
+          [
+            'log' => NULL,
+            'field_text_long_plain' => NULL,
+            'revision_created' => '1552126296',
+          ],
+        // Node 8, revision 9, fr.
+        11 =>
+          [
+            'log' => NULL,
+            'field_text_long_plain' => NULL,
+            'revision_created' => '1552126296',
+          ],
+        // Node 8, revision 10, en.
+        12 =>
+          [
+            'log' => NULL,
+            'field_text_long_plain' => NULL,
+            'revision_created' => '1552126363',
+          ],
+        // Node 8, revision 10, fr.
+        13 =>
+          [
+            'log' => NULL,
+            'field_text_long_plain' => NULL,
+            'revision_created' => '1552126363',
+          ],
+        // Node 8, revision 10, is.
+        14 =>
+          [
+            'log' => NULL,
+            'field_text_long_plain' => NULL,
+            'revision_created' => '1552126363',
+          ],
+        // Node 2, revision 11, en.
+        15 =>
+          [
+            'log' => 'DS9 2nd rev',
+            'field_text_long_plain' => NULL,
+            'revision_created' => '1564543637',
+          ],
+        // Node 2, revision 11, is.
+        16 =>
+          [
+            'log' => 'DS9 2nd rev',
+            'field_text_long_plain' => NULL,
+            'revision_created' => '1564543637',
+          ],
+        // Node 2, revision 12, en.
+        17 =>
+          [
+            'log' => 'is - DS9 2nd rev',
+            'field_text_long_plain' => NULL,
+            'revision_created' => '1564543706',
+          ],
+        // Node 2, revision 12, is.
+        18 =>
+          [
+            'log' => 'is - DS9 2nd rev',
+            'field_text_long_plain' => NULL,
+            'revision_created' => '1564543706',
+          ],
+        // Node 4, revision 13, en.
+        19 =>
+          [
+            'log' => 'is - Firefly 2nd rev',
+            'field_text_long_plain' => NULL,
+            'revision_created' => '1564543810',
+          ],
+        // Node 4, revision 13, is.
+        20 =>
+          [
+            'log' => 'is - Firefly 2nd rev',
+            'field_text_long_plain' => NULL,
+            'revision_created' => '1564543810',
+          ],
+        // Node 4, revision 14, en.
+        21 =>
+          [
+            'log' => 'Firefly 2nd rev',
+            'field_text_long_plain' => NULL,
+            'revision_created' => '1564543929',
+          ],
+        // Node 4, revision 14, is.
+        22 =>
+          [
+            'log' => 'Firefly 2nd rev',
+            'field_text_long_plain' => NULL,
+            'revision_created' => '1564543929',
+          ],
+        // Node 11, revision 15, en.
+        23 =>
+          [
+            'log' => NULL,
+            'body' => '1st',
+            'field_tree' => 'lancewood',
+            'revision_created' => '1568261523',
+          ],
+        // Node 11, revision 16, en.
+        24 =>
+          [
+            'log' => NULL,
+            'body' => '1st',
+            'field_tree' => 'lancewood',
+            'revision_created' => '1568261548',
+          ],
+        // Node 11, revision 16, is.
+        25 =>
+          [
+            'log' => NULL,
+            'body' => '1st',
+            'field_tree' => 'is - lancewood',
+            'revision_created' => '1568261548',
+          ],
+        // Node 11, revision 17, en.
+        26 =>
+          [
+            'log' => '2nd',
+            'body' => '2nd',
+            'field_tree' => 'lancewood',
+            'revision_created' => '1568261548',
+          ],
+        // Node 11, revision 17, is.
+        27 =>
+          [
+            'log' => '2nd',
+            'body' => '2nd',
+            'field_tree' => 'is - lancewood',
+            'revision_created' => '1568261548',
+          ],
+        // Node 11, revision 18, en.
+        28 =>
+          [
+            'log' => NULL,
+            'body' => '2nd',
+            'field_tree' => 'lancewood',
+            'revision_created' => '1568261548',
+          ],
+        // Node 11, revision 18, f5.
+        29 =>
+          [
+            'log' => NULL,
+            'body' => '2nd',
+            'field_tree' => 'fr - lancewood',
+            'revision_created' => '1568261548',
+          ],
+        // Node 11, revision 18, is.
+        30 =>
+          [
+            'log' => NULL,
+            'body' => '2nd',
+            'field_tree' => 'is - lancewood',
+            'revision_created' => '1568261548',
+          ],
+      ],
+    ];
+  }
+
+}
diff --git a/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeRevisionTest.php b/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeRevisionTest.php
index 563bcf9be2..8c04019bb0 100644
--- a/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeRevisionTest.php
+++ b/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeRevisionTest.php
@@ -112,8 +112,8 @@ protected function assertRevision($id, $langcode, $title, $log, $timestamp) {
    */
   public function testNodeRevisions() {
     $this->assertRevision(1, 'en', 'An English Node', NULL, '1441032132');
-    $this->assertRevision(2, 'en', 'The thing about Deep Space 9', NULL, '1471428152');
-    $this->assertRevision(4, 'is', 'is - The thing about Firefly', NULL, '1478755314');
+    $this->assertRevision(2, 'en', 'The thing about Deep Space 9 (1st rev)', 'DS9 1st rev', '1564543588');
+    $this->assertRevision(4, 'is', 'is - The thing about Firefly (1st rev)', 'is - Firefly 1st rev', '1478755274');
     $this->assertRevision(6, 'en', 'Comments are closed :-(', NULL, '1504715414');
     $this->assertRevision(7, 'en', 'Comments are open :-)', NULL, '1504715432');
     $this->assertRevision(8, 'en', 'The number 47', NULL, '1552126363');
diff --git a/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeTest.php b/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeTest.php
index 25aa75654f..19f7bf7cb1 100644
--- a/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeTest.php
+++ b/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeTest.php
@@ -149,6 +149,12 @@ protected function assertRevision($id, $title, $uid, $log, $timestamp) {
    * Test node migration from Drupal 7 to 8.
    */
   public function testNode() {
+    // Confirm there are only classic node migration map tables. This shows
+    // that only the classic migration ran.
+    $results = $this->nodeMigrateMapTableCount('7');
+    $this->assertSame(8, $results['node']);
+    $this->assertSame(0, $results['node_complete']);
+
     $this->assertEntity(1, 'test_content_type', 'en', 'An English Node', '2', TRUE, '1421727515', '1441032132', TRUE, FALSE);
     $this->assertRevision(1, 'An English Node', '1', NULL, '1441032132');
 
diff --git a/core/modules/path/migrations/d6_url_alias.yml b/core/modules/path/migrations/d6_url_alias.yml
index 747a06805b..2ef20469f9 100644
--- a/core/modules/path/migrations/d6_url_alias.yml
+++ b/core/modules/path/migrations/d6_url_alias.yml
@@ -35,7 +35,11 @@ process:
         - 1
     -
       plugin: migration_lookup
-      migration: d6_node_translation
+      migration:
+        - d6_node_complete
+        - d6_node_translation
+    -
+      plugin: node_complete_node_translation_lookup
   langcode:
     -
       plugin: null_coalesce
diff --git a/core/modules/path/migrations/d7_url_alias.yml b/core/modules/path/migrations/d7_url_alias.yml
index b49686a7fb..0add8532a3 100644
--- a/core/modules/path/migrations/d7_url_alias.yml
+++ b/core/modules/path/migrations/d7_url_alias.yml
@@ -34,7 +34,11 @@ process:
         - 1
     -
       plugin: migration_lookup
-      migration: d7_node_translation
+      migration:
+        - d7_node_complete
+        - d7_node_translation
+    -
+      plugin: node_complete_node_translation_lookup
   langcode:
     plugin: null_coalesce
     source:
diff --git a/core/modules/statistics/migrations/statistics_node_counter.yml b/core/modules/statistics/migrations/statistics_node_counter.yml
index 748a4a83c0..0c2aa71d71 100644
--- a/core/modules/statistics/migrations/statistics_node_counter.yml
+++ b/core/modules/statistics/migrations/statistics_node_counter.yml
@@ -10,8 +10,14 @@ process:
   nid:
     -
       plugin: migration_lookup
-      migration: [d6_node, d7_node]
+      migration:
+        - d6_node_complete
+        - d7_node_complete
+        - d6_node
+        - d7_node
       source: nid
+    -
+      plugin: node_complete_node_lookup
     -
       plugin: skip_on_empty
       method: row
diff --git a/core/modules/taxonomy/migrations/d6_term_node.yml b/core/modules/taxonomy/migrations/d6_term_node.yml
index fdb8cc9a41..1e358bf0b4 100644
--- a/core/modules/taxonomy/migrations/d6_term_node.yml
+++ b/core/modules/taxonomy/migrations/d6_term_node.yml
@@ -10,8 +10,12 @@ process:
   nid:
     -
       plugin: migration_lookup
-      migration: d6_node
+      migration:
+        - d6_node_complete
+        - d6_node
       source: nid
+    -
+      plugin: node_complete_node_lookup
     -
       plugin: skip_on_empty
       method: row
diff --git a/core/modules/taxonomy/migrations/d6_term_node_revision.yml b/core/modules/taxonomy/migrations/d6_term_node_revision.yml
index 9487984f94..4b196ac2df 100644
--- a/core/modules/taxonomy/migrations/d6_term_node_revision.yml
+++ b/core/modules/taxonomy/migrations/d6_term_node_revision.yml
@@ -11,8 +11,12 @@ process:
   vid:
     -
       plugin: migration_lookup
-      migration: d6_node_revision
+      migration:
+        - d6_node_copmplete
+        - d6_node_revision
       source: vid
+    -
+      plugin: node_complete_node_revision_lookup
     -
       plugin: skip_on_empty
       method: row
diff --git a/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTermNodeComplete.php b/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTermNodeComplete.php
new file mode 100644
index 0000000000..77e4db72f1
--- /dev/null
+++ b/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTermNodeComplete.php
@@ -0,0 +1,67 @@
+<?php
+
+namespace Drupal\Tests\taxonomy\Kernel\Migrate\d6;
+
+use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
+use Drupal\migrate_drupal\NodeMigrateType;
+use Drupal\node\Entity\Node;
+
+/**
+ * Upgrade taxonomy term node associations.
+ *
+ * @group migrate_drupal_6
+ */
+class MigrateTermNodeComplete extends MigrateDrupal6TestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = [
+    'content_translation',
+    'language',
+    'menu_ui',
+    // A requirement for d6_node_translation.
+    'migrate_drupal_multilingual',
+    'taxonomy',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    // Remove the classic node table made in setup.
+    $this->removeNodeMigrateMapTable(NodeMigrateType::NODE_MIGRATE_TYPE_CLASSIC, '6');
+
+    $this->installSchema('node', ['node_access']);
+    $this->installEntitySchema('node');
+
+    $this->executeMigration('language');
+    $this->migrateUsers(FALSE);
+    $this->migrateFields();
+    $this->executeMigrations(['d6_node_settings', 'd6_node_complete']);
+    $this->migrateTaxonomy();
+    // This is a base plugin ID and we want to run all derivatives.
+    $this->executeMigrations(['d6_term_node']);
+  }
+
+  /**
+   * Tests the Drupal 6 term-node association to Drupal 8 migration.
+   */
+  public function testTermNode() {
+    $this->container->get('entity_type.manager')
+      ->getStorage('node')
+      ->resetCache([1, 2]);
+
+    $nodes = Node::loadMultiple([1, 2]);
+    $node = $nodes[1];
+    $this->assertSame(1, count($node->field_vocabulary_1_i_0_));
+    $this->assertSame('1', $node->field_vocabulary_1_i_0_[0]->target_id);
+    $node = $nodes[2];
+    $this->assertSame(2, count($node->field_vocabulary_2_i_1_));
+    $this->assertSame('2', $node->field_vocabulary_2_i_1_[0]->target_id);
+    $this->assertSame('3', $node->field_vocabulary_2_i_1_[1]->target_id);
+  }
+
+}
