commit 74850bbff1b52e986a7712398b54555b2e91e69e
Author: Bart Feenstra <bart@mynameisbart.com>
Date:   Fri Jan 17 08:57:55 2014 +0100

    foo

diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index f94ecb2..46dc074 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -18,6 +18,7 @@
 use Drupal\field\FieldInstanceInterface;
 use Drupal\field\FieldInterface;
 use Drupal\file\FileInterface;
+use Drupal\user\EntityOwnerInterface;
 
 /**
  * Comments are displayed in a flat list - expanded.
@@ -905,18 +906,22 @@ function comment_entity_insert(EntityInterface $entity) {
       'last_comment_uid',
       'comment_count'
     ));
+    $execute_query = FALSE;
     foreach ($fields as $field_name => $detail) {
       // Skip fields that entity does not have.
       if (!$entity->hasField($field_name)) {
         continue;
       }
       // There is at least one comment field, the query needs to be executed.
-      // @todo Use $entity->getAuthorId() after https://drupal.org/node/2078387
-      if ($entity->hasField('uid')) {
-        $last_comment_uid = $entity->get('uid')->value;
+      $execute_query = TRUE;
+      // Get the user ID from the entity if it is set, or default to the
+      // currently logged in user.
+      if ($entity instanceof EntityOwnerInterface) {
+        $last_comment_uid = $entity->getOwnerId();
       }
-      else {
-        // Default to current user when entity does not have a uid property.
+      if (!isset($last_comment_uid)) {
+        // Default to current user when entity does not implement
+        // EntityOwnerInterface or author is not set.
         $last_comment_uid = \Drupal::currentUser()->id();
       }
       // Default to REQUEST_TIME when entity does not have a changed property.
@@ -935,7 +940,9 @@ function comment_entity_insert(EntityInterface $entity) {
         'comment_count' => 0,
       ));
     }
-    $query->execute();
+    if ($execute_query) {
+      $query->execute();
+    }
   }
 }
 
@@ -1061,9 +1068,10 @@ function comment_user_cancel($edit, $account, $method) {
       break;
 
     case 'user_cancel_reassign':
+      /** @var \Drupal\comment\CommentInterface[] $comments */
       $comments = entity_load_multiple_by_properties('comment', array('uid' => $account->id()));
       foreach ($comments as $comment) {
-        $comment->uid->target_id = 0;
+        $comment->setOwnerId(0);
         $comment->save();
       }
       break;
