diff --git a/core/modules/migrate_drupal/src/Tests/Table/d7/Node.php b/core/modules/migrate_drupal/src/Tests/Table/d7/Node.php
index 9227d91..3064754 100644
--- a/core/modules/migrate_drupal/src/Tests/Table/d7/Node.php
+++ b/core/modules/migrate_drupal/src/Tests/Table/d7/Node.php
@@ -135,10 +135,10 @@ public function load() {
       'type' => 'test_content_type',
       'language' => 'en',
       'title' => 'A Node',
-      'uid' => '1',
+      'uid' => '2',
       'status' => '1',
       'created' => '1421727515',
-      'changed' => '1421727515',
+      'changed' => '1441032132',
       'comment' => '2',
       'promote' => '1',
       'sticky' => '0',
@@ -148,4 +148,4 @@ public function load() {
   }
 
 }
-#ad72334d15f155644075803c26757ee5
+#06cbcf4df265ff717f83f472c22fdbcf
diff --git a/core/modules/migrate_drupal/src/Tests/Table/d7/NodeRevision.php b/core/modules/migrate_drupal/src/Tests/Table/d7/NodeRevision.php
index 70a9fc8..d709a8b 100644
--- a/core/modules/migrate_drupal/src/Tests/Table/d7/NodeRevision.php
+++ b/core/modules/migrate_drupal/src/Tests/Table/d7/NodeRevision.php
@@ -106,7 +106,7 @@ public function load() {
       'uid' => '1',
       'title' => 'A Node',
       'log' => '',
-      'timestamp' => '1421727515',
+      'timestamp' => '1441032132',
       'status' => '1',
       'comment' => '2',
       'promote' => '1',
@@ -115,4 +115,4 @@ public function load() {
   }
 
 }
