diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/StringFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/StringFormatter.php
index 95ab0b2cf4..23e8a1100e 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/StringFormatter.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/StringFormatter.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Core\Field\Plugin\Field\FieldFormatter;
 
+use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldItemInterface;
@@ -117,7 +118,7 @@ public function viewElements(FieldItemListInterface $items, $langcode) {
     $url = NULL;
     if ($this->getSetting('link_to_entity')) {
       // For the default revision this falls back to 'canonical'
-      $url = $items->getEntity()->urlInfo('revision');
+      $url = $this->getEntityUrl($items->getEntity());
     }
 
     foreach ($items as $delta => $item) {
@@ -155,4 +156,18 @@ protected function viewValue(FieldItemInterface $item) {
     ];
   }
 
+  /**
+   * Gets the URI elements of the entity.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $entity
+   *   The entity object.
+   *
+   * @return \Drupal\Core\Url
+   *   The URI elements of the entity.
+   */
+  protected function getEntityUrl(EntityInterface $entity) {
+    // For the default revision this falls back to 'canonical'.
+    return $entity->toUrl('revision');
+  }
+
 }
diff --git a/core/modules/comment/comment.post_update.php b/core/modules/comment/comment.post_update.php
new file mode 100644
index 0000000000..04bf2db28d
--- /dev/null
+++ b/core/modules/comment/comment.post_update.php
@@ -0,0 +1,38 @@
+<?php
+
+/**
+ * @file
+ * Post update functions for the comment module.
+ */
+
+use Drupal\Core\Config\FileStorage;
+use Drupal\Core\Config\InstallStorage;
+
+/**
+ * Enable the comment admin view.
+ */
+function comment_post_update_enable_comment_admin_view() {
+  $module_handler = \Drupal::moduleHandler();
+  $entity_type_manager = \Drupal::entityTypeManager();
+
+  // Save the comment delete action to config.
+  $config_install_path = $module_handler->getModule('comment')->getPath() . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY;
+  $storage = new FileStorage($config_install_path);
+  $entity_type_manager
+    ->getStorage('action')
+    ->create($storage->read('system.action.comment_delete_action'))
+    ->save();
+
+  // Only create if the views module is enabled.
+  if (!$module_handler->moduleExists('views')) {
+    return;
+  }
+
+  // Save the comment admin view to config.
+  $optional_install_path = $module_handler->getModule('comment')->getPath() . '/' . InstallStorage::CONFIG_OPTIONAL_DIRECTORY;
+  $storage = new FileStorage($optional_install_path);
+  $entity_type_manager
+    ->getStorage('view')
+    ->create($storage->read('views.view.comment'))
+    ->save();
+}
diff --git a/core/modules/comment/comment.routing.yml b/core/modules/comment/comment.routing.yml
index 3d698b837a..80ee86c795 100644
--- a/core/modules/comment/comment.routing.yml
+++ b/core/modules/comment/comment.routing.yml
@@ -2,7 +2,7 @@ comment.admin:
   path: '/admin/content/comment'
   defaults:
     _title: 'Comments'
-    _controller: '\Drupal\comment\Controller\AdminController::adminPage'
+    _form: '\Drupal\comment\Form\CommentAdminOverview'
     type: 'new'
   requirements:
     _permission: 'administer comments'
@@ -11,7 +11,7 @@ comment.admin_approval:
   path: '/admin/content/comment/approval'
   defaults:
     _title: 'Unapproved comments'
-    _controller: '\Drupal\comment\Controller\AdminController::adminPage'
+    _form: '\Drupal\comment\Form\CommentAdminOverview'
     type: 'approval'
   requirements:
     _permission: 'administer comments'
@@ -54,6 +54,14 @@ entity.comment.delete_form:
     _entity_access: 'comment.delete'
     comment: \d+
 
+comment.multiple_delete_confirm:
+  path: '/admin/content/comment/delete'
+  defaults:
+    _title: 'Delete'
+    _form: '\Drupal\comment\Form\ConfirmDeleteMultiple'
+  requirements:
+    _permission: 'administer comments'
+
 comment.reply:
   path: '/comment/reply/{entity_type}/{entity}/{field_name}/{pid}'
   defaults:
diff --git a/core/modules/comment/config/install/system.action.comment_delete_action.yml b/core/modules/comment/config/install/system.action.comment_delete_action.yml
new file mode 100644
index 0000000000..035299ea12
--- /dev/null
+++ b/core/modules/comment/config/install/system.action.comment_delete_action.yml
@@ -0,0 +1,10 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - comment
+id: comment_delete_action
+label: 'Delete comment'
+type: comment
+plugin: comment_delete_action
+configuration: {  }
diff --git a/core/modules/comment/config/optional/views.view.comment.yml b/core/modules/comment/config/optional/views.view.comment.yml
new file mode 100644
index 0000000000..52e6613a0d
--- /dev/null
+++ b/core/modules/comment/config/optional/views.view.comment.yml
@@ -0,0 +1,1053 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - comment
+    - user
+id: comment
+label: Comments
+module: comment
+description: 'Find and manage comments.'
+tag: default
+base_table: comment_field_data
+base_field: cid
+core: 8.x
+display:
+  default:
+    display_plugin: default
+    id: default
+    display_title: Master
+    position: 0
+    display_options:
+      access:
+        type: perm
+        options:
+          perm: 'administer comments'
+      cache:
+        type: tag
+        options: {  }
+      query:
+        type: views_query
+        options:
+          disable_sql_rewrite: false
+          distinct: false
+          replica: false
+          query_comment: ''
+          query_tags: {  }
+      exposed_form:
+        type: basic
+        options:
+          submit_button: Apply
+          reset_button: false
+          reset_button_label: Reset
+          exposed_sorts_label: 'Sort by'
+          expose_sort_order: true
+          sort_asc_label: Asc
+          sort_desc_label: Desc
+      pager:
+        type: full
+        options:
+          items_per_page: 50
+          offset: 0
+          id: 0
+          total_pages: null
+          tags:
+            previous: '‹ previous'
+            next: 'next ›'
+            first: '« first'
+            last: 'last »'
+          expose:
+            items_per_page: false
+            items_per_page_label: 'Items per page'
+            items_per_page_options: '5, 10, 25, 50'
+            items_per_page_options_all: false
+            items_per_page_options_all_label: '- All -'
+            offset: false
+            offset_label: Offset
+          quantity: 9
+      style:
+        type: table
+        options:
+          grouping: {  }
+          row_class: ''
+          default_row_class: true
+          override: true
+          sticky: true
+          caption: ''
+          summary: ''
+          description: ''
+          columns:
+            comment_bulk_form: comment_bulk_form
+            subject: subject
+            uid: uid
+            entity_id: entity_id
+            changed: changed
+            operations: operations
+          info:
+            comment_bulk_form:
+              align: ''
+              separator: ''
+              empty_column: false
+              responsive: ''
+            subject:
+              sortable: true
+              default_sort_order: asc
+              align: ''
+              separator: ''
+              empty_column: false
+              responsive: ''
+            uid:
+              sortable: true
+              default_sort_order: asc
+              align: ''
+              separator: ''
+              empty_column: false
+              responsive: ''
+            entity_id:
+              sortable: false
+              default_sort_order: asc
+              align: ''
+              separator: ''
+              empty_column: false
+              responsive: ''
+            changed:
+              sortable: true
+              default_sort_order: desc
+              align: ''
+              separator: ''
+              empty_column: false
+              responsive: priority-low
+            operations:
+              sortable: false
+              default_sort_order: asc
+              align: ''
+              separator: ''
+              empty_column: false
+              responsive: ''
+          default: changed
+          empty_table: true
+      row:
+        type: fields
+      fields:
+        comment_bulk_form:
+          id: comment_bulk_form
+          table: comment
+          field: comment_bulk_form
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: ''
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: false
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          action_title: 'Update Options'
+          include_exclude: include
+          selected_actions:
+            - comment_delete_action
+            - comment_unpublish_action
+          plugin_id: comment_bulk_form
+          entity_type: comment
+        subject:
+          id: subject
+          table: comment_field_data
+          field: subject
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Subject
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: value
+          type: comment_permalink
+          settings:
+            link_to_entity: true
+          group_column: value
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+          entity_type: comment
+          entity_field: subject
+          plugin_id: field
+        uid:
+          id: uid
+          table: comment_field_data
+          field: uid
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Author
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: target_id
+          type: entity_reference_label
+          settings:
+            link: true
+          group_column: target_id
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+          entity_type: comment
+          entity_field: uid
+          plugin_id: field
+        entity_id:
+          id: entity_id
+          table: comment_field_data
+          field: entity_id
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: 'Posted in'
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: target_id
+          type: entity_reference_label
+          settings:
+            link: true
+          group_column: target_id
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+          entity_type: comment
+          entity_field: entity_id
+          plugin_id: commented_entity
+        changed:
+          id: changed
+          table: comment_field_data
+          field: changed
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Updated
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: value
+          type: timestamp
+          settings:
+            date_format: short
+            custom_date_format: ''
+            timezone: ''
+          group_column: value
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+          entity_type: comment
+          entity_field: changed
+          plugin_id: field
+        operations:
+          id: operations
+          table: comment
+          field: operations
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Operations
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          destination: true
+          entity_type: comment
+          plugin_id: entity_operations
+      filters:
+        status:
+          id: status
+          table: comment_field_data
+          field: status
+          relationship: none
+          group_type: group
+          admin_label: ''
+          operator: '='
+          value: '1'
+          group: 1
+          exposed: false
+          expose:
+            operator_id: ''
+            label: ''
+            description: ''
+            use_operator: false
+            operator: ''
+            identifier: ''
+            required: false
+            remember: false
+            multiple: false
+            remember_roles:
+              authenticated: authenticated
+          is_grouped: false
+          group_info:
+            label: ''
+            description: ''
+            identifier: ''
+            optional: true
+            widget: select
+            multiple: false
+            remember: false
+            default_group: All
+            default_group_multiple: {  }
+            group_items: {  }
+          entity_type: comment
+          entity_field: status
+          plugin_id: boolean
+      sorts:
+        changed:
+          id: changed
+          table: comment_field_data
+          field: changed
+          relationship: none
+          group_type: group
+          admin_label: ''
+          order: DESC
+          exposed: false
+          expose:
+            label: ''
+          granularity: second
+          entity_type: comment
+          entity_field: changed
+          plugin_id: date
+      title: Comments
+      header: {  }
+      footer: {  }
+      empty:
+        area_text_custom:
+          id: area_text_custom
+          table: views
+          field: area_text_custom
+          relationship: none
+          group_type: group
+          admin_label: ''
+          empty: true
+          tokenize: false
+          content: 'No comments available.'
+          plugin_id: text_custom
+      arguments: {  }
+      display_extenders: {  }
+      use_more: false
+      use_more_always: true
+      use_more_text: more
+      use_ajax: false
+      hide_attachment_summary: false
+      show_admin_links: true
+      group_by: false
+      css_class: ''
+    cache_metadata:
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url.query_args
+        - user.permissions
+      cacheable: false
+      max-age: 0
+      tags: {  }
+  page_1:
+    display_plugin: page
+    id: page_1
+    display_title: 'Published Comments'
+    position: 1
+    display_options:
+      path: admin/content/comment
+      menu:
+        type: tab
+        title: Comments
+        description: 'Comments published'
+        parent: ''
+        weight: 0
+        context: '0'
+        menu_name: admin
+      display_description: ''
+      display_extenders: {  }
+      exposed_block: false
+      display_comment: ''
+    cache_metadata:
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url.query_args
+        - user.permissions
+      cacheable: false
+      max-age: 0
+      tags: {  }
+  page_2:
+    display_plugin: page
+    id: page_2
+    display_title: 'Unapproved Comments'
+    position: 2
+    display_options:
+      path: admin/content/comment/approval
+      menu:
+        type: tab
+        title: 'Unapproved comments'
+        description: 'Comments unapproved'
+        parent: ''
+        weight: 1
+        context: '0'
+        menu_name: admin
+      display_description: ''
+      filters:
+        status:
+          id: status
+          table: comment_field_data
+          field: status
+          relationship: none
+          group_type: group
+          admin_label: ''
+          operator: '='
+          value: '0'
+          group: 1
+          exposed: false
+          expose:
+            operator_id: ''
+            label: ''
+            description: ''
+            use_operator: false
+            operator: ''
+            identifier: ''
+            required: false
+            remember: false
+            multiple: false
+            remember_roles:
+              authenticated: authenticated
+          is_grouped: false
+          group_info:
+            label: ''
+            description: ''
+            identifier: ''
+            optional: true
+            widget: select
+            multiple: false
+            remember: false
+            default_group: All
+            default_group_multiple: {  }
+            group_items: {  }
+          entity_type: comment
+          entity_field: status
+          plugin_id: boolean
+      defaults:
+        filters: false
+        filter_groups: false
+        fields: false
+      display_extenders: {  }
+      fields:
+        comment_bulk_form:
+          id: comment_bulk_form
+          table: comment
+          field: comment_bulk_form
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: ''
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: false
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          action_title: 'Update Options'
+          include_exclude: include
+          selected_actions:
+            - comment_delete_action
+            - comment_publish_action
+          plugin_id: comment_bulk_form
+          entity_type: comment
+        subject:
+          id: subject
+          table: comment_field_data
+          field: subject
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Subject
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: value
+          type: comment_permalink
+          settings:
+            link_to_entity: true
+          group_column: value
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+          entity_type: comment
+          entity_field: subject
+          plugin_id: field
+        name:
+          id: name
+          table: comment_field_data
+          field: name
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Author
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: value
+          type: comment_username
+          settings: {  }
+          group_column: value
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+          entity_type: comment
+          entity_field: name
+          plugin_id: field
+        entity_id:
+          id: entity_id
+          table: comment_field_data
+          field: entity_id
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: 'Posted in'
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: target_id
+          type: entity_reference_label
+          settings:
+            link: true
+          group_column: target_id
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+          entity_type: comment
+          entity_field: entity_id
+          plugin_id: commented_entity
+        changed:
+          id: changed
+          table: comment_field_data
+          field: changed
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Updated
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: value
+          type: timestamp
+          settings:
+            date_format: short
+            custom_date_format: ''
+            timezone: ''
+          group_column: value
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+          entity_type: comment
+          entity_field: changed
+          plugin_id: field
+        operations:
+          id: operations
+          table: comment
+          field: operations
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Operations
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          destination: true
+          entity_type: comment
+          plugin_id: entity_operations
+    cache_metadata:
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url.query_args
+        - user.permissions
+      cacheable: false
+      max-age: 0
+      tags: {  }
diff --git a/core/modules/comment/config/schema/comment.schema.yml b/core/modules/comment/config/schema/comment.schema.yml
index a55488a222..045e9ad544 100644
--- a/core/modules/comment/config/schema/comment.schema.yml
+++ b/core/modules/comment/config/schema/comment.schema.yml
@@ -38,6 +38,10 @@ action.configuration.comment_unpublish_action:
   type: action_configuration_default
   label: 'Unpublish comment configuration'
 
