diff --git a/core/modules/comment/src/CommentViewBuilder.php b/core/modules/comment/src/CommentViewBuilder.php
index bf0f526..df371d2 100644
--- a/core/modules/comment/src/CommentViewBuilder.php
+++ b/core/modules/comment/src/CommentViewBuilder.php
@@ -2,12 +2,13 @@
 
 /**
  * @file
- * Contents Drupal\comment\CommentViewBuilder.
+ * Definition of Drupal\comment\CommentViewBuilder.
  */
 
 namespace Drupal\comment;
 
 use Drupal\Core\Cache\Cache;
+use Drupal\comment\Entity\Comment;
 use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityViewBuilder;
@@ -130,6 +131,132 @@ public function buildComponents(array &$build, array $entities, array $displays,
   }
 
   /**
+   * #post_render_cache callback; replaces the placeholder with comment links.
+   *
+   * Renders the links on a comment.
+   *
+   * @param array $element
+   *   The renderable array that contains the to be replaced placeholder.
+   * @param array $context
+   *   An array with the following keys:
+   *   - comment_entity_id: a comment entity ID
+   *   - view_mode: the view mode in which the comment entity is being viewed
+   *   - langcode: in which language the comment entity is being viewed
+   *   - commented_entity_type: the entity type to which the comment is attached
+   *   - commented_entity_id: the entity ID to which the comment is attached
+   *   - in_preview: whether the comment is currently being previewed
+   *
+   * @return array
+   *   A renderable array representing the comment links.
+   */
+  public static function renderLinks(array $element, array $context) {
+    $callback = get_called_class() . '::renderLinks';
+    $placeholder = drupal_render_cache_generate_placeholder($callback, $context);
+    $links = array(
+      '#theme' => 'links__comment',
+      '#pre_render' => array('drupal_pre_render_links'),
+      '#attributes' => array('class' => array('links', 'inline')),
+    );
+
+    if (!$context['in_preview']) {
+      /**
+       * @var $comment CommentInterface
+       */
+      $comment = Comment::load($context['comment_entity_id']);
+      $commented_entity = $comment->getCommentedEntity();
+
+      $links['comment'] = static::buildLinks($comment, $commented_entity);
+      // Allow other modules to alter the comment links.
+      $hook_context = array(
+        'view_mode' => $context['view_mode'],
+        'langcode' => $context['langcode'],
+        'commented_entity' => $commented_entity
+      );
+      \Drupal::moduleHandler()->alter('comment_links', $links, $comment, $hook_context);
+    }
+    $markup = drupal_render($links);
+    $element['#markup'] = str_replace($placeholder, $markup, $element['#markup']);
+
+    return $element;
+  }
+
+  /**
+   * Build the default links (reply, edit, delete …) for a comment.
+   *
+   * @param \Drupal\comment\CommentInterface $entity
+   *   The comment object.
+   * @param \Drupal\Core\Entity\EntityInterface $commented_entity
+   *   The entity to which the comment is attached.
+   *
+   * @return array
+   *   An array that can be processed by drupal_pre_render_links().
+   */
+  protected static function buildLinks(CommentInterface $entity, EntityInterface $commented_entity) {
+    $links = array();
+    $status = $commented_entity->get($entity->getFieldName())->status;
+
+    $container = \Drupal::getContainer();
+
+    if ($status == CommentItemInterface::OPEN) {
+      if ($entity->access('delete')) {
+        $links['comment-delete'] = array(
+          'title' => t('Delete'),
+          'url' => $entity->urlInfo('delete-form'),
+          'html' => TRUE,
+        );
+      }
+
+      if ($entity->access('update')) {
+        $links['comment-edit'] = array(
+          'title' => t('Edit'),
+          'url' => $entity->urlInfo('edit-form'),
+          'html' => TRUE,
+        );
+      }
+      if ($entity->access('create')) {
+        $links['comment-reply'] = array(
+          'title' => t('Reply'),
+          'url' => Url::fromRoute('comment.reply', [
+            'entity_type' => $entity->getCommentedEntityTypeId(),
+            'entity' => $entity->getCommentedEntityId(),
+            'field_name' => $entity->getFieldName(),
+            'pid' => $entity->id(),
+          ]),
+          'html' => TRUE,
+        );
+      }
+      if (!$entity->isPublished() && $entity->access('approve')) {
+        $links['comment-approve'] = array(
+          'title' => t('Approve'),
+          'url' => Url::fromRoute('comment.approve', ['comment' => $entity->id()]),
+          'html' => TRUE,
+        );
+      }
+      if (empty($links) && \Drupal::currentUser()->isAnonymous()) {
+        $links['comment-forbidden']['title'] = \Drupal::service('comment.manager')->forbiddenMessage($commented_entity, $entity->getFieldName());
+        $links['comment-forbidden']['html'] = TRUE;
+      }
+    }
+
+    // Add translations link for translation-enabled comment bundles.
+    if (\Drupal::moduleHandler()->moduleExists('content_translation') && content_translation_translate_access($entity)->isAllowed()) {
+      $links['comment-translations'] = array(
+        'title' => t('Translate'),
+        'url' => $entity->urlInfo('drupal:content-translation-overview'),
+        'html' => TRUE,
+      );
+    }
+
+    return array(
+      '#theme' => 'links__comment__comment',
+      // The "entity" property is specified to be present, so no need to
+      // check.
+      '#links' => $links,
+      '#attributes' => array('class' => array('links', 'inline')),
+    );
+  }
+
+  /**
    * {@inheritdoc}
    */
   protected function alterBuild(array &$build, EntityInterface $comment, EntityViewDisplayInterface $display, $view_mode, $langcode = NULL) {
@@ -158,4 +285,52 @@ protected function alterBuild(array &$build, EntityInterface $comment, EntityVie
     }
   }
 