@@ -1257,7 +1265,7 @@ function comment_preview(CommentInterface $comment, array &$form_state) {
     }
 
     if (!empty($account) && $account->isAuthenticated()) {
-      $comment->uid->target_id = $account->id();
+      $comment->setOwner($account);
       $comment->name->value = check_plain($account->getUsername());
     }
     else {
@@ -1328,7 +1336,7 @@ function comment_preprocess_block(&$variables) {
  */
 function comment_prepare_author(CommentInterface $comment) {
   // The account has been pre-loaded by CommentViewBuilder::buildContent().
-  $account = $comment->uid->entity;
+  $account = $comment->getOwner();
   if (empty($account->uid->value)) {
     $account = entity_create('user', array('uid' => 0, 'name' => $comment->name->value, 'homepage' => $comment->homepage->value));
   }
@@ -1346,6 +1354,7 @@ function comment_prepare_author(CommentInterface $comment) {
  *     Array keys: #comment, #commented_entity.
  */
 function template_preprocess_comment(&$variables) {
+  /** @var \Drupal\comment\CommentInterface $comment */
   $comment = $variables['elements']['#comment'];
   $commented_entity = entity_load($comment->entity_type->value, $comment->entity_id->value);
   $variables['comment'] = $comment;
@@ -1447,12 +1456,11 @@ function template_preprocess_comment(&$variables) {
   if ($variables['status'] != 'published') {
     $variables['attributes']['class'][] = $variables['status'];
   }
-  if (!$comment->uid->target_id) {
+  if (!$comment->getOwnerId()) {
     $variables['attributes']['class'][] = 'by-anonymous';
   }
   else {
-    // @todo Use $entity->getAuthorId() after https://drupal.org/node/2078387
-    if ($commented_entity->hasField('uid') && $comment->uid->target_id == $commented_entity->get('uid')->value) {
+    if ($commented_entity instanceof EntityOwnerInterface && $comment->getOwnerId() == $commented_entity->getOwnerId()) {
       $variables['attributes']['class'][] = 'by-' . $commented_entity->entityType() . '-author';
     }
   }
@@ -1460,7 +1468,7 @@ function template_preprocess_comment(&$variables) {
   $variables['attributes']['class'][] = 'clearfix';
 
   // Add comment author user ID. Necessary for the comment-by-viewer library.
-  $variables['attributes']['data-comment-user-id'] = $comment->uid->value;
+  $variables['attributes']['data-comment-user-id'] = $comment->getOwnerId();
 
   $variables['content_attributes']['class'][] = 'content';
 }
diff --git a/core/modules/comment/comment.tokens.inc b/core/modules/comment/comment.tokens.inc
index eab4d3e..b0c83a3 100644
--- a/core/modules/comment/comment.tokens.inc
+++ b/core/modules/comment/comment.tokens.inc
@@ -127,6 +127,7 @@ function comment_tokens($type, $tokens, array $data = array(), array $options =
   $replacements = array();
 
   if ($type == 'comment' && !empty($data['comment'])) {
+    /** @var \Drupal\comment\CommentInterface $comment */
     $comment = $data['comment'];
 
     foreach ($tokens as $name => $original) {
@@ -142,13 +143,15 @@ function comment_tokens($type, $tokens, array $data = array(), array $options =
           break;
 
         case 'name':
-          $name = ($comment->uid->target_id == 0) ? \Drupal::config('user.settings')->get('anonymous') : $comment->name->value;
+          $name = ($comment->getOwnerId() == 0) ? \Drupal::config('user.settings')->get('anonymous') : $comment->name->value;
           $replacements[$original] = $sanitize ? filter_xss($name) : $name;
           break;
 
         case 'mail':
-          if ($comment->uid->target_id != 0) {
-            $mail = $comment->uid->entity->getEmail();
+          // Check identicality, because getOwnerId() returns NULL if there is no
+          // ID, which evaluates to 0.
+          if ($comment->getOwnerId() !== 0) {
+            $mail = $comment->getOwner()->getEmail();
           }
           else {
             $mail = $comment->mail->value;
@@ -244,7 +247,7 @@ function comment_tokens($type, $tokens, array $data = array(), array $options =
       $replacements += $token_service->generate('comment', $parent_tokens, array('comment' => $parent), $options);
     }
 
-    if (($author_tokens = $token_service->findwithPrefix($tokens, 'author')) && $account = $comment->uid->entity) {
+    if (($author_tokens = $token_service->findwithPrefix($tokens, 'author')) && $account = $comment->getOwner()) {
       $replacements += $token_service->generate('user', $author_tokens, array('user' => $account), $options);
     }
   }
diff --git a/core/modules/comment/lib/Drupal/comment/CommentAccessController.php b/core/modules/comment/lib/Drupal/comment/CommentAccessController.php
index ce25a1c..fe03f3b 100644
--- a/core/modules/comment/lib/Drupal/comment/CommentAccessController.php
+++ b/core/modules/comment/lib/Drupal/comment/CommentAccessController.php
@@ -22,13 +22,14 @@ class CommentAccessController extends EntityAccessController {
    * {@inheritdoc}
    */
   protected function checkAccess(EntityInterface $entity, $operation, $langcode, AccountInterface $account) {
+    /** @var \Drupal\Core\Entity\EntityInterface|\Drupal\user\EntityOwnerInterface $entity */
     switch ($operation) {
       case 'view':
         return user_access('access comments', $account);
         break;
 
       case 'update':
-        return ($account->id() && $account->id() == $entity->uid->value && $entity->status->value == CommentInterface::PUBLISHED && user_access('edit own comments', $account)) || user_access('administer comments', $account);
+        return ($account->id() && $account->id() == $entity->getOwnerId() && $entity->status->value == CommentInterface::PUBLISHED && user_access('edit own comments', $account)) || user_access('administer comments', $account);
         break;
 
       case 'delete':
diff --git a/core/modules/comment/lib/Drupal/comment/CommentFormController.php b/core/modules/comment/lib/Drupal/comment/CommentFormController.php
index 0adb4fc..56ac916 100644
--- a/core/modules/comment/lib/Drupal/comment/CommentFormController.php
+++ b/core/modules/comment/lib/Drupal/comment/CommentFormController.php
@@ -77,6 +77,7 @@ protected function init(array &$form_state) {
    * Overrides Drupal\Core\Entity\EntityFormController::form().
    */
   public function form(array $form, array &$form_state) {
+    /** @var \Drupal\comment\CommentInterface $comment */
     $comment = $this->entity;
     $entity = $this->entityManager->getStorageController($comment->entity_type->value)->load($comment->entity_id->value);
     $field_name = $comment->field_name->value;
@@ -212,7 +213,7 @@ public function form(array $form, array &$form_state) {
     // Used for conditional validation of author fields.
     $form['is_anonymous'] = array(
       '#type' => 'value',
-      '#value' => ($comment->id() ? !$comment->uid->target_id : $this->currentUser->isAnonymous()),
+      '#value' => ($comment->id() ? !$comment->getOwnerId() : $this->currentUser->isAnonymous()),
     );
 
     // Add internal comment properties.
@@ -313,13 +314,14 @@ public function buildEntity(array $form, array &$form_state) {
    * Overrides Drupal\Core\Entity\EntityFormController::submit().
    */
   public function submit(array $form, array &$form_state) {
+    /** @var \Drupal\comment\CommentInterface $comment */
     $comment = parent::submit($form, $form_state);
 
     // If the comment was posted by a registered user, assign the author's ID.
     // @todo Too fragile. Should be prepared and stored in comment_form()
     // already.
     if (!$comment->is_anonymous && !empty($comment->name->value) && ($account = user_load_by_name($comment->name->value))) {
-      $comment->uid->target_id = $account->id();
+      $comment->setOwner($account);
     }
     // If the comment was posted by an anonymous user and no author name was
     // required, use "Anonymous" by default.
diff --git a/core/modules/comment/lib/Drupal/comment/CommentInterface.php b/core/modules/comment/lib/Drupal/comment/CommentInterface.php
index 28ec9fb..0e55501 100644
--- a/core/modules/comment/lib/Drupal/comment/CommentInterface.php
+++ b/core/modules/comment/lib/Drupal/comment/CommentInterface.php
@@ -8,12 +8,13 @@
 namespace Drupal\comment;
 
 use Drupal\Core\Entity\ContentEntityInterface;
+use Drupal\user\EntityOwnerInterface;
 use Drupal\Core\Entity\EntityChangedInterface;
 
 /**
  * Provides an interface defining a comment entity.
  */
-interface CommentInterface extends ContentEntityInterface, EntityChangedInterface {
+interface CommentInterface extends ContentEntityInterface, EntityChangedInterface, EntityOwnerInterface {
 
   /**
    * Comment is awaiting approval.
diff --git a/core/modules/comment/lib/Drupal/comment/CommentStorageController.php b/core/modules/comment/lib/Drupal/comment/CommentStorageController.php
index 82cc6e4..3ea26e6 100644
--- a/core/modules/comment/lib/Drupal/comment/CommentStorageController.php
+++ b/core/modules/comment/lib/Drupal/comment/CommentStorageController.php
@@ -10,6 +10,7 @@
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\FieldableDatabaseStorageController;
 use Drupal\Core\Entity\EntityChangedInterface;
+use Drupal\user\EntityOwnerInterface;
 
 /**
  * Defines the controller class for comments.
@@ -92,6 +93,16 @@ public function updateEntityStatistics(CommentInterface $comment) {
     else {
       // Comments do not exist.
       $entity = entity_load($comment->entity_type->value, $comment->entity_id->value);
+      // Get the user ID from the entity if it's set, or default to the
+      // currently logged in user.
+      if ($entity instanceof EntityOwnerInterface) {
+        $last_comment_uid = $entity->getOwnerId();
+      }
+      if (!isset($last_comment_uid)) {
+        // Default to current user when entity does not implement
+        // EntityOwnerInterface or author is not set.
+        $last_comment_uid = \Drupal::currentUser()->id();
+      }
       $this->database->update('comment_entity_statistics')
         ->fields(array(
           'cid' => 0,
@@ -100,10 +111,7 @@ public function updateEntityStatistics(CommentInterface $comment) {
           // REQUEST_TIME.
           'last_comment_timestamp' => ($entity instanceof EntityChangedInterface) ? $entity->getChangedTime() : REQUEST_TIME,
           'last_comment_name' => '',
-          // @todo Use $entity->getAuthorId() after https://drupal.org/node/2078387
-          // Get the user ID from the entity if it's set, or default to the
-          // currently logged in user.
-          'last_comment_uid' => $entity->hasField('uid') ? $entity->get('uid')->value : \Drupal::currentUser()->id(),
+          'last_comment_uid' => $last_comment_uid,
         ))
         ->condition('entity_id', $comment->entity_id->value)
         ->condition('entity_type', $comment->entity_type->value)
diff --git a/core/modules/comment/lib/Drupal/comment/CommentViewBuilder.php b/core/modules/comment/lib/Drupal/comment/CommentViewBuilder.php
index 5d23466..87fa2f8 100644
--- a/core/modules/comment/lib/Drupal/comment/CommentViewBuilder.php
+++ b/core/modules/comment/lib/Drupal/comment/CommentViewBuilder.php
@@ -101,7 +101,7 @@ public function buildContent(array $entities, array $displays, $view_mode, $lang
     // Pre-load associated users into cache to leverage multiple loading.
     $uids = array();
     foreach ($entities as $entity) {
-      $uids[] = $entity->uid->target_id;
+      $uids[] = $entity->getOwnerId();
     }
     $this->entityManager->getStorageController('user')->loadMultiple(array_unique($uids));
 
diff --git a/core/modules/comment/lib/Drupal/comment/Entity/Comment.php b/core/modules/comment/lib/Drupal/comment/Entity/Comment.php
index 3c8b696..7609133 100644
--- a/core/modules/comment/lib/Drupal/comment/Entity/Comment.php
+++ b/core/modules/comment/lib/Drupal/comment/Entity/Comment.php
@@ -14,6 +14,7 @@
 use Drupal\Core\Field\FieldDefinition;
 use Drupal\Core\Language\Language;
 use Drupal\Core\TypedData\DataDefinition;
+use Drupal\user\UserInterface;
 
 /**
  * Defines the comment entity class.
@@ -293,7 +294,7 @@ public function preSave(EntityStorageControllerInterface $storage_controller) {
       }
       // We test the value with '===' because we need to modify anonymous
       // users as well.
-      if ($this->uid->target_id === \Drupal::currentUser()->id() && \Drupal::currentUser()->isAuthenticated()) {
+      if ($this->getOwnerId() === \Drupal::currentUser()->id() && \Drupal::currentUser()->isAuthenticated()) {
         $this->name->value = \Drupal::currentUser()->getUsername();
       }
       // Add the values which aren't passed into the function.
@@ -467,4 +468,34 @@ public static function preCreate(EntityStorageControllerInterface $storage_contr
     }
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getOwner() {
+    return $this->get('uid')->entity;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getOwnerId() {
+    return $this->get('uid')->target_id;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setOwnerId($uid) {
+    $this->set('uid', $uid);
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setOwner(UserInterface $account) {
+    $this->set('uid', $account->id());
+    return $this;
+  }
+
 }
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentInterfaceTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentInterfaceTest.php
index 1e13ddb..5f7c735 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentInterfaceTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentInterfaceTest.php
@@ -80,7 +80,7 @@ function testCommentInterface() {
 
     // Test changing the comment author to "Anonymous".
     $comment = $this->postComment(NULL, $comment->comment_body->value, $comment->subject->value, array('name' => ''));
-    $this->assertTrue(empty($comment->name->value) && $comment->uid->target_id == 0, 'Comment author successfully changed to anonymous.');
+    $this->assertTrue(empty($comment->name->value) && $comment->getOwnerId() == 0, 'Comment author successfully changed to anonymous.');
 
     // Test changing the comment author to an unverified user.
     $random_name = $this->randomName();
@@ -92,7 +92,7 @@ function testCommentInterface() {
     // Test changing the comment author to a verified user.
     $this->drupalGet('comment/' . $comment->id() . '/edit');
     $comment = $this->postComment(NULL, $comment->comment_body->value, $comment->subject->value, array('name' => $this->web_user->getUsername()));
-    $this->assertTrue($comment->name->value == $this->web_user->getUsername() && $comment->uid->target_id == $this->web_user->id(), 'Comment author successfully changed to a registered user.');
+    $this->assertTrue($comment->name->value == $this->web_user->getUsername() && $comment->getOwnerId() == $this->web_user->id(), 'Comment author successfully changed to a registered user.');
 
     $this->drupalLogout();
 
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentNodeAccessTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentNodeAccessTest.php
index 0b8936d..a3eba40 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentNodeAccessTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentNodeAccessTest.php
@@ -48,7 +48,7 @@ function setUp() {
     ));
 
     // Set the author of the created node to the web_user uid.
-    $this->node->setAuthorId($this->web_user->id())->save();
+    $this->node->setOwnerId($this->web_user->id())->save();
   }
 
   /**
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentTokenReplaceTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentTokenReplaceTest.php
index 7b9b9ff..a09da3a 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:title]'] = check_plain($parent_comment->subject->value);
     $tests['[comment:node:nid]'] = $comment->entity_id->value;
     $tests['[comment:node:title]'] = check_plain($node->getTitle());
-    $tests['[comment:author:uid]'] = $comment->uid->target_id;
+    $tests['[comment:author:uid]'] = $comment->getOwnerId();
     $tests['[comment:author:name]'] = check_plain($this->admin_user->getUsername());
 
     // Test to make sure that we generated something for each token.
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentTranslationUITest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentTranslationUITest.php
index e9fd575..43ed097 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentTranslationUITest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentTranslationUITest.php
@@ -108,7 +108,7 @@ protected function createEntity($values, $langcode, $node_bundle = 'node__commen
     $values['entity_id'] = $node->id();
     $values['entity_type'] = 'node';
     $values['field_id'] = $node_bundle;
-    $values['uid'] = $node->getAuthorId();
+    $values['uid'] = $node->getOwnerId();
     return parent::createEntity($values, $langcode, $node_bundle);
   }
 
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 fbc4769..807fc58 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/Views/DefaultViewRecentComments.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/Views/DefaultViewRecentComments.php
@@ -82,13 +82,14 @@ public function setUp() {
 
     // Create some comments and attach them to the created node.
     for ($i = 0; $i < $this->masterDisplayResults; $i++) {
+      /** @var \Drupal\comment\CommentInterface $comment */
       $comment = entity_create('comment', array(
         'status' => CommentInterface::PUBLISHED,
         'field_name' => 'comment',
         'entity_type' => 'node',
         'entity_id' => $this->node->id(),
       ));
-      $comment->uid->target_id = 0;
+      $comment->setOwnerId(0);
       $comment->subject->value = 'Test comment ' . $i;
       $comment->comment_body->value = 'Test body ' . $i;
       $comment->comment_body->format = 'full_html';
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldWidget/AutocompleteWidgetBase.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldWidget/AutocompleteWidgetBase.php
index 4621c5c..956fb7c 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldWidget/AutocompleteWidgetBase.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldWidget/AutocompleteWidgetBase.php
@@ -9,6 +9,7 @@
 
 use Drupal\Core\Field\FieldItemListInterface;
 use Drupal\Core\Field\WidgetBase;
+use Drupal\user\EntityOwnerInterface;
 use Symfony\Component\Validator\ConstraintViolationInterface;
 
 /**
@@ -94,8 +95,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
       '#size' => $this->getSetting('size'),
       '#placeholder' => $this->getSetting('placeholder'),
       '#element_validate' => array(array($this, 'elementValidate')),
-      // @todo: Use wrapper to get the user if exists or needed.
-      '#autocreate_uid' => isset($entity->uid) ? $entity->uid : $user->id(),
+      '#autocreate_uid' => ($entity instanceof EntityOwnerInterface) ? $entity->getOwnerId() : $user->id(),
     );
 
     return array('target_id' => $element);
@@ -172,11 +172,16 @@ protected function createNewEntity($label, $uid) {
     $bundle_key = $entity_info->getKey('bundle');
     $label_key = $entity_info->getKey('label');
 
-    return $entity_manager->getStorageController($target_type)->create(array(
+    $entity = $entity_manager->getStorageController($target_type)->create(array(
       $label_key => $label,
       $bundle_key => $bundle,
-      'uid' => $uid,
     ));
+
+    if ($entity instanceof EntityOwnerInterface) {
+      $entity->setOwnerId($uid);
+    }
+
+    return $entity;
   }
 
   /**
diff --git a/core/modules/file/file.module b/core/modules/file/file.module
index 892b214..d78f809 100644
--- a/core/modules/file/file.module
+++ b/core/modules/file/file.module
@@ -602,6 +602,7 @@ function file_file_download($uri, $field_type = 'file') {
   $user = \Drupal::currentUser();
 
   // Get the file record based on the URI. If not in the database just return.
+  /** @var \Drupal\file\FileInterface[] $files */
   $files = entity_load_multiple_by_properties('file', array('uri' => $uri));
   if (count($files)) {
     foreach ($files as $item) {
@@ -625,7 +626,7 @@ function file_file_download($uri, $field_type = 'file') {
   // temporary files where the host entity has not yet been saved (for example,
   // an image preview on a node/add form) in which case, allow download by the
   // file's owner.
-  if (empty($references) && ($file->isPermanent() || $file->getOwner()->id() != $user->id())) {
+  if (empty($references) && ($file->isPermanent() || $file->getOwnerId() != $user->id())) {
     return;
   }
 
@@ -1005,6 +1006,7 @@ function file_tokens($type, $tokens, array $data = array(), array $options = arr
   $replacements = array();
 
   if ($type == 'file' && !empty($data['file'])) {
+    /** @var \Drupal\file\FileInterface $file */
     $file = $data['file'];
 
     foreach ($tokens as $name => $original) {
diff --git a/core/modules/file/lib/Drupal/file/Entity/File.php b/core/modules/file/lib/Drupal/file/Entity/File.php
index 816435b..62a754b 100644
--- a/core/modules/file/lib/Drupal/file/Entity/File.php
+++ b/core/modules/file/lib/Drupal/file/Entity/File.php
@@ -132,8 +132,24 @@ public function getOwner() {
   /**
    * {@inheritdoc}
    */
-  public function setOwner(UserInterface $user) {
-    return $this->get('uid')->entity = $user;
+  public function getOwnerId() {
+    return $this->get('uid')->target_id;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setOwnerId($uid) {
+    $this->set('uid', $uid);
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setOwner(UserInterface $account) {
+    $this->set('uid', $account->id());
+    return $this;
   }
 
   /**
diff --git a/core/modules/file/lib/Drupal/file/FileInterface.php b/core/modules/file/lib/Drupal/file/FileInterface.php
index c4fd9f0..be94aaa 100644
--- a/core/modules/file/lib/Drupal/file/FileInterface.php
+++ b/core/modules/file/lib/Drupal/file/FileInterface.php
@@ -8,13 +8,14 @@
 namespace Drupal\file;
 
 use Drupal\Core\Entity\ContentEntityInterface;
+use Drupal\user\EntityOwnerInterface;
 use Drupal\Core\Entity\EntityChangedInterface;
 use Drupal\user\UserInterface;
 
 /**
  * Defines getter and setter methods for file entity base fields.
  */
-interface FileInterface extends ContentEntityInterface, EntityChangedInterface {
+interface FileInterface extends ContentEntityInterface, EntityChangedInterface, EntityOwnerInterface {
 
   /**
    * Returns the name of the file.
@@ -112,22 +113,6 @@ public function setPermanent();
   public function setTemporary();
 
   /**
-   * Returns the user that owns this file.
-   *
-   * @return \Drupal\user\UserInterface
-   *   The user that owns the file.
-   */
-  public function getOwner();
-
-  /**
-   * Sets the user that owns this file.
-   *
-   * @param \Drupal\user\UserInterface $user
-   *   The user that owns the file.
-   */
-  public function setOwner(UserInterface $user);
-
-  /**
    * Returns the node creation timestamp.
    *
    * @return int
diff --git a/core/modules/file/lib/Drupal/file/Tests/FileTokenReplaceTest.php b/core/modules/file/lib/Drupal/file/Tests/FileTokenReplaceTest.php
index 9e0039d..03aedcb 100644
--- a/core/modules/file/lib/Drupal/file/Tests/FileTokenReplaceTest.php
+++ b/core/modules/file/lib/Drupal/file/Tests/FileTokenReplaceTest.php
@@ -58,7 +58,7 @@ function testFileTokenReplacement() {
     $tests['[file:changed]'] = format_date($file->getChangedTime(), 'medium', '', NULL, $language_interface->id);
     $tests['[file:changed:short]'] = format_date($file->getChangedTime(), 'short', '', NULL, $language_interface->id);
     $tests['[file:owner]'] = check_plain(user_format_name($this->admin_user));
-    $tests['[file:owner:uid]'] = $file->getOwner()->id();
+    $tests['[file:owner:uid]'] = $file->getOwnerId();
 
     // Test to make sure that we generated something for each token.
     $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.');
diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module
index 2271f56..8064749 100644
--- a/core/modules/forum/forum.module
+++ b/core/modules/forum/forum.module
@@ -739,6 +739,7 @@ function template_preprocess_forum_topic_list(&$variables) {
 
   if (!empty($variables['topics'])) {
     $row = 0;
+    /** @var \Drupal\node\NodeInterface $topic */
     foreach ($variables['topics'] as $id => $topic) {
       $variables['topics'][$id]->icon = array(
         '#theme' => 'forum_icon',
@@ -765,8 +766,8 @@ function template_preprocess_forum_topic_list(&$variables) {
         $variables['topics'][$id]->message = '';
       }
       $forum_submitted = array('#theme' => 'forum_submitted', '#topic' => (object) array(
-        'uid' => $topic->getAuthorId(),
-        'name' => $topic->getAuthor()->getUsername(),
+        'uid' => $topic->getOwnerId(),
+        'name' => $topic->getOwner()->getUsername(),
         'created' => $topic->getCreatedTime(),
       ));
       $variables['topics'][$id]->submitted = drupal_render($forum_submitted);
diff --git a/core/modules/node/lib/Drupal/node/Entity/Node.php b/core/modules/node/lib/Drupal/node/Entity/Node.php
index 90d4fac..15a8a02 100644
--- a/core/modules/node/lib/Drupal/node/Entity/Node.php
+++ b/core/modules/node/lib/Drupal/node/Entity/Node.php
@@ -13,6 +13,7 @@
 use Drupal\Core\Language\Language;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\node\NodeInterface;
+use Drupal\user\UserInterface;
 
 /**
  * Defines the node entity class.
@@ -294,21 +295,21 @@ public function setPublished($published) {
   /**
    * {@inheritdoc}
    */
-  public function getAuthor() {
+  public function getOwner() {
     return $this->get('uid')->entity;
   }
 
   /**
    * {@inheritdoc}
    */
-  public function getAuthorId() {
+  public function getOwnerId() {
     return $this->get('uid')->target_id;
   }
 
   /**
    * {@inheritdoc}
    */
-  public function setAuthorId($uid) {
+  public function setOwnerId($uid) {
     $this->set('uid', $uid);
     return $this;
   }
@@ -316,6 +317,14 @@ public function setAuthorId($uid) {
   /**
    * {@inheritdoc}
    */
+  public function setOwner(UserInterface $account) {
+    $this->set('uid', $account->id());
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function getRevisionCreationTime() {
     return $this->get('revision_timestamp')->value;
   }
diff --git a/core/modules/node/lib/Drupal/node/NodeAccessController.php b/core/modules/node/lib/Drupal/node/NodeAccessController.php
index a069854..a2c1931 100644
--- a/core/modules/node/lib/Drupal/node/NodeAccessController.php
+++ b/core/modules/node/lib/Drupal/node/NodeAccessController.php
@@ -90,7 +90,9 @@ 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 = $node->getTranslation($langcode)->isPublished();
-    $uid = $node->getTranslation($langcode)->getAuthorId();
+    /** @var \Drupal\node\NodeInterface $translation */
+    $translation = $node->getTranslation($langcode);
+    $uid = $translation->getOwnerId();
 
     // 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/NodeFormController.php b/core/modules/node/lib/Drupal/node/NodeFormController.php
index 3fb7584..ec5971c 100644
--- a/core/modules/node/lib/Drupal/node/NodeFormController.php
+++ b/core/modules/node/lib/Drupal/node/NodeFormController.php
@@ -29,6 +29,7 @@ class NodeFormController extends ContentEntityFormController {
    * {@inheritdoc}
    */
   protected function prepareEntity() {
+    /** @var \Drupal\node\NodeInterface $node */
     $node = $this->entity;
     // Set up default values, if required.
     $type = entity_load('node_type', $node->bundle());
@@ -47,7 +48,7 @@ protected function prepareEntity() {
           $node->$key = (int) !empty($this->settings['options'][$key]);
         }
       }
-      $node->setAuthorId(\Drupal::currentUser()->id());
+      $node->setOwnerId(\Drupal::currentUser()->id());
       $node->setCreatedTime(REQUEST_TIME);
     }
     else {
@@ -63,6 +64,7 @@ protected function prepareEntity() {
    * Overrides Drupal\Core\Entity\EntityFormController::form().
    */
   public function form(array $form, array &$form_state) {
+    /** @var \Drupal\node\NodeInterface $node */
     $node = $this->entity;
 
     if ($this->operation == 'edit') {
@@ -180,7 +182,7 @@ public function form(array $form, array &$form_state) {
       '#title' => t('Authored by'),
       '#maxlength' => 60,
       '#autocomplete_route_name' => 'user.autocomplete',
-      '#default_value' => $node->getAuthorId()? $node->getAuthor()->getUsername() : '',
+      '#default_value' => $node->getOwnerId()? $node->getOwner()->getUsername() : '',
       '#weight' => -1,
       '#description' => t('Leave blank for %anonymous.', array('%anonymous' => $user_config->get('anonymous'))),
     );
@@ -424,14 +426,15 @@ public function unpublish(array $form, array &$form_state) {
    * {@inheritdoc}
    */
   public function buildEntity(array $form, array &$form_state) {
+    /** @var \Drupal\node\NodeInterface $entity */
     $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());
+      $entity->setOwnerId($account->id());
     }
     else {
-      $entity->setAuthorId(0);
+      $entity->setOwnerId(0);
     }
 
     if (!empty($form_state['values']['date']) && $form_state['values']['date'] instanceOf DrupalDateTime) {
diff --git a/core/modules/node/lib/Drupal/node/NodeInterface.php b/core/modules/node/lib/Drupal/node/NodeInterface.php
index b4906af..4ca91c7 100644
--- a/core/modules/node/lib/Drupal/node/NodeInterface.php
+++ b/core/modules/node/lib/Drupal/node/NodeInterface.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\node;
 
+use Drupal\user\EntityOwnerInterface;
 use Drupal\Core\Entity\EntityChangedInterface;
 use Drupal\Core\Entity\ContentEntityInterface;
 use Drupal\user\UserInterface;
@@ -14,7 +15,7 @@
 /**
  * Provides an interface defining a node entity.
  */
-interface NodeInterface extends ContentEntityInterface, EntityChangedInterface {
+interface NodeInterface extends ContentEntityInterface, EntityChangedInterface, EntityOwnerInterface {
 
   /**
    * Returns the node type.
@@ -25,7 +26,6 @@
   public function getType();
 
   /**
-   *
    * Returns the node title.
    *
    * @return string
@@ -102,33 +102,6 @@ public function isSticky();
   public function setSticky($sticky);
 
   /**
-   * Returns the node author user entity.
-   *
-   * @return \Drupal\user\UserInterface
-   *   The author user entity.
-   */
-  public function getAuthor();
-
-  /**
-   * Returns the node author user ID.
-   *
-   * @return int
-   *   The author user ID.
-   */
-  public function getAuthorId();
-
-  /**
-   * Sets the node author user ID.
-   *
-   * @param int $uid
-   *   The author user id.
-   *
-   * @return \Drupal\node\NodeInterface
-   *   The called node entity.
-   */
-  public function setAuthorId($uid);
-
-  /**
    * Returns the node published status indicator.
    *
    * Unpublished nodes are only visible to their authors and to administrators.
@@ -160,7 +133,7 @@ public function getRevisionCreationTime();
   /**
    * Sets the node revision creation timestamp.
    *
-   * @param int $imestamp
+   * @param int $timestamp
    *   The UNIX timestamp of when this revision was created.
    *
    * @return \Drupal\node\NodeInterface
diff --git a/core/modules/node/lib/Drupal/node/NodeListController.php b/core/modules/node/lib/Drupal/node/NodeListController.php
index b9582ae..4605c58 100644
--- a/core/modules/node/lib/Drupal/node/NodeListController.php
+++ b/core/modules/node/lib/Drupal/node/NodeListController.php
@@ -94,6 +94,7 @@ public function buildHeader() {
    * {@inheritdoc}
    */
   public function buildRow(EntityInterface $entity) {
+    /** @var \Drupal\node\NodeInterface $entity */
     $mark = array(
       '#theme' => 'mark',
       '#mark_type' => node_mark($entity->id(), $entity->getChangedTime()),
@@ -110,7 +111,7 @@ public function buildRow(EntityInterface $entity) {
     $row['type'] = String::checkPlain(node_get_type_label($entity));
     $row['author']['data'] = array(
       '#theme' => 'username',
-      '#account' => $entity->getAuthor(),
+      '#account' => $entity->getOwner(),
     );
     $row['status'] = $entity->isPublished() ? $this->t('published') : $this->t('not published');
     $row['changed'] = $this->dateService->format($entity->getChangedTime(), 'short');
diff --git a/core/modules/node/lib/Drupal/node/NodeViewBuilder.php b/core/modules/node/lib/Drupal/node/NodeViewBuilder.php
index fcaeaed..7b9ccce 100644
--- a/core/modules/node/lib/Drupal/node/NodeViewBuilder.php
+++ b/core/modules/node/lib/Drupal/node/NodeViewBuilder.php
@@ -137,6 +137,7 @@ protected static function buildLinks(NodeInterface $entity, $view_mode) {
    * {@inheritdoc}
    */
   protected function alterBuild(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode, $langcode = NULL) {
+    /** @var \Drupal\node\NodeInterface $entity */
     parent::alterBuild($build, $entity, $display, $view_mode, $langcode);
     if ($entity->id()) {
       $build['#contextual_links']['node'] = array(
@@ -146,7 +147,7 @@ protected function alterBuild(array &$build, EntityInterface $entity, EntityView
 
     // The node 'submitted' info is not rendered in a standard way (renderable
     // array) so we have to add a cache tag manually.
-    $build['#cache']['tags']['user'][] = $entity->getAuthorId();
+    $build['#cache']['tags']['user'][] = $entity->getOwnerId();
   }
 
 }
diff --git a/core/modules/node/lib/Drupal/node/Plugin/Search/NodeSearch.php b/core/modules/node/lib/Drupal/node/Plugin/Search/NodeSearch.php
index fb0538a..ff76e3e 100644
--- a/core/modules/node/lib/Drupal/node/Plugin/Search/NodeSearch.php
+++ b/core/modules/node/lib/Drupal/node/Plugin/Search/NodeSearch.php
@@ -232,6 +232,7 @@ public function execute() {
 
     foreach ($find as $item) {
       // Render the node.
+      /** @var \Drupal\node\NodeInterface $node */
       $node = $node_storage->load($item->sid)->getTranslation($item->langcode);
       $build = $node_render->view($node, 'search_result', $item->langcode);
       unset($build['#theme']);
@@ -246,7 +247,7 @@ public function execute() {
       $uri = $node->uri();
       $username = array(
         '#theme' => 'username',
-        '#account' => $node->getAuthor(),
+        '#account' => $node->getOwner(),
       );
       $results[] = array(
         'link' => url($uri['path'], array_merge($uri['options'], array('absolute' => TRUE, 'language' => $language))),
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 979d222..08cae61 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
@@ -102,6 +102,7 @@ public function render($row) {
     }
 
     // Load the specified node:
+    /** @var \Drupal\node\NodeInterface $node */
     $node = $this->nodes[$nid];
     if (empty($node)) {
       return;
@@ -119,7 +120,7 @@ public function render($row) {
       ),
       array(
         'key' => 'dc:creator',
-        'value' => $node->getAuthor()->getUsername(),
+        'value' => $node->getOwner()->getUsername(),
       ),
       array(
         'key' => 'guid',
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeSaveTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeSaveTest.php
index 4f50fd3..5164ecf 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeSaveTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeSaveTest.php
@@ -56,11 +56,12 @@ function testImport() {
       'type' => 'article',
       'nid' => $test_nid,
     );
+    /** @var \Drupal\node\NodeInterface $node */
     $node = entity_create('node', $node);
     $node->enforceIsNew();
 
     // Verify that node_submit did not overwrite the user ID.
-    $this->assertEqual($node->getAuthorId(), $this->web_user->id(), 'Function node_submit() preserves user ID');
+    $this->assertEqual($node->getOwnerId(), $this->web_user->id(), 'Function node_submit() preserves user ID');
 
     $node->save();
     // Test the import.
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeTokenReplaceTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeTokenReplaceTest.php
index 0834116..24f6653 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeTokenReplaceTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeTokenReplaceTest.php
@@ -59,7 +59,7 @@ function testNodeTokenReplacement() {
     $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->getAuthorId();
+    $tests['[node:author:uid]'] = $node->getOwnerId();
     $tests['[node:author:name]'] = check_plain(user_format_name($account));
     $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);
diff --git a/core/modules/node/lib/Drupal/node/Tests/PageEditTest.php b/core/modules/node/lib/Drupal/node/Tests/PageEditTest.php
index 3e52eb0..b7b0106 100644
--- a/core/modules/node/lib/Drupal/node/Tests/PageEditTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/PageEditTest.php
@@ -87,7 +87,7 @@ function testPageEdit() {
     $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->getAuthorId(), $revised_node->getAuthorId(), 'The node author has been preserved.');
+    $this->assertIdentical($node->getOwnerId(), $revised_node->getOwnerId(), '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->getRevisionId());
@@ -110,7 +110,7 @@ function testPageAuthoredBy() {
 
     // Check that the node was authored by the currently logged in user.
     $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
-    $this->assertIdentical($node->getAuthorId(), $this->admin_user->id(), 'Node authored by admin user.');
+    $this->assertIdentical($node->getOwnerId(), $this->admin_user->id(), 'Node authored by admin user.');
 
     // Try to change the 'authored by' field to an invalid user name.
     $edit = array(
@@ -124,14 +124,14 @@ function testPageAuthoredBy() {
     $edit['name'] = '';
     $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
     $node = node_load($node->id(), TRUE);
-    $this->assertIdentical($node->getAuthorId(), '0', 'Node authored by anonymous user.');
+    $this->assertIdentical($node->getOwnerId(), '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->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
     $node = node_load($node->id(), TRUE);
-    $this->assertIdentical($node->getAuthorId(), $this->web_user->id(), 'Node authored by normal user.');
+    $this->assertIdentical($node->getOwnerId(), $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/node.api.php b/core/modules/node/node.api.php
index d53673c..b41a11e 100644
--- a/core/modules/node/node.api.php
+++ b/core/modules/node/node.api.php
@@ -279,7 +279,7 @@ function hook_node_access_records(\Drupal\node\NodeInterface $node) {
     // have status unpublished.
     $grants[] = array(
       'realm' => 'example_author',
-      'gid' => $node->getAuthorId(),
+      'gid' => $node->getOwnerId(),
       'grant_view' => 1,
       'grant_update' => 1,
       'grant_delete' => 1,
@@ -577,13 +577,13 @@ function hook_node_access(\Drupal\node\NodeInterface $node, $op, $account, $lang
     }
 
     if ($op == 'update') {
-      if (user_access('edit any ' . $type . ' content', $account) || (user_access('edit own ' . $type . ' content', $account) && ($account->id() == $node->getAuthorId()))) {
+      if (user_access('edit any ' . $type . ' content', $account) || (user_access('edit own ' . $type . ' content', $account) && ($account->id() == $node->getOwnerId()))) {
         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->getAuthorId()))) {
+      if (user_access('delete any ' . $type . ' content', $account) || (user_access('delete own ' . $type . ' content', $account) && ($account->id() == $node->getOwnerId()))) {
         return NODE_ACCESS_ALLOW;
       }
     }
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index b457cb9..51f060a 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -10,6 +10,7 @@
 
 use Drupal\Component\Utility\String;
 use Drupal\Core\Language\Language;
+use Drupal\node\NodeInterface;
 use Symfony\Component\HttpFoundation\Response;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Database\Query\AlterableInterface;
@@ -515,7 +516,7 @@ function node_type_update_nodes($old_id, $new_id) {
  *   (optional) Whether to reset the internal node_load() cache.  Defaults to
  *   FALSE.
  *
- * @return array
+ * @return \Drupal\node\NodeInterface[]
  *   An array of node entities indexed by nid.
  *
  * @see entity_load_multiple()
@@ -637,12 +638,13 @@ function template_preprocess_node(&$variables) {
   // Provide a distinct $teaser boolean.
   $variables['teaser'] = $variables['view_mode'] == 'teaser';
   $variables['node'] = $variables['elements']['#node'];
+  /** @var \Drupal\node\NodeInterface $node */
   $node = $variables['node'];
 
   $variables['date'] = format_date($node->getCreatedTime());
   $username = array(
     '#theme' => 'username',
-    '#account' => $node->getAuthor(),
+    '#account' => $node->getOwner(),
     '#link_options' => array('attributes' => array('rel' => 'author')),
   );
   $variables['name'] = drupal_render($username);
@@ -670,7 +672,7 @@ function template_preprocess_node(&$variables) {
       // To change user picture settings (e.g. image style), edit the 'compact'
       // view mode on the User entity. Note that the 'compact' view mode might
       // not be configured, so remember to always check the theme setting first.
-      $variables['user_picture'] = user_view($node->getAuthor(), 'compact');
+      $variables['user_picture'] = user_view($node->getOwner(), 'compact');
     }
     else {
       $variables['user_picture'] = array();
@@ -1200,6 +1202,7 @@ function node_feed($nids = FALSE, $channel = array()) {
   $namespaces = array('xmlns:dc' => 'http://purl.org/dc/elements/1.1/');
 
   // Load all nodes to be rendered.
+  /** @var \Drupal\node\NodeInterface[] $nodes */
   $nodes = node_load_multiple($nids);
   $items = '';
   foreach ($nodes as $node) {
@@ -1209,7 +1212,7 @@ function node_feed($nids = FALSE, $channel = array()) {
     $node->rss_namespaces = array();
     $node->rss_elements = array(
       array('key' => 'pubDate', 'value' => gmdate('r', $node->getCreatedTime())),
-      array('key' => 'dc:creator', 'value' => $node->getAuthor()->label()),
+      array('key' => 'dc:creator', 'value' => $node->getOwner()->label()),
       array('key' => 'guid', 'value' => $node->id() . ' at ' . $base_url, 'attributes' => array('isPermaLink' => 'false'))
     );
 
@@ -1392,7 +1395,7 @@ function node_form_system_themes_admin_form_submit($form, &$form_state) {
 /**
  * Implements hook_node_access().
  */
-function node_node_access($node, $op, $account) {
+function node_node_access(NodeInterface $node, $op, $account) {
   $type = $node->bundle();
 
   $configured_types = node_permissions_get_configured_types();
@@ -1402,13 +1405,13 @@ function node_node_access($node, $op, $account) {
     }
 
     if ($op == 'update') {
-      if (user_access('edit any ' . $type . ' content', $account) || (user_access('edit own ' . $type . ' content', $account) && ($account->id() == $node->getAuthorId()))) {
+      if (user_access('edit any ' . $type . ' content', $account) || (user_access('edit own ' . $type . ' content', $account) && ($account->id() == $node->getOwnerId()))) {
         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->getAuthorId()))) {
+      if (user_access('delete any ' . $type . ' content', $account) || (user_access('delete own ' . $type . ' content', $account) && ($account->id() == $node->getOwnerId()))) {
         return NODE_ACCESS_ALLOW;
       }
     }
diff --git a/core/modules/node/node.tokens.inc b/core/modules/node/node.tokens.inc
index 4037d59..dbf668c 100644
--- a/core/modules/node/node.tokens.inc
+++ b/core/modules/node/node.tokens.inc
@@ -101,6 +101,7 @@ function node_tokens($type, $tokens, array $data = array(), array $options = arr
   $replacements = array();
 
   if ($type == 'node' && !empty($data['node'])) {
+    /** @var \Drupal\node\NodeInterface $node */
     $node = $data['node'];
 
     foreach ($tokens as $name => $original) {
@@ -177,7 +178,7 @@ function node_tokens($type, $tokens, array $data = array(), array $options = arr
 
         // Default values for the chained tokens handled below.
         case 'author':
-          $account = $node->getAuthor() ? $node->getAuthor() : user_load(0);
+          $account = $node->getOwner() ? $node->getOwner() : user_load(0);
           $replacements[$original] = $sanitize ? check_plain($account->label()) : $account->label();
           break;
 
@@ -192,7 +193,7 @@ function node_tokens($type, $tokens, array $data = array(), array $options = arr
     }
 
     if ($author_tokens = $token_service->findWithPrefix($tokens, 'author')) {
-      $replacements += $token_service->generate('user', $author_tokens, array('user' => $node->getAuthor()), $options);
+      $replacements += $token_service->generate('user', $author_tokens, array('user' => $node->getOwner()), $options);
     }
 
     if ($created_tokens = $token_service->findWithPrefix($tokens, 'created')) {
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 bcfc3aa..2a6fed9 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
@@ -58,7 +58,7 @@ function node_access_test_node_access_records(NodeInterface $node) {
     // means there are many many groups of just 1 user.
     $grants[] = array(
       'realm' => 'node_access_test_author',
-      'gid' => $node->getAuthorId(),
+      'gid' => $node->getOwnerId(),
       'grant_view' => 1,
       'grant_update' => 1,
       'grant_delete' => 1,
diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/CommentAttributesTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/CommentAttributesTest.php
index b8a3bfb..a1ce434 100644
--- a/core/modules/rdf/lib/Drupal/rdf/Tests/CommentAttributesTest.php
+++ b/core/modules/rdf/lib/Drupal/rdf/Tests/CommentAttributesTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\rdf\Tests;
 
+use Drupal\comment\CommentInterface;
 use Drupal\comment\Tests\CommentTestBase;
 
 /**
@@ -226,7 +227,7 @@ public function testCommentReplyOfRdfaMarkup() {
    * @param $account
    *   An array containing information about an anonymous user.
    */
-  function _testBasicCommentRdfaMarkup($graph, $comment, $account = array()) {
+  function _testBasicCommentRdfaMarkup($graph, CommentInterface $comment, $account = array()) {
     $uri = $comment->uri();
     $comment_uri = url($uri['path'], $uri['options'] + array('absolute' => TRUE));
 
@@ -275,8 +276,8 @@ function _testBasicCommentRdfaMarkup($graph, $comment, $account = array()) {
     $this->assertTrue($graph->hasProperty($comment_uri, 'http://purl.org/rss/1.0/modules/content/encoded', $expected_value), 'Comment body found in RDF output (content:encoded).');
 
     // The comment author can be a registered user or an anonymous user.
-    if ($comment->uid->value > 0) {
-      $author_uri = url('user/' . $comment->uid->value, array('absolute' => TRUE));
+    if ($comment->getOwnerId() > 0) {
+      $author_uri = url('user/' . $comment->getOwnerId(), array('absolute' => TRUE));
       // Comment relation to author.
       $expected_value = array(
         'type' => 'uri',
@@ -304,7 +305,7 @@ function _testBasicCommentRdfaMarkup($graph, $comment, $account = array()) {
     $this->assertTrue($graph->hasProperty($author_uri, 'http://xmlns.com/foaf/0.1/name', $expected_value), 'Comment author name found in RDF output (foaf:name).');
 
     // Comment author homepage (only for anonymous authors).
-    if ($comment->uid->value == 0) {
+    if ($comment->getOwnerId() == 0) {
       $expected_value = array(
         'type' => 'uri',
         'value' => 'http://example.org/',
diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/TrackerAttributesTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/TrackerAttributesTest.php
index 26b15f5..fa7f673 100644
--- a/core/modules/rdf/lib/Drupal/rdf/Tests/TrackerAttributesTest.php
+++ b/core/modules/rdf/lib/Drupal/rdf/Tests/TrackerAttributesTest.php
@@ -8,6 +8,7 @@
 namespace Drupal\rdf\Tests;
 
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\node\NodeInterface;
 use Drupal\simpletest\WebTestBase;
 
 /**
@@ -119,9 +120,9 @@ function testAttributesInTracker() {
    * @param \Drupal\Core\Entity\EntityInterface $node
    * The node just created.
    */
-  function _testBasicTrackerRdfaMarkup(EntityInterface $node) {
+  function _testBasicTrackerRdfaMarkup(NodeInterface $node) {
     $node_uri = url('node/' . $node->id(), array('absolute' => TRUE));
-    $user_uri = url('user/' . $node->getAuthorId(), array('absolute' => TRUE));
+    $user_uri = url('user/' . $node->getOwnerId(), array('absolute' => TRUE));
 
     // Parses tracker page where the nodes are displayed in a table.
     $parser = new \EasyRdf_Parser_Rdfa();
@@ -150,10 +151,10 @@ function _testBasicTrackerRdfaMarkup(EntityInterface $node) {
       'type' => 'uri',
       'value' => $user_uri,
     );
-    if ($node->getAuthorId() == 0) {
+    if ($node->getOwnerId() == 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->getAuthorId() > 0) {
+    elseif ($node->getOwnerId() > 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.
diff --git a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
index 265012e..af8dc69 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
@@ -200,7 +200,7 @@ function __construct($test_id = NULL) {
    * @param $reset
    *   (optional) Whether to reset the entity cache.
    *
-   * @return \Drupal\Core\Entity\EntityInterface
+   * @return \Drupal\node\NodeInterface
    *   A node entity matching $title.
    */
   function drupalGetNodeByTitle($title, $reset = FALSE) {
@@ -247,7 +247,7 @@ function drupalGetNodeByTitle($title, $reset = FALSE) {
    *   - revision: 1. (Backwards-compatible binary flag indicating whether a
    *     new revision should be created; use 1 to specify a new revision.)
    *
-   * @return \Drupal\node\Entity\Node
+   * @return \Drupal\node\NodeInterface
    *   The created node entity.
    */
   protected function drupalCreateNode(array $settings = array()) {
diff --git a/core/modules/system/lib/Drupal/system/Tests/File/FileTestBase.php b/core/modules/system/lib/Drupal/system/Tests/File/FileTestBase.php
index 540c19a..382cc5a 100644
--- a/core/modules/system/lib/Drupal/system/Tests/File/FileTestBase.php
+++ b/core/modules/system/lib/Drupal/system/Tests/File/FileTestBase.php
@@ -37,7 +37,7 @@ function setUp() {
    */
   function assertFileUnchanged(FileInterface $before, FileInterface $after) {
     $this->assertEqual($before->id(), $after->id(), t('File id is the same: %file1 == %file2.', array('%file1' => $before->id(), '%file2' => $after->id())), 'File unchanged');
-    $this->assertEqual($before->getOwner()->id(), $after->getOwner()->id(), t('File owner is the same: %file1 == %file2.', array('%file1' => $before->getOwner()->id(), '%file2' => $after->getOwner()->id())), 'File unchanged');
+    $this->assertEqual($before->getOwnerId(), $after->getOwnerId(), t('File owner is the same: %file1 == %file2.', array('%file1' => $before->getOwnerId(), '%file2' => $after->getOwnerId())), 'File unchanged');
     $this->assertEqual($before->getFilename(), $after->getFilename(), t('File name is the same: %file1 == %file2.', array('%file1' => $before->getFilename(), '%file2' => $after->getFilename())), 'File unchanged');
     $this->assertEqual($before->getFileUri(), $after->getFileUri(), t('File path is the same: %file1 == %file2.', array('%file1' => $before->getFileUri(), '%file2' => $after->getFileUri())), 'File unchanged');
     $this->assertEqual($before->getMimeType(), $after->getMimeType(), t('File MIME type is the same: %file1 == %file2.', array('%file1' => $before->getMimeType(), '%file2' => $after->getMimeType())), 'File unchanged');
diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php
index 1de6b15..1ea190c 100644
--- a/core/modules/system/system.api.php
+++ b/core/modules/system/system.api.php
@@ -1563,9 +1563,10 @@ function hook_mail($key, &$message, $params) {
 
   // Node-based variable translation is only available if we have a node.
   if (isset($params['node'])) {
+    /** @var \Drupal\node\NodeInterface $node */
     $node = $params['node'];
     $variables += array(
-      '%uid' => $node->getAuthorId(),
+      '%uid' => $node->getOwnerId(),
       '%node_url' => url('node/' . $node->id(), array('absolute' => TRUE)),
       '%node_type' => node_get_type_label($node),
       '%title' => $node->getTitle(),
@@ -2746,6 +2747,7 @@ function hook_tokens($type, $tokens, array $data = array(), array $options = arr
   $replacements = array();
 
   if ($type == 'node' && !empty($data['node'])) {
+    /** @var \Drupal\node\NodeInterface $node */
     $node = $data['node'];
 
     foreach ($tokens as $name => $original) {
@@ -2765,7 +2767,7 @@ function hook_tokens($type, $tokens, array $data = array(), array $options = arr
 
         // Default values for the chained tokens handled below.
         case 'author':
-          $account = $node->getAuthor() ? $node->getAuthor() : user_load(0);
+          $account = $node->getOwner() ? $node->getOwner() : user_load(0);
           $replacements[$original] = $sanitize ? check_plain($account->label()) : $account->label();
           break;
 
@@ -2776,7 +2778,7 @@ function hook_tokens($type, $tokens, array $data = array(), array $options = arr
     }
 
     if ($author_tokens = $token_service->findWithPrefix($tokens, 'author')) {
-      $replacements += $token_service->generate('user', $author_tokens, array('user' => $node->getAuthor()), $options);
+      $replacements += $token_service->generate('user', $author_tokens, array('user' => $node->getOwner()), $options);
     }
 
     if ($created_tokens = $token_service->findWithPrefix($tokens, 'created')) {
diff --git a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTest.php b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTest.php
index 9798c4f..d865687 100644
--- a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTest.php
+++ b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTest.php
@@ -11,6 +11,8 @@
 use Drupal\Core\Field\FieldDefinition;
 use Drupal\Core\Entity\EntityStorageControllerInterface;
 use Drupal\Core\Language\Language;
+use Drupal\user\EntityOwnerInterface;
+use Drupal\user\UserInterface;
 
 /**
  * Defines the test entity class.
@@ -44,7 +46,7 @@
  *   }
  * )
  */
-class EntityTest extends ContentEntityBase {
+class EntityTest extends ContentEntityBase implements EntityOwnerInterface {
 
   /**
    * The entity ID.
@@ -159,4 +161,34 @@ public static function baseFieldDefinitions($entity_type) {
     return $fields;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getOwner() {
+    return $this->get('user_id')->entity;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getOwnerId() {
+    return $this->get('user_id')->target_id;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setOwnerId($uid) {
+    $this->set('user_id', $uid);
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setOwner(UserInterface $account) {
+    $this->set('user_id', $account->id());
+    return $this;
+  }
+
 }
diff --git a/core/modules/tracker/lib/Drupal/tracker/Tests/Views/TrackerTestBase.php b/core/modules/tracker/lib/Drupal/tracker/Tests/Views/TrackerTestBase.php
index 843af22..a727ad5 100644
--- a/core/modules/tracker/lib/Drupal/tracker/Tests/Views/TrackerTestBase.php
+++ b/core/modules/tracker/lib/Drupal/tracker/Tests/Views/TrackerTestBase.php
@@ -23,6 +23,13 @@
    */
   public static $modules = array('comment', 'tracker', 'tracker_test_views');
 
+  /**
+   * The node used for testing.
+   *
+   * @var \Drupal\node\NodeInterface
+   */
+  protected $node;
+
   protected function setUp() {
     parent::setUp();
 
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 54a689b..8c4016c 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->getAuthorId();
+    $view->filter['uid_touch_tracker']->value = $this->node->getOwnerId();
     $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->getAuthorId()));
+    $this->executeView($view, array($this->node->getOwnerId()));
     $this->assertIdenticalResultSet($view, $expected, $map);
   }
 
diff --git a/core/modules/tracker/tracker.module b/core/modules/tracker/tracker.module
index b1be041..01970b9 100644
--- a/core/modules/tracker/tracker.module
+++ b/core/modules/tracker/tracker.module
@@ -159,7 +159,7 @@ function _tracker_user_access($account) {
  * Adds new tracking information for this node since it's new.
  */
 function tracker_node_insert(NodeInterface $node, $arg = 0) {
-  _tracker_add($node->id(), $node->getAuthorId(), $node->getChangedTime());
+  _tracker_add($node->id(), $node->getOwnerId(), $node->getChangedTime());
 }
 
 /**
@@ -168,7 +168,7 @@ function tracker_node_insert(NodeInterface $node, $arg = 0) {
  * Adds tracking information for this node since it's been updated.
  */
 function tracker_node_update(NodeInterface $node, $arg = 0) {
-  _tracker_add($node->id(), $node->getAuthorId(), $node->getChangedTime());
+  _tracker_add($node->id(), $node->getOwnerId(), $node->getChangedTime());
 }
 
 /**
@@ -191,11 +191,11 @@ function tracker_node_predelete(EntityInterface $node, $arg = 0) {
  * Comment module doesn't call hook_comment_unpublish() when saving individual
  * comments so we need to check for those here.
  */
-function tracker_comment_update($comment) {
+function tracker_comment_update(CommentInterface $comment) {
   // $comment->save() calls hook_comment_publish() for all published comments
   // so we need to handle all other values here.
   if ($comment->status->value != CommentInterface::PUBLISHED && $comment->entity_type->value == 'node') {
-    _tracker_remove($comment->entity_id->target_id, $comment->uid->target_id, $comment->changed->value);
+    _tracker_remove($comment->entity_id->target_id, $comment->getOwnerId(), $comment->changed->value);
   }
 }
 
@@ -205,27 +205,27 @@ function tracker_comment_update($comment) {
  * This actually handles the insert and update of published nodes since
  * $comment->save() calls hook_comment_publish() for all published comments.
  */
-function tracker_comment_publish($comment) {
+function tracker_comment_publish(CommentInterface $comment) {
   if ($comment->entity_type->value == 'node') {
-    _tracker_add($comment->entity_id->target_id, $comment->uid->target_id, $comment->changed->value);
+    _tracker_add($comment->entity_id->target_id, $comment->getOwnerId(), $comment->changed->value);
   }
 }
 
 /**
  * Implements hook_comment_unpublish().
  */
-function tracker_comment_unpublish($comment) {
+function tracker_comment_unpublish(CommentInterface $comment) {
   if ($comment->entity_type->value == 'node') {
-    _tracker_remove($comment->entity_id->target_id, $comment->uid->target_id, $comment->changed->value);
+    _tracker_remove($comment->entity_id->target_id, $comment->getOwnerId(), $comment->changed->value);
   }
 }
 
 /**
  * Implements hook_comment_delete().
  */
-function tracker_comment_delete($comment) {
+function tracker_comment_delete(CommentInterface $comment) {
   if ($comment->entity_type->value == 'node') {
-    _tracker_remove($comment->entity_id->target_id, $comment->uid->target_id, $comment->changed->value);
+    _tracker_remove($comment->entity_id->target_id, $comment->getOwnerId(), $comment->changed->value);
   }
 }
 
diff --git a/core/modules/tracker/tracker.pages.inc b/core/modules/tracker/tracker.pages.inc
index 332d9ac..e94c163 100644
--- a/core/modules/tracker/tracker.pages.inc
+++ b/core/modules/tracker/tracker.pages.inc
@@ -88,7 +88,7 @@ function tracker_page($account = NULL) {
       $row = array(
         'type' => check_plain(node_get_type_label($node)),
         'title' => array('data' => l($node->getTitle(), 'node/' . $node->id()) . ' ' . drupal_render($mark_build)),
-        'author' => array('data' => array('#theme' => 'username', '#account' => $node->getAuthor())),
+        'author' => array('data' => array('#theme' => 'username', '#account' => $node->getOwner())),
         'replies' => array('class' => array('replies'), 'data' => $comments),
         'last updated' => array('data' => t('!time ago', array('!time' => format_interval(REQUEST_TIME - $node->last_activity)))),
       );
diff --git a/core/modules/user/lib/Drupal/user/EntityOwnerInterface.php b/core/modules/user/lib/Drupal/user/EntityOwnerInterface.php
new file mode 100644
index 0000000..81d4ac2
--- /dev/null
+++ b/core/modules/user/lib/Drupal/user/EntityOwnerInterface.php
@@ -0,0 +1,58 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\user\EntityOwnerInterface.
+ */
+
+namespace Drupal\user;
+
+/**
+ * Defines a common interface for entities that have an owner.
+ *
+ * An owner is someone who has primary control over an entity, similar to
+ * owners in Unix file system access. This may or may not be the entity's
+ * original author. The owner may also have less permissions than other users,
+ * such as administrators.
+ */
+interface EntityOwnerInterface {
+
+  /**
+   * Returns the entity owner's user entity.
+   *
+   * @return \Drupal\user\UserInterface
+   *   The owner user entity.
+   */
+  public function getOwner();
+
+  /**
+   * Sets the entity owner's user entity.
+   *
+   * @param \Drupal\user\UserInterface $account
+   *   The owner user entity.
+   *
+   * @return self
+   *   The called entity.
+   */
+  public function setOwner(UserInterface $account);
+
+  /**
+   * Returns the entity owner's user ID.
+   *
+   * @return int
+   *   The owner user ID.
+   */
+  public function getOwnerId();
+
+  /**
+   * Sets the entity owner's user ID.
+   *
+   * @param int $uid
+   *   The owner user id.
+   *
+   * @return self
+   *   The called entity.
+   */
+  public function setOwnerId($uid);
+
+}
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 aaee8c8..a9698c4 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
@@ -98,7 +98,7 @@ public function getArgument() {
     if (!empty($this->options['user']) && $this->request->attributes->has('node')) {
       $node = $this->request->attributes->get('node');
       if ($node instanceof NodeInterface) {
-        return $node->getAuthorId();
+        return $node->getOwnerId();
       }
     }
 
diff --git a/core/modules/user/lib/Drupal/user/Tests/UserCancelTest.php b/core/modules/user/lib/Drupal/user/Tests/UserCancelTest.php
index fdd6b1b..c9d893d 100644
--- a/core/modules/user/lib/Drupal/user/Tests/UserCancelTest.php
+++ b/core/modules/user/lib/Drupal/user/Tests/UserCancelTest.php
@@ -56,7 +56,7 @@ function testUserCancelWithoutPermission() {
 
     // Confirm user's content has not been altered.
     $test_node = node_load($node->id(), TRUE);
-    $this->assertTrue(($test_node->getAuthorId() == $account->id() && $test_node->isPublished()), 'Node of the user has not been altered.');
+    $this->assertTrue(($test_node->getOwnerId() == $account->id() && $test_node->isPublished()), 'Node of the user has not been altered.');
   }
 
   /**
@@ -137,7 +137,7 @@ function testUserCancelInvalid() {
 
     // Confirm user's content has not been altered.
     $test_node = node_load($node->id(), TRUE);
-    $this->assertTrue(($test_node->getAuthorId() == $account->id() && $test_node->isPublished()), 'Node of the user has not been altered.');
+    $this->assertTrue(($test_node->getOwnerId() == $account->id() && $test_node->isPublished()), 'Node of the user has not been altered.');
   }
 
   /**
@@ -260,11 +260,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->getAuthorId() == 0 && $test_node->isPublished()), 'Node of the user has been attributed to anonymous user.');
+    $this->assertTrue(($test_node->getOwnerId() == 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->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->getAuthorId() != 0 && $test_node->isPublished()), "Current revision of the user's node was not attributed to anonymous user.");
+    $this->assertTrue(($test_node->getOwnerId() != 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.");
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 88862d5..e193eb1 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -161,23 +161,23 @@ function user_uri($user) {
  * Called by Drupal\Core\Entity\EntityViewBuilderInterface::buildContent()
  * implementations.
  *
- * @param array $entities
+ * @param \Drupal\user\EntityOwnerInterface[] $entities
  *   The entities keyed by entity ID.
  */
 function user_attach_accounts(array $entities) {
   $uids = array();
   foreach ($entities as $entity) {
-    $uids[] = $entity->getAuthorId();
+    $uids[] = $entity->getOwnerId();
   }
   $uids = array_unique($uids);
   $accounts = user_load_multiple($uids);
   $anonymous = drupal_anonymous_user();
   foreach ($entities as $id => $entity) {
-    if (isset($accounts[$entity->getAuthorId()])) {
-      $entities[$id]->account = $accounts[$entity->getAuthorId()];
+    if (isset($accounts[$entity->getOwnerId()])) {
+      $entities[$id]->setOwner($accounts[$entity->getOwnerId()]);
     }
     else {
-      $entities[$id]->account = $anonymous;
+      $entities[$id]->setOwner($anonymous);
     }
   }
 }
diff --git a/core/themes/seven/seven.theme b/core/themes/seven/seven.theme
index fa99324..4a1a901 100644
--- a/core/themes/seven/seven.theme
+++ b/core/themes/seven/seven.theme
@@ -236,6 +236,7 @@ function seven_preprocess_install_page(&$variables) {
  * Changes vertical tabs to container and adds meta information.
  */
 function seven_form_node_form_alter(&$form, &$form_state) {
+  /** @var \Drupal\node\NodeInterface $node */
   $node = $form_state['controller']->getEntity();
 
   $form['#theme'] = array('node_edit_form');
@@ -265,7 +266,7 @@ function seven_form_node_form_alter(&$form, &$form_state) {
       '#type' => 'item',
       '#wrapper_attributes' => array('class' => array('author', 'container-inline')),
       '#title' => t('Author'),
-      '#markup' => $node->getAuthor()->getUsername(),
+      '#markup' => $node->getOwner()->getUsername(),
     ),
   );
   $form['revision_information']['#type'] = 'container';