+action.configuration.comment_delete_action:
+  type: action_configuration_default
+  label: 'Delete comment configuration'
+
 comment.type.*:
   type: config_entity
   label: 'Comment type settings'
@@ -105,3 +109,6 @@ field.field_settings.comment:
     preview:
       type: integer
       label: 'Preview comment'
+
+field.formatter.settings.comment_permalink:
+  type: field.formatter.settings.string
diff --git a/core/modules/comment/config/schema/comment.views.schema.yml b/core/modules/comment/config/schema/comment.views.schema.yml
index 606af826cd..a46a004d73 100644
--- a/core/modules/comment/config/schema/comment.views.schema.yml
+++ b/core/modules/comment/config/schema/comment.views.schema.yml
@@ -16,6 +16,14 @@ views.field.comment_entity_link:
       type: boolean
       label: 'Show teaser-style link'
 
+views.field.comment_bulk_form:
+  type: views_field_bulk_form
+  label: 'Comment bulk form'
+
+views.field.commented_entity:
+  type: views.field.field
+  label: 'Commented entity'
+
 views.field.comment_last_timestamp:
   type: views.field.date
   label: 'Last comment date'
diff --git a/core/modules/comment/src/CommentViewsData.php b/core/modules/comment/src/CommentViewsData.php
index 52af015d59..ead61c1a33 100644
--- a/core/modules/comment/src/CommentViewsData.php
+++ b/core/modules/comment/src/CommentViewsData.php
@@ -23,6 +23,7 @@ public function getViewsData() {
 
     $data['comment_field_data']['subject']['title'] = $this->t('Title');
     $data['comment_field_data']['subject']['help'] = $this->t('The title of the comment.');
+    $data['comment_field_data']['subject']['field']['default_formatter'] = 'comment_permalink';
 
     $data['comment_field_data']['name']['title'] = $this->t('Author');
     $data['comment_field_data']['name']['help'] = $this->t("The name of the comment's author. Can be rendered as a link to the author's homepage.");
@@ -168,6 +169,17 @@ public function getViewsData() {
       ],
     ];
 
+    $data['comment_field_data']['entity_id']['field']['id'] = 'commented_entity';
+    unset($data['comment_field_data']['entity_id']['relationship']);
+
+    $data['comment']['comment_bulk_form'] = [
+      'title' => $this->t('Comment operations bulk form'),
+      'help' => $this->t('Add a form element that lets you run operations on multiple comments.'),
+      'field' => [
+        'id' => 'comment_bulk_form',
+      ],
+    ];
+
     $data['comment_field_data']['thread']['field'] = [
       'title' => $this->t('Depth'),
       'help' => $this->t('Display the depth of the comment if it is threaded.'),
diff --git a/core/modules/comment/src/Controller/AdminController.php b/core/modules/comment/src/Controller/AdminController.php
deleted file mode 100644
index 61cb8761dd..0000000000
--- a/core/modules/comment/src/Controller/AdminController.php
+++ /dev/null
@@ -1,62 +0,0 @@
-<?php
-
-namespace Drupal\comment\Controller;
-
-use Drupal\Core\Controller\ControllerBase;
-use Drupal\Core\Form\FormBuilderInterface;
-use Symfony\Component\HttpFoundation\Request;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Returns responses for comment module administrative routes.
- */
-class AdminController extends ControllerBase {
-
-  /**
-   * The form builder.
-   *
-   * @var \Drupal\Core\Form\FormBuilderInterface
-   */
-  protected $formBuilder;
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container) {
-    return new static(
-      $container->get('form_builder')
-    );
-  }
-
-  /**
-   * Constructs an AdminController object.
-   *
-   * @param \Drupal\Core\Form\FormBuilderInterface $form_builder
-   *   The form builder.
-   */
-  public function __construct(FormBuilderInterface $form_builder) {
-    $this->formBuilder = $form_builder;
-  }
-
-  /**
-   * Presents an administrative comment listing.
-   *
-   * @param \Symfony\Component\HttpFoundation\Request $request
-   *   The request of the page.
-   * @param string $type
-   *   The type of the overview form ('approval' or 'new') default to 'new'.
-   *
-   * @return array
-   *   Then comment multiple delete confirmation form or the comments overview
-   *   administration form.
-   */
-  public function adminPage(Request $request, $type = 'new') {
-    if ($request->request->get('operation') == 'delete' && $request->request->get('comments')) {
-      return $this->formBuilder->getForm('\Drupal\comment\Form\ConfirmDeleteMultiple', $request);
-    }
-    else {
-      return $this->formBuilder->getForm('\Drupal\comment\Form\CommentAdminOverview', $type);
-    }
-  }
-
-}
diff --git a/core/modules/comment/src/Form/CommentAdminOverview.php b/core/modules/comment/src/Form/CommentAdminOverview.php
index 24f8b0aa2e..445138d475 100644
--- a/core/modules/comment/src/Form/CommentAdminOverview.php
+++ b/core/modules/comment/src/Form/CommentAdminOverview.php
@@ -3,13 +3,13 @@
 namespace Drupal\comment\Form;
 
 use Drupal\comment\CommentInterface;
-use Drupal\comment\CommentStorageInterface;
 use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Datetime\DateFormatterInterface;