+  /**
+   * #post_render_cache callback; attaches "X new comments" link metadata.
+   *
+   * @param array $element
+   *   A render array with the following keys:
+   *   - #markup
+   *   - #attached
+   * @param array $context
+   *   An array with the following keys:
+   *   - entity_type: an entity type
+   *   - entity_id: an entity ID
+   *   - field_name: a comment field name
+   *
+   * @return array $element
+   *   The updated $element.
+   */
+  public static function attachNewCommentsLinkMetadata(array $element, array $context) {
+    // Build "X new comments" link metadata.
+    $new = \Drupal::service('comment.manager')
+      ->getCountNewComments(entity_load($context['entity_type'], $context['entity_id']));
+    // Early-return if there are zero new comments for the current user.
+    if ($new === 0) {
+      return $element;
+    }
+    $entity = \Drupal::entityManager()
+      ->getStorage($context['entity_type'])
+      ->load($context['entity_id']);
+    $field_name = $context['field_name'];
+    $page_number = \Drupal::entityManager()
+      ->getStorage('comment')
+      ->getNewCommentPageNumber($entity->{$field_name}->comment_count, $new, $entity);
+    $query = $page_number ? array('page' => $page_number) : NULL;
+
+    // Attach metadata.
+    $element['#attached']['drupalSettings']['comment']['newCommentsLinks'] = [
+      $context['entity_type'] => [
+        $context['field_name'] => [
+          $context['entity_id'] => [
+            'new_comment_count' => (int)$new,
+            'first_new_comment_link' => \Drupal::urlGenerator()->generateFromPath('node/' . $entity->id(), ['query' => $query, 'fragment' => 'new']),
+          ],
+        ],
+      ],
+    ];
+
+    return $element;
+  }
+
 }
diff --git a/core/modules/comment/src/Plugin/views/row/Rss.php b/core/modules/comment/src/Plugin/views/row/Rss.php
index 2412892..28b9efa 100644
--- a/core/modules/comment/src/Plugin/views/row/Rss.php
+++ b/core/modules/comment/src/Plugin/views/row/Rss.php
@@ -7,7 +7,9 @@
 
 namespace Drupal\comment\Plugin\views\row;
 
+use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\views\Plugin\views\row\RssPluginBase;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Plugin which formats the comments as RSS items.
@@ -35,6 +37,38 @@ class Rss extends RssPluginBase {
   protected $base_field = 'cid';
 
   /**
+   * @var EntityManagerInterface
+   */
+  protected $entityManager;
+
+  /**
+   * @var \Drupal\comment\CommentInterface[]
+   */
+  protected $comments;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $entity_manager) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_manager);
+
+    $this->definition = $plugin_definition + $configuration;
+    $this->entityManager = $entity_manager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('entity.manager')
+    );
+  }
+
+  /**
    * {@inheritdoc}
    */
   protected $entityTypeId = 'comment';
@@ -46,7 +80,7 @@ public function preRender($result) {
       $cids[] = $row->cid;
     }
 
-    $this->comments = entity_load_multiple('comment', $cids);
+    $this->comments = $this->entityManager->getStorage('comment')->loadMultiple($cids);
     foreach ($this->comments as $comment) {
       $comment->depth = count(explode('.', $comment->getThread())) - 1;
     }