-#02a3aed2de9a2df056ef6b81d329213e
+#e202cc75a51afc39cabf52cbf0a0f9e2
diff --git a/core/modules/migrate_drupal/src/Tests/Table/d7/NodeType.php b/core/modules/migrate_drupal/src/Tests/Table/d7/NodeType.php
index bbf0a4a..215bb60 100644
--- a/core/modules/migrate_drupal/src/Tests/Table/d7/NodeType.php
+++ b/core/modules/migrate_drupal/src/Tests/Table/d7/NodeType.php
@@ -122,7 +122,7 @@ public function load() {
       'base' => 'node_content',
       'module' => 'node',
       'description' => 'Use <em>articles</em> for time-sensitive content like news, press releases or blog posts.',
-      'help' => '',
+      'help' => 'Help text for articles',
       'has_title' => '1',
       'title_label' => 'Title',
       'custom' => '1',
@@ -136,11 +136,11 @@ public function load() {
       'base' => 'blog',
       'module' => 'blog',
       'description' => 'Use for multi-user blogs. Every user gets a personal blog.',
-      'help' => '',
+      'help' => 'Blog away, good sir!',
       'has_title' => '1',
       'title_label' => 'Title',
       'custom' => '0',
-      'modified' => '0',
+      'modified' => '1',
       'locked' => '1',
       'disabled' => '0',
       'orig_type' => 'blog',
@@ -164,11 +164,11 @@ public function load() {
       'base' => 'forum',
       'module' => 'forum',
       'description' => 'A <em>forum topic</em> starts a new discussion thread within a forum.',
-      'help' => '',
+      'help' => 'No name-calling, no flame wars. Be nice.',
       'has_title' => '1',
       'title_label' => 'Subject',
       'custom' => '0',
-      'modified' => '0',
+      'modified' => '1',
       'locked' => '1',
       'disabled' => '0',
       'orig_type' => 'forum',
@@ -178,7 +178,7 @@ public function load() {
       'base' => 'node_content',
       'module' => 'node',
       'description' => "Use <em>basic pages</em> for your static content, such as an 'About us' page.",
-      'help' => '',
+      'help' => 'Help text for basic pages',
       'has_title' => '1',
       'title_label' => 'Title',
       'custom' => '1',
@@ -192,7 +192,7 @@ public function load() {
       'base' => 'node_content',
       'module' => 'node',
       'description' => 'This is the description of the test content type.',
-      'help' => '',
+      'help' => 'Help text for test content type',
       'has_title' => '1',
       'title_label' => 'Title',
       'custom' => '1',
@@ -204,4 +204,4 @@ public function load() {
   }
 
 }
-#c3cc0500356b35e3e6b106aabf2c7aac
+#9bef45bc61d3712f730ca19ec8be6f21
diff --git a/core/modules/migrate_drupal/src/Tests/Table/d7/Variable.php b/core/modules/migrate_drupal/src/Tests/Table/d7/Variable.php
index 177ec92..a5936ac 100644
--- a/core/modules/migrate_drupal/src/Tests/Table/d7/Variable.php
+++ b/core/modules/migrate_drupal/src/Tests/Table/d7/Variable.php
@@ -44,9 +44,24 @@ public function load() {
       'value',
     ))
     ->values(array(
-      'name' => 'additional_settings__active_tab_test_content_type',
+      'name' => 'additional_settings__active_tab_article',
+      'value' => 's:15:"edit-submission";',
+    ))->values(array(
+      'name' => 'additional_settings__active_tab_blog',
       'value' => 's:15:"edit-submission";',
     ))->values(array(
+      'name' => 'additional_settings__active_tab_book',
+      'value' => 's:13:"edit-workflow";',
+    ))->values(array(
+      'name' => 'additional_settings__active_tab_forum',
+      'value' => 's:15:"edit-submission";',
+    ))->values(array(
+      'name' => 'additional_settings__active_tab_page',
+      'value' => 's:15:"edit-submission";',
+    ))->values(array(
+      'name' => 'additional_settings__active_tab_test_content_type',
+      'value' => 's:13:"edit-workflow";',
+    ))->values(array(
       'name' => 'admin_theme',
       'value' => 's:5:"seven";',
     ))->values(array(
@@ -92,24 +107,126 @@ public function load() {
       'name' => 'clean_url',
       'value' => 's:1:"1";',
     ))->values(array(
+      'name' => 'comment_anonymous_article',
+      'value' => 'i:0;',
+    ))->values(array(
+      'name' => 'comment_anonymous_blog',
+      'value' => 'i:0;',
+    ))->values(array(
+      'name' => 'comment_anonymous_book',
+      'value' => 'i:0;',
+    ))->values(array(
+      'name' => 'comment_anonymous_forum',
+      'value' => 'i:0;',
+    ))->values(array(
+      'name' => 'comment_anonymous_page',
+      'value' => 'i:0;',
+    ))->values(array(
       'name' => 'comment_anonymous_test_content_type',
       'value' => 'i:0;',
     ))->values(array(
+      'name' => 'comment_article',
+      'value' => 's:1:"2";',
+    ))->values(array(
+      'name' => 'comment_blog',
+      'value' => 's:1:"2";',
+    ))->values(array(
+      'name' => 'comment_book',
+      'value' => 's:1:"2";',
+    ))->values(array(
+      'name' => 'comment_default_mode_article',
+      'value' => 'i:1;',
+    ))->values(array(
+      'name' => 'comment_default_mode_blog',
+      'value' => 'i:1;',
+    ))->values(array(
+      'name' => 'comment_default_mode_book',
+      'value' => 'i:1;',
+    ))->values(array(
+      'name' => 'comment_default_mode_forum',
+      'value' => 'i:1;',
+    ))->values(array(
+      'name' => 'comment_default_mode_page',
+      'value' => 'i:1;',
+    ))->values(array(
       'name' => 'comment_default_mode_test_content_type',
       'value' => 'i:1;',
     ))->values(array(
+      'name' => 'comment_default_per_page_article',
+      'value' => 's:2:"50";',
+    ))->values(array(
+      'name' => 'comment_default_per_page_blog',
+      'value' => 's:2:"50";',
+    ))->values(array(
+      'name' => 'comment_default_per_page_book',
+      'value' => 's:2:"50";',
+    ))->values(array(
+      'name' => 'comment_default_per_page_forum',
+      'value' => 's:2:"50";',
+    ))->values(array(
+      'name' => 'comment_default_per_page_page',
+      'value' => 's:2:"50";',
+    ))->values(array(
       'name' => 'comment_default_per_page_test_content_type',
       'value' => 's:2:"30";',
     ))->values(array(
+      'name' => 'comment_form_location_article',
+      'value' => 'i:1;',
+    ))->values(array(
+      'name' => 'comment_form_location_blog',
+      'value' => 'i:1;',
+    ))->values(array(
+      'name' => 'comment_form_location_book',
+      'value' => 'i:1;',
+    ))->values(array(
+      'name' => 'comment_form_location_forum',
+      'value' => 'i:1;',
+    ))->values(array(
+      'name' => 'comment_form_location_page',
+      'value' => 'i:1;',
+    ))->values(array(
       'name' => 'comment_form_location_test_content_type',
       'value' => 'i:1;',
     ))->values(array(
+      'name' => 'comment_forum',
+      'value' => 's:1:"2";',
+    ))->values(array(
       'name' => 'comment_page',
-      'value' => 'i:0;',
+      'value' => 's:1:"0";',
+    ))->values(array(
+      'name' => 'comment_preview_article',
+      'value' => 's:1:"1";',
+    ))->values(array(
+      'name' => 'comment_preview_blog',
+      'value' => 's:1:"1";',
+    ))->values(array(
+      'name' => 'comment_preview_book',
+      'value' => 's:1:"1";',
+    ))->values(array(
+      'name' => 'comment_preview_forum',
+      'value' => 's:1:"1";',
+    ))->values(array(
+      'name' => 'comment_preview_page',
+      'value' => 's:1:"1";',
     ))->values(array(
       'name' => 'comment_preview_test_content_type',
       'value' => 's:1:"1";',
     ))->values(array(
+      'name' => 'comment_subject_field_article',
+      'value' => 'i:1;',
+    ))->values(array(
+      'name' => 'comment_subject_field_blog',
+      'value' => 'i:1;',
+    ))->values(array(
+      'name' => 'comment_subject_field_book',
+      'value' => 'i:1;',
+    ))->values(array(
+      'name' => 'comment_subject_field_forum',
+      'value' => 'i:1;',
+    ))->values(array(
+      'name' => 'comment_subject_field_page',
+      'value' => 'i:1;',
+    ))->values(array(
       'name' => 'comment_subject_field_test_content_type',
       'value' => 'i:1;',
     ))->values(array(
@@ -161,6 +278,15 @@ public function load() {
       'name' => 'field_bundle_settings_user__user',
       'value' => 'a:2:{s:10:"view_modes";a:0:{}s:12:"extra_fields";a:2:{s:4:"form";a:2:{s:7:"account";a:1:{s:6:"weight";s:3:"-10";}s:8:"timezone";a:1:{s:6:"weight";s:1:"6";}}s:7:"display";a:0:{}}}',
     ))->values(array(
+      'name' => 'file_default_scheme',
+      'value' => 's:6:"public";',
+    ))->values(array(
+      'name' => 'file_private_path',
+      'value' => 's:0:"";',
+    ))->values(array(
+      'name' => 'file_public_path',
+      'value' => 's:19:"sites/default/files";',
+    ))->values(array(
       'name' => 'file_temporary_path',
       'value' => 's:4:"/tmp";',
     ))->values(array(
@@ -185,6 +311,21 @@ public function load() {
       'name' => 'install_time',
       'value' => 'i:1421694923;',
     ))->values(array(
+      'name' => 'language_content_type_article',
+      'value' => 's:1:"0";',
+    ))->values(array(
+      'name' => 'language_content_type_blog',
+      'value' => 's:1:"0";',
+    ))->values(array(
+      'name' => 'language_content_type_book',
+      'value' => 's:1:"0";',
+    ))->values(array(
+      'name' => 'language_content_type_forum',
+      'value' => 's:1:"0";',
+    ))->values(array(
+      'name' => 'language_content_type_page',
+      'value' => 's:1:"0";',
+    ))->values(array(
       'name' => 'language_content_type_test_content_type',
       'value' => 's:1:"0";',
     ))->values(array(
@@ -216,7 +357,22 @@ public function load() {
       'value' => 'a:0:{}',
     ))->values(array(
       'name' => 'menu_masks',
-      'value' => 'a:36:{i:0;i:501;i:1;i:493;i:2;i:250;i:3;i:247;i:4;i:246;i:5;i:245;i:6;i:126;i:7;i:125;i:8;i:123;i:9;i:122;i:10;i:121;i:11;i:117;i:12;i:63;i:13;i:62;i:14;i:61;i:15;i:60;i:16;i:59;i:17;i:58;i:18;i:44;i:19;i:31;i:20;i:30;i:21;i:29;i:22;i:24;i:23;i:21;i:24;i:15;i:25;i:14;i:26;i:13;i:27;i:12;i:28;i:11;i:29;i:8;i:30;i:7;i:31;i:6;i:32;i:5;i:33;i:3;i:34;i:2;i:35;i:1;}',
+      'value' => 'a:35:{i:0;i:501;i:1;i:493;i:2;i:250;i:3;i:247;i:4;i:246;i:5;i:245;i:6;i:126;i:7;i:125;i:8;i:123;i:9;i:122;i:10;i:121;i:11;i:117;i:12;i:63;i:13;i:62;i:14;i:61;i:15;i:60;i:16;i:59;i:17;i:58;i:18;i:44;i:19;i:31;i:20;i:30;i:21;i:29;i:22;i:24;i:23;i:21;i:24;i:15;i:25;i:14;i:26;i:13;i:27;i:12;i:28;i:11;i:29;i:7;i:30;i:6;i:31;i:5;i:32;i:3;i:33;i:2;i:34;i:1;}',
+    ))->values(array(
+      'name' => 'menu_options_article',
+      'value' => 'a:1:{i:0;s:9:"main-menu";}',
+    ))->values(array(
+      'name' => 'menu_options_blog',
+      'value' => 'a:1:{i:0;s:9:"main-menu";}',
+    ))->values(array(
+      'name' => 'menu_options_book',
+      'value' => 'a:1:{i:0;s:9:"main-menu";}',
+    ))->values(array(
+      'name' => 'menu_options_forum',
+      'value' => 'a:1:{i:0;s:9:"main-menu";}',
+    ))->values(array(
+      'name' => 'menu_options_page',
+      'value' => 'a:1:{i:0;s:9:"main-menu";}',
     ))->values(array(
       'name' => 'menu_options_test_content_type',
       'value' => 'a:4:{i:0;s:9:"main-menu";i:1;s:10:"management";i:2;s:10:"navigation";i:3;s:9:"user-menu";}',
@@ -224,6 +380,21 @@ public function load() {
       'name' => 'menu_override_parent_selector',
       'value' => 'b:1;',
     ))->values(array(
+      'name' => 'menu_parent_article',
+      'value' => 's:11:"main-menu:0";',
+    ))->values(array(
+      'name' => 'menu_parent_blog',
+      'value' => 's:11:"main-menu:0";',
+    ))->values(array(
+      'name' => 'menu_parent_book',
+      'value' => 's:11:"main-menu:0";',
+    ))->values(array(
+      'name' => 'menu_parent_forum',
+      'value' => 's:11:"main-menu:0";',
+    ))->values(array(
+      'name' => 'menu_parent_page',
+      'value' => 's:11:"main-menu:0";',
+    ))->values(array(
       'name' => 'menu_parent_test_content_type',
       'value' => 's:11:"main-menu:0";',
     ))->values(array(
@@ -236,8 +407,14 @@ public function load() {
       'name' => 'node_cron_last',
       'value' => 's:10:"1421727515";',
     ))->values(array(
+      'name' => 'node_options_article',
+      'value' => 'a:2:{i:0;s:6:"status";i:1;s:7:"promote";}',
+    ))->values(array(
+      'name' => 'node_options_blog',
+      'value' => 'a:2:{i:0;s:6:"status";i:1;s:7:"promote";}',
+    ))->values(array(
       'name' => 'node_options_book',
-      'value' => 'a:1:{i:0;s:6:"status";}',
+      'value' => 'a:2:{i:0;s:6:"status";i:1;s:8:"revision";}',
     ))->values(array(
       'name' => 'node_options_forum',
       'value' => 'a:1:{i:0;s:6:"status";}',
@@ -246,7 +423,22 @@ public function load() {
       'value' => 'a:1:{i:0;s:6:"status";}',
     ))->values(array(
       'name' => 'node_options_test_content_type',
-      'value' => 'a:2:{i:0;s:6:"status";i:1;s:7:"promote";}',
+      'value' => 'a:3:{i:0;s:6:"status";i:1;s:7:"promote";i:2;s:8:"revision";}',
+    ))->values(array(
+      'name' => 'node_preview_article',
+      'value' => 's:1:"1";',
+    ))->values(array(
+      'name' => 'node_preview_blog',
+      'value' => 's:1:"1";',
+    ))->values(array(
+      'name' => 'node_preview_book',
+      'value' => 's:1:"1";',
+    ))->values(array(
+      'name' => 'node_preview_forum',
+      'value' => 's:1:"1";',
+    ))->values(array(
+      'name' => 'node_preview_page',
+      'value' => 's:1:"1";',
     ))->values(array(
       'name' => 'node_preview_test_content_type',
       'value' => 's:1:"1";',
@@ -266,11 +458,23 @@ public function load() {
       'name' => 'node_rank_views',
       'value' => 's:1:"0";',
     ))->values(array(
+      'name' => 'node_submitted_article',
+      'value' => 'i:1;',
+    ))->values(array(
+      'name' => 'node_submitted_blog',
+      'value' => 'i:1;',
+    ))->values(array(
+      'name' => 'node_submitted_book',
+      'value' => 'i:1;',
+    ))->values(array(
+      'name' => 'node_submitted_forum',
+      'value' => 'i:1;',
+    ))->values(array(
       'name' => 'node_submitted_page',
-      'value' => 'b:0;',
+      'value' => 'i:0;',
     ))->values(array(
       'name' => 'node_submitted_test_content_type',
-      'value' => 'i:1;',
+      'value' => 'i:0;',
     ))->values(array(
       'name' => 'overlap_cjk',
       'value' => 'i:1;',
@@ -488,4 +692,4 @@ public function load() {
   }
 
 }
-#6c379107303f95fe9118597506168dc2
+#7dc2bf954651dff3a1774f619801d40b
diff --git a/core/modules/node/config/schema/node.source.schema.yml b/core/modules/node/config/schema/node.source.schema.yml
index a9d88e8..319072c 100644
--- a/core/modules/node/config/schema/node.source.schema.yml
+++ b/core/modules/node/config/schema/node.source.schema.yml
@@ -26,17 +26,33 @@ migrate.source.d6_node:
   label: 'Drupal 6 node'
   mapping:
     node_type:
-      # The node type can be specified both as a string ID of a node type or an
-      # array of node type IDs, so there is no way to consistently parse this.
-      type: ignore
+      type: string
+      label: 'Node type'
+
+migrate.source.d7_node:
+  type: migrate_source_sql
+  label: 'Drupal 7 node'
+  mapping:
+    node_type:
+      type: string
       label: 'Node type'
 
 migrate.source.d6_node_revision:
   type: migrate_source_sql
-  label: 'Drupal 6 node'
+  label: 'Drupal 6 node revision'
   mapping:
     node_type:
-      # The node type can be specified both as a string ID of a node type or an
-      # array of node type IDs, so there is no way to consistently parse this.
-      type: ignore
+      type: string
       label: 'Node type'
+
+migrate.source.d7_node_revision:
+  type: migrate_source_sql
+  label: 'Drupal 7 node revision'
+  mapping:
+    node_type:
+      type: string
+      label: 'Node type'
+
+migrate.source.d7_node_type:
+  type: migrate_source_sql
+  label: 'Drupal 7 node type'
diff --git a/core/modules/node/migration_templates/d6_node.yml b/core/modules/node/migration_templates/d6_node.yml
index 779bda1..c1acd0b 100644
--- a/core/modules/node/migration_templates/d6_node.yml
+++ b/core/modules/node/migration_templates/d6_node.yml
@@ -15,14 +15,11 @@ process:
     source: language
     default_value: "und"
   title: title
-  uid: node_uid
-# Core migrations are designed for replacing the upgrade path and therefore
-# all node and user ids are preserved. For that reason we do not need to look-up
-# the user id for the node. If you're writing a custom migration, user ids will
-# vary from the source site and a lookup as shown below will be required.
-#    plugin: migration
-#    migration: d6_user
-#    source: node_uid
+  uid:
+    plugin: migration
+    source:
+      - node_uid
+    migration: d6_user
   status: status
   created: created
   changed: changed
diff --git a/core/modules/node/migration_templates/d6_node_revision.yml b/core/modules/node/migration_templates/d6_node_revision.yml
index 9ba85d3..f448591 100644
--- a/core/modules/node/migration_templates/d6_node_revision.yml
+++ b/core/modules/node/migration_templates/d6_node_revision.yml
@@ -15,7 +15,10 @@ process:
     source: language
     default_value: "und"
   title: title
-  uid: node_uid
+    plugin: migration
+    source:
+      - node_uid
+    migration: d6_user
   status: status
   created: created
   changed: changed
diff --git a/core/modules/node/migration_templates/d6_node_revision.yml b/core/modules/node/migration_templates/d7_node.yml
similarity index 54%
copy from core/modules/node/migration_templates/d6_node_revision.yml
copy to core/modules/node/migration_templates/d7_node.yml
index 9ba85d3..15f13db 100644
--- a/core/modules/node/migration_templates/d6_node_revision.yml
+++ b/core/modules/node/migration_templates/d7_node.yml
@@ -1,11 +1,11 @@
-id: d6_node_revision
-label: Drupal 6 node revisions
+id: d7_node
+label: Drupal 7 nodes
 migration_tags:
-  - Drupal 6
+  - Drupal 7
 builder:
-  plugin: d6_node
+  plugin: d7_node
 source:
-  plugin: d6_node_revision
+  plugin: d7_node
 process:
   nid: nid
   vid: vid
@@ -15,30 +15,22 @@ process:
     source: language
     default_value: "und"
   title: title
-  uid: node_uid
+  uid:
+    plugin: migration
+    source:
+      - node_uid
+    migration: d7_user
   status: status
   created: created
   changed: changed
   promote: promote
   sticky: sticky
-  'body/format':
-    plugin: migration
-    migration: d6_filter_format
-    source: format
-  'body/value': body
-  'body/summary': teaser
   revision_uid: revision_uid
   revision_log: log
   revision_timestamp: timestamp
-
-#  unmapped d6 fields.
-#  tnid
-#  translate
-#  moderate
-#  comment
-
 destination:
-  plugin: entity_revision:node
+  plugin: entity:node
 migration_dependencies:
   required:
-    - d6_node:*
+    - d7_user
+    - d7_node_type
diff --git a/core/modules/node/migration_templates/d6_node_revision.yml b/core/modules/node/migration_templates/d7_node_revision.yml
similarity index 58%
copy from core/modules/node/migration_templates/d6_node_revision.yml
copy to core/modules/node/migration_templates/d7_node_revision.yml
index 9ba85d3..fe33a3f 100644
--- a/core/modules/node/migration_templates/d6_node_revision.yml
+++ b/core/modules/node/migration_templates/d7_node_revision.yml
@@ -1,11 +1,11 @@
-id: d6_node_revision
-label: Drupal 6 node revisions
+id: d7_node_revision
+label: Drupal 7 node revisions
 migration_tags:
-  - Drupal 6
+  - Drupal 7
 builder:
-  plugin: d6_node
+  plugin: d7_node
 source:
-  plugin: d6_node_revision
+  plugin: d7_node_revision
 process:
   nid: nid
   vid: vid
@@ -15,30 +15,21 @@ process:
     source: language
     default_value: "und"
   title: title
-  uid: node_uid
+  uid:
+    plugin: migration
+    source:
+      - node_uid
+    migration: d7_user
   status: status
   created: created
   changed: changed
   promote: promote
   sticky: sticky
-  'body/format':
-    plugin: migration
-    migration: d6_filter_format
-    source: format
-  'body/value': body
-  'body/summary': teaser
   revision_uid: revision_uid
   revision_log: log
   revision_timestamp: timestamp
-
-#  unmapped d6 fields.
-#  tnid
-#  translate
-#  moderate
-#  comment
-
 destination:
   plugin: entity_revision:node
 migration_dependencies:
   required:
-    - d6_node:*
+    - d7_node:*
diff --git a/core/modules/node/migration_templates/d7_node_settings.yml b/core/modules/node/migration_templates/d7_node_settings.yml
new file mode 100644
index 0000000..adff19c
--- /dev/null
+++ b/core/modules/node/migration_templates/d7_node_settings.yml
@@ -0,0 +1,13 @@
+id: d7_node_settings
+label: Drupal 7 node configuration
+migration_tags:
+  - Drupal 7
+source:
+  plugin: variable
+  variables:
+    - node_admin_theme
+process:
+  use_admin_theme: node_admin_theme
+destination:
+  plugin: config
+  config_name: node.settings
diff --git a/core/modules/node/migration_templates/d7_node_title_label.yml b/core/modules/node/migration_templates/d7_node_title_label.yml
new file mode 100644
index 0000000..2024949
--- /dev/null
+++ b/core/modules/node/migration_templates/d7_node_title_label.yml
@@ -0,0 +1,19 @@
+id: d7_node_title_label
+label: Drupal 7 node title label
+migration_tags:
+  - Drupal 7
+source:
+  plugin: d7_node_type
+  constants:
+    entity_type: node
+    field_name: title
+process:
+  entity_type: 'constants/entity_type'
+  bundle: type
+  field_name: 'constants/field_name'
+  label: title_label
+destination:
+  plugin: entity:base_field_override
+migration_dependencies:
+  required:
+    - d7_node_type
diff --git a/core/modules/node/migration_templates/d7_node_type.yml b/core/modules/node/migration_templates/d7_node_type.yml
new file mode 100644
index 0000000..c8e0dd0
--- /dev/null
+++ b/core/modules/node/migration_templates/d7_node_type.yml
@@ -0,0 +1,21 @@
+id: d7_node_type
+label: Drupal 7 node type configuration
+migration_tags:
+  - Drupal 7
+source:
+  plugin: d7_node_type
+  constants:
+    preview: 1 # DRUPAL_OPTIONAL
+process:
+  type: type
+  name: name
+  description: description
+  help: help
+  title_label: title_label
+  preview_mode: 'constants/preview'
+  display_submitted: display_submitted
+  new_revision: 'options/revision'
+  create_body: create_body
+  create_body_label: body_label
+destination:
+  plugin: entity:node_type
diff --git a/core/modules/node/src/Plugin/migrate/builder/d7/Node.php b/core/modules/node/src/Plugin/migrate/builder/d7/Node.php
new file mode 100644
index 0000000..8b1dda3
--- /dev/null
+++ b/core/modules/node/src/Plugin/migrate/builder/d7/Node.php
@@ -0,0 +1,52 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\node\Plugin\migrate\builder\d7\Node.
+ */
+
+namespace Drupal\node\Plugin\migrate\builder\d7;
+
+use Drupal\migrate\Entity\Migration;
+use Drupal\migrate\Plugin\migrate\builder\BuilderBase;
+
+/**
+ * @PluginID("d7_node")
+ */
+class Node extends BuilderBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildMigrations(array $template) {
+    $migrations = [];
+
+    $fields = [];
+    foreach ($this->getSourcePlugin('d7_field_instance', $template['source']) as $field) {
+      $entity_type = $field->getSourceProperty('entity_type');
+      $bundle = $field->getSourceProperty('bundle');
+      $field_name = $field->getSourceProperty('field_name');
+      $fields[$entity_type][$bundle][$field_name] = $field->getSource();
+    }
+
+    foreach ($this->getSourcePlugin('d7_node_type', $template['source']) as $node_type) {
+      $bundle = $node_type->getSourceProperty('type');
+      $values = $template;
+      $values['id'] .= '__' . $bundle;
+      $values['label'] = $this->t('@label (@type)', ['@label' => $values['label'], '@type' => $node_type->getSourceProperty('name')]);
+      $values['source']['node_type'] = $bundle;
+      $migration = Migration::create($values);
+
+      if (isset($fields['node'][$bundle])) {
+        foreach (array_keys($fields['node'][$bundle]) as $field) {
+          $migration->setProcessOfProperty($field, $field);
+        }
+      }
+
+      $migrations[] = $migration;
+    }
+
+    return $migrations;
+  }
+
+}
diff --git a/core/modules/node/src/Plugin/migrate/source/d7/Node.php b/core/modules/node/src/Plugin/migrate/source/d7/Node.php
new file mode 100644
index 0000000..2c3b6ad
--- /dev/null
+++ b/core/modules/node/src/Plugin/migrate/source/d7/Node.php
@@ -0,0 +1,109 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\node\Plugin\migrate\source\d7\Node.
+ */
+
+namespace Drupal\node\Plugin\migrate\source\d7;
+
+use Drupal\migrate\Row;
+use Drupal\migrate_drupal\Plugin\migrate\source\d7\FieldableEntity;
+
+/**
+ * Drupal 7 node source from database.
+ *
+ * @MigrateSource(
+ *   id = "d7_node",
+ *   source_provider = "node"
+ * )
+ */
+class Node extends FieldableEntity {
+
+  /**
+   * The join options between the node and the node_revisions table.
+   */
+  const JOIN = 'n.vid = nr.vid';
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+    // Select node in its last revision.
+    $query = $this->select('node_revision', 'nr')
+      ->fields('n', array(
+        'nid',
+        'type',
+        'language',
+        'status',
+        'created',
+        'changed',
+        'comment',
+        'promote',
+        'sticky',
+        'tnid',
+        'translate',
+      ))
+      ->fields('nr', array(
+        'vid',
+        'title',
+        'log',
+        'timestamp',
+      ));
+    $query->addField('n', 'uid', 'node_uid');
+    $query->addField('nr', 'uid', 'revision_uid');
+    $query->innerJoin('node', 'n', static::JOIN);
+
+    if (isset($this->configuration['node_type'])) {
+      $query->condition('type', $this->configuration['node_type']);
+    }
+
+    return $query;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function prepareRow(Row $row) {
+    // Get Field API field values.
+    foreach (array_keys($this->getFields('node', $row->getSourceProperty('type'))) as $field) {
+      $nid = $row->getSourceProperty('nid');
+      $vid = $row->getSourceProperty('vid');
+      $row->setSourceProperty($field, $this->getFieldValues('node', $field, $nid, $vid));
+    }
+    return parent::prepareRow($row);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fields() {
+    $fields = array(
+      'nid' => $this->t('Node ID'),
+      'type' => $this->t('Type'),
+      'title' => $this->t('Title'),
+      'node_uid' => $this->t('Node authored by (uid)'),
+      'revision_uid' => $this->t('Revision authored by (uid)'),
+      'created' => $this->t('Created timestamp'),
+      'changed' => $this->t('Modified timestamp'),
+      'status' => $this->t('Published'),
+      'promote' => $this->t('Promoted to front page'),
+      'sticky' => $this->t('Sticky at top of lists'),
+      'revision' => $this->t('Create new revision'),
+      'language' => $this->t('Language (fr, en, ...)'),
+      'tnid' => $this->t('The translation set id for this node'),
+      'timestamp' => $this->t('The timestamp the latest revision of this node was created.'),
+    );
+    return $fields;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    $ids['nid']['type'] = 'integer';
+    $ids['nid']['alias'] = 'n';
+    return $ids;
+  }
+
+}
diff --git a/core/modules/node/src/Plugin/migrate/source/d7/NodeRevision.php b/core/modules/node/src/Plugin/migrate/source/d7/NodeRevision.php
new file mode 100644
index 0000000..0e18186
--- /dev/null
+++ b/core/modules/node/src/Plugin/migrate/source/d7/NodeRevision.php
@@ -0,0 +1,46 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\node\Plugin\migrate\source\d7\NodeRevision.
+ */
+
+namespace Drupal\node\Plugin\migrate\source\d7;
+
+/**
+ * Drupal 7 node revision source from database.
+ *
+ * @MigrateSource(
+ *   id = "d7_node_revision",
+ *   source_provider = "node"
+ * )
+ */
+class NodeRevision extends Node {
+
+  /**
+   * The join options between the node and the node_revisions_table.
+   */
+  const JOIN = 'n.nid = nr.nid AND n.vid <> nr.vid';
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fields() {
+    // Use all the node fields plus the vid that identifies the version.
+    return parent::fields() + array(
+      'vid' => t('The primary identifier for this version.'),
+      'log' => $this->t('Revision Log message'),
+      'timestamp' => $this->t('Revision timestamp'),
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    $ids['vid']['type'] = 'integer';
+    $ids['vid']['alias'] = 'nr';
+    return $ids;
+  }
+
+}
diff --git a/core/modules/node/src/Plugin/migrate/source/d7/NodeType.php b/core/modules/node/src/Plugin/migrate/source/d7/NodeType.php
new file mode 100644
index 0000000..d496363
--- /dev/null
+++ b/core/modules/node/src/Plugin/migrate/source/d7/NodeType.php
@@ -0,0 +1,120 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\node\Plugin\migrate\source\d7\NodeType.
+ */
+
+namespace Drupal\node\Plugin\migrate\source\d7;
+
+use Drupal\migrate\Row;
+use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
+
+/**
+ * Drupal 7 Node types source from database.
+ *
+ * @MigrateSource(
+ *   id = "d7_node_type",
+ *   source_provider = "node"
+ * )
+ */
+class NodeType extends DrupalSqlBase {
+
+  /**
+   * The teaser length
+   *
+   * @var int
+   */
+  protected $teaserLength;
+
+  /**
+   * Node preview optional / required.
+   *
+   * @var int
+   */
+  protected $nodePreview;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+    return $this->select('node_type', 't')->fields('t');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fields() {
+    return array(
+      'type' => $this->t('Machine name of the node type.'),
+      'name' => $this->t('Human name of the node type.'),
+      'description' => $this->t('Description of the node type.'),
+      'help' => $this->t('Help text for the node type.'),
+      'title_label' => $this->t('Title label.'),
+      'disabled' => $this->t('Flag indicating the node type is enable'),
+      'base' => $this->t('base node.'),
+      'custom' => $this->t('Flag.'),
+      'modified' => $this->t('Flag.'),
+      'locked' => $this->t('Flag.'),
+      'orig_type' => $this->t('The original type.'),
+      'teaser_length' => $this->t('Teaser length'),
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function initializeIterator() {
+    $this->teaserLength = $this->variableGet('teaser_length', 600);
+    $this->nodePreview = $this->variableGet('node_preview', 0);
+    return parent::initializeIterator();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function prepareRow(Row $row) {
+    $row->setSourceProperty('teaser_length', $this->teaserLength);
+    $row->setSourceProperty('node_preview', $this->nodePreview);
+
+    $type = $row->getSourceProperty('type');
+    $source_options = $this->variableGet('node_options_' . $type, array('promote', 'sticky'));
+    $options = array();
+    foreach (array('promote', 'sticky', 'status', 'revision') as $item) {
+      $options[$item] = in_array($item, $source_options);
+    }
+    $row->setSourceProperty('options', $options);
+
+    // Don't create a body field until we prove that this node type has one.
+    $row->setSourceProperty('create_body', FALSE);
+
+    if ($this->moduleExists('field')) {
+      // Find body field for this node type.
+      $body = $this->select('field_config_instance', 'fci')
+        ->fields('fci', array('data'))
+        ->condition('entity_type', 'node')
+        ->condition('bundle', $row->getSourceProperty('type'))
+        ->condition('field_name', 'body')
+        ->execute()
+        ->fetchAssoc();
+      if ($body) {
+        $row->setSourceProperty('create_body', TRUE);
+        $body['data'] = unserialize($body['data']);
+        $row->setSourceProperty('body_label', $body['data']['label']);
+      }
+    }
+
+    $row->setSourceProperty('display_submitted', $this->variableGet('node_submitted_' . $type, TRUE));
+
+    return parent::prepareRow($row);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    $ids['type']['type'] = 'string';
+    return $ids;
+  }
+
+}
diff --git a/core/modules/node/src/Tests/Migrate/d7/MigrateNodeSettingsTest.php b/core/modules/node/src/Tests/Migrate/d7/MigrateNodeSettingsTest.php
new file mode 100644
index 0000000..0bccde9
--- /dev/null
+++ b/core/modules/node/src/Tests/Migrate/d7/MigrateNodeSettingsTest.php
@@ -0,0 +1,45 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\node\Tests\Migrate\d7\MigrateNodeSettingsTest.
+ */
+
+namespace Drupal\node\Tests\Migrate\d7;
+
+use Drupal\config\Tests\SchemaCheckTestTrait;
+use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
+
+/**
+ * Upgrade variables to node.settings config object.
+ *
+ * @group node
+ */
+class MigrateNodeSettingsTest extends MigrateDrupal7TestBase {
+
+  use SchemaCheckTestTrait;
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['node'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->executeMigration('d7_node_settings');
+  }
+
+  /**
+   * Tests migration of node variables to node.settings config object.
+   */
+  public function testAggregatorSettings() {
+    $config = $this->config('node.settings');
+    $this->assertEqual(1, $config->get('use_admin_theme'));
+  }
+
+}
diff --git a/core/modules/node/src/Tests/Migrate/d7/MigrateNodeTest.php b/core/modules/node/src/Tests/Migrate/d7/MigrateNodeTest.php
new file mode 100644
index 0000000..f6681f8
--- /dev/null
+++ b/core/modules/node/src/Tests/Migrate/d7/MigrateNodeTest.php
@@ -0,0 +1,112 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\node\Tests\Migrate\d7\MigrateNodeTest.
+ */
+
+namespace Drupal\node\Tests\Migrate\d7;
+
+use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
+use Drupal\node\Entity\Node;
+use Drupal\node\NodeInterface;
+
+/**
+ * Tests node migration.
+ *
+ * @group node
+ */
+class MigrateNodeTest extends MigrateDrupal7TestBase {
+
+  static $modules = array('node', 'text', 'filter', 'entity_reference');
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->installEntitySchema('node');
+    $this->installConfig(['node']);
+    $this->installSchema('node', ['node_access']);
+    $this->installSchema('system', ['sequences']);
+
+    $this->executeMigration('d7_user_role');
+    $this->executeMigration('d7_user');
+    $this->executeMigration('d7_node_type');
+    $this->executeMigration('d7_node__test_content_type');
+  }
+
+  /**
+   * Asserts various aspects of a node.
+   *
+   * @param string $id
+   *   The node ID.
+   * @param string $type
+   *   The node type.
+   * @param string $langcode
+   *   The expected language code.
+   * @param string $title
+   *   The expected title.
+   * @param int $uid
+   *   The expected author ID.
+   * @param bool $status
+   *   The expected status of the node.
+   * @param int $created
+   *   The expected creation time.
+   * @param int $changed
+   *   The expected modification time.
+   * @param bool $promoted
+   *   Whether the node is expected to be promoted to the front page.
+   * @param bool $sticky
+   *   Whether the node is expected to be sticky.
+   */
+  protected function assertEntity($id, $type, $langcode, $title, $uid, $status, $created, $changed, $promoted, $sticky) {
+    /** @var \Drupal\node\NodeInterface $node */
+    $node = Node::load($id);
+    $this->assertTrue($node instanceof NodeInterface);
+    $this->assertIdentical($type, $node->getType());
+    $this->assertIdentical($langcode, $node->langcode->value);
+    $this->assertIdentical($title, $node->getTitle());
+    $this->assertIdentical($uid, $node->getOwnerId());
+    $this->assertIdentical($status, $node->isPublished());
+    $this->assertIdentical($created, $node->getCreatedTime());
+    if (isset($changed)) {
+      $this->assertIdentical($changed, $node->getChangedTime());
+    }
+    $this->assertIdentical($promoted, $node->isPromoted());
+    $this->assertIdentical($sticky, $node->isSticky());
+  }
+
+  /**
+   * Asserts various aspects of a node revision.
+   *
+   * @param int $id
+   *   The revision ID.
+   * @param string $title
+   *   The expected title.
+   * @param int $uid
+   *   The revision author ID.
+   * @param string $log
+   *   The revision log message.
+   * @param int $timestamp
+   *   The revision's time stamp.
+   */
+  protected function assertRevision($id, $title, $uid, $log, $timestamp) {
+    $revision = \Drupal::entityManager()->getStorage('node')->loadRevision($id);
+    $this->assertTrue($revision instanceof NodeInterface);
+    $this->assertIdentical($title, $revision->getTitle());
+    $this->assertIdentical($uid, $revision->getRevisionAuthor()->id());
+    $this->assertIdentical($log, $revision->revision_log->value);
+    $this->assertIdentical($timestamp, $revision->getRevisionCreationTime());
+  }
+
+  /**
+   * Test node migration from Drupal 7 to 8.
+   */
+  public function testNode() {
+    $this->assertEntity(1, 'test_content_type', 'en', 'A Node', '2', TRUE, '1421727515', '1441032132', TRUE, FALSE);
+    $this->assertRevision(1, 'A Node', '2', NULL, '1441032132');
+  }
+
+}
diff --git a/core/modules/node/src/Tests/Migrate/d7/MigrateNodeTitleLabelTest.php b/core/modules/node/src/Tests/Migrate/d7/MigrateNodeTitleLabelTest.php
new file mode 100644
index 0000000..4817288
--- /dev/null
+++ b/core/modules/node/src/Tests/Migrate/d7/MigrateNodeTitleLabelTest.php
@@ -0,0 +1,60 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\node\Tests\Migrate\d7\MigrateNodeTitleLabelTest.
+ */
+
+namespace Drupal\node\Tests\Migrate\d7;
+
+use Drupal\Core\Field\Entity\BaseFieldOverride;
+use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
+
+/**
+ * Tests migration of the title field label for node types.
+ *
+ * @group node
+ */
+class MigrateNodeTitleLabelTest extends MigrateDrupal7TestBase {
+
+  public static $modules = ['node', 'text'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->installConfig(static::$modules);
+    $this->installEntitySchema('node');
+    $this->executeMigration('d7_node_type');
+    $this->executeMigration('d7_node_title_label');
+  }
+
+  /**
+   * Asserts various aspects of a base_field_override entity.
+   *
+   * @param string $id
+   *   The override ID.
+   * @param string $label
+   *   The label's expected (overridden) value.
+   */
+  protected function assertEntity($id, $label) {
+    $override = BaseFieldOverride::load($id);
+    $this->assertTrue($override instanceof BaseFieldOverride);
+    /** @var \Drupal\Core\Field\Entity\BaseFieldOverride $override */
+    $this->assertIdentical($label, $override->getLabel());
+  }
+
+  /**
+   * Tests migration of node title field overrides.
+   */
+  public function testMigration() {
+    $this->assertEntity('node.article.title', 'Title');
+    $this->assertEntity('node.blog.title', 'Title');
+    $this->assertEntity('node.book.title', 'Title');
+    $this->assertEntity('node.forum.title', 'Subject');
+    $this->assertEntity('node.page.title', 'Title');
+    $this->assertEntity('node.test_content_type.title', 'Title');
+  }
+
+}
diff --git a/core/modules/node/src/Tests/Migrate/d7/MigrateNodeTypeTest.php b/core/modules/node/src/Tests/Migrate/d7/MigrateNodeTypeTest.php
new file mode 100644
index 0000000..c3706a9
--- /dev/null
+++ b/core/modules/node/src/Tests/Migrate/d7/MigrateNodeTypeTest.php
@@ -0,0 +1,85 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\node\Tests\Migrate\d7\MigrateNodeTypeTest.
+ */
+
+namespace Drupal\node\Tests\Migrate\d7;
+
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\FieldConfigInterface;
+use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
+use Drupal\node\Entity\NodeType;
+use Drupal\node\NodeTypeInterface;
+
+/**
+ * Upgrade node types to node.type.*.yml.
+ *
+ * @group node
+ */
+class MigrateNodeTypeTest extends MigrateDrupal7TestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('node', 'text', 'filter');
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->installConfig(array('node'));
+    $this->executeMigration('d7_node_type');
+  }
+
+  /**
+   * Tests a single node type.
+   *
+   * @dataProvider testNodeTypeDataProvider
+   * @param string $id
+   *  The node type ID.
+   * @param string $label
+   *  The expected label.
+   * @param string $description
+   *  The expected node type description.
+   * @param string $help
+   *  The expected help text.
+   */
+  protected function assertEntity($id, $label, $description, $help, $display_submitted, $new_revision, $body_label = NULL) {
+    /** @var \Drupal\node\NodeTypeInterface $entity */
+    $entity = NodeType::load($id);
+    $this->assertTrue($entity instanceof NodeTypeInterface);
+    $this->assertIdentical($label, $entity->label());
+    $this->assertIdentical($description, $entity->getDescription());
+    $this->assertIdentical($help, $entity->getHelp());
+
+    $this->assertIdentical($display_submitted, $entity->displaySubmitted(), 'Submission info is displayed');
+    $this->assertIdentical($new_revision, $entity->isNewRevision(), 'Is a new revision');
+
+    if ($body_label) {
+      /** @var \Drupal\field\FieldConfigInterface $body */
+      $body = FieldConfig::load('node.' . $id . '.body');
+      $this->assertTrue($body instanceof FieldConfigInterface);
+      $this->assertIdentical($body_label, $body->label());
+    }
+  }
+
+  /**
+   * Tests Drupal 7 node type to Drupal 8 migration.
+   */
+  public function testNodeType() {
+    $this->assertEntity('article', 'Article', 'Use <em>articles</em> for time-sensitive content like news, press releases or blog posts.', 'Help text for articles', TRUE, FALSE, "Body");
+    $this->assertEntity('blog', 'Blog entry', 'Use for multi-user blogs. Every user gets a personal blog.', 'Blog away, good sir!', TRUE, FALSE, 'Body');
+    // book's display_submitted flag is not set, so it will default to TRUE.
+    $this->assertEntity('book', 'Book page', '<em>Books</em> have a built-in hierarchical navigation. Use for handbooks or tutorials.', '', TRUE, TRUE, "Body");
+    $this->assertEntity('forum', 'Forum topic', 'A <em>forum topic</em> starts a new discussion thread within a forum.', 'No name-calling, no flame wars. Be nice.', TRUE, FALSE, 'Body');
+    $this->assertEntity('page', 'Basic page', "Use <em>basic pages</em> for your static content, such as an 'About us' page.", 'Help text for basic pages', FALSE, FALSE, "Body");
+    // This node type does not carry a body field.
+    $this->assertEntity('test_content_type', 'Test content type', 'This is the description of the test content type.', 'Help text for test content type', FALSE, TRUE);
+  }
+
+}
diff --git a/core/modules/node/src/Tests/Migrate/d7/NodeBuilderTest.php b/core/modules/node/src/Tests/Migrate/d7/NodeBuilderTest.php
new file mode 100644
index 0000000..09172f7
--- /dev/null
+++ b/core/modules/node/src/Tests/Migrate/d7/NodeBuilderTest.php
@@ -0,0 +1,41 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\node\Tests\Migrate\d7\NodeBuilderTest.
+ */
+
+namespace Drupal\node\Tests\Migrate\d7;
+
+use Drupal\migrate\Entity\Migration;
+use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
+
+/**
+ * Tests the d7_node builder.
+ *
+ * @group node
+ */
+class NodeBuilderTest extends MigrateDrupal7TestBase {
+
+  public static $modules = ['node'];
+
+  public function testBuilder() {
+    $process = Migration::load('d7_node__test_content_type')->getProcess();
+    $this->assertIdentical('field_boolean', $process['field_boolean'][0]['source']);
+    $this->assertIdentical('field_email', $process['field_email'][0]['source']);
+    $this->assertIdentical('field_phone', $process['field_phone'][0]['source']);
+    $this->assertIdentical('field_date', $process['field_date'][0]['source']);
+    $this->assertIdentical('field_date_with_end_time', $process['field_date_with_end_time'][0]['source']);
+    $this->assertIdentical('field_file', $process['field_file'][0]['source']);
+    $this->assertIdentical('field_float', $process['field_float'][0]['source']);
+    $this->assertIdentical('field_images', $process['field_images'][0]['source']);
+    $this->assertIdentical('field_integer', $process['field_integer'][0]['source']);
+    $this->assertIdentical('field_link', $process['field_link'][0]['source']);
+    $this->assertIdentical('field_text_list', $process['field_text_list'][0]['source']);
+    $this->assertIdentical('field_integer_list', $process['field_integer_list'][0]['source']);
+    $this->assertIdentical('field_long_text', $process['field_long_text'][0]['source']);
+    $this->assertIdentical('field_term_reference', $process['field_term_reference'][0]['source']);
+    $this->assertIdentical('field_text', $process['field_text'][0]['source']);
+  }
+
+}
diff --git a/core/modules/node/tests/src/Unit/Plugin/migrate/source/d7/NodeTest.php b/core/modules/node/tests/src/Unit/Plugin/migrate/source/d7/NodeTest.php
new file mode 100644
index 0000000..c94cb40
--- /dev/null
+++ b/core/modules/node/tests/src/Unit/Plugin/migrate/source/d7/NodeTest.php
@@ -0,0 +1,152 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\node\Unit\Plugin\migrate\source\d7\NodeTest.
+ */
+
+namespace Drupal\Tests\node\Unit\Plugin\migrate\source\d7;
+
+use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
+
+/**
+ * Tests D7 node source plugin.
+ *
+ * @group node
+ */
+class NodeTest extends MigrateSqlSourceTestCase {
+
+  const PLUGIN_CLASS = 'Drupal\node\Plugin\migrate\source\d7\Node';
+
+  protected $migrationConfiguration = array(
+    'id' => 'test',
+    'source' => array(
+      'plugin' => 'd7_node',
+    ),
+  );
+
+  protected $expectedResults = array(
+    array(
+      // Node fields.
+      'nid' => 1,
+      'vid' => 1,
+      'type' => 'page',
+      'language' => 'en',
+      'title' => 'node title 1',
+      'uid' => 1,
+      'status' => 1,
+      'created' => 1279051598,
+      'changed' => 1279051598,
+      'comment' => 2,
+      'promote' => 1,
+      'sticky' => 0,
+      'tnid' => 0,
+      'translate' => 0,
+      'log' => '',
+      'timestamp' => 1279051598,
+    ),
+    array(
+      // Node fields.
+      'nid' => 2,
+      'vid' => 2,
+      'type' => 'page',
+      'language' => 'en',
+      'title' => 'node title 2',
+      'uid' => 1,
+      'status' => 1,
+      'created' => 1279290908,
+      'changed' => 1279308993,
+      'comment' => 0,
+      'promote' => 1,
+      'sticky' => 0,
+      'tnid' => 0,
+      'translate' => 0,
+      'log' => '',
+      'timestamp' => 1279308993,
+    ),
+    array(
+      // Node fields.
+      'nid' => 5,
+      'vid' => 5,
+      'type' => 'article',
+      'language' => 'en',
+      'title' => 'node title 5',
+      'uid' => 1,
+      'status' => 1,
+      'created' => 1279290908,
+      'changed' => 1279308993,
+      'comment' => 0,
+      'promote' => 1,
+      'sticky' => 0,
+      'tnid' => 0,
+      'translate' => 0,
+      'log' => '',
+      'timestamp' => 1279308993,
+    ),
+  );
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    foreach ($this->expectedResults as $k => $row) {
+      foreach (array('nid', 'vid', 'title', 'uid', 'timestamp', 'log') as $field) {
+        $this->databaseContents['node_revision'][$k][$field] = $row[$field];
+        switch ($field) {
+          case 'nid': case 'vid':
+            break;
+          case 'uid':
+            $this->databaseContents['node_revision'][$k]['uid']++;
+            break;
+          default:
+            unset($row[$field]);
+            break;
+        }
+      }
+      $this->databaseContents['node'][$k] = $row;
+    }
+    array_walk($this->expectedResults, function (&$row) {
+      $row['node_uid'] = $row['uid'];
+      $row['revision_uid'] = $row['uid'] + 1;
+      unset($row['uid']);
+    });
+
+    $this->databaseContents['field_config_instance'] = array(
+      array(
+        'id' => '2',
+        'field_id' => '2',
+        'field_name' => 'body',
+        'entity_type' => 'node',
+        'bundle' => 'page',
+        'data' => 'a:0:{}',
+        'deleted' => '0',
+      ),
+      array(
+        'id' => '2',
+        'field_id' => '2',
+        'field_name' => 'body',
+        'entity_type' => 'node',
+        'bundle' => 'article',
+        'data' => 'a:0:{}',
+        'deleted' => '0',
+      ),
+    );
+    $this->databaseContents['field_revision_body'] = array(
+      array(
+        'entity_type' => 'node',
+        'bundle' => 'page',
+        'deleted' => '0',
+        'entity_id' => '1',
+        'revision_id' => '1',
+        'language' => 'en',
+        'delta' => '0',
+        'body_value' => 'Foobaz',
+        'body_summary' => '',
+        'body_format' => 'filtered_html',
+      ),
+    );
+
+    parent::setUp();
+  }
+
+}
diff --git a/core/modules/node/tests/src/Unit/Plugin/migrate/source/d7/NodeTypeTest.php b/core/modules/node/tests/src/Unit/Plugin/migrate/source/d7/NodeTypeTest.php
new file mode 100644
index 0000000..5f444b0
--- /dev/null
+++ b/core/modules/node/tests/src/Unit/Plugin/migrate/source/d7/NodeTypeTest.php
@@ -0,0 +1,89 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\node\Unit\Plugin\migrate\source\d7\NodeTypeTest.
+ */
+
+namespace Drupal\Tests\node\Unit\Plugin\migrate\source\d7;
+
+use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
+
+/**
+ * Tests D7 node type source plugin.
+ *
+ * @group node
+ */
+class NodeTypeTest extends MigrateSqlSourceTestCase {
+
+  const PLUGIN_CLASS = 'Drupal\node\Plugin\migrate\source\d7\NodeType';
+
+  protected $migrationConfiguration = array(
+    'id' => 'test_nodetypes',
+    'source' => array(
+      'plugin' => 'd7_node_type',
+    ),
+  );
+
+  protected $expectedResults = array(
+    array(
+      'type' => 'page',
+      'name' => 'Page',
+      'base' => 'node',
+      'description' => 'A <em>page</em>, similar in form to a <em>story</em>, is a simple method for creating and displaying information that rarely changes, such as an "About us" section of a website. By default, a <em>page</em> entry does not allow visitor comments and is not featured on the site\'s initial home page.',
+      'help' => '',
+      'title_label' => 'Title',
+      'custom' => 1,
+      'modified' => 0,
+      'locked' => 0,
+      'disabled' => 0,
+      'orig_type' => 'page',
+    ),
+    array(
+      'type' => 'story',
+      'name' => 'Story',
+      'base' => 'node',
+      'description' => 'A <em>story</em>, similar in form to a <em>page</em>, is ideal for creating and displaying content that informs or engages website visitors. Press releases, site announcements, and informal blog-like entries may all be created with a <em>story</em> entry. By default, a <em>story</em> entry is automatically featured on the site\'s initial home page, and provides the ability to post comments.',
+      'help' => '',
+      'title_label' => 'Title',
+      'custom' => 1,
+      'modified' => 0,
+      'locked' => 0,
+      'disabled' => 0,
+      'orig_type' => 'story',
+    ),
+  );
+
+  /**
+   * Prepopulate contents with results.
+   */
+  protected function setUp() {
+    $this->databaseContents['node_type'] = $this->expectedResults;
+    $this->databaseContents['variable'] = array(
+      array(
+        'name' => 'node_options_page',
+        'value' => 'a:1:{i:0;s:6:"status";}',
+      ),
+      array(
+        'name' => 'node_options_story',
+        'value' => 'a:1:{i:0;s:6:"status";}',
+      ),
+    );
+    $this->databaseContents['field_config_instance'] = array(
+      array(
+        'entity_type' => 'node',
+        'bundle' => 'page',
+        'field_name' => 'body',
+        'data' => 'a:1:{s:5:"label";s:4:"Body";}',
+      ),
+      array(
+        'entity_type' => 'node',
+        'bundle' => 'story',
+        'field_name' => 'body',
+        'data' => 'a:1:{s:5:"label";s:4:"Body";}',
+      )
+    );
+    parent::setUp();
+  }
+
+}