-use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\user\PrivateTempStoreFactory;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -18,11 +18,11 @@
 class CommentAdminOverview extends FormBase {
 
   /**
-   * The entity storage.
+   * The entity type manager.
    *
-   * @var \Drupal\Core\Entity\EntityManagerInterface
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
    */
-  protected $entityManager;
+  protected $entityTypeManager;
 
   /**
    * The comment storage.
@@ -46,22 +46,30 @@ class CommentAdminOverview extends FormBase {
   protected $moduleHandler;
 
   /**
+   * The tempstore factory.
+   *
+   * @var \Drupal\user\PrivateTempStoreFactory
+   */
+  protected $tempStoreFactory;
+
+  /**
    * Creates a CommentAdminOverview form.
    *
-   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
    *   The entity manager service.
-   * @param \Drupal\comment\CommentStorageInterface $comment_storage
-   *   The comment storage.
    * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
    *   The date formatter service.
    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
    *   The module handler.
+   * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
+   *   The tempstore factory.
    */
-  public function __construct(EntityManagerInterface $entity_manager, CommentStorageInterface $comment_storage, DateFormatterInterface $date_formatter, ModuleHandlerInterface $module_handler) {
-    $this->entityManager = $entity_manager;
-    $this->commentStorage = $comment_storage;
+  public function __construct(EntityTypeManagerInterface $entity_type_manager, DateFormatterInterface $date_formatter, ModuleHandlerInterface $module_handler, PrivateTempStoreFactory $temp_store_factory) {
+    $this->entityTypeManager = $entity_type_manager;
+    $this->commentStorage = $entity_type_manager->getStorage('comment');
     $this->dateFormatter = $date_formatter;
     $this->moduleHandler = $module_handler;
+    $this->tempStoreFactory = $temp_store_factory;
   }
 
   /**
@@ -69,10 +77,10 @@ public function __construct(EntityManagerInterface $entity_manager, CommentStora
    */
   public static function create(ContainerInterface $container) {
     return new static(
-      $container->get('entity.manager'),
-      $container->get('entity.manager')->getStorage('comment'),
+      $container->get('entity_type.manager'),
       $container->get('date.formatter'),
-      $container->get('module_handler')
+      $container->get('module_handler'),
+      $container->get('user.private_tempstore')
     );
   }
 
@@ -171,7 +179,9 @@ public function buildForm(array $form, FormStateInterface $form_state, $type = '
     }
 
     foreach ($commented_entity_ids as $entity_type => $ids) {
-      $commented_entities[$entity_type] = $this->entityManager->getStorage($entity_type)->loadMultiple($ids);
+      $commented_entities[$entity_type] = $this->entityTypeManager
+        ->getStorage($entity_type)
+        ->loadMultiple($ids);
     }
 
     foreach ($comments as $comment) {
@@ -255,23 +265,33 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
   public function submitForm(array &$form, FormStateInterface $form_state) {
     $operation = $form_state->getValue('operation');
     $cids = $form_state->getValue('comments');
-
-    foreach ($cids as $cid) {
-      // Delete operation handled in \Drupal\comment\Form\ConfirmDeleteMultiple
-      // see \Drupal\comment\Controller\AdminController::adminPage().
-      if ($operation == 'unpublish') {
-        $comment = $this->commentStorage->load($cid);
-        $comment->setPublished(FALSE);
+    /** @var \Drupal\comment\CommentInterface[] $comments */
+    $comments = $this->commentStorage->loadMultiple($cids);
+    if ($operation != 'delete') {
+      foreach ($comments as $comment) {
+        if ($operation == 'unpublish') {
+          $comment->setPublished(FALSE);
+        }
+        elseif ($operation == 'publish') {
+          $comment->setPublished(TRUE);
+        }
         $comment->save();
       }
-      elseif ($operation == 'publish') {
-        $comment = $this->commentStorage->load($cid);
-        $comment->setPublished(TRUE);
-        $comment->save();
+      drupal_set_message($this->t('The update has been performed.'));
+      $form_state->setRedirect('comment.admin');
+    }
+    else {
+      $info = [];
+      /** @var \Drupal\comment\CommentInterface $comment */
+      foreach ($comments as $comment) {
+        $langcode = $comment->language()->getId();
+        $info[$comment->id()][$langcode] = $langcode;
       }
+      $this->tempStoreFactory
+        ->get('comment_multiple_delete_confirm')
+        ->set($this->currentUser()->id(), $info);
+      $form_state->setRedirect('comment.multiple_delete_confirm');
     }
-    drupal_set_message($this->t('The update has been performed.'));
-    $form_state->setRedirect('comment.admin');
   }
 
 }
diff --git a/core/modules/comment/src/Form/ConfirmDeleteMultiple.php b/core/modules/comment/src/Form/ConfirmDeleteMultiple.php
index 5906248316..3752ddd661 100644
--- a/core/modules/comment/src/Form/ConfirmDeleteMultiple.php
+++ b/core/modules/comment/src/Form/ConfirmDeleteMultiple.php
@@ -3,7 +3,7 @@
 namespace Drupal\comment\Form;
 
 use Drupal\comment\CommentStorageInterface;
-use Drupal\Component\Utility\Html;
+use Drupal\user\PrivateTempStoreFactory;
 use Drupal\Core\Form\ConfirmFormBase;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Url;
@@ -15,6 +15,13 @@
 class ConfirmDeleteMultiple extends ConfirmFormBase {
 
   /**
+   * The tempstore factory.
+   *
+   * @var \Drupal\user\PrivateTempStoreFactory
+   */
+  protected $tempStoreFactory;
+
+  /**
    * The comment storage.
    *
    * @var \Drupal\comment\CommentStorageInterface
@@ -24,18 +31,21 @@ class ConfirmDeleteMultiple extends ConfirmFormBase {
   /**
    * An array of comments to be deleted.
    *
-   * @var \Drupal\comment\CommentInterface[]
+   * @var string[][]
    */
-  protected $comments;
+  protected $commentInfo;
 
   /**
    * Creates an new ConfirmDeleteMultiple form.
    *
    * @param \Drupal\comment\CommentStorageInterface $comment_storage
    *   The comment storage.
+   * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
+   *   The tempstore factory.
    */
-  public function __construct(CommentStorageInterface $comment_storage) {
+  public function __construct(CommentStorageInterface $comment_storage, PrivateTempStoreFactory $temp_store_factory) {
     $this->commentStorage = $comment_storage;
+    $this->tempStoreFactory = $temp_store_factory;
   }
 
   /**
@@ -43,7 +53,8 @@ public function __construct(CommentStorageInterface $comment_storage) {
    */
   public static function create(ContainerInterface $container) {
     return new static(
-      $container->get('entity.manager')->getStorage('comment')
+      $container->get('entity.manager')->getStorage('comment'),
+      $container->get('user.private_tempstore')
     );
   }
 
@@ -58,7 +69,7 @@ public function getFormId() {
    * {@inheritdoc}
    */
   public function getQuestion() {
-    return $this->t('Are you sure you want to delete these comments and all their children?');
+    return $this->formatPlural(count($this->commentInfo), 'Are you sure you want to delete this comment and all its children?', 'Are you sure you want to delete these comments and all their children?');
   }
 
   /**
@@ -72,39 +83,56 @@ public function getCancelUrl() {
    * {@inheritdoc}
    */
   public function getConfirmText() {
-    return $this->t('Delete comments');
+    return $this->t('Delete');
   }
 
   /**
    * {@inheritdoc}
    */
   public function buildForm(array $form, FormStateInterface $form_state) {
-    $edit = $form_state->getUserInput();
+    $this->commentInfo = $this->tempStoreFactory->get('comment_multiple_delete_confirm')->get($this->currentUser()->id());
+    if (empty($this->commentInfo)) {
+      return $this->redirect('comment.admin');
+    }
+    /** @var \Drupal\comment\CommentInterface[] $comments */
+    $comments = $this->commentStorage->loadMultiple(array_keys($this->commentInfo));
+
+    $items = [];
+    foreach ($this->commentInfo as $id => $langcodes) {
+      foreach ($langcodes as $langcode) {
+        $comment = $comments[$id]->getTranslation($langcode);
+        $key = $id . ':' . $langcode;
+        $default_key = $id . ':' . $comment->getUntranslated()->language()->getId();
+
+        // If we have a translated entity we build a nested list of translations
+        // that will be deleted.
+        $languages = $comment->getTranslationLanguages();
+        if (count($languages) > 1 && $comment->isDefaultTranslation()) {
+          $names = [];
+          foreach ($languages as $translation_langcode => $language) {
+            $names[] = $language->getName();
+            unset($items[$id . ':' . $translation_langcode]);
+          }
+          $items[$default_key] = [
+            'label' => [
+              '#markup' => $this->t('@label (Original translation) - <em>The following content translations will be deleted:</em>', ['@label' => $node->label()]),
+            ],
+            'deleted_translations' => [
+              '#theme' => 'item_list',
+              '#items' => $names,
+            ],
+          ];
+        }
+        elseif (!isset($items[$default_key])) {
+          $items[$key] = $comment->label();
+        }
+      }
+    }
 
     $form['comments'] = [
-      '#prefix' => '<ul>',
-      '#suffix' => '</ul>',
-      '#tree' => TRUE,
+      '#theme' => 'item_list',
+      '#items' => $items,
     ];
-    // array_filter() returns only elements with actual values.
-    $comment_counter = 0;
-    $this->comments = $this->commentStorage->loadMultiple(array_keys(array_filter($edit['comments'])));
-    foreach ($this->comments as $comment) {
-      $cid = $comment->id();
-      $form['comments'][$cid] = [
-        '#type' => 'hidden',
-        '#value' => $cid,
-        '#prefix' => '<li>',
-        '#suffix' => Html::escape($comment->label()) . '</li>'
-      ];
-      $comment_counter++;
-    }
-    $form['operation'] = ['#type' => 'hidden', '#value' => 'delete'];
-
-    if (!$comment_counter) {
-      drupal_set_message($this->t('There do not appear to be any comments to delete, or your selected comment was deleted by another administrator.'));
-      $form_state->setRedirect('comment.admin');
-    }
 
     return parent::buildForm($form, $form_state);
   }
@@ -113,12 +141,56 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    if ($form_state->getValue('confirm')) {
-      $this->commentStorage->delete($this->comments);
-      $count = count($form_state->getValue('comments'));
-      $this->logger('comment')->notice('Deleted @count comments.', ['@count' => $count]);
-      drupal_set_message($this->formatPlural($count, 'Deleted 1 comment.', 'Deleted @count comments.'));
+    if ($form_state->getValue('confirm') && !empty($this->commentInfo)) {
+      $total_count = 0;
+      $delete_comments = [];
+      /** @var \Drupal\Core\Entity\ContentEntityInterface[][] $delete_translations */
+      $delete_translations = [];
+      /** @var \Drupal\comment\CommentInterface[] $comments */
+      $comments = $this->commentStorage->loadMultiple(array_keys($this->commentInfo));
+
+      foreach ($this->commentInfo as $id => $langcodes) {
+        foreach ($langcodes as $langcode) {
+          $comment = $comments[$id]->getTranslation($langcode);
+          if ($comment->isDefaultTranslation()) {
+            $delete_comments[$id] = $comment;
+            unset($delete_translations[$id]);
+            $total_count += count($comment->getTranslationLanguages());
+          }
+          elseif (!isset($delete_comments[$id])) {
+            $delete_translations[$id][] = $comment;
+          }
+        }
+      }
+
+      if ($delete_comments) {
+        $this->commentStorage->delete($delete_comments);
+        $this->logger('content')->notice('Deleted @count comments.', ['@count' => count($delete_comments)]);
+      }
+
+      if ($delete_translations) {
+        $count = 0;
+        foreach ($delete_translations as $id => $translations) {
+          $comment = $comments[$id]->getUntranslated();
+          foreach ($translations as $translation) {
+            $comment->removeTranslation($translation->language()->getId());
+          }
+          $comment->save();
+          $count += count($translations);
+        }
+        if ($count) {
+          $total_count += $count;
+          $this->logger('content')->notice('Deleted @count comment translations.', ['@count' => $count]);
+        }
+      }
+
+      if ($total_count) {
+        drupal_set_message($this->formatPlural($total_count, 'Deleted 1 comment.', 'Deleted @count comments.'));
+      }
+
+      $this->tempStoreFactory->get('comment_multiple_delete_confirm')->delete($this->currentUser()->id());
     }
+
     $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
diff --git a/core/modules/comment/src/Plugin/Action/DeleteComment.php b/core/modules/comment/src/Plugin/Action/DeleteComment.php
new file mode 100644
index 0000000000..7f5651655a
--- /dev/null
+++ b/core/modules/comment/src/Plugin/Action/DeleteComment.php
@@ -0,0 +1,96 @@
+<?php
+
+namespace Drupal\comment\Plugin\Action;
+
+use Drupal\Core\Action\ActionBase;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\user\PrivateTempStoreFactory;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Deletes a comment.
+ *
+ * @Action(
+ *   id = "comment_delete_action",
+ *   label = @Translation("Delete comment"),
+ *   type = "comment",
+ *   confirm_form_route_name = "comment.multiple_delete_confirm"
+ * )
+ */
+class DeleteComment extends ActionBase implements ContainerFactoryPluginInterface {
+
+  /**
+   * The tempstore object.
+   *
+   * @var \Drupal\user\PrivateTempStore
+   */
+  protected $tempStore;
+
+  /**
+   * The current user.
+   *
+   * @var \Drupal\Core\Session\AccountInterface
+   */
+  protected $currentUser;
+
+  /**
+   * Constructs a new DeleteComment object.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin ID for the plugin instance.
+   * @param array $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
+   *   The tempstore factory.
+   */
+  public function __construct(array $configuration, $plugin_id, array $plugin_definition, PrivateTempStoreFactory $temp_store_factory, AccountInterface $current_user) {
+    $this->currentUser = $current_user;
+    $this->tempStore = $temp_store_factory->get('comment_multiple_delete_confirm');
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('user.private_tempstore'),
+      $container->get('current_user')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function executeMultiple(array $entities) {
+    $info = [];
+    /** @var \Drupal\comment\CommentInterface $comment */
+    foreach ($entities as $comment) {
+      $langcode = $comment->language()->getId();
+      $info[$comment->id()][$langcode] = $langcode;
+    }
+    $this->tempStore->set($this->currentUser->id(), $info);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function execute($entity = NULL) {
+    $this->executeMultiple([$entity]);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function access($comment, AccountInterface $account = NULL, $return_as_object = FALSE) {
+    /** @var \Drupal\comment\CommentInterface $comment */
+    return $comment->access('delete', $account, $return_as_object);
+  }
+
+}
diff --git a/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentPermalinkFormatter.php b/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentPermalinkFormatter.php
new file mode 100644
index 0000000000..d579243e17
--- /dev/null
+++ b/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentPermalinkFormatter.php
@@ -0,0 +1,53 @@
+<?php
+
+namespace Drupal\comment\Plugin\Field\FieldFormatter;
+
+use Drupal\Component\Utility\Unicode;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\Core\Field\Plugin\Field\FieldFormatter\StringFormatter;
+
+/**
+ * Plugin implementation of the 'comment_permalink' formatter.
+ *
+ * All the other entities use 'canonical' or 'revision' links to link the entity
+ * to itself but comments use permalink URL.
+ *
+ * @FieldFormatter(
+ *   id = "comment_permalink",
+ *   label = @Translation("Comment Permalink"),
+ *   field_types = {
+ *     "string",
+ *     "uri",
+ *   },
+ *   quickedit = {
+ *     "editor" = "plain_text"
+ *   }
+ * )
+ */
+class CommentPermalinkFormatter extends StringFormatter {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getEntityUrl(EntityInterface $comment) {
+    /** @var $comment \Drupal\comment\CommentInterface */
+    $body = '';
+    if (!empty($comment->comment_body->value)) {
+      $body = $comment->comment_body->value;
+    }
+    $comment_permalink = $comment->permalink();
+    $attributes = $comment_permalink->getOption('attributes') ?: [];
+    $attributes += ['title' => Unicode::truncate($body, 128)];
+    $comment_permalink->setOption('attributes', $attributes);
+    return $comment_permalink;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function isApplicable(FieldDefinitionInterface $field_definition) {
+    return parent::isApplicable($field_definition) && $field_definition->getTargetEntityTypeId() === 'comment' && $field_definition->getName() === 'subject';
+  }
+
+}
diff --git a/core/modules/comment/src/Plugin/views/field/CommentBulkForm.php b/core/modules/comment/src/Plugin/views/field/CommentBulkForm.php
new file mode 100644
index 0000000000..d4283734f7
--- /dev/null
+++ b/core/modules/comment/src/Plugin/views/field/CommentBulkForm.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace Drupal\comment\Plugin\views\field;
+
+use Drupal\system\Plugin\views\field\BulkForm;
+
+/**
+ * Defines a comment operations bulk form element.
+ *
+ * @ViewsField("comment_bulk_form")
+ */
+class CommentBulkForm extends BulkForm {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function emptySelectedMessage() {
+    return $this->t('Select one or more comments to perform the update on.');
+  }
+
+}
diff --git a/core/modules/comment/src/Plugin/views/field/CommentedEntity.php b/core/modules/comment/src/Plugin/views/field/CommentedEntity.php
new file mode 100644
index 0000000000..1f92b70434
--- /dev/null
+++ b/core/modules/comment/src/Plugin/views/field/CommentedEntity.php
@@ -0,0 +1,48 @@
+<?php
+
+namespace Drupal\comment\Plugin\views\field;
+
+use Drupal\views\Plugin\views\field\Field;
+use Drupal\views\ResultRow;
+
+/**
+ * Views field display for commented entity.
+ *
+ * @ViewsField("commented_entity")
+ */
+class CommentedEntity extends Field {
+
+  /**
+   * Array of entities that has comments.
+   *
+   * We use this to load all the commented entities of same entity type at once
+   * to the EntityStorageController static cache.
+   *
+   * @var array
+   */
+  protected $loadedCommentedEntities = [];
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getItems(ResultRow $values) {
+    if (empty($this->loadedCommentedEntities)) {
+      $result = $this->view->result;
+
+      $entity_ids_per_type = [];
+      foreach ($result as $value) {
+        /** @var \Drupal\comment\CommentInterface $comment */
+        if ($comment = $this->getEntity($value)) {
+          $entity_ids_per_type[$comment->getCommentedEntityTypeId()][] = $comment->getCommentedEntityId();
+        }
+      }
+
+      foreach ($entity_ids_per_type as $type => $ids) {
+        $this->loadedCommentedEntities[$type] = $this->entityManager->getStorage($type)->loadMultiple($ids);
+      }
+    }
+
+    return parent::getItems($values);
+  }
+
+}
diff --git a/core/modules/comment/src/Tests/CommentAdminTest.php b/core/modules/comment/src/Tests/CommentAdminTest.php
index 980ad30a26..8bd768d9e2 100644
--- a/core/modules/comment/src/Tests/CommentAdminTest.php
+++ b/core/modules/comment/src/Tests/CommentAdminTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\comment\Tests;
 
+use Drupal\Component\Utility\SafeMarkup;
 use Drupal\user\RoleInterface;
 use Drupal\comment\Entity\Comment;
 
@@ -90,7 +91,7 @@ public function testApprovalAdminInterface() {
     ];
     $this->drupalPostForm(NULL, $edit, t('Update'));
     $this->assertText(t('Are you sure you want to delete these comments and all their children?'), 'Confirmation required.');
-    $this->drupalPostForm(NULL, $edit, t('Delete comments'));
+    $this->drupalPostForm(NULL, [], t('Delete'));
     $this->assertText(t('No comments available.'), 'All comments were deleted.');
     // Test message when no comments selected.
     $edit = [
@@ -98,6 +99,15 @@ public function testApprovalAdminInterface() {
     ];
     $this->drupalPostForm(NULL, $edit, t('Update'));
     $this->assertText(t('Select one or more comments to perform the update on.'));
+
+    // Make sure the label of unpublished node is not visible on listing page.
+    $this->drupalGet('admin/content/comment');
+    $this->postComment($this->node, $this->randomMachineName());
+    $this->drupalGet('admin/content/comment');
+    $this->assertText(SafeMarkup::checkPlain($this->node->label()));
+    $this->node->setPublished(FALSE)->save();
+    $this->drupalGet('admin/content/comment');
+    $this->assertNoText(SafeMarkup::checkPlain($this->node->label()));
   }
 
   /**
diff --git a/core/modules/comment/src/Tests/CommentNonNodeTest.php b/core/modules/comment/src/Tests/CommentNonNodeTest.php
index 3c285d8f1c..c75da84f62 100644
--- a/core/modules/comment/src/Tests/CommentNonNodeTest.php
+++ b/core/modules/comment/src/Tests/CommentNonNodeTest.php
@@ -222,7 +222,7 @@ public function performCommentOperation($comment, $operation, $approval = FALSE)
     $this->drupalPostForm('admin/content/comment' . ($approval ? '/approval' : ''), $edit, t('Update'));
 
     if ($operation == 'delete') {
-      $this->drupalPostForm(NULL, [], t('Delete comments'));
+      $this->drupalPostForm(NULL, [], t('Delete'));
       $this->assertRaw(\Drupal::translation()->formatPlural(1, 'Deleted 1 comment.', 'Deleted @count comments.'), format_string('Operation "@operation" was performed on comment.', ['@operation' => $operation]));
     }
     else {
diff --git a/core/modules/comment/src/Tests/CommentTestBase.php b/core/modules/comment/src/Tests/CommentTestBase.php
index c42d9883c6..e15915ff93 100644
--- a/core/modules/comment/src/Tests/CommentTestBase.php
+++ b/core/modules/comment/src/Tests/CommentTestBase.php
@@ -354,7 +354,7 @@ public function performCommentOperation(CommentInterface $comment, $operation, $
     $this->drupalPostForm('admin/content/comment' . ($approval ? '/approval' : ''), $edit, t('Update'));
 
     if ($operation == 'delete') {
-      $this->drupalPostForm(NULL, [], t('Delete comments'));
+      $this->drupalPostForm(NULL, [], t('Delete'));
       $this->assertRaw(\Drupal::translation()->formatPlural(1, 'Deleted 1 comment.', 'Deleted @count comments.'), format_string('Operation "@operation" was performed on comment.', ['@operation' => $operation]));
     }
     else {
diff --git a/core/modules/comment/src/Tests/Update/CommentAdminViewUpdateTest.php b/core/modules/comment/src/Tests/Update/CommentAdminViewUpdateTest.php
new file mode 100644
index 0000000000..930c152add
--- /dev/null
+++ b/core/modules/comment/src/Tests/Update/CommentAdminViewUpdateTest.php
@@ -0,0 +1,52 @@
+<?php
+
+namespace Drupal\comment\Tests\Update;
+
+use Drupal\system\Tests\Update\UpdatePathTestBase;
+use Drupal\user\Entity\User;
+
+/**
+ * Tests that comment admin view is enabled after update.
+ *
+ * @see comment_post_update_enable_comment_admin_view()
+ *
+ * @group Update
+ */
+class CommentAdminViewUpdateTest extends UpdatePathTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $modules = ['comment', 'views'];
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setDatabaseDumpFiles() {
+    $this->databaseDumpFiles = [
+      __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz',
+    ];
+  }
+
+  /**
+   * Tests that comment admin view is enabled after update.
+   */
+  public function testCommentAdminPostUpdateHook() {
+    $this->runUpdates();
+    // Ensure we can load the view from the storage after the update and it's
+    // enabled.
+    $entity_type_manager = \Drupal::entityTypeManager();
+    /** @var \Drupal\views\ViewEntityInterface $comment_admin_view */
+    $comment_admin_view = $entity_type_manager->getStorage('view')->load('comment');
+    $this->assertNotNull($comment_admin_view, 'Comment admin view exist in storage.');
+    $this->assertTrue($comment_admin_view->enable(), 'Comment admin view is enabled.');
+    $comment_delete_action = $entity_type_manager->getStorage('action')->load('comment_delete_action');
+    $this->assertNotNull($comment_delete_action, 'Comment delete action imported');
+    // Verify comment admin page is working after updates.
+    $account = $this->drupalCreateUser(['administer comments']);
+    $this->drupalLogin($account);
+    $this->drupalGet('admin/content/comment');
+    $this->assertText(t('No comments available.'));
+  }
+
+}
diff --git a/core/modules/comment/src/Tests/Views/CommentAdminTest.php b/core/modules/comment/src/Tests/Views/CommentAdminTest.php
new file mode 100644
index 0000000000..9097a26e32
--- /dev/null
+++ b/core/modules/comment/src/Tests/Views/CommentAdminTest.php
@@ -0,0 +1,179 @@
+<?php
+
+namespace Drupal\comment\Tests\Views;
+
+use Drupal\block_content\Entity\BlockContent;
+use Drupal\block_content\Entity\BlockContentType;
+use Drupal\comment\Entity\Comment;
+use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
+use Drupal\Component\Render\FormattableMarkup;
+use Drupal\Component\Render\HtmlEscapedText;
+use Drupal\comment\Tests\CommentTestBase as CommentWebTestBase;
+use Drupal\user\RoleInterface;
+use Drupal\views\Views;
+
+/**
+ * Tests comment approval functionality.
+ *
+ * @group comment
+ */
+class CommentAdminTest extends CommentWebTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    \Drupal::service('module_installer')->install(['views']);
+    $view = Views::getView('comment');
+    $view->storage->enable()->save();
+    \Drupal::service('router.builder')->rebuildIfNeeded();
+  }
+
+  /**
+   * Test comment approval functionality through admin/content/comment.
+   */
+  public function testApprovalAdminInterface() {
+    // Set anonymous comments to require approval.
+    user_role_change_permissions(RoleInterface::ANONYMOUS_ID, [
+      'access comments' => TRUE,
+      'post comments' => TRUE,
+      'skip comment approval' => FALSE,
+    ]);
+    $this->drupalPlaceBlock('page_title_block');
+    $this->drupalLogin($this->adminUser);
+    // Ensure that doesn't require contact info.
+    $this->setCommentAnonymous('0');
+
+    // Test that the comments page loads correctly when there are no comments.
+    $this->drupalGet('admin/content/comment');
+    $this->assertText(t('No comments available.'));
+
+    $this->drupalLogout();
+
+    // Post anonymous comment without contact info.
+    $subject = $this->randomMachineName();
+    $body = $this->randomMachineName();
+    // Set $contact to true so that it won't check for id and message.
+    $this->postComment($this->node, $body, $subject, TRUE);
+    $this->assertText(t('Your comment has been queued for review by site administrators and will be published after approval.'), 'Comment requires approval.');
+
+    // Get unapproved comment id.
+    $this->drupalLogin($this->adminUser);
+    $anonymous_comment4 = $this->getUnapprovedComment($subject);
+    $anonymous_comment4 = Comment::create([
+      'cid' => $anonymous_comment4,
+      'subject' => $subject,
+      'comment_body' => $body,
+      'entity_id' => $this->node->id(),
+      'entity_type' => 'node',
+      'field_name' => 'comment',
+    ]);
+    $this->drupalLogout();
+
+    $this->assertFalse($this->commentExists($anonymous_comment4), 'Anonymous comment was not published.');
+
+    // Approve comment.
+    $this->drupalLogin($this->adminUser);
+    $edit = [];
+    $edit['action'] = 'comment_publish_action';
+    $edit['comment_bulk_form[0]'] = $anonymous_comment4->id();
+    $this->drupalPostForm('admin/content/comment/approval', $edit, t('Apply to selected items'));
+
+    $this->assertText('Publish comment was applied to 1 item.', new FormattableMarkup('Operation "@operation" was performed on comment.', ['@operation' => 'publish']));
+    $this->drupalLogout();
+
+    $this->drupalGet('node/' . $this->node->id());
+    $this->assertTrue($this->commentExists($anonymous_comment4), 'Anonymous comment visible.');
+
+    // Post 2 anonymous comments without contact info.
+    $comments[] = $this->postComment($this->node, $this->randomMachineName(), $this->randomMachineName(), TRUE);
+    $comments[] = $this->postComment($this->node, $this->randomMachineName(), $this->randomMachineName(), TRUE);
+
+    // Publish multiple comments in one operation.
+    $this->drupalLogin($this->adminUser);
+    $this->drupalGet('admin/content/comment/approval');
+    $this->assertText(t('Unapproved comments (@count)', ['@count' => 2]), 'Two unapproved comments waiting for approval.');
+    $edit = [
+      "action" => 'comment_publish_action',
+      "comment_bulk_form[1]" => $comments[0]->id(),
+      "comment_bulk_form[0]" => $comments[1]->id(),
+    ];
+    $this->drupalPostForm(NULL, $edit, t('Apply to selected items'));
+    $this->assertText(t('Unapproved comments (@count)', ['@count' => 0]), 'All comments were approved.');
+
+    // Test message when no comments selected.
+    $this->drupalPostForm('admin/content/comment', [], t('Apply to selected items'));
+    $this->assertText(t('Select one or more comments to perform the update on.'));
+    // Delete multiple comments in one operation.
+    $edit = [
+      'action' => 'comment_delete_action',
+      "comment_bulk_form[1]" => $comments[0]->id(),
+      "comment_bulk_form[0]" => $comments[1]->id(),
+      "comment_bulk_form[2]" => $anonymous_comment4->id(),
+    ];
+    $this->drupalPostForm(NULL, $edit, t('Apply to selected items'));
+    $this->assertText(t('Are you sure you want to delete these comments and all their children?'), 'Confirmation required.');
+    $this->drupalPostForm(NULL, [], t('Delete'));
+    $this->assertText(t('No comments available.'), 'All comments were deleted.');
+
+    // Make sure the label of unpublished node is not visible on listing page.
+    $this->drupalGet('admin/content/comment');
+    $this->postComment($this->node, $this->randomMachineName());
+    $this->drupalLogout();
+    $this->drupalLogin($this->adminUser);
+    $this->drupalGet('admin/content/comment');
+    $this->assertText(new HtmlEscapedText($this->node->label()), 'Comment admin can see the title of a published node');
+    $this->node->setPublished(FALSE)->save();
+    $this->assertFalse($this->node->isPublished(), 'Node is unpublished now.');
+    $this->drupalGet('admin/content/comment');
+    $this->assertNoText(new HtmlEscapedText($this->node->label()), 'Comment admin cannot see the title of an unpublished node');
+    $this->drupalLogout();
+    $node_access_user = $this->drupalCreateUser([
+      'administer comments',
+      'bypass node access',
+    ]);
+    $this->drupalLogin($node_access_user);
+    $this->drupalGet('admin/content/comment');
+    $this->assertText(new HtmlEscapedText($this->node->label()), 'Comment admin with bypass node access permissions can still see the title of a published node');
+  }
+
+  /**
+   * Tests commented entity label of admin view.
+   */
+  public function testCommentedEntityLabel() {
+    \Drupal::service('module_installer')->install(['block_content']);
+    \Drupal::service('router.builder')->rebuildIfNeeded();
+    $bundle = BlockContentType::create([
+      'id' => 'basic',
+      'label' => 'basic',
+      'revision' => FALSE,
+    ]);
+    $bundle->save();
+    $block_content = BlockContent::create([
+      'type' => 'basic',
+      'label' => 'Some block title',
+      'info' => 'Test block',
+    ]);
+    $block_content->save();
+
+    // Create comment field on block_content.
+    $this->addDefaultCommentField('block_content', 'basic', 'block_comment', CommentItemInterface::OPEN, 'block_comment');
+    $this->drupalLogin($this->webUser);
+    // Post a comment to node.
+    $node_comment = $this->postComment($this->node, $this->randomMachineName(), $this->randomMachineName(), TRUE);
+    // Post a comment to block content.
+    $block_content_comment = $this->postComment($block_content, $this->randomMachineName(), $this->randomMachineName(), TRUE, 'block_comment');
+    $this->drupalLogout();
+    // Login as admin to test the admin comment page.
+    $this->drupalLogin($this->adminUser);
+    $this->drupalGet('admin/content/comment');
+    // Admin page contains label of both entities.
+    $this->assertText(new HtmlEscapedText($this->node->label()), 'Node title is visible.');
+    $this->assertText(new HtmlEscapedText($block_content->label()), 'Block content label is visible.');
+    // Admin page contains subject of both entities.
+    $this->assertText(new HtmlEscapedText($node_comment->label()), 'Node comment is visible.');
+    $this->assertText(new HtmlEscapedText($block_content_comment->label()), 'Block content comment is visible.');
+  }
+
+}
diff --git a/core/modules/comment/src/Tests/Views/CommentEditTest.php b/core/modules/comment/src/Tests/Views/CommentEditTest.php
new file mode 100644
index 0000000000..2a11ef9628
--- /dev/null
+++ b/core/modules/comment/src/Tests/Views/CommentEditTest.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace Drupal\comment\Tests\Views;
+
+use Drupal\comment\Tests\CommentTestBase as CommentWebTestBase;
+
+/**
+ * Tests comment edit functionality.
+ *
+ * @group comment
+ */
+class CommentEditTest extends CommentWebTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $profile = 'standard';
+
+  /**
+   * Tests comment label in admin view.
+   */
+  public function testCommentEdit() {
+    $this->drupalLogin($this->adminUser);
+    // Post a comment to node.
+    $node_comment = $this->postComment($this->node, $this->randomMachineName(), $this->randomMachineName(), TRUE);
+    $this->drupalGet('admin/content/comment');
+    $this->assertText($this->adminUser->label());
+    $this->drupalGet($node_comment->toUrl('edit-form')->toString());
+    $edit = [
+      'comment_body[0][value]' => $this->randomMachineName(),
+    ];
+    $this->drupalPostForm(NULL, $edit, t('Save'));
+    $this->drupalGet('admin/content/comment');
+    $this->assertText($this->adminUser->label());
+  }
+
+}
diff --git a/core/modules/comment/tests/src/Unit/Plugin/views/field/CommentBulkFormTest.php b/core/modules/comment/tests/src/Unit/Plugin/views/field/CommentBulkFormTest.php
new file mode 100644
index 0000000000..4e86bb7ef0
--- /dev/null
+++ b/core/modules/comment/tests/src/Unit/Plugin/views/field/CommentBulkFormTest.php
@@ -0,0 +1,93 @@
+<?php
+
+namespace Drupal\Tests\comment\Unit\Plugin\views\field;
+
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\comment\Plugin\views\field\CommentBulkForm;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\comment\Plugin\views\field\CommentBulkForm
+ * @group comment
+ */
+class CommentBulkFormTest extends UnitTestCase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function tearDown() {
+    parent::tearDown();
+    $container = new ContainerBuilder();
+    \Drupal::setContainer($container);
+  }
+
+  /**
+   * Tests the constructor assignment of actions.
+   */
+  public function testConstructor() {
+    $actions = [];
+
+    for ($i = 1; $i <= 2; $i++) {
+      $action = $this->getMock('\Drupal\system\ActionConfigEntityInterface');
+      $action->expects($this->any())
+        ->method('getType')
+        ->will($this->returnValue('comment'));
+      $actions[$i] = $action;
+    }
+
+    $action = $this->getMock('\Drupal\system\ActionConfigEntityInterface');
+    $action->expects($this->any())
+      ->method('getType')
+      ->will($this->returnValue('user'));
+    $actions[] = $action;
+
+    $entity_storage = $this->getMock('Drupal\Core\Entity\EntityStorageInterface');
+    $entity_storage->expects($this->any())
+      ->method('loadMultiple')
+      ->will($this->returnValue($actions));
+
+    $entity_manager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface');
+    $entity_manager->expects($this->once())
+      ->method('getStorage')
+      ->with('action')
+      ->will($this->returnValue($entity_storage));
+
+    $language_manager = $this->getMock('Drupal\Core\Language\LanguageManagerInterface');
+
+    $views_data = $this->getMockBuilder('Drupal\views\ViewsData')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $views_data->expects($this->any())
+      ->method('get')
+      ->with('comment')
+      ->will($this->returnValue(['table' => ['entity type' => 'comment']]));
+    $container = new ContainerBuilder();
+    $container->set('views.views_data', $views_data);
+    $container->set('string_translation', $this->getStringTranslationStub());
+    \Drupal::setContainer($container);
+
+    $storage = $this->getMock('Drupal\views\ViewEntityInterface');
+    $storage->expects($this->any())
+      ->method('get')
+      ->with('base_table')
+      ->will($this->returnValue('comment'));
+
+    $executable = $this->getMockBuilder('Drupal\views\ViewExecutable')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $executable->storage = $storage;
+
+    $display = $this->getMockBuilder('Drupal\views\Plugin\views\display\DisplayPluginBase')
+      ->disableOriginalConstructor()
+      ->getMock();
+
+    $definition['title'] = '';
+    $options = [];
+
+    $comment_bulk_form = new CommentBulkForm([], 'comment_bulk_form', $definition, $entity_manager, $language_manager);
+    $comment_bulk_form->init($executable, $display, $options);
+
+    $this->assertAttributeEquals(array_slice($actions, 0, -1, TRUE), 'actions', $comment_bulk_form);
+  }
+
+}
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MigrateUpgrade6Test.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MigrateUpgrade6Test.php
index 5299f38e24..1c4b883a35 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MigrateUpgrade6Test.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MigrateUpgrade6Test.php
@@ -57,7 +57,7 @@ protected function getEntityCounts() {
       'search_page' => 2,
       'shortcut' => 2,
       'shortcut_set' => 1,
-      'action' => 22,
+      'action' => 23,
       'menu' => 8,
       'taxonomy_term' => 7,
       'taxonomy_vocabulary' => 6,
@@ -65,7 +65,7 @@ protected function getEntityCounts() {
       'user' => 7,
       'user_role' => 6,
       'menu_link_content' => 4,
-      'view' => 15,
+      'view' => 16,
       'date_format' => 11,
       'entity_form_display' => 19,
       'entity_form_mode' => 1,
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7Test.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7Test.php
index e1e70bd5d8..248213ad45 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7Test.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7Test.php
@@ -63,7 +63,7 @@ protected function getEntityCounts() {
       'search_page' => 2,
       'shortcut' => 6,
       'shortcut_set' => 2,
-      'action' => 16,
+      'action' => 17,
       'menu' => 6,
       'taxonomy_term' => 18,
       'taxonomy_vocabulary' => 4,
@@ -71,7 +71,7 @@ protected function getEntityCounts() {
       'user' => 4,
       'user_role' => 3,
       'menu_link_content' => 7,
-      'view' => 15,
+      'view' => 16,
       'date_format' => 11,
       'entity_form_display' => 18,
       'entity_form_mode' => 1,
diff --git a/core/modules/views/tests/src/Functional/DefaultViewsTest.php b/core/modules/views/tests/src/Functional/DefaultViewsTest.php
index 0e5c893442..3e7d0b48b2 100644
--- a/core/modules/views/tests/src/Functional/DefaultViewsTest.php
+++ b/core/modules/views/tests/src/Functional/DefaultViewsTest.php
@@ -100,6 +100,15 @@ protected function setUp($import_test_views = TRUE) {
         'field_name' => 'comment'
       ];
       Comment::create($comment)->save();
+
+      $unpublished_comment = [
+        'uid' => $user->id(),
+        'status' => CommentInterface::NOT_PUBLISHED,
+        'entity_id' => $node->id(),
+        'entity_type' => 'node',
+        'field_name' => 'comment',
+      ];
+      Comment::create($unpublished_comment)->save();
     }
 
     // Some views, such as the "Who's Online" view, only return results if at