diff --git a/core/modules/comment/src/Tests/CommentNonNodeTest.php b/core/modules/comment/src/Tests/CommentNonNodeTest.php
index b4fabee..dc848a9 100644
--- a/core/modules/comment/src/Tests/CommentNonNodeTest.php
+++ b/core/modules/comment/src/Tests/CommentNonNodeTest.php
@@ -8,6 +8,7 @@
 namespace Drupal\comment\Tests;
 
 use Drupal\comment\CommentInterface;
+use Drupal\comment\Entity\Comment;
 use Drupal\comment\Entity\CommentType;
 use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
 use Drupal\field\Entity\FieldConfig;
@@ -163,7 +164,7 @@ function postComment(EntityInterface $entity, $comment, $subject = '', $contact
     }
 
     if (isset($match[1])) {
-      return entity_load('comment', $match[1]);
+      return Comment::load($match[1]);
     }
   }
 
diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateCommentTest.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateCommentTest.php
index e72731c..ed52fe9 100644
--- a/core/modules/migrate_drupal/src/Tests/d6/MigrateCommentTest.php
+++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateCommentTest.php
@@ -76,23 +76,26 @@ protected function setUp() {
    * Tests the Drupal 6 to Drupal 8 comment migration.
    */
   public function testComments() {
+    /** @var EntityStorageInterface */
+    $comment_storage = $this->container->get('entity.manager')->getStorage('comment');
     /** @var \Drupal\comment\CommentInterface $comment */
-    $comment = entity_load('comment', 1);
-    $this->assertIdentical('The first comment.', $comment->getSubject());
-    $this->assertIdentical('The first comment body.', $comment->comment_body->value);
-    $this->assertIdentical('filtered_html', $comment->comment_body->format);
-    $this->assertIdentical('0', $comment->pid->target_id);
-    $this->assertIdentical('1', $comment->getCommentedEntityId());
-    $this->assertIdentical('node', $comment->getCommentedEntityTypeId());
-    $this->assertIdentical('en', $comment->language()->getId());
-    $this->assertIdentical('comment_no_subject', $comment->getTypeId());
 
-    $comment = entity_load('comment', 2);
-    $this->assertIdentical('The response to the second comment.', $comment->subject->value);
-    $this->assertIdentical('3', $comment->pid->target_id);
+    $comment = $comment_storage->load(1);
+    $this->assertEqual('The first comment.', $comment->getSubject());
+    $this->assertEqual('The first comment body.', $comment->comment_body->value);
+    $this->assertEqual('filtered_html', $comment->comment_body->format);
+    $this->assertEqual(0, $comment->pid->target_id);
+    $this->assertEqual(1, $comment->getCommentedEntityId());
+    $this->assertEqual('node', $comment->getCommentedEntityTypeId());
+    $this->assertEqual('en', $comment->language()->getId());
+    $this->assertEqual('comment_no_subject', $comment->getTypeId());
 
-    $comment = entity_load('comment', 3);
-    $this->assertIdentical('The second comment.', $comment->subject->value);
-    $this->assertIdentical('0', $comment->pid->target_id);
+    $comment = $comment_storage->load(2);
+    $this->assertEqual('The response to the second comment.', $comment->subject->value);
+    $this->assertEqual(3, $comment->pid->target_id);
+
+    $comment = $comment_storage->load(3);
+    $this->assertEqual('The second comment.', $comment->subject->value);
+    $this->assertEqual(0, $comment->pid->target_id);
   }
 }
diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateCommentTypeTest.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateCommentTypeTest.php
index d5fffb6..956171a 100644
--- a/core/modules/migrate_drupal/src/Tests/d6/MigrateCommentTypeTest.php
+++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateCommentTypeTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\migrate_drupal\Tests\d6;
 
+use Drupal\comment\Entity\CommentType;
 use Drupal\migrate\MigrateExecutable;
 use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
 
@@ -41,10 +42,10 @@ protected function setUp() {
    * Tests the Drupal 6 to Drupal 8 comment type migration.
    */
   public function testCommentType() {
-    $comment_type = entity_load('comment_type', 'comment');
-    $this->assertIdentical('node', $comment_type->getTargetEntityTypeId());
-    $comment_type = entity_load('comment_type', 'comment_no_subject');
-    $this->assertIdentical('node', $comment_type->getTargetEntityTypeId());
+    $comment_type = CommentType::load('comment');
+    $this->assertEqual('node', $comment_type->getTargetEntityTypeId());
+    $comment_type = CommentType::load('comment_no_subject');
+    $this->assertEqual('node', $comment_type->getTargetEntityTypeId());
   }
 
 }
