diff --git a/core/includes/menu.inc b/core/includes/menu.inc
index 915f809..2486594 100644
--- a/core/includes/menu.inc
+++ b/core/includes/menu.inc
@@ -1008,7 +1008,7 @@ function menu_item_route_access(Route $route, $href, &$map) {
  * "story" content type:
  * @code
  * $node = menu_get_object();
- * $story = $node->type == 'story';
+ * $story = $node->getType() == 'story';
  * @endcode
  *
  * @param $type
diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index d0161ab..8cbdd1b 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -2534,7 +2534,7 @@ function template_preprocess_html(&$variables) {
 
   // If on an individual node page, add the node type to body classes.
   if ($node = menu_get_object()) {
-    $variables['attributes']['class'][] = drupal_html_class('node-type-' . $node->type);
+    $variables['attributes']['class'][] = drupal_html_class('node-type-' . $node->getType());
   }
 
   // Initializes attributes which are specific to the html and body elements.
diff --git a/core/lib/Drupal/Core/Entity/EntityAccessController.php b/core/lib/Drupal/Core/Entity/EntityAccessController.php
index 164b83e..4658d50 100644
--- a/core/lib/Drupal/Core/Entity/EntityAccessController.php
+++ b/core/lib/Drupal/Core/Entity/EntityAccessController.php
@@ -58,7 +58,7 @@ public function access(EntityInterface $entity, $operation, $langcode = Language
     // We grant access to the entity if both of these conditions are met:
     // - No modules say to deny access.
     // - At least one module says to grant access.
-    $access = module_invoke_all($entity->entityType() . '_access', $entity->getBCEntity(), $operation, $account, $langcode);
+    $access = module_invoke_all($entity->entityType() . '_access', $entity, $operation, $account, $langcode);
 
     if (($return = $this->processAccessHookResults($access)) === NULL) {
       // No module had an opinion about the access, so let's the access
diff --git a/core/lib/Drupal/Core/Entity/EntityFormController.php b/core/lib/Drupal/Core/Entity/EntityFormController.php
index ceb09de..e148048 100644
--- a/core/lib/Drupal/Core/Entity/EntityFormController.php
+++ b/core/lib/Drupal/Core/Entity/EntityFormController.php
@@ -506,9 +506,7 @@ public function getEntity() {
    */
   protected function getTranslatedEntity(array $form_state) {
     $langcode = $this->getFormLangcode($form_state);
-    $translation = $this->entity->getTranslation($langcode);
-    // Ensure that the entity object is a BC entity if the original one is.
-    return $this->entity instanceof EntityBCDecorator ? $translation->getBCEntity() : $translation;
+    return $this->entity->getTranslation($langcode);
   }
 
   /**
diff --git a/core/modules/action/lib/Drupal/action/Tests/BulkFormTest.php b/core/modules/action/lib/Drupal/action/Tests/BulkFormTest.php
index 8a86279..2ae5dea 100644
--- a/core/modules/action/lib/Drupal/action/Tests/BulkFormTest.php
+++ b/core/modules/action/lib/Drupal/action/Tests/BulkFormTest.php
@@ -64,14 +64,14 @@ public function testBulkForm() {
 
     foreach ($nodes as $node) {
       $changed_node = node_load($node->id());
-      $this->assertTrue($changed_node->sticky, format_string('Node @nid got marked as sticky.', array('@nid' => $node->id())));
+      $this->assertTrue($changed_node->isSticky(), format_string('Node @nid got marked as sticky.', array('@nid' => $node->id())));
     }
 
     $this->assertText('Make content sticky was applied to 10 items.');
 
     // Unpublish just one node.
     $node = node_load($nodes[0]->id());
-    $this->assertTrue($node->status, 'The node is published.');
+    $this->assertTrue($node->isPublished(), 'The node is published.');
 
     $edit = array('action_bulk_form[0]' => TRUE, 'action' => 'node_unpublish_action');
     $this->drupalPost(NULL, $edit, t('Apply'));
@@ -80,11 +80,11 @@ public function testBulkForm() {
 
     // Load the node again.
     $node = node_load($node->id(), TRUE);
-    $this->assertFalse($node->status, 'A single node has been unpublished.');
+    $this->assertFalse($node->isPublished(), 'A single node has been unpublished.');
 
     // The second node should still be published.
     $node = node_load($nodes[1]->id(), TRUE);
-    $this->assertTrue($node->status, 'An unchecked node is still published.');
+    $this->assertTrue($node->isPublished(), 'An unchecked node is still published.');
 
     // Set up to include just the sticky actions.
     $view = views_get_view('test_bulk_form');
diff --git a/core/modules/book/book.admin.inc b/core/modules/book/book.admin.inc
index 611537b..07ba878 100644
--- a/core/modules/book/book.admin.inc
+++ b/core/modules/book/book.admin.inc
@@ -79,11 +79,10 @@ function book_admin_edit_submit($form, &$form_state) {
       // Update the title if changed.
       if ($row['title']['#default_value'] != $values['title']) {
         $node = node_load($values['nid']);
-        $langcode = Language::LANGCODE_NOT_SPECIFIED;
         $node->title = $values['title'];
-        $node->book['link_title'] = $values['title'];
+        $node->book->link_title = $values['title'];
         $node->setNewRevision();
-        $node->log = t('Title changed from %original to %current.', array('%original' => $node->title, '%current' => $values['title']));
+        $node->log = t('Title changed from %original to %current.', array('%original' => $node->label(), '%current' => $values['title']));
 
         $node->save();
         watchdog('content', 'book: updated %title.', array('%title' => $node->label()), WATCHDOG_NOTICE, l(t('view'), 'node/' . $node->id()));
diff --git a/core/modules/book/book.module b/core/modules/book/book.module
index ac26714..d0e0931 100644
--- a/core/modules/book/book.module
+++ b/core/modules/book/book.module
@@ -113,6 +113,21 @@ function book_permission() {
 }
 
 /**
+ * Implements hook_entity_field_info().
+ */
+function book_entity_field_info($entity_type) {
+  if ($entity_type === 'node') {
+    $info['definitions']['book'] = array(
+      'type' => 'book_field',
+      'label' => t('The book data'),
+      'computed' => TRUE,
+      'list' => TRUE,
+    );
+    return $info;
+  }
+}
+
+/**
  * Adds relevant book links to the node's links.
  *
  * @param \Drupal\Core\Entity\EntityInterface $node
@@ -120,17 +135,17 @@ function book_permission() {
  * @param $view_mode
  *   The view mode of the node.
  */
-function book_node_view_link(EntityInterface $node, $view_mode) {
+function book_node_view_link(NodeInterface $node, $view_mode) {
   $links = array();
 
-  if (isset($node->book['depth'])) {
+  if (isset($node->book->depth)) {
     if ($view_mode == 'full' && node_is_page($node)) {
       $child_type = Drupal::config('book.settings')->get('child_type');
-      if ((user_access('add content to books') || user_access('administer book outlines')) && node_access('create', $child_type) && $node->status == 1 && $node->book['depth'] < MENU_MAX_DEPTH) {
+      if ((user_access('add content to books') || user_access('administer book outlines')) && node_access('create', $child_type) && $node->isPublished() && $node->book['depth'] < MENU_MAX_DEPTH) {
         $links['book_add_child'] = array(
           'title' => t('Add child page'),
           'href' => 'node/add/' . $child_type,
-          'query' => array('parent' => $node->book['mlid']),
+          'query' => array('parent' => $node->book->mlid),
         );
       }
 
@@ -265,7 +280,7 @@ function _book_outline_remove_access(EntityInterface $node) {
  *   The node to remove from the outline.
  */
 function _book_node_is_removable(EntityInterface $node) {
-  return (!empty($node->book['bid']) && (($node->book['bid'] != $node->id()) || !$node->book['has_children']));
+  return (!empty($node->book->bid) && (($node->book->bid != $node->id()) || !$node->book->has_children));
 }
 
 /**
@@ -307,7 +322,7 @@ function book_form_node_form_alter(&$form, &$form_state, $form_id) {
   $node = $form_state['controller']->getEntity();
   $access = user_access('administer book outlines');
   if (!$access) {
-    if (user_access('add content to books') && ((!empty($node->book['mlid']) && !$node->isNew()) || book_type_is_allowed($node->type))) {
+    if (user_access('add content to books') && ((!empty($node->book->mlid) && !$node->isNew()) || book_type_is_allowed($node->getType()))) {
       // Already in the book hierarchy, or this node type is allowed.
       $access = TRUE;
     }
@@ -373,25 +388,25 @@ function _book_parent_select($book_link) {
     '#suffix' => '</div>',
   );
 
-  if ($book_link['nid'] === $book_link['bid']) {
+  if ($book_link->nid === $book_link->bid) {
     // This is a book - at the top level.
-    if ($book_link['original_bid'] === $book_link['bid']) {
+    if ($book_link->original_bid === $book_link->bid) {
       $form['#prefix'] .= '<em>' . t('This is the top-level page in this book.') . '</em>';
     }
     else {
       $form['#prefix'] .= '<em>' . t('This will be the top-level page in this book.') . '</em>';
     }
   }
-  elseif (!$book_link['bid']) {
+  elseif (!$book_link->bid) {
     $form['#prefix'] .= '<em>' . t('No book selected.') . '</em>';
   }
   else {
     $form = array(
       '#type' => 'select',
       '#title' => t('Parent item'),
-      '#default_value' => $book_link['plid'],
+      '#default_value' => $book_link->plid,
       '#description' => t('The parent page in the book. The maximum depth for a book and all child pages is !maxdepth. Some pages in the selected book may not be available as parents if selecting them would exceed this limit.', array('!maxdepth' => MENU_MAX_DEPTH)),
-      '#options' => book_toc($book_link['bid'], $book_link['parent_depth_limit'], array($book_link['mlid'])),
+      '#options' => book_toc($book_link->bid, $book_link->parent_depth_limit, array($book_link->mlid)),
       '#attributes' => array('class' => array('book-title-select')),
       '#prefix' => '<div id="edit-book-plid-wrapper">',
       '#suffix' => '</div>',
@@ -431,7 +446,7 @@ function _book_add_form_elements(&$form, &$form_state, EntityInterface $node) {
   foreach (array('menu_name', 'mlid', 'nid', 'router_path', 'has_children', 'options', 'module', 'original_bid', 'parent_depth_limit') as $key) {
     $form['book'][$key] = array(
       '#type' => 'value',
-      '#value' => $node->book[$key],
+      '#value' => $node->book->$key,
     );
   }
 
@@ -441,15 +456,15 @@ function _book_add_form_elements(&$form, &$form_state, EntityInterface $node) {
   $form['book']['weight'] = array(
     '#type' => 'weight',
     '#title' => t('Weight'),
-    '#default_value' => $node->book['weight'],
-    '#delta' => max(15, abs($node->book['weight'])),
+    '#default_value' => $node->book->weight,
+    '#delta' => max(15, abs($node->book->weight)),
     '#weight' => 5,
     '#description' => t('Pages at a given level are ordered first by weight and then by title.'),
   );
   $options = array();
   $nid = !$node->isNew() ? $node->id() : 'new';
 
-  if ($node->id() && ($nid == $node->book['original_bid']) && ($node->book['parent_depth_limit'] == 0)) {
+  if ($node->id() && ($nid == $node->book->original_bid) && ($node->book->parent_depth_limit == 0)) {
     // This is the top level node in a maximum depth book and thus cannot be moved.
     $options[$node->id()] = $node->label();
   }
@@ -459,11 +474,11 @@ function _book_add_form_elements(&$form, &$form_state, EntityInterface $node) {
     }
   }
 
-  if (user_access('create new books') && ($nid == 'new' || ($nid != $node->book['original_bid']))) {
+  if (user_access('create new books') && ($nid == 'new' || ($nid != $node->book->original_bid))) {
     // The node can become a new book, if it is not one already.
     $options = array($nid => t('- Create a new book -')) + $options;
   }
-  if (!$node->book['mlid']) {
+  if (!$node->book->mlid) {
     // The node is not currently in the hierarchy.
     $options = array(0 => t('- None -')) + $options;
   }
@@ -472,7 +487,7 @@ function _book_add_form_elements(&$form, &$form_state, EntityInterface $node) {
   $form['book']['bid'] = array(
     '#type' => 'select',
     '#title' => t('Book'),
-    '#default_value' => $node->book['bid'],
+    '#default_value' => $node->book->bid,
     '#options' => $options,
     '#access' => (bool) $options,
     '#description' => t('Your page will be a part of the selected book.'),
@@ -514,50 +529,52 @@ function book_form_update($form, $form_state) {
  *   TRUE if the menu link was saved; FALSE otherwise.
  */
 function _book_update_outline(EntityInterface $node) {
-  if (empty($node->book['bid'])) {
+  if (empty($node->book->bid)) {
     return FALSE;
   }
-  $new = empty($node->book['mlid']);
+  $new = empty($node->book->mlid);
 
-  $node->book['link_path'] = 'node/' . $node->id();
-  $node->book['link_title'] = $node->label();
-  $node->book['parent_mismatch'] = FALSE; // The normal case.
+  $node->book->link_path = 'node/' . $node->id();
+  $node->book->link_title = $node->label();
+  $node->book->parent_mismatch = FALSE; // The normal case.
 
-  if ($node->book['bid'] == $node->id()) {
-    $node->book['plid'] = 0;
-    $node->book['menu_name'] = book_menu_name($node->id());
+  if ($node->book->bid == $node->id()) {
+    $node->book->plid = 0;
+    $node->book->menu_name = book_menu_name($node->id());
   }
   else {
     // Check in case the parent is not is this book; the book takes precedence.
-    if (!empty($node->book['plid'])) {
+    if (!empty($node->book->plid)) {
       $parent = db_query("SELECT * FROM {book} WHERE mlid = :mlid", array(
-        ':mlid' => $node->book['plid'],
+        ':mlid' => $node->book->plid,
       ))->fetchAssoc();
     }
-    if (empty($node->book['plid']) || !$parent || $parent['bid'] != $node->book['bid']) {
-      $node->book['plid'] = db_query("SELECT mlid FROM {book} WHERE nid = :nid", array(
-        ':nid' => $node->book['bid'],
+    if (empty($node->book->plid) || !$parent || $parent['bid'] != $node->book->bid) {
+      $node->book->plid = db_query("SELECT mlid FROM {book} WHERE nid = :nid", array(
+        ':nid' => $node->book->bid,
       ))->fetchField();
-      $node->book['parent_mismatch'] = TRUE; // Likely when JS is disabled.
+      $node->book->parent_mismatch = TRUE; // Likely when JS is disabled.
     }
   }
 
-  $node->book = entity_create('menu_link', $node->book);
-  if ($node->book->save()) {
+  $link = entity_create('menu_link', $node->book->getValue());
+  debug($link);
+  if ($link->save()) {
+    debug($link);
     if ($new) {
       // Insert new.
       db_insert('book')
         ->fields(array(
           'nid' => $node->id(),
-          'mlid' => $node->book['mlid'],
-          'bid' => $node->book['bid'],
+          'mlid' => $link->mlid,
+          'bid' => $node->book->bid,
         ))
         ->execute();
       // Reset the cache of stored books.
       drupal_static_reset('book_get_books');
     }
     else {
-      if ($node->book['bid'] != db_query("SELECT bid FROM {book} WHERE nid = :nid", array(
+      if ($node->book->bid != db_query("SELECT bid FROM {book} WHERE nid = :nid", array(
           ':nid' => $node->id(),
         ))->fetchField()) {
         // Update the bid for this page and all children.
@@ -583,14 +600,14 @@ function _book_update_outline(EntityInterface $node) {
 function book_update_bid($book_link) {
   $query = db_select('menu_links');
   $query->addField('menu_links', 'mlid');
-  for ($i = 1; $i <= MENU_MAX_DEPTH && $book_link["p$i"]; $i++) {
-    $query->condition("p$i", $book_link["p$i"]);
+  for ($i = 1; $i <= MENU_MAX_DEPTH && $book_link->{"p$i"}; $i++) {
+    $query->condition("p$i", $book_link->{"p$i"});
   }
   $mlids = $query->execute()->fetchCol();
 
   if ($mlids) {
     db_update('book')
-      ->fields(array('bid' => $book_link['bid']))
+      ->fields(array('bid' => $book_link->bid))
       ->condition('mlid', $mlids, 'IN')
       ->execute();
   }
@@ -612,14 +629,14 @@ function book_update_bid($book_link) {
 function book_get_flat_menu($book_link) {
   $flat = &drupal_static(__FUNCTION__, array());
 
-  if (!isset($flat[$book_link['mlid']])) {
+  if (!isset($flat[$book_link->mlid])) {
     // Call menu_tree_all_data() to take advantage of the menu system's caching.
-    $tree = menu_tree_all_data($book_link['menu_name'], $book_link, $book_link['depth'] + 1);
-    $flat[$book_link['mlid']] = array();
-    _book_flatten_menu($tree, $flat[$book_link['mlid']]);
+    $tree = menu_tree_all_data($book_link->menu_name, $book_link, $book_link->depth + 1);
+    $flat[$book_link->mlid] = array();
+    _book_flatten_menu($tree, $flat[$book_link->mlid]);
   }
 
-  return $flat[$book_link['mlid']];
+  return $flat[$book_link->mlid];
 }
 
 /**
@@ -655,7 +672,7 @@ function _book_flatten_menu($tree, &$flat) {
  */
 function book_prev($book_link) {
   // If the parent is zero, we are at the start of a book.
-  if ($book_link['plid'] == 0) {
+  if ($book_link->plid == 0) {
     return NULL;
   }
   $flat = book_get_flat_menu($book_link);
@@ -664,11 +681,11 @@ function book_prev($book_link) {
   do {
     $prev = $curr;
     list($key, $curr) = each($flat);
-  } while ($key && $key != $book_link['mlid']);
+  } while ($key && $key != $book_link->mlid);
 
-  if ($key == $book_link['mlid']) {
+  if ($key == $book_link->mlid) {
     // The previous page in the book may be a child of the previous visible link.
-    if ($prev['depth'] == $book_link['depth'] && $prev['has_children']) {
+    if ($prev->depth == $book_link->depth && $prev->has_children) {
       // The subtree will have only one link at the top level - get its data.
       $tree = book_menu_subtree_data($prev);
       $data = array_shift($tree);
@@ -701,9 +718,9 @@ function book_next($book_link) {
   do {
     list($key, $curr) = each($flat);
   }
-  while ($key && $key != $book_link['mlid']);
+  while ($key && $key != $book_link->mlid);
 
-  if ($key == $book_link['mlid']) {
+  if ($key == $book_link->mlid) {
     return current($flat);
   }
 }
@@ -722,14 +739,14 @@ function book_children($book_link) {
 
   $children = array();
 
-  if ($book_link['has_children']) {
+  if ($book_link->has_children) {
     // Walk through the array until we find the current page.
     do {
       $link = array_shift($flat);
     }
-    while ($link && ($link['mlid'] != $book_link['mlid']));
+    while ($link && ($link['mlid'] != $book_link->mlid));
     // Continue though the array and collect the links whose parent is this page.
-    while (($link = array_shift($flat)) && $link['plid'] == $book_link['mlid']) {
+    while (($link = array_shift($flat)) && $link['plid'] == $book_link->mlid) {
       $data['link'] = $link;
       $data['below'] = '';
       $children[] = $data;
@@ -762,10 +779,11 @@ function book_menu_name($bid) {
 function book_node_load($nodes, $types) {
   $result = db_query("SELECT * FROM {book} b INNER JOIN {menu_links} ml ON b.mlid = ml.mlid WHERE b.nid IN (:nids)", array(':nids' =>  array_keys($nodes)), array('fetch' => PDO::FETCH_ASSOC));
   foreach ($result as $record) {
+    debug($record);
     $nodes[$record['nid']]->book = $record;
-    $nodes[$record['nid']]->book['href'] = $record['link_path'];
-    $nodes[$record['nid']]->book['title'] = $record['link_title'];
-    $nodes[$record['nid']]->book['options'] = unserialize($record['options']);
+    $nodes[$record['nid']]->book->href = $record['link_path'];
+    $nodes[$record['nid']]->book->title = $record['link_title'];
+    $nodes[$record['nid']]->book->options = unserialize($record['options']);
   }
 }
 
@@ -774,7 +792,7 @@ function book_node_load($nodes, $types) {
  */
 function book_node_view(EntityInterface $node, EntityDisplay $display, $view_mode) {
   if ($view_mode == 'full') {
-    if (!empty($node->book['bid']) && empty($node->in_preview)) {
+    if (!empty($node->book->bid) && empty($node->in_preview)) {
       $book_navigation = array( '#theme' => 'book_navigation', '#book_link' => $node->book);
       $node->content['book_navigation'] = array(
         '#markup' => drupal_render($book_navigation),
@@ -800,9 +818,9 @@ function book_node_view(EntityInterface $node, EntityDisplay $display, $view_mod
  * viewing a book page.
  */
 function book_page_alter(&$page) {
-  if (($node = menu_get_object()) && !empty($node->book['bid'])) {
+  if (($node = menu_get_object()) && !empty($node->book->bid)) {
     $active_menus = menu_get_active_menu_names();
-    $active_menus[] = $node->book['menu_name'];
+    $active_menus[] = $node->book->menu_name;
     menu_set_active_menu_names($active_menus);
   }
 }
@@ -812,12 +830,12 @@ function book_page_alter(&$page) {
  */
 function book_node_presave(EntityInterface $node) {
   // Always save a revision for non-administrators.
-  if (!empty($node->book['bid']) && !user_access('administer nodes')) {
+  if (!empty($node->book->bid) && !user_access('administer nodes')) {
     $node->setNewRevision();
   }
   // Make sure a new node gets a new menu link.
   if ($node->isNew()) {
-    $node->book['mlid'] = NULL;
+    $node->book->mlid = NULL;
   }
 }
 
@@ -825,13 +843,13 @@ function book_node_presave(EntityInterface $node) {
  * Implements hook_node_insert().
  */
 function book_node_insert(EntityInterface $node) {
-  if (!empty($node->book['bid'])) {
-    if ($node->book['bid'] == 'new') {
+  if (!empty($node->book->bid)) {
+    if ($node->book->bid == 'new') {
       // New nodes that are their own book.
-      $node->book['bid'] = $node->id();
+      $node->book->bid = $node->id();
     }
-    $node->book['nid'] = $node->id();
-    $node->book['menu_name'] = book_menu_name($node->book['bid']);
+    $node->book->nid = $node->id();
+    $node->book->menu_name = book_menu_name($node->book->bid);
     _book_update_outline($node);
   }
 }
@@ -840,13 +858,13 @@ function book_node_insert(EntityInterface $node) {
  * Implements hook_node_update().
  */
 function book_node_update(EntityInterface $node) {
-  if (!empty($node->book['bid'])) {
-    if ($node->book['bid'] == 'new') {
+  if (!empty($node->book->bid)) {
+    if ($node->book->bid == 'new') {
       // New nodes that are their own book.
-      $node->book['bid'] = $node->id();
+      $node->book->bid = $node->id();
     }
-    $node->book['nid'] = $node->id();
-    $node->book['menu_name'] = book_menu_name($node->book['bid']);
+    $node->book->nid = $node->id();
+    $node->book->menu_name = book_menu_name($node->book->bid);
     _book_update_outline($node);
   }
 }
@@ -855,21 +873,21 @@ function book_node_update(EntityInterface $node) {
  * Implements hook_node_predelete().
  */
 function book_node_predelete(EntityInterface $node) {
-  if (!empty($node->book['bid'])) {
-    if ($node->id() == $node->book['bid']) {
+  if (!empty($node->book->bid)) {
+    if ($node->id() == $node->book->bid) {
       // Handle deletion of a top-level post.
       $result = db_query("SELECT b.nid FROM {menu_links} ml INNER JOIN {book} b on b.mlid = ml.mlid WHERE ml.plid = :plid", array(
-        ':plid' => $node->book['mlid']
+        ':plid' => $node->book->mlid
       ));
       foreach ($result as $child) {
         $child_node = node_load($child->id());
-        $child_node->book['bid'] = $child_node->id();
+        $child_node->book->bid = $child_node->id();
         _book_update_outline($child_node);
       }
     }
-    menu_link_delete($node->book['mlid']);
+    menu_link_delete($node->book->mlid);
     db_delete('book')
-      ->condition('mlid', $node->book['mlid'])
+      ->condition('mlid', $node->book->mlid)
       ->execute();
     drupal_static_reset('book_get_books');
   }
@@ -889,22 +907,22 @@ function book_node_prepare_form(NodeInterface $node, $form_display, $operation,
       $parent = book_link_load($query->get('parent'));
 
       if ($parent && $parent['access']) {
-        $node->book['bid'] = $parent['bid'];
-        $node->book['plid'] = $parent['mlid'];
-        $node->book['menu_name'] = $parent['menu_name'];
+        $node->book->bid = $parent['bid'];
+        $node->book->plid = $parent['mlid'];
+        $node->book->menu_name = $parent['menu_name'];
       }
     }
     // Set defaults.
     $node->book += _book_link_defaults(!$node->isNew() ? $node->id() : 'new');
   }
   else {
-    if (isset($node->book['bid']) && !isset($node->book['original_bid'])) {
-      $node->book['original_bid'] = $node->book['bid'];
+    if (isset($node->book->bid) && !isset($node->book->original_bid)) {
+      $node->book->original_bid = $node->book->bid;
     }
   }
   // Find the depth limit for the parent select.
-  if (isset($node->book['bid']) && !isset($node->book['parent_depth_limit'])) {
-    $node->book['parent_depth_limit'] = _book_parent_depth_limit($node->book);
+  if (isset($node->book->bid) && !isset($node->book->parent_depth_limit)) {
+    $node->book->parent_depth_limit = _book_parent_depth_limit($node->book);
   }
 }
 
@@ -918,7 +936,7 @@ function book_node_prepare_form(NodeInterface $node, $form_display, $operation,
  *   The depth limit for items in the parent select.
  */
 function _book_parent_depth_limit($book_link) {
-  return MENU_MAX_DEPTH - 1 - (($book_link['mlid'] && $book_link['has_children']) ? entity_get_controller('menu_link')->findChildrenRelativeDepth($book_link) : 0);
+  return MENU_MAX_DEPTH - 1 - (($book_link->mlid && $book_link->has_children) ? entity_get_controller('menu_link')->findChildrenRelativeDepth($book_link) : 0);
 }
 
 /**
@@ -931,7 +949,7 @@ function _book_parent_depth_limit($book_link) {
 function book_form_node_delete_confirm_alter(&$form, $form_state) {
   $node = node_load($form['nid']['#value']);
 
-  if (isset($node->book) && $node->book['has_children']) {
+  if (isset($node->book) && $node->book->has_children) {
     $form['book_warning'] = array(
       '#markup' => '<p>' . t('%title is part of a book outline, and has associated child pages. If you proceed with deletion, the child pages will be relocated automatically.', array('%title' => $node->label())) . '</p>',
       '#weight' => -10,
@@ -998,13 +1016,13 @@ function template_preprocess_book_navigation(&$variables) {
   $book_link = $variables['book_link'];
 
   // Provide extra variables for themers. Not needed by default.
-  $variables['book_id'] = $book_link['bid'];
-  $variables['book_title'] = check_plain($book_link['link_title']);
-  $variables['book_url'] = 'node/' . $book_link['bid'];
-  $variables['current_depth'] = $book_link['depth'];
+  $variables['book_id'] = $book_link->bid;
+  $variables['book_title'] = check_plain($book_link->link_title);
+  $variables['book_url'] = 'node/' . $book_link->bid;
+  $variables['current_depth'] = $book_link->depth;
   $variables['tree'] = '';
 
-  if ($book_link['mlid']) {
+  if ($book_link->mlid) {
     $variables['tree'] = book_children($book_link);
 
     if ($prev = book_prev($book_link)) {
@@ -1014,7 +1032,7 @@ function template_preprocess_book_navigation(&$variables) {
       $variables['prev_title'] = check_plain($prev['title']);
     }
 
-    if ($book_link['plid'] && $parent = book_link_load($book_link['plid'])) {
+    if ($book_link->plid && $parent = book_link_load($book_link->plid)) {
       $parent_href = url($parent['link_path']);
       drupal_add_html_head_link(array('rel' => 'up', 'href' => $parent_href));
       $variables['parent_url'] = $parent_href;
@@ -1099,7 +1117,9 @@ function _book_toc_recurse($tree, $indent, &$toc, $exclude, $depth_limit) {
  *   book page.
  */
 function book_toc($bid, $depth_limit, $exclude = array()) {
+  debug(array_keys(entity_load_multiple('menu')));
   $tree = menu_tree_all_data(book_menu_name($bid));
+  debug($tree);
   $toc = array();
   _book_toc_recurse($tree, '', $toc, $exclude, $depth_limit);
 
@@ -1208,7 +1228,7 @@ function book_node_export(EntityInterface $node, $children = '') {
  *     to an empty string.
  */
 function template_preprocess_book_node_export_html(&$variables) {
-  $variables['depth'] = $variables['node']->book['depth'];
+  $variables['depth'] = $variables['node']->book->depth;
   $variables['title'] = check_plain($variables['node']->label());
   $variables['content'] = $variables['node']->rendered;
 }
@@ -1290,7 +1310,7 @@ function book_menu_subtree_data($link) {
   $tree = &drupal_static(__FUNCTION__, array());
 
   // Generate a cache ID (cid) specific for this $menu_name and $link.
-  $cid = 'links:' . $link['menu_name'] . ':subtree-cid:' . $link['mlid'];
+  $cid = 'links:' . $link->menu_name . ':subtree-cid:' . $link->mlid;
 
   if (!isset($tree[$cid])) {
     $cache = cache('menu')->get($cid);
@@ -1313,22 +1333,24 @@ function book_menu_subtree_data($link) {
       $query->fields('b');
       $query->fields('m', array('load_functions', 'to_arg_functions', 'access_callback', 'access_arguments', 'page_callback', 'page_arguments', 'title', 'title_callback', 'title_arguments', 'type'));
       $query->fields('ml');
-      $query->condition('menu_name', $link['menu_name']);
-      for ($i = 1; $i <= MENU_MAX_DEPTH && $link["p$i"]; ++$i) {
-        $query->condition("p$i", $link["p$i"]);
+      $query->condition('menu_name', $link->menu_name);
+      for ($i = 1; $i <= MENU_MAX_DEPTH && $link->{"p$i"}; ++$i) {
+        $query->condition("p$i", $link->{"p$i"});
       }
       for ($i = 1; $i <= MENU_MAX_DEPTH; ++$i) {
         $query->orderBy("p$i");
       }
       $links = array();
+      debug((string)$query);
+      debug($query->getArguments());
       foreach ($query->execute() as $item) {
         $links[] = $item;
       }
-      $data['tree'] = menu_tree_data($links, array(), $link['depth']);
+      $data['tree'] = menu_tree_data($links, array(), $link->depth);
       $data['node_links'] = array();
       menu_tree_collect_node_links($data['tree'], $data['node_links']);
       // Compute the real cid for book subtree data.
-      $tree_cid = 'links:' . $item['menu_name'] . ':subtree-data:' . hash('sha256', serialize($data));
+      $tree_cid = 'links:' . $item->menu_name . ':subtree-data:' . hash('sha256', serialize($data));
       // Cache the data, if it is not already in the cache.
 
       if (!cache('menu')->get($tree_cid)) {
diff --git a/core/modules/book/book.pages.inc b/core/modules/book/book.pages.inc
index 4cd7e25..7b087f6 100644
--- a/core/modules/book/book.pages.inc
+++ b/core/modules/book/book.pages.inc
@@ -72,7 +72,7 @@ function book_export_html(EntityInterface $node) {
     if (isset($node->book)) {
       $tree = book_menu_subtree_data($node->book);
       $contents = book_export_traverse($tree, 'book_node_export');
-      $book_exported_html = array('#theme' => 'book_export_html', '#title' => $node->label(), '#contents' => $contents, '#depth' => $node->book['depth']);
+      $book_exported_html = array('#theme' => 'book_export_html', '#title' => $node->label(), '#contents' => $contents, '#depth' => $node->book->depth);
       return drupal_render($book_exported_html);
     }
     else {
@@ -118,12 +118,12 @@ function book_outline_form($form, &$form_state, EntityInterface $node) {
     $node->book = _book_link_defaults($node->id());
   }
   else {
-    $node->book['original_bid'] = $node->book['bid'];
+    $node->book->original_bid = $node->book->bid;
   }
 
   // Find the depth limit for the parent select.
-  if (!isset($node->book['parent_depth_limit'])) {
-    $node->book['parent_depth_limit'] = _book_parent_depth_limit($node->book);
+  if (!isset($node->book->parent_depth_limit)) {
+    $node->book->parent_depth_limit = _book_parent_depth_limit($node->book);
   }
   $form['#node'] = $node;
   $form['#id'] = 'book-outline';
@@ -131,7 +131,7 @@ function book_outline_form($form, &$form_state, EntityInterface $node) {
 
   $form['update'] = array(
     '#type' => 'submit',
-    '#value' => $node->book['original_bid'] ? t('Update book outline') : t('Add to book outline'),
+    '#value' => $node->book->original_bid ? t('Update book outline') : t('Add to book outline'),
     '#weight' => 15,
   );
 
@@ -175,7 +175,7 @@ function book_outline_form_submit($form, &$form_state) {
   $book_link['menu_name'] = book_menu_name($book_link['bid']);
   $node->book = $book_link;
   if (_book_update_outline($node)) {
-    if ($node->book['parent_mismatch']) {
+    if ($node->book->parent_mismatch) {
       // This will usually only happen when JS is disabled.
       drupal_set_message(t('The post has been added to the selected book. You may now position it relative to other pages.'));
       $form_state['redirect'] = "node/" . $node->id() . "/outline";
@@ -203,7 +203,7 @@ function book_remove_form($form, &$form_state, EntityInterface $node) {
   $form['#node'] = $node;
   $title = array('%title' => $node->label());
 
-  if ($node->book['has_children']) {
+  if ($node->book->has_children) {
     $description = t('%title has associated child pages, which will be relocated automatically to maintain their connection to the book. To recreate the hierarchy (as it was before removing this page), %title may be added again using the Outline tab, and each of its former child pages will need to be relocated manually.', $title);
   }
   else {
@@ -219,7 +219,7 @@ function book_remove_form($form, &$form_state, EntityInterface $node) {
 function book_remove_form_submit($form, &$form_state) {
   $node = $form['#node'];
   if (_book_node_is_removable($node)) {
-    menu_link_delete($node->book['mlid']);
+    menu_link_delete($node->book->mlid);
     db_delete('book')
       ->condition('nid', $node->id())
       ->execute();
diff --git a/core/modules/book/lib/Drupal/book/Plugin/Block/BookNavigationBlock.php b/core/modules/book/lib/Drupal/book/Plugin/Block/BookNavigationBlock.php
index 8cacc04..fe7fd35 100644
--- a/core/modules/book/lib/Drupal/book/Plugin/Block/BookNavigationBlock.php
+++ b/core/modules/book/lib/Drupal/book/Plugin/Block/BookNavigationBlock.php
@@ -64,7 +64,7 @@ public function blockSubmit($form, &$form_state) {
   public function build() {
     $current_bid = 0;
     if ($node = menu_get_object()) {
-      $current_bid = empty($node->book['bid']) ? 0 : $node->book['bid'];
+      $current_bid = $node->book->bid;
     }
     if ($this->configuration['block_mode'] == 'all pages') {
       $book_menus = array();
@@ -73,7 +73,7 @@ public function build() {
         if ($book['bid'] == $current_bid) {
           // If the current page is a node associated with a book, the menu
           // needs to be retrieved.
-          $book_menus[$book_id] = menu_tree_output(menu_tree_all_data($node->book['menu_name'], $node->book));
+          $book_menus[$book_id] = menu_tree_output(menu_tree_all_data($node->book->menu_name, $node->book));
         }
         else {
           // Since we know we will only display a link to the top node, there
@@ -97,7 +97,7 @@ public function build() {
       // Only display this block when the user is browsing a book.
       $select = db_select('node', 'n')
         ->fields('n', array('nid'))
-        ->condition('n.nid', $node->book['bid'])
+        ->condition('n.nid', $node->book->bid)
         ->addTag('node_access');
       $nid = $select->execute()->fetchField();
       // Only show the block if the user has view access for the top-level node.
diff --git a/core/modules/book/lib/Drupal/book/Plugin/DataType/BookItem.php b/core/modules/book/lib/Drupal/book/Plugin/DataType/BookItem.php
new file mode 100644
index 0000000..c54822b
--- /dev/null
+++ b/core/modules/book/lib/Drupal/book/Plugin/DataType/BookItem.php
@@ -0,0 +1,60 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\book\Plugin\DataType\BookItem.
+ */
+
+namespace Drupal\book\Plugin\DataType;
+
+use Drupal\Core\TypedData\Annotation\DataType;
+use Drupal\Core\Annotation\Translation;
+use Drupal\Core\Entity\Field\FieldItemBase;
+
+/**
+ * Defines the 'book_field' entity field item.
+ *
+ * @DataType(
+ *   id = "book_field",
+ *   label = @Translation("Book field item"),
+ *   description = @Translation("An entity field containing a book id and related data."),
+ *   list_class = "\Drupal\Core\Entity\Field\Field"
+ * )
+ */
+class BookItem extends FieldItemBase {
+
+  /**
+   * Definitions of the contained properties.
+   *
+   * @see BookItem::getPropertyDefinitions()
+   *
+   * @var array
+   */
+  static $propertyDefinitions;
+
+  /**
+   * Implements \Drupal\Core\TypedData\ComplexDataInterface::getPropertyDefinitions().
+   */
+  public function getPropertyDefinitions() {
+    if (!isset(static::$propertyDefinitions)) {
+      static::$propertyDefinitions['bid'] = array(
+        'type' => 'integer',
+        'label' => t('Book id'),
+      );
+      static::$propertyDefinitions['menu_name'] = array(
+        'type' => 'string',
+        'label' => t('Menu name'),
+      );
+      static::$propertyDefinitions['link_path'] = array(
+        'type' => 'string',
+        'label' => t('Link path'),
+      );
+      static::$propertyDefinitions['link_title'] = array(
+        'type' => 'string',
+        'label' => t('Link title'),
+      );
+    }
+    return static::$propertyDefinitions;
+  }
+
+}
diff --git a/core/modules/book/lib/Drupal/book/Tests/BookTest.php b/core/modules/book/lib/Drupal/book/Tests/BookTest.php
index 85c8c85..105dd57 100644
--- a/core/modules/book/lib/Drupal/book/Tests/BookTest.php
+++ b/core/modules/book/lib/Drupal/book/Tests/BookTest.php
@@ -80,6 +80,8 @@ function createBook() {
 
     $this->book = $this->createBookNode('new');
     $book = $this->book;
+    debug($book->id());
+    debug($book->getPropertyValues());
 
     /*
      * Add page hierarchy to book.
@@ -92,8 +94,11 @@ function createBook() {
      */
     $nodes = array();
     $nodes[] = $this->createBookNode($book->id()); // Node 0.
-    $nodes[] = $this->createBookNode($book->id(), $nodes[0]->book['mlid']); // Node 1.
-    $nodes[] = $this->createBookNode($book->id(), $nodes[0]->book['mlid']); // Node 2.
+    debug(1);
+    $nodes[] = $this->createBookNode($book->id(), $nodes[0]->book->mlid); // Node 1.
+    debug(2);
+    $nodes[] = $this->createBookNode($book->id(), $nodes[0]->book->mlid); // Node 2.
+    debug($nodes[0]->book->getValue());
     $nodes[] = $this->createBookNode($book->id()); // Node 3.
     $nodes[] = $this->createBookNode($book->id()); // Node 4.
 
@@ -206,7 +211,7 @@ function checkBookNode(EntityInterface $node, $nodes, $previous = FALSE, $up = F
     // Check printer friendly version.
     $this->drupalGet('book/export/html/' . $node->id());
     $this->assertText($node->label(), 'Printer friendly title found.');
-    $this->assertRaw(check_markup($node->body[Language::LANGCODE_NOT_SPECIFIED][0]['value'], $node->body[Language::LANGCODE_NOT_SPECIFIED][0]['format']), 'Printer friendly body found.');
+    $this->assertRaw(check_markup($node->body->value, $node->body->format), 'Printer friendly body found.');
 
     $number++;
   }
@@ -281,7 +286,7 @@ function testBookExport() {
     // Make sure each part of the book is there.
     foreach ($nodes as $node) {
       $this->assertText($node->label(), 'Node title found in printer friendly version.');
-      $this->assertRaw(check_markup($node->body[Language::LANGCODE_NOT_SPECIFIED][0]['value'], $node->body[Language::LANGCODE_NOT_SPECIFIED][0]['format']), 'Node body found in printer friendly version.');
+      $this->assertRaw(check_markup($node->body->value, $node->body->format), 'Node body found in printer friendly version.');
     }
 
     // Make sure we can't export an unsupported format.
@@ -494,7 +499,7 @@ public function testBookOrdering() {
     $this->drupalLogin($this->admin_user);
     $node1 = $this->createBookNode($book->id());
     $node2 = $this->createBookNode($book->id());
-    $plid = $node1->book['mlid'];
+    $plid = $node1->book->mlid;
 
     // Head to admin screen and attempt to re-order.
     $this->drupalGet('admin/structure/book/' . $book->id());
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index a68f39b..8501a2f 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -432,8 +432,8 @@ function comment_get_recent($number = 10) {
  *   "page=X" if the page number is greater than zero; empty string otherwise.
  */
 function comment_new_page_count($num_comments, $new_replies, EntityInterface $node) {
-  $mode = variable_get('comment_default_mode_' . $node->type, COMMENT_MODE_THREADED);
-  $comments_per_page = variable_get('comment_default_per_page_' . $node->type, 50);
+  $mode = variable_get('comment_default_mode_' . $node->getType(), COMMENT_MODE_THREADED);
+  $comments_per_page = variable_get('comment_default_per_page_' . $node->getType(), 50);
   $pagenum = NULL;
   $flat = $mode == COMMENT_MODE_FLAT ? TRUE : FALSE;
   if ($num_comments <= $comments_per_page) {
@@ -516,7 +516,7 @@ function theme_comment_block($variables) {
 function comment_node_view(EntityInterface $node, EntityDisplay $display, $view_mode) {
   $links = array();
 
-  if ($node->comment != COMMENT_NODE_HIDDEN) {
+  if ($node->comment->value != COMMENT_NODE_HIDDEN) {
     if ($view_mode == 'rss') {
       // Add a comments RSS element which is a URL to the comments of this node.
       $node->rss_elements[] = array(
@@ -550,8 +550,8 @@ function comment_node_view(EntityInterface $node, EntityDisplay $display, $view_
           }
         }
       }
-      if ($node->comment == COMMENT_NODE_OPEN) {
-        $comment_form_location = variable_get('comment_form_location_' . $node->type, COMMENT_FORM_BELOW);
+      if ($node->comment->value == COMMENT_NODE_OPEN) {
+        $comment_form_location = variable_get('comment_form_location_' . $node->getType(), COMMENT_FORM_BELOW);
         if (user_access('post comments')) {
           $links['comment-add'] = array(
             'title' => t('Add new comment'),
@@ -580,8 +580,8 @@ function comment_node_view(EntityInterface $node, EntityDisplay $display, $view_
       // allowed to post comments and if this node is allowing new comments.
       // But we don't want this link if we're building the node for search
       // indexing or constructing a search result excerpt.
-      if ($node->comment == COMMENT_NODE_OPEN) {
-        $comment_form_location = variable_get('comment_form_location_' . $node->type, COMMENT_FORM_BELOW);
+      if ($node->comment->value == COMMENT_NODE_OPEN) {
+        $comment_form_location = variable_get('comment_form_location_' . $node->getType(), COMMENT_FORM_BELOW);
         if (user_access('post comments')) {
           // Show the "post comment" link if the form is on another page, or
           // if there are existing comments that the link will skip past.
@@ -643,8 +643,8 @@ function comment_node_page_additions(EntityInterface $node) {
   // Unpublished comments are not included in $node->comment_count, so show
   // comments unconditionally if the user is an administrator.
   if (($node->comment_count && user_access('access comments')) || user_access('administer comments')) {
-    $mode = variable_get('comment_default_mode_' . $node->type, COMMENT_MODE_THREADED);
-    $comments_per_page = variable_get('comment_default_per_page_' . $node->type, 50);
+    $mode = variable_get('comment_default_mode_' . $node->getType(), COMMENT_MODE_THREADED);
+    $comments_per_page = variable_get('comment_default_per_page_' . $node->getType(), 50);
     if ($cids = comment_get_thread($node, $mode, $comments_per_page)) {
       $comments = comment_load_multiple($cids);
       comment_prepare_thread($comments);
@@ -655,13 +655,13 @@ function comment_node_page_additions(EntityInterface $node) {
   }
 
   // Append comment form if needed.
-  if (user_access('post comments') && $node->comment == COMMENT_NODE_OPEN && (variable_get('comment_form_location_' . $node->type, COMMENT_FORM_BELOW) == COMMENT_FORM_BELOW)) {
+  if (user_access('post comments') && $node->comment->value == COMMENT_NODE_OPEN && (variable_get('comment_form_location_' . $node->getType(), COMMENT_FORM_BELOW) == COMMENT_FORM_BELOW)) {
     $additions['comment_form'] = comment_add($node);
   }
 
   if ($additions) {
     $additions += array(
-      '#theme' => 'comment_wrapper__node_' . $node->type,
+      '#theme' => 'comment_wrapper__node_' . $node->getType(),
       '#node' => $node,
       'comments' => array(),
       'comment_form' => array(),
@@ -684,7 +684,7 @@ function comment_node_page_additions(EntityInterface $node) {
  *   The renderable array for the comment addition form.
  */
 function comment_add(EntityInterface $node, $pid = NULL) {
-  $values = array('nid' => $node->id(), 'pid' => $pid, 'node_type' => 'comment_node_' . $node->type);
+  $values = array('nid' => $node->id(), 'pid' => $pid, 'node_type' => 'comment_node_' . $node->getType());
   $comment = entity_create('comment', $values);
   return Drupal::entityManager()->getForm($comment);
 }
@@ -874,7 +874,7 @@ function comment_view(Comment $comment, $view_mode = 'full', $langcode = NULL) {
  */
 function comment_links(Comment $comment, EntityInterface $node) {
   $links = array();
-  if ($node->comment == COMMENT_NODE_OPEN) {
+  if ($node->comment->value == COMMENT_NODE_OPEN) {
     if ($comment->access('delete')) {
       $links['comment-delete'] = array(
         'title' => t('delete'),
@@ -1072,7 +1072,7 @@ function comment_form_node_form_alter(&$form, $form_state) {
     '#weight' => 30,
   );
   $comment_count = $node->id() ? db_query('SELECT comment_count FROM {node_comment_statistics} WHERE nid = :nid', array(':nid' => $node->id()))->fetchField() : 0;
-  $comment_settings = ($node->comment == COMMENT_NODE_HIDDEN && empty($comment_count)) ? COMMENT_NODE_CLOSED : $node->comment;
+  $comment_settings = ($node->comment->value == COMMENT_NODE_HIDDEN && empty($comment_count)) ? COMMENT_NODE_CLOSED : $node->comment->value;
   $form['comment_settings']['comment'] = array(
     '#type' => 'radios',
     '#title' => t('Comments'),
@@ -1113,14 +1113,14 @@ function comment_node_load($nodes, $types) {
   // assign values without hitting the database.
   foreach ($nodes as $node) {
     // Store whether comments are enabled for this node.
-    if ($node->comment != COMMENT_NODE_HIDDEN) {
+    if ($node->comment->value != COMMENT_NODE_HIDDEN) {
       $comments_enabled[] = $node->id();
     }
     else {
       $node->cid = 0;
-      $node->last_comment_timestamp = $node->created;
+      $node->last_comment_timestamp = $node->getCreatedTime();
       $node->last_comment_name = '';
-      $node->last_comment_uid = $node->uid;
+      $node->last_comment_uid = $node->getAuthorId();
       $node->comment_count = 0;
     }
   }
@@ -1142,8 +1142,8 @@ function comment_node_load($nodes, $types) {
  * Implements hook_node_prepare_form().
  */
 function comment_node_prepare_form(NodeInterface $node, $form_display, $operation, array &$form_state) {
-  if (!isset($node->comment)) {
-    $node->comment = variable_get("comment_$node->type", COMMENT_NODE_OPEN);
+  if (!isset($node->comment->value)) {
+    $node->comment = variable_get('comment_' . $node->getType(), COMMENT_NODE_OPEN);
   }
 }
 
@@ -1158,9 +1158,9 @@ function comment_node_insert(EntityInterface $node) {
       ->fields(array(
         'nid' => $node->id(),
         'cid' => 0,
-        'last_comment_timestamp' => $node->changed,
+        'last_comment_timestamp' => $node->getChangedTime(),
         'last_comment_name' => NULL,
-        'last_comment_uid' => $node->uid,
+        'last_comment_uid' => $node->getAuthorId(),
         'comment_count' => 0,
       ))
       ->execute();
@@ -1208,9 +1208,9 @@ function comment_node_update_index(EntityInterface $node, $langcode) {
   }
 
   if ($index_comments) {
-    $mode = variable_get('comment_default_mode_' . $node->type, COMMENT_MODE_THREADED);
-    $comments_per_page = variable_get('comment_default_per_page_' . $node->type, 50);
-    if ($node->comment && $cids = comment_get_thread($node, $mode, $comments_per_page)) {
+    $mode = variable_get('comment_default_mode_' . $node->getType(), COMMENT_MODE_THREADED);
+    $comments_per_page = variable_get('comment_default_per_page_' . $node->bundle(), 50);
+    if ($node->comment->value && $cids = comment_get_thread($node, $mode, $comments_per_page)) {
       $comments = comment_load_multiple($cids);
       comment_prepare_thread($comments);
       $build = comment_view_multiple($comments, $langcode);
@@ -1236,11 +1236,11 @@ function comment_update_index() {
  */
 function comment_node_search_result(EntityInterface $node) {
   // Do not make a string if comments are hidden.
-  if (user_access('access comments') && $node->comment != COMMENT_NODE_HIDDEN) {
+  if (user_access('access comments') && $node->comment->value != COMMENT_NODE_HIDDEN) {
     $comments = db_query('SELECT comment_count FROM {node_comment_statistics} WHERE nid = :nid', array('nid' => $node->id()))->fetchField();
     // Do not make a string if comments are closed and there are currently
     // zero comments.
-    if ($node->comment != COMMENT_NODE_CLOSED || $comments > 0) {
+    if ($node->comment->value != COMMENT_NODE_CLOSED || $comments > 0) {
       return array('comment' => format_plural($comments, '1 comment', '@count comments'));
     }
   }
@@ -1610,7 +1610,7 @@ function template_preprocess_comment(&$variables) {
     $variables['attributes']['class'][] = 'by-anonymous';
   }
   else {
-    if ($comment->uid->target_id == $variables['node']->uid) {
+    if ($comment->uid->target_id == $variables['node']->getAuthorId()) {
       $variables['attributes']['class'][] = 'by-node-author';
     }
     if ($comment->uid->target_id == $variables['user']->id()) {
@@ -1651,7 +1651,7 @@ function theme_comment_post_forbidden($variables) {
     if ($authenticated_post_comments) {
       // We cannot use drupal_get_destination() because these links
       // sometimes appear on /node and taxonomy listing pages.
-      if (variable_get('comment_form_location_' . $node->type, COMMENT_FORM_BELOW) == COMMENT_FORM_SEPARATE_PAGE) {
+      if (variable_get('comment_form_location_' . $node->getType(), COMMENT_FORM_BELOW) == COMMENT_FORM_SEPARATE_PAGE) {
         $destination = array('destination' => 'comment/reply/' . $node->id() . '#comment-form');
       }
       else {
@@ -1683,7 +1683,7 @@ function theme_comment_post_forbidden($variables) {
 function template_preprocess_comment_wrapper(&$variables) {
   // Provide contextual information.
   $variables['node'] = $variables['content']['#node'];
-  $variables['display_mode'] = variable_get('comment_default_mode_' . $variables['node']->type, COMMENT_MODE_THREADED);
+  $variables['display_mode'] = variable_get('comment_default_mode_' . $variables['node']->getType(), COMMENT_MODE_THREADED);
 
   // The comment form is optional and may not exist.
   $variables['content'] += array('comment_form' => array());
diff --git a/core/modules/comment/comment.pages.inc b/core/modules/comment/comment.pages.inc
index 221fbfc..13c2df3 100644
--- a/core/modules/comment/comment.pages.inc
+++ b/core/modules/comment/comment.pages.inc
@@ -84,7 +84,7 @@ function comment_reply(EntityInterface $node, $pid = NULL) {
     }
 
     // Should we show the reply box?
-    if ($node->comment != COMMENT_NODE_OPEN) {
+    if ($node->comment->value != COMMENT_NODE_OPEN) {
       drupal_set_message(t("This discussion is closed: you can't post new comments."), 'error');
       return new RedirectResponse(url('node/' . $node->id(), array('absolute' => TRUE)));
     }
diff --git a/core/modules/comment/lib/Drupal/comment/CommentFormController.php b/core/modules/comment/lib/Drupal/comment/CommentFormController.php
index d5a4a50..237eb93 100644
--- a/core/modules/comment/lib/Drupal/comment/CommentFormController.php
+++ b/core/modules/comment/lib/Drupal/comment/CommentFormController.php
@@ -26,9 +26,9 @@ public function form(array $form, array &$form_state) {
 
     // Use #comment-form as unique jump target, regardless of node type.
     $form['#id'] = drupal_html_id('comment_form');
-    $form['#theme'] = array('comment_form__node_' . $node->type, 'comment_form');
+    $form['#theme'] = array('comment_form__node_' . $node->getType(), 'comment_form');
 
-    $anonymous_contact = variable_get('comment_anonymous_' . $node->type, COMMENT_ANONYMOUS_MAYNOT_CONTACT);
+    $anonymous_contact = variable_get('comment_anonymous_' . $node->getType(), COMMENT_ANONYMOUS_MAYNOT_CONTACT);
     $is_admin = $comment->id() && user_access('administer comments');
 
     if (!$user->isAuthenticated() && $anonymous_contact != COMMENT_ANONYMOUS_MAYNOT_CONTACT) {
@@ -145,7 +145,7 @@ public function form(array $form, array &$form_state) {
       '#title' => t('Subject'),
       '#maxlength' => 64,
       '#default_value' => $comment->subject->value,
-      '#access' => variable_get('comment_subject_field_' . $node->type, 1) == 1,
+      '#access' => variable_get('comment_subject_field_' . $node->getType(), 1) == 1,
     );
 
     // Used for conditional validation of author fields.
@@ -178,7 +178,7 @@ protected function actions(array $form, array &$form_state) {
     $element = parent::actions($form, $form_state);
     $comment = $this->entity;
     $node = $comment->nid->entity;
-    $preview_mode = variable_get('comment_preview_' . $node->type, DRUPAL_OPTIONAL);
+    $preview_mode = variable_get('comment_preview_' . $node->getType(), DRUPAL_OPTIONAL);
 
     // No delete action on the comment form.
     unset($element['delete']);
@@ -318,7 +318,7 @@ public function save(array $form, array &$form_state) {
     $node = node_load($form_state['values']['nid']);
     $comment = $this->entity;
 
-    if (user_access('post comments') && (user_access('administer comments') || $node->comment == COMMENT_NODE_OPEN)) {
+    if (user_access('post comments') && (user_access('administer comments') || $node->comment->value == COMMENT_NODE_OPEN)) {
       // Save the anonymous user information to a cookie for reuse.
       if (user_is_anonymous()) {
         user_cookie_save(array_intersect_key($form_state['values'], array_flip(array('name', 'mail', 'homepage'))));
@@ -341,7 +341,7 @@ public function save(array $form, array &$form_state) {
       }
       $query = array();
       // Find the current display page for this comment.
-      $page = comment_get_display_page($comment->id(), $node->type);
+      $page = comment_get_display_page($comment->id(), $node->getType());
       if ($page > 0) {
         $query['page'] = $page;
       }
diff --git a/core/modules/comment/lib/Drupal/comment/Controller/CommentController.php b/core/modules/comment/lib/Drupal/comment/Controller/CommentController.php
index 84ef0c1..6bd628e 100644
--- a/core/modules/comment/lib/Drupal/comment/Controller/CommentController.php
+++ b/core/modules/comment/lib/Drupal/comment/Controller/CommentController.php
@@ -121,7 +121,7 @@ public function commentPermalink(Request $request, CommentInterface $comment) {
         throw new AccessDeniedHttpException();
       }
       // Find the current display page for this comment.
-      $page = comment_get_display_page($comment->id(), $node->type);
+      $page = comment_get_display_page($comment->id(), $node->getType());
       // @todo: Cleaner sub request handling.
       $redirect_request = Request::create('/node/' . $node->id(), 'GET', $request->query->all(), $request->cookies->all(), array(), $request->server->all());
       $redirect_request->query->set('page', $page);
diff --git a/core/modules/comment/lib/Drupal/comment/Plugin/Core/Entity/Comment.php b/core/modules/comment/lib/Drupal/comment/Plugin/Core/Entity/Comment.php
index 5bad9ea..2b711dd 100644
--- a/core/modules/comment/lib/Drupal/comment/Plugin/Core/Entity/Comment.php
+++ b/core/modules/comment/lib/Drupal/comment/Plugin/Core/Entity/Comment.php
@@ -217,7 +217,7 @@ public function id() {
   public static function preCreate(EntityStorageControllerInterface $storage_controller, array &$values) {
     if (empty($values['node_type']) && !empty($values['nid'])) {
       $node = node_load(is_object($values['nid']) ? $values['nid']->value : $values['nid']);
-      $values['node_type'] = 'comment_node_' . $node->type;
+      $values['node_type'] = 'comment_node_' . $node->getType();
     }
   }
 
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php
index 5e40a7b..bf7cdb5 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php
@@ -143,7 +143,7 @@ function setEnvironment(array $info) {
         $comment = entity_create('comment', array(
           'cid' => NULL,
           'nid' => $this->node->id(),
-          'node_type' => $this->node->type,
+          'node_type' => $this->node->getType(),
           'pid' => 0,
           'uid' => 0,
           'status' => COMMENT_PUBLISHED,
@@ -167,9 +167,9 @@ function setEnvironment(array $info) {
     }
 
     // Change comment settings.
-    variable_set('comment_form_location_' . $this->node->type, $info['form']);
-    variable_set('comment_anonymous_' . $this->node->type, $info['contact']);
-    if ($this->node->comment != $info['comments']) {
+    variable_set('comment_form_location_' . $this->node->getType(), $info['form']);
+    variable_set('comment_anonymous_' . $this->node->getType(), $info['contact']);
+    if ($this->node->comment->value != $info['comments']) {
       $this->node->comment = $info['comments'];
       $this->node->save();
     }
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentNewIndicatorTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentNewIndicatorTest.php
index 04fc481..55deb61 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentNewIndicatorTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentNewIndicatorTest.php
@@ -49,7 +49,7 @@ public function testCommentNewCommentsIndicator() {
     $comment = entity_create('comment', array(
       'cid' => NULL,
       'nid' => $this->node->id(),
-      'node_type' => $this->node->type,
+      'node_type' => $this->node->getType(),
       'pid' => 0,
       'uid' => $this->loggedInUser->id(),
       'status' => COMMENT_PUBLISHED,
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentStatisticsTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentStatisticsTest.php
index 2e6aab3..e471421 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentStatisticsTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentStatisticsTest.php
@@ -49,7 +49,7 @@ function testCommentNodeCommentStatistics() {
 
     // Checks the initial values of node comment statistics with no comment.
     $node = node_load($this->node->id());
-    $this->assertEqual($node->last_comment_timestamp, $this->node->created, 'The initial value of node last_comment_timestamp is the node created date.');
+    $this->assertEqual($node->last_comment_timestamp, $this->node->getCreatedTime(), 'The initial value of node last_comment_timestamp is the node created date.');
     $this->assertEqual($node->last_comment_name, NULL, 'The initial value of node last_comment_name is NULL.');
     $this->assertEqual($node->last_comment_uid, $this->web_user->id(), 'The initial value of node last_comment_uid is the node uid.');
     $this->assertEqual($node->comment_count, 0, 'The initial value of node comment_count is zero.');
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentTokenReplaceTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentTokenReplaceTest.php
index 3572475..1819b10 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentTokenReplaceTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentTokenReplaceTest.php
@@ -67,7 +67,7 @@ function testCommentTokenReplacement() {
     $tests['[comment:parent:cid]'] = $comment->pid->target_id;
     $tests['[comment:parent:title]'] = check_plain($parent_comment->subject->value);
     $tests['[comment:node:nid]'] = $comment->nid->target_id;
-    $tests['[comment:node:title]'] = check_plain($node->title);
+    $tests['[comment:node:title]'] = check_plain($node->getTitle());
     $tests['[comment:author:uid]'] = $comment->uid->target_id;
     $tests['[comment:author:name]'] = check_plain($this->admin_user->getUsername());
 
@@ -87,7 +87,7 @@ function testCommentTokenReplacement() {
     $tests['[comment:title]'] = $comment->subject->value;
     $tests['[comment:body]'] = $comment->comment_body->value;
     $tests['[comment:parent:title]'] = $parent_comment->subject->value;
-    $tests['[comment:node:title]'] = $node->title;
+    $tests['[comment:node:title]'] = $node->getTitle();
     $tests['[comment:author:name]'] = $this->admin_user->getUsername();
 
     foreach ($tests as $input => $expected) {
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentTranslationUITest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentTranslationUITest.php
index 296a3e2..5c25660 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentTranslationUITest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentTranslationUITest.php
@@ -77,7 +77,7 @@ protected function createEntity($values, $langcode, $node_bundle = NULL) {
     }
     $node = $this->drupalCreateNode(array('type' => $node_bundle));
     $values['nid'] = $node->id();
-    $values['uid'] = $node->uid;
+    $values['uid'] = $node->getAuthorId();
     return parent::createEntity($values, $langcode);
   }
 
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/Views/CommentTestBase.php b/core/modules/comment/lib/Drupal/comment/Tests/Views/CommentTestBase.php
index 138c5d0..dabf53f 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/Views/CommentTestBase.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/Views/CommentTestBase.php
@@ -41,7 +41,7 @@ function setUp() {
     $this->drupalLogin($this->account);
 
     $this->node_user_posted = $this->drupalCreateNode();
-    $this->node_user_commented = $this->drupalCreateNode(array('uid' => $this->account2->uid));
+    $this->node_user_commented = $this->drupalCreateNode(array('uid' => $this->account2->id()));
 
     $comment = array(
       'uid' => $this->loggedInUser->id(),
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/Views/DefaultViewRecentComments.php b/core/modules/comment/lib/Drupal/comment/Tests/Views/DefaultViewRecentComments.php
index 6ffa95e..f4a4316 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/Views/DefaultViewRecentComments.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/Views/DefaultViewRecentComments.php
@@ -77,7 +77,7 @@ public function setUp() {
 
     // Create some comments and attach them to the created node.
     for ($i = 0; $i < $this->masterDisplayResults; $i++) {
-      $comment = entity_create('comment', array('node_type' => 'comment_node_' . $this->node->type));
+      $comment = entity_create('comment', array('node_type' => 'comment_node_' . $this->node->getType()));
       $comment->uid->target_id = 0;
       $comment->nid->target_id = $this->node->id();
       $comment->subject->value = 'Test comment ' . $i;
diff --git a/core/modules/datetime/datetime.module b/core/modules/datetime/datetime.module
index eafc616..0da06cb 100644
--- a/core/modules/datetime/datetime.module
+++ b/core/modules/datetime/datetime.module
@@ -1049,5 +1049,5 @@ function datetime_form_node_form_alter(&$form, &$form_state, $form_id) {
  */
 function datetime_node_prepare_form(NodeInterface $node, $form_display, $operation, array &$form_state) {
   // Prepare the 'Authored on' date to use datetime.
-  $node->date = DrupalDateTime::createFromTimestamp($node->created);
+  $node->date = DrupalDateTime::createFromTimestamp($node->getCreatedTime());
 }
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutoCreateTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutoCreateTest.php
index f5f74d0..a19e1a9 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutoCreateTest.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutoCreateTest.php
@@ -113,7 +113,7 @@ public function testAutoCreate() {
 
     $referencing_nid = key($result);
     $referencing_node = node_load($referencing_nid);
-    $this->assertEqual($referenced_nid, $referencing_node->test_field[Language::LANGCODE_NOT_SPECIFIED][0]['target_id'], 'Newly created node is referenced from the referencing node.');
+    $this->assertEqual($referenced_nid, $referencing_node->test_field->target_id, 'Newly created node is referenced from the referencing node.');
 
     // Now try to view the node and check that the referenced node is shown.
     $this->drupalGet('node/' . $referencing_node->id());
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/Views/SelectionTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/Views/SelectionTest.php
index cad4bd8..c9b8d62 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/Views/SelectionTest.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/Views/SelectionTest.php
@@ -36,7 +36,7 @@ public function testSelectionHandler() {
 
     $nodes = array();
     foreach (array($node1, $node2, $node3) as $node) {
-      $nodes[$node->type][$node->id()] = $node->label();
+      $nodes[$node->getType()][$node->id()] = $node->label();
     }
 
     // Create a field and instance.
diff --git a/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php b/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php
index fdfea10..a487a7a 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php
@@ -726,10 +726,10 @@ function process_entity(EntityInterface $entity) {
       if ($data) {
         // Now, overwrite the original value with our aggregated value.
         // This overwrites it so there is always just one entry.
-        $processed_entity->{$this->definition['field_name']}[$langcode] = array($base_value);
+        $processed_entity->getTranslation($langcode)->{$this->definition['field_name']} = array($base_value);
       }
       else {
-        $processed_entity->{$this->definition['field_name']}[$langcode] = array();
+        $processed_entity->getTranslation($langcode)->{$this->definition['field_name']} = array();
       }
     }
 
@@ -740,7 +740,7 @@ function process_entity(EntityInterface $entity) {
 
     // We are supposed to show only certain deltas.
     if ($this->limit_values && !empty($processed_entity->{$this->definition['field_name']})) {
-      $all_values = !empty($processed_entity->{$this->definition['field_name']}[$langcode]) ? $processed_entity->{$this->definition['field_name']}[$langcode] : array();
+      $all_values = !empty($processed_entity->getTranslation($langcode)->{$this->definition['field_name']}) ? $processed_entity->getTranslation($langcode)->{$this->definition['field_name']}->getValue() : array();
       if ($this->options['delta_reversed']) {
         $all_values = array_reverse($all_values);
       }
@@ -786,7 +786,7 @@ function process_entity(EntityInterface $entity) {
           }
         }
       }
-      $processed_entity->{$this->definition['field_name']}[$langcode] = $new_values;
+      $processed_entity->getTranslation($langcode)->{$this->definition['field_name']} = $new_values;
     }
 
     return $processed_entity;
diff --git a/core/modules/field/lib/Drupal/field/Tests/Views/HandlerFieldFieldTest.php b/core/modules/field/lib/Drupal/field/Tests/Views/HandlerFieldFieldTest.php
index 8658c52..c42950d 100644
--- a/core/modules/field/lib/Drupal/field/Tests/Views/HandlerFieldFieldTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/Views/HandlerFieldFieldTest.php
@@ -107,7 +107,7 @@ public function _testSimpleFieldRender() {
       for ($key = 0; $key < 2; $key++) {
         $field = $this->fields[$key];
         $rendered_field = $view->style_plugin->getField($i, $field['field_name']);
-        $expected_field = $this->nodes[$i]->{$field['field_name']}[Language::LANGCODE_NOT_SPECIFIED][0]['value'];
+        $expected_field = $this->nodes[$i]->{$field['field_name']}->value;
         $this->assertEqual($rendered_field, $expected_field);
       }
     }
@@ -146,7 +146,7 @@ public function _testMultipleFieldRender() {
     for ($i = 0; $i < 3; $i++) {
       $rendered_field = $view->style_plugin->getField($i, $field_name);
       $items = array();
-      $pure_items = $this->nodes[$i]->{$field_name}[Language::LANGCODE_NOT_SPECIFIED];
+      $pure_items = $this->nodes[$i]->{$field_name}->getValue();
       $pure_items = array_splice($pure_items, 0, 3);
       foreach ($pure_items as $j => $item) {
         $items[] = $pure_items[$j]['value'];
@@ -169,7 +169,7 @@ public function _testMultipleFieldRender() {
     for ($i = 0; $i < 3; $i++) {
       $rendered_field = $view->style_plugin->getField($i, $field_name);
       $items = array();
-      $pure_items = $this->nodes[$i]->{$field_name}[Language::LANGCODE_NOT_SPECIFIED];
+      $pure_items = $this->nodes[$i]->{$field_name}->getValue();
       $pure_items = array_splice($pure_items, 1, 3);
       foreach ($pure_items as $j => $item) {
         $items[] = $pure_items[$j]['value'];
@@ -189,7 +189,7 @@ public function _testMultipleFieldRender() {
     for ($i = 0; $i < 3; $i++) {
       $rendered_field = $view->style_plugin->getField($i, $field_name);
       $items = array();
-      $pure_items = $this->nodes[$i]->{$field_name}[Language::LANGCODE_NOT_SPECIFIED];
+      $pure_items = $this->nodes[$i]->{$field_name}->getValue();
       array_splice($pure_items, 0, -3);
       $pure_items = array_reverse($pure_items);
       foreach ($pure_items as $j => $item) {
@@ -210,7 +210,7 @@ public function _testMultipleFieldRender() {
     for ($i = 0; $i < 3; $i++) {
       $rendered_field = $view->style_plugin->getField($i, $field_name);
       $items = array();
-      $pure_items = $this->nodes[$i]->{$field_name}[Language::LANGCODE_NOT_SPECIFIED];
+      $pure_items = $this->nodes[$i]->{$field_name}->getValue();
       $items[] = $pure_items[0]['value'];
       $items[] = $pure_items[4]['value'];
       $this->assertEqual($rendered_field, implode(', ', $items), 'Take sure that the amount of items are limited.');
@@ -228,7 +228,7 @@ public function _testMultipleFieldRender() {
     for ($i = 0; $i < 3; $i++) {
       $rendered_field = $view->style_plugin->getField($i, $field_name);
       $items = array();
-      $pure_items = $this->nodes[$i]->{$field_name}[Language::LANGCODE_NOT_SPECIFIED];
+      $pure_items = $this->nodes[$i]->{$field_name}->getValue();
       $pure_items = array_splice($pure_items, 0, 3);
       foreach ($pure_items as $j => $item) {
         $items[] = $pure_items[$j]['value'];
diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldDisplayTest.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldDisplayTest.php
index 4ef654d..7f3f5c8 100644
--- a/core/modules/file/lib/Drupal/file/Tests/FileFieldDisplayTest.php
+++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldDisplayTest.php
@@ -60,7 +60,7 @@ function testNodeDisplay() {
 
     // Check that the default formatter is displaying with the file name.
     $node = node_load($nid, TRUE);
-    $node_file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']);
+    $node_file = file_load($node->{$field_name}->target_id);
     $file_link = array(
       '#theme' => 'file_link',
       '#file' => $node_file,
diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldPathTest.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldPathTest.php
index f2c45b6..374b5fd 100644
--- a/core/modules/file/lib/Drupal/file/Tests/FileFieldPathTest.php
+++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldPathTest.php
@@ -35,7 +35,7 @@ function testUploadPath() {
 
     // Check that the file was uploaded to the file root.
     $node = node_load($nid, TRUE);
-    $node_file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']);
+    $node_file = file_load($node->{$field_name}->target_id);
     $this->assertPathMatch('public://' . $test_file->getFilename(), $node_file->getFileUri(), format_string('The file %file was uploaded to the correct path.', array('%file' => $node_file->getFileUri())));
 
     // Change the path to contain multiple subdirectories.
@@ -46,7 +46,7 @@ function testUploadPath() {
 
     // Check that the file was uploaded into the subdirectory.
     $node = node_load($nid, TRUE);
-    $node_file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id'], TRUE);
+    $node_file = file_load($node->{$field_name}->target_id, TRUE);
     $this->assertPathMatch('public://foo/bar/baz/' . $test_file->getFilename(), $node_file->getFileUri(), format_string('The file %file was uploaded to the correct path.', array('%file' => $node_file->getFileUri())));
 
     // Check the path when used with tokens.
@@ -58,7 +58,7 @@ function testUploadPath() {
 
     // Check that the file was uploaded into the subdirectory.
     $node = node_load($nid, TRUE);
-    $node_file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']);
+    $node_file = file_load($node->{$field_name}->target_id);
     // Do token replacement using the same user which uploaded the file, not
     // the user running the test case.
     $data = array('user' => $this->admin_user);
diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldRSSContentTest.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldRSSContentTest.php
index d031ffe..7f051f5 100644
--- a/core/modules/file/lib/Drupal/file/Tests/FileFieldRSSContentTest.php
+++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldRSSContentTest.php
@@ -67,7 +67,7 @@ function testFileFieldRSSContent() {
 
     // Get the uploaded file from the node.
     $node = node_load($nid, TRUE);
-    $node_file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']);
+    $node_file = file_load($node->{$field_name}->target_id);
 
     // Check that the RSS enclosure appears in the RSS feed.
     $this->drupalGet('rss.xml');
diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldRevisionTest.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldRevisionTest.php
index d9604cc..c7c2c72 100644
--- a/core/modules/file/lib/Drupal/file/Tests/FileFieldRevisionTest.php
+++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldRevisionTest.php
@@ -47,8 +47,8 @@ function testRevisions() {
 
     // Check that the file exists on disk and in the database.
     $node = node_load($nid, TRUE);
-    $node_file_r1 = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']);
-    $node_vid_r1 = $node->vid;
+    $node_file_r1 = file_load($node->{$field_name}->target_id);
+    $node_vid_r1 = $node->getRevisionId();
     $this->assertFileExists($node_file_r1, 'New file saved to disk on node creation.');
     $this->assertFileEntryExists($node_file_r1, 'File entry exists in database on node creation.');
     $this->assertFileIsPermanent($node_file_r1, 'File is permanent.');
@@ -56,15 +56,15 @@ function testRevisions() {
     // Upload another file to the same node in a new revision.
     $this->replaceNodeFile($test_file, $field_name, $nid);
     $node = node_load($nid, TRUE);
-    $node_file_r2 = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']);
-    $node_vid_r2 = $node->vid;
+    $node_file_r2 = file_load($node->{$field_name}->target_id);
+    $node_vid_r2 = $node->getRevisionId();
     $this->assertFileExists($node_file_r2, 'Replacement file exists on disk after creating new revision.');
     $this->assertFileEntryExists($node_file_r2, 'Replacement file entry exists in database after creating new revision.');
     $this->assertFileIsPermanent($node_file_r2, 'Replacement file is permanent.');
 
     // Check that the original file is still in place on the first revision.
     $node = node_revision_load($node_vid_r1);
-    $current_file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']);
+    $current_file = file_load($node->{$field_name}->target_id);
     $this->assertEqual($node_file_r1->id(), $current_file->id(), 'Original file still in place after replacing file in new revision.');
     $this->assertFileExists($node_file_r1, 'Original file still in place after replacing file in new revision.');
     $this->assertFileEntryExists($node_file_r1, 'Original file entry still in place after replacing file in new revision');
@@ -74,16 +74,16 @@ function testRevisions() {
     // Check that the file is still the same as the previous revision.
     $this->drupalPost('node/' . $nid . '/edit', array('revision' => '1'), t('Save and keep published'));
     $node = node_load($nid, TRUE);
-    $node_file_r3 = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']);
-    $node_vid_r3 = $node->vid;
+    $node_file_r3 = file_load($node->{$field_name}->target_id);
+    $node_vid_r3 = $node->getRevisionId();
     $this->assertEqual($node_file_r2->id(), $node_file_r3->id(), 'Previous revision file still in place after creating a new revision without a new file.');
     $this->assertFileIsPermanent($node_file_r3, 'New revision file is permanent.');
 
     // Revert to the first revision and check that the original file is active.
     $this->drupalPost('node/' . $nid . '/revisions/' . $node_vid_r1 . '/revert', array(), t('Revert'));
     $node = node_load($nid, TRUE);
-    $node_file_r4 = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']);
-    $node_vid_r4 = $node->vid;
+    $node_file_r4 = file_load($node->{$field_name}->target_id);
+    $node_vid_r4 = $node->getRevisionId();
     $this->assertEqual($node_file_r1->id(), $node_file_r4->id(), 'Original revision file still in place after reverting to the original revision.');
     $this->assertFileIsPermanent($node_file_r4, 'Original revision file still permanent after reverting to the original revision.');
 
diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php
index 3582893..ba51a17 100644
--- a/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php
+++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php
@@ -155,7 +155,7 @@ function uploadNodeFile($file, $field_name, $nid_or_type, $new_revision = TRUE,
       $node->setNewRevision();
       $node->save();
       $node = node_load($nid, TRUE);
-      $this->assertNotEqual($nid, $node->vid, 'Node revision exists.');
+      $this->assertNotEqual($nid, $node->getRevisionId(), 'Node revision exists.');
     }
 
     // Attach a file to the node.
diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldValidateTest.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldValidateTest.php
index a7cf1e5..2b3019c 100644
--- a/core/modules/file/lib/Drupal/file/Tests/FileFieldValidateTest.php
+++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldValidateTest.php
@@ -47,7 +47,7 @@ function testRequired() {
 
     $node = node_load($nid, TRUE);
 
-    $node_file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']);
+    $node_file = file_load($node->{$field_name}->target_id);
     $this->assertFileExists($node_file, 'File exists after uploading to the required field.');
     $this->assertFileEntryExists($node_file, 'File entry exists after uploading to the required field.');
 
@@ -63,7 +63,7 @@ function testRequired() {
     // Create a new node with the uploaded file into the multivalue field.
     $nid = $this->uploadNodeFile($test_file, $field_name, $type_name);
     $node = node_load($nid, TRUE);
-    $node_file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']);
+    $node_file = file_load($node->{$field_name}->target_id);
     $this->assertFileExists($node_file, 'File exists after uploading to the required multiple value field.');
     $this->assertFileEntryExists($node_file, 'File entry exists after uploading to the required multiple value field.');
   }
@@ -93,7 +93,7 @@ function testFileMaxSize() {
       // Create a new node with the small file, which should pass.
       $nid = $this->uploadNodeFile($small_file, $field_name, $type_name);
       $node = node_load($nid, TRUE);
-      $node_file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']);
+      $node_file = file_load($node->{$field_name}->target_id);
       $this->assertFileExists($node_file, format_string('File exists after uploading a file (%filesize) under the max limit (%maxsize).', array('%filesize' => format_size($small_file->getSize()), '%maxsize' => $max_filesize)));
       $this->assertFileEntryExists($node_file, format_string('File entry exists after uploading a file (%filesize) under the max limit (%maxsize).', array('%filesize' => format_size($small_file->getSize()), '%maxsize' => $max_filesize)));
 
@@ -109,7 +109,7 @@ function testFileMaxSize() {
     // Upload the big file successfully.
     $nid = $this->uploadNodeFile($large_file, $field_name, $type_name);
     $node = node_load($nid, TRUE);
-    $node_file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']);
+    $node_file = file_load($node->{$field_name}->target_id);
     $this->assertFileExists($node_file, format_string('File exists after uploading a file (%filesize) with no max limit.', array('%filesize' => format_size($large_file->getSize()))));
     $this->assertFileEntryExists($node_file, format_string('File entry exists after uploading a file (%filesize) with no max limit.', array('%filesize' => format_size($large_file->getSize()))));
   }
@@ -131,7 +131,7 @@ function testFileExtension() {
     // Check that the file can be uploaded with no extension checking.
     $nid = $this->uploadNodeFile($test_file, $field_name, $type_name);
     $node = node_load($nid, TRUE);
-    $node_file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']);
+    $node_file = file_load($node->{$field_name}->target_id);
     $this->assertFileExists($node_file, 'File exists after uploading a file with no extension checking.');
     $this->assertFileEntryExists($node_file, 'File entry exists after uploading a file with no extension checking.');
 
@@ -149,7 +149,7 @@ function testFileExtension() {
     // Check that the file can be uploaded with extension checking.
     $nid = $this->uploadNodeFile($test_file, $field_name, $type_name);
     $node = node_load($nid, TRUE);
-    $node_file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']);
+    $node_file = file_load($node->{$field_name}->target_id);
     $this->assertFileExists($node_file, 'File exists after uploading a file with extension checking.');
     $this->assertFileEntryExists($node_file, 'File entry exists after uploading a file with extension checking.');
   }
diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php
index e481384..24a5475 100644
--- a/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php
+++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php
@@ -46,7 +46,7 @@ function testSingleValuedWidget() {
       //   does not yet support file uploads.
       $nid = $this->uploadNodeFile($test_file, $field_name, $type_name);
       $node = node_load($nid, TRUE);
-      $node_file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']);
+      $node_file = file_load($node->{$field_name}->target_id);
       $this->assertFileExists($node_file, 'New file saved to disk on node creation.');
 
       // Ensure the file can be downloaded.
@@ -79,7 +79,7 @@ function testSingleValuedWidget() {
       // Save the node and ensure it does not have the file.
       $this->drupalPost(NULL, array(), t('Save and keep published'));
       $node = node_load($nid, TRUE);
-      $this->assertTrue(empty($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']), 'File was successfully removed from the node.');
+      $this->assertTrue(empty($node->{$field_name}->target_id), 'File was successfully removed from the node.');
     }
   }
 
@@ -196,7 +196,7 @@ function testMultiValuedWidget() {
       preg_match('/node\/([0-9]+)/', $this->getUrl(), $matches);
       $nid = $matches[1];
       $node = node_load($nid, TRUE);
-      $this->assertTrue(empty($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']), 'Node was successfully saved without any files.');
+      $this->assertTrue(empty($node->{$field_name}->target_id), 'Node was successfully saved without any files.');
     }
   }
 
@@ -216,7 +216,7 @@ function testPrivateFileSetting() {
     $this->drupalPost("admin/structure/types/manage/$type_name/fields/$instance->id/field", $edit, t('Save field settings'));
     $nid = $this->uploadNodeFile($test_file, $field_name, $type_name);
     $node = node_load($nid, TRUE);
-    $node_file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']);
+    $node_file = file_load($node->{$field_name}->target_id);
     $this->assertFileExists($node_file, 'New file saved to disk on node creation.');
 
     // Ensure the private file is available to the user who uploaded it.
diff --git a/core/modules/file/lib/Drupal/file/Tests/FileListingTest.php b/core/modules/file/lib/Drupal/file/Tests/FileListingTest.php
index e8a2f5d..69842eb 100644
--- a/core/modules/file/lib/Drupal/file/Tests/FileListingTest.php
+++ b/core/modules/file/lib/Drupal/file/Tests/FileListingTest.php
@@ -75,14 +75,14 @@ function testFileListingPages() {
     }
 
     foreach ($nodes as &$node) {
-      $this->drupalGet('node/' . $node->nid . '/edit');
+      $this->drupalGet('node/' . $node->id() . '/edit');
       $file = $this->getTestFile('image');
 
       $edit = array(
         'files[file_' . Language::LANGCODE_NOT_SPECIFIED . '_' . 0 . ']' => drupal_realpath($file->getFileUri()),
       );
       $this->drupalPost(NULL, $edit, t('Save'));
-      $node = entity_load('node', $node->nid)->getNGEntity();
+      $node = entity_load('node', $node->id());
     }
 
     $this->drupalGet('admin/content/files');
diff --git a/core/modules/file/lib/Drupal/file/Tests/FilePrivateTest.php b/core/modules/file/lib/Drupal/file/Tests/FilePrivateTest.php
index 1b8a82f..cfeee72 100644
--- a/core/modules/file/lib/Drupal/file/Tests/FilePrivateTest.php
+++ b/core/modules/file/lib/Drupal/file/Tests/FilePrivateTest.php
@@ -50,7 +50,7 @@ function testPrivateFile() {
     $test_file = $this->getTestFile('text');
     $nid = $this->uploadNodeFile($test_file, $field_name, $type_name, TRUE, array('private' => TRUE));
     $node = node_load($nid, TRUE);
-    $node_file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']);
+    $node_file = file_load($node->{$field_name}->target_id);
     // Ensure the file can be downloaded.
     $this->drupalGet(file_create_url($node_file->getFileUri()));
     $this->assertResponse(200, 'Confirmed that the generated URL is correct by downloading the shipped file.');
@@ -62,7 +62,7 @@ function testPrivateFile() {
     $this->drupalLogin($this->admin_user);
     $nid = $this->uploadNodeFile($test_file, $no_access_field_name, $type_name, TRUE, array('private' => TRUE));
     $node = node_load($nid, TRUE);
-    $node_file = file_load($node->{$no_access_field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']);
+    $node_file = file_load($node->{$no_access_field_name}->target_id);
     // Ensure the file cannot be downloaded.
     $this->drupalGet(file_create_url($node_file->getFileUri()));
     $this->assertResponse(403, 'Confirmed that access is denied for the file without view field access permission.');
diff --git a/core/modules/file/lib/Drupal/file/Tests/FileTokenReplaceTest.php b/core/modules/file/lib/Drupal/file/Tests/FileTokenReplaceTest.php
index 36d323d..5036c3e 100644
--- a/core/modules/file/lib/Drupal/file/Tests/FileTokenReplaceTest.php
+++ b/core/modules/file/lib/Drupal/file/Tests/FileTokenReplaceTest.php
@@ -47,7 +47,7 @@ function testFileTokenReplacement() {
 
     // Load the node and the file.
     $node = node_load($nid, TRUE);
-    $file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']);
+    $file = file_load($node->{$field_name}->target_id);
 
     // Generate and test sanitized tokens.
     $tests = array();
diff --git a/core/modules/filter/lib/Drupal/filter/Tests/FilterSecurityTest.php b/core/modules/filter/lib/Drupal/filter/Tests/FilterSecurityTest.php
index 75af0b0..2023434 100644
--- a/core/modules/filter/lib/Drupal/filter/Tests/FilterSecurityTest.php
+++ b/core/modules/filter/lib/Drupal/filter/Tests/FilterSecurityTest.php
@@ -72,8 +72,8 @@ function setUp() {
   function testDisableFilterModule() {
     // Create a new node.
     $node = $this->drupalCreateNode(array('promote' => 1));
-    $body_raw = $node->body[Language::LANGCODE_NOT_SPECIFIED][0]['value'];
-    $format_id = $node->body[Language::LANGCODE_NOT_SPECIFIED][0]['format'];
+    $body_raw = $node->body->value;
+    $format_id = $node->body->format;
     $this->drupalGet('node/' . $node->id());
     $this->assertText($body_raw, 'Node body found.');
 
diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module
index 46921af..03efb6c 100644
--- a/core/modules/forum/forum.module
+++ b/core/modules/forum/forum.module
@@ -6,7 +6,7 @@
  */
 
 use Drupal\Core\Entity\EntityInterface;
-use Drupal\entity\Plugin\Core\Entity\EntityDisplay;
+use Drupal\node\NodeInterface;
 use Drupal\taxonomy\Plugin\Core\Entity\Term;
 
 /**
@@ -264,7 +264,7 @@ function forum_uri($forum) {
  */
 function _forum_node_check_node_type(EntityInterface $node) {
   // Fetch information about the forum field.
-  $instance = field_info_instance('node', 'taxonomy_forums', $node->type);
+  $instance = field_info_instance('node', 'taxonomy_forums', $node->getType());
   return !empty($instance);
 }
 
@@ -278,17 +278,18 @@ function forum_node_validate(EntityInterface $node, $form) {
   if (_forum_node_check_node_type($node)) {
     $langcode = $form['taxonomy_forums']['#language'];
     // vocabulary is selected, not a "container" term.
-    if (!empty($node->taxonomy_forums[$langcode])) {
+    if (!$node->taxonomy_forums->isEmpty()) {
       // Extract the node's proper topic ID.
       $containers = Drupal::config('forum.settings')->get('containers');
-      foreach ($node->taxonomy_forums[$langcode] as $delta => $item) {
+      foreach ($node->taxonomy_forums as $delta => $item) {
         // If no term was selected (e.g. when no terms exist yet), remove the
         // item.
-        if (empty($item['target_id'])) {
-          unset($node->taxonomy_forums[$langcode][$delta]);
+        if (empty($item->target_id)) {
+          // @todo: Does this work?
+          unset($node->taxonomy_forums[$delta]);
           continue;
         }
-        $term = entity_load('taxonomy_term', $item['target_id']);
+        $term = $item->entity;
         if (!$term) {
           form_set_error('taxonomy_forums', t('Select a forum.'));
           continue;
@@ -311,19 +312,18 @@ function forum_node_validate(EntityInterface $node, $form) {
  * Assigns the forum taxonomy when adding a topic from within a forum.
  */
 function forum_node_presave(EntityInterface $node) {
+
   if (_forum_node_check_node_type($node)) {
     // Make sure all fields are set properly:
     $node->icon = !empty($node->icon) ? $node->icon : '';
-    reset($node->taxonomy_forums);
-    $langcode = key($node->taxonomy_forums);
-    if (!empty($node->taxonomy_forums[$langcode])) {
-      $node->forum_tid = $node->taxonomy_forums[$langcode][0]['target_id'];
+    if (!$node->taxonomy_forums->isEmpty()) {
+      $node->forum_tid = $node->taxonomy_forums->target_id;
       // Only do a shadow copy check if this is not a new node.
       if (!$node->isNew()) {
         $old_tid = db_query_range("SELECT f.tid FROM {forum} f INNER JOIN {node} n ON f.vid = n.vid WHERE n.nid = :nid ORDER BY f.vid DESC", 0, 1, array(':nid' => $node->id()))->fetchField();
         if ($old_tid && isset($node->forum_tid) && ($node->forum_tid != $old_tid) && !empty($node->shadow)) {
           // A shadow copy needs to be created. Retain new term and add old term.
-          $node->taxonomy_forums[$langcode][] = array('target_id' => $old_tid);
+          $node->taxonomy_forums[count($node->taxonomy_forums)] = array('target_id' => $old_tid);
         }
       }
     }
@@ -341,7 +341,7 @@ function forum_node_update(EntityInterface $node) {
       if (!empty($node->forum_tid)) {
         db_update('forum')
           ->fields(array('tid' => $node->forum_tid))
-          ->condition('vid', $node->vid)
+          ->condition('vid', $node->getRevisionId())
           ->execute();
       }
       // The node is removed from the forum.
@@ -356,7 +356,7 @@ function forum_node_update(EntityInterface $node) {
         db_insert('forum')
           ->fields(array(
             'tid' => $node->forum_tid,
-            'vid' => $node->vid,
+            'vid' => $node->getRevisionId(),
             'nid' => $node->id(),
           ))
           ->execute();
@@ -367,12 +367,12 @@ function forum_node_update(EntityInterface $node) {
     if (!empty($node->shadow)) {
       db_delete('forum')
         ->condition('nid', $node->id())
-        ->condition('vid', $node->vid)
+        ->condition('vid', $node->getRevisionId())
         ->execute();
       db_insert('forum')
         ->fields(array(
           'nid' => $node->id(),
-          'vid' => $node->vid,
+          'vid' => $node->getRevisionId(),
           'tid' => $node->forum_tid,
         ))
         ->execute();
@@ -389,7 +389,7 @@ function forum_node_insert(EntityInterface $node) {
       $nid = db_insert('forum')
         ->fields(array(
           'tid' => $node->forum_tid,
-          'vid' => $node->vid,
+          'vid' => $node->getRevisionId(),
           'nid' => $node->id(),
         ))
         ->execute();
@@ -418,7 +418,7 @@ function forum_node_load($nodes) {
   $node_vids = array();
   foreach ($nodes as $node) {
     if (_forum_node_check_node_type($node)) {
-      $node_vids[] = $node->vid;
+      $node_vids[] = $node->getRevisionId();
     }
   }
   if (!empty($node_vids)) {
@@ -501,18 +501,19 @@ function forum_comment_delete($comment) {
  * Implements hook_field_storage_pre_insert().
  */
 function forum_field_storage_pre_insert(EntityInterface $entity, &$skip_fields) {
-  if ($entity->entityType() == 'node' && $entity->status && _forum_node_check_node_type($entity)) {
+  $entity = $entity->getNGEntity();
+  if ($entity->entityType() == 'node' && $entity->isPublished() && _forum_node_check_node_type($entity)) {
     $query = db_insert('forum_index')->fields(array('nid', 'title', 'tid', 'sticky', 'created', 'comment_count', 'last_comment_timestamp'));
     foreach ($entity->getTranslationLanguages() as $langcode => $language) {
       $translation = $entity->getTranslation($langcode);
       $query->values(array(
         'nid' => $entity->id(),
-        'title' => $translation->title->value,
+        'title' => $translation->label(),
         'tid' => $translation->taxonomy_forums->target_id,
-        'sticky' => $entity->sticky,
-        'created' => $entity->created,
+        'sticky' => (int) $entity->isSticky(),
+        'created' => $entity->getCreatedTime(),
         'comment_count' => 0,
-        'last_comment_timestamp' => $entity->created,
+        'last_comment_timestamp' => $entity->getCreatedTime(),
       ));
     }
     $query->execute();
@@ -525,29 +526,31 @@ function forum_field_storage_pre_insert(EntityInterface $entity, &$skip_fields)
 function forum_field_storage_pre_update(EntityInterface $entity, &$skip_fields) {
   $first_call = &drupal_static(__FUNCTION__, array());
 
+  $entity = $entity->getNGEntity();
   if ($entity->entityType() == 'node' && _forum_node_check_node_type($entity)) {
 
     // If the node is published, update the forum index.
-    if ($entity->status) {
+    if ($entity->isPublished()) {
 
       // We don't maintain data for old revisions, so clear all previous values
       // from the table. Since this hook runs once per field, per object, make
       // sure we only wipe values once.
-      if (!isset($first_call[$entity->nid])) {
-        $first_call[$entity->nid] = FALSE;
+      if (!isset($first_call[$entity->id()])) {
+        $first_call[$entity->id()] = FALSE;
         db_delete('forum_index')->condition('nid', $entity->id())->execute();
       }
       $query = db_insert('forum_index')->fields(array('nid', 'title', 'tid', 'sticky', 'created', 'comment_count', 'last_comment_timestamp'));
-      foreach ($entity->taxonomy_forums as $language) {
-        foreach ($language as $item) {
+      foreach ($entity->getTranslationLanguages() as $langcode => $language) {
+        $translation = $entity->getTranslation($langcode);
+        foreach ($translation->taxonomy_forums as $item) {
           $query->values(array(
-            'nid' => $entity->nid,
-            'title' => $entity->title,
-            'tid' => $item['target_id'],
-            'sticky' => $entity->sticky,
-            'created' => $entity->created,
+            'nid' => $entity->id(),
+            'title' => $translation->label(),
+            'tid' => $item->target_id,
+            'sticky' => (int) $entity->isSticky(),
+            'created' => $entity->getCreatedTime(),
             'comment_count' => 0,
-            'last_comment_timestamp' => $entity->created,
+            'last_comment_timestamp' => $entity->getCreatedTime(),
           ));
         }
       }
@@ -1109,7 +1112,7 @@ function template_preprocess_forum_topic_list(&$variables) {
         '#new_posts' => $topic->new,
         '#num_posts' => $topic->comment_count,
         '#comment_mode' => $topic->comment_mode,
-        '#sticky' => $topic->sticky,
+        '#sticky' => $topic->isSticky(),
         '#first_new' => $topic->first_new,
       );
       $variables['topics'][$id]->zebra = $row % 2 == 0 ? 'odd' : 'even';
@@ -1120,16 +1123,20 @@ function template_preprocess_forum_topic_list(&$variables) {
       // them is a shadow copy.
       if ($variables['tid'] != $topic->forum_tid) {
         $variables['topics'][$id]->moved = TRUE;
-        $variables['topics'][$id]->title = check_plain($topic->title);
+        $variables['topics'][$id]->title = check_plain($topic->getTitle());
         $variables['topics'][$id]->message = l(t('This topic has been moved'), "forum/$topic->forum_tid");
       }
       else {
         $variables['topics'][$id]->moved = FALSE;
-        $variables['topics'][$id]->title = l($topic->title, 'node/' . $topic->id());
+        $variables['topics'][$id]->title_link = l($topic->getTitle(), 'node/' . $topic->id());
         $variables['topics'][$id]->message = '';
       }
-      $forum_submitted = array('#theme' => 'forum_submitted', '#topic' => $topic);
-      $variables['topics'][$id]->created = drupal_render($forum_submitted);
+      $forum_submitted = array('#theme' => 'forum_submitted', '#topic' => (object) array(
+        'uid' => $topic->getAuthorId(),
+        'name' => $topic->getAuthor()->getUsername(),
+        'created' => $topic->getCreatedTime(),
+      ));
+      $variables['topics'][$id]->submitted = drupal_render($forum_submitted);
       $forum_submitted = array(
         '#theme' => 'forum_submitted',
         '#topic' => isset($topic->last_reply) ? $topic->last_reply : NULL,
@@ -1139,7 +1146,7 @@ function template_preprocess_forum_topic_list(&$variables) {
       $variables['topics'][$id]->new_text = '';
       $variables['topics'][$id]->new_url = '';
       if ($topic->new_replies) {
-        $variables['topics'][$id]->new_text = format_plural($topic->new_replies, '1 new post<span class="visually-hidden"> in topic %title</span>', '@count new posts<span class="visually-hidden"> in topic %title</span>', array('%title' => $variables['topics'][$id]->title));
+        $variables['topics'][$id]->new_text = format_plural($topic->new_replies, '1 new post<span class="visually-hidden"> in topic %title</span>', '@count new posts<span class="visually-hidden"> in topic %title</span>', array('%title' => $variables['topics'][$id]->label()));
         $variables['topics'][$id]->new_url = url('node/' . $topic->id(), array('query' => comment_new_page_count($topic->comment_count, $topic->new_replies, $topic), 'fragment' => 'new'));
       }
 
diff --git a/core/modules/forum/lib/Drupal/forum/Tests/ForumNodeAccessTest.php b/core/modules/forum/lib/Drupal/forum/Tests/ForumNodeAccessTest.php
index 1491ce2..dde4701 100644
--- a/core/modules/forum/lib/Drupal/forum/Tests/ForumNodeAccessTest.php
+++ b/core/modules/forum/lib/Drupal/forum/Tests/ForumNodeAccessTest.php
@@ -82,16 +82,16 @@ function testForumNodeAccess() {
     $this->drupalGet('');
 
     // Ensure private node and public node are found.
-    $this->assertText($private_node->title, 'Private node found in block by $access_user');
-    $this->assertText($public_node->title, 'Public node found in block by $access_user');
+    $this->assertText($private_node->getTitle(), 'Private node found in block by $access_user');
+    $this->assertText($public_node->getTitle(), 'Public node found in block by $access_user');
 
     // Test for $no_access_user.
     $this->drupalLogin($no_access_user);
     $this->drupalGet('');
 
     // Ensure private node is not found but public is found.
-    $this->assertNoText($private_node->title, 'Private node not found in block by $no_access_user');
-    $this->assertText($public_node->title, 'Public node found in block by $no_access_user');
+    $this->assertNoText($private_node->getTitle(), 'Private node not found in block by $no_access_user');
+    $this->assertText($public_node->getTitle(), 'Public node found in block by $no_access_user');
   }
 
 }
diff --git a/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php b/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php
index d09baf5..b8e41ed 100644
--- a/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php
+++ b/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php
@@ -529,7 +529,7 @@ function createForumTopic($forum, $container = FALSE) {
     // Retrieve node object, ensure that the topic was created and in the proper forum.
     $node = $this->drupalGetNodeByTitle($title);
     $this->assertTrue($node != NULL, format_string('Node @title was loaded', array('@title' => $title)));
-    $this->assertEqual($node->taxonomy_forums[Language::LANGCODE_NOT_SPECIFIED][0]['target_id'], $tid, 'Saved forum topic was in the expected forum');
+    $this->assertEqual($node->taxonomy_forums->target_id, $tid, 'Saved forum topic was in the expected forum');
 
     // View forum topic.
     $this->drupalGet('node/' . $node->id());
@@ -607,7 +607,7 @@ private function verifyForums($node_user, EntityInterface $node, $admin, $respon
       // Verify topic was moved to a different forum.
       $forum_tid = db_query("SELECT tid FROM {forum} WHERE nid = :nid AND vid = :vid", array(
         ':nid' => $node->id(),
-        ':vid' => $node->vid,
+        ':vid' => $node->getRevisionId(),
       ))->fetchField();
       $this->assertTrue($forum_tid == $this->root_forum['tid'], 'The forum topic is linked to a different forum');
 
diff --git a/core/modules/forum/templates/forum-topic-list.html.twig b/core/modules/forum/templates/forum-topic-list.html.twig
index 85888ba..0e8cd16 100644
--- a/core/modules/forum/templates/forum-topic-list.html.twig
+++ b/core/modules/forum/templates/forum-topic-list.html.twig
@@ -13,7 +13,7 @@
  *   - icon: The icon to display.
  *   - moved: A flag to indicate whether the topic has been moved to another
  *     forum.
- *   - title: The title of the topic. Safe to output.
+ *   - title_link: The title of the topic. Safe to output.
  *   - message: If the topic has been moved, this contains an explanation and a
  *     link.
  *   - zebra: 'even' or 'odd', used for row class.
@@ -21,7 +21,7 @@
  *   - new_replies: A flag to indicate whether there are unread comments.
  *   - new_url: If there are unread replies, this is a link to them.
  *   - new_text: Text containing the translated, properly pluralized count.
- *   - created: Text representing when the topic was posted. Safe to output.
+ *   - submitted: Text representing when the topic was posted. Safe to output.
  *   - last_reply: Text representing when the topic was last replied to.
  *   - timestamp: The raw timestamp this topic was posted.
  * - topic_id: Numeric ID for the current forum topic.
@@ -42,10 +42,10 @@
         {{ topic.icon }}
         <div class="title">
           <div>
-            {{ topic.title }}
+            {{ topic.title_link }}
           </div>
           <div>
-            {{ topic.created }}
+            {{ topic.submitted }}
           </div>
         </div>
       </td>
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
index 8ec6727..b594767 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
@@ -58,7 +58,7 @@ function _testImageFieldFormatters($scheme) {
     $node = node_load($nid, TRUE);
 
     // Test that the default formatter is being used.
-    $image_uri = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id'])->getFileUri();
+    $image_uri = file_load($node->{$field_name}->target_id)->getFileUri();
     $image_info = array(
       'uri' => $image_uri,
       'width' => 40,
@@ -72,7 +72,7 @@ function _testImageFieldFormatters($scheme) {
       'type' => 'image',
       'settings' => array('image_link' => 'file'),
     );
-    $display = entity_get_display('node', $node->type, 'default');
+    $display = entity_get_display('node', $node->getType(), 'default');
     $display->setComponent($field_name, $display_options)
       ->save();
 
@@ -165,7 +165,7 @@ function testImageFieldSettings() {
     // style.
     $node = node_load($nid, TRUE);
     $image_info = array(
-      'uri' => file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id'])->getFileUri(),
+      'uri' => file_load($node->{$field_name}->target_id)->getFileUri(),
       'width' => 220,
       'height' => 110,
       'style_name' => 'medium',
@@ -175,7 +175,7 @@ function testImageFieldSettings() {
 
     // Add alt/title fields to the image and verify that they are displayed.
     $image_info = array(
-      'uri' => file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id'])->getFileUri(),
+      'uri' => file_load($node->{$field_name}->target_id)->getFileUri(),
       'alt' => $this->randomName(),
       'title' => $this->randomName(),
       'width' => 40,
@@ -243,7 +243,7 @@ function testImageFieldDefaultImage() {
     $nid = $this->uploadNodeImage($images[1], $field_name, 'article');
     $node = node_load($nid, TRUE);
     $image_info = array(
-      'uri' => file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id'])->getFileUri(),
+      'uri' => file_load($node->{$field_name}->target_id)->getFileUri(),
       'width' => 40,
       'height' => 20,
     );
diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module
index 01c9a4f..c4ff11f 100644
--- a/core/modules/locale/locale.module
+++ b/core/modules/locale/locale.module
@@ -869,15 +869,15 @@ function locale_system_file_system_settings_submit(&$form, $form_state) {
  * Implements hook_preprocess_HOOK() for node.html.twig.
  */
 function locale_preprocess_node(&$variables) {
-  if ($variables['node']->langcode != Language::LANGCODE_NOT_SPECIFIED) {
+  if ($variables['node']->language()->id != Language::LANGCODE_NOT_SPECIFIED) {
     $language_interface = language(Language::TYPE_INTERFACE);
 
-    $node_language = language_load($variables['node']->langcode);
+    $node_language = $variables['node']->language();
     if ($node_language->id != $language_interface->id) {
       // If the node language was different from the page language, we should
       // add markup to identify the language. Otherwise the page language is
       // inherited.
-      $variables['attributes']['lang'] = $variables['node']->langcode;
+      $variables['attributes']['lang'] = $node_language->id;
       if ($node_language->direction != $language_interface->direction) {
         // If text direction is different form the page's text direction, add
         // direction information as well.
diff --git a/core/modules/menu/menu.module b/core/modules/menu/menu.module
index 5d83382..a9a50a2 100644
--- a/core/modules/menu/menu.module
+++ b/core/modules/menu/menu.module
@@ -457,12 +457,12 @@ function menu_node_predelete(EntityInterface $node) {
 function menu_node_prepare_form(NodeInterface $node, $form_display, $operation, array &$form_state) {
   if (empty($node->menu)) {
     // Prepare the node for the edit form so that $node->menu always exists.
-    $menu_name = strtok(variable_get('menu_parent_' . $node->type, 'main:0'), ':');
+    $menu_name = strtok(variable_get('menu_parent_' . $node->getType(), 'main:0'), ':');
     $menu_link = FALSE;
     if ($node->id()) {
       $mlid = FALSE;
       // Give priority to the default menu
-      $type_menus = variable_get('menu_options_' . $node->type, array('main' => 'main'));
+      $type_menus = variable_get('menu_options_' . $node->getType(), array('main' => 'main'));
       if (in_array($menu_name, $type_menus)) {
         $query = Drupal::entityQuery('menu_link')
           ->condition('link_path', 'node/' . $node->id())
@@ -526,7 +526,7 @@ function menu_form_node_form_alter(&$form, $form_state) {
   // @todo This must be handled in a #process handler.
   $node = $form_state['controller']->getEntity();
   $link = $node->menu;
-  $type = $node->type;
+  $type = $node->getType();
   $options = menu_parent_options(menu_get_menus(), $link, $type);
   // If no possible parent menu items were found, there is nothing to display.
   if (empty($options)) {
diff --git a/core/modules/node/lib/Drupal/node/NodeAccessController.php b/core/modules/node/lib/Drupal/node/NodeAccessController.php
index 2556d76..3e4d97b 100644
--- a/core/modules/node/lib/Drupal/node/NodeAccessController.php
+++ b/core/modules/node/lib/Drupal/node/NodeAccessController.php
@@ -100,13 +100,8 @@ public function createAccess($entity_bundle = NULL, AccountInterface $account =
    */
   protected function checkAccess(EntityInterface $node, $operation, $langcode, AccountInterface $account) {
     // Fetch information from the node object if possible.
-    $status = isset($node->status) ? $node->status : NULL;
-    $uid = isset($node->uid) ? $node->uid : NULL;
-    // If it is a proper EntityNG object, use the proper methods.
-    if ($node instanceof EntityNG) {
-      $status = $node->getTranslation($langcode)->status->value;
-      $uid = $node->getTranslation($langcode)->uid->value;
-    }
+    $status = $node->getTranslation($langcode)->isPublished();
+    $uid = $node->getTranslation($langcode)->getAuthorId();
 
     // Check if authors can view their own unpublished nodes.
     if ($operation === 'view' && !$status && user_access('view own unpublished content', $account)) {
diff --git a/core/modules/node/lib/Drupal/node/NodeBCDecorator.php b/core/modules/node/lib/Drupal/node/NodeBCDecorator.php
deleted file mode 100644
index 77694fc..0000000
--- a/core/modules/node/lib/Drupal/node/NodeBCDecorator.php
+++ /dev/null
@@ -1,135 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\node\NodeBCDecorator.
- */
-
-namespace Drupal\node;
-
-use Drupal\Core\Entity\EntityBCDecorator;
-
-/**
- * Defines the node specific entity BC decorator.
- */
-class NodeBCDecorator extends EntityBCDecorator implements NodeInterface {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setTitle($title) {
-    $this->decorated->setTitle($title);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getCreatedTime() {
-    return $this->decorated->getCreatedTime();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setCreatedTime($timestamp) {
-    return $this->decorated->setCreatedTime($timestamp);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getChangedTime() {
-    return $this->decorated->getChangedTime();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isPromoted() {
-    return $this->decorated->isPromoted();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setPromoted($promoted) {
-    $this->decorated->setPromoted($promoted);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isSticky() {
-    return $this->decorated->isSticky();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setSticky($sticky) {
-    $this->decorated->setSticky($sticky);
-  }
-  /**
-   * {@inheritdoc}
-   */
-  public function getAuthor() {
-    return $this->decorated->getAuthor();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getAuthorId() {
-    return $this->decorated->getAuthorId();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setAuthorId($uid) {
-    $this->decorated->setAuthorId($uid);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isPublished() {
-    return $this->decorated->isPublished();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setPublished($published) {
-    $this->decorated->setPublished($published);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getRevisionCreationTime() {
-    return $this->decorated->getRevisionCreationTime();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setRevisionCreationTime($timestamp) {
-    return $this->decorated->setRevisionCreationTime($timestamp);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getRevisionAuthor() {
-    return $this->decorated->getRevisionAuthor();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setRevisionAuthorId($uid) {
-    return $this->decorated->setRevisionAuthorId($uid);
-  }
-
-}
diff --git a/core/modules/node/lib/Drupal/node/NodeFormController.php b/core/modules/node/lib/Drupal/node/NodeFormController.php
index ccc1dcc..de45706 100644
--- a/core/modules/node/lib/Drupal/node/NodeFormController.php
+++ b/core/modules/node/lib/Drupal/node/NodeFormController.php
@@ -9,13 +9,13 @@
 
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Datetime\DrupalDateTime;
-use Drupal\Core\Entity\EntityFormController;
+use Drupal\Core\Entity\EntityFormControllerNG;
 use Drupal\Core\Language\Language;
 
 /**
  * Form controller for the node edit forms.
  */
-class NodeFormController extends EntityFormController {
+class NodeFormController extends EntityFormControllerNG {
 
   /**
    * Default settings for this content/node type.
@@ -42,16 +42,16 @@ protected function prepareEntity() {
     if ($node->isNew()) {
       foreach (array('status', 'promote', 'sticky') as $key) {
         // Multistep node forms might have filled in something already.
-        if (!isset($node->$key)) {
+        if ($node->$key->isEmpty()) {
           $node->$key = (int) in_array($key, $this->settings['options']);
         }
       }
       global $user;
-      $node->uid = $user->id();
-      $node->created = REQUEST_TIME;
+      $node->setAuthorId($user->id());
+      $node->setCreatedTime(REQUEST_TIME);
     }
     else {
-      $node->date = format_date($node->created, 'custom', 'Y-m-d H:i:s O');
+      $node->date = format_date($node->getCreatedTime(), 'custom', 'Y-m-d H:i:s O');
       // Remove the log message from the original node entity.
       $node->log = NULL;
     }
@@ -82,7 +82,7 @@ public function form(array $form, array &$form_state) {
     // Override the default CSS class name, since the user-defined node type
     // name in 'TYPE-node-form' potentially clashes with third-party class
     // names.
-    $form['#attributes']['class'][0] = drupal_html_class('node-' . $node->type . '-form');
+    $form['#attributes']['class'][0] = drupal_html_class('node-' . $node->getType() . '-form');
 
     // Basic node information.
     // These elements are just values so they are not even sent to the client.
@@ -96,26 +96,26 @@ public function form(array $form, array &$form_state) {
     // Changed must be sent to the client, for later overwrite error checking.
     $form['changed'] = array(
       '#type' => 'hidden',
-      '#default_value' => isset($node->changed) ? $node->changed : NULL,
+      '#default_value' => $node->getChangedTime(),
     );
 
-    $node_type = node_type_load($node->type);
+    $node_type = node_type_load($node->getType());
     if ($node_type->has_title) {
       $form['title'] = array(
         '#type' => 'textfield',
         '#title' => check_plain($node_type->title_label),
         '#required' => TRUE,
-        '#default_value' => $node->title,
+        '#default_value' => $node->title->value,
         '#maxlength' => 255,
         '#weight' => -5,
       );
     }
 
-    $language_configuration = module_invoke('language', 'get_default_configuration', 'node', $node->type);
+    $language_configuration = module_invoke('language', 'get_default_configuration', 'node', $node->getType());
     $form['langcode'] = array(
       '#title' => t('Language'),
       '#type' => 'language_select',
-      '#default_value' => $node->langcode,
+      '#default_value' => $node->getUntranslated()->language()->id,
       '#languages' => Language::STATE_ALL,
       '#access' => isset($language_configuration['language_show']) && $language_configuration['language_show'],
     );
@@ -155,7 +155,7 @@ public function form(array $form, array &$form_state) {
       '#type' => 'textarea',
       '#title' => t('Revision log message'),
       '#rows' => 4,
-      '#default_value' => !empty($node->log) ? $node->log : '',
+      '#default_value' => !empty($node->log->value) ? $node->log->value : '',
       '#description' => t('Briefly describe the changes you have made.'),
       '#states' => array(
         'visible' => array(
@@ -191,7 +191,7 @@ public function form(array $form, array &$form_state) {
       '#title' => t('Authored by'),
       '#maxlength' => 60,
       '#autocomplete_path' => 'user/autocomplete',
-      '#default_value' => !empty($node->name) ? $node->name : '',
+      '#default_value' => $node->getAuthorId()? $node->getAuthor()->getUsername() : '',
       '#weight' => -1,
       '#description' => t('Leave blank for %anonymous.', array('%anonymous' => $user_config->get('anonymous'))),
     );
@@ -199,7 +199,7 @@ public function form(array $form, array &$form_state) {
       '#type' => 'textfield',
       '#title' => t('Authored on'),
       '#maxlength' => 25,
-      '#description' => t('Format: %time. The date format is YYYY-MM-DD and %timezone is the time zone offset from UTC. Leave blank to use the time of form submission.', array('%time' => !empty($node->date) ? date_format(date_create($node->date), 'Y-m-d H:i:s O') : format_date($node->created, 'custom', 'Y-m-d H:i:s O'), '%timezone' => !empty($node->date) ? date_format(date_create($node->date), 'O') : format_date($node->created, 'custom', 'O'))),
+      '#description' => t('Format: %time. The date format is YYYY-MM-DD and %timezone is the time zone offset from UTC. Leave blank to use the time of form submission.', array('%time' => !empty($node->date) ? date_format(date_create($node->date), 'Y-m-d H:i:s O') : format_date($node->getCreatedTime(), 'custom', 'Y-m-d H:i:s O'), '%timezone' => !empty($node->date) ? date_format(date_create($node->date), 'O') : format_date($node->getCreatedTime(), 'custom', 'O'))),
       '#default_value' => !empty($node->date) ? $node->date : '',
     );
 
@@ -222,13 +222,13 @@ public function form(array $form, array &$form_state) {
     $form['options']['promote'] = array(
       '#type' => 'checkbox',
       '#title' => t('Promoted to front page'),
-      '#default_value' => $node->promote,
+      '#default_value' => $node->isPromoted(),
     );
 
     $form['options']['sticky'] = array(
       '#type' => 'checkbox',
       '#title' => t('Sticky at top of lists'),
-      '#default_value' => $node->sticky,
+      '#default_value' => $node->isSticky(),
     );
 
     // This form uses a button-level #submit handler for the form's main submit
@@ -271,7 +271,7 @@ protected function actions(array $form, array &$form_state) {
         $element['publish']['#value'] = t('Save and publish');
       }
       else {
-        $element['publish']['#value'] = $node->status ? t('Save and keep published') : t('Save and publish');
+        $element['publish']['#value'] = $node->isPublished() ? t('Save and keep published') : t('Save and publish');
       }
       $element['publish']['#weight'] = 0;
       array_unshift($element['publish']['#submit'], array($this, 'publish'));
@@ -283,13 +283,13 @@ protected function actions(array $form, array &$form_state) {
         $element['unpublish']['#value'] = t('Save as unpublished');
       }
       else {
-        $element['unpublish']['#value'] = !$node->status ? t('Save and keep unpublished') : t('Save and unpublish');
+        $element['unpublish']['#value'] = !$node->isPublished() ? t('Save and keep unpublished') : t('Save and unpublish');
       }
       $element['unpublish']['#weight'] = 10;
       array_unshift($element['unpublish']['#submit'], array($this, 'unpublish'));
 
       // If already published, the 'publish' button is primary.
-      if ($node->status) {
+      if ($node->isPublished()) {
         unset($element['unpublish']['#button_type']);
       }
       // Otherwise, the 'unpublish' button is primary and should come first.
@@ -327,16 +327,16 @@ protected function actions(array $form, array &$form_state) {
   public function validate(array $form, array &$form_state) {
     $node = $this->buildEntity($form, $form_state);
 
-    if ($node->id() && (node_last_changed($node->id(), $this->getFormLangcode($form_state)) > $node->changed)) {
+    if ($node->id() && (node_last_changed($node->id(), $this->getFormLangcode($form_state)) > $node->getChangedTime())) {
       form_set_error('changed', t('The content on this page has either been modified by another user, or you have already submitted modifications using this form. As a result, your changes cannot be saved.'));
     }
 
     // Validate the "authored by" field.
-    if (!empty($node->name) && !($account = user_load_by_name($node->name))) {
+    if (!empty($form_state['values']['name']) && !($account = user_load_by_name($form_state['values']['name']))) {
       // The use of empty() is mandatory in the context of usernames
       // as the empty string denotes the anonymous user. In case we
       // are dealing with an anonymous user we set the user ID to 0.
-      form_set_error('name', t('The username %name does not exist.', array('%name' => $node->name)));
+      form_set_error('name', t('The username %name does not exist.', array('%name' => $form_state['values']['name'])));
     }
 
     // Validate the "authored on" field.
@@ -373,9 +373,13 @@ public function submit(array $form, array &$form_state) {
     // Save as a new revision if requested to do so.
     if (!empty($form_state['values']['revision'])) {
       $node->setNewRevision();
+      // If a new revision is created, save the current user as revision author.
+      $node->setRevisionCreationTime(REQUEST_TIME);
+      global $user;
+      $node->setRevisionAuthorId($user->id());
     }
 
-    node_submit($node);
+    $node->validated = TRUE;
     foreach (\Drupal::moduleHandler()->getImplementations('node_submit') as $module) {
       $function = $module . '_node_submit';
       $function($node, $form, $form_state);
@@ -411,7 +415,7 @@ public function preview(array $form, array &$form_state) {
    */
   public function publish(array $form, array &$form_state) {
     $node = $this->entity;
-    $node->status = 1;
+    $node->setPublished(TRUE);
     return $node;
   }
 
@@ -425,11 +429,35 @@ public function publish(array $form, array &$form_state) {
    */
   public function unpublish(array $form, array &$form_state) {
     $node = $this->entity;
-    $node->status = 0;
+    $node->setPublished(FALSE);
     return $node;
   }
 
   /**
+   * {@inheritdoc}
+   */
+  public function buildEntity(array $form, array &$form_state) {
+    $entity = parent::buildEntity($form, $form_state);
+    // A user might assign the node author by entering a user name in the node
+    // form, which we then need to translate to a user ID.
+    if (!empty($form_state['values']['name']) && $account = user_load_by_name($form_state['values']['name'])) {
+      $entity->setAuthorId($account->id());
+    }
+    else {
+      $entity->setAuthorId(0);
+    }
+
+    if (!empty($form_state['values']['date']) && $form_state['values']['date'] instanceOf DrupalDateTime) {
+      $entity->setCreatedTime($form_state['values']['date']->getTimestamp());
+    }
+    else {
+      $entity->setCreatedTime(REQUEST_TIME);
+    }
+    return $entity;
+  }
+
+
+  /**
    * Overrides Drupal\Core\Entity\EntityFormController::save().
    */
   public function save(array $form, array &$form_state) {
@@ -437,7 +465,7 @@ public function save(array $form, array &$form_state) {
     $insert = $node->isNew();
     $node->save();
     $node_link = l(t('view'), 'node/' . $node->id());
-    $watchdog_args = array('@type' => $node->type, '%title' => $node->label());
+    $watchdog_args = array('@type' => $node->getType(), '%title' => $node->label());
     $t_args = array('@type' => node_get_type_label($node), '%title' => $node->label());
 
     if ($insert) {
diff --git a/core/modules/node/lib/Drupal/node/NodeGrantDatabaseStorage.php b/core/modules/node/lib/Drupal/node/NodeGrantDatabaseStorage.php
index 9688390..537b26a 100644
--- a/core/modules/node/lib/Drupal/node/NodeGrantDatabaseStorage.php
+++ b/core/modules/node/lib/Drupal/node/NodeGrantDatabaseStorage.php
@@ -71,7 +71,7 @@ public function access(EntityInterface $node, $operation, $langcode, AccountInte
       ->condition('langcode', $langcode);
     // If the node is published, also take the default grant into account. The
     // default is saved with a node ID of 0.
-    $status = $node instanceof EntityNG ? $node->status : $node->get('status', $langcode)->value;
+    $status = $node->isPublished();
     if ($status) {
       $nids = $query->orConditionGroup()
         ->condition($nids)
@@ -213,7 +213,7 @@ public function write(NodeInterface $node, array $grants, $realm = NULL, $delete
             $grant['nid'] = $node->id();
             $grant['langcode'] = $grant_langcode;
             // The record with the original langcode is used as the fallback.
-            if ($grant['langcode'] == $node->langcode) {
+            if ($grant['langcode'] == $node->language()->id) {
               $grant['fallback'] = 1;
             }
             else {
diff --git a/core/modules/node/lib/Drupal/node/NodeInterface.php b/core/modules/node/lib/Drupal/node/NodeInterface.php
index 61e60a5..a9acd34 100644
--- a/core/modules/node/lib/Drupal/node/NodeInterface.php
+++ b/core/modules/node/lib/Drupal/node/NodeInterface.php
@@ -16,6 +16,23 @@
 interface NodeInterface extends ContentEntityInterface {
 
   /**
+   * Returns the node type.
+   *
+   * @return string
+   *   The node type.
+   */
+  public function getType();
+
+  /**
+   *
+   * Returns the node title.
+   *
+   * @return string
+   *   Title of the node.
+   */
+  public function getTitle();
+
+  /**
    * Sets the node title.
    *
    * @param string $title
diff --git a/core/modules/node/lib/Drupal/node/NodeRenderController.php b/core/modules/node/lib/Drupal/node/NodeRenderController.php
index 1b234f7..c571292 100644
--- a/core/modules/node/lib/Drupal/node/NodeRenderController.php
+++ b/core/modules/node/lib/Drupal/node/NodeRenderController.php
@@ -49,7 +49,7 @@ public function buildContent(array $entities, array $displays, $view_mode, $lang
           'title' => t('Read more<span class="visually-hidden"> about @title</span>', array(
             '@title' => $node_title_stripped,
           )),
-          'href' => 'node/' . $entity->nid,
+          'href' => 'node/' . $entity->id(),
           'html' => TRUE,
           'attributes' => array(
             'rel' => 'tag',
diff --git a/core/modules/node/lib/Drupal/node/NodeStorageController.php b/core/modules/node/lib/Drupal/node/NodeStorageController.php
index 1a874fe..ee282d8 100644
--- a/core/modules/node/lib/Drupal/node/NodeStorageController.php
+++ b/core/modules/node/lib/Drupal/node/NodeStorageController.php
@@ -26,22 +26,21 @@ public function create(array $values) {
     if (empty($values['created'])) {
       $values['created'] = REQUEST_TIME;
     }
-    return parent::create($values)->getBCEntity();
+    return parent::create($values);
   }
 
   /**
    * Overrides Drupal\Core\Entity\DatabaseStorageControllerNG::attachLoad().
    */
   protected function attachLoad(&$queried_entities, $load_revision = FALSE) {
-    $nodes = $this->mapFromStorageRecords($queried_entities, $load_revision);
+    $queried_entities = $this->mapFromStorageRecords($queried_entities, $load_revision);
 
     // Create an array of nodes for each content type and pass this to the
     // object type specific callback. To preserve backward-compatibility we
     // pass on BC decorators to node-specific hooks, while we pass on the
     // regular entity objects else.
     $typed_nodes = array();
-    foreach ($nodes as $id => $node) {
-      $queried_entities[$id] = $node->getBCEntity();
+    foreach ($queried_entities as $id => $node) {
       $typed_nodes[$node->bundle()][$id] = $queried_entities[$id];
     }
 
@@ -72,31 +71,6 @@ protected function attachLoad(&$queried_entities, $load_revision = FALSE) {
   }
 
   /**
-   * Overrides Drupal\Core\Entity\DatabaseStorageController::invokeHook().
-   */
-  protected function invokeHook($hook, EntityInterface $node) {
-    $node = $node->getUntranslated()->getBCEntity();
-
-    // Inline parent::invokeHook() to pass on BC-entities to node-specific
-    // hooks.
-
-    $function = 'field_attach_' . $hook;
-    // @todo: field_attach_delete_revision() is named the wrong way round,
-    // consider renaming it.
-    if ($function == 'field_attach_revision_delete') {
-      $function = 'field_attach_delete_revision';
-    }
-    if (!empty($this->entityInfo['fieldable']) && function_exists($function)) {
-      $function($node);
-    }
-
-    // Invoke the hook.
-    module_invoke_all($this->entityType . '_' . $hook, $node);
-    // Invoke the respective entity-level hook.
-    module_invoke_all('entity_' . $hook, $node, $this->entityType);
-  }
-
-  /**
    * {@inheritdoc}
    */
   protected function mapToDataStorageRecord(EntityInterface $entity, $langcode) {
diff --git a/core/modules/node/lib/Drupal/node/NodeTranslationController.php b/core/modules/node/lib/Drupal/node/NodeTranslationController.php
index 4df3946..9436996 100644
--- a/core/modules/node/lib/Drupal/node/NodeTranslationController.php
+++ b/core/modules/node/lib/Drupal/node/NodeTranslationController.php
@@ -54,7 +54,7 @@ public function entityFormEntityBuild($entity_type, EntityInterface $entity, arr
     if (isset($form_state['values']['content_translation'])) {
       $form_controller = content_translation_form_controller($form_state);
       $translation = &$form_state['values']['content_translation'];
-      $translation['status'] = $form_controller->getEntity()->status;
+      $translation['status'] = $form_controller->getEntity()->isPublished();
       $translation['name'] = $form_state['values']['name'];
       $translation['created'] = $form_state['values']['date'];
     }
diff --git a/core/modules/node/lib/Drupal/node/Plugin/Action/DemoteNode.php b/core/modules/node/lib/Drupal/node/Plugin/Action/DemoteNode.php
index 7676a76..8adbdb1 100644
--- a/core/modules/node/lib/Drupal/node/Plugin/Action/DemoteNode.php
+++ b/core/modules/node/lib/Drupal/node/Plugin/Action/DemoteNode.php
@@ -26,7 +26,7 @@ class DemoteNode extends ActionBase {
    * {@inheritdoc}
    */
   public function execute($entity = NULL) {
-    $entity->promote = NODE_NOT_PROMOTED;
+    $entity->setPromoted(FALSE);
     $entity->save();
   }
 
diff --git a/core/modules/node/lib/Drupal/node/Plugin/Action/PromoteNode.php b/core/modules/node/lib/Drupal/node/Plugin/Action/PromoteNode.php
index 56f8658..0b87b38 100644
--- a/core/modules/node/lib/Drupal/node/Plugin/Action/PromoteNode.php
+++ b/core/modules/node/lib/Drupal/node/Plugin/Action/PromoteNode.php
@@ -26,8 +26,8 @@ class PromoteNode extends ActionBase {
    * {@inheritdoc}
    */
   public function execute($entity = NULL) {
-    $entity->status = NODE_PUBLISHED;
-    $entity->promote = NODE_PROMOTED;
+    $entity->setPublished(TRUE);
+    $entity->setPromoted(TRUE);
     $entity->save();
   }
 
diff --git a/core/modules/node/lib/Drupal/node/Plugin/Action/UnpublishByKeywordNode.php b/core/modules/node/lib/Drupal/node/Plugin/Action/UnpublishByKeywordNode.php
index 2ad65f8..a525802 100644
--- a/core/modules/node/lib/Drupal/node/Plugin/Action/UnpublishByKeywordNode.php
+++ b/core/modules/node/lib/Drupal/node/Plugin/Action/UnpublishByKeywordNode.php
@@ -29,7 +29,7 @@ public function execute($node = NULL) {
     foreach ($this->configuration['keywords'] as $keyword) {
       $elements = node_view(clone $node);
       if (strpos(drupal_render($elements), $keyword) !== FALSE || strpos($node->label(), $keyword) !== FALSE) {
-        $node->status = NODE_NOT_PUBLISHED;
+        $node->setPublished(FALSE);
         $node->save();
         break;
       }
diff --git a/core/modules/node/lib/Drupal/node/Plugin/Condition/NodeType.php b/core/modules/node/lib/Drupal/node/Plugin/Condition/NodeType.php
index 4f30bb7..bf71eb2 100644
--- a/core/modules/node/lib/Drupal/node/Plugin/Condition/NodeType.php
+++ b/core/modules/node/lib/Drupal/node/Plugin/Condition/NodeType.php
@@ -85,7 +85,7 @@ public function summary() {
    */
   public function evaluate() {
     $node = $this->getContextValue('node');
-    return in_array($node->type, $this->configuration['bundles']);
+    return in_array($node->getType(), $this->configuration['bundles']);
   }
 
 }
diff --git a/core/modules/node/lib/Drupal/node/Plugin/Core/Entity/Node.php b/core/modules/node/lib/Drupal/node/Plugin/Core/Entity/Node.php
index 54ae77f..ab4798f 100644
--- a/core/modules/node/lib/Drupal/node/Plugin/Core/Entity/Node.php
+++ b/core/modules/node/lib/Drupal/node/Plugin/Core/Entity/Node.php
@@ -12,7 +12,6 @@
 use Drupal\Core\Entity\Annotation\EntityType;
 use Drupal\Core\Annotation\Translation;
 use Drupal\node\NodeInterface;
-use Drupal\node\NodeBCDecorator;
 
 /**
  * Defines the node entity class.
@@ -104,7 +103,7 @@ public function preSaveRevision(EntityStorageControllerInterface $storage_contro
       // need to make sure $entity->log is reset whenever it is empty.
       // Therefore, this code allows us to avoid clobbering an existing log
       // entry with an empty one.
-      $record->log = $this->original->log;
+      $record->log = $this->original->log->value;
     }
   }
 
@@ -116,24 +115,13 @@ public function postSave(EntityStorageControllerInterface $storage_controller, $
     // default revision. There's no need to delete existing records if the node
     // is new.
     if ($this->isDefaultRevision()) {
-      \Drupal::entityManager()->getAccessController('node')->writeGrants($this->getBCEntity(), $update);
+      \Drupal::entityManager()->getAccessController('node')->writeGrants($this, $update);
     }
   }
 
   /**
    * {@inheritdoc}
    */
-  public function getBCEntity() {
-    if (!isset($this->bcEntity)) {
-      $this->getPropertyDefinitions();
-      $this->bcEntity = new NodeBCDecorator($this, $this->fieldDefinitions);
-    }
-    return $this->bcEntity;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public static function preDelete(EntityStorageControllerInterface $storage_controller, array $entities) {
     if (module_exists('search')) {
       foreach ($entities as $entity) {
@@ -145,6 +133,20 @@ public static function preDelete(EntityStorageControllerInterface $storage_contr
   /**
    * {@inheritdoc}
    */
+  public function getType() {
+    return $this->bundle();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getTitle() {
+    return $this->get('title')->value;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function setTitle($title) {
     $this->set('title', $title);
     return $this;
@@ -184,7 +186,7 @@ public function isPromoted() {
    * {@inheritdoc}
    */
   public function setPromoted($promoted) {
-    $this->set('promoted', $promoted ? NODE_PROMOTED : NODE_NOT_PROMOTED);
+    $this->set('promote', $promoted ? NODE_PROMOTED : NODE_NOT_PROMOTED);
     return $this;
   }
 
@@ -221,12 +223,7 @@ public function setPublished($published) {
    * {@inheritdoc}
    */
   public function getAuthor() {
-    $entity = $this->get('uid')->entity;
-    // If no user is given, default to the anonymous user.
-    if (!$entity) {
-      return user_load(0);
-    }
-    return $entity;
+    return $this->get('uid')->entity;
   }
 
   /**
diff --git a/core/modules/node/lib/Drupal/node/Plugin/views/argument_validator/Node.php b/core/modules/node/lib/Drupal/node/Plugin/views/argument_validator/Node.php
index 36f3ab0..ac76687 100644
--- a/core/modules/node/lib/Drupal/node/Plugin/views/argument_validator/Node.php
+++ b/core/modules/node/lib/Drupal/node/Plugin/views/argument_validator/Node.php
@@ -106,7 +106,7 @@ public function validateArgument($argument) {
           return TRUE;
         }
 
-        return isset($types[$node->type]);
+        return isset($types[$node->getType()]);
 
       case 'nids':
         $nids = new stdClass();
@@ -121,7 +121,7 @@ public function validateArgument($argument) {
 
         $nodes = node_load_multiple($nids->value);
         foreach ($nodes as $node) {
-          if ($types && empty($types[$node->type])) {
+          if ($types && empty($types[$node->getType()])) {
             return FALSE;
           }
 
diff --git a/core/modules/node/lib/Drupal/node/Plugin/views/field/LinkEdit.php b/core/modules/node/lib/Drupal/node/Plugin/views/field/LinkEdit.php
index 63c07fb..fdf933e 100644
--- a/core/modules/node/lib/Drupal/node/Plugin/views/field/LinkEdit.php
+++ b/core/modules/node/lib/Drupal/node/Plugin/views/field/LinkEdit.php
@@ -30,7 +30,7 @@ protected function renderLink($node, ResultRow $values) {
     }
 
     $this->options['alter']['make_link'] = TRUE;
-    $this->options['alter']['path'] = "node/$node->nid/edit";
+    $this->options['alter']['path'] = "node/" . $node->id() . "/edit";
     $this->options['alter']['query'] = drupal_get_destination();
 
     $text = !empty($this->options['text']) ? $this->options['text'] : t('edit');
diff --git a/core/modules/node/lib/Drupal/node/Plugin/views/field/RevisionLink.php b/core/modules/node/lib/Drupal/node/Plugin/views/field/RevisionLink.php
index 6b43b81..8b3d3d7 100644
--- a/core/modules/node/lib/Drupal/node/Plugin/views/field/RevisionLink.php
+++ b/core/modules/node/lib/Drupal/node/Plugin/views/field/RevisionLink.php
@@ -70,7 +70,7 @@ function get_revision_entity($values, $op) {
     $vid = $this->getValue($values, 'node_vid');
     $node = $this->getEntity($values);
     // Unpublished nodes ignore access control.
-    $node->status = 1;
+    $node->setPublished(TRUE);
     // Ensure user has access to perform the operation on this node.
     if (!node_access($op, $node)) {
       return array($node, NULL);
diff --git a/core/modules/node/lib/Drupal/node/Plugin/views/row/Rss.php b/core/modules/node/lib/Drupal/node/Plugin/views/row/Rss.php
index 89c7940..fef9608 100644
--- a/core/modules/node/lib/Drupal/node/Plugin/views/row/Rss.php
+++ b/core/modules/node/lib/Drupal/node/Plugin/views/row/Rss.php
@@ -117,11 +117,11 @@ public function render($row) {
     $node->rss_elements = array(
       array(
         'key' => 'pubDate',
-        'value' => gmdate('r', $node->created),
+        'value' => gmdate('r', $node->getCreatedTime()),
       ),
       array(
         'key' => 'dc:creator',
-        'value' => $node->name,
+        'value' => $node->getAuthor()->getUsername(),
       ),
       array(
         'key' => 'guid',
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeAccessLanguageTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeAccessLanguageTest.php
index 54ba085..6facbdb 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeAccessLanguageTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeAccessLanguageTest.php
@@ -47,6 +47,10 @@ function setUp() {
       'id' => 'ca',
     ));
     language_save($language);
+    $language = new Language(array(
+      'id' => 'hr',
+    ));
+    language_save($language);
   }
 
   /**
@@ -61,7 +65,7 @@ function testNodeAccess() {
     // Creating a public node with langcode Hungarian, will be saved as the
     // fallback in node access table.
     $node_public = $this->drupalCreateNode(array('body' => array(array()), 'langcode' => 'hu', 'private' => FALSE));
-    $this->assertTrue($node_public->langcode == 'hu', 'Node created as Hungarian.');
+    $this->assertTrue($node_public->language()->id == 'hu', 'Node created as Hungarian.');
 
     // Tests the default access is provided for the public Hungarian node.
     $this->assertNodeAccess($expected_node_access, $node_public, $web_user);
@@ -78,7 +82,7 @@ function testNodeAccess() {
     // Creating a public node with no special langcode, like when no language
     // module enabled.
     $node_public_no_language = $this->drupalCreateNode(array('private' => FALSE));
-    $this->assertTrue($node_public_no_language->langcode == Language::LANGCODE_NOT_SPECIFIED, 'Node created with not specified language.');
+    $this->assertTrue($node_public_no_language->language()->id == Language::LANGCODE_NOT_SPECIFIED, 'Node created with not specified language.');
 
     // Tests that access is granted if requested with no language.
     $this->assertNodeAccess($expected_node_access, $node_public_no_language, $web_user);
@@ -113,14 +117,14 @@ function testNodeAccessPrivate() {
     $web_user = $this->drupalCreateUser(array('access content'));
 
     $node = $this->drupalCreateNode(array('body' => array(array()), 'langcode' => 'hu'));
-    $this->assertTrue($node->langcode == 'hu', 'Node created as Hungarian.');
+    $this->assertTrue($node->language()->id == 'hu', 'Node created as Hungarian.');
     $expected_node_access = array('view' => TRUE, 'update' => FALSE, 'delete' => FALSE);
     $expected_node_access_no_access = array('view' => FALSE, 'update' => FALSE, 'delete' => FALSE);
 
     // Creating a private node with langcode Hungarian, will be saved as the
     // fallback in node access table.
     $node_public = $this->drupalCreateNode(array('body' => array(array()), 'langcode' => 'hu', 'private' => TRUE));
-    $this->assertTrue($node_public->langcode == 'hu', 'Node created as Hungarian.');
+    $this->assertTrue($node_public->language()->id == 'hu', 'Node created as Hungarian.');
 
     // Tests the default access is not provided for the private Hungarian node.
     $this->assertNodeAccess($expected_node_access_no_access, $node_public, $web_user);
@@ -137,7 +141,7 @@ function testNodeAccessPrivate() {
     // Creating a private node with no special langcode, like when no language
     // module enabled.
     $node_private_no_language = $this->drupalCreateNode(array('private' => TRUE));
-    $this->assertTrue($node_private_no_language->langcode == Language::LANGCODE_NOT_SPECIFIED, 'Node created with not specified language.');
+    $this->assertTrue($node_private_no_language->language()->id == Language::LANGCODE_NOT_SPECIFIED, 'Node created with not specified language.');
 
     // Tests that access is not granted if requested with no language.
     $this->assertNodeAccess($expected_node_access_no_access, $node_private_no_language, $web_user);
@@ -179,17 +183,17 @@ function testNodeAccessQueryTag() {
     // Creating a private node with langcode Hungarian, will be saved as
     // the fallback in node access table.
     $node_private = $this->drupalCreateNode(array('body' => array(array()), 'langcode' => 'hu', 'private' => TRUE));
-    $this->assertTrue($node_private->langcode == 'hu', 'Node created as Hungarian.');
+    $this->assertTrue($node_private->language()->id == 'hu', 'Node created as Hungarian.');
 
     // Creating a public node with langcode Hungarian, will be saved as
     // the fallback in node access table.
     $node_public = $this->drupalCreateNode(array('body' => array(array()), 'langcode' => 'hu', 'private' => FALSE));
-    $this->assertTrue($node_public->langcode == 'hu', 'Node created as Hungarian.');
+    $this->assertTrue($node_public->language()->id == 'hu', 'Node created as Hungarian.');
 
     // Creating a public node with no special langcode, like when no language
     // module enabled.
     $node_no_language = $this->drupalCreateNode(array('private' => FALSE));
-    $this->assertTrue($node_no_language->langcode == Language::LANGCODE_NOT_SPECIFIED, 'Node created with not specified language.');
+    $this->assertTrue($node_no_language->language()->id == Language::LANGCODE_NOT_SPECIFIED, 'Node created with not specified language.');
 
     // Query the nodes table as the web user with the node access tag and no
     // specific langcode.
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeBlockFunctionalTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeBlockFunctionalTest.php
index f652895..a63bcf8 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeBlockFunctionalTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeBlockFunctionalTest.php
@@ -76,13 +76,13 @@ public function testRecentNodeBlock() {
     // Change the changed time for node so that we can test ordering.
     db_update('node_field_data')
       ->fields(array(
-        'changed' => $node1->changed + 100,
+        'changed' => $node1->getChangedTime() + 100,
       ))
       ->condition('nid', $node2->id())
       ->execute();
     db_update('node_field_data')
       ->fields(array(
-        'changed' => $node1->changed + 200,
+        'changed' => $node1->getChangedTime() + 200,
       ))
       ->condition('nid', $node3->id())
       ->execute();
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php b/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php
index 6df2698..c66865e 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php
@@ -82,7 +82,7 @@ function testMultilingualNodeForm() {
     $this->drupalPost('node/add/page', $edit, t('Save'));
 
     // Check that the node exists in the database.
-    $node = $this->drupalGetNodeByTitle($edit[$title_key])->getNGEntity();
+    $node = $this->drupalGetNodeByTitle($edit[$title_key]);
     $this->assertTrue($node, 'Node found in database.');
     $this->assertTrue($node->language()->id == $langcode && $node->body->value == $body_value, 'Field language correctly set.');
 
@@ -94,7 +94,7 @@ function testMultilingualNodeForm() {
       'langcode' => $langcode,
     );
     $this->drupalPost(NULL, $edit, t('Save'));
-    $node = $this->drupalGetNodeByTitle($edit[$title_key], TRUE)->getNGEntity();
+    $node = $this->drupalGetNodeByTitle($edit[$title_key], TRUE);
     $this->assertTrue($node, 'Node found in database.');
     $this->assertTrue($node->language()->id == $langcode && $node->body->value == $body_value, 'Field language correctly changed.');
 
@@ -136,7 +136,7 @@ function testMultilingualDisplaySettings() {
       ':id' => 'node-' . $node->id(),
       ':class' => 'content',
     ));
-    $this->assertEqual(current($body), $node->body['en'][0]['value'], 'Node body found.');
+    $this->assertEqual(current($body), $node->body->value, 'Node body found.');
   }
 
 }
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeFormButtonsTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeFormButtonsTest.php
index 2a8f025..6a0902f 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeFormButtonsTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeFormButtonsTest.php
@@ -52,7 +52,7 @@ function testNodeFormButtons() {
 
     // Get the node.
     $node_1 = node_load(1);
-    $this->assertEqual(1, $node_1->status, 'Node is published');
+    $this->assertTrue($node_1->isPublished(), 'Node is published');
 
     // Verify the buttons on a node edit form.
     $this->drupalGet('node/' . $node_1->id() . '/edit');
@@ -62,13 +62,13 @@ function testNodeFormButtons() {
     // 'Save and keep published'.
     $this->drupalPost(NULL, $edit, t('Save and keep published'));
     $node = node_load(1, TRUE);
-    $this->assertEqual(1, $node_1->status, 'Node is published');
+    $this->assertTrue($node_1->isPublished(), 'Node is published');
 
     // Save the node and verify it's unpublished after clicking
     // 'Save and unpublish'.
     $this->drupalPost('node/' . $node_1->id() . '/edit', $edit, t('Save and unpublish'));
     $node_1 = node_load(1, TRUE);
-    $this->assertEqual(0, $node_1->status, 'Node is unpublished');
+    $this->assertFalse($node_1->isPublished(), 'Node is unpublished');
 
     // Verify the buttons on an unpublished node edit screen.
     $this->drupalGet('node/' . $node_1->id() . '/edit');
@@ -86,7 +86,7 @@ function testNodeFormButtons() {
     $edit = array('title' => $this->randomString());
     $this->drupalPost('node/add/article', $edit, t('Save'));
     $node_2 = node_load(2);
-    $this->assertEqual(1, $node_2->status, 'Node is published');
+    $this->assertTrue($node_2->isPublished(), 'Node is published');
 
     // Login as an administrator and unpublish the node that just
     // was created by the normal user.
@@ -94,7 +94,7 @@ function testNodeFormButtons() {
     $this->drupalLogin($this->admin_user);
     $this->drupalPost('node/' . $node_2->id() . '/edit', array(), t('Save and unpublish'));
     $node_2 = node_load(2, TRUE);
-    $this->assertEqual(0, $node_2->status, 'Node is unpublished');
+    $this->assertFalse($node_2->isPublished(), 'Node is unpublished');
 
     // Login again as the normal user, save the node and verify
     // it's still unpublished.
@@ -102,7 +102,7 @@ function testNodeFormButtons() {
     $this->drupalLogin($this->web_user);
     $this->drupalPost('node/' . $node_2->id() . '/edit', array(), t('Save'));
     $node_2 = node_load(2, TRUE);
-    $this->assertEqual(0, $node_2->status, 'Node is still unpublished');
+    $this->assertFalse($node_2->isPublished(), 'Node is still unpublished');
     $this->drupalLogout();
 
     // Set article content type default to unpublished. This will change the
@@ -122,7 +122,7 @@ function testNodeFormButtons() {
     $edit = array('title' => $this->randomString());
     $this->drupalPost('node/add/article', $edit, t('Save'));
     $node_3 = node_load(3);
-    $this->assertEqual(0, $node_3->status, 'Node is unpublished');
+    $this->assertFalse($node_3->isPublished(), 'Node is unpublished');
   }
 
   /**
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeRevisionsAllTestCase.php b/core/modules/node/lib/Drupal/node/Tests/NodeRevisionsAllTestCase.php
index 3906c94..c98515f 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeRevisionsAllTestCase.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeRevisionsAllTestCase.php
@@ -59,7 +59,7 @@ function setUp() {
 
       // Create revision with a random title and body and update variables.
       $node->title = $this->randomName();
-      $node->body[$node->language()->id][0] = array(
+      $node->body = array(
         'value' => $this->randomName(32),
         'format' => filter_default_format(),
       );
@@ -97,11 +97,11 @@ function testRevisions() {
     $this->drupalLogin($content_admin);
 
     // Confirm the correct revision text appears on "view revisions" page.
-    $this->drupalGet("node/$node->nid/revisions/$node->vid/view");
-    $this->assertText($node->body[Language::LANGCODE_NOT_SPECIFIED][0]['value'], 'Correct text displays for version.');
+    $this->drupalGet("node/" . $node->id() . "/revisions/" . $node->getRevisionId() . "/view");
+    $this->assertText($node->body->value, 'Correct text displays for version.');
 
     // Confirm the correct log message appears on "revisions overview" page.
-    $this->drupalGet("node/$node->nid/revisions");
+    $this->drupalGet("node/" . $node->id() . "/revisions");
     foreach ($logs as $log) {
       $this->assertText($log, 'Log message found.');
     }
@@ -110,47 +110,47 @@ function testRevisions() {
     $this->assertTrue($node->isDefaultRevision(), 'Third node revision is the current one.');
 
     // Confirm that revisions revert properly.
-    $this->drupalPost("node/$node->nid/revisions/{$nodes[1]->vid}/revert", array(), t('Revert'));
+    $this->drupalPost("node/" . $node->id() . "/revisions/" . $nodes[1]->getRevisionId() . "/revert", array(), t('Revert'));
     $this->assertRaw(t('@type %title has been reverted back to the revision from %revision-date.',
       array(
         '@type' => 'Basic page',
-        '%title' => $nodes[1]->title,
-        '%revision-date' => format_date($nodes[1]->revision_timestamp)
+        '%title' => $nodes[1]->getTitle(),
+        '%revision-date' => format_date($nodes[1]->getRevisionCreationTime())
       )),
       'Revision reverted.');
     $reverted_node = node_load($node->id(), TRUE);
-    $this->assertTrue(($nodes[1]->body[Language::LANGCODE_NOT_SPECIFIED][0]['value'] == $reverted_node->body[Language::LANGCODE_NOT_SPECIFIED][0]['value']), 'Node reverted correctly.');
+    $this->assertTrue(($nodes[1]->body->value == $reverted_node->body->value), 'Node reverted correctly.');
 
     // Confirm that this is not the current version.
-    $node = node_revision_load($node->vid);
+    $node = node_revision_load($node->getRevisionId());
     $this->assertFalse($node->isDefaultRevision(), 'Third node revision is not the current one.');
 
     // Confirm revisions delete properly.
-    $this->drupalPost("node/$node->nid/revisions/{$nodes[1]->vid}/delete", array(), t('Delete'));
+    $this->drupalPost("node/" . $node->id() . "/revisions/" . $nodes[1]->getRevisionId() . "/delete", array(), t('Delete'));
     $this->assertRaw(t('Revision from %revision-date of @type %title has been deleted.',
       array(
-        '%revision-date' => format_date($nodes[1]->revision_timestamp),
+        '%revision-date' => format_date($nodes[1]->getRevisionCreationTime()),
         '@type' => 'Basic page',
-        '%title' => $nodes[1]->title,
+        '%title' => $nodes[1]->getTitle(),
       )),
       'Revision deleted.');
     $this->assertTrue(db_query('SELECT COUNT(vid) FROM {node_field_revision} WHERE nid = :nid and vid = :vid',
-      array(':nid' => $node->id(), ':vid' => $nodes[1]->vid))->fetchField() == 0,
+      array(':nid' => $node->id(), ':vid' => $nodes[1]->getRevisionId()))->fetchField() == 0,
       'Revision not found.');
 
     // Set the revision timestamp to an older date to make sure that the
     // confirmation message correctly displays the stored revision date.
     $old_revision_date = REQUEST_TIME - 86400;
     db_update('node_field_revision')
-      ->condition('vid', $nodes[2]->vid)
+      ->condition('vid', $nodes[2]->getRevisionId())
       ->fields(array(
         'revision_timestamp' => $old_revision_date,
       ))
       ->execute();
-    $this->drupalPost("node/$node->nid/revisions/{$nodes[2]->vid}/revert", array(), t('Revert'));
+    $this->drupalPost("node/" . $node->id() . "/revisions/" . $nodes[2]->getRevisionId() . "/revert", array(), t('Revert'));
     $this->assertRaw(t('@type %title has been reverted back to the revision from %revision-date.', array(
       '@type' => 'Basic page',
-      '%title' => $nodes[2]->title,
+      '%title' => $nodes[2]->getTitle(),
       '%revision-date' => format_date($old_revision_date),
     )));
   }
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeRevisionsTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeRevisionsTest.php
index 62ebcb1..2bb852d 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeRevisionsTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeRevisionsTest.php
@@ -59,7 +59,7 @@ function setUp() {
 
       // Create revision with a random title and body and update variables.
       $node->title = $this->randomName();
-      $node->body[$node->language()->id][0] = array(
+      $node->body = array(
         'value' => $this->randomName(32),
         'format' => filter_default_format(),
       );
@@ -85,11 +85,11 @@ function testRevisions() {
     $node = $nodes[3];
 
     // Confirm the correct revision text appears on "view revisions" page.
-    $this->drupalGet("node/$node->nid/revisions/$node->vid/view");
-    $this->assertText($node->body[Language::LANGCODE_NOT_SPECIFIED][0]['value'], 'Correct text displays for version.');
+    $this->drupalGet("node/" . $node->id() . "/revisions/" . $node->getRevisionId() . "/view");
+    $this->assertText($node->body->value, 'Correct text displays for version.');
 
     // Confirm the correct log message appears on "revisions overview" page.
-    $this->drupalGet("node/$node->nid/revisions");
+    $this->drupalGet("node/" . $node->id() . "/revisions");
     foreach ($logs as $log) {
       $this->assertText($log, 'Log message found.');
     }
@@ -98,34 +98,34 @@ function testRevisions() {
     $this->assertTrue($node->isDefaultRevision(), 'Third node revision is the default one.');
 
     // Confirm that revisions revert properly.
-    $this->drupalPost("node/$node->nid/revisions/{$nodes[1]->vid}/revert", array(), t('Revert'));
+    $this->drupalPost("node/" . $node->id() . "/revisions/" . $nodes[1]->getRevisionid() . "/revert", array(), t('Revert'));
     $this->assertRaw(t('@type %title has been reverted back to the revision from %revision-date.',
                         array('@type' => 'Basic page', '%title' => $nodes[1]->label(),
-                              '%revision-date' => format_date($nodes[1]->revision_timestamp))), 'Revision reverted.');
+                              '%revision-date' => format_date($nodes[1]->getRevisionCreationTime()))), 'Revision reverted.');
     $reverted_node = node_load($node->id(), TRUE);
-    $this->assertTrue(($nodes[1]->body[Language::LANGCODE_NOT_SPECIFIED][0]['value'] == $reverted_node->body[Language::LANGCODE_NOT_SPECIFIED][0]['value']), 'Node reverted correctly.');
+    $this->assertTrue(($nodes[1]->body->value == $reverted_node->body->value), 'Node reverted correctly.');
 
     // Confirm that this is not the default version.
-    $node = node_revision_load($node->vid);
+    $node = node_revision_load($node->getRevisionId());
     $this->assertFalse($node->isDefaultRevision(), 'Third node revision is not the default one.');
 
     // Confirm revisions delete properly.
-    $this->drupalPost("node/$node->nid/revisions/{$nodes[1]->vid}/delete", array(), t('Delete'));
+    $this->drupalPost("node/" . $node->id() . "/revisions/" . $nodes[1]->getRevisionId() . "/delete", array(), t('Delete'));
     $this->assertRaw(t('Revision from %revision-date of @type %title has been deleted.',
-                        array('%revision-date' => format_date($nodes[1]->revision_timestamp),
+                        array('%revision-date' => format_date($nodes[1]->getRevisionCreationTime()),
                               '@type' => 'Basic page', '%title' => $nodes[1]->label())), 'Revision deleted.');
-    $this->assertTrue(db_query('SELECT COUNT(vid) FROM {node_field_revision} WHERE nid = :nid and vid = :vid', array(':nid' => $node->id(), ':vid' => $nodes[1]->vid))->fetchField() == 0, 'Revision not found.');
+    $this->assertTrue(db_query('SELECT COUNT(vid) FROM {node_field_revision} WHERE nid = :nid and vid = :vid', array(':nid' => $node->id(), ':vid' => $nodes[1]->getRevisionId()))->fetchField() == 0, 'Revision not found.');
 
     // Set the revision timestamp to an older date to make sure that the
     // confirmation message correctly displays the stored revision date.
     $old_revision_date = REQUEST_TIME - 86400;
     db_update('node_field_revision')
-      ->condition('vid', $nodes[2]->vid)
+      ->condition('vid', $nodes[2]->getRevisionId())
       ->fields(array(
         'revision_timestamp' => $old_revision_date,
       ))
       ->execute();
-    $this->drupalPost("node/$node->nid/revisions/{$nodes[2]->vid}/revert", array(), t('Revert'));
+    $this->drupalPost("node/" . $node->id() . "/revisions/" . $nodes[2]->getRevisionId() . "/revert", array(), t('Revert'));
     $this->assertRaw(t('@type %title has been reverted back to the revision from %revision-date.', array(
       '@type' => 'Basic page',
       '%title' => $nodes[2]->label(),
@@ -136,7 +136,7 @@ function testRevisions() {
     // This will create a new revision that is not "front facing".
     $new_node_revision = clone $node;
     $new_body = $this->randomName();
-    $new_node_revision->body[Language::LANGCODE_NOT_SPECIFIED][0]['value'] = $new_body;
+    $new_node_revision->body->value = $new_body;
     // Save this as a non-default revision.
     $new_node_revision->setNewRevision();
     $new_node_revision->isDefaultRevision = FALSE;
@@ -146,7 +146,7 @@ function testRevisions() {
     $this->assertNoText($new_body, 'Revision body text is not present on default version of node.');
 
     // Verify that the new body text is present on the revision.
-    $this->drupalGet("node/$node->nid/revisions/" . $new_node_revision->vid . "/view");
+    $this->drupalGet("node/" . $node->id() . "/revisions/" . $new_node_revision->getRevisionId() . "/view");
     $this->assertText($new_body, 'Revision body text is present when loading specific revision.');
 
     // Verify that the non-default revision vid is greater than the default
@@ -157,7 +157,7 @@ function testRevisions() {
       ->execute()
       ->fetchCol();
     $default_revision_vid = $default_revision[0];
-    $this->assertTrue($new_node_revision->vid > $default_revision_vid, 'Revision vid is greater than default revision vid.');
+    $this->assertTrue($new_node_revision->getRevisionId() > $default_revision_vid, 'Revision vid is greater than default revision vid.');
   }
 
   /**
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeSaveTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeSaveTest.php
index c33aa05..a3f16f8 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeSaveTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeSaveTest.php
@@ -56,11 +56,11 @@ function testImport() {
       'type' => 'article',
       'nid' => $test_nid,
     );
-    $node = node_submit(entity_create('node', $node));
+    $node = entity_create('node', $node);
     $node->enforceIsNew();
 
     // Verify that node_submit did not overwrite the user ID.
-    $this->assertEqual($node->uid, $this->web_user->id(), 'Function node_submit() preserves user ID');
+    $this->assertEqual($node->getAuthorId(), $this->web_user->id(), 'Function node_submit() preserves user ID');
 
     $node->save();
     // Test the import.
@@ -84,24 +84,24 @@ function testTimestamps() {
 
     entity_create('node', $edit)->save();
     $node = $this->drupalGetNodeByTitle($edit['title']);
-    $this->assertEqual($node->created, REQUEST_TIME, 'Creating a node sets default "created" timestamp.');
-    $this->assertEqual($node->changed, REQUEST_TIME, 'Creating a node sets default "changed" timestamp.');
+    $this->assertEqual($node->getCreatedTime(), REQUEST_TIME, 'Creating a node sets default "created" timestamp.');
+    $this->assertEqual($node->getChangedTime(), REQUEST_TIME, 'Creating a node sets default "changed" timestamp.');
 
     // Store the timestamps.
-    $created = $node->created;
-    $changed = $node->changed;
+    $created = $node->getCreatedTime();
+    $changed = $node->getChangedTime();
 
     $node->save();
     $node = $this->drupalGetNodeByTitle($edit['title'], TRUE);
-    $this->assertEqual($node->created, $created, 'Updating a node preserves "created" timestamp.');
+    $this->assertEqual($node->getCreatedTime(), $created, 'Updating a node preserves "created" timestamp.');
 
     // Programmatically set the timestamps using hook_node_presave.
     $node->title = 'testing_node_presave';
 
     $node->save();
     $node = $this->drupalGetNodeByTitle('testing_node_presave', TRUE);
-    $this->assertEqual($node->created, 280299600, 'Saving a node uses "created" timestamp set in presave hook.');
-    $this->assertEqual($node->changed, 979534800, 'Saving a node uses "changed" timestamp set in presave hook.');
+    $this->assertEqual($node->getCreatedTime(), 280299600, 'Saving a node uses "created" timestamp set in presave hook.');
+    $this->assertEqual($node->getChangedTime(), 979534800, 'Saving a node uses "changed" timestamp set in presave hook.');
 
     // Programmatically set the timestamps on the node.
     $edit = array(
@@ -114,17 +114,17 @@ function testTimestamps() {
 
     entity_create('node', $edit)->save();
     $node = $this->drupalGetNodeByTitle($edit['title']);
-    $this->assertEqual($node->created, 280299600, 'Creating a node uses user-set "created" timestamp.');
-    $this->assertNotEqual($node->changed, 979534800, 'Creating a node does not use user-set "changed" timestamp.');
+    $this->assertEqual($node->getCreatedTime(), 280299600, 'Creating a node uses user-set "created" timestamp.');
+    $this->assertNotEqual($node->getChangedTime(), 979534800, 'Creating a node does not use user-set "changed" timestamp.');
 
     // Update the timestamps.
-    $node->created = 979534800;
+    $node->setCreatedTime(979534800);
     $node->changed = 280299600;
 
     $node->save();
     $node = $this->drupalGetNodeByTitle($edit['title'], TRUE);
-    $this->assertEqual($node->created, 979534800, 'Updating a node uses user-set "created" timestamp.');
-    $this->assertNotEqual($node->changed, 280299600, 'Updating a node does not use user-set "changed" timestamp.');
+    $this->assertEqual($node->getCreatedTime(), 979534800, 'Updating a node uses user-set "created" timestamp.');
+    $this->assertNotEqual($node->getChangedTime(), 280299600, 'Updating a node does not use user-set "changed" timestamp.');
   }
 
   /**
@@ -172,6 +172,6 @@ function testNodeSaveOnInsert() {
     // node_test_node_insert() tiggers a save on insert if the title equals
     // 'new'.
     $node = $this->drupalCreateNode(array('title' => 'new'));
-    $this->assertEqual($node->title, 'Node ' . $node->id(), 'Node saved on node insert.');
+    $this->assertEqual($node->getTitle(), 'Node ' . $node->id(), 'Node saved on node insert.');
   }
 }
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeTokenReplaceTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeTokenReplaceTest.php
index 6416a77..1e55f29 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeTokenReplaceTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeTokenReplaceTest.php
@@ -44,26 +44,26 @@ function testNodeTokenReplacement() {
 
     // Load node so that the body and summary fields are structured properly.
     $node = node_load($node->id());
-    $instance = field_info_instance('node', 'body', $node->type);
+    $instance = field_info_instance('node', 'body', $node->getType());
 
     // Generate and test sanitized tokens.
     $tests = array();
     $tests['[node:nid]'] = $node->id();
-    $tests['[node:vid]'] = $node->vid;
-    $tests['[node:tnid]'] = $node->tnid;
+    $tests['[node:vid]'] = $node->getRevisionId();
+    $tests['[node:tnid]'] = $node->tnid->value;
     $tests['[node:type]'] = 'article';
     $tests['[node:type-name]'] = 'Article';
-    $tests['[node:title]'] = check_plain($node->title);
-    $tests['[node:body]'] = text_sanitize($instance['settings']['text_processing'], $node->langcode, $node->body[$node->langcode][0], 'value');
-    $tests['[node:summary]'] = text_sanitize($instance['settings']['text_processing'], $node->langcode, $node->body[$node->langcode][0], 'summary');
-    $tests['[node:langcode]'] = check_plain($node->langcode);
+    $tests['[node:title]'] = check_plain($node->getTitle());
+    $tests['[node:body]'] = text_sanitize($instance['settings']['text_processing'], $node->language()->id, $node->body[0]->getValue(), 'value');
+    $tests['[node:summary]'] = text_sanitize($instance['settings']['text_processing'], $node->language()->id, $node->body[0]->getValue(), 'summary');
+    $tests['[node:langcode]'] = check_plain($node->language()->id);
     $tests['[node:url]'] = url('node/' . $node->id(), $url_options);
     $tests['[node:edit-url]'] = url('node/' . $node->id() . '/edit', $url_options);
     $tests['[node:author]'] = check_plain(user_format_name($account));
-    $tests['[node:author:uid]'] = $node->uid;
+    $tests['[node:author:uid]'] = $node->getAuthorId();
     $tests['[node:author:name]'] = check_plain(user_format_name($account));
-    $tests['[node:created:since]'] = format_interval(REQUEST_TIME - $node->created, 2, $language_interface->id);
-    $tests['[node:changed:since]'] = format_interval(REQUEST_TIME - $node->changed, 2, $language_interface->id);
+    $tests['[node:created:since]'] = format_interval(REQUEST_TIME - $node->getCreatedTime(), 2, $language_interface->id);
+    $tests['[node:changed:since]'] = format_interval(REQUEST_TIME - $node->getChangedTime(), 2, $language_interface->id);
 
     // Test to make sure that we generated something for each token.
     $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.');
@@ -74,10 +74,11 @@ function testNodeTokenReplacement() {
     }
 
     // Generate and test unsanitized tokens.
-    $tests['[node:title]'] = $node->title;
-    $tests['[node:body]'] = $node->body[$node->langcode][0]['value'];
-    $tests['[node:summary]'] = $node->body[$node->langcode][0]['summary'];
-    $tests['[node:langcode]'] = $node->langcode;
+    $tests['[node:title]'] = $node->getTitle();
+    $tests['[node:title]'] = $node->label();
+    $tests['[node:body]'] = $node->body->value;
+    $tests['[node:summary]'] = $node->body->summary;
+    $tests['[node:langcode]'] = $node->language()->id;
     $tests['[node:author:name]'] = user_format_name($account);
 
     foreach ($tests as $input => $expected) {
@@ -92,11 +93,11 @@ function testNodeTokenReplacement() {
     // Load node (without summary) so that the body and summary fields are
     // structured properly.
     $node = node_load($node->id());
-    $instance = field_info_instance('node', 'body', $node->type);
+    $instance = field_info_instance('node', 'body', $node->getType());
 
     // Generate and test sanitized token - use full body as expected value.
     $tests = array();
-    $tests['[node:summary]'] = text_sanitize($instance['settings']['text_processing'], $node->langcode, $node->body[$node->langcode][0], 'value');
+    $tests['[node:summary]'] = text_sanitize($instance['settings']['text_processing'], $node->language()->id, $node->body[0]->getValue(), 'value');
 
     // Test to make sure that we generated something for each token.
     $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated for node without a summary.');
@@ -107,7 +108,7 @@ function testNodeTokenReplacement() {
     }
 
     // Generate and test unsanitized tokens.
-    $tests['[node:summary]'] = $node->body[$node->langcode][0]['value'];
+    $tests['[node:summary]'] = $node->body->value;
 
     foreach ($tests as $input => $expected) {
       $output = $token_service->replace($input, array('node' => $node), array('language' => $language_interface, 'sanitize' => FALSE));
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php b/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php
index dac3575..6861c52 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php
@@ -69,7 +69,7 @@ protected function getNewEntityValues($langcode) {
    * Overrides \Drupal\content_translation\Tests\ContentTranslationUITest::getFormSubmitAction().
    */
   protected function getFormSubmitAction(EntityInterface $entity) {
-    if ($entity->status) {
+    if ($entity->isPublished()) {
       return t('Save and unpublish');
     }
     return t('Save and keep unpublished');
diff --git a/core/modules/node/lib/Drupal/node/Tests/PageEditTest.php b/core/modules/node/lib/Drupal/node/Tests/PageEditTest.php
index b9243b2..43704b0 100644
--- a/core/modules/node/lib/Drupal/node/Tests/PageEditTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/PageEditTest.php
@@ -52,7 +52,7 @@ function testPageEdit() {
 
     // Check that "edit" link points to correct page.
     $this->clickLink(t('Edit'));
-    $edit_url = url("node/$node->nid/edit", array('absolute' => TRUE));
+    $edit_url = url("node/" . $node->id() . "/edit", array('absolute' => TRUE));
     $actual_url = $this->getURL();
     $this->assertEqual($edit_url, $actual_url, 'On edit page.');
 
@@ -78,7 +78,7 @@ function testPageEdit() {
     $second_web_user = $this->drupalCreateUser(array('administer nodes', 'edit any page content'));
     $this->drupalLogin($second_web_user);
     // Edit the same node, creating a new revision.
-    $this->drupalGet("node/$node->nid/edit");
+    $this->drupalGet("node/" . $node->id() . "/edit");
     $edit = array();
     $edit['title'] = $this->randomName(8);
     $edit[$body_key] = $this->randomName(16);
@@ -87,15 +87,15 @@ function testPageEdit() {
 
     // Ensure that the node revision has been created.
     $revised_node = $this->drupalGetNodeByTitle($edit['title'], TRUE);
-    $this->assertNotIdentical($node->vid, $revised_node->vid, 'A new revision has been created.');
+    $this->assertNotIdentical($node->getRevisionId(), $revised_node->getRevisionId(), 'A new revision has been created.');
     // Ensure that the node author is preserved when it was not changed in the
     // edit form.
-    $this->assertIdentical($node->uid, $revised_node->uid, 'The node author has been preserved.');
+    $this->assertIdentical($node->getAuthorId(), $revised_node->getAuthorId(), 'The node author has been preserved.');
     // Ensure that the revision authors are different since the revisions were
     // made by different users.
-    $first_node_version = node_revision_load($node->vid);
-    $second_node_version = node_revision_load($revised_node->vid);
-    $this->assertNotIdentical($first_node_version->revision_uid, $second_node_version->revision_uid, 'Each revision has a distinct user.');
+    $first_node_version = node_revision_load($node->getRevisionId());
+    $second_node_version = node_revision_load($revised_node->getRevisionId());
+    $this->assertNotIdentical($first_node_version->getRevisionAuthor()->id(), $second_node_version->getRevisionAuthor()->id(), 'Each revision has a distinct user.');
   }
 
   /**
@@ -114,7 +114,7 @@ function testPageAuthoredBy() {
 
     // Check that the node was authored by the currently logged in user.
     $node = $this->drupalGetNodeByTitle($edit['title']);
-    $this->assertIdentical($node->uid, $this->admin_user->id(), 'Node authored by admin user.');
+    $this->assertIdentical($node->getAuthorId(), $this->admin_user->id(), 'Node authored by admin user.');
 
     // Try to change the 'authored by' field to an invalid user name.
     $edit = array(
@@ -128,14 +128,14 @@ function testPageAuthoredBy() {
     $edit['name'] = '';
     $this->drupalPost('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
     $node = node_load($node->id(), TRUE);
-    $this->assertIdentical($node->uid, '0', 'Node authored by anonymous user.');
+    $this->assertIdentical($node->getAuthorId(), '0', 'Node authored by anonymous user.');
 
     // Change the authored by field to another user's name (that is not
     // logged in).
     $edit['name'] = $this->web_user->getUsername();
     $this->drupalPost('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
-    $node = node_load($node->nid, TRUE);
-    $this->assertIdentical($node->uid, $this->web_user->id(), 'Node authored by normal user.');
+    $node = node_load($node->id(), TRUE);
+    $this->assertIdentical($node->getAuthorId(), $this->web_user->id(), 'Node authored by normal user.');
 
     // Check that normal users cannot change the authored by information.
     $this->drupalLogin($this->web_user);
diff --git a/core/modules/node/lib/Drupal/node/Tests/PageViewTest.php b/core/modules/node/lib/Drupal/node/Tests/PageViewTest.php
index ececc4c..7186d45 100644
--- a/core/modules/node/lib/Drupal/node/Tests/PageViewTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/PageViewTest.php
@@ -28,7 +28,7 @@ function testPageView() {
     $this->assertTrue(node_load($node->id()), 'Node created.');
 
     // Try to edit with anonymous user.
-    $this->drupalGet("node/$node->nid/edit");
+    $this->drupalGet("node/" . $node->id() . "/edit");
     $this->assertResponse(403);
 
     // Create a user without permission to edit node.
@@ -36,7 +36,7 @@ function testPageView() {
     $this->drupalLogin($web_user);
 
     // Attempt to access edit page.
-    $this->drupalGet("node/$node->nid/edit");
+    $this->drupalGet("node/" . $node->id() . "/edit");
     $this->assertResponse(403);
 
     // Create user with permission to edit node.
@@ -44,7 +44,7 @@ function testPageView() {
     $this->drupalLogin($web_user);
 
     // Attempt to access edit page.
-    $this->drupalGet("node/$node->nid/edit");
+    $this->drupalGet("node/" . $node->id() . "/edit");
     $this->assertResponse(200);
   }
 }
diff --git a/core/modules/node/lib/Drupal/node/Tests/SummaryLengthTest.php b/core/modules/node/lib/Drupal/node/Tests/SummaryLengthTest.php
index 21b1fe6..2b0c493 100644
--- a/core/modules/node/lib/Drupal/node/Tests/SummaryLengthTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/SummaryLengthTest.php
@@ -47,7 +47,7 @@ function testSummaryLength() {
     $this->assertRaw($expected);
 
     // Change the teaser length for "Basic page" content type.
-    $display = entity_get_display('node', $node->type, 'teaser');
+    $display = entity_get_display('node', $node->getType(), 'teaser');
     $display_options = $display->getComponent('body');
     $display_options['settings']['trim_length'] = 200;
     $display->setComponent('body', $display_options)
diff --git a/core/modules/node/lib/Drupal/node/Tests/Views/RowPluginTest.php b/core/modules/node/lib/Drupal/node/Tests/Views/RowPluginTest.php
index 4924f56..4ccce6d 100644
--- a/core/modules/node/lib/Drupal/node/Tests/Views/RowPluginTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/Views/RowPluginTest.php
@@ -93,7 +93,7 @@ public function drupalCreateComment(array $settings = array()) {
     $node = node_load($settings['nid']);
     $settings += array(
       'subject' => $this->randomName(),
-      'node_type' => "comment_node_{$node->bundle()}",
+      'node_type' => 'comment_node_' . $node->bundle(),
       'comment_body' => $this->randomName(40),
     );
 
@@ -116,11 +116,8 @@ public function testRowPlugin() {
     $output = $view->preview();
     $output = drupal_render($output);
     foreach ($this->nodes as $node) {
-      $body = $node->body;
-      $teaser = $body[Language::LANGCODE_NOT_SPECIFIED][0]['summary'];
-      $full = $body[Language::LANGCODE_NOT_SPECIFIED][0]['value'];
-      $this->assertFalse(strpos($output, $teaser) !== FALSE, 'Make sure the teaser appears in the output of the view.');
-      $this->assertTrue(strpos($output, $full) !== FALSE, 'Make sure the full text appears in the output of the view.');
+      $this->assertFalse(strpos($output, $node->body->summary) !== FALSE, 'Make sure the teaser appears in the output of the view.');
+      $this->assertTrue(strpos($output, $node->body->value) !== FALSE, 'Make sure the full text appears in the output of the view.');
     }
 
     // Test with teasers.
@@ -128,11 +125,8 @@ public function testRowPlugin() {
     $output = $view->preview();
     $output = drupal_render($output);
     foreach ($this->nodes as $node) {
-      $body = $node->body;
-      $teaser = $body[Language::LANGCODE_NOT_SPECIFIED][0]['summary'];
-      $full = $body[Language::LANGCODE_NOT_SPECIFIED][0]['value'];
-      $this->assertTrue(strpos($output, $teaser) !== FALSE, 'Make sure the teaser appears in the output of the view.');
-      $this->assertFalse(strpos($output, $full) !== FALSE, 'Make sure the full text does not appears in the output of the view if teaser is set as viewmode.');
+      $this->assertTrue(strpos($output, $node->body->summary) !== FALSE, 'Make sure the teaser appears in the output of the view.');
+      $this->assertFalse(strpos($output, $node->body->value) !== FALSE, 'Make sure the full text does not appears in the output of the view if teaser is set as viewmode.');
     }
 
     // Test with links disabled.
diff --git a/core/modules/node/node.admin.inc b/core/modules/node/node.admin.inc
index ded7789..03387f8 100644
--- a/core/modules/node/node.admin.inc
+++ b/core/modules/node/node.admin.inc
@@ -236,10 +236,10 @@ function node_admin_nodes() {
     '#empty' => t('No content available.'),
   );
   foreach ($nodes as $node) {
-    $l_options = $node->langcode != Language::LANGCODE_NOT_SPECIFIED && isset($languages[$node->langcode]) ? array('language' => $languages[$node->langcode]) : array();
+    $l_options = $node->language()->id != Language::LANGCODE_NOT_SPECIFIED && isset($languages[$node->language()->id]) ? array('language' => $languages[$node->language()->id]) : array();
     $mark = array(
       '#theme' => 'mark',
-      '#status' => node_mark($node->id(), $node->changed),
+      '#status' => node_mark($node->id(), $node->getChangedTime()),
     );
     $form['nodes'][$node->id()]['title'] = array(
       '#type' => 'link',
@@ -253,17 +253,17 @@ function node_admin_nodes() {
     );
     $form['nodes'][$node->id()]['author'] = array(
       '#theme' => 'username',
-      '#account' => user_load($node->uid),
+      '#account' => $node->getAuthor(),
     );
     $form['nodes'][$node->id()]['status'] = array(
-      '#markup' => $node->status ? t('published') : t('not published'),
+      '#markup' => $node->isPublished() ? t('published') : t('not published'),
     );
     $form['nodes'][$node->id()]['changed'] = array(
-      '#markup' => format_date($node->changed, 'short'),
+      '#markup' => format_date($node->getChangedTime(), 'short'),
     );
     if ($multilingual) {
       $form['nodes'][$node->id()]['language_name'] = array(
-        '#markup' => language_name($node->langcode),
+        '#markup' => $node->language()->name,
       );
     }
 
diff --git a/core/modules/node/node.api.php b/core/modules/node/node.api.php
index 2166391..064e83e 100644
--- a/core/modules/node/node.api.php
+++ b/core/modules/node/node.api.php
@@ -214,7 +214,7 @@ function hook_node_grants($account, $op) {
  * - 'gid': A 'grant ID' from hook_node_grants().
  * - 'grant_view': If set to 1 a user that has been identified as a member
  *   of this gid within this realm can view this node. This should usually be
- *   set to $node->status. Failure to do so may expose unpublished content
+ *   set to $node->isPublished(). Failure to do so may expose unpublished content
  *   to some users.
  * - 'grant_update': If set to 1 a user that has been identified as a member
  *   of this gid within this realm can edit this node.
@@ -257,15 +257,15 @@ function hook_node_grants($account, $op) {
  * @see hook_node_access_records_alter()
  * @ingroup node_access
  */
-function hook_node_access_records(\Drupal\Core\Entity\EntityInterface $node) {
+function hook_node_access_records(\Drupal\node\NodeInterface $node) {
   // We only care about the node if it has been marked private. If not, it is
   // treated just like any other node and we completely ignore it.
-  if ($node->private) {
+  if ($node->private->value) {
     $grants = array();
     // Only published Catalan translations of private nodes should be viewable
-    // to all users. If we fail to check $node->status, all users would be able
+    // to all users. If we fail to check $node->isPublished(), all users would be able
     // to view an unpublished node.
-    if ($node->status) {
+    if ($node->isPublished()) {
       $grants[] = array(
         'realm' => 'example',
         'gid' => 1,
@@ -281,7 +281,7 @@ function hook_node_access_records(\Drupal\Core\Entity\EntityInterface $node) {
     // have status unpublished.
     $grants[] = array(
       'realm' => 'example_author',
-      'gid' => $node->uid,
+      'gid' => $node->getAuthorId(),
       'grant_view' => 1,
       'grant_update' => 1,
       'grant_delete' => 1,
@@ -438,7 +438,7 @@ function hook_node_delete(\Drupal\Core\Entity\EntityInterface $node) {
  */
 function hook_node_revision_delete(\Drupal\Core\Entity\EntityInterface $node) {
   db_delete('mytable')
-    ->condition('vid', $node->vid)
+    ->condition('vid', $node->getRevisionId())
     ->execute();
 }
 
@@ -567,8 +567,8 @@ function hook_node_load($nodes, $types) {
  *
  * @ingroup node_access
  */
-function hook_node_access($node, $op, $account, $langcode) {
-  $type = is_string($node) ? $node : $node->type;
+function hook_node_access(\Drupal\node\NodeInterface $node, $op, $account, $langcode) {
+  $type = is_string($node) ? $node : $node->getType();
 
   $configured_types = node_permissions_get_configured_types();
   if (isset($configured_types[$type])) {
@@ -577,13 +577,13 @@ function hook_node_access($node, $op, $account, $langcode) {
     }
 
     if ($op == 'update') {
-      if (user_access('edit any ' . $type . ' content', $account) || (user_access('edit own ' . $type . ' content', $account) && ($account->id() == $node->uid))) {
+      if (user_access('edit any ' . $type . ' content', $account) || (user_access('edit own ' . $type . ' content', $account) && ($account->id() == $node->getAuthorId()))) {
         return NODE_ACCESS_ALLOW;
       }
     }
 
     if ($op == 'delete') {
-      if (user_access('delete any ' . $type . ' content', $account) || (user_access('delete own ' . $type . ' content', $account) && ($account->id() == $node->uid))) {
+      if (user_access('delete any ' . $type . ' content', $account) || (user_access('delete own ' . $type . ' content', $account) && ($account->id() == $node->getAuthorId()))) {
         return NODE_ACCESS_ALLOW;
       }
     }
@@ -611,8 +611,8 @@ function hook_node_access($node, $op, $account, $langcode) {
  * @ingroup node_api_hooks
  */
 function hook_node_prepare_form(\Drupal\node\NodeInterface $node, $form_display, $operation, array &$form_state) {
-  if (!isset($node->comment)) {
-    $node->comment = variable_get("comment_$node->type", COMMENT_NODE_OPEN);
+  if (!isset($node->comment->value)) {
+    $node->comment = variable_get('comment_' . $node->getType(), COMMENT_NODE_OPEN);
   }
 }
 
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 200c6f6..bc7ceca 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -520,12 +520,7 @@ function node_type_update_nodes($old_id, $new_id) {
  * @see Drupal\Core\Entity\Query\EntityQueryInterface
  */
 function node_load_multiple(array $nids = NULL, $reset = FALSE) {
-  $entities = entity_load_multiple('node', $nids, $reset);
-  // Return BC-entities.
-  foreach ($entities as $id => $entity) {
-    $entities[$id] = $entity->getBCEntity();
-  }
-  return $entities;
+  return entity_load_multiple('node', $nids, $reset);
 }
 
 /**
@@ -537,63 +532,27 @@ function node_load_multiple(array $nids = NULL, $reset = FALSE) {
  *   (optional) Whether to reset the node_load_multiple() cache. Defaults to
  *   FALSE.
  *
- * @return \Drupal\node\Node|null
- *   A fully-populated node entity or NULL if the node is not found.
+ * @return \Drupal\node\NodeInterface|null
+ *   A fully-populated node entity, or NULL if the node is not found.
  */
 function node_load($nid = NULL, $reset = FALSE) {
-  $entity = entity_load('node', $nid, $reset);
-  return $entity ? $entity->getBCEntity() : NULL;
+  return entity_load('node', $nid, $reset);
 }
 
 /**
  * Loads a node revision from the database.
  *
- * @param int $nid
+ * @param int $vid
  *   The node revision id.
  *
- * @return \Drupal\node\Node|null
- *   A fully-populated node entity or NULL if the node is not found.
+ * @return \Drupal\node\NodeInterface|null
+ *   A fully-populated node entity, or NULL if the node is not found.
  */
 function node_revision_load($vid = NULL) {
   return entity_revision_load('node', $vid);
 }
 
 /**
- * Prepares a node for saving by populating the author and creation date.
- *
- * @param \Drupal\Core\Entity\EntityInterface $node
- *   A node object.
- *
- * @return Drupal\node\Node
- *   An updated node object.
- */
-function node_submit(EntityInterface $node) {
-  global $user;
-
-  // A user might assign the node author by entering a user name in the node
-  // form, which we then need to translate to a user ID.
-  if (isset($node->name)) {
-    if ($account = user_load_by_name($node->name)) {
-      $node->setAuthorId($account->id());
-    }
-    else {
-      $node->setAuthorId(0);
-    }
-  }
-
-  // If a new revision is created, save the current user as revision author.
-  if ($node->isNewRevision()) {
-    $node->setRevisionAuthorId($user->id());
-    $node->setRevisionCreationTime(REQUEST_TIME);
-  }
-
-  $node->setCreatedTime(!empty($node->date) && $node->date instanceOf DrupalDateTime ? $node->date->getTimestamp() : REQUEST_TIME);
-  $node->validated = TRUE;
-
-  return $node;
-}
-
-/**
  * Deletes a node revision.
  *
  * @param $revision_id
@@ -693,7 +652,7 @@ function template_preprocess_node(&$variables) {
   //   http://drupal.org/node/1941286.
   $username = array(
     '#theme' => 'username',
-    '#account' => user_load($node->uid),
+    '#account' => $node->getAuthor(),
     '#link_options' => array('attributes' => array('rel' => 'author')),
   );
   $variables['name'] = drupal_render($username);
@@ -951,7 +910,7 @@ function node_search_execute($keys = NULL, $conditions = NULL) {
     $uri = $node->uri();
     $username = array(
       '#theme' => 'username',
-      '#account' => user_load($node->uid),
+      '#account' => $node->getAuthor(),
     );
     $results[] = array(
       'link' => url($uri['path'], array_merge($uri['options'], array('absolute' => TRUE, 'language' => $language))),
diff --git a/core/modules/node/node.pages.inc b/core/modules/node/node.pages.inc
index 48ad45f..d80898e 100644
--- a/core/modules/node/node.pages.inc
+++ b/core/modules/node/node.pages.inc
@@ -11,6 +11,7 @@
 
 use Drupal\Core\Entity\EntityInterface;
 use Symfony\Component\HttpFoundation\RedirectResponse;
+use Drupal\node\NodeInterface;
 
 /**
  * Page callback: Displays add content links for available content types.
@@ -90,7 +91,7 @@ function node_add($node_type) {
     'name' => $user->getUsername(),
     'type' => $type,
     'langcode' => $langcode ? $langcode : language_default()->id,
-  ))->getBCEntity();
+  ));
   drupal_set_title(t('Create @name', array('@name' => $node_type->name)), PASS_THROUGH);
   return Drupal::entityManager()->getForm($node);
 }
@@ -106,23 +107,8 @@ function node_add($node_type) {
  *
  * @see node_form_build_preview()
  */
-function node_preview(EntityInterface $node) {
+function node_preview(NodeInterface $node) {
   if (node_access('create', $node) || node_access('update', $node)) {
-    // Load the user's name when needed.
-    if (isset($node->name)) {
-      // The use of isset() is mandatory in the context of user IDs, because
-      // user ID 0 denotes the anonymous user.
-      if ($user = user_load_by_name($node->name)) {
-        $node->uid = $user->id();
-      }
-      else {
-        $node->uid = 0; // anonymous user
-      }
-    }
-    elseif ($node->uid) {
-      $user = user_load($node->uid);
-      $node->name = $user->getUsername();
-    }
 
     $node->changed = REQUEST_TIME;
 
@@ -198,7 +184,7 @@ function node_revision_overview($node) {
   $revisions = node_revision_list($node);
 
   $rows = array();
-  $type = $node->type;
+  $type = $node->getType();
 
   $revert_permission = FALSE;
   if ((user_access("revert $type revisions") || user_access('revert all revisions') || user_access('administer nodes')) && node_access('update', $node)) {
@@ -225,18 +211,18 @@ function node_revision_overview($node) {
         '#theme' => 'username',
         '#account' => user_load($revision->uid),
       );
-      $row[] = t('!date by !username', array('!date' => l(format_date($revision->revision_timestamp, 'short'), "node/$node->nid/revisions/$revision->vid/view"), '!username' => drupal_render($username)))
+      $row[] = t('!date by !username', array('!date' => l(format_date($revision->revision_timestamp, 'short'), "node/" . $node->id() . "/revisions/" . $revision->vid . "/view"), '!username' => drupal_render($username)))
                . (($revision->log != '') ? '<p class="revision-log">' . filter_xss($revision->log) . '</p>' : '');
       if ($revert_permission) {
         $links['revert'] = array(
           'title' => t('Revert'),
-          'href' => "node/$node->nid/revisions/$revision->vid/revert",
+          'href' => "node/" . $node->id() . "/revisions/" . $revision->vid . "/revert",
         );
       }
       if ($delete_permission) {
         $links['delete'] = array(
           'title' => t('Delete'),
-          'href' => "node/$node->nid/revisions/$revision->vid/delete",
+          'href' => "node/" . $node->id() . "/revisions/" . $revision->vid . "/delete",
         );
       }
       $row[] = array(
diff --git a/core/modules/node/node.tokens.inc b/core/modules/node/node.tokens.inc
index 3575621..9240497 100644
--- a/core/modules/node/node.tokens.inc
+++ b/core/modules/node/node.tokens.inc
@@ -115,15 +115,15 @@ function node_tokens($type, $tokens, array $data = array(), array $options = arr
           break;
 
         case 'vid':
-          $replacements[$original] = $node->vid;
+          $replacements[$original] = $node->getRevisionId();
           break;
 
         case 'tnid':
-          $replacements[$original] = $node->tnid;
+          $replacements[$original] = $node->tnid->value;
           break;
 
         case 'type':
-          $replacements[$original] = $sanitize ? check_plain($node->type) : $node->type;
+          $replacements[$original] = $sanitize ? check_plain($node->getType()) : $node->getType();
           break;
 
         case 'type-name':
@@ -132,14 +132,14 @@ function node_tokens($type, $tokens, array $data = array(), array $options = arr
           break;
 
         case 'title':
-          $replacements[$original] = $sanitize ? check_plain($node->title) : $node->title;
+          $replacements[$original] = $sanitize ? check_plain($node->getTitle()) : $node->getTitle();
           break;
 
         case 'body':
         case 'summary':
           if (($items = $node->getTranslation($langcode)->get('body')) && !$items->isEmpty()) {
             $item = $items[0];
-            $instance = field_info_instance('node', 'body', $node->type);
+            $instance = field_info_instance('node', 'body', $node->getType());
             $field_langcode = field_language($node, 'body', $langcode);
 
             // If the summary was requested and is not empty, use it.
@@ -155,7 +155,7 @@ function node_tokens($type, $tokens, array $data = array(), array $options = arr
 
                 // Get the 'trim_length' size used for the 'teaser' mode, if
                 // present, or use the default trim_length size.
-                $display_options = entity_get_display('node', $node->type, 'teaser')->getComponent('body');
+                $display_options = entity_get_display('node', $node->getType(), 'teaser')->getComponent('body');
                 if (isset($display_options['settings']['trim_length'])) {
                   $length = $display_options['settings']['trim_length'];
                 }
@@ -172,7 +172,7 @@ function node_tokens($type, $tokens, array $data = array(), array $options = arr
           break;
 
         case 'langcode':
-          $replacements[$original] = $sanitize ? check_plain($node->langcode) : $node->langcode;
+          $replacements[$original] = $sanitize ? check_plain($node->language()->id) : $node->language()->id;
           break;
 
         case 'url':
@@ -185,32 +185,30 @@ function node_tokens($type, $tokens, array $data = array(), array $options = arr
 
         // Default values for the chained tokens handled below.
         case 'author':
-          $account = user_load($node->uid);
-          $name = user_format_name($account);
-          $replacements[$original] = $sanitize ? check_plain($name) : $name;
+          $account = $node->getAuthor() ? $node->getAuthor() : user_load(0);
+          $replacements[$original] = $sanitize ? check_plain($account->label()) : $account->label();
           break;
 
         case 'created':
-          $replacements[$original] = format_date($node->created, 'medium', '', NULL, $langcode);
+          $replacements[$original] = format_date($node->getCreatedTime(), 'medium', '', NULL, $langcode);
           break;
 
         case 'changed':
-          $replacements[$original] = format_date($node->changed, 'medium', '', NULL, $langcode);
+          $replacements[$original] = format_date($node->getChangedTime(), 'medium', '', NULL, $langcode);
           break;
       }
     }
 
     if ($author_tokens = $token_service->findWithPrefix($tokens, 'author')) {
-      $author = user_load($node->uid);
-      $replacements += $token_service->generate('user', $author_tokens, array('user' => $author), $options);
+      $replacements += $token_service->generate('user', $author_tokens, array('user' => $node->getAuthor()), $options);
     }
 
     if ($created_tokens = $token_service->findWithPrefix($tokens, 'created')) {
-      $replacements += $token_service->generate('date', $created_tokens, array('date' => $node->created), $options);
+      $replacements += $token_service->generate('date', $created_tokens, array('date' => $node->getCreatedTime()), $options);
     }
 
     if ($changed_tokens = $token_service->findWithPrefix($tokens, 'changed')) {
-      $replacements += $token_service->generate('date', $changed_tokens, array('date' => $node->changed), $options);
+      $replacements += $token_service->generate('date', $changed_tokens, array('date' => $node->getChangedTime()), $options);
     }
   }
 
diff --git a/core/modules/node/node.views.inc b/core/modules/node/node.views.inc
index b2d00a6..deacf4d 100644
--- a/core/modules/node/node.views.inc
+++ b/core/modules/node/node.views.inc
@@ -635,7 +635,7 @@ function node_row_node_view_preprocess_node(&$variables) {
     unset($variables['content']['links']);
   }
 
-  if (!empty($options['comments']) && user_access('access comments') && $node->comment) {
+  if (!empty($options['comments']) && user_access('access comments') && $node->comment->value) {
     $variables['content']['comments'] = comment_node_page_additions($node);
   }
 }
diff --git a/core/modules/node/templates/node.html.twig b/core/modules/node/templates/node.html.twig
index ad12811..daf308a 100644
--- a/core/modules/node/templates/node.html.twig
+++ b/core/modules/node/templates/node.html.twig
@@ -5,15 +5,16 @@
  *
  * Available variables:
  * - node: Full node entity.
- *   - type: The type of the node, for example, "page" or "article".
- *   - uid: The user ID of the node author.
- *   - created: Formatted creation date. Preprocess functions can reformat it by
+ *   - id: The node ID
+ *   - bundle: The type of the node, for example, "page" or "article".
+ *   - authorid: The user ID of the node author.
+ *   - createdtime: Formatted creation date. Preprocess functions can reformat it by
  *     calling format_date() with the desired parameters on
- *     $variables['node']->created.
- *   - promote: Whether the node is promoted to the front page.
+ *     $variables['node']->getCreatedTime().
+ *   - promoted: Whether the node is promoted to the front page.
  *   - sticky: Whether the node is 'sticky'. Sticky nodes are ordered above
  *     other non-sticky nodes in teaser listings
- *   - status: Whether the node is published.
+ *   - published: Whether the node is published.
  *   - comment: A value representing the comment status of the current node. May
  *     be one of the following:
  *     - 0: The comment form and any existing comments are hidden.
@@ -81,7 +82,7 @@
  * @ingroup themeable
  */
 #}
-<article id="node-{{ node.nid }}" class="{{ attributes.class }} clearfix"{{ attributes }}>
+<article id="node-{{ node.id }}" class="{{ attributes.class }} clearfix"{{ attributes }}>
 
   {{ title_prefix }}
   {% if not page %}
diff --git a/core/modules/node/tests/modules/node_access_test/node_access_test.module b/core/modules/node/tests/modules/node_access_test/node_access_test.module
index d4bfc29..abc18c6 100644
--- a/core/modules/node/tests/modules/node_access_test/node_access_test.module
+++ b/core/modules/node/tests/modules/node_access_test/node_access_test.module
@@ -10,6 +10,7 @@
  */
 
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\node\NodeInterface;
 
 /**
  * Implements hook_node_grants().
@@ -32,10 +33,10 @@ function node_access_test_node_grants($account, $op) {
 /**
  * Implements hook_node_access_records().
  */
-function node_access_test_node_access_records(EntityInterface $node) {
+function node_access_test_node_access_records(NodeInterface $node) {
   $grants = array();
   // For NodeAccessBaseTableTestCase, only set records for private nodes.
-  if (!Drupal::state()->get('node_access_test.private') || $node->private) {
+  if (!Drupal::state()->get('node_access_test.private') || $node->private->value) {
     $grants[] = array(
       'realm' => 'node_access_test',
       'gid' => 8888,
@@ -56,7 +57,7 @@ function node_access_test_node_access_records(EntityInterface $node) {
     // means there are many many groups of just 1 user.
     $grants[] = array(
       'realm' => 'node_access_test_author',
-      'gid' => $node->uid,
+      'gid' => $node->getAuthorId(),
       'grant_view' => 1,
       'grant_update' => 1,
       'grant_delete' => 1,
@@ -77,6 +78,21 @@ function node_access_test_permission() {
 }
 
 /**
+ * Implements hook_entity_field_info().
+ */
+function node_access_test_entity_field_info($entity_type) {
+  if ($entity_type === 'node') {
+    $info['definitions']['private'] = array(
+      'type' => 'boolean_field',
+      'label' => t('Private'),
+      'computed' => TRUE,
+      'list' => TRUE,
+    );
+    return $info;
+  }
+}
+
+/**
  * Implements hook_form_BASE_FORM_ID_alter().
  */
 function node_access_test_form_node_form_alter(&$form, $form_state) {
@@ -87,7 +103,7 @@ function node_access_test_form_node_form_alter(&$form, $form_state) {
       '#type' => 'checkbox',
       '#title' => t('Private'),
       '#description' => t('Check here if this content should be set private and only shown to privileged users.'),
-      '#default_value' => isset($node->private) ? $node->private : FALSE,
+      '#default_value' => $node->private->value,
     );
   }
 }
@@ -128,12 +144,10 @@ function node_access_test_node_update(EntityInterface $node) {
  * Helper for node insert/update.
  */
 function _node_access_test_node_write(EntityInterface $node) {
-  if (isset($node->private)) {
-    db_merge('node_access_test')
-      ->key(array('nid' => $node->id()))
-      ->fields(array('private' => (int) $node->private))
-      ->execute();
-  }
+  db_merge('node_access_test')
+    ->key(array('nid' => $node->id()))
+    ->fields(array('private' => (int) $node->private->value))
+    ->execute();
 }
 
 /**
diff --git a/core/modules/node/tests/modules/node_access_test_language/node_access_test_language.module b/core/modules/node/tests/modules/node_access_test_language/node_access_test_language.module
index 1baa48e..fb217f2 100644
--- a/core/modules/node/tests/modules/node_access_test_language/node_access_test_language.module
+++ b/core/modules/node/tests/modules/node_access_test_language/node_access_test_language.module
@@ -29,10 +29,11 @@ function node_access_test_language_node_access_records(EntityInterface $node) {
   // Create grants for each translation of the node.
   foreach ($node->getTranslationLanguages() as $langcode => $language) {
     // If the translation is not marked as private, grant access.
+    $translation = $node->getTranslation($langcode);
     $grants[] = array(
       'realm' => 'node_access_language_test',
       'gid' => 7888,
-      'grant_view' => empty($node->field_private[$langcode][0]['value']) ? 1 : 0,
+      'grant_view' => empty($translation->field_private->value) ? 1 : 0,
       'grant_update' => 0,
       'grant_delete' => 0,
       'priority' => 0,
diff --git a/core/modules/node/tests/modules/node_test/node_test.module b/core/modules/node/tests/modules/node_test/node_test.module
index a11a616..4c06364 100644
--- a/core/modules/node/tests/modules/node_test/node_test.module
+++ b/core/modules/node/tests/modules/node_test/node_test.module
@@ -10,6 +10,7 @@
 
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\entity\Plugin\Core\Entity\EntityDisplay;
+use Drupal\node\NodeInterface;
 
 /**
  * Implements hook_node_load().
@@ -77,7 +78,7 @@ function node_test_node_access_records(EntityInterface $node) {
     return;
   }
   $grants = array();
-  if ($node->type == 'article') {
+  if ($node->getType() == 'article') {
     // Create grant in arbitrary article_realm for article nodes.
     $grants[] = array(
       'realm' => 'test_article_realm',
@@ -88,7 +89,7 @@ function node_test_node_access_records(EntityInterface $node) {
       'priority' => 0,
     );
   }
-  elseif ($node->type == 'page') {
+  elseif ($node->getType() == 'page') {
     // Create grant in arbitrary page_realm for page nodes.
     $grants[] = array(
       'realm' => 'test_page_realm',
@@ -105,11 +106,11 @@ function node_test_node_access_records(EntityInterface $node) {
 /**
  * Implements hook_node_access_records_alter().
  */
-function node_test_node_access_records_alter(&$grants, EntityInterface $node) {
+function node_test_node_access_records_alter(&$grants, NodeInterface $node) {
   if (!empty($grants)) {
     foreach ($grants as $key => $grant) {
       // Alter grant from test_page_realm to test_alter_realm and modify the gid.
-      if ($grant['realm'] == 'test_page_realm' && $node->promote) {
+      if ($grant['realm'] == 'test_page_realm' && $node->isPromoted()) {
         $grants[$key]['realm'] = 'test_alter_realm';
         $grants[$key]['gid'] = 2;
       }
@@ -129,16 +130,16 @@ function node_test_node_grants_alter(&$grants, $account, $op) {
  * Implements hook_node_presave().
  */
 function node_test_node_presave(EntityInterface $node) {
-  if ($node->title == 'testing_node_presave') {
+  if ($node->getTitle() == 'testing_node_presave') {
     // Sun, 19 Nov 1978 05:00:00 GMT
-    $node->created = 280299600;
+    $node->setCreatedTime(280299600);
     // Drupal 1.0 release.
     $node->changed = 979534800;
   }
   // Determine changes.
-  if (!empty($node->original) && $node->original->title == 'test_changes') {
-    if ($node->original->title != $node->title) {
-      $node->title .= '_presave';
+  if (!empty($node->original) && $node->original->getTitle() == 'test_changes') {
+    if ($node->original->getTitle() != $node->getTitle()) {
+      $node->title->value .= '_presave';
     }
   }
 }
@@ -148,9 +149,9 @@ function node_test_node_presave(EntityInterface $node) {
  */
 function node_test_node_update(EntityInterface $node) {
   // Determine changes on update.
-  if (!empty($node->original) && $node->original->title == 'test_changes') {
-    if ($node->original->title != $node->title) {
-      $node->title .= '_update';
+  if (!empty($node->original) && $node->original->getTitle() == 'test_changes') {
+    if ($node->original->getTitle() != $node->getTitle()) {
+      $node->title->value .= '_update';
     }
   }
 }
@@ -175,8 +176,8 @@ function node_test_entity_view_mode_alter(&$view_mode, Drupal\Core\Entity\Entity
  */
 function node_test_node_insert(EntityInterface $node) {
   // Set the node title to the node ID and save.
-  if ($node->title == 'new') {
-    $node->title = 'Node '. $node->id();
+  if ($node->getTitle() == 'new') {
+    $node->setTitle('Node '. $node->id());
     $node->save();
   }
 }
diff --git a/core/modules/node/tests/modules/node_test_exception/node_test_exception.module b/core/modules/node/tests/modules/node_test_exception/node_test_exception.module
index 9eaa4f1..184dfce 100644
--- a/core/modules/node/tests/modules/node_test_exception/node_test_exception.module
+++ b/core/modules/node/tests/modules/node_test_exception/node_test_exception.module
@@ -11,7 +11,7 @@
  * Implements hook_node_insert().
  */
 function node_test_exception_node_insert(EntityInterface $node) {
-  if ($node->title == 'testing_transaction_exception') {
+  if ($node->getTitle() == 'testing_transaction_exception') {
     throw new Exception('Test exception for rollback.');
   }
 }
diff --git a/core/modules/path/lib/Drupal/path/Tests/PathLanguageTest.php b/core/modules/path/lib/Drupal/path/Tests/PathLanguageTest.php
index 122747d..1724a4a 100644
--- a/core/modules/path/lib/Drupal/path/Tests/PathLanguageTest.php
+++ b/core/modules/path/lib/Drupal/path/Tests/PathLanguageTest.php
@@ -86,6 +86,11 @@ function testAliasTranslation() {
     // Clear the path lookup cache.
     $this->container->get('path.alias_manager')->cacheClear();
 
+    // Languages are cached on many levels, and we need to clear those caches.
+    drupal_static_reset('language_list');
+    $this->rebuildContainer();
+    $languages = language_list();
+
     // Ensure the node was created.
     $french_node = $this->drupalGetNodeByTitle($edit["title"]);
     $this->assertTrue(($french_node), 'Node found in database.');
@@ -94,12 +99,8 @@ function testAliasTranslation() {
     $this->drupalGet('fr/' . $edit['path[alias]']);
     $this->assertText($french_node->label(), 'Alias for French translation works.');
 
-    // Confirm that the alias is returned by url(). Languages are cached on
-    // many levels, and we need to clear those caches.
-    drupal_static_reset('language_list');
-    $this->rebuildContainer();
-    $languages = language_list();
-    $url = $this->container->get('url_generator')->generateFromPath('node/' . $french_node->id(), array('language' => $languages[$french_node->langcode]));
+    // Confirm that the alias is returned by url().
+    $url = $this->container->get('url_generator')->generateFromPath('node/' . $french_node->id(), array('language' => $languages[$french_node->language()->id]));
 
     $this->assertTrue(strpos($url, $edit['path[alias]']), 'URL contains the path alias.');
 
@@ -150,17 +151,17 @@ function testAliasTranslation() {
     // The alias manager has an internal path lookup cache. Check to see that
     // it has the appropriate contents at this point.
     $this->container->get('path.alias_manager')->cacheClear();
-    $french_node_path = $this->container->get('path.alias_manager')->getSystemPath($french_alias, $french_node->langcode);
+    $french_node_path = $this->container->get('path.alias_manager')->getSystemPath($french_alias, $french_node->language()->id);
     $this->assertEqual($french_node_path, 'node/' . $french_node->id(), 'Normal path works.');
     // Second call should return the same path.
-    $french_node_path = $this->container->get('path.alias_manager')->getSystemPath($french_alias, $french_node->langcode);
+    $french_node_path = $this->container->get('path.alias_manager')->getSystemPath($french_alias, $french_node->language()->id);
     $this->assertEqual($french_node_path, 'node/' . $french_node->id(), 'Normal path is the same.');
 
     // Confirm that the alias works.
-    $french_node_alias = $this->container->get('path.alias_manager')->getPathAlias('node/' . $french_node->id(), $french_node->langcode);
+    $french_node_alias = $this->container->get('path.alias_manager')->getPathAlias('node/' . $french_node->id(), $french_node->language()->id);
     $this->assertEqual($french_node_alias, $french_alias, 'Alias works.');
     // Second call should return the same alias.
-    $french_node_alias = $this->container->get('path.alias_manager')->getPathAlias('node/' . $french_node->id(), $french_node->langcode);
+    $french_node_alias = $this->container->get('path.alias_manager')->getPathAlias('node/' . $french_node->id(), $french_node->language()->id);
     $this->assertEqual($french_node_alias, $french_alias, 'Alias is the same.');
   }
 }
diff --git a/core/modules/path/path.module b/core/modules/path/path.module
index 0966334..38ebaa2 100644
--- a/core/modules/path/path.module
+++ b/core/modules/path/path.module
@@ -5,10 +5,8 @@
  * Enables users to rename URLs.
  */
 
-use Drupal\Core\Entity\EntityInterface;
-
 use Drupal\Core\Language\Language;
-use Drupal\taxonomy\Plugin\Core\Entity\Term;
+use Drupal\Core\Entity\EntityInterface;
 
 /**
  * Implements hook_help().
@@ -101,8 +99,8 @@ function path_form_node_form_alter(&$form, $form_state) {
   $path = array();
   if (!$node->isNew()) {
     $conditions = array('source' => 'node/' . $node->id());
-    if ($node->langcode != Language::LANGCODE_NOT_SPECIFIED) {
-      $conditions['langcode'] = $node->langcode;
+    if ($node->language()->id != Language::LANGCODE_NOT_SPECIFIED) {
+      $conditions['langcode'] = $node->language()->id;
     }
     $path = Drupal::service('path.crud')->load($conditions);
     if ($path === FALSE) {
@@ -113,7 +111,7 @@ function path_form_node_form_alter(&$form, $form_state) {
     'pid' => NULL,
     'source' => $node->id() ? 'node/' . $node->id() : NULL,
     'alias' => '',
-    'langcode' => isset($node->langcode) ? $node->langcode : Language::LANGCODE_NOT_SPECIFIED,
+    'langcode' => $node->language()->id,
   );
 
   $form['path'] = array(
@@ -182,51 +180,6 @@ function path_form_element_validate($element, &$form_state, $complete_form) {
 }
 
 /**
- * Implements hook_node_insert().
- */
-function path_node_insert(EntityInterface $node) {
-  if (isset($node->path)) {
-    $alias = trim($node->path['alias']);
-    // Only save a non-empty alias.
-    if (!empty($alias)) {
-      // Ensure fields for programmatic executions.
-      $source = 'node/' . $node->id();
-      $langcode = isset($node->langcode) ? $node->langcode : Language::LANGCODE_NOT_SPECIFIED;
-      Drupal::service('path.crud')->save($source, $alias, $langcode);
-    }
-  }
-}
-
-/**
- * Implements hook_node_update().
- */
-function path_node_update(EntityInterface $node) {
-  if (isset($node->path)) {
-    $path = $node->path;
-    $alias = trim($path['alias']);
-    // Delete old alias if user erased it.
-    if (!empty($path['pid']) && empty($path['alias'])) {
-      Drupal::service('path.crud')->delete(array('pid' => $path['pid']));
-    }
-    // Only save a non-empty alias.
-    if (!empty($path['alias'])) {
-      // Ensure fields for programmatic executions.
-      $source = 'node/' . $node->id();
-      $langcode = isset($node->langcode) ? $node->langcode : Language::LANGCODE_NOT_SPECIFIED;
-      Drupal::service('path.crud')->save($source, $alias, $langcode, $path['pid']);
-    }
-  }
-}
-
-/**
- * Implements hook_node_predelete().
- */
-function path_node_predelete(EntityInterface $node) {
-  // Delete all aliases associated with this node.
-  Drupal::service('path.crud')->delete(array('source' => 'node/' . $node->id()));
-}
-
-/**
  * Implements hook_form_FORM_ID_alter() for taxonomy_term_form().
  */
 function path_form_taxonomy_term_form_alter(&$form, $form_state) {
@@ -266,7 +219,7 @@ function path_form_taxonomy_term_form_alter(&$form, $form_state) {
  * Implements hook_entity_field_info().
  */
 function path_entity_field_info($entity_type) {
-  if ($entity_type === 'taxonomy_term') {
+  if ($entity_type === 'taxonomy_term' || $entity_type === 'node') {
     $info['definitions']['path'] = array(
       'type' => 'path_field',
       'label' => t('The path alias'),
@@ -278,48 +231,53 @@ function path_entity_field_info($entity_type) {
 }
 
 /**
- * Implements hook_taxonomy_term_insert().
+ * Implements hook_entity_insert().
+ *
+ * @todo: Move this to methods on the FieldItem class.
  */
-function path_taxonomy_term_insert(Term $term) {
-  if (isset($term->path)) {
-    $term->path->alias = trim($term->path->alias);
+function path_entity_insert(EntityInterface $entity) {
+  if ($entity->getPropertyDefinition('path')) {
+    $entity->path->alias = trim($entity->path->alias);
     // Only save a non-empty alias.
-    if (!empty($term->path->alias)) {
+    if (!empty($entity->path->alias)) {
       // Ensure fields for programmatic executions.
-      $source = 'taxonomy/term/' . $term->id();
-      $langcode = Language::LANGCODE_NOT_SPECIFIED;
-      Drupal::service('path.crud')->save($source, $term->path->alias, $langcode);
+      $uri = $entity->uri();
+      $langcode = $entity->language()->id;
+      Drupal::service('path.crud')->save($uri['path'], $entity->path->alias, $langcode);
     }
   }
 }
 
 /**
- * Implements hook_taxonomy_term_update().
+ * Implements hook_entity_update().
  */
-function path_taxonomy_term_update(Term $term) {
-  if (isset($term->path)) {
-    $term->path->alias = trim($term->path->alias);
+function path_entity_update(EntityInterface $entity) {
+  if ($entity->getPropertyDefinition('path')) {
+    $entity->path->alias = trim($entity->path->alias);
     // Delete old alias if user erased it.
-    if (!empty($term->path->pid) && empty($term->path->alias)) {
-      Drupal::service('path.crud')->delete(array('pid' => $term->path->pid));
+    if ($entity->path->pid && !$entity->path->alias) {
+      Drupal::service('path.crud')->delete(array('pid' => $entity->path->pid));
     }
     // Only save a non-empty alias.
-    if ($term->path->alias) {
-      $pid = (!empty($term->path->pid) ? $term->path->pid  : NULL);
+    if ($entity->path->alias) {
+      $pid = $entity->path->pid;
       // Ensure fields for programmatic executions.
-      $source = 'taxonomy/term/' . $term->id();
-      $langcode = Language::LANGCODE_NOT_SPECIFIED;
-      Drupal::service('path.crud')->save($source, $term->path->alias, $langcode, $pid);
+      $uri = $entity->uri();
+      $langcode = $entity->language()->id;
+      Drupal::service('path.crud')->save($uri['path'], $entity->path->alias, $langcode, $pid);
     }
   }
 }
 
 /**
- * Implements hook_taxonomy_term_delete().
+ * Implements hook_entity_predelete().
  */
-function path_taxonomy_term_delete(Term $term) {
-  // Delete all aliases associated with this term.
-  Drupal::service('path.crud')->delete(array('source' => 'taxonomy/term/' . $term->id()));
+function path_entity_predelete(EntityInterface $entity) {
+  if ($entity->getPropertyDefinition('path')) {
+    // Delete all aliases associated with this term.
+    $uri = $entity->uri();
+    Drupal::service('path.crud')->delete(array('source' => $uri['path']));
+  }
 }
 
 /**
diff --git a/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php b/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php
index e23dbc5..b7ca46d 100644
--- a/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php
+++ b/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php
@@ -123,7 +123,7 @@ public function _testPictureFieldFormatters($scheme) {
     $node = node_load($nid, TRUE);
 
     // Test that the default formatter is being used.
-    $image_uri = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id'])->getFileUri();
+    $image_uri = file_load($node->{$field_name}->target_id)->getFileUri();
     $image = array(
       '#theme' => 'image',
       '#uri' => $image_uri,
diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/FileFieldAttributesTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/FileFieldAttributesTest.php
index 11176dc..f1a69cc 100644
--- a/core/modules/rdf/lib/Drupal/rdf/Tests/FileFieldAttributesTest.php
+++ b/core/modules/rdf/lib/Drupal/rdf/Tests/FileFieldAttributesTest.php
@@ -73,7 +73,7 @@ public function setUp() {
     $nid = $this->uploadNodeFile($test_file, $this->fieldName, $type_name);
 
     $this->node = node_load($nid, TRUE);
-    $this->file = file_load($this->node->{$this->fieldName}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']);
+    $this->file = file_load($this->node->{$this->fieldName}->target_id);
 
   }
 
diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/ImageFieldAttributesTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/ImageFieldAttributesTest.php
index a622a8c..14af8f6 100644
--- a/core/modules/rdf/lib/Drupal/rdf/Tests/ImageFieldAttributesTest.php
+++ b/core/modules/rdf/lib/Drupal/rdf/Tests/ImageFieldAttributesTest.php
@@ -73,7 +73,7 @@ public function setUp() {
     // Save a node with the image.
     $nid = $this->uploadNodeImage($image, $this->fieldName, 'article');
     $this->node = node_load($nid);
-    $this->file = file_load($this->node->{$this->fieldName}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']);
+    $this->file = file_load($this->node->{$this->fieldName}->target_id);
   }
 
   /**
diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/NodeAttributesTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/NodeAttributesTest.php
index a026bd6..e8ba1d3 100644
--- a/core/modules/rdf/lib/Drupal/rdf/Tests/NodeAttributesTest.php
+++ b/core/modules/rdf/lib/Drupal/rdf/Tests/NodeAttributesTest.php
@@ -77,21 +77,21 @@ function testNodeAttributes() {
     // Node title.
     $expected_value = array(
       'type' => 'literal',
-      'value' => $node->title,
+      'value' => $node->getTitle(),
       'lang' => 'en',
     );
     $this->assertTrue($graph->hasProperty($node_uri, 'http://purl.org/dc/terms/title', $expected_value), 'Node title found in RDF output (dc:title).');
     // Node date.
     $expected_value = array(
       'type' => 'literal',
-      'value' => date('c', $node->created),
+      'value' => date('c', $node->getCreatedTime()),
       'datatype' => 'http://www.w3.org/2001/XMLSchema#dateTime',
     );
     $this->assertTrue($graph->hasProperty($node_uri, 'http://purl.org/dc/terms/date', $expected_value), 'Node date found in RDF output (dc:date).');
     // Node date.
     $expected_value = array(
       'type' => 'literal',
-      'value' => date('c', $node->created),
+      'value' => date('c', $node->getCreatedTime()),
       'datatype' => 'http://www.w3.org/2001/XMLSchema#dateTime',
     );
     $this->assertTrue($graph->hasProperty($node_uri, 'http://purl.org/dc/terms/created', $expected_value), 'Node date found in RDF output (dc:created).');
diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/TrackerAttributesTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/TrackerAttributesTest.php
index 909b7b5..072fcc5 100644
--- a/core/modules/rdf/lib/Drupal/rdf/Tests/TrackerAttributesTest.php
+++ b/core/modules/rdf/lib/Drupal/rdf/Tests/TrackerAttributesTest.php
@@ -119,9 +119,9 @@ function testAttributesInTracker() {
    */
   function _testBasicTrackerRdfaMarkup(EntityInterface $node) {
     $node_uri = url('node/' . $node->id(), array('absolute' => TRUE));
-    $user_uri = url('user/' . $node->uid, array('absolute' => TRUE));
+    $user_uri = url('user/' . $node->getAuthorId(), array('absolute' => TRUE));
 
-    $user = ($node->uid == 0) ? 'Anonymous user' : 'Registered user';
+    $user = ($node->getAuthorId() == 0) ? 'Anonymous user' : 'Registered user';
 
     // Parses tracker page where the nodes are displayed in a table.
     $parser = new \EasyRdf_Parser_Rdfa();
@@ -134,7 +134,7 @@ function _testBasicTrackerRdfaMarkup(EntityInterface $node) {
       'type' => 'literal',
       // The theme layer adds a space after the title a element, and the RDFa
       // attribute is on the wrapping td. Adds a space to match this.
-      'value' => $node->title . ' ',
+      'value' => $node->getTitle() . ' ',
       'lang' => 'en',
     );
     $this->assertTrue($graph->hasProperty($node_uri, 'http://purl.org/dc/terms/title', $expected_value), 'Title found in RDF output (dc:title).');
@@ -150,16 +150,16 @@ function _testBasicTrackerRdfaMarkup(EntityInterface $node) {
       'type' => 'uri',
       'value' => $user_uri,
     );
-    if ($node->uid == 0) {
+    if ($node->getAuthorId() == 0) {
       $this->assertFalse($graph->hasProperty($node_uri, 'http://rdfs.org/sioc/ns#has_creator', $expected_value), 'No relation to author found in RDF output (sioc:has_creator).');
     }
-    elseif ($node->uid > 0) {
+    elseif ($node->getAuthorId() > 0) {
       $this->assertTrue($graph->hasProperty($node_uri, 'http://rdfs.org/sioc/ns#has_creator', $expected_value), 'Relation to author found in RDF output (sioc:has_creator).');
     }
     // Last updated.
     $expected_value = array(
       'type' => 'literal',
-      'value' => date('c', $node->changed),
+      'value' => date('c', $node->getChangedTime()),
       'datatype' => 'http://www.w3.org/2001/XMLSchema#dateTime',
     );
     $this->assertTrue($graph->hasProperty($node_uri, 'http://rdfs.org/sioc/ns#last_activity_date', $expected_value), 'Last activity date found in RDF output (sioc:last_activity_date).');
diff --git a/core/modules/rdf/rdf.module b/core/modules/rdf/rdf.module
index 06b25a0..16f4b91 100644
--- a/core/modules/rdf/rdf.module
+++ b/core/modules/rdf/rdf.module
@@ -277,7 +277,7 @@ function rdf_preprocess_node(&$variables) {
   // Adds RDFa markup for the date.
   $created_mapping = $mapping->getPreparedFieldMapping('created');
   if (!empty($created_mapping) && $variables['submitted']) {
-    $date_attributes = rdf_rdfa_attributes($created_mapping, $variables['node']->created);
+    $date_attributes = rdf_rdfa_attributes($created_mapping, $variables['node']->getCreatedTime());
     $rdf_metadata = array(
       '#theme' => 'rdf_metadata',
       '#metadata' => array($date_attributes),
diff --git a/core/modules/search/lib/Drupal/search/Tests/SearchAdvancedSearchFormTest.php b/core/modules/search/lib/Drupal/search/Tests/SearchAdvancedSearchFormTest.php
index 5b0efeb..ed47384 100644
--- a/core/modules/search/lib/Drupal/search/Tests/SearchAdvancedSearchFormTest.php
+++ b/core/modules/search/lib/Drupal/search/Tests/SearchAdvancedSearchFormTest.php
@@ -42,7 +42,7 @@ function setUp() {
    * Test using the advanced search form to limit search to nodes of type "Basic page".
    */
   function testNodeType() {
-    $this->assertTrue($this->node->type == 'page', 'Node type is Basic page.');
+    $this->assertTrue($this->node->getType() == 'page', 'Node type is Basic page.');
 
     // Assert that the dummy title doesn't equal the real title.
     $dummy_title = 'Lorem ipsum';
diff --git a/core/modules/search/lib/Drupal/search/Tests/SearchMultilingualEntityTest.php b/core/modules/search/lib/Drupal/search/Tests/SearchMultilingualEntityTest.php
index e1021b4..95f51b8 100644
--- a/core/modules/search/lib/Drupal/search/Tests/SearchMultilingualEntityTest.php
+++ b/core/modules/search/lib/Drupal/search/Tests/SearchMultilingualEntityTest.php
@@ -118,10 +118,8 @@ function testSearchingMultilingualFieldValues() {
     search_update_totals();
     foreach ($this->searchable_nodes as $node) {
       // Each searchable node that we created contains values in the body field
-      // in one or more languages. Let's pick the last language variant from the
-      // body array and execute a search using that as a search keyword.
-      $body_language_variant = end($node->body);
-      $search_result = node_search_execute($body_language_variant[0]['value']);
+      // in one or more languages.
+      $search_result = node_search_execute($node->body->value);
       // See whether we get the same node as a result.
       $this->assertEqual($search_result[0]['node']->id(), $node->id(), 'The search has resulted the correct node.');
     }
diff --git a/core/modules/search/search.api.php b/core/modules/search/search.api.php
index 649a933..1fff4a6 100644
--- a/core/modules/search/search.api.php
+++ b/core/modules/search/search.api.php
@@ -226,12 +226,12 @@ function hook_search_execute($keys = NULL, $conditions = NULL) {
       'type' => check_plain(node_get_type_label($node)),
       'title' => $node->label($item->langcode),
       'user' => drupal_render($username),
-      'date' => $node->changed,
+      'date' => $node->getChangedTime(),
       'node' => $node,
       'extra' => $extra,
       'score' => $item->calculated_score,
       'snippet' => search_excerpt($keys, $node->rendered, $item->langcode),
-      'langcode' => $node->langcode,
+      'langcode' => $node->language()->id,
     );
   }
   return $results;
@@ -347,7 +347,7 @@ function hook_update_index() {
 
     // Save the changed time of the most recent indexed node, for the search
     // results half-life calculation.
-    \Drupal::state()->set('node.cron_last', $node->changed);
+    \Drupal::state()->set('node.cron_last', $node->getChangedTime());
 
     // Render the node.
     $build = node_view($node, 'search_index');
diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationFormTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationFormTest.php
index 80e8a6b..4404ca5 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationFormTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationFormTest.php
@@ -69,12 +69,12 @@ function testEntityFormLanguage() {
     $this->drupalPost(NULL, $edit, t('Save'));
 
     $node = $this->drupalGetNodeByTitle($edit["title"]);
-    $this->assertTrue($node->langcode == $form_langcode, 'Form language is the same as the entity language.');
+    $this->assertTrue($node->language()->id == $form_langcode, 'Form language is the same as the entity language.');
 
     // Edit the node and test the form language.
     $this->drupalGet($this->langcodes[0] . '/node/' . $node->id() . '/edit');
     $form_langcode = \Drupal::state()->get('entity_test.form_langcode') ?: FALSE;
-    $this->assertTrue($node->langcode == $form_langcode, 'Form language is the same as the entity language.');
+    $this->assertTrue($node->language()->id == $form_langcode, 'Form language is the same as the entity language.');
 
     // Explicitly set form langcode.
     $langcode = $this->langcodes[0];
diff --git a/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php b/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php
index d51c9ea..7d1814e 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php
@@ -174,15 +174,15 @@ function testBreadCrumbs() {
     $trail = $home;
     $this->assertBreadcrumb("node/$nid1", $trail);
     // Also verify that the node does not appear elsewhere (e.g., menu trees).
-    $this->assertNoLink($node1->title);
+    $this->assertNoLink($node1->getTitle());
     // The node itself should not be contained in the breadcrumb on the default
     // local task, since there is no difference between both pages.
     $this->assertBreadcrumb("node/$nid1/view", $trail);
     // Also verify that the node does not appear elsewhere (e.g., menu trees).
-    $this->assertNoLink($node1->title);
+    $this->assertNoLink($node1->getTitle());
 
     $trail += array(
-      "node/$nid1" => $node1->title,
+      "node/$nid1" => $node1->getTitle(),
     );
     $this->assertBreadcrumb("node/$nid1/edit", $trail);
 
@@ -220,10 +220,10 @@ function testBreadCrumbs() {
       $tree = array(
         "node/$nid2" => $node2->menu['link_title'],
       );
-      $this->assertBreadcrumb("node/$nid2", $trail, $node2->title, $tree);
+      $this->assertBreadcrumb("node/$nid2", $trail, $node2->getTitle(), $tree);
       // The node itself should not be contained in the breadcrumb on the
       // default local task, since there is no difference between both pages.
-      $this->assertBreadcrumb("node/$nid2/view", $trail, $node2->title, $tree);
+      $this->assertBreadcrumb("node/$nid2/view", $trail, $node2->getTitle(), $tree);
       $trail += array(
         "node/$nid2" => $node2->menu['link_title'],
       );
@@ -244,10 +244,10 @@ function testBreadCrumbs() {
       ));
       $nid3 = $node3->id();
 
-      $this->assertBreadcrumb("node/$nid3", $trail, $node3->title, $tree, FALSE);
+      $this->assertBreadcrumb("node/$nid3", $trail, $node3->getTitle(), $tree, FALSE);
       // The node itself should not be contained in the breadcrumb on the
       // default local task, since there is no difference between both pages.
-      $this->assertBreadcrumb("node/$nid3/view", $trail, $node3->title, $tree, FALSE);
+      $this->assertBreadcrumb("node/$nid3/view", $trail, $node3->getTitle(), $tree, FALSE);
       $trail += array(
         "node/$nid3" => $node3->menu['link_title'],
       );
@@ -288,14 +288,14 @@ function testBreadCrumbs() {
     $tree = $expected + array(
       'node/' . $parent->id() => $parent->menu['link_title'],
     );
-    $this->assertBreadcrumb(NULL, $trail, $parent->title, $tree);
+    $this->assertBreadcrumb(NULL, $trail, $parent->getTitle(), $tree);
     $trail += array(
       'node/' . $parent->id() => $parent->menu['link_title'],
     );
     $tree += array(
       'node/' . $parent->id() => $child->menu['link_title'],
     );
-    $this->assertBreadcrumb('node/' . $child->id(), $trail, $child->title, $tree);
+    $this->assertBreadcrumb('node/' . $child->id(), $trail, $child->getTitle(), $tree);
 
     // Add a taxonomy term/tag to last node, and add a link for that term to the
     // Tools menu.
@@ -350,7 +350,7 @@ function testBreadCrumbs() {
         $link['link_path'] => $link['link_title'],
       );
       $this->assertBreadcrumb($link['link_path'], $trail, $term->label(), $tree);
-      $this->assertRaw(check_plain($parent->title), 'Tagged node found.');
+      $this->assertRaw(check_plain($parent->getTitle()), 'Tagged node found.');
 
       // Additionally make sure that this link appears only once; i.e., the
       // untranslated menu links automatically generated from menu router items
diff --git a/core/modules/system/lib/Drupal/system/Tests/ParamConverter/UpcastingTest.php b/core/modules/system/lib/Drupal/system/Tests/ParamConverter/UpcastingTest.php
index ad966e2..f1ff08f 100644
--- a/core/modules/system/lib/Drupal/system/Tests/ParamConverter/UpcastingTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/ParamConverter/UpcastingTest.php
@@ -51,12 +51,12 @@ public function testUpcasting() {
 
     // paramconverter_test/test_node_user_user/{node}/{foo}/{user}
     // options.parameters.foo.type = entity:user
-    $this->drupalGet("paramconverter_test/test_node_user_user/{$node->nid}/" . $user->id() . "/" . $user->id());
+    $this->drupalGet("paramconverter_test/test_node_user_user/" . $node->id() . "/" . $user->id() . "/" . $user->id());
     $this->assertRaw("user: {$user->label()}, node: {$node->label()}, foo: {$user->label()}", 'foo converted to user as well');
 
     // paramconverter_test/test_node_node_foo/{user}/{node}/{foo}
     // options.parameters.user.type = entity:node
-    $this->drupalGet("paramconverter_test/test_node_node_foo/{$node->nid}/{$node->nid}/$foo");
+    $this->drupalGet("paramconverter_test/test_node_node_foo/" . $node->id() . "/" . $node->id() . "/$foo");
     $this->assertRaw("user: {$node->label()}, node: {$node->label()}, foo: $foo", 'user is upcast to node (rather than to user)');
   }
 
@@ -68,7 +68,7 @@ public function testSameTypes() {
     $parent = $this->drupalCreateNode(array('title' => $this->randomName(8)));
     // paramconverter_test/node/{node}/set/parent/{parent}
     // options.parameters.parent.type = entity:node
-    $this->drupalGet("paramconverter_test/node/" . $node->nid . "/set/parent/" . $parent->nid);
-    $this->assertRaw("Setting '" . $parent->title . "' as parent of '" . $node->title . "'.");
+    $this->drupalGet("paramconverter_test/node/" . $node->id() . "/set/parent/" . $parent->id());
+    $this->assertRaw("Setting '" . $parent->getTitle() . "' as parent of '" . $node->getTitle() . "'.");
   }
 }
diff --git a/core/modules/system/lib/Drupal/system/Tests/Plugin/PluginTestBase.php b/core/modules/system/lib/Drupal/system/Tests/Plugin/PluginTestBase.php
index c580338..c73fd67 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Plugin/PluginTestBase.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Plugin/PluginTestBase.php
@@ -89,7 +89,7 @@ public function setUp() {
         'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockComplexContextBlock',
         'context' => array(
           'user' => array('class' => 'Drupal\user\UserInterface'),
-          'node' => array('class' => 'Drupal\Core\Entity\EntityBCDecorator'),
+          'node' => array('class' => 'Drupal\node\NodeInterface'),
         ),
       ),
     );
diff --git a/core/modules/system/lib/Drupal/system/Tests/System/DateFormatsLanguageTest.php b/core/modules/system/lib/Drupal/system/Tests/System/DateFormatsLanguageTest.php
index 962d21f..e17c709 100644
--- a/core/modules/system/lib/Drupal/system/Tests/System/DateFormatsLanguageTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/System/DateFormatsLanguageTest.php
@@ -100,10 +100,10 @@ function testLocalizeDateFormats() {
 
     // Configure format for the node posted date changes with the language.
     $this->drupalGet('node/' . $node->id());
-    $english_date = format_date($node->created, 'custom', 'j M Y');
+    $english_date = format_date($node->getCreatedTime(), 'custom', 'j M Y');
     $this->assertText($english_date, 'English date format appears');
     $this->drupalGet('fr/node/' . $node->id());
-    $french_date = format_date($node->created, 'custom', 'd.m.Y');
+    $french_date = format_date($node->getCreatedTime(), 'custom', 'd.m.Y');
     $this->assertText($french_date, 'French date format appears');
 
     // Make sure we can reset dates back to default.
diff --git a/core/modules/system/lib/Drupal/system/Tests/System/TokenReplaceTest.php b/core/modules/system/lib/Drupal/system/Tests/System/TokenReplaceTest.php
index 84bf929..4350d10 100644
--- a/core/modules/system/lib/Drupal/system/Tests/System/TokenReplaceTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/System/TokenReplaceTest.php
@@ -43,9 +43,9 @@ function testTokenReplacement() {
     $source .= '[user:name]';          // No user passed in, should be untouched
     $source .= '[bogus:token]';        // Non-existent token
 
-    $target  = check_plain($node->title);
+    $target  = check_plain($node->getTitle());
     $target .= check_plain($account->getUsername());
-    $target .= format_interval(REQUEST_TIME - $node->created, 2, $language_interface->id);
+    $target .= format_interval(REQUEST_TIME - $node->getCreatedTime(), 2, $language_interface->id);
     $target .= check_plain($user->getUsername());
     $target .= format_date(REQUEST_TIME, 'short', '', NULL, $language_interface->id);
 
@@ -65,10 +65,10 @@ function testTokenReplacement() {
     // correctly by a 'known' token, [node:title].
     $raw_tokens = array('title' => '[node:title]');
     $generated = $token_service->generate('node', $raw_tokens, array('node' => $node));
-    $this->assertEqual($generated['[node:title]'], check_plain($node->title), 'Token sanitized.');
+    $this->assertEqual($generated['[node:title]'], check_plain($node->getTitle()), 'Token sanitized.');
 
     $generated = $token_service->generate('node', $raw_tokens, array('node' => $node), array('sanitize' => FALSE));
-    $this->assertEqual($generated['[node:title]'], $node->title, 'Unsanitized token generated properly.');
+    $this->assertEqual($generated['[node:title]'], $node->getTitle(), 'Unsanitized token generated properly.');
 
     // Test token replacement when the string contains no tokens.
     $this->assertEqual($token_service->replace('No tokens here.'), 'No tokens here.');
diff --git a/core/modules/system/lib/Drupal/system/Tests/Theme/EntityFilteringThemeTest.php b/core/modules/system/lib/Drupal/system/Tests/Theme/EntityFilteringThemeTest.php
index f7d53e2..bf62114 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Theme/EntityFilteringThemeTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Theme/EntityFilteringThemeTest.php
@@ -108,7 +108,7 @@ function setUp() {
     // Create a test comment on the test node.
     $this->comment = entity_create('comment', array(
       'nid' => $this->node->id(),
-      'node_type' => $this->node->type,
+      'node_type' => $this->node->getType(),
       'status' => COMMENT_PUBLISHED,
       'subject' => $this->xss_label,
       'comment_body' => array($this->randomName()),
diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php
index 66a95c0..1df8dec 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php
@@ -6,7 +6,9 @@
  */
 
 namespace Drupal\system\Tests\Upgrade;
-use Drupal\Core\Language\Language;
+
+use Drupal\Core\Entity\DatabaseStorageController;
+use Drupal\field\Plugin\Core\Entity\Field;
 
 /**
  * Tests upgrade of system variables.
@@ -209,16 +211,10 @@ function testFieldUpgradeToConfig() {
     // The deleted field uuid and deleted instance field_uuid must match.
     $this->assertEqual($deleted_field['uuid'], $deleted_instance['field_uuid']);
 
-    // Check that pre-existing deleted field values are read correctly.
-    $entity = _field_create_entity_from_ids((object) array(
-      'entity_type' => 'node',
-      'bundle' => 'article',
-      'entity_id' => 2,
-      'revision_id' => 2,
-    ));
-    field_attach_load('node', array(2 => $entity), FIELD_LOAD_CURRENT, array('instance' => entity_create('field_instance', $deleted_instance)));
-    $deleted_value = $entity->get('test_deleted_field');
-    $this->assertEqual($deleted_value[Language::LANGCODE_NOT_SPECIFIED][0]['value'], 'Some deleted value');
+    // Check that pre-existing deleted field table is renamed correctly.
+    $field_entity = new Field($deleted_field);
+    $table_name = _field_sql_storage_tablename($deleted_field);
+    $this->assertEqual("field_deleted_data_" . substr(hash('sha256', $deleted_field['uuid']), 0, 10), $table_name);
 
     // Check that creation of a new node works as expected.
     $value = $this->randomName();
diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/LanguageUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/LanguageUpgradePathTest.php
index 4c5f590..2fba93f6 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/LanguageUpgradePathTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/LanguageUpgradePathTest.php
@@ -84,9 +84,9 @@ public function testLanguageUpgrade() {
     $spanish_nid = 51;
     $translation_source_nid = 52;
     $translation_nid = 53;
-    // Check directly for the $node->langcode property.
-    $this->assertEqual(node_load($language_none_nid)->langcode, Language::LANGCODE_NOT_SPECIFIED, "'language' property was renamed to 'langcode' for Language::LANGCODE_NOT_SPECIFIED node.");
-    $this->assertEqual(node_load($spanish_nid)->langcode, 'ca', "'language' property was renamed to 'langcode' for Catalan node.");
+    // Check directly for the node langcode.
+    $this->assertEqual(node_load($language_none_nid)->language()->id, Language::LANGCODE_NOT_SPECIFIED, "'language' property was renamed to 'langcode' for Language::LANGCODE_NOT_SPECIFIED node.");
+    $this->assertEqual(node_load($spanish_nid)->language()->id, 'ca', "'language' property was renamed to 'langcode' for Catalan node.");
     // Check that the translation table works correctly.
     $this->drupalGet("node/$translation_source_nid/translate");
     $this->assertResponse(200, 'The translated node has a proper translation table.');
diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php
index bbc3c72..fca2eb0 100644
--- a/core/modules/system/system.api.php
+++ b/core/modules/system/system.api.php
@@ -1861,10 +1861,10 @@ function hook_mail($key, &$message, $params) {
   if (isset($params['node'])) {
     $node = $params['node'];
     $variables += array(
-      '%uid' => $node->uid,
+      '%uid' => $node->getAuthorId(),
       '%node_url' => url('node/' . $node->id(), array('absolute' => TRUE)),
       '%node_type' => node_get_type_label($node),
-      '%title' => $node->title,
+      '%title' => $node->getTitle(),
       '%teaser' => $node->teaser,
       '%body' => $node->body,
     );
@@ -3144,7 +3144,7 @@ function hook_tokens($type, $tokens, array $data = array(), array $options = arr
           break;
 
         case 'title':
-          $replacements[$original] = $sanitize ? check_plain($node->title) : $node->title;
+          $replacements[$original] = $sanitize ? check_plain($node->getTitle()) : $node->getTitle();
           break;
 
         case 'edit-url':
@@ -3153,23 +3153,22 @@ function hook_tokens($type, $tokens, array $data = array(), array $options = arr
 
         // Default values for the chained tokens handled below.
         case 'author':
-          $name = ($node->uid == 0) ? Drupal::config('user.settings')->get('anonymous') : $node->name;
-          $replacements[$original] = $sanitize ? filter_xss($name) : $name;
+          $account = $node->getAuthor() ? $node->getAuthor() : user_load(0);
+          $replacements[$original] = $sanitize ? check_plain($account->label()) : $account->label();
           break;
 
         case 'created':
-          $replacements[$original] = format_date($node->created, 'medium', '', NULL, $langcode);
+          $replacements[$original] = format_date($node->getCreatedTime(), 'medium', '', NULL, $langcode);
           break;
       }
     }
 
     if ($author_tokens = $token_service->findWithPrefix($tokens, 'author')) {
-      $author = user_load($node->uid);
-      $replacements += $token_service->generate('user', $author_tokens, array('user' => $author), $options);
+      $replacements += $token_service->generate('user', $author_tokens, array('user' => $node->getAuthor()), $options);
     }
 
     if ($created_tokens = $token_service->findWithPrefix($tokens, 'created')) {
-      $replacements += $token_service->generate('date', $created_tokens, array('date' => $node->created), $options);
+      $replacements += $token_service->generate('date', $created_tokens, array('date' => $node->getCreatedTime()), $options);
     }
   }
 
diff --git a/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/MockBlockManager.php b/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/MockBlockManager.php
index a897160..386841b 100644
--- a/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/MockBlockManager.php
+++ b/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/MockBlockManager.php
@@ -91,7 +91,7 @@ public function __construct() {
       'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockComplexContextBlock',
       'context' => array(
         'user' => array('class' => 'Drupal\user\UserInterface'),
-        'node' => array('class' => 'Drupal\Core\Entity\EntityBCDecorator'),
+        'node' => array('class' => 'Drupal\node\NodeInterface'),
       ),
     ));
 
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/argument_default/Tid.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/argument_default/Tid.php
index 0257435..2ceb843 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/argument_default/Tid.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/argument_default/Tid.php
@@ -135,7 +135,7 @@ public function getArgument() {
       // Just check, if a node could be detected.
       if ($node) {
         $taxonomy = array();
-        $fields = field_info_instances('node', $node->type);
+        $fields = field_info_instances('node', $node->getType());
         foreach ($fields as $name => $info) {
           $field_info = field_info_field($name);
           if ($field_info['type'] == 'taxonomy_term_reference') {
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/LegacyTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/LegacyTest.php
index 5a34e15..3758df7 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/LegacyTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/LegacyTest.php
@@ -48,6 +48,6 @@ function testTaxonomyLegacyNode() {
     $this->drupalPost('node/add/article', $edit, t('Save and publish'));
     // Checks that the node has been saved.
     $node = $this->drupalGetNodeByTitle($edit['title']);
-    $this->assertEqual($node->created, $date->getTimestamp(), 'Legacy node was saved with the right date.');
+    $this->assertEqual($node->getCreatedTime(), $date->getTimestamp(), 'Legacy node was saved with the right date.');
   }
 }
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php
index 991f274..239e927 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php
@@ -170,7 +170,7 @@ function testTaxonomyIndex() {
     $this->assertEqual(1, $index_count, 'Term 2 is indexed once.');
 
     // Update the article to change one term.
-    $node->{$this->field_name_1}[$langcode] = array(array('target_id' => $term_1->id()));
+    $node->{$this->field_name_1} = array(array('target_id' => $term_1->id()));
     $node->save();
 
     // Check that both terms are indexed.
@@ -186,7 +186,7 @@ function testTaxonomyIndex() {
     $this->assertEqual(1, $index_count, 'Term 2 is indexed.');
 
     // Update the article to change another term.
-    $node->{$this->field_name_2}[$langcode] = array(array('target_id' => $term_1->id()));
+    $node->{$this->field_name_2} = array(array('target_id' => $term_1->id()));
     $node->save();
 
     // Check that only one term is indexed.
diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module
index 090baaf..94255b2 100644
--- a/core/modules/taxonomy/taxonomy.module
+++ b/core/modules/taxonomy/taxonomy.module
@@ -1130,40 +1130,21 @@ function taxonomy_build_node_index($node) {
   // only data for current, published nodes.
   $status = NULL;
   if (Drupal::config('taxonomy.settings')->get('maintain_index_table')) {
-    // If a node property is not set in the node object when $node->save() is
-    // called, the old value from $node->original is used.
-    if (!empty($node->original)) {
-      $status = (int)(!empty($node->status) || (!isset($node->status) && !empty($node->original->status)));
-      $sticky = (int)(!empty($node->sticky) || (!isset($node->sticky) && !empty($node->original->sticky)));
-    }
-    else {
-      $status = (int)(!empty($node->status));
-      $sticky = (int)(!empty($node->sticky));
-    }
+    $status = $node->isPublished();
+    $sticky = (int) $node->isSticky();
   }
   // We only maintain the taxonomy index for published nodes.
   if ($status && $node->isDefaultRevision()) {
     // Collect a unique list of all the term IDs from all node fields.
     $tid_all = array();
-    foreach (field_info_instances('node', $node->type) as $instance) {
+    foreach (field_info_instances('node', $node->getType()) as $instance) {
       $field_name = $instance['field_name'];
       $field = field_info_field($field_name);
       if ($field['module'] == 'taxonomy' && $field['storage']['type'] == 'field_sql_storage') {
-        // If a field value is not set in the node object when $node->save() is
-        // called, the old value from $node->original is used.
-        if (isset($node->{$field_name})) {
-          $items = $node->{$field_name};
-        }
-        elseif (isset($node->original->{$field_name})) {
-          $items = $node->original->{$field_name};
-        }
-        else {
-          continue;
-        }
-        foreach (field_available_languages('node', $field) as $langcode) {
-          if (!empty($items[$langcode])) {
-            foreach ($items[$langcode] as $item) {
-              $tid_all[$item['target_id']] = $item['target_id'];
+        foreach ($node->getTranslationLanguages() as $language) {
+          foreach ($node->getTranslation($language->id)->$field_name as $item) {
+            if (!$item->isEmpty()) {
+              $tid_all[$item->target_id] = $item->target_id;
             }
           }
         }
@@ -1177,7 +1158,7 @@ function taxonomy_build_node_index($node) {
           'nid' => $node->id(),
           'tid' => $tid,
           'sticky' => $sticky,
-          'created' => $node->created,
+          'created' => $node->getCreatedTime(),
         ));
       }
       $query->execute();
diff --git a/core/modules/tracker/lib/Drupal/tracker/Tests/TrackerNodeAccessTest.php b/core/modules/tracker/lib/Drupal/tracker/Tests/TrackerNodeAccessTest.php
index 76033fb..4598aae 100644
--- a/core/modules/tracker/lib/Drupal/tracker/Tests/TrackerNodeAccessTest.php
+++ b/core/modules/tracker/lib/Drupal/tracker/Tests/TrackerNodeAccessTest.php
@@ -59,19 +59,19 @@ function testTrackerNodeAccess() {
 
     // User with access should see both nodes created.
     $this->drupalGet('tracker');
-    $this->assertText($private_node->title, 'Private node is visible to user with private access.');
-    $this->assertText($public_node->title, 'Public node is visible to user with private access.');
+    $this->assertText($private_node->getTitle(), 'Private node is visible to user with private access.');
+    $this->assertText($public_node->getTitle(), 'Public node is visible to user with private access.');
     $this->drupalGet('user/' . $access_user->id() . '/track');
-    $this->assertText($private_node->title, 'Private node is visible to user with private access.');
-    $this->assertText($public_node->title, 'Public node is visible to user with private access.');
+    $this->assertText($private_node->getTitle(), 'Private node is visible to user with private access.');
+    $this->assertText($public_node->getTitle(), 'Public node is visible to user with private access.');
 
     // User without access should not see private node.
     $this->drupalLogin($no_access_user);
     $this->drupalGet('tracker');
-    $this->assertNoText($private_node->title, 'Private node is not visible to user without private access.');
-    $this->assertText($public_node->title, 'Public node is visible to user without private access.');
+    $this->assertNoText($private_node->getTitle(), 'Private node is not visible to user without private access.');
+    $this->assertText($public_node->getTitle(), 'Public node is visible to user without private access.');
     $this->drupalGet('user/' . $access_user->id() . '/track');
-    $this->assertNoText($private_node->title, 'Private node is not visible to user without private access.');
-    $this->assertText($public_node->title, 'Public node is visible to user without private access.');
+    $this->assertNoText($private_node->getTitle(), 'Private node is not visible to user without private access.');
+    $this->assertText($public_node->getTitle(), 'Public node is visible to user without private access.');
   }
 }
diff --git a/core/modules/tracker/lib/Drupal/tracker/Tests/Views/TrackerUserUidTest.php b/core/modules/tracker/lib/Drupal/tracker/Tests/Views/TrackerUserUidTest.php
index 804774d..54a689b 100644
--- a/core/modules/tracker/lib/Drupal/tracker/Tests/Views/TrackerUserUidTest.php
+++ b/core/modules/tracker/lib/Drupal/tracker/Tests/Views/TrackerUserUidTest.php
@@ -52,7 +52,7 @@ public function testUserUid() {
 
     // Change the filter value to our user.
     $view->initHandlers();
-    $view->filter['uid_touch_tracker']->value = $this->node->uid;
+    $view->filter['uid_touch_tracker']->value = $this->node->getAuthorId();
     $this->executeView($view);
 
     // We should have one result as the filter is set for the created user.
@@ -70,7 +70,7 @@ public function testUserUid() {
 
     // Test the correct argument UID.
     $view->initHandlers();
-    $this->executeView($view, array($this->node->uid));
+    $this->executeView($view, array($this->node->getAuthorId()));
     $this->assertIdenticalResultSet($view, $expected, $map);
   }
 
diff --git a/core/modules/tracker/tracker.module b/core/modules/tracker/tracker.module
index 1052b5f..581a10d 100644
--- a/core/modules/tracker/tracker.module
+++ b/core/modules/tracker/tracker.module
@@ -6,6 +6,7 @@
  */
 
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\node\NodeInterface;
 
 /**
  * Implements hook_help().
@@ -195,8 +196,8 @@ function _tracker_user_access($account) {
  *
  * Adds new tracking information for this node since it's new.
  */
-function tracker_node_insert(EntityInterface $node, $arg = 0) {
-  _tracker_add($node->id(), $node->uid, $node->changed);
+function tracker_node_insert(NodeInterface $node, $arg = 0) {
+  _tracker_add($node->id(), $node->getAuthorId(), $node->getChangedTime());
 }
 
 /**
@@ -204,8 +205,8 @@ function tracker_node_insert(EntityInterface $node, $arg = 0) {
  *
  * Adds tracking information for this node since it's been updated.
  */
-function tracker_node_update(EntityInterface $node, $arg = 0) {
-  _tracker_add($node->id(), $node->uid, $node->changed);
+function tracker_node_update(NodeInterface $node, $arg = 0) {
+  _tracker_add($node->id(), $node->getAuthorId(), $node->getChangedTime());
 }
 
 /**
@@ -302,14 +303,14 @@ function _tracker_add($nid, $uid, $changed) {
 }
 
 /**
- * Determines the max timestamp between $node->changed and the last comment.
+ * Picks the most recent timestamp between node changed and the last comment.
  *
  * @param $nid
  *   A node ID.
  *
  * @return
- *  The $node->changed timestamp, or most recent comment timestamp, whichever
- *  is the greatest.
+ *  The node changed timestamp, or most recent comment timestamp, whichever is
+ *  the greatest.
  */
 function _tracker_calculate_changed($nid) {
   // @todo This should be actually filtering on the desired language and just
diff --git a/core/modules/tracker/tracker.pages.inc b/core/modules/tracker/tracker.pages.inc
index cf2f51a..8e187ef 100644
--- a/core/modules/tracker/tracker.pages.inc
+++ b/core/modules/tracker/tracker.pages.inc
@@ -76,21 +76,20 @@ function tracker_page($account = NULL, $set_title = FALSE) {
 
       $mark_build = array(
         '#theme' => 'mark',
-        '#status' => node_mark($node->id(), $node->changed),
+        '#status' => node_mark($node->id(), $node->getChangedTime()),
       );
 
       $row = array(
         'type' => check_plain(node_get_type_label($node)),
-        // Do not use $node->label(), because $node comes from the database.
-        'title' => array('data' => l($node->title, 'node/' . $node->id()) . ' ' . drupal_render($mark_build)),
-        'author' => array('data' => array('#theme' => 'username', '#account' => user_load($node->uid))),
+        'title' => array('data' => l($node->getTitle(), 'node/' . $node->id()) . ' ' . drupal_render($mark_build)),
+        'author' => array('data' => array('#theme' => 'username', '#account' => $node->getAuthor())),
         'replies' => array('class' => array('replies'), 'data' => $comments),
         'last updated' => array('data' => t('!time ago', array('!time' => format_interval(REQUEST_TIME - $node->last_activity)))),
       );
 
       // Adds extra RDFa markup to the $row array if the RDF module is enabled.
       if (module_exists('rdf')) {
-        $mapping = rdf_get_mapping('node', $node->type);
+        $mapping = rdf_get_mapping('node', $node->getType());
         // Adds RDFa markup to the title of the node. Because the RDFa markup is
         // added to the td tag which might contain HTML code, we specify an
         // empty datatype to ensure the value of the title read by the RDFa
diff --git a/core/modules/translation/lib/Drupal/translation/Tests/TranslationTest.php b/core/modules/translation/lib/Drupal/translation/Tests/TranslationTest.php
index 761197a..0f3056c 100644
--- a/core/modules/translation/lib/Drupal/translation/Tests/TranslationTest.php
+++ b/core/modules/translation/lib/Drupal/translation/Tests/TranslationTest.php
@@ -86,7 +86,7 @@ function testContentTranslation() {
     $languages = language_list();
     $prefixes = language_negotiation_url_prefixes();
     $this->drupalGet('node/' . $node->id() . '/translate');
-    $this->assertLinkByHref($prefixes['es'] . '/node/add/' . $node->type, 0, format_string('The "add translation" link for %language points to the localized path of the target language.', array('%language' => $languages['es']->name)));
+    $this->assertLinkByHref($prefixes['es'] . '/node/add/' . $node->getType(), 0, format_string('The "add translation" link for %language points to the localized path of the target language.', array('%language' => $languages['es']->name)));
 
     // Submit translation in Spanish.
     $node_translation_title = $this->randomName();
@@ -112,11 +112,11 @@ function testContentTranslation() {
     $edit["body[$langcode][0][value]"] = $this->randomName();
     $this->drupalPost('node/add/page', $edit, t('Save'), array('query' => array('translation' => $node->id(), 'language' => 'es')));
     $duplicate = $this->drupalGetNodeByTitle($edit["title"]);
-    $this->assertEqual($duplicate->tnid, 0, 'The node does not have a tnid.');
+    $this->assertEqual($duplicate->tnid->value, 0, 'The node does not have a tnid.');
 
     // Update original and mark translation as outdated.
     $node_body = $this->randomName();
-    $node->body[Language::LANGCODE_NOT_SPECIFIED][0]['value'] = $node_body;
+    $node->body->value = $node_body;
     $edit = array();
     $edit["body[$langcode][0][value]"] = $node_body;
     $edit['translation[retranslate]'] = TRUE;
@@ -139,7 +139,7 @@ function testContentTranslation() {
     $this->drupalGet('node/add/page');
     $this->assertFieldByXPath('//select[@name="langcode"]//option', Language::LANGCODE_NOT_SPECIFIED, 'Language neutral is available in language selection with disabled languages.');
     $node2 = $this->createPage($this->randomName(), $this->randomName(), Language::LANGCODE_NOT_SPECIFIED);
-    $this->assertRaw($node2->body[Language::LANGCODE_NOT_SPECIFIED][0]['value'], 'Language neutral content created with disabled languages available.');
+    $this->assertRaw($node2->body->value, 'Language neutral content created with disabled languages available.');
 
     // Leave just one language installed and check that the translation overview
     // page is still accessible.
@@ -171,7 +171,7 @@ function testLanguageSwitchLinks() {
     // Unpublish the Spanish translation to check that the related language
     // switch link is not shown.
     $this->drupalLogin($this->admin_user);
-    $this->drupalPost("node/$translation_es->nid/edit", array(), t('Save and unpublish'));
+    $this->drupalPost('node/' . $translation_es->id() . '/edit', array(), t('Save and unpublish'));
     $this->drupalLogin($this->translator);
     $this->assertLanguageSwitchLinks($node, $translation_es, FALSE);
 
@@ -181,7 +181,7 @@ function testLanguageSwitchLinks() {
     $edit = array('language_interface[enabled][language-url]' => FALSE);
     $this->drupalPost('admin/config/regional/language/detection', $edit, t('Save settings'));
     $this->resetCaches();
-    $this->drupalPost("node/$translation_es->nid/edit", array(), t('Save and publish'));
+    $this->drupalPost('node/' . $translation_es->id() . '/edit', array(), t('Save and publish'));
     $this->drupalLogin($this->translator);
     $this->assertLanguageSwitchLinks($node, $translation_es, TRUE, 'node');
   }
@@ -396,7 +396,7 @@ function createTranslation(EntityInterface $node, $title, $body, $langcode) {
     // Check to make sure that translation was successful.
     $translation = $this->drupalGetNodeByTitle($title);
     $this->assertTrue($translation, 'Node found in database.');
-    $this->assertTrue($translation->tnid == $node->id(), 'Translation set id correctly stored.');
+    $this->assertTrue($translation->tnid->value == $node->id(), 'Translation set id correctly stored.');
 
     return $translation;
   }
@@ -449,10 +449,9 @@ function assertLanguageSwitchLinks(NodeInterface $node, $translation, $find = TR
     }
 
     $result = TRUE;
-    $languages = language_list();
-    $page_language = $languages[$node->langcode];
-    $translation_language = $languages[$translation->langcode];
-    $url = url("node/$translation->nid", array('language' => $translation_language));
+    $page_language = $node->language();
+    $translation_language = $translation->language();
+    $url = url('node/' . $translation->id(), array('language' => $translation_language));
 
     $this->drupalGet('node/' . $node->id(), array('language' => $page_language));
 
diff --git a/core/modules/translation/translation.module b/core/modules/translation/translation.module
index 5846ca2..5a2931e 100644
--- a/core/modules/translation/translation.module
+++ b/core/modules/translation/translation.module
@@ -87,8 +87,8 @@ function translation_menu() {
  *
  * @see translation_menu()
  */
-function _translation_tab_access($node) {
-  if ($node->langcode != Language::LANGCODE_NOT_SPECIFIED && translation_supported_type($node->type) && node_access('view', $node)) {
+function _translation_tab_access(NodeInterface $node) {
+  if ($node->language()->id != Language::LANGCODE_NOT_SPECIFIED && translation_supported_type($node->getType()) && node_access('view', $node)) {
     return translation_user_can_translate_node($node);
   }
   return FALSE;
@@ -154,7 +154,7 @@ function translation_user_can_translate_node($node, $account = NULL) {
   if (empty($account)) {
     $account = $GLOBALS['user'];
   }
-  return node_access('view', $node, $account) && (user_access('translate all content', $account) || ($node->uid == $account->id() && user_access('translate own content', $account)));
+  return node_access('view', $node, $account) && (user_access('translate all content', $account) || ($node->getAuthorId() == $account->id() && user_access('translate own content', $account)));
 }
 
 /**
@@ -199,33 +199,33 @@ function translation_node_type_language_translation_enabled_validate($element, &
  */
 function translation_form_node_form_alter(&$form, &$form_state) {
   $node = $form_state['controller']->getEntity();
-  if (translation_supported_type($node->type)) {
+  if (translation_supported_type($node->getType())) {
     if (!empty($node->translation_source)) {
       // We are creating a translation. Add values and lock language field.
       $form['translation_source'] = array('#type' => 'value', '#value' => $node->translation_source);
       $form['langcode']['#disabled'] = TRUE;
     }
-    elseif (!$node->isNew() && !empty($node->tnid)) {
+    elseif (!$node->isNew() && $node->tnid->value) {
       // Disable languages for existing translations, so it is not possible
       // to switch this node to some language which is already in the
       // translation set. Also remove the language neutral option.
       unset($form['langcode']['#options'][Language::LANGCODE_NOT_SPECIFIED]);
-      foreach (translation_node_get_translations($node->tnid) as $langcode => $translation) {
+      foreach (translation_node_get_translations($node->tnid->value) as $langcode => $translation) {
         if ($translation->nid != $node->id()) {
           unset($form['langcode']['#options'][$langcode]);
         }
       }
       // Add translation values and workflow options.
-      $form['tnid'] = array('#type' => 'value', '#value' => $node->tnid);
+      $form['tnid'] = array('#type' => 'value', '#value' => $node->tnid->value);
       $form['translation'] = array(
         '#type' => 'details',
         '#title' => t('Translation settings'),
         '#access' => translation_user_can_translate_node($node),
-        '#collapsed' => !$node->translate,
+        '#collapsed' => !$node->translate->value,
         '#tree' => TRUE,
         '#weight' => 30,
       );
-      if ($node->tnid == $node->id()) {
+      if ($node->tnid->value == $node->id()) {
         // This is the source node of the translation.
         $form['translation']['retranslate'] = array(
           '#type' => 'checkbox',
@@ -239,7 +239,7 @@ function translation_form_node_form_alter(&$form, &$form_state) {
         $form['translation']['status'] = array(
           '#type' => 'checkbox',
           '#title' => t('This translation needs to be updated'),
-          '#default_value' => $node->translate,
+          '#default_value' => $node->translate->value,
           '#description' => t('When this option is checked, this translation needs to be updated because the source post has changed. Uncheck when the translation is up to date again.'),
         );
       }
@@ -257,7 +257,7 @@ function translation_form_node_form_alter(&$form, &$form_state) {
 function translation_node_view(EntityInterface $node, EntityDisplay $display, $view_mode) {
   // If the site has no translations or is not multilingual we have no content
   // translation links to display.
-  if (isset($node->tnid) && language_multilingual() && $translations = translation_node_get_translations($node->tnid)) {
+  if ($node->tnid->value && language_multilingual() && $translations = translation_node_get_translations($node->tnid->value)) {
     $languages = language_list(Language::STATE_ALL);
 
     // There might be a language provider enabled defining custom language
@@ -272,7 +272,7 @@ function translation_node_view(EntityInterface $node, EntityDisplay $display, $v
 
     foreach ($translations as $langcode => $translation) {
       // Do not show links to the same node or to unpublished translations.
-      if ($translation->status && isset($languages[$langcode]) && $langcode != $node->langcode) {
+      if ($translation->status && isset($languages[$langcode]) && $langcode != $node->language()->id) {
         $key = "translation_$langcode";
 
         if (isset($custom_links->links[$langcode])) {
@@ -313,7 +313,7 @@ function translation_node_prepare_form(NodeInterface $node, $form_display, $oper
   $translation = $query->get('translation');
   $target = $query->get('target');
   // Only act if we are dealing with a content type supporting translations.
-  if (translation_supported_type($node->type) &&
+  if (translation_supported_type($node->getType()) &&
     // And it's a new node.
     $node->isNew() &&
     // And the request variables are set properly.
@@ -325,16 +325,16 @@ function translation_node_prepare_form(NodeInterface $node, $form_display, $oper
 
     $language_list = language_list();
     $langcode = $target;
-    if (!isset($language_list[$langcode]) || ($source_node->langcode == $langcode)) {
+    if (!isset($language_list[$langcode]) || ($source_node->language()->id == $langcode)) {
       // If not supported language, or same language as source node, break.
       return;
     }
 
     // Ensure we don't have an existing translation in this language.
-    if (!empty($source_node->tnid)) {
-      $translations = translation_node_get_translations($source_node->tnid);
+    if (!empty($source_node->tnid->value)) {
+      $translations = translation_node_get_translations($source_node->tnid->value);
       if (isset($translations[$langcode])) {
-        drupal_set_message(t('A translation of %title in %language already exists, a new %type will be created instead of a translation.', array('%title' => $source_node->label(), '%language' => $language_list[$langcode]->name, '%type' => $node->type)), 'error');
+        drupal_set_message(t('A translation of %title in %language already exists, a new %type will be created instead of a translation.', array('%title' => $source_node->label(), '%language' => $language_list[$langcode]->name, '%type' => $node->getType())), 'error');
         return;
       }
     }
@@ -342,7 +342,7 @@ function translation_node_prepare_form(NodeInterface $node, $form_display, $oper
     // Populate fields based on source node.
     $node->langcode = $langcode;
     $node->translation_source = $source_node;
-    $node->title = $source_node->title;
+    $node->title = $source_node->getTitle();
   }
 }
 
@@ -351,11 +351,11 @@ function translation_node_prepare_form(NodeInterface $node, $form_display, $oper
  */
 function translation_node_insert(EntityInterface $node) {
   // Only act if we are dealing with a content type supporting translations.
-  if (translation_supported_type($node->type)) {
+  if (translation_supported_type($node->getType())) {
     if (!empty($node->translation_source)) {
-      if ($node->translation_source->tnid) {
+      if ($node->translation_source->tnid->value) {
         // Add node to existing translation set.
-        $tnid = $node->translation_source->tnid;
+        $tnid = $node->translation_source->tnid->value;
       }
       else {
         // Create new translation set, using nid from the source node.
@@ -384,14 +384,14 @@ function translation_node_insert(EntityInterface $node) {
 /**
  * Implements hook_node_update().
  */
-function translation_node_update(EntityInterface $node) {
+function translation_node_update(NodeInterface $node) {
   // Only act if we are dealing with a content type supporting translations.
-  if (translation_supported_type($node->type)) {
-    if (isset($node->translation) && $node->translation && !empty($node->langcode) && $node->tnid) {
+  if (translation_supported_type($node->getType())) {
+    if (isset($node->translation) && $node->translation && $node->tnid->value) {
       // Update translation information.
       db_update('node')
         ->fields(array(
-          'tnid' => $node->tnid,
+          'tnid' => $node->tnid->value,
           'translate' => $node->translation['status'],
         ))
         ->condition('nid', $node->id())
@@ -401,7 +401,7 @@ function translation_node_update(EntityInterface $node) {
         db_update('node')
           ->fields(array('translate' => 1))
           ->condition('nid', $node->id(), '<>')
-          ->condition('tnid', $node->tnid)
+          ->condition('tnid', $node->tnid->value)
           ->execute();
       }
     }
@@ -413,11 +413,11 @@ function translation_node_update(EntityInterface $node) {
  *
  * Ensures that duplicate translations can't be created for the same source.
  */
-function translation_node_validate(EntityInterface $node, $form, &$form_state) {
+function translation_node_validate(NodeInterface $node, $form, &$form_state) {
   // Only act on translatable nodes with a tnid or translation_source.
   $form_node = $form_state['controller']->getEntity();
-  if (translation_supported_type($node->type) && (!empty($node->tnid) || ($form_node->translation_source && $form_node->translation_source->id()))) {
-    $tnid = !empty($node->tnid) ? $node->tnid : $form_node->translation_source->id();
+  if (translation_supported_type($node->getType()) && ($node->tnid->value || ($form_node->translation_source && $form_node->translation_source->id()))) {
+    $tnid = $node->tnid->value ?: $form_node->translation_source->id();
     $translations = translation_node_get_translations($tnid);
     if (isset($translations[$node->language()->id]) && $translations[$node->language()->id]->nid != $node->id()) {
       form_set_error('langcode', t('There is already a translation in this language.'));
@@ -428,9 +428,9 @@ function translation_node_validate(EntityInterface $node, $form, &$form_state) {
 /**
  * Implements hook_node_predelete().
  */
-function translation_node_predelete(EntityInterface $node) {
+function translation_node_predelete(NodeInterface $node) {
   // Only act if we are dealing with a content type supporting translations.
-  if (translation_supported_type($node->type)) {
+  if (translation_supported_type($node->getType())) {
     translation_remove_from_set($node);
   }
 }
@@ -441,17 +441,17 @@ function translation_node_predelete(EntityInterface $node) {
  * @param $node
  *   A node entity.
  */
-function translation_remove_from_set($node) {
-  if (isset($node->tnid)) {
+function translation_remove_from_set(NodeInterface $node) {
+  if ($node->tnid->value) {
     $query = db_update('node')
       ->fields(array(
         'tnid' => 0,
         'translate' => 0,
       ));
-    if (db_query('SELECT COUNT(*) FROM {node} WHERE tnid = :tnid', array(':tnid' => $node->tnid))->fetchField() == 1) {
+    if (db_query('SELECT COUNT(*) FROM {node} WHERE tnid = :tnid', array(':tnid' => $node->tnid->value))->fetchField() == 1) {
       // There is only one node left in the set: remove the set altogether.
       $query
-        ->condition('tnid', $node->tnid)
+        ->condition('tnid', $node->tnid->value)
         ->execute();
     }
     else {
@@ -461,11 +461,11 @@ function translation_remove_from_set($node) {
 
       // If the node being removed was the source of the translation set,
       // we pick a new source - preferably one that is up to date.
-      if ($node->tnid == $node->id()) {
-        $new_tnid = db_query('SELECT nid FROM {node} WHERE tnid = :tnid ORDER BY translate ASC, nid ASC', array(':tnid' => $node->tnid))->fetchField();
+      if ($node->tnid->value == $node->id()) {
+        $new_tnid = db_query('SELECT nid FROM {node} WHERE tnid = :tnid ORDER BY translate ASC, nid ASC', array(':tnid' => $node->tnid->value))->fetchField();
         db_update('node')
           ->fields(array('tnid' => $new_tnid))
-          ->condition('tnid', $node->tnid)
+          ->condition('tnid', $node->tnid->value)
           ->execute();
       }
     }
@@ -531,8 +531,8 @@ function translation_supported_type($type) {
 function translation_path_get_translations($path) {
   $paths = array();
   // Check for a node related path, and for its translations.
-  if ((preg_match("!^node/(\d+)(/.+|)$!", $path, $matches)) && ($node = node_load((int) $matches[1])) && !empty($node->tnid)) {
-    foreach (translation_node_get_translations($node->tnid) as $language => $translation_node) {
+  if ((preg_match("!^node/(\d+)(/.+|)$!", $path, $matches)) && ($node = node_load((int) $matches[1])) && $node->tnid->value) {
+    foreach (translation_node_get_translations($node->tnid->value) as $language => $translation_node) {
       $paths[$language] = 'node/' . $translation_node->id() . $matches[2];
     }
   }
@@ -549,24 +549,24 @@ function translation_language_switch_links_alter(array &$links, $type, $path) {
   if ($type == $language_type && preg_match("!^node/(\d+)(/.+|)!", $path, $matches)) {
     $node = node_load((int) $matches[1]);
 
-    if (empty($node->tnid)) {
+    if (empty($node->tnid->value)) {
       // If the node cannot be found nothing needs to be done. If it does not
       // have translations it might be a language neutral node, in which case we
       // must leave the language switch links unaltered. This is true also for
       // nodes not having translation support enabled.
-      if (empty($node) || $node->langcode == Language::LANGCODE_NOT_SPECIFIED || !translation_supported_type($node->type)) {
+      if (empty($node) || $node->language()->id == Language::LANGCODE_NOT_SPECIFIED || !translation_supported_type($node->getType())) {
         return;
       }
-      $translations = array($node->langcode => $node);
+      $translations = array($node->language()->id => $node);
     }
     else {
-      $translations = translation_node_get_translations($node->tnid);
+      $translations = translation_node_get_translations($node->tnid->value);
     }
 
     foreach ($links as $langcode => $link) {
       if (isset($translations[$langcode]) && $translations[$langcode]->status) {
         // Translation in a different node.
-        $nid = $translations[$langcode]->nid;
+        $nid = $translations[$langcode] instanceof EntityInterface ? $translations[$langcode]->id() : $translations[$langcode]->nid;
         $links[$langcode]['href'] = 'node/' . $nid  . $matches[2];
       }
       else {
diff --git a/core/modules/translation/translation.pages.inc b/core/modules/translation/translation.pages.inc
index 62d2ada..b5ec442 100644
--- a/core/modules/translation/translation.pages.inc
+++ b/core/modules/translation/translation.pages.inc
@@ -22,15 +22,15 @@
 function translation_node_overview(EntityInterface $node) {
   include_once DRUPAL_ROOT . '/core/includes/language.inc';
 
-  if ($node->tnid) {
+  if ($node->tnid->value) {
     // Already part of a set, grab that set.
-    $tnid = $node->tnid;
-    $translations = translation_node_get_translations($node->tnid);
+    $tnid = $node->tnid->value;
+    $translations = translation_node_get_translations($node->tnid->value);
   }
   else {
     // We have no translation source nid, this could be a new set, emulate that.
-    $tnid = $node->nid;
-    $translations = array($node->langcode => $node);
+    $tnid = $node->id();
+    $translations = array($node->language()->id => $node);
   }
 
   $type = Drupal::config('translation.settings')->get('language_type');
@@ -42,7 +42,8 @@ function translation_node_overview(EntityInterface $node) {
     if (isset($translations[$langcode])) {
       // Existing translation in the translation set: display status.
       // We load the full node to check whether the user can edit it.
-      $translation_node = node_load($translations[$langcode]->nid);
+      $nid = $translations[$langcode] instanceof EntityInterface ? $translations[$langcode]->id() : $translations[$langcode]->nid;
+      $translation_node = node_load($nid);
       $path = 'node/' . $translation_node->id();
       $links = language_negotiation_get_switch_links($type, $path);
       $title = empty($links->links[$langcode]['href']) ? l($translation_node->label(), $path) : l($translation_node->label(), $links->links[$langcode]['href'], $links->links[$langcode]);
@@ -55,8 +56,8 @@ function translation_node_overview(EntityInterface $node) {
           ) + $links->links[$langcode];
         }
       }
-      $status = $translation_node->status ? t('Published') : t('Not published');
-      $status .= $translation_node->translate ? ' - <span class="marker">' . t('outdated') . '</span>' : '';
+      $status = $translation_node->isPublished() ? t('Published') : t('Not published');
+      $status .= $translation_node->translate->value ? ' - <span class="marker">' . t('outdated') . '</span>' : '';
       if ($translation_node->id() == $tnid) {
         $language_name = t('<strong>@language_name</strong> (source)', array('@language_name' => $language_name));
       }
@@ -65,7 +66,7 @@ function translation_node_overview(EntityInterface $node) {
       // No such translation in the set yet: help user to create it.
       $title = t('n/a');
       if (node_access('create', $node)) {
-        $path = 'node/add/' . $node->type;
+        $path = 'node/add/' . $node->getType();
         $links = language_negotiation_get_switch_links($type, $path);
         $query = array('query' => array('translation' => $node->id(), 'target' => $langcode));
         if (!empty($links->links[$langcode]['href'])) {
diff --git a/core/modules/user/lib/Drupal/user/Plugin/views/argument_default/User.php b/core/modules/user/lib/Drupal/user/Plugin/views/argument_default/User.php
index f58c641..42d39a7 100644
--- a/core/modules/user/lib/Drupal/user/Plugin/views/argument_default/User.php
+++ b/core/modules/user/lib/Drupal/user/Plugin/views/argument_default/User.php
@@ -56,7 +56,7 @@ public function getArgument() {
       foreach (range(1, 3) as $i) {
         $node = menu_get_object('node', $i);
         if (!empty($node)) {
-          return $node->uid;
+          return $node->getAuthorId();
         }
       }
     }
@@ -69,7 +69,7 @@ public function getArgument() {
       if (arg(0) == 'node' && is_numeric(arg(1))) {
         $node = node_load(arg(1));
         if ($node) {
-          return $node->uid;
+          return $node->getAuthorId();
         }
       }
     }
diff --git a/core/modules/user/lib/Drupal/user/Tests/UserCancelTest.php b/core/modules/user/lib/Drupal/user/Tests/UserCancelTest.php
index 051499e..8ae5b5a 100644
--- a/core/modules/user/lib/Drupal/user/Tests/UserCancelTest.php
+++ b/core/modules/user/lib/Drupal/user/Tests/UserCancelTest.php
@@ -57,7 +57,7 @@ function testUserCancelWithoutPermission() {
 
     // Confirm user's content has not been altered.
     $test_node = node_load($node->id(), TRUE);
-    $this->assertTrue(($test_node->uid == $account->id() && $test_node->status == 1), 'Node of the user has not been altered.');
+    $this->assertTrue(($test_node->getAuthorId() == $account->id() && $test_node->isPublished()), 'Node of the user has not been altered.');
   }
 
   /**
@@ -138,7 +138,7 @@ function testUserCancelInvalid() {
 
     // Confirm user's content has not been altered.
     $test_node = node_load($node->id(), TRUE);
-    $this->assertTrue(($test_node->uid == $account->id() && $test_node->status == 1), 'Node of the user has not been altered.');
+    $this->assertTrue(($test_node->getAuthorId() == $account->id() && $test_node->isPublished()), 'Node of the user has not been altered.');
   }
 
   /**
@@ -212,9 +212,9 @@ function testUserBlockUnpublish() {
 
     // Confirm user's content has been unpublished.
     $test_node = node_load($node->id(), TRUE);
-    $this->assertTrue($test_node->status == 0, 'Node of the user has been unpublished.');
-    $test_node = node_revision_load($node->vid);
-    $this->assertTrue($test_node->status == 0, 'Node revision of the user has been unpublished.');
+    $this->assertFalse($test_node->isPublished(), 'Node of the user has been unpublished.');
+    $test_node = node_revision_load($node->getRevisionId());
+    $this->assertFalse($test_node->isPublished(), 'Node revision of the user has been unpublished.');
 
     // Confirm that the confirmation message made it through to the end user.
     $this->assertRaw(t('%name has been disabled.', array('%name' => $account->getUsername())), "Confirmation message displayed to user.");
@@ -238,7 +238,7 @@ function testUserAnonymize() {
     // Create a node with two revisions, the initial one belonging to the
     // cancelling user.
     $revision_node = $this->drupalCreateNode(array('uid' => $account->id()));
-    $revision = $revision_node->vid;
+    $revision = $revision_node->getRevisionId();
     $settings = get_object_vars($revision_node);
     $settings['revision'] = 1;
     $settings['uid'] = 1; // Set new/current revision to someone else.
@@ -261,11 +261,11 @@ function testUserAnonymize() {
 
     // Confirm that user's content has been attributed to anonymous user.
     $test_node = node_load($node->id(), TRUE);
-    $this->assertTrue(($test_node->uid == 0 && $test_node->status == 1), 'Node of the user has been attributed to anonymous user.');
+    $this->assertTrue(($test_node->getAuthorId() == 0 && $test_node->isPublished()), 'Node of the user has been attributed to anonymous user.');
     $test_node = node_revision_load($revision, TRUE);
-    $this->assertTrue(($test_node->revision_uid == 0 && $test_node->status == 1), 'Node revision of the user has been attributed to anonymous user.');
+    $this->assertTrue(($test_node->getRevisionAuthor()->id() == 0 && $test_node->isPublished()), 'Node revision of the user has been attributed to anonymous user.');
     $test_node = node_load($revision_node->id(), TRUE);
-    $this->assertTrue(($test_node->uid != 0 && $test_node->status == 1), "Current revision of the user's node was not attributed to anonymous user.");
+    $this->assertTrue(($test_node->getAuthorId() != 0 && $test_node->isPublished()), "Current revision of the user's node was not attributed to anonymous user.");
 
     // Confirm that the confirmation message made it through to the end user.
     $this->assertRaw(t('%name has been deleted.', array('%name' => $account->getUsername())), "Confirmation message displayed to user.");
@@ -304,7 +304,7 @@ function testUserDelete() {
     // Create a node with two revisions, the initial one belonging to the
     // cancelling user.
     $revision_node = $this->drupalCreateNode(array('uid' => $account->id()));
-    $revision = $revision_node->vid;
+    $revision = $revision_node->getRevisionId();
     $settings = get_object_vars($revision_node);
     $settings['revision'] = 1;
     $settings['uid'] = 1; // Set new/current revision to someone else.
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 2c0e2d3..82267b2 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -168,14 +168,14 @@ function user_label($entity_type, $entity) {
 function user_attach_accounts(array $entities) {
   $uids = array();
   foreach ($entities as $entity) {
-    $uids[] = $entity->uid;
+    $uids[] = $entity->getAuthorId();
   }
   $uids = array_unique($uids);
   $accounts = user_load_multiple($uids);
   $anonymous = drupal_anonymous_user();
   foreach ($entities as $id => $entity) {
-    if (isset($accounts[$entity->uid])) {
-      $entities[$id]->account = $accounts[$entity->uid];
+    if (isset($accounts[$entity->getAuthorId()])) {
+      $entities[$id]->account = $accounts[$entity->getAuthorId()];
     }
     else {
       $entities[$id]->account = $anonymous;
@@ -1966,7 +1966,7 @@ function user_node_load($nodes, $types) {
   // Build an array of all uids for node authors, keyed by nid.
   $uids = array();
   foreach ($nodes as $nid => $node) {
-    $uids[$nid] = $node->uid;
+    $uids[$nid] = $node->getAuthorId();
   }
 
   // Fetch name and data for these users.
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/argument/Date.php b/core/modules/views/lib/Drupal/views/Plugin/views/argument/Date.php
index fefd5d1..868c20d 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/argument/Date.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/argument/Date.php
@@ -77,10 +77,10 @@ public function getDefaultArgument($raw = FALSE) {
         return parent::getDefaultArgument();
       }
       elseif ($this->options['default_argument_type'] == 'node_created') {
-        return date($this->argFormat, $node->created);
+        return date($this->argFormat, $node->getCreatedTime());
       }
       elseif ($this->options['default_argument_type'] == 'node_changed') {
-        return date($this->argFormat, $node->changed);
+        return date($this->argFormat, $node->getChangedTime());
       }
     }
 
diff --git a/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php b/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php
index 066f518..3306755 100644
--- a/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php
@@ -97,7 +97,7 @@ protected function setUp() {
 
       $node = $this->drupalCreateNode($values);
 
-      search_index($node->id(), 'node', $node->body[Language::LANGCODE_NOT_SPECIFIED][0]['value'], Language::LANGCODE_NOT_SPECIFIED);
+      search_index($node->id(), 'node', $node->body->value, Language::LANGCODE_NOT_SPECIFIED);
 
       $comment = array(
         'uid' => $user->id(),
diff --git a/core/themes/bartik/templates/node.html.twig b/core/themes/bartik/templates/node.html.twig
index d8af3d5..d45cc55 100644
--- a/core/themes/bartik/templates/node.html.twig
+++ b/core/themes/bartik/templates/node.html.twig
@@ -5,15 +5,16 @@
  *
  * Available variables:
  * - node: Full node entity.
- *   - type: The type of the node, for example, "page" or "article".
- *   - uid: The user ID of the node author.
- *   - created: Formatted creation date. Preprocess functions can reformat it by
- *     calling format_date() with the desired parameters on
- *     $variables['node']->created.
- *   - promote: Whether the node is promoted to the front page.
+ *   - id: The node ID
+ *   - bundle: The type of the node, for example, "page" or "article".
+ *   - authorid: The user ID of the node author.
+ *   - createdtime: Formatted creation date. Preprocess functions can reformat
+       it by calling format_date() with the desired parameters on
+ *     $variables['node']->getCreatedTime().
+ *   - promoted: Whether the node is promoted to the front page.
  *   - sticky: Whether the node is 'sticky'. Sticky nodes are ordered above
  *     other non-sticky nodes in teaser listings
- *   - status: Whether the node is published.
+ *   - published: Whether the node is published.
  *   - comment: A value representing the comment status of the current node. May
  *     be one of the following:
  *     - 0: The comment form and any existing comments are hidden.
@@ -77,7 +78,7 @@
  * @ingroup themeable
  */
 #}
-<article id="node-{{ node.nid }}" class="{{ attributes.class}} clearfix"{{ attributes }} role="article">
+<article id="node-{{ node.id }}" class="{{ attributes.class}} clearfix"{{ attributes }} role="article">
 
   <header>
     {{ title_prefix }}
diff --git a/core/themes/seven/seven.theme b/core/themes/seven/seven.theme
index a73fb56..5735f29 100644
--- a/core/themes/seven/seven.theme
+++ b/core/themes/seven/seven.theme
@@ -172,20 +172,20 @@ function seven_form_node_form_alter(&$form, &$form_state) {
     'published' => array(
       '#type' => 'item',
       '#wrapper_attributes' => array('class' => array('published')),
-      '#markup' => !empty($node->status) ? t('Published') : t('Not published'),
+      '#markup' => $node->isPublished() ? t('Published') : t('Not published'),
       '#access' => !$node->isNew(),
     ),
     'changed' => array(
       '#type' => 'item',
       '#wrapper_attributes' => array('class' => array('changed', 'container-inline')),
       '#title' => t('Last saved'),
-      '#markup' => !$node->isNew() ? format_date($node->changed, 'short') : t('Not saved yet'),
+      '#markup' => !$node->isNew() ? format_date($node->getChangedTime(), 'short') : t('Not saved yet'),
     ),
     'author' => array(
       '#type' => 'item',
       '#wrapper_attributes' => array('class' => array('author', 'container-inline')),
       '#title' => t('Author'),
-      '#markup' => user_format_name(user_load($node->uid)),
+      '#markup' => $node->getAuthor()->getUsername(),
     ),
   );
   $form['revision_information']['#type'] = 'container';
