diff --git a/core/modules/comment/comment.links.menu.yml b/core/modules/comment/comment.links.menu.yml
index e4d4488..94a2ad6 100644
--- a/core/modules/comment/comment.links.menu.yml
+++ b/core/modules/comment/comment.links.menu.yml
@@ -2,7 +2,7 @@ comment.admin:
   title: Comments
   route_name: comment.admin
   parent: system.admin_content
-  description: 'List and edit site comments and the comment approval queue.'
+  description: 'List and edit site comments and the comment unpublished queue.'
 comment.type_list:
   title: 'Comment types'
   route_name: comment.type_list
diff --git a/core/modules/comment/comment.links.task.yml b/core/modules/comment/comment.links.task.yml
index a976171..9cfed06 100644
--- a/core/modules/comment/comment.links.task.yml
+++ b/core/modules/comment/comment.links.task.yml
@@ -23,10 +23,10 @@ comment.admin_new:
   route_name: comment.admin
   parent_id: comment.admin
 
-comment.admin_approval:
-  title: 'Unapproved comments'
-  route_name: comment.admin_approval
-  class: Drupal\comment\Plugin\Menu\LocalTask\UnapprovedComments
+comment.admin_unpublished:
+  title: 'Unpublished comments'
+  route_name: comment.admin_unpublished
+  class: Drupal\comment\Plugin\Menu\LocalTask\UnpublishedComments
   parent_id: comment.admin
   weight: 1
 
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index 5ce3ba9..5be4bee 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -83,7 +83,7 @@ function comment_help($route_name, RouteMatchInterface $route_match) {
       $output .= '<dt>' . t('Overriding default settings') . '</dt>';
       $output .= '<dd>' . t('When you create an entity item, you can override the default comment settings. Changing the entity sub-type defaults will not affect existing entity items, whether they used the default settings or had overrides.') . '</dd>';
       $output .= '<dt>' . t('Approving and managing comments') . '</dt>';
-      $output .= '<dd>' . t('Comments from users who have the <em>Skip comment approval</em> permission are published immediately. All other comments are placed in the <a href="!comment-approval">Unapproved comments</a> queue, until a user who has permission to <em>Administer comments and comment settings</em> publishes or deletes them. Published comments can be bulk managed on the <a href="!admin-comment">Published comments</a> administration page. When a comment has no replies, it remains editable by its author, as long as the author has <em>Edit own comments</em> permission.', array('!comment-approval' => \Drupal::url('comment.admin_approval'), '!admin-comment' => \Drupal::url('comment.admin'))) . '</dd>';
+      $output .= '<dd>' . t('Comments from users who have the <em>Skip comment approval</em> permission are published immediately. All other comments are placed in the <a href="!comment-approval">Unpublished comments</a> queue, until a user who has permission to <em>Administer comments and comment settings</em> publishes or deletes them. Published comments can be bulk managed on the <a href="!admin-comment">Published comments</a> administration page. When a comment has no replies, it remains editable by its author, as long as the author has <em>Edit own comments</em> permission.', array('!comment-approval' => \Drupal::url('comment.admin_unpublished'), '!admin-comment' => \Drupal::url('comment.admin'))) . '</dd>';
       $output .= '</dl>';
       return $output;
 
diff --git a/core/modules/comment/comment.routing.yml b/core/modules/comment/comment.routing.yml
index f7bae41..0853c74 100644
--- a/core/modules/comment/comment.routing.yml
+++ b/core/modules/comment/comment.routing.yml
@@ -7,12 +7,12 @@ comment.admin:
   requirements:
     _permission: 'administer comments'
 
-comment.admin_approval:
-  path: '/admin/content/comment/approval'
+comment.admin_unpublished:
+  path: '/admin/content/comment/unpublished'
   defaults:
-    _title: 'Unapproved comments'
+    _title: 'Unpublished comments'
     _content: '\Drupal\comment\Controller\AdminController::adminPage'
-    type: 'approval'
+    type: 'unpublished'
   requirements:
     _permission: 'administer comments'
 
@@ -24,14 +24,24 @@ entity.comment.edit_form:
   requirements:
     _entity_access: 'comment.update'
 
-comment.approve:
-  path: '/comment/{comment}/approve'
+comment.publish:
+  path: '/comment/{comment}/publish'
   defaults:
-    _title: 'Approve'
-    _content: '\Drupal\comment\Controller\CommentController::commentApprove'
+    _title: 'Publish'
+    _content: '\Drupal\comment\Controller\CommentController::commentPublish'
     entity_type: 'comment'
   requirements:
-    _entity_access: 'comment.approve'
+    _entity_access: 'comment.publish'
+    _csrf_token: 'TRUE'
+
+comment.unpublish:
+  path: '/comment/{comment}/unpublish'
+  defaults:
+    _title: 'Unpublish'
+    _content: '\Drupal\comment\Controller\CommentController::commentUnpublish'
+    entity_type: 'comment'
+  requirements:
+    _entity_access: 'comment.unpublish'
     _csrf_token: 'TRUE'
 
 entity.comment.canonical:
diff --git a/core/modules/comment/comment.views.inc b/core/modules/comment/comment.views.inc
index 52f517c..9a103f5 100644
--- a/core/modules/comment/comment.views.inc
+++ b/core/modules/comment/comment.views.inc
@@ -235,17 +235,17 @@ function comment_views_data() {
   );
 
   $data['comment_field_data']['status'] = array(
-    'title' => t('Approved status'),
-    'help' => t('Whether the comment is approved (or still in the moderation queue).'),
+    'title' => t('Published status'),
+    'help' => t('Whether or not the comment is published.'),
     'field' => array(
       'id' => 'boolean',
       'output formats' => array(
-        'approved-not-approved' => array(t('Approved'), t('Not Approved')),
+        'published-notpublished' => array(t('Published'), t('Not published')),
       ),
     ),
     'filter' => array(
       'id' => 'boolean',
-      'label' => t('Approved comment status'),
+      'label' => t('Published status'),
       'type' => 'yes-no',
     ),
     'sort' => array(
@@ -277,11 +277,19 @@ function comment_views_data() {
     ),
   );
 
-  $data['comment']['approve_comment'] = array(
+  $data['comment']['publish_comment'] = array(
     'field' => array(
-      'title' => t('Link to approve comment'),
-      'help' => t('Provide a simple link to approve the comment.'),
-      'id' => 'comment_link_approve',
+      'title' => t('Link to publish comment'),
+      'help' => t('Provide a simple link to publish the comment.'),
+      'id' => 'comment_link_publish',
+    ),
+  );
+
+  $data['comment']['unpublish_comment'] = array(
+    'field' => array(
+      'title' => t('Link to unpublish comment'),
+      'help' => t('Provide a simple link to unpublish the comment.'),
+      'id' => 'comment_link_unpublish',
     ),
   );
 
diff --git a/core/modules/comment/config/schema/comment.views.schema.yml b/core/modules/comment/config/schema/comment.views.schema.yml
index fbd09b9..5970360 100644
--- a/core/modules/comment/config/schema/comment.views.schema.yml
+++ b/core/modules/comment/config/schema/comment.views.schema.yml
@@ -42,9 +42,13 @@ views.field.comment_link:
       type: views_field
       label: 'Link field to the entity if there is no comment.'
 
-views.field.comment_link_approve:
+views.field.comment_link_publish:
   type: views.field.comment_link
-  label: 'Comment approve link'
+  label: 'Comment publish link'
+
+views.field.comment_link_unpublish:
+  type: views.field.comment_link
+  label: 'Comment unpublish link'
 
 views.field.comment_link_delete:
   type: views.field.comment_link
diff --git a/core/modules/comment/src/CommentAccessController.php b/core/modules/comment/src/CommentAccessController.php
index d741d86..e949dea 100644
--- a/core/modules/comment/src/CommentAccessController.php
+++ b/core/modules/comment/src/CommentAccessController.php
@@ -38,7 +38,11 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, A
         return $account->hasPermission('administer comments');
         break;
 
-      case 'approve':
+      case 'publish':
+        return $account->hasPermission('administer comments');
+        break;
+
+      case 'unpublish':
         return $account->hasPermission('administer comments');
         break;
     }
diff --git a/core/modules/comment/src/CommentInterface.php b/core/modules/comment/src/CommentInterface.php
index d2fd09a..8ded79e 100644
--- a/core/modules/comment/src/CommentInterface.php
+++ b/core/modules/comment/src/CommentInterface.php
@@ -17,7 +17,7 @@
 interface CommentInterface extends ContentEntityInterface, EntityChangedInterface, EntityOwnerInterface {
 
   /**
-   * Comment is awaiting approval.
+   * Comment is unpublished and awaiting approval.
    */
   const NOT_PUBLISHED = 0;
 
diff --git a/core/modules/comment/src/CommentStorage.php b/core/modules/comment/src/CommentStorage.php
index 2d5541e..25fe538 100644
--- a/core/modules/comment/src/CommentStorage.php
+++ b/core/modules/comment/src/CommentStorage.php
@@ -381,7 +381,7 @@ public function getSchema() {
   /**
    * {@inheritdoc}
    */
-  public function getUnapprovedCount() {
+  public function getUnpublishedCount() {
     return  $this->database->select('comment_field_data', 'c')
       ->condition('status', CommentInterface::NOT_PUBLISHED, '=')
       ->condition('default_langcode', 1)
diff --git a/core/modules/comment/src/CommentStorageInterface.php b/core/modules/comment/src/CommentStorageInterface.php
index 9087e5c..7f7166e 100644
--- a/core/modules/comment/src/CommentStorageInterface.php
+++ b/core/modules/comment/src/CommentStorageInterface.php
@@ -117,8 +117,7 @@ public function loadThread(EntityInterface $entity, $field_name, $mode, $comment
    * - last_comment_uid: The user ID of the poster for the last comment for
    *   this entity, or the entity author's user ID if no comments exist for the
    *   entity.
-   * - comment_count: The total number of approved/published comments on this
-   *   entity.
+   * - comment_count: The total number of published comments on this entity.
    *
    * @param \Drupal\comment\CommentInterface $comment
    *   The comment being saved.
@@ -126,11 +125,11 @@ public function loadThread(EntityInterface $entity, $field_name, $mode, $comment
   public function updateEntityStatistics(CommentInterface $comment);
 
   /**
-   * Returns the number of unapproved comments.
+   * Returns the number of unpublished comments.
    *
    * @return int
-   *   The number of unapproved comments.
+   *   The number of unpublished comments.
    */
-  public function getUnapprovedCount();
+  public function getUnpublishedCount();
 
 }
diff --git a/core/modules/comment/src/CommentViewBuilder.php b/core/modules/comment/src/CommentViewBuilder.php
index 6a4760b..e1adcd8 100644
--- a/core/modules/comment/src/CommentViewBuilder.php
+++ b/core/modules/comment/src/CommentViewBuilder.php
@@ -248,10 +248,18 @@ protected static function buildLinks(CommentInterface $entity, EntityInterface $
           'html' => TRUE,
         );
       }
-      if (!$entity->isPublished() && $entity->access('approve')) {
-        $links['comment-approve'] = array(
-          'title' => t('Approve'),
-          'route_name' => 'comment.approve',
+      if (!$entity->isPublished() && $entity->access('publish')) {
+        $links['comment-publish'] = array(
+          'title' => t('Publish'),
+          'route_name' => 'comment.publish',
+          'route_parameters' => array('comment' => $entity->id()),
+          'html' => TRUE,
+        );
+      }
+      if ($entity->isPublished() && $entity->access('unpublish')) {
+        $links['comment-unpublish'] = array(
+          'title' => t('Unpublish'),
+          'route_name' => 'comment.unpublish',
           'route_parameters' => array('comment' => $entity->id()),
           'html' => TRUE,
         );
diff --git a/core/modules/comment/src/Controller/AdminController.php b/core/modules/comment/src/Controller/AdminController.php
index 4c1592f..3895456 100644
--- a/core/modules/comment/src/Controller/AdminController.php
+++ b/core/modules/comment/src/Controller/AdminController.php
@@ -49,7 +49,7 @@ public function __construct(FormBuilderInterface $form_builder) {
    * @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'.
+   *   The type of the overview form ('unpublished' or 'new') default to 'new'.
    *
    * @return array
    *   Then comment multiple delete confirmation form or the comments overview
diff --git a/core/modules/comment/src/Controller/CommentController.php b/core/modules/comment/src/Controller/CommentController.php
index e550afc..e7a3e33 100644
--- a/core/modules/comment/src/Controller/CommentController.php
+++ b/core/modules/comment/src/Controller/CommentController.php
@@ -73,11 +73,30 @@ public static function create(ContainerInterface $container) {
    * @return \Symfony\Component\HttpFoundation\RedirectResponse.
    *   Redirects to the permalink URL for this comment.
    */
-  public function commentApprove(CommentInterface $comment) {
+  public function commentPublish(CommentInterface $comment) {
     $comment->setPublished(TRUE);
     $comment->save();
 
-    drupal_set_message($this->t('Comment approved.'));
+    drupal_set_message($this->t('Comment published.'));
+    $permalink_uri = $comment->permalink();
+    $permalink_uri->setAbsolute();
+    return new RedirectResponse($permalink_uri->toString());
+  }
+
+  /**
+   * Unpublishes the specified comment.
+   *
+   * @param \Drupal\comment\CommentInterface $comment
+   *   A comment entity.
+   *
+   * @return \Symfony\Component\HttpFoundation\RedirectResponse.
+   *   Redirects to the permalink URL for this comment.
+   */
+  public function commentUnpublish(CommentInterface $comment) {
+    $comment->setPublished(FALSE);
+    $comment->save();
+
+    drupal_set_message($this->t('Comment unpublished.'));
     $permalink_uri = $comment->permalink();
     $permalink_uri->setAbsolute();
     return new RedirectResponse($permalink_uri->toString());
diff --git a/core/modules/comment/src/Form/CommentAdminOverview.php b/core/modules/comment/src/Form/CommentAdminOverview.php
index e65ac1a..2d3995e 100644
--- a/core/modules/comment/src/Form/CommentAdminOverview.php
+++ b/core/modules/comment/src/Form/CommentAdminOverview.php
@@ -111,7 +111,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $type = '
       '#attributes' => array('class' => array('container-inline')),
     );
 
-    if ($type == 'approval') {
+    if ($type == 'unpublished') {
       $options['publish'] = $this->t('Publish the selected comments');
     }
     else {
@@ -132,7 +132,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $type = '
     );
 
     // Load the comments that need to be displayed.
-    $status = ($type == 'approval') ? CommentInterface::NOT_PUBLISHED : CommentInterface::PUBLISHED;
+    $status = ($type == 'unpublished') ? CommentInterface::NOT_PUBLISHED : CommentInterface::PUBLISHED;
     $header = array(
       'subject' => array(
         'data' => $this->t('Subject'),
diff --git a/core/modules/comment/src/Plugin/Menu/LocalTask/UnapprovedComments.php b/core/modules/comment/src/Plugin/Menu/LocalTask/UnapprovedComments.php
deleted file mode 100644
index 0b8f6da..0000000
--- a/core/modules/comment/src/Plugin/Menu/LocalTask/UnapprovedComments.php
+++ /dev/null
@@ -1,63 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\comment\Plugin\Menu\LocalTask\UnapprovedComments.
- */
-
-namespace Drupal\comment\Plugin\Menu\LocalTask;
-
-use Drupal\comment\CommentStorageInterface;
-use Drupal\Core\Menu\LocalTaskDefault;
-use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Provides a local task that shows the amount of unapproved comments.
- */
-class UnapprovedComments extends LocalTaskDefault implements ContainerFactoryPluginInterface {
-
-  /**
-   * The comment storage service.
-   *
-   * @var \Drupal\comment\CommentStorageInterface
-   */
-  protected $commentStorage;
-
-  /**
-   * Construct the UnapprovedComments 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\comment\CommentStorageInterface $comment_storage
-   *   The comment storage service.
-   */
-  public function __construct(array $configuration, $plugin_id, array $plugin_definition, CommentStorageInterface $comment_storage) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition);
-    $this->commentStorage = $comment_storage;
-  }
-
-  /**
-   * {@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')->getStorage('comment')
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getTitle() {
-    return t('Unapproved comments (@count)', array('@count' => $this->commentStorage->getUnapprovedCount()));
-  }
-
-}
diff --git a/core/modules/comment/src/Plugin/Menu/LocalTask/UnpublishedComments.php b/core/modules/comment/src/Plugin/Menu/LocalTask/UnpublishedComments.php
new file mode 100644
index 0000000..116641f
--- /dev/null
+++ b/core/modules/comment/src/Plugin/Menu/LocalTask/UnpublishedComments.php
@@ -0,0 +1,63 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\comment\Plugin\Menu\LocalTask\UnpublishedComments.
+ */
+
+namespace Drupal\comment\Plugin\Menu\LocalTask;
+
+use Drupal\comment\CommentStorageInterface;
+use Drupal\Core\Menu\LocalTaskDefault;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Provides a local task that shows the amount of unpublished comments.
+ */
+class UnpublishedComments extends LocalTaskDefault implements ContainerFactoryPluginInterface {
+
+  /**
+   * The comment storage service.
+   *
+   * @var \Drupal\comment\CommentStorageInterface
+   */
+  protected $commentStorage;
+
+  /**
+   * Construct the UnpublishedComments 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\comment\CommentStorageInterface $comment_storage
+   *   The comment storage service.
+   */
+  public function __construct(array $configuration, $plugin_id, array $plugin_definition, CommentStorageInterface $comment_storage) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+    $this->commentStorage = $comment_storage;
+  }
+
+  /**
+   * {@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')->getStorage('comment')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getTitle() {
+    return t('Unpublished comments (@count)', array('@count' => $this->commentStorage->getUnpublishedCount()));
+  }
+
+}
diff --git a/core/modules/comment/src/Plugin/views/field/LinkApprove.php b/core/modules/comment/src/Plugin/views/field/LinkApprove.php
deleted file mode 100644
index 1fde0a7..0000000
--- a/core/modules/comment/src/Plugin/views/field/LinkApprove.php
+++ /dev/null
@@ -1,60 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\comment\Plugin\views\field\LinkApprove.
- */
-
-namespace Drupal\comment\Plugin\views\field;
-
-use Drupal\comment\CommentInterface;
-use Drupal\Core\Session\AccountInterface;
-use Drupal\views\ResultRow;
-
-/**
- * Provides a comment approve link.
- *
- * @ingroup views_field_handlers
- *
- * @ViewsField("comment_link_approve")
- */
-class LinkApprove extends Link {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function access(AccountInterface $account) {
-    //needs permission to administer comments in general
-    return $account->hasPermission('administer comments');
-  }
-
-  /**
-   * Prepares the link pointing for approving the comment.
-   *
-   * @param \Drupal\Core\Entity\EntityInterface $data
-   *   The comment entity.
-   * @param \Drupal\views\ResultRow $values
-   *   The values retrieved from a single row of a view's query result.
-   *
-   * @return string
-   *   Returns a string for the link text.
-   */
-  protected function renderLink($data, ResultRow $values) {
-    $status = $this->getValue($values, 'status');
-
-    // Don't show an approve link on published comment.
-    if ($status == CommentInterface::PUBLISHED) {
-      return;
-    }
-
-    $text = !empty($this->options['text']) ? $this->options['text'] : t('Approve');
-    $comment = $this->get_entity($values);
-
-    $this->options['alter']['make_link'] = TRUE;
-    $this->options['alter']['path'] = "comment/" . $comment->id() . "/approve";
-    $this->options['alter']['query'] = drupal_get_destination() + array('token' => \Drupal::csrfToken()->get($this->options['alter']['path']));
-
-    return $text;
-  }
-
-}
diff --git a/core/modules/comment/src/Plugin/views/field/LinkPublish.php b/core/modules/comment/src/Plugin/views/field/LinkPublish.php
new file mode 100644
index 0000000..29c7e82
--- /dev/null
+++ b/core/modules/comment/src/Plugin/views/field/LinkPublish.php
@@ -0,0 +1,60 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\comment\Plugin\views\field\LinkPublish.
+ */
+
+namespace Drupal\comment\Plugin\views\field;
+
+use Drupal\comment\CommentInterface;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\views\ResultRow;
+
+/**
+ * Provides a comment publish link.
+ *
+ * @ingroup views_field_handlers
+ *
+ * @ViewsField("comment_link_publish")
+ */
+class LinkPublish extends Link {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function access(AccountInterface $account) {
+    //needs permission to administer comments in general
+    return $account->hasPermission('administer comments');
+  }
+
+  /**
+   * Prepares the link for publishing the comment.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $data
+   *   The comment entity.
+   * @param \Drupal\views\ResultRow $values
+   *   The values retrieved from a single row of a view's query result.
+   *
+   * @return string
+   *   Returns a string for the link text.
+   */
+  protected function renderLink($data, ResultRow $values) {
+    $status = $this->getValue($values, 'status');
+
+    // Don't show a publish link on published comment.
+    if ($status == CommentInterface::PUBLISHED) {
+      return;
+    }
+
+    $text = !empty($this->options['text']) ? $this->options['text'] : t('Publish');
+    $comment = $this->get_entity($values);
+
+    $this->options['alter']['make_link'] = TRUE;
+    $this->options['alter']['path'] = "comment/" . $comment->id() . "/publish";
+    $this->options['alter']['query'] = drupal_get_destination() + array('token' => \Drupal::csrfToken()->get($this->options['alter']['path']));
+
+    return $text;
+  }
+
+}
diff --git a/core/modules/comment/src/Plugin/views/field/LinkUnpublish.php b/core/modules/comment/src/Plugin/views/field/LinkUnpublish.php
new file mode 100644
index 0000000..a11bc0a
--- /dev/null
+++ b/core/modules/comment/src/Plugin/views/field/LinkUnpublish.php
@@ -0,0 +1,60 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\comment\Plugin\views\field\LinkUnpublish.
+ */
+
+namespace Drupal\comment\Plugin\views\field;
+
+use Drupal\comment\CommentInterface;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\views\ResultRow;
+
+/**
+ * Provides a comment unpublish link.
+ *
+ * @ingroup views_field_handlers
+ *
+ * @ViewsField("comment_link_unpublish")
+ */
+class LinkUnpublish extends Link {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function access(AccountInterface $account) {
+    //needs permission to administer comments in general
+    return $account->hasPermission('administer comments');
+  }
+
+  /**
+   * Prepares the link for unpublishing the comment.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $data
+   *   The comment entity.
+   * @param \Drupal\views\ResultRow $values
+   *   The values retrieved from a single row of a view's query result.
+   *
+   * @return string
+   *   Returns a string for the link text.
+   */
+  protected function renderLink($data, ResultRow $values) {
+    $status = $this->getValue($values, 'status');
+
+    // Don't show an unpublish link on unpublished comment.
+    if ($status == CommentInterface::NOT_PUBLISHED) {
+      return;
+    }
+
+    $text = !empty($this->options['text']) ? $this->options['text'] : t('Unpublish');
+    $comment = $this->get_entity($values);
+
+    $this->options['alter']['make_link'] = TRUE;
+    $this->options['alter']['path'] = "comment/" . $comment->id() . "/unpublish";
+    $this->options['alter']['query'] = drupal_get_destination() + array('token' => \Drupal::csrfToken()->get($this->options['alter']['path']));
+
+    return $text;
+  }
+
+}
diff --git a/core/modules/comment/src/Tests/CommentAdminTest.php b/core/modules/comment/src/Tests/CommentAdminTest.php
index 0ca8f2e..049523d 100644
--- a/core/modules/comment/src/Tests/CommentAdminTest.php
+++ b/core/modules/comment/src/Tests/CommentAdminTest.php
@@ -8,15 +8,15 @@
 namespace Drupal\comment\Tests;
 
 /**
- * Tests comment approval functionality.
+ * Tests comment administration functionality.
  *
  * @group comment
  */
 class CommentAdminTest extends CommentTestBase {
   /**
-   * Test comment approval functionality through admin/content/comment.
+   * Tests comment overview with published and unpublished comments.
    */
-  function testApprovalAdminInterface() {
+  function testContentAdminPages() {
     // Set anonymous comments to require approval.
     user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array(
       'access comments' => TRUE,
@@ -38,9 +38,9 @@ function testApprovalAdminInterface() {
     $this->postComment($this->node, $body, $subject, TRUE); // Set $contact to true so that it won't check for id and message.
     $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.
+    // Get unpublished comment id.
     $this->drupalLogin($this->admin_user);
-    $anonymous_comment4 = $this->getUnapprovedComment($subject);
+    $anonymous_comment4 = $this->getUnpublishedComment($subject);
     $anonymous_comment4 = entity_create('comment', array(
       'cid' => $anonymous_comment4,
       'subject' => $subject,
@@ -53,7 +53,7 @@ function testApprovalAdminInterface() {
 
     $this->assertFalse($this->commentExists($anonymous_comment4), 'Anonymous comment was not published.');
 
-    // Approve comment.
+    // Publish comment.
     $this->drupalLogin($this->admin_user);
     $this->performCommentOperation($anonymous_comment4, 'publish', TRUE);
     $this->drupalLogout();
@@ -67,14 +67,14 @@ function testApprovalAdminInterface() {
 
     // Publish multiple comments in one operation.
     $this->drupalLogin($this->admin_user);
-    $this->drupalGet('admin/content/comment/approval');
-    $this->assertText(t('Unapproved comments (@count)', array('@count' => 2)), 'Two unapproved comments waiting for approval.');
+    $this->drupalGet('admin/content/comment/unpublished');
+    $this->assertText(t('Unpublished comments (@count)', array('@count' => 2)), 'Two unpublished comments waiting for approval.');
     $edit = array(
       "comments[{$comments[0]->id()}]" => 1,
       "comments[{$comments[1]->id()}]" => 1,
     );
     $this->drupalPostForm(NULL, $edit, t('Update'));
-    $this->assertText(t('Unapproved comments (@count)', array('@count' => 0)), 'All comments were approved.');
+    $this->assertText(t('Unpublished comments (@count)', array('@count' => 0)), 'All comments were unpublished.');
 
     // Delete multiple comments in one operation.
     $edit = array(
@@ -96,9 +96,9 @@ function testApprovalAdminInterface() {
   }
 
   /**
-   * Tests comment approval functionality through the node interface.
+   * Tests comment publish functionality through the node interface.
    */
-  function testApprovalNodeInterface() {
+  function testPublishNodeInterface() {
     // Set anonymous comments to require approval.
     user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array(
       'access comments' => TRUE,
@@ -115,9 +115,9 @@ function testApprovalNodeInterface() {
     $this->postComment($this->node, $body, $subject, TRUE); // Set $contact to true so that it won't check for id and message.
     $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.
+    // Get unpublished comment id.
     $this->drupalLogin($this->admin_user);
-    $anonymous_comment4 = $this->getUnapprovedComment($subject);
+    $anonymous_comment4 = $this->getUnpublishedComment($subject);
     $anonymous_comment4 = entity_create('comment', array(
       'cid' => $anonymous_comment4,
       'subject' => $subject,
@@ -130,18 +130,31 @@ function testApprovalNodeInterface() {
 
     $this->assertFalse($this->commentExists($anonymous_comment4), 'Anonymous comment was not published.');
 
-    // Approve comment.
+    // Publish comment.
     $this->drupalLogin($this->admin_user);
-    $this->drupalGet('comment/1/approve');
-    $this->assertResponse(403, 'Forged comment approval was denied.');
-    $this->drupalGet('comment/1/approve', array('query' => array('token' => 'forged')));
-    $this->assertResponse(403, 'Forged comment approval was denied.');
+    $this->drupalGet('comment/1/publish');
+    $this->assertResponse(403, 'Forged comment publishing was denied.');
+    $this->drupalGet('comment/1/publish', array('query' => array('token' => 'forged')));
+    $this->assertResponse(403, 'Forged comment publishing was denied.');
     $this->drupalGet('node/' . $this->node->id());
-    $this->clickLink(t('Approve'));
+    $this->clickLink(t('Publish'));
     $this->drupalLogout();
 
     $this->drupalGet('node/' . $this->node->id());
     $this->assertTrue($this->commentExists($anonymous_comment4), 'Anonymous comment visible.');
+
+    // Unpublish comment.
+    $this->drupalLogin($this->admin_user);
+    $this->drupalGet('comment/1/unpublish');
+    $this->assertResponse(403, 'Forged comment unpublishing was denied.');
+    $this->drupalGet('comment/1/unpublish', array('query' => array('token' => 'forged')));
+    $this->assertResponse(403, 'Forged comment unpublishing was denied.');
+    $this->drupalGet('node/' . $this->node->id());
+    $this->clickLink(t('Unpublish'));
+    $this->drupalLogout();
+
+    $this->drupalGet('node/' . $this->node->id());
+    $this->assertFalse($this->commentExists($anonymous_comment4), 'Anonymous comment not visible.');
   }
 
   /**
diff --git a/core/modules/comment/src/Tests/CommentAnonymousTest.php b/core/modules/comment/src/Tests/CommentAnonymousTest.php
index 1b46bdd..146c32f 100644
--- a/core/modules/comment/src/Tests/CommentAnonymousTest.php
+++ b/core/modules/comment/src/Tests/CommentAnonymousTest.php
@@ -98,7 +98,7 @@ function testAnonymous() {
     // Unpublish comment.
     $this->performCommentOperation($anonymous_comment3, 'unpublish');
 
-    $this->drupalGet('admin/content/comment/approval');
+    $this->drupalGet('admin/content/comment/unpublished');
     $this->assertRaw('comments[' . $anonymous_comment3->id() . ']', 'Comment was unpublished.');
 
     // Publish comment.
diff --git a/core/modules/comment/src/Tests/CommentNonNodeTest.php b/core/modules/comment/src/Tests/CommentNonNodeTest.php
index e13a019..217bf82 100644
--- a/core/modules/comment/src/Tests/CommentNonNodeTest.php
+++ b/core/modules/comment/src/Tests/CommentNonNodeTest.php
@@ -194,14 +194,14 @@ function commentContactInfoAvailable() {
    *   Comment to perform operation on.
    * @param string $operation
    *   Operation to perform.
-   * @param boolean $aproval
-   *   Operation is found on approval page.
+   * @param boolean $unpublished
+   *   Operation is found on unpublished comments page.
    */
-  function performCommentOperation($comment, $operation, $approval = FALSE) {
+  function performCommentOperation($comment, $operation, $unpublished = FALSE) {
     $edit = array();
     $edit['operation'] = $operation;
     $edit['comments[' . $comment->id() . ']'] = TRUE;
-    $this->drupalPostForm('admin/content/comment' . ($approval ? '/approval' : ''), $edit, t('Update'));
+    $this->drupalPostForm('admin/content/comment' . ($unpublished ? '/unpublished' : ''), $edit, t('Update'));
 
     if ($operation == 'delete') {
       $this->drupalPostForm(NULL, array(), t('Delete comments'));
@@ -213,7 +213,7 @@ function performCommentOperation($comment, $operation, $approval = FALSE) {
   }
 
   /**
-   * Gets the comment ID for an unapproved comment.
+   * Gets the comment ID for an unapproved (unpublished) comment.
    *
    * @param string $subject
    *   Comment subject to find.
@@ -221,8 +221,8 @@ function performCommentOperation($comment, $operation, $approval = FALSE) {
    * @return integer
    *   Comment ID.
    */
-  function getUnapprovedComment($subject) {
-    $this->drupalGet('admin/content/comment/approval');
+  function getUnpublishedComment($subject) {
+    $this->drupalGet('admin/content/comment/unpublished');
     preg_match('/href="(.*?)#comment-([^"]+)"(.*?)>(' . $subject . ')/', $this->drupalGetContent(), $match);
 
     return $match[2];
@@ -256,7 +256,7 @@ function testCommentFunctionality() {
 
     // Unpublish the comment.
     $this->performCommentOperation($comment1, 'unpublish');
-    $this->drupalGet('admin/content/comment/approval');
+    $this->drupalGet('admin/content/comment/unpublished');
     $this->assertRaw('comments[' . $comment1->id() . ']', 'Comment was unpublished.');
 
     // Publish the comment.
diff --git a/core/modules/comment/src/Tests/CommentTestBase.php b/core/modules/comment/src/Tests/CommentTestBase.php
index 6decc59..39fc5a7 100644
--- a/core/modules/comment/src/Tests/CommentTestBase.php
+++ b/core/modules/comment/src/Tests/CommentTestBase.php
@@ -332,14 +332,14 @@ function commentContactInfoAvailable() {
    *   Comment to perform operation on.
    * @param string $operation
    *   Operation to perform.
-   * @param boolean $aproval
-   *   Operation is found on approval page.
+   * @param boolean $unpublished
+   *   Operation is found on unpublished comments page.
    */
-  function performCommentOperation(CommentInterface $comment, $operation, $approval = FALSE) {
+  function performCommentOperation(CommentInterface $comment, $operation, $unpublished = FALSE) {
     $edit = array();
     $edit['operation'] = $operation;
     $edit['comments[' . $comment->id() . ']'] = TRUE;
-    $this->drupalPostForm('admin/content/comment' . ($approval ? '/approval' : ''), $edit, t('Update'));
+    $this->drupalPostForm('admin/content/comment' . ($unpublished ? '/unpublished' : ''), $edit, t('Update'));
 
     if ($operation == 'delete') {
       $this->drupalPostForm(NULL, array(), t('Delete comments'));
@@ -351,7 +351,7 @@ function performCommentOperation(CommentInterface $comment, $operation, $approva
   }
 
   /**
-   * Gets the comment ID for an unapproved comment.
+   * Gets the comment ID for an unapproved (unpublished) comment.
    *
    * @param string $subject
    *   Comment subject to find.
@@ -359,8 +359,8 @@ function performCommentOperation(CommentInterface $comment, $operation, $approva
    * @return integer
    *   Comment id.
    */
-  function getUnapprovedComment($subject) {
-    $this->drupalGet('admin/content/comment/approval');
+  function getUnpublishedComment($subject) {
+    $this->drupalGet('admin/content/comment/unpublished');
     preg_match('/href="(.*?)#comment-([^"]+)"(.*?)>(' . $subject . ')/', $this->drupalGetContent(), $match);
 
     return $match[2];
