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 6276f95..ac61f07 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/StringFormatter.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/StringFormatter.php
@@ -8,6 +8,7 @@
 namespace Drupal\Core\Field\Plugin\Field\FieldFormatter;
 
 use Drupal\Component\Utility\SafeMarkup;
+use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Entity\RevisionableInterface;
 use Drupal\Core\Field\FieldDefinitionInterface;
@@ -123,8 +124,7 @@ public function viewElements(FieldItemListInterface $items) {
     $elements = array();
     $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) {
@@ -158,4 +158,21 @@ protected function viewValue(FieldItemInterface $item) {
     return nl2br(SafeMarkup::checkPlain($item->value));
   }
 
+  /**
+   * 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) {
+    if (class_exists('Drupal\comment\Entity\Comment') && $entity instanceof \Drupal\comment\CommentInterface) {
+      return $entity->permalink();
+    }
+    // For the default revision this falls back to 'canonical'
+    return $entity->urlInfo('revision');
+  }
+
 }
diff --git a/core/modules/comment/comment.routing.yml b/core/modules/comment/comment.routing.yml
index 967cb3f..91c81bb 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'
@@ -50,6 +50,14 @@ entity.comment.delete_form:
   requirements:
     _entity_access: 'comment.delete'
 
+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 0000000..89dd7c9
--- /dev/null
+++ b/core/modules/comment/config/install/system.action.comment_delete_action.yml
@@ -0,0 +1,9 @@
+id: comment_delete_action
+label: 'Delete comment'
+status: true
+langcode: en
+type: comment
+plugin: comment_delete_action
+dependencies:
+  module:
+    - comment
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 0000000..b5b65fd
--- /dev/null
+++ b/core/modules/comment/config/optional/views.view.comment.yml
@@ -0,0 +1,994 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - comment
+    - user
+id: comment
+label: Comments
+module: comment
+description: 'Find and manage comments.'
+tag: ''
+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: none
+      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
+            name: name
+            commented_entity_label: commented_entity_label
+            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: ''
+            name:
+              sortable: true
+              default_sort_order: asc
+              align: ''
+              separator: ''
+              empty_column: false
+              responsive: priority-medium
+            commented_entity_label:
+              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: string
+          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
+        commented_entity_label:
+          id: commented_entity_label
+          table: comment
+          field: commented_entity_label
+          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
+          link_to_entity: true
+          entity_type: comment
+          plugin_id: commented_entity_label
+        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
+          date_format: short
+          custom_date_format: ''
+          timezone: ''
+          entity_type: comment
+          entity_field: changed
+          plugin_id: date
+        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: true
+          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.pagers:0'
+        - 'url.query_args:order'
+        - 'url.query_args:sort'
+      cacheable: false
+  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.pagers:0'
+        - 'url.query_args:order'
+        - 'url.query_args:sort'
+      cacheable: false
+  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: false
+          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: string
+          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
+        commented_entity_label:
+          id: commented_entity_label
+          table: comment
+          field: commented_entity_label
+          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
+          link_to_entity: true
+          entity_type: comment
+          plugin_id: commented_entity_label
+        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
+          date_format: short
+          custom_date_format: ''
+          timezone: ''
+          entity_type: comment
+          entity_field: changed
+          plugin_id: date
+        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.pagers:0'
+        - 'url.query_args:order'
+        - 'url.query_args:sort'
+      cacheable: false
diff --git a/core/modules/comment/config/schema/comment.schema.yml b/core/modules/comment/config/schema/comment.schema.yml
index d9f5a77..0503651 100644
--- a/core/modules/comment/config/schema/comment.schema.yml
+++ b/core/modules/comment/config/schema/comment.schema.yml
@@ -102,3 +102,7 @@ field.field_settings.comment:
     preview:
       type: integer
       label: 'Preview comment'
+
+action.configuration.comment_delete_action:
+  type: action_configuration_default
+  label: 'Delete comment configuration'
diff --git a/core/modules/comment/config/schema/comment.views.schema.yml b/core/modules/comment/config/schema/comment.views.schema.yml
index 606af82..9b59207 100644
--- a/core/modules/comment/config/schema/comment.views.schema.yml
+++ b/core/modules/comment/config/schema/comment.views.schema.yml
@@ -16,6 +16,18 @@ 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_label:
+  type: views_field
+  label: 'Commented entity label'
+  mapping:
+    link_to_entity:
+      type: boolean
+      label: 'Link to 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 c70f77f..49bbbd4 100644
--- a/core/modules/comment/src/CommentViewsData.php
+++ b/core/modules/comment/src/CommentViewsData.php
@@ -118,6 +118,22 @@ public function getViewsData() {
       ),
     );
 
+    $data['comment']['commented_entity_label'] = array(
+      'title' => t('Label of commented entity'),
+      'help' => t('Provide a label of commented entity.'),
+      'field' => array(
+        'id' => 'commented_entity_label',
+      ),
+    );
+
+    $data['comment']['comment_bulk_form'] = array(
+      'title' => t('Comment operations bulk form'),
+      'help' => t('Add a form element that lets you run operations on multiple comments.'),
+      'field' => array(
+        'id' => 'comment_bulk_form',
+      ),
+    );
+
     $data['comment_field_data']['thread']['field'] = array(
       'title' => t('Depth'),
       'help' => 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 4c1592f..0000000
--- a/core/modules/comment/src/Controller/AdminController.php
+++ /dev/null
@@ -1,67 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\comment\Controller\AdminController.
- */
-
-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/Entity/Comment.php b/core/modules/comment/src/Entity/Comment.php
index bd3fbfc..5525765 100644
--- a/core/modules/comment/src/Entity/Comment.php
+++ b/core/modules/comment/src/Entity/Comment.php
@@ -35,6 +35,7 @@
  *       "default" = "Drupal\comment\CommentForm",
  *       "delete" = "Drupal\comment\Form\DeleteForm"
  *     },
+ *     "list_builder" = "Drupal\Core\Entity\EntityListBuilder",
  *     "translation" = "Drupal\comment\CommentTranslationHandler"
  *   },
  *   base_table = "comment",
diff --git a/core/modules/comment/src/Form/CommentAdminOverview.php b/core/modules/comment/src/Form/CommentAdminOverview.php
index 008e0bb..070f452 100644
--- a/core/modules/comment/src/Form/CommentAdminOverview.php
+++ b/core/modules/comment/src/Form/CommentAdminOverview.php
@@ -8,7 +8,6 @@
 namespace Drupal\comment\Form;
 
 use Drupal\comment\CommentInterface;
-use Drupal\comment\CommentStorageInterface;
 use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Datetime\DateFormatter;
 use Drupal\Core\Entity\EntityManagerInterface;
@@ -16,6 +15,7 @@
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Url;
+use Drupal\user\PrivateTempStoreFactory;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -52,22 +52,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
    *   The entity manager service.
-   * @param \Drupal\comment\CommentStorageInterface $comment_storage
-   *   The comment storage.
    * @param \Drupal\Core\Datetime\DateFormatter $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, DateFormatter $date_formatter, ModuleHandlerInterface $module_handler) {
+  public function __construct(EntityManagerInterface $entity_manager, DateFormatter $date_formatter, ModuleHandlerInterface $module_handler, PrivateTempStoreFactory $temp_store_factory) {
     $this->entityManager = $entity_manager;
-    $this->commentStorage = $comment_storage;
+    $this->commentStorage = $entity_manager->getStorage('comment');
     $this->dateFormatter = $date_formatter;
     $this->moduleHandler = $module_handler;
+    $this->tempStoreFactory = $temp_store_factory;
   }
 
   /**
@@ -76,9 +84,9 @@ 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('date.formatter'),
-      $container->get('module_handler')
+      $container->get('module_handler'),
+      $container->get('user.private_tempstore')
     );
   }
 
@@ -262,23 +270,27 @@ 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);
-        $comment->save();
-      }
-      elseif ($operation == 'publish') {
-        $comment = $this->commentStorage->load($cid);
-        $comment->setPublished(TRUE);
+    /** @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();
       }
+      drupal_set_message($this->t('The update has been performed.'));
+      $form_state->setRedirect('comment.admin');
+    }
+    else {
+      $this->tempStoreFactory
+        ->get('comment_multiple_delete_confirm')
+        ->set($this->currentUser()->id(), $comments);
+      $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 666b555..9d990f4 100644
--- a/core/modules/comment/src/Form/ConfirmDeleteMultiple.php
+++ b/core/modules/comment/src/Form/ConfirmDeleteMultiple.php
@@ -8,6 +8,7 @@
 namespace Drupal\comment\Form;
 
 use Drupal\comment\CommentStorageInterface;
+use Drupal\user\PrivateTempStoreFactory;
 use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Form\ConfirmFormBase;
 use Drupal\Core\Form\FormStateInterface;
@@ -20,6 +21,13 @@
 class ConfirmDeleteMultiple extends ConfirmFormBase {
 
   /**
+   * The tempstore factory.
+   *
+   * @var \Drupal\user\PrivateTempStoreFactory
+   */
+  protected $tempStoreFactory;
+
+  /**
    * The comment storage.
    *
    * @var \Drupal\comment\CommentStorageInterface
@@ -38,9 +46,12 @@ class ConfirmDeleteMultiple extends ConfirmFormBase {
    *
    * @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;
   }
 
   /**
@@ -48,7 +59,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')
     );
   }
 
@@ -63,7 +75,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->comments), '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?');
   }
 
   /**
@@ -77,23 +89,24 @@ 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->comments = $this->tempStoreFactory->get('comment_multiple_delete_confirm')->get($this->currentUser()->id());
+    if (empty($this->comments)) {
+      return $this->redirect('comment.admin');
+    }
 
     $form['comments'] = array(
       '#prefix' => '<ul>',
       '#suffix' => '</ul>',
       '#tree' => TRUE,
     );
-    // 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] = array(
@@ -102,15 +115,9 @@ public function buildForm(array $form, FormStateInterface $form_state) {
         '#prefix' => '<li>',
         '#suffix' => SafeMarkup::checkPlain($comment->label()) . '</li>'
       );
-      $comment_counter++;
     }
     $form['operation'] = array('#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);
   }
 
@@ -118,9 +125,10 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    if ($form_state->getValue('confirm')) {
+    if ($form_state->getValue('confirm') && !empty($this->comments)) {
       $this->commentStorage->delete($this->comments);
-      $count = count($form_state->getValue('comments'));
+      $this->tempStoreFactory->get('comment_multiple_delete_confirm')->delete($this->currentUser()->id());
+      $count = count($this->comments);
       $this->logger('content')->notice('Deleted @count comments.', array('@count' => $count));
       drupal_set_message($this->formatPlural($count, 'Deleted 1 comment.', 'Deleted @count comments.'));
     }
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 0000000..ee759f3
--- /dev/null
+++ b/core/modules/comment/src/Plugin/Action/DeleteComment.php
@@ -0,0 +1,95 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\comment\Plugin\Action\DeleteComment.
+ */
+
+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) {
+    $this->tempStore->set($this->currentUser->id(), $entities);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function execute($entity = NULL) {
+    $this->executeMultiple(array($entity));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function access($comment, AccountInterface $account = NULL, $return_as_object = FALSE) {
+    /** @var \Drupal\comment\CommentInterface $object */
+    return $comment->access('delete', $account, $return_as_object);
+  }
+
+}
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 0000000..e4b691f
--- /dev/null
+++ b/core/modules/comment/src/Plugin/views/field/CommentBulkForm.php
@@ -0,0 +1,26 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\comment\Plugin\views\field\CommentBulkForm.
+ */
+
+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('No comments selected.');
+  }
+
+}
diff --git a/core/modules/comment/src/Plugin/views/field/CommentedEntityLabel.php b/core/modules/comment/src/Plugin/views/field/CommentedEntityLabel.php
new file mode 100644
index 0000000..fca2efb
--- /dev/null
+++ b/core/modules/comment/src/Plugin/views/field/CommentedEntityLabel.php
@@ -0,0 +1,135 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\views\Plugin\views\field\CommentedEntityLabel.
+ */
+
+namespace Drupal\comment\Plugin\views\field;
+
+use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\views\Plugin\views\field\FieldPluginBase;
+use Drupal\views\ResultRow;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Views field display label of commented entity optionally linked to entity.
+ *
+ * @ViewsField("commented_entity_label")
+ */
+class CommentedEntityLabel extends FieldPluginBase {
+
+  /**
+   * Array of entities that has comments.
+   *
+   * @var array
+   */
+  protected $loadedCommentedEntities = array();
+
+  /**
+   * EntityManager class.
+   *
+   * @var \Drupal\Core\Entity\EntityManagerInterface
+   */
+  protected $entityManager;
+
+  /**
+   * Constructs a CommentedEntityLabel 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 mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Entity\EntityManagerInterface $manager
+   *   EntityManager that is stored internally and used to load nodes.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $manager) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+
+    $this->entityManager = $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 function defineOptions() {
+    $options = parent::defineOptions();
+    $options['link_to_entity'] = array('default' => FALSE);
+    return $options;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildOptionsForm(&$form, FormStateInterface $form_state) {
+    $form['link_to_entity'] = array(
+      '#title' => $this->t('Link to entity'),
+      '#description' => $this->t('Make entity label a link to entity page.'),
+      '#type' => 'checkbox',
+      '#default_value' => !empty($this->options['link_to_entity']),
+    );
+    parent::buildOptionsForm($form, $form_state);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function render(ResultRow $values) {
+    /** @var \Drupal\comment\CommentInterface $comment */
+    if(($comment = $this->getEntity($values)) && isset($this->loadedCommentedEntities[$comment->getCommentedEntityTypeId()]) && isset($this->loadedCommentedEntities[$comment->getCommentedEntityTypeId()][$comment->getCommentedEntityId()])) {
+
+      /** @var $entity \Drupal\Core\Entity\EntityInterface */
+      $entity = $this->loadedCommentedEntities[$comment->getCommentedEntityTypeId()][$comment->getCommentedEntityId()];
+
+      if (!empty($this->options['link_to_entity'])) {
+        $this->options['alter']['make_link'] = TRUE;
+        $this->options['alter']['url'] = $entity->urlInfo();
+      }
+      if ($entity->access('view')) {
+        return $this->sanitizeValue($entity->label());
+      }
+    }
+    return '';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function preRender(&$values) {
+    parent::preRender($values);
+
+    $entity_ids_per_type = array();
+    foreach ($values 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);
+    }
+  }
+
+}
diff --git a/core/modules/comment/src/Tests/CommentAdminTest.php b/core/modules/comment/src/Tests/CommentAdminTest.php
index ee03405..46393c9 100644
--- a/core/modules/comment/src/Tests/CommentAdminTest.php
+++ b/core/modules/comment/src/Tests/CommentAdminTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\comment\Tests;
 
+use Drupal\Component\Utility\SafeMarkup;
 use Drupal\user\RoleInterface;
 
 /**
@@ -87,7 +88,7 @@ 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, $edit, t('Delete'));
     $this->assertText(t('No comments available.'), 'All comments were deleted.');
     // Test message when no comments selected.
     $edit = array(
@@ -95,6 +96,15 @@ 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 a7f7918..c0fdd8a 100644
--- a/core/modules/comment/src/Tests/CommentNonNodeTest.php
+++ b/core/modules/comment/src/Tests/CommentNonNodeTest.php
@@ -222,7 +222,7 @@ function performCommentOperation($comment, $operation, $approval = FALSE) {
     $this->drupalPostForm('admin/content/comment' . ($approval ? '/approval' : ''), $edit, t('Update'));
 
     if ($operation == 'delete') {
-      $this->drupalPostForm(NULL, array(), t('Delete comments'));
+      $this->drupalPostForm(NULL, array(), t('Delete'));
       $this->assertRaw(\Drupal::translation()->formatPlural(1, 'Deleted 1 comment.', 'Deleted @count comments.'), format_string('Operation "@operation" was performed on comment.', array('@operation' => $operation)));
     }
     else {
diff --git a/core/modules/comment/src/Tests/CommentTestBase.php b/core/modules/comment/src/Tests/CommentTestBase.php
index 8ebc4e7..46d174e 100644
--- a/core/modules/comment/src/Tests/CommentTestBase.php
+++ b/core/modules/comment/src/Tests/CommentTestBase.php
@@ -347,7 +347,7 @@ function performCommentOperation(CommentInterface $comment, $operation, $approva
     $this->drupalPostForm('admin/content/comment' . ($approval ? '/approval' : ''), $edit, t('Update'));
 
     if ($operation == 'delete') {
-      $this->drupalPostForm(NULL, array(), t('Delete comments'));
+      $this->drupalPostForm(NULL, array(), t('Delete'));
       $this->assertRaw(\Drupal::translation()->formatPlural(1, 'Deleted 1 comment.', 'Deleted @count comments.'), format_string('Operation "@operation" was performed on comment.', array('@operation' => $operation)));
     }
     else {
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 0000000..1946688
--- /dev/null
+++ b/core/modules/comment/src/Tests/Views/CommentAdminTest.php
@@ -0,0 +1,129 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\comment\Tests\Views\CommentAdminTest.
+ */
+
+namespace Drupal\comment\Tests\Views;
+
+use Drupal\Component\Utility\SafeMarkup;
+use Drupal\comment\Tests\CommentTestBase;
+use Drupal\user\RoleInterface;
+use Drupal\views\Views;
+
+/**
+ * Tests comment approval functionality.
+ *
+ * @group comment
+ */
+class CommentAdminTest extends CommentTestBase {
+
+  /**
+   * Test comment approval functionality through admin/content/comment.
+   */
+  function testApprovalAdminInterface() {
+    \Drupal::service('module_installer')->install(['views']);
+    $view = Views::getView('comment');
+    $view->storage->enable()->save();
+    \Drupal::service('router.builder')->rebuildIfNeeded();
+    // Set anonymous comments to require approval.
+    user_role_change_permissions(RoleInterface::ANONYMOUS_ID, array(
+      'access comments' => TRUE,
+      'post comments' => TRUE,
+      'skip comment approval' => FALSE,
+    ));
+    $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 = entity_create('comment', array(
+      '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 = array();
+    $edit['action'] = 'comment_publish_action';
+    $edit['comment_bulk_form[0]'] = $anonymous_comment4->language()->getId() . '-' . $anonymous_comment4->id() . '-';
+    $this->drupalPostForm('admin/content/comment/approval', $edit, t('Apply'));
+
+    $this->assertText('Publish comment was applied to 1 item.', format_string('Operation "@operation" was performed on comment.', array('@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)', array('@count' => 2)), 'Two unapproved comments waiting for approval.');
+    $edit = array(
+      "action" => 'comment_publish_action',
+      "comment_bulk_form[1]" => $comments[0]->language()->getId() . '-' . $comments[0]->id() . '-',
+      "comment_bulk_form[0]" => $comments[1]->language()->getId() . '-' . $comments[1]->id() . '-',
+  );
+    $this->drupalPostForm(NULL, $edit, t('Apply'));
+    $this->assertText(t('Unapproved comments (@count)', array('@count' => 0)), 'All comments were approved.');
+
+    // Test message when no comments selected.
+    $this->drupalPostForm('admin/content/comment', [], t('Apply'));
+    $this->assertText(t('No comments selected.'));
+    // Delete multiple comments in one operation.
+    $edit = array(
+      'action' => 'comment_delete_action',
+      "comment_bulk_form[1]" => $comments[0]->language()->getId() . '-' . $comments[0]->id() . '-',
+      "comment_bulk_form[0]" => $comments[1]->language()->getId() . '-' . $comments[1]->id() . '-',
+      "comment_bulk_form[2]" => $anonymous_comment4->language()->getId() . '-' . $anonymous_comment4->id() . '-',
+    );
+    $this->drupalPostForm(NULL, $edit, t('Apply'));
+    $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->commentAdminUser = $this->drupalCreateUser(array(
+      'administer comments',
+    ));
+    $this->drupalLogin($this->commentAdminUser);
+    $this->drupalGet('admin/content/comment');
+    $this->assertText(SafeMarkup::checkPlain($this->node->label()), 'Comment admin can see title of publish node');
+    $this->node->setPublished(FALSE)->save();
+    $this->assertFalse($this->node->isPublished(), 'Node is unpublished now.');
+    drupal_flush_all_caches();
+    $this->drupalGet('admin/content/comment');
+    $this->assertNoText(SafeMarkup::checkPlain($this->node->label()), 'Comment admin cannot see title of unpublish node');
+  }
+
+}
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 0000000..5821274
--- /dev/null
+++ b/core/modules/comment/tests/src/Unit/Plugin/views/field/CommentBulkFormTest.php
@@ -0,0 +1,96 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\comment\Unit\Plugin\views\field\CommentBulkFormTest.
+ */
+
+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 = array();
+
+    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));
+
+    $views_data = $this->getMockBuilder('Drupal\views\ViewsData')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $views_data->expects($this->any())
+      ->method('get')
+      ->with('comment')
+      ->will($this->returnValue(array('table' => array('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 = array();
+
+    $comment_bulk_form = new CommentBulkForm(array(), 'comment_bulk_form', $definition, $entity_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/views/src/Tests/DefaultViewsTest.php b/core/modules/views/src/Tests/DefaultViewsTest.php
index 4ef5091..a058a45 100644
--- a/core/modules/views/src/Tests/DefaultViewsTest.php
+++ b/core/modules/views/src/Tests/DefaultViewsTest.php
@@ -100,6 +100,15 @@ protected function setUp() {
         'field_name' => 'comment'
       );
       entity_create('comment', $comment)->save();
+
+      $unpublished_comment = array(
+        'uid' => $user->id(),
+        'status' => CommentInterface::NOT_PUBLISHED,
+        'entity_id' => $node->id(),
+        'entity_type' => 'node',
+        'field_name' => 'comment'
+      );
+      entity_create('comment', $unpublished_comment)->save();
     }
 
     // Some views, such as the "Who's Online" view, only return results if at
