From bd65ce7887ced3bb197ade1b4561a68dfa107978 Mon Sep 17 00:00:00 2001
From: Damian Lee <damian@damoweb.co.uk>
Date: Sat, 28 Jul 2012 18:33:10 +0100
Subject: [PATCH] Copied all module handlers to new plugin folder structure

---
 ...ndler_argument_aggregator_category_cid.inc |  28 +
 .../views_handler_argument_aggregator_fid.inc |  28 +
 .../views_handler_argument_aggregator_iid.inc |  32 +
 ...iews_handler_field_aggregator_category.inc |  62 ++
 ...ws_handler_field_aggregator_title_link.inc |  57 ++
 .../views_handler_field_aggregator_xss.inc    |  20 +
 ...handler_filter_aggregator_category_cid.inc |  28 +
 .../row/views_plugin_row_aggregator_rss.inc   |  76 ++
 ...iews_plugin_argument_default_book_root.inc |  23 +
 ...iews_handler_argument_comment_user_uid.inc |  61 ++
 .../field/views_handler_field_comment.inc     |  75 ++
 .../views_handler_field_comment_depth.inc     |  21 +
 .../views_handler_field_comment_link.inc      |  69 ++
 ...ews_handler_field_comment_link_approve.inc |  36 +
 ...iews_handler_field_comment_link_delete.inc |  29 +
 .../views_handler_field_comment_link_edit.inc |  52 +
 ...views_handler_field_comment_link_reply.inc |  29 +
 .../views_handler_field_comment_node_link.inc |  64 ++
 .../views_handler_field_comment_username.inc  |  58 ++
 ...s_handler_field_last_comment_timestamp.inc |  28 +
 ...ws_handler_field_ncs_last_comment_name.inc |  56 ++
 .../views_handler_field_ncs_last_updated.inc  |  18 +
 .../views_handler_field_node_comment.inc      |  28 +
 .../views_handler_field_node_new_comments.inc | 118 +++
 .../views_handler_filter_comment_user_uid.inc |  29 +
 .../views_handler_filter_ncs_last_updated.inc |  27 +
 .../views_handler_filter_node_comment.inc     |  23 +
 .../row/views_plugin_row_comment_rss.inc      | 154 +++
 .../row/views_plugin_row_comment_view.inc     |  99 ++
 .../views_handler_sort_comment_thread.inc     |  38 +
 ...ews_handler_sort_ncs_last_comment_name.inc |  40 +
 .../views_handler_sort_ncs_last_updated.inc   |  22 +
 .../views_handler_field_contact_link.inc      |  57 ++
 .../views_handler_argument_field_list.inc     |  64 ++
 ...ews_handler_argument_field_list_string.inc |  66 ++
 .../views/field/views_handler_field_field.inc | 939 ++++++++++++++++++
 .../views_handler_filter_field_list.inc       |  20 +
 ...ws_handler_relationship_entity_reverse.inc |  87 ++
 ...views_handler_field_filter_format_name.inc |  36 +
 .../views_handler_argument_locale_group.inc   |  40 +
 ...views_handler_argument_locale_language.inc |  38 +
 .../views_handler_field_locale_group.inc      |  21 +
 .../views_handler_field_locale_language.inc   |  36 +
 .../views_handler_field_locale_link_edit.inc  |  60 ++
 .../views_handler_field_node_language.inc     |  37 +
 .../views_handler_filter_locale_group.inc     |  25 +
 .../views_handler_filter_locale_language.inc  |  28 +
 .../views_handler_filter_locale_version.inc   |  30 +
 .../views_handler_filter_node_language.inc    |  28 +
 .../views_handler_argument_dates_various.inc  | 178 ++++
 .../views_handler_argument_node_language.inc  |  36 +
 .../views_handler_argument_node_nid.inc       |  24 +
 .../views_handler_argument_node_type.inc      |  39 +
 ...ews_handler_argument_node_uid_revision.inc |  18 +
 .../views_handler_argument_node_vid.inc       |  26 +
 .../views_plugin_argument_default_node.inc    |  28 +
 .../views_plugin_argument_validate_node.inc   | 141 +++
 ...s_handler_field_history_user_timestamp.inc |  83 ++
 .../views/field/views_handler_field_node.inc  |  82 ++
 .../field/views_handler_field_node_link.inc   |  48 +
 .../views_handler_field_node_link_delete.inc  |  31 +
 .../views_handler_field_node_link_edit.inc    |  31 +
 .../field/views_handler_field_node_path.inc   |  47 +
 .../views_handler_field_node_revision.inc     |  71 ++
 ...views_handler_field_node_revision_link.inc |  66 ++
 ...andler_field_node_revision_link_delete.inc |  36 +
 ...andler_field_node_revision_link_revert.inc |  36 +
 .../field/views_handler_field_node_type.inc   |  49 +
 ..._handler_filter_history_user_timestamp.inc |  89 ++
 .../views_handler_filter_node_access.inc      |  43 +
 .../filter/views_handler_filter_node_type.inc |  28 +
 ...views_handler_filter_node_uid_revision.inc |  25 +
 .../views/row/views_plugin_row_node_rss.inc   | 176 ++++
 .../views/row/views_plugin_row_node_view.inc  | 110 ++
 .../views_handler_argument_search.inc         | 103 ++
 .../views_handler_field_search_score.inc      |  83 ++
 .../filter/views_handler_filter_search.inc    | 220 ++++
 .../row/views_plugin_row_search_view.inc      |  41 +
 .../sort/views_handler_sort_search_score.inc  |  41 +
 .../views_handler_field_accesslog_path.inc    |  60 ++
 .../views_handler_argument_file_fid.inc       |  28 +
 .../views/field/views_handler_field_file.inc  |  61 ++
 .../views_handler_field_file_extension.inc    |  19 +
 .../views_handler_field_file_filemime.inc     |  38 +
 .../field/views_handler_field_file_status.inc |  18 +
 .../field/views_handler_field_file_uri.inc    |  35 +
 .../views_handler_filter_file_status.inc      |  19 +
 .../views_handler_filter_system_type.inc      |  21 +
 .../views_handler_argument_taxonomy.inc       |  29 +
 .../views_handler_argument_term_node_tid.inc  |  49 +
 ...s_handler_argument_term_node_tid_depth.inc | 149 +++
 ..._argument_term_node_tid_depth_modifier.inc |  64 ++
 ...ndler_argument_vocabulary_machine_name.inc |  28 +
 .../views_handler_argument_vocabulary_vid.inc |  28 +
 ...s_plugin_argument_default_taxonomy_tid.inc | 156 +++
 ...plugin_argument_validate_taxonomy_term.inc | 222 +++++
 .../field/views_handler_field_taxonomy.inc    |  86 ++
 .../views_handler_field_term_link_edit.inc    |  60 ++
 .../views_handler_field_term_node_tid.inc     | 148 +++
 .../views_handler_filter_term_node_tid.inc    | 364 +++++++
 ...ews_handler_filter_term_node_tid_depth.inc | 100 ++
 ...handler_filter_vocabulary_machine_name.inc |  25 +
 .../views_handler_filter_vocabulary_vid.inc   |  25 +
 ...ws_handler_relationship_node_term_data.inc |  98 ++
 .../views_handler_argument_node_tnid.inc      |  26 +
 ...iews_handler_field_node_link_translate.inc |  29 +
 ...ws_handler_field_node_translation_link.inc |  49 +
 .../filter/views_handler_filter_node_tnid.inc |  45 +
 .../views_handler_filter_node_tnid_child.inc  |  22 +
 ...views_handler_relationship_translation.inc | 106 ++
 .../views_handler_argument_user_uid.inc       |  35 +
 ...views_handler_argument_users_roles_rid.inc |  25 +
 ...s_plugin_argument_default_current_user.inc |  20 +
 .../views_plugin_argument_default_user.inc    |  79 ++
 .../views_plugin_argument_validate_user.inc   | 142 +++
 .../views/field/views_handler_field_user.inc  |  55 +
 .../views_handler_field_user_language.inc     |  39 +
 .../field/views_handler_field_user_link.inc   |  58 ++
 .../views_handler_field_user_link_cancel.inc  |  33 +
 .../views_handler_field_user_link_edit.inc    |  30 +
 .../field/views_handler_field_user_mail.inc   |  44 +
 .../field/views_handler_field_user_name.inc   |  85 ++
 .../views_handler_field_user_permissions.inc  |  68 ++
 .../views_handler_field_user_picture.inc      | 116 +++
 .../field/views_handler_field_user_roles.inc  |  59 ++
 .../views_handler_filter_user_current.inc     |  38 +
 .../filter/views_handler_filter_user_name.inc | 152 +++
 .../views_handler_filter_user_permissions.inc |  37 +
 .../views_handler_filter_user_roles.inc       |  30 +
 .../views/row/views_plugin_row_user_view.inc  |  83 ++
 130 files changed, 8604 insertions(+)
 create mode 100644 lib/Drupal/aggregator/Plugin/views/argument/views_handler_argument_aggregator_category_cid.inc
 create mode 100644 lib/Drupal/aggregator/Plugin/views/argument/views_handler_argument_aggregator_fid.inc
 create mode 100644 lib/Drupal/aggregator/Plugin/views/argument/views_handler_argument_aggregator_iid.inc
 create mode 100644 lib/Drupal/aggregator/Plugin/views/field/views_handler_field_aggregator_category.inc
 create mode 100644 lib/Drupal/aggregator/Plugin/views/field/views_handler_field_aggregator_title_link.inc
 create mode 100644 lib/Drupal/aggregator/Plugin/views/field/views_handler_field_aggregator_xss.inc
 create mode 100644 lib/Drupal/aggregator/Plugin/views/filter/views_handler_filter_aggregator_category_cid.inc
 create mode 100644 lib/Drupal/aggregator/Plugin/views/row/views_plugin_row_aggregator_rss.inc
 create mode 100644 lib/Drupal/book/Plugin/views/argument_default/views_plugin_argument_default_book_root.inc
 create mode 100644 lib/Drupal/comment/Plugin/views/argument/views_handler_argument_comment_user_uid.inc
 create mode 100644 lib/Drupal/comment/Plugin/views/field/views_handler_field_comment.inc
 create mode 100644 lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_depth.inc
 create mode 100644 lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_link.inc
 create mode 100644 lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_link_approve.inc
 create mode 100644 lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_link_delete.inc
 create mode 100644 lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_link_edit.inc
 create mode 100644 lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_link_reply.inc
 create mode 100644 lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_node_link.inc
 create mode 100644 lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_username.inc
 create mode 100644 lib/Drupal/comment/Plugin/views/field/views_handler_field_last_comment_timestamp.inc
 create mode 100644 lib/Drupal/comment/Plugin/views/field/views_handler_field_ncs_last_comment_name.inc
 create mode 100644 lib/Drupal/comment/Plugin/views/field/views_handler_field_ncs_last_updated.inc
 create mode 100644 lib/Drupal/comment/Plugin/views/field/views_handler_field_node_comment.inc
 create mode 100644 lib/Drupal/comment/Plugin/views/field/views_handler_field_node_new_comments.inc
 create mode 100644 lib/Drupal/comment/Plugin/views/filter/views_handler_filter_comment_user_uid.inc
 create mode 100644 lib/Drupal/comment/Plugin/views/filter/views_handler_filter_ncs_last_updated.inc
 create mode 100644 lib/Drupal/comment/Plugin/views/filter/views_handler_filter_node_comment.inc
 create mode 100644 lib/Drupal/comment/Plugin/views/row/views_plugin_row_comment_rss.inc
 create mode 100644 lib/Drupal/comment/Plugin/views/row/views_plugin_row_comment_view.inc
 create mode 100644 lib/Drupal/comment/Plugin/views/sort/views_handler_sort_comment_thread.inc
 create mode 100644 lib/Drupal/comment/Plugin/views/sort/views_handler_sort_ncs_last_comment_name.inc
 create mode 100644 lib/Drupal/comment/Plugin/views/sort/views_handler_sort_ncs_last_updated.inc
 create mode 100644 lib/Drupal/contact/Plugin/views/field/views_handler_field_contact_link.inc
 create mode 100644 lib/Drupal/field/Plugin/views/argument/views_handler_argument_field_list.inc
 create mode 100644 lib/Drupal/field/Plugin/views/argument/views_handler_argument_field_list_string.inc
 create mode 100644 lib/Drupal/field/Plugin/views/field/views_handler_field_field.inc
 create mode 100644 lib/Drupal/field/Plugin/views/filter/views_handler_filter_field_list.inc
 create mode 100644 lib/Drupal/field/Plugin/views/relationship/views_handler_relationship_entity_reverse.inc
 create mode 100644 lib/Drupal/filter/Plugin/views/field/views_handler_field_filter_format_name.inc
 create mode 100644 lib/Drupal/locale/Plugin/views/argument/views_handler_argument_locale_group.inc
 create mode 100644 lib/Drupal/locale/Plugin/views/argument/views_handler_argument_locale_language.inc
 create mode 100644 lib/Drupal/locale/Plugin/views/field/views_handler_field_locale_group.inc
 create mode 100644 lib/Drupal/locale/Plugin/views/field/views_handler_field_locale_language.inc
 create mode 100644 lib/Drupal/locale/Plugin/views/field/views_handler_field_locale_link_edit.inc
 create mode 100644 lib/Drupal/locale/Plugin/views/field/views_handler_field_node_language.inc
 create mode 100644 lib/Drupal/locale/Plugin/views/filter/views_handler_filter_locale_group.inc
 create mode 100644 lib/Drupal/locale/Plugin/views/filter/views_handler_filter_locale_language.inc
 create mode 100644 lib/Drupal/locale/Plugin/views/filter/views_handler_filter_locale_version.inc
 create mode 100644 lib/Drupal/locale/Plugin/views/filter/views_handler_filter_node_language.inc
 create mode 100644 lib/Drupal/node/Plugin/views/argument/views_handler_argument_dates_various.inc
 create mode 100644 lib/Drupal/node/Plugin/views/argument/views_handler_argument_node_language.inc
 create mode 100644 lib/Drupal/node/Plugin/views/argument/views_handler_argument_node_nid.inc
 create mode 100644 lib/Drupal/node/Plugin/views/argument/views_handler_argument_node_type.inc
 create mode 100644 lib/Drupal/node/Plugin/views/argument/views_handler_argument_node_uid_revision.inc
 create mode 100644 lib/Drupal/node/Plugin/views/argument/views_handler_argument_node_vid.inc
 create mode 100644 lib/Drupal/node/Plugin/views/argument_default/views_plugin_argument_default_node.inc
 create mode 100644 lib/Drupal/node/Plugin/views/argument_validate/views_plugin_argument_validate_node.inc
 create mode 100644 lib/Drupal/node/Plugin/views/field/views_handler_field_history_user_timestamp.inc
 create mode 100644 lib/Drupal/node/Plugin/views/field/views_handler_field_node.inc
 create mode 100644 lib/Drupal/node/Plugin/views/field/views_handler_field_node_link.inc
 create mode 100644 lib/Drupal/node/Plugin/views/field/views_handler_field_node_link_delete.inc
 create mode 100644 lib/Drupal/node/Plugin/views/field/views_handler_field_node_link_edit.inc
 create mode 100644 lib/Drupal/node/Plugin/views/field/views_handler_field_node_path.inc
 create mode 100644 lib/Drupal/node/Plugin/views/field/views_handler_field_node_revision.inc
 create mode 100644 lib/Drupal/node/Plugin/views/field/views_handler_field_node_revision_link.inc
 create mode 100644 lib/Drupal/node/Plugin/views/field/views_handler_field_node_revision_link_delete.inc
 create mode 100644 lib/Drupal/node/Plugin/views/field/views_handler_field_node_revision_link_revert.inc
 create mode 100644 lib/Drupal/node/Plugin/views/field/views_handler_field_node_type.inc
 create mode 100644 lib/Drupal/node/Plugin/views/filter/views_handler_filter_history_user_timestamp.inc
 create mode 100644 lib/Drupal/node/Plugin/views/filter/views_handler_filter_node_access.inc
 create mode 100644 lib/Drupal/node/Plugin/views/filter/views_handler_filter_node_type.inc
 create mode 100644 lib/Drupal/node/Plugin/views/filter/views_handler_filter_node_uid_revision.inc
 create mode 100644 lib/Drupal/node/Plugin/views/row/views_plugin_row_node_rss.inc
 create mode 100644 lib/Drupal/node/Plugin/views/row/views_plugin_row_node_view.inc
 create mode 100644 lib/Drupal/search/Plugin/views/argument/views_handler_argument_search.inc
 create mode 100644 lib/Drupal/search/Plugin/views/field/views_handler_field_search_score.inc
 create mode 100644 lib/Drupal/search/Plugin/views/filter/views_handler_filter_search.inc
 create mode 100644 lib/Drupal/search/Plugin/views/row/views_plugin_row_search_view.inc
 create mode 100644 lib/Drupal/search/Plugin/views/sort/views_handler_sort_search_score.inc
 create mode 100644 lib/Drupal/statistics/Plugin/views/field/views_handler_field_accesslog_path.inc
 create mode 100644 lib/Drupal/system/Plugin/views/argument/views_handler_argument_file_fid.inc
 create mode 100644 lib/Drupal/system/Plugin/views/field/views_handler_field_file.inc
 create mode 100644 lib/Drupal/system/Plugin/views/field/views_handler_field_file_extension.inc
 create mode 100644 lib/Drupal/system/Plugin/views/field/views_handler_field_file_filemime.inc
 create mode 100644 lib/Drupal/system/Plugin/views/field/views_handler_field_file_status.inc
 create mode 100644 lib/Drupal/system/Plugin/views/field/views_handler_field_file_uri.inc
 create mode 100644 lib/Drupal/system/Plugin/views/filter/views_handler_filter_file_status.inc
 create mode 100644 lib/Drupal/system/Plugin/views/filter/views_handler_filter_system_type.inc
 create mode 100644 lib/Drupal/taxonomy/Plugin/views/argument/views_handler_argument_taxonomy.inc
 create mode 100644 lib/Drupal/taxonomy/Plugin/views/argument/views_handler_argument_term_node_tid.inc
 create mode 100644 lib/Drupal/taxonomy/Plugin/views/argument/views_handler_argument_term_node_tid_depth.inc
 create mode 100644 lib/Drupal/taxonomy/Plugin/views/argument/views_handler_argument_term_node_tid_depth_modifier.inc
 create mode 100644 lib/Drupal/taxonomy/Plugin/views/argument/views_handler_argument_vocabulary_machine_name.inc
 create mode 100644 lib/Drupal/taxonomy/Plugin/views/argument/views_handler_argument_vocabulary_vid.inc
 create mode 100644 lib/Drupal/taxonomy/Plugin/views/argument_default/views_plugin_argument_default_taxonomy_tid.inc
 create mode 100644 lib/Drupal/taxonomy/Plugin/views/argument_validate/views_plugin_argument_validate_taxonomy_term.inc
 create mode 100644 lib/Drupal/taxonomy/Plugin/views/field/views_handler_field_taxonomy.inc
 create mode 100644 lib/Drupal/taxonomy/Plugin/views/field/views_handler_field_term_link_edit.inc
 create mode 100644 lib/Drupal/taxonomy/Plugin/views/field/views_handler_field_term_node_tid.inc
 create mode 100644 lib/Drupal/taxonomy/Plugin/views/filter/views_handler_filter_term_node_tid.inc
 create mode 100644 lib/Drupal/taxonomy/Plugin/views/filter/views_handler_filter_term_node_tid_depth.inc
 create mode 100644 lib/Drupal/taxonomy/Plugin/views/filter/views_handler_filter_vocabulary_machine_name.inc
 create mode 100644 lib/Drupal/taxonomy/Plugin/views/filter/views_handler_filter_vocabulary_vid.inc
 create mode 100644 lib/Drupal/taxonomy/Plugin/views/relationship/views_handler_relationship_node_term_data.inc
 create mode 100644 lib/Drupal/translation/Plugin/views/argument/views_handler_argument_node_tnid.inc
 create mode 100644 lib/Drupal/translation/Plugin/views/field/views_handler_field_node_link_translate.inc
 create mode 100644 lib/Drupal/translation/Plugin/views/field/views_handler_field_node_translation_link.inc
 create mode 100644 lib/Drupal/translation/Plugin/views/filter/views_handler_filter_node_tnid.inc
 create mode 100644 lib/Drupal/translation/Plugin/views/filter/views_handler_filter_node_tnid_child.inc
 create mode 100644 lib/Drupal/translation/Plugin/views/relationship/views_handler_relationship_translation.inc
 create mode 100644 lib/Drupal/user/Plugin/views/argument/views_handler_argument_user_uid.inc
 create mode 100644 lib/Drupal/user/Plugin/views/argument/views_handler_argument_users_roles_rid.inc
 create mode 100644 lib/Drupal/user/Plugin/views/argument_default/views_plugin_argument_default_current_user.inc
 create mode 100644 lib/Drupal/user/Plugin/views/argument_default/views_plugin_argument_default_user.inc
 create mode 100644 lib/Drupal/user/Plugin/views/argument_validate/views_plugin_argument_validate_user.inc
 create mode 100644 lib/Drupal/user/Plugin/views/field/views_handler_field_user.inc
 create mode 100644 lib/Drupal/user/Plugin/views/field/views_handler_field_user_language.inc
 create mode 100644 lib/Drupal/user/Plugin/views/field/views_handler_field_user_link.inc
 create mode 100644 lib/Drupal/user/Plugin/views/field/views_handler_field_user_link_cancel.inc
 create mode 100644 lib/Drupal/user/Plugin/views/field/views_handler_field_user_link_edit.inc
 create mode 100644 lib/Drupal/user/Plugin/views/field/views_handler_field_user_mail.inc
 create mode 100644 lib/Drupal/user/Plugin/views/field/views_handler_field_user_name.inc
 create mode 100644 lib/Drupal/user/Plugin/views/field/views_handler_field_user_permissions.inc
 create mode 100644 lib/Drupal/user/Plugin/views/field/views_handler_field_user_picture.inc
 create mode 100644 lib/Drupal/user/Plugin/views/field/views_handler_field_user_roles.inc
 create mode 100644 lib/Drupal/user/Plugin/views/filter/views_handler_filter_user_current.inc
 create mode 100644 lib/Drupal/user/Plugin/views/filter/views_handler_filter_user_name.inc
 create mode 100644 lib/Drupal/user/Plugin/views/filter/views_handler_filter_user_permissions.inc
 create mode 100644 lib/Drupal/user/Plugin/views/filter/views_handler_filter_user_roles.inc
 create mode 100644 lib/Drupal/user/Plugin/views/row/views_plugin_row_user_view.inc

diff --git a/lib/Drupal/aggregator/Plugin/views/argument/views_handler_argument_aggregator_category_cid.inc b/lib/Drupal/aggregator/Plugin/views/argument/views_handler_argument_aggregator_category_cid.inc
new file mode 100644
index 000000000000..08865175858e
--- /dev/null
+++ b/lib/Drupal/aggregator/Plugin/views/argument/views_handler_argument_aggregator_category_cid.inc
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_argument_aggregator_category_cid.
+ */
+
+use Drupal\views\Plugins\views\argument\Numeric;
+
+/**
+ * Argument handler to accept an aggregator category id.
+ *
+ * @ingroup views_argument_handlers
+ */
+class views_handler_argument_aggregator_category_cid extends Numeric {
+  /**
+   * Override the behavior of title(). Get the title of the category.
+   */
+  function title_query() {
+    $titles = array();
+
+    $result = db_query("SELECT c.title FROM {aggregator_category} c WHERE c.cid IN (:cid)", array(':cid' => $this->value));
+    foreach ($result as $term) {
+      $titles[] = check_plain($term->title);
+    }
+    return $titles;
+  }
+}
diff --git a/lib/Drupal/aggregator/Plugin/views/argument/views_handler_argument_aggregator_fid.inc b/lib/Drupal/aggregator/Plugin/views/argument/views_handler_argument_aggregator_fid.inc
new file mode 100644
index 000000000000..99a1f05c4a80
--- /dev/null
+++ b/lib/Drupal/aggregator/Plugin/views/argument/views_handler_argument_aggregator_fid.inc
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_argument_aggregator_fid.
+ */
+
+use Drupal\views\Plugins\views\argument\Numeric;
+
+/**
+ * Argument handler to accept an aggregator feed id.
+ *
+ * @ingroup views_argument_handlers
+ */
+class views_handler_argument_aggregator_fid extends Numeric {
+  /**
+   * Override the behavior of title(). Get the title of the feed.
+   */
+  function title_query() {
+    $titles = array();
+
+    $result = db_query("SELECT f.title FROM {aggregator_feed} f WHERE f.fid IN (:fids)", array(':fids' => $this->value));
+    foreach ($result as $term) {
+      $titles[] = check_plain($term->title);
+    }
+    return $titles;
+  }
+}
diff --git a/lib/Drupal/aggregator/Plugin/views/argument/views_handler_argument_aggregator_iid.inc b/lib/Drupal/aggregator/Plugin/views/argument/views_handler_argument_aggregator_iid.inc
new file mode 100644
index 000000000000..659ceb633586
--- /dev/null
+++ b/lib/Drupal/aggregator/Plugin/views/argument/views_handler_argument_aggregator_iid.inc
@@ -0,0 +1,32 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_argument_aggregator_iid.
+ */
+
+use Drupal\views\Plugins\views\argument\Numeric;
+
+/**
+ * Argument handler to accept an aggregator item id.
+ *
+ * @ingroup views_argument_handlers
+ */
+class views_handler_argument_aggregator_iid extends Numeric {
+  /**
+   * Override the behavior of title(). Get the title of the category.
+   */
+  function title_query() {
+    $titles = array();
+    $placeholders = implode(', ', array_fill(0, sizeof($this->value), '%d'));
+
+    $result = db_select('aggregator_item')
+      ->condition('iid', $this->value, 'IN')
+      ->fields(array('title'))
+      ->execute();
+    foreach ($result as $term) {
+      $titles[] = check_plain($term->title);
+    }
+    return $titles;
+  }
+}
diff --git a/lib/Drupal/aggregator/Plugin/views/field/views_handler_field_aggregator_category.inc b/lib/Drupal/aggregator/Plugin/views/field/views_handler_field_aggregator_category.inc
new file mode 100644
index 000000000000..6d308e32fa27
--- /dev/null
+++ b/lib/Drupal/aggregator/Plugin/views/field/views_handler_field_aggregator_category.inc
@@ -0,0 +1,62 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_aggregator_category.
+ */
+
+use Drupal\views\Plugins\views\field\FieldPluginBase;
+
+/**
+ * Field handler to provide simple renderer that allows linking to aggregator
+ * category.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_aggregator_category extends FieldPluginBase {
+  /**
+   * Constructor to provide additional field to add.
+   */
+  function construct() {
+    parent::construct();
+    $this->additional_fields['cid'] = 'cid';
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['link_to_category'] = array('default' => FALSE, 'bool' => TRUE);
+    return $options;
+  }
+
+  /**
+   * Provide link to category option
+   */
+  function options_form(&$form, &$form_state) {
+    $form['link_to_category'] = array(
+      '#title' => t('Link this field to its aggregator category page'),
+      '#description' => t('This will override any other link you have set.'),
+      '#type' => 'checkbox',
+      '#default_value' => !empty($this->options['link_to_category']),
+    );
+    parent::options_form($form, $form_state);
+  }
+
+  /**
+   * Render whatever the data is as a link to the category.
+   *
+   * Data should be made XSS safe prior to calling this function.
+   */
+  function render_link($data, $values) {
+    $cid = $this->get_value($values, 'cid');
+    if (!empty($this->options['link_to_category']) && !empty($cid) && $data !== NULL && $data !== '') {
+      $this->options['alter']['make_link'] = TRUE;
+      $this->options['alter']['path'] = "aggregator/category/$cid";
+    }
+    return $data;
+  }
+
+  function render($values) {
+    $value = $this->get_value($values);
+    return $this->render_link($this->sanitize_value($value), $values);
+  }
+}
diff --git a/lib/Drupal/aggregator/Plugin/views/field/views_handler_field_aggregator_title_link.inc b/lib/Drupal/aggregator/Plugin/views/field/views_handler_field_aggregator_title_link.inc
new file mode 100644
index 000000000000..bfbcc1a4c653
--- /dev/null
+++ b/lib/Drupal/aggregator/Plugin/views/field/views_handler_field_aggregator_title_link.inc
@@ -0,0 +1,57 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_aggregator_title_link.
+ */
+
+use Drupal\views\Plugins\views\field\FieldPluginBase;
+
+/**
+ * Field handler that turns an item's title into a clickable link to the original
+ * source article.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_aggregator_title_link extends FieldPluginBase {
+  function construct() {
+    parent::construct();
+    $this->additional_fields['link'] = 'link';
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['display_as_link'] = array('default' => TRUE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  /**
+   * Provide link to the page being visited.
+   */
+  function options_form(&$form, &$form_state) {
+    $form['display_as_link'] = array(
+      '#title' => t('Display as link'),
+      '#type' => 'checkbox',
+      '#default_value' => !empty($this->options['display_as_link']),
+    );
+    parent::options_form($form, $form_state);
+  }
+
+  function render($values) {
+    $value = $this->get_value($values);
+    return $this->render_link($this->sanitize_value($value), $values);
+  }
+
+  function render_link($data, $values) {
+    $link = $this->get_value($values, 'link');
+    if (!empty($this->options['display_as_link'])) {
+      $this->options['alter']['make_link'] = TRUE;
+      $this->options['alter']['path'] = $link;
+      $this->options['alter']['html'] = TRUE;
+    }
+
+    return $data;
+  }
+}
diff --git a/lib/Drupal/aggregator/Plugin/views/field/views_handler_field_aggregator_xss.inc b/lib/Drupal/aggregator/Plugin/views/field/views_handler_field_aggregator_xss.inc
new file mode 100644
index 000000000000..eae41b1db960
--- /dev/null
+++ b/lib/Drupal/aggregator/Plugin/views/field/views_handler_field_aggregator_xss.inc
@@ -0,0 +1,20 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_aggregator_xss.
+ */
+
+use Drupal\views\Plugins\views\field\FieldPluginBase;
+
+/**
+ * Filters htmls tags from item.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_aggregator_xss extends FieldPluginBase {
+  function render($values) {
+    $value = $this->get_value($values);
+    return aggregator_filter_xss($value);
+  }
+}
diff --git a/lib/Drupal/aggregator/Plugin/views/filter/views_handler_filter_aggregator_category_cid.inc b/lib/Drupal/aggregator/Plugin/views/filter/views_handler_filter_aggregator_category_cid.inc
new file mode 100644
index 000000000000..e0b5921585d5
--- /dev/null
+++ b/lib/Drupal/aggregator/Plugin/views/filter/views_handler_filter_aggregator_category_cid.inc
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_filter_aggregator_category_cid.
+ */
+
+use Drupal\views\Plugins\views\filter\InOperator;
+
+/**
+ * Filter by aggregator category cid
+ *
+ * @ingroup views_filter_handlers
+ */
+class views_handler_filter_aggregator_category_cid extends InOperator {
+  function get_value_options() {
+    if (isset($this->value_options)) {
+      return;
+    }
+
+    $this->value_options = array();
+
+    $result = db_query('SELECT * FROM {aggregator_category} ORDER BY title');
+    foreach ($result as $category) {
+      $this->value_options[$category->cid] = $category->title;
+    }
+  }
+}
diff --git a/lib/Drupal/aggregator/Plugin/views/row/views_plugin_row_aggregator_rss.inc b/lib/Drupal/aggregator/Plugin/views/row/views_plugin_row_aggregator_rss.inc
new file mode 100644
index 000000000000..e53781bbcaff
--- /dev/null
+++ b/lib/Drupal/aggregator/Plugin/views/row/views_plugin_row_aggregator_rss.inc
@@ -0,0 +1,76 @@
+<?php
+
+/**
+ * @file
+ * Contains the Aggregator Item RSS row style plugin.
+ */
+
+use Drupal\views\Plugins\views\row\RowPluginBase;
+
+/**
+ * Plugin which loads an aggregator item and formats it as an RSS item.
+ */
+class views_plugin_row_aggregator_rss extends RowPluginBase {
+  var $base_table = 'aggregator_item';
+  var $base_field = 'iid';
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['item_length'] = array('default' => 'default');
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['item_length'] = array(
+      '#type' => 'select',
+      '#title' => t('Display type'),
+      '#options' => array(
+        'fulltext' => t('Full text'),
+        'teaser' => t('Title plus teaser'),
+        'title' => t('Title only'),
+        'default' => t('Use default RSS settings'),
+      ),
+      '#default_value' => $this->options['item_length'],
+    );
+  }
+
+  function render($row) {
+    $iid =  $row->{$this->field_alias};
+    $sql =  "SELECT ai.iid, ai.fid, ai.title, ai.link, ai.author, ai.description, ";
+    $sql .= "ai.timestamp, ai.guid, af.title AS feed_title, ai.link AS feed_LINK ";
+    $sql .= "FROM {aggregator_item} ai LEFT JOIN {aggregator_feed} af ON ai.fid = af.fid ";
+    $sql .= "WHERE ai.iid = :iid";
+
+    $item = db_query($sql, array(':iid' => $iid))->fetchObject();
+
+    $item->elements = array(
+      array(
+        'key' => 'pubDate',
+        'value' => gmdate('r', $item->timestamp),
+      ),
+      array(
+        'key' => 'dc:creator',
+        'value' => $item->author,
+      ),
+      array(
+        'key' => 'guid',
+        'value' => $item->guid,
+        'attributes' => array('isPermaLink' => 'false')
+      ),
+    );
+
+    foreach ($item->elements as $element) {
+      if (isset($element['namespace'])) {
+        $this->view->style_plugin->namespaces = array_merge($this->view->style_plugin->namespaces, $element['namespace']);
+      }
+    }
+
+    return theme($this->theme_functions(), array(
+      'view' => $this->view,
+      'options' => $this->options,
+      'row' => $item
+    ));
+  }
+}
diff --git a/lib/Drupal/book/Plugin/views/argument_default/views_plugin_argument_default_book_root.inc b/lib/Drupal/book/Plugin/views/argument_default/views_plugin_argument_default_book_root.inc
new file mode 100644
index 000000000000..22e14f7a3822
--- /dev/null
+++ b/lib/Drupal/book/Plugin/views/argument_default/views_plugin_argument_default_book_root.inc
@@ -0,0 +1,23 @@
+<?php
+/**
+ * @file
+ * Contains the book root from current node argument default plugin.
+ */
+
+use Drupal\views\Plugins\views\argument_default\Node;
+
+/**
+ * Default argument plugin to get the current node's book root.
+ */
+class views_plugin_argument_default_book_root extends Node {
+  function get_argument() {
+    // Use the argument_default_node plugin to get the nid argument.
+    $nid = parent::get_argument();
+    if (!empty($nid)) {
+      $node = node_load($nid);
+      if (isset($node->book['bid'])) {
+        return $node->book['bid'];
+      }
+    }
+  }
+}
diff --git a/lib/Drupal/comment/Plugin/views/argument/views_handler_argument_comment_user_uid.inc b/lib/Drupal/comment/Plugin/views/argument/views_handler_argument_comment_user_uid.inc
new file mode 100644
index 000000000000..d821f32c3613
--- /dev/null
+++ b/lib/Drupal/comment/Plugin/views/argument/views_handler_argument_comment_user_uid.inc
@@ -0,0 +1,61 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_argument_comment_user_uid.
+ */
+
+/**
+ * Argument handler to accept a user id to check for nodes that
+ * user posted or commented on.
+ *
+ * @ingroup views_argument_handlers
+ */
+class views_handler_argument_comment_user_uid extends views_handler_argument {
+  function title() {
+    if (!$this->argument) {
+      $title = variable_get('anonymous', t('Anonymous'));
+    }
+    else {
+      $title = db_query('SELECT u.name FROM {users} u WHERE u.uid = :uid', array(':uid' => $this->argument))->fetchField();
+    }
+    if (empty($title)) {
+      return t('No user');
+    }
+
+    return check_plain($title);
+  }
+
+  function default_actions($which = NULL) {
+    // Disallow summary views on this argument.
+    if (!$which) {
+      $actions = parent::default_actions();
+      unset($actions['summary asc']);
+      unset($actions['summary desc']);
+      return $actions;
+    }
+
+    if ($which != 'summary asc' && $which != 'summary desc') {
+      return parent::default_actions($which);
+    }
+  }
+
+  function query($group_by = FALSE) {
+    $this->ensure_my_table();
+
+    $subselect = db_select('comment', 'c');
+    $subselect->addField('c', 'cid');
+    $subselect->condition('c.uid', $this->argument);
+    $subselect->where("c.nid = $this->table_alias.nid");
+
+    $condition = db_or()
+      ->condition("$this->table_alias.uid", $this->argument, '=')
+      ->exists($subselect);
+
+    $this->query->add_where(0, $condition);
+  }
+
+  function get_sort_name() {
+    return t('Numerical', array(), array('context' => 'Sort order'));
+  }
+}
diff --git a/lib/Drupal/comment/Plugin/views/field/views_handler_field_comment.inc b/lib/Drupal/comment/Plugin/views/field/views_handler_field_comment.inc
new file mode 100644
index 000000000000..14da47d87a5a
--- /dev/null
+++ b/lib/Drupal/comment/Plugin/views/field/views_handler_field_comment.inc
@@ -0,0 +1,75 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_comment.
+ */
+
+use Drupal\views\Plugins\views\field\FieldPluginBase;
+
+/**
+ * Field handler to allow linking to a comment.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_comment extends FieldPluginBase {
+  /**
+   * Override init function to provide generic option to link to comment.
+   */
+  function init(&$view, &$options) {
+    parent::init($view, $options);
+    if (!empty($this->options['link_to_comment'])) {
+      $this->additional_fields['cid'] = 'cid';
+      $this->additional_fields['nid'] = 'nid';
+    }
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['link_to_comment'] = array('default' => TRUE, 'bool' => TRUE);
+    $options['link_to_node'] = array('default' => FALSE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  /**
+   * Provide link-to-comment option
+   */
+  function options_form(&$form, &$form_state) {
+    $form['link_to_comment'] = array(
+      '#title' => t('Link this field to its comment'),
+      '#description' => t("Enable to override this field's links."),
+      '#type' => 'checkbox',
+      '#default_value' => $this->options['link_to_comment'],
+    );
+    $form['link_to_node'] = array(
+      '#title' => t('Link field to the node if there is no comment.'),
+      '#type' => 'checkbox',
+      '#default_value' => $this->options['link_to_node'],
+    );
+    parent::options_form($form, $form_state);
+  }
+
+  function render_link($data, $values) {
+    if (!empty($this->options['link_to_comment'])) {
+      $this->options['alter']['make_link'] = TRUE;
+      $nid = $this->get_value($values, 'nid');
+      $cid = $this->get_value($values, 'cid');
+      if (!empty($cid)) {
+        $this->options['alter']['path'] = "comment/" . $cid;
+        $this->options['alter']['fragment'] = "comment-" . $cid;
+      }
+      // If there is no comment link to the node.
+      else if ($this->options['link_to_node']) {
+        $this->options['alter']['path'] = "node/" . $nid;
+      }
+    }
+
+    return $data;
+  }
+
+  function render($values) {
+    $value = $this->get_value($values);
+    return $this->render_link($this->sanitize_value($value), $values);
+  }
+}
diff --git a/lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_depth.inc b/lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_depth.inc
new file mode 100644
index 000000000000..4840a1e5cb51
--- /dev/null
+++ b/lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_depth.inc
@@ -0,0 +1,21 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_comment_depth.
+ */
+
+/**
+ * Field handler to display the depth of a comment.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_comment_depth extends views_handler_field {
+  /**
+   * Work out the depth of this comment
+   */
+  function render($values) {
+    $comment_thread = $this->get_value($values);
+    return count(explode('.', $comment_thread)) - 1;
+  }
+}
diff --git a/lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_link.inc b/lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_link.inc
new file mode 100644
index 000000000000..162924e166f7
--- /dev/null
+++ b/lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_link.inc
@@ -0,0 +1,69 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_comment_link.
+ */
+
+/**
+ * Base field handler to present a link.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_comment_link extends views_handler_field_entity {
+  function construct() {
+    parent::construct();
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['text'] = array('default' => '', 'translatable' => TRUE);
+    $options['link_to_node'] = array('default' => FALSE, 'bool' => TRUE);
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['text'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Text to display'),
+      '#default_value' => $this->options['text'],
+    );
+    $form['link_to_node'] = array(
+      '#title' => t('Link field to the node if there is no comment.'),
+      '#type' => 'checkbox',
+      '#default_value' => $this->options['link_to_node'],
+    );
+    parent::options_form($form, $form_state);
+  }
+
+  function query() {
+    $this->ensure_my_table();
+    $this->add_additional_fields();
+  }
+
+  function render($values) {
+    $value = $this->get_value($values, 'cid');
+    return $this->render_link($this->sanitize_value($value), $values);
+  }
+
+  function render_link($data, $values) {
+    $text = !empty($this->options['text']) ? $this->options['text'] : t('view');
+    $comment = $this->get_value($values);
+    $nid = $comment->nid;
+    $cid = $comment->cid;
+
+    $this->options['alter']['make_link'] = TRUE;
+    $this->options['alter']['html'] = TRUE;
+
+    if (!empty($cid)) {
+      $this->options['alter']['path'] = "comment/" . $cid;
+      $this->options['alter']['fragment'] = "comment-" . $cid;
+    }
+    // If there is no comment link to the node.
+    else if ($this->options['link_to_node']) {
+      $this->options['alter']['path'] = "node/" . $nid;
+    }
+
+    return $text;
+  }
+}
diff --git a/lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_link_approve.inc b/lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_link_approve.inc
new file mode 100644
index 000000000000..0953d0c8d1ff
--- /dev/null
+++ b/lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_link_approve.inc
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_comment_link_approve.
+ */
+
+/**
+ * Provides a comment approve link.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_comment_link_approve extends views_handler_field_comment_link {
+  function access() {
+    //needs permission to administer comments in general
+    return user_access('administer comments');
+  }
+
+  function render_link($data, $values) {
+    $status = $this->get_value($values, 'status');
+
+    // Don't show an approve link on published nodes.
+    if ($status == COMMENT_PUBLISHED) {
+      return;
+    }
+
+    $text = !empty($this->options['text']) ? $this->options['text'] : t('approve');
+    $cid =  $this->get_value($values, 'cid');
+
+    $this->options['alter']['make_link'] = TRUE;
+    $this->options['alter']['path'] = "comment/" . $cid . "/approve";
+    $this->options['alter']['query'] = drupal_get_destination() + array('token' => drupal_get_token("comment/$cid/approve"));
+
+    return $text;
+  }
+}
diff --git a/lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_link_delete.inc b/lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_link_delete.inc
new file mode 100644
index 000000000000..c55ac1cf4b13
--- /dev/null
+++ b/lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_link_delete.inc
@@ -0,0 +1,29 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_comment_link_delete.
+ */
+
+/**
+ * Field handler to present a link to delete a node.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_comment_link_delete extends views_handler_field_comment_link {
+  function access() {
+    //needs permission to administer comments in general
+    return user_access('administer comments');
+  }
+
+  function render_link($data, $values) {
+    $text = !empty($this->options['text']) ? $this->options['text'] : t('delete');
+    $cid =  $this->get_value($values, 'cid');
+
+    $this->options['alter']['make_link'] = TRUE;
+    $this->options['alter']['path'] = "comment/" . $cid . "/delete";
+    $this->options['alter']['query'] = drupal_get_destination();
+
+    return $text;
+  }
+}
diff --git a/lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_link_edit.inc b/lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_link_edit.inc
new file mode 100644
index 000000000000..0b06c0e9442c
--- /dev/null
+++ b/lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_link_edit.inc
@@ -0,0 +1,52 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_comment_link_edit.
+ */
+
+/**
+ * Field handler to present a link node edit.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_comment_link_edit extends views_handler_field_comment_link {
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['destination'] = array('default' => FALSE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $form['destination'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Use destination'),
+      '#description' => t('Add destination to the link'),
+      '#default_value' => $this->options['destination'],
+      '#fieldset' => 'more',
+    );
+  }
+
+  function render_link($data, $values) {
+    parent::render_link($data, $values);
+    // ensure user has access to edit this comment.
+    $comment = $this->get_value($values);
+    if (!comment_access('edit', $comment)) {
+      return;
+    }
+
+    $text = !empty($this->options['text']) ? $this->options['text'] : t('edit');
+    unset($this->options['alter']['fragment']);
+
+    if (!empty($this->options['destination'])) {
+      $this->options['alter']['query'] = drupal_get_destination();
+    }
+
+    $this->options['alter']['path'] = "comment/" . $comment->cid . "/edit";
+
+    return $text;
+  }
+}
diff --git a/lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_link_reply.inc b/lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_link_reply.inc
new file mode 100644
index 000000000000..47d0f17036e9
--- /dev/null
+++ b/lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_link_reply.inc
@@ -0,0 +1,29 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_comment_link_reply.
+ */
+
+/**
+ * Field handler to present a link to delete a node.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_comment_link_reply extends views_handler_field_comment_link {
+  function access() {
+    //check for permission to reply to comments
+    return user_access('post comments');
+  }
+
+  function render_link($data, $values) {
+    $text = !empty($this->options['text']) ? $this->options['text'] : t('reply');
+    $nid =  $this->get_value($values, 'nid');
+    $cid =  $this->get_value($values, 'cid');
+
+    $this->options['alter']['make_link'] = TRUE;
+    $this->options['alter']['path'] = "comment/reply/" . $nid . '/' . $cid;
+
+    return $text;
+  }
+}
diff --git a/lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_node_link.inc b/lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_node_link.inc
new file mode 100644
index 000000000000..7feecfba9c09
--- /dev/null
+++ b/lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_node_link.inc
@@ -0,0 +1,64 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_comment_node_link.
+ */
+
+/**
+ * Handler for showing comment module's node link.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_comment_node_link extends views_handler_field_entity {
+  function construct() {
+    parent::construct();
+
+    // Add the node fields that comment_link will need..
+    $this->additional_fields['nid'] = array(
+      'field' => 'nid',
+    );
+    $this->additional_fields['type'] = array(
+      'field' => 'type',
+    );
+    $this->additional_fields['comment'] = array(
+      'field' => 'comment',
+    );
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['teaser'] = array('default' => FALSE, 'bool' => TRUE);
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['teaser'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Show teaser-style link'),
+      '#default_value' => $this->options['teaser'],
+      '#description' => t('Show the comment link in the form used on standard node teasers, rather than the full node form.'),
+    );
+
+    parent::options_form($form, $form_state);
+  }
+
+  function query() {
+    $this->ensure_my_table();
+    $this->add_additional_fields();
+  }
+
+  function render($values) {
+    // Build fake $node.
+    $node = $this->get_value($values);
+
+    // Call comment.module's hook_link: comment_link($type, $node = NULL, $teaser = FALSE)
+    // Call node by reference so that something is changed here
+    comment_node_view($node, $this->options['teaser'] ? 'teaser' : 'full');
+    // question: should we run these through:    drupal_alter('link', $links, $node);
+    // might this have unexpected consequences if these hooks expect items in $node that we don't have?
+
+    // Only render the links, if they are defined.
+    return !empty($node->content['links']['comment']) ? drupal_render($node->content['links']['comment']) : '';
+  }
+}
diff --git a/lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_username.inc b/lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_username.inc
new file mode 100644
index 000000000000..551b12ae2338
--- /dev/null
+++ b/lib/Drupal/comment/Plugin/views/field/views_handler_field_comment_username.inc
@@ -0,0 +1,58 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_comment_username.
+ */
+
+/**
+ * Field handler to allow linking to a user account or homepage.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_comment_username extends views_handler_field {
+  /**
+   * Override init function to add uid and homepage fields.
+   */
+  function init(&$view, &$data) {
+    parent::init($view, $data);
+    $this->additional_fields['uid'] = 'uid';
+    $this->additional_fields['homepage'] = 'homepage';
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['link_to_user'] = array('default' => TRUE, 'bool' => TRUE);
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['link_to_user'] = array(
+      '#title' => t("Link this field to its user or an author's homepage"),
+      '#type' => 'checkbox',
+      '#default_value' => $this->options['link_to_user'],
+    );
+    parent::options_form($form, $form_state);
+  }
+
+  function render_link($data, $values) {
+    if (!empty($this->options['link_to_user'])) {
+      $account = entity_create('user', array());
+      $account->uid = $this->get_value($values, 'uid');
+      $account->name = $this->get_value($values);
+      $account->homepage = $this->get_value($values, 'homepage');
+
+      return theme('username', array(
+        'account' => $account
+      ));
+    }
+    else {
+      return $data;
+    }
+  }
+
+  function render($values) {
+    $value = $this->get_value($values);
+    return $this->render_link($this->sanitize_value($value), $values);
+  }
+}
diff --git a/lib/Drupal/comment/Plugin/views/field/views_handler_field_last_comment_timestamp.inc b/lib/Drupal/comment/Plugin/views/field/views_handler_field_last_comment_timestamp.inc
new file mode 100644
index 000000000000..e7cf8bdef375
--- /dev/null
+++ b/lib/Drupal/comment/Plugin/views/field/views_handler_field_last_comment_timestamp.inc
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_last_comment_timestamp.
+ */
+
+/**
+ * Field handler to display the timestamp of a comment with the count of comments.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_last_comment_timestamp extends views_handler_field_date {
+  function construct() {
+    parent::construct();
+    $this->additional_fields['comment_count'] = 'comment_count';
+  }
+
+  function render($values) {
+    $comment_count = $this->get_value($values, 'comment_count');
+    if (empty($this->options['empty_zero']) || $comment_count) {
+      return parent::render($values);
+    }
+    else {
+      return NULL;
+    }
+  }
+}
diff --git a/lib/Drupal/comment/Plugin/views/field/views_handler_field_ncs_last_comment_name.inc b/lib/Drupal/comment/Plugin/views/field/views_handler_field_ncs_last_comment_name.inc
new file mode 100644
index 000000000000..45b7966e8554
--- /dev/null
+++ b/lib/Drupal/comment/Plugin/views/field/views_handler_field_ncs_last_comment_name.inc
@@ -0,0 +1,56 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_ncs_last_comment_name.
+ */
+
+use Drupal\views\Join;
+
+/**
+ * Field handler to present the name of the last comment poster.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_ncs_last_comment_name extends views_handler_field {
+  function query() {
+    // last_comment_name only contains data if the user is anonymous. So we
+    // have to join in a specially related user table.
+    $this->ensure_my_table();
+    // join 'users' to this table via vid
+    $join = new Join();
+    $join->construct('users', $this->table_alias, 'last_comment_uid', 'uid');
+    $join->extra = array(array('field' => 'uid', 'operator' => '!=', 'value' => '0'));
+
+    // ncs_user alias so this can work with the sort handler, below.
+//    $this->user_table = $this->query->add_relationship(NULL, $join, 'users', $this->relationship);
+    $this->user_table = $this->query->ensure_table('ncs_users', $this->relationship, $join);
+
+    $this->field_alias = $this->query->add_field(NULL, "COALESCE($this->user_table.name, $this->table_alias.$this->field)", $this->table_alias . '_' . $this->field);
+
+    $this->user_field = $this->query->add_field($this->user_table, 'name');
+    $this->uid = $this->query->add_field($this->table_alias, 'last_comment_uid');
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['link_to_user'] = array('default' => TRUE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  function render($values) {
+    if (!empty($this->options['link_to_user'])) {
+      $account = entity_create('user', array());
+      $account->name = $this->get_value($values);
+      $account->uid = $values->{$this->uid};
+      return theme('username', array(
+        'account' => $account
+      ));
+    }
+    else {
+      return $this->sanitize_value($this->get_value($values));
+    }
+  }
+}
diff --git a/lib/Drupal/comment/Plugin/views/field/views_handler_field_ncs_last_updated.inc b/lib/Drupal/comment/Plugin/views/field/views_handler_field_ncs_last_updated.inc
new file mode 100644
index 000000000000..d1d730605ef9
--- /dev/null
+++ b/lib/Drupal/comment/Plugin/views/field/views_handler_field_ncs_last_updated.inc
@@ -0,0 +1,18 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_ncs_last_updated.
+ */
+/**
+ * Field handler to display the newer of last comment / node updated.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_ncs_last_updated extends views_handler_field_date {
+  function query() {
+    $this->ensure_my_table();
+    $this->node_table = $this->query->ensure_table('node', $this->relationship);
+    $this->field_alias = $this->query->add_field(NULL, "GREATEST(" . $this->node_table . ".changed, " . $this->table_alias . ".last_comment_timestamp)", $this->table_alias . '_' . $this->field);
+  }
+}
diff --git a/lib/Drupal/comment/Plugin/views/field/views_handler_field_node_comment.inc b/lib/Drupal/comment/Plugin/views/field/views_handler_field_node_comment.inc
new file mode 100644
index 000000000000..09b9f7be83a2
--- /dev/null
+++ b/lib/Drupal/comment/Plugin/views/field/views_handler_field_node_comment.inc
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_node_comment.
+ */
+
+use Drupal\views\Plugins\views\field\FieldPluginBase;
+
+/**
+ * Display node comment status.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_node_comment extends FieldPluginBase {
+  function render($values) {
+    $value = $this->get_value($values);
+    switch ($value) {
+      case COMMENT_NODE_HIDDEN:
+      default:
+        return t('Hidden');
+      case COMMENT_NODE_CLOSED:
+        return t('Closed');
+      case COMMENT_NODE_OPEN:
+        return t('Open');
+    }
+  }
+}
diff --git a/lib/Drupal/comment/Plugin/views/field/views_handler_field_node_new_comments.inc b/lib/Drupal/comment/Plugin/views/field/views_handler_field_node_new_comments.inc
new file mode 100644
index 000000000000..861dca826bd1
--- /dev/null
+++ b/lib/Drupal/comment/Plugin/views/field/views_handler_field_node_new_comments.inc
@@ -0,0 +1,118 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_node_new_comments.
+ */
+
+use Drupal\views\Plugins\views\field\Numeric;
+
+/**
+ * Field handler to display the number of new comments.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_node_new_comments extends Numeric {
+  function init(&$view, &$options) {
+    parent::init($view, $options);
+
+    // translate an older setting:
+    if (!empty($options['no_empty'])) {
+      $this->options['hide_empty'] = TRUE;
+      unset($this->options['no_empty']);
+    }
+  }
+
+  function construct() {
+    parent::construct();
+    $this->additional_fields['nid'] = 'nid';
+    $this->additional_fields['type'] = 'type';
+    $this->additional_fields['comment_count'] = array('table' => 'node_comment_statistics', 'field' => 'comment_count');
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['link_to_comment'] = array('default' => TRUE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['link_to_comment'] = array(
+      '#title' => t('Link this field to new comments'),
+      '#description' => t("Enable to override this field's links."),
+      '#type' => 'checkbox',
+      '#default_value' => $this->options['link_to_comment'],
+    );
+
+    parent::options_form($form, $form_state);
+  }
+
+  function query() {
+    $this->ensure_my_table();
+    $this->add_additional_fields();
+    $this->field_alias = $this->table . '_' . $this->field;
+  }
+
+  function pre_render(&$values) {
+    global $user;
+    if (!$user->uid || empty($values)) {
+      return;
+    }
+
+    $nids = array();
+    $ids = array();
+    foreach ($values as $id => $result) {
+      $nids[] = $result->{$this->aliases['nid']};
+      $values[$id]->{$this->field_alias} = 0;
+      // Create a reference so we can find this record in the values again.
+      if (empty($ids[$result->{$this->aliases['nid']}])) {
+        $ids[$result->{$this->aliases['nid']}] = array();
+      }
+      $ids[$result->{$this->aliases['nid']}][] = $id;
+    }
+
+    if ($nids) {
+      $result = db_query("SELECT n.nid, COUNT(c.cid) as num_comments FROM {node} n INNER JOIN {comment} c ON n.nid = c.nid
+        LEFT JOIN {history} h ON h.nid = n.nid AND h.uid = :h_uid WHERE n.nid IN (:nids)
+        AND c.changed > GREATEST(COALESCE(h.timestamp, :timestamp), :timestamp) AND c.status = :status GROUP BY n.nid  ", array(
+          ':status' => COMMENT_PUBLISHED,
+          ':h_uid' => $user->uid,
+          ':nids' => $nids,
+          ':timestamp' => NODE_NEW_LIMIT,
+        ));
+
+      foreach ($result as $node) {
+        foreach ($ids[$node->nid] as $id) {
+          $values[$id]->{$this->field_alias} = $node->num_comments;
+        }
+      }
+    }
+  }
+
+  function render_link($data, $values) {
+    if (!empty($this->options['link_to_comment']) && $data !== NULL && $data !== '') {
+      $node = entity_create('node', array(
+        'nid' => $this->get_value($values, 'nid'),
+        'type' => $this->get_value($values, 'type'),
+      ));
+      $this->options['alter']['make_link'] = TRUE;
+      $this->options['alter']['path'] = 'node/' . $node->nid;
+      $this->options['alter']['query'] = comment_new_page_count($this->get_value($values, 'comment_count'), $this->get_value($values), $node);
+      $this->options['alter']['fragment'] = 'new';
+    }
+
+    return $data;
+  }
+
+  function render($values) {
+    $value = $this->get_value($values);
+    if (!empty($value)) {
+      return $this->render_link(parent::render($values), $values);
+    }
+    else {
+      $this->options['alter']['make_link'] = FALSE;
+    }
+  }
+}
diff --git a/lib/Drupal/comment/Plugin/views/filter/views_handler_filter_comment_user_uid.inc b/lib/Drupal/comment/Plugin/views/filter/views_handler_filter_comment_user_uid.inc
new file mode 100644
index 000000000000..e76ebb79c55f
--- /dev/null
+++ b/lib/Drupal/comment/Plugin/views/filter/views_handler_filter_comment_user_uid.inc
@@ -0,0 +1,29 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_filter_comment_user_uid.
+ */
+
+/**
+ * Filter handler to accept a user id to check for nodes that user posted or
+ * commented on.
+ *
+ * @ingroup views_filter_handlers
+ */
+class views_handler_filter_comment_user_uid extends views_handler_filter_user_name {
+  function query() {
+    $this->ensure_my_table();
+
+    $subselect = db_select('comment', 'c');
+    $subselect->addField('c', 'cid');
+    $subselect->condition('c.uid', $this->value, $this->operator);
+    $subselect->where("c.nid = $this->table_alias.nid");
+
+    $condition = db_or()
+      ->condition("$this->table_alias.uid", $this->value, $this->operator)
+      ->exists($subselect);
+
+    $this->query->add_where($this->options['group'], $condition);
+  }
+}
diff --git a/lib/Drupal/comment/Plugin/views/filter/views_handler_filter_ncs_last_updated.inc b/lib/Drupal/comment/Plugin/views/filter/views_handler_filter_ncs_last_updated.inc
new file mode 100644
index 000000000000..45f48758f161
--- /dev/null
+++ b/lib/Drupal/comment/Plugin/views/filter/views_handler_filter_ncs_last_updated.inc
@@ -0,0 +1,27 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_filter_ncs_last_updated.
+ */
+
+use Drupal\views\Plugins\views\filter\Date;
+
+/**
+ * Filter handler for the newer of last comment / node updated.
+ *
+ * @ingroup views_filter_handlers
+ */
+class views_handler_filter_ncs_last_updated extends Date {
+  function query() {
+    $this->ensure_my_table();
+    $this->node_table = $this->query->ensure_table('node', $this->relationship);
+
+    $field = "GREATEST(" . $this->node_table . ".changed, " . $this->table_alias . ".last_comment_timestamp)";
+
+    $info = $this->operators();
+    if (!empty($info[$this->operator]['method'])) {
+      $this->{$info[$this->operator]['method']}($field);
+    }
+  }
+}
diff --git a/lib/Drupal/comment/Plugin/views/filter/views_handler_filter_node_comment.inc b/lib/Drupal/comment/Plugin/views/filter/views_handler_filter_node_comment.inc
new file mode 100644
index 000000000000..d5a9ca3ae3eb
--- /dev/null
+++ b/lib/Drupal/comment/Plugin/views/filter/views_handler_filter_node_comment.inc
@@ -0,0 +1,23 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_filter_node_comment.
+ */
+
+use Drupal\views\Plugins\views\filter\InOperator;
+
+/**
+ * Filter based on comment node status.
+ *
+ * @ingroup views_filter_handlers
+ */
+class views_handler_filter_node_comment extends InOperator {
+  function get_value_options() {
+    $this->value_options = array(
+      COMMENT_NODE_HIDDEN => t('Hidden'),
+      COMMENT_NODE_CLOSED => t('Closed'),
+      COMMENT_NODE_OPEN => t('Open'),
+    );
+  }
+}
diff --git a/lib/Drupal/comment/Plugin/views/row/views_plugin_row_comment_rss.inc b/lib/Drupal/comment/Plugin/views/row/views_plugin_row_comment_rss.inc
new file mode 100644
index 000000000000..a81988c4f4d8
--- /dev/null
+++ b/lib/Drupal/comment/Plugin/views/row/views_plugin_row_comment_rss.inc
@@ -0,0 +1,154 @@
+<?php
+
+/**
+ * @file
+ * Contains the comment RSS row style plugin.
+ */
+
+use Drupal\views\Plugins\views\row\RowPluginBase;
+
+/**
+ * Plugin which formats the comments as RSS items.
+ */
+class views_plugin_row_comment_rss extends RowPluginBase {
+   var $base_table = 'comment';
+   var $base_field = 'cid';
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['item_length'] = array('default' => 'default');
+    $options['links'] = array('default' => FALSE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $form['item_length'] = array(
+      '#type' => 'select',
+      '#title' => t('Display type'),
+      '#options' => $this->options_form_summary_options(),
+      '#default_value' => $this->options['item_length'],
+    );
+    $form['links'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Display links'),
+      '#default_value' => $this->options['links'],
+    );
+  }
+
+
+  function pre_render($result) {
+    $cids = array();
+    $nids = array();
+
+    foreach ($result as $row) {
+      $cids[] = $row->cid;
+    }
+
+    $this->comments = comment_load_multiple($cids);
+    foreach ($this->comments as &$comment) {
+      $comment->depth = count(explode('.', $comment->thread)) - 1;
+      $nids[] = $comment->nid;
+    }
+
+    $this->nodes = node_load_multiple($nids);
+  }
+
+  /**
+   * Return the main options, which are shown in the summary title
+   *
+   * @see views_plugin_row_node_rss::options_form_summary_options()
+   * @todo: Maybe provide a views_plugin_row_rss_entity and reuse this method
+   * in views_plugin_row_comment|node_rss.inc
+   */
+  function options_form_summary_options() {
+    $entity_info = entity_get_info('node');
+    $options = array();
+    if (!empty($entity_info['view modes'])) {
+      foreach ($entity_info['view modes'] as $mode => $settings) {
+        $options[$mode] = $settings['label'];
+      }
+    }
+    $options['title'] = t('Title only');
+    $options['default'] = t('Use site default RSS settings');
+    return $options;
+  }
+
+
+  function render($row) {
+    global $base_url;
+
+    $cid = $row->{$this->field_alias};
+    if (!is_numeric($cid)) {
+      return;
+    }
+
+    $item_length = $this->options['item_length'];
+    if ($item_length == 'default') {
+      $item_length = variable_get('feed_item_length', 'teaser');
+    }
+
+    // Load the specified comment and its associated node:
+    $comment = $this->comments[$cid];
+    if (empty($comment) || empty($this->nodes[$comment->nid])) {
+      return;
+    }
+
+    $item_text = '';
+
+    $uri = $comment->uri();
+    $comment->link = url($uri['path'], $uri['options'] + array('absolute' => TRUE));
+    $comment->rss_namespaces = array();
+    $comment->rss_elements = array(
+      array(
+        'key' => 'pubDate',
+        'value' => gmdate('r', $comment->created),
+      ),
+      array(
+        'key' => 'dc:creator',
+        'value' => $comment->name,
+      ),
+      array(
+        'key' => 'guid',
+        'value' => 'comment ' . $comment->cid . ' at ' . $base_url,
+        'attributes' => array('isPermaLink' => 'false'),
+      ),
+    );
+
+    // The comment gets built and modules add to or modify
+    // $comment->rss_elements and $comment->rss_namespaces.
+    $build = comment_view($comment, $this->nodes[$comment->nid], 'rss');
+    unset($build['#theme']);
+
+    if (!empty($comment->rss_namespaces)) {
+      $this->view->style_plugin->namespaces = array_merge($this->view->style_plugin->namespaces, $comment->rss_namespaces);
+    }
+
+    // Hide the links if desired.
+    if (!$this->options['links']) {
+      hide($build['links']);
+    }
+
+    if ($item_length != 'title') {
+      // We render comment contents and force links to be last.
+      $build['links']['#weight'] = 1000;
+      $item_text .= drupal_render($build);
+    }
+
+    $item = new stdClass();
+    $item->description = $item_text;
+    $item->title = $comment->subject;
+    $item->link = $comment->link;
+    $item->elements = $comment->rss_elements;
+    $item->cid = $comment->cid;
+
+    return theme($this->theme_functions(), array(
+      'view' => $this->view,
+      'options' => $this->options,
+      'row' => $item
+    ));
+  }
+}
diff --git a/lib/Drupal/comment/Plugin/views/row/views_plugin_row_comment_view.inc b/lib/Drupal/comment/Plugin/views/row/views_plugin_row_comment_view.inc
new file mode 100644
index 000000000000..c53602f05171
--- /dev/null
+++ b/lib/Drupal/comment/Plugin/views/row/views_plugin_row_comment_view.inc
@@ -0,0 +1,99 @@
+<?php
+
+/**
+ * @file
+ * Contains the node RSS row style plugin.
+ */
+
+use Drupal\views\Plugins\views\row\RowPluginBase;
+
+/**
+ * Plugin which performs a comment_view on the resulting object.
+ */
+class views_plugin_row_comment_view extends RowPluginBase {
+  var $base_field = 'cid';
+  var $base_table = 'comment';
+
+  /**
+   * Stores all comments which are preloaded.
+   */
+  var $comments = array();
+
+  /**
+   * Stores all nodes of all comments which are preloaded.
+   */
+  var $nodes = array();
+
+  function summary_title() {
+    return t('Settings');
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['links'] = array('default' => TRUE, 'bool' => TRUE);
+    $options['view_mode'] = array('default' => 'full');
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $options = $this->options_form_summary_options();
+    $form['view_mode'] = array(
+      '#type' => 'select',
+      '#options' => $options,
+      '#title' => t('View mode'),
+      '#default_value' => $this->options['view_mode'],
+     );
+
+    $form['links'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Display links'),
+      '#default_value' => $this->options['links'],
+    );
+  }
+
+
+  /**
+   * Return the main options, which are shown in the summary title.
+   */
+  function options_form_summary_options() {
+    $entity_info = entity_get_info('comment');
+    $options = array();
+    if (!empty($entity_info['view modes'])) {
+      foreach ($entity_info['view modes'] as $mode => $settings) {
+        $options[$mode] = $settings['label'];
+      }
+    }
+    if (empty($options)) {
+      $options = array(
+        'full' => t('Full content')
+      );
+    }
+
+    return $options;
+  }
+
+  function pre_render($result) {
+    $cids = array();
+
+    foreach ($result as $row) {
+      $cids[] = $row->cid;
+    }
+
+    // Load all comments.
+    $cresult = comment_load_multiple($cids);
+    $nids = array();
+    foreach ($cresult as $comment) {
+      $comment->depth = count(explode('.', $comment->thread)) - 1;
+      $this->comments[$comment->cid] = $comment;
+      $nids[] = $comment->nid;
+    }
+
+    // Load all nodes of the comments.
+    $nodes = node_load_multiple(array_unique($nids));
+    foreach ($nodes as $node) {
+      $this->nodes[$node->nid] = $node;
+    }
+  }
+}
diff --git a/lib/Drupal/comment/Plugin/views/sort/views_handler_sort_comment_thread.inc b/lib/Drupal/comment/Plugin/views/sort/views_handler_sort_comment_thread.inc
new file mode 100644
index 000000000000..ea8661b5b3dd
--- /dev/null
+++ b/lib/Drupal/comment/Plugin/views/sort/views_handler_sort_comment_thread.inc
@@ -0,0 +1,38 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_sort_comment_thread.
+ */
+
+use Drupal\views\Plugins\views\sort\SortPluginBase;
+use Drupal\Core\Annotation\Plugin;
+
+
+/**
+ * Sort handler for ordering by thread.
+ *
+ * @ingroup views_sort_handlers
+ */
+
+/**
+ * @Plugin(
+ *   plugin_id = 'comment_thread'
+ * )
+ */
+class views_handler_sort_comment_thread extends SortPluginBase {
+  function query() {
+    $this->ensure_my_table();
+
+    //Read comment_render() in comment.module for an explanation of the
+    //thinking behind this sort.
+    if ($this->options['order'] == 'DESC') {
+      $this->query->add_orderby($this->table_alias, $this->real_field, $this->options['order']);
+    }
+    else {
+      $alias = $this->table_alias . '_' . $this->real_field . 'asc';
+      //@todo is this secure?
+      $this->query->add_orderby(NULL, "SUBSTRING({$this->table_alias}.{$this->real_field}, 1, (LENGTH({$this->table_alias}.{$this->real_field}) - 1))", $this->options['order'], $alias);
+    }
+  }
+}
diff --git a/lib/Drupal/comment/Plugin/views/sort/views_handler_sort_ncs_last_comment_name.inc b/lib/Drupal/comment/Plugin/views/sort/views_handler_sort_ncs_last_comment_name.inc
new file mode 100644
index 000000000000..2ea91aa43f8a
--- /dev/null
+++ b/lib/Drupal/comment/Plugin/views/sort/views_handler_sort_ncs_last_comment_name.inc
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_sort_ncs_last_comment_name.
+ */
+
+use Drupal\views\Join;
+use Drupal\views\Plugins\views\sort\SortPluginBase;
+use Drupal\Core\Annotation\Plugin;
+
+/**
+ * Sort handler to sort by last comment name which might be in 2 different
+ * fields.
+ *
+ * @ingroup views_sort_handlers
+ */
+
+/**
+ * @Plugin(
+ *   plugin_id = "ncs_last_comment_name"
+ * )
+ */
+class views_handler_sort_ncs_last_comment_name extends SortPluginBase {
+  function query() {
+    $this->ensure_my_table();
+    $join = new Join();
+    $join->construct('users', $this->table_alias, 'last_comment_uid', 'uid');
+
+    // @todo this might be safer if we had an ensure_relationship rather than guessing
+    // the table alias. Though if we did that we'd be guessing the relationship name
+    // so that doesn't matter that much.
+//    $this->user_table = $this->query->add_relationship(NULL, $join, 'users', $this->relationship);
+    $this->user_table = $this->query->ensure_table('ncs_users', $this->relationship, $join);
+    $this->user_field = $this->query->add_field($this->user_table, 'name');
+
+    // Add the field.
+    $this->query->add_orderby(NULL, "LOWER(COALESCE($this->user_table.name, $this->table_alias.$this->field))", $this->options['order'], $this->table_alias . '_' . $this->field);
+  }
+}
diff --git a/lib/Drupal/comment/Plugin/views/sort/views_handler_sort_ncs_last_updated.inc b/lib/Drupal/comment/Plugin/views/sort/views_handler_sort_ncs_last_updated.inc
new file mode 100644
index 000000000000..a3290a5628d0
--- /dev/null
+++ b/lib/Drupal/comment/Plugin/views/sort/views_handler_sort_ncs_last_updated.inc
@@ -0,0 +1,22 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_sort_ncs_last_updated.
+ */
+
+use Drupal\views\Plugins\views\sort\Date;
+
+
+/**
+ * Sort handler for the newer of last comment / node updated.
+ *
+ * @ingroup views_sort_handlers
+ */
+class views_handler_sort_ncs_last_updated extends Date {
+  function query() {
+    $this->ensure_my_table();
+    $this->node_table = $this->query->ensure_table('node', $this->relationship);
+    $this->field_alias = $this->query->add_orderby(NULL, "GREATEST(" . $this->node_table . ".changed, " . $this->table_alias . ".last_comment_timestamp)", $this->options['order'], $this->table_alias . '_' . $this->field);
+  }
+}
diff --git a/lib/Drupal/contact/Plugin/views/field/views_handler_field_contact_link.inc b/lib/Drupal/contact/Plugin/views/field/views_handler_field_contact_link.inc
new file mode 100644
index 000000000000..9d22f01d023e
--- /dev/null
+++ b/lib/Drupal/contact/Plugin/views/field/views_handler_field_contact_link.inc
@@ -0,0 +1,57 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_contact_link.
+ */
+
+/**
+ * A field that links to the user contact page, if access is permitted.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_contact_link extends views_handler_field_user_link {
+
+  function options_form(&$form, &$form_state) {
+    $form['text']['#title'] = t('Link label');
+    $form['text']['#required'] = TRUE;
+    $form['text']['#default_value'] = empty($this->options['text']) ? t('contact') : $this->options['text'];
+    parent::options_form($form, $form_state);
+  }
+
+  // An example of field level access control.
+  // We must override the access method in the parent class, as that requires
+  // the 'access user profiles' permission, which the contact form does not.
+  function access() {
+    return user_access('access user contact forms');
+  }
+
+  function render_link($data, $values) {
+    global $user;
+    $uid = $this->get_value($values, 'uid');
+
+    if (empty($uid)) {
+      return;
+    }
+
+    $account = user_load($uid);
+    if (empty($account)) {
+      return;
+    }
+
+    // Check access when we pull up the user account so we know
+    // if the user has made the contact page available.
+    $menu_item = menu_get_item("user/$uid/contact");
+    if (!$menu_item['access'] || empty($account->data['contact'])) {
+      return;
+    }
+
+    $this->options['alter']['make_link'] = TRUE;
+    $this->options['alter']['path'] = 'user/' . $account->uid . '/contact';
+    $this->options['alter']['attributes'] = array('title' => t('Contact %user', array('%user' => $account->name)));
+
+    $text = $this->options['text'];
+
+    return $text;
+  }
+}
diff --git a/lib/Drupal/field/Plugin/views/argument/views_handler_argument_field_list.inc b/lib/Drupal/field/Plugin/views/argument/views_handler_argument_field_list.inc
new file mode 100644
index 000000000000..0acf14a5c99f
--- /dev/null
+++ b/lib/Drupal/field/Plugin/views/argument/views_handler_argument_field_list.inc
@@ -0,0 +1,64 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_argument_field_list.
+ */
+
+use Drupal\views\Plugins\views\argument\Numeric;
+
+/**
+ * Argument handler for list field to show the human readable name in the
+ * summary.
+ *
+ * @ingroup views_argument_handlers
+ */
+class views_handler_argument_field_list extends Numeric {
+  /**
+   * Stores the allowed values of this field.
+   *
+   * @var array
+   */
+  var $allowed_values = NULL;
+
+  function init(&$view, &$options) {
+    parent::init($view, $options);
+    $field = field_info_field($this->definition['field_name']);
+    $this->allowed_values = list_allowed_values($field);
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['summary']['contains']['human'] = array('default' => FALSE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $form['summary']['human'] = array(
+      '#title' => t('Display list value as human readable'),
+      '#type' => 'checkbox',
+      '#default_value' => $this->options['summary']['human'],
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[default_action]"]' => array('value' => 'summary'),
+        ),
+      ),
+    );
+  }
+
+
+  function summary_name($data) {
+    $value = $data->{$this->name_alias};
+    // If the list element has a human readable name show it,
+    if (isset($this->allowed_values[$value]) && !empty($this->options['summary']['human'])) {
+      return field_filter_xss($this->allowed_values[$value]);
+    }
+    // else fallback to the key.
+    else {
+      return check_plain($value);
+    }
+  }
+}
diff --git a/lib/Drupal/field/Plugin/views/argument/views_handler_argument_field_list_string.inc b/lib/Drupal/field/Plugin/views/argument/views_handler_argument_field_list_string.inc
new file mode 100644
index 000000000000..e35e5e413196
--- /dev/null
+++ b/lib/Drupal/field/Plugin/views/argument/views_handler_argument_field_list_string.inc
@@ -0,0 +1,66 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_argument_field_list_text.
+ */
+
+use Drupal\views\Plugins\views\argument\String;
+
+
+/**
+ * Argument handler for list field to show the human readable name in the
+ * summary.
+ *
+ * @ingroup views_argument_handlers
+ */
+class views_handler_argument_field_list_string extends String {
+  /**
+   * Stores the allowed values of this field.
+   *
+   * @var array
+   */
+  var $allowed_values = NULL;
+
+  function init(&$view, &$options) {
+    parent::init($view, $options);
+    $field = field_info_field($this->definition['field_name']);
+    $this->allowed_values = list_allowed_values($field);
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['summary']['contains']['human'] = array('default' => FALSE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $form['summary']['human'] = array(
+      '#title' => t('Display list value as human readable'),
+      '#type' => 'checkbox',
+      '#default_value' => $this->options['summary']['human'],
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[default_action]"]' => array('value' => 'summary'),
+        ),
+      ),
+    );
+  }
+
+
+  function summary_name($data) {
+    $value = $data->{$this->name_alias};
+    // If the list element has a human readable name show it,
+    if (isset($this->allowed_values[$value]) && !empty($this->options['summary']['human'])) {
+      return $this->case_transform(field_filter_xss($this->allowed_values[$value]), $this->options['case']);
+    }
+    // else fallback to the key.
+    else {
+      return $this->case_transform(check_plain($value), $this->options['case']);
+    }
+  }
+}
diff --git a/lib/Drupal/field/Plugin/views/field/views_handler_field_field.inc b/lib/Drupal/field/Plugin/views/field/views_handler_field_field.inc
new file mode 100644
index 000000000000..b8b5f82d2c76
--- /dev/null
+++ b/lib/Drupal/field/Plugin/views/field/views_handler_field_field.inc
@@ -0,0 +1,939 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_field.
+ */
+
+use Drupal\views\Plugins\views\field\FieldPluginBase;
+
+/**
+ * Helper function: Return an array of formatter options for a field type.
+ *
+ * Borrowed from field_ui.
+ */
+function _field_view_formatter_options($field_type = NULL) {
+  $options = &drupal_static(__FUNCTION__);
+
+  if (!isset($options)) {
+    $field_types = field_info_field_types();
+    $options = array();
+    foreach (field_info_formatter_types() as $name => $formatter) {
+      foreach ($formatter['field types'] as $formatter_field_type) {
+        // Check that the field type exists.
+        if (isset($field_types[$formatter_field_type])) {
+          $options[$formatter_field_type][$name] = $formatter['label'];
+        }
+      }
+    }
+  }
+
+  if ($field_type) {
+    return !empty($options[$field_type]) ? $options[$field_type] : array();
+  }
+  return $options;
+}
+
+/**
+ * A field that displays fieldapi fields.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_field extends FieldPluginBase {
+  /**
+   * An array to store field renderable arrays for use by render_items.
+   * @var array
+   */
+  public $items = array();
+
+  /**
+   * Store the field information.
+   * @var array
+   */
+  public $field_info = array();
+
+
+  /**
+   * Does the field supports multiple field values.
+   * @var bool
+   */
+  public $multiple;
+
+  /**
+   * Does the rendered fields get limited.
+   * @var bool
+   */
+  public $limit_values;
+
+  /**
+   * A shortcut for $view->base_table.
+   * @var string
+   */
+  public $base_table;
+
+  function init(&$view, &$options) {
+    parent::init($view, $options);
+
+    $this->field_info = $field = field_info_field($this->definition['field_name']);
+    $this->multiple = FALSE;
+    $this->limit_values = FALSE;
+
+    if ($field['cardinality'] > 1 || $field['cardinality'] == FIELD_CARDINALITY_UNLIMITED) {
+      $this->multiple = TRUE;
+
+      // If "Display all values in the same row" is FALSE, then we always limit
+      // in order to show a single unique value per row.
+      if (!$this->options['group_rows']) {
+        $this->limit_values = TRUE;
+      }
+
+      // If "First and last only" is chosen, limit the values
+      if (!empty($this->options['delta_first_last'])) {
+        $this->limit_values = TRUE;
+      }
+
+      // Otherwise, we only limit values if the user hasn't selected "all", 0, or
+      // the value matching field cardinality.
+      if ((intval($this->options['delta_limit']) && ($this->options['delta_limit'] != $field['cardinality'])) || intval($this->options['delta_offset'])) {
+        $this->limit_values = TRUE;
+      }
+    }
+
+    // Convert old style entity id group column to new format.
+    // @todo Remove for next major version.
+    if ($this->options['group_column'] == 'entity id') {
+      $this->options['group_column'] = 'entity_id';
+    }
+  }
+
+  /**
+   * Check whether current user has access to this handler.
+   *
+   * @return bool
+   *   Return TRUE if the user has access to view this field.
+   */
+  function access() {
+    $base_table = $this->get_base_table();
+    return field_access('view', $this->field_info, $this->definition['entity_tables'][$base_table]);
+  }
+
+  /**
+   * Set the base_table and base_table_alias.
+   *
+   * @return string
+   *   The base table which is used in the current view "context".
+   */
+  function get_base_table() {
+    if (!isset($this->base_table)) {
+      // This base_table is coming from the entity not the field.
+      $this->base_table = $this->view->base_table;
+
+      // If the current field is under a relationship you can't be sure that the
+      // base table of the view is the base table of the current field.
+      // For example a field from a node author on a node view does have users as base table.
+      if (!empty($this->options['relationship']) && $this->options['relationship'] != 'none') {
+        $relationships = $this->view->display_handler->get_option('relationships');
+        if (!empty($relationships[$this->options['relationship']])) {
+          $options = $relationships[$this->options['relationship']];
+          $data = views_fetch_data($options['table']);
+          $this->base_table = $data[$options['field']]['relationship']['base'];
+        }
+      }
+    }
+
+    return $this->base_table;
+  }
+
+  /**
+   * Called to add the field to a query.
+   *
+   * By default, the only columns added to the query are entity_id and
+   * entity_type. This is because other needed data is fetched by entity_load().
+   * Other columns are added only if they are used in groupings, or if
+   * 'add fields to query' is specifically set to TRUE in the field definition.
+   *
+   * The 'add fields to query' switch is used by modules which need all data
+   * present in the query itself (such as "sphinx").
+   */
+  function query($use_groupby = FALSE) {
+    $this->get_base_table();
+
+    $params = array();
+    if ($use_groupby) {
+      // When grouping on a "field API" field (whose "real_field" is set to
+      // entity_id), retrieve the minimum entity_id to have a valid entity_id to
+      // pass to field_view_field().
+      $params = array(
+        'function' => 'min',
+      );
+
+      $this->ensure_my_table();
+    }
+
+    // Get the entity type according to the base table of the field.
+    // Then add it to the query as a formula. That way we can avoid joining
+    // the field table if all we need is entity_id and entity_type.
+    $entity_type = $this->definition['entity_tables'][$this->base_table];
+    $entity_info = entity_get_info($entity_type);
+
+    if (isset($this->relationship)) {
+      $this->base_table_alias = $this->relationship;
+    }
+    else {
+      $this->base_table_alias = $this->base_table;
+    }
+
+    // We always need the base field (entity_id / revision_id).
+    if (empty($this->definition['is revision'])) {
+      $this->field_alias = $this->query->add_field($this->base_table_alias, $entity_info['entity keys']['id'], '', $params);
+    }
+    else {
+      $this->field_alias = $this->query->add_field($this->base_table_alias, $entity_info['entity keys']['revision'], '', $params);
+      $this->aliases['entity_id'] = $this->query->add_field($this->base_table_alias, $entity_info['entity keys']['id'], '', $params);
+    }
+
+
+    // The alias needs to be unique, so we use both the field table and the entity type.
+    $entity_type_alias = $this->definition['table'] . '_' . $entity_type . '_entity_type';
+    $this->aliases['entity_type'] = $this->query->add_field(NULL, "'$entity_type'", $entity_type_alias);
+
+    $fields = $this->additional_fields;
+    // We've already added entity_type, so we can remove it from the list.
+    $entity_type_key = array_search('entity_type', $fields);
+    if ($entity_type_key !== FALSE) {
+      unset($fields[$entity_type_key]);
+    }
+
+    if ($use_groupby) {
+      // Add the fields that we're actually grouping on.
+      $options = array();
+
+      if ($this->options['group_column'] != 'entity_id') {
+        $options = array($this->options['group_column'] => $this->options['group_column']);
+      }
+
+      $options += is_array($this->options['group_columns']) ? $this->options['group_columns'] : array();
+
+
+      $fields = array();
+      $rkey = $this->definition['is revision'] ? 'FIELD_LOAD_REVISION' : 'FIELD_LOAD_CURRENT';
+      // Go through the list and determine the actual column name from field api.
+      foreach ($options as $column) {
+        $name = $column;
+        if (isset($this->field_info['storage']['details']['sql'][$rkey][$this->table][$column])) {
+          $name = $this->field_info['storage']['details']['sql'][$rkey][$this->table][$column];
+        }
+
+        $fields[$column] = $name;
+      }
+
+      $this->group_fields = $fields;
+    }
+
+    // Add additional fields (and the table join itself) if needed.
+    if ($this->add_field_table($use_groupby)) {
+      $this->ensure_my_table();
+      $this->add_additional_fields($fields);
+
+      // Filter by language, if field translation is enabled.
+      $field = $this->field_info;
+      if (field_is_translatable($entity_type, $field) && !empty($this->view->display_handler->options['field_language_add_to_query'])) {
+        $column = $this->table_alias . '.language';
+        // By the same reason as field_language the field might be LANGUAGE_NOT_SPECIFIED in reality so allow it as well.
+        // @see this::field_language()
+        $default_language = language_default()->langcode;
+        $language = str_replace(array('***CURRENT_LANGUAGE***', '***DEFAULT_LANGUAGE***'),
+                                array(drupal_container()->get(LANGUAGE_TYPE_CONTENT)->langcode, $default_language),
+                                $this->view->display_handler->options['field_language']);
+        $placeholder = $this->placeholder();
+        $language_fallback_candidates = array($language);
+        if (variable_get('locale_field_language_fallback', TRUE)) {
+          require_once DRUPAL_ROOT . '/includes/language.inc';
+          $language_fallback_candidates = array_merge($language_fallback_candidates, language_fallback_get_candidates());
+        }
+        else {
+          $language_fallback_candidates[] = LANGUAGE_NOT_SPECIFIED;
+        }
+        $this->query->add_where_expression(0, "$column IN($placeholder) OR $column IS NULL", array($placeholder => $language_fallback_candidates));
+      }
+    }
+
+    // The revision id inhibits grouping.
+    // So, stop here if we're using grouping, or if aren't adding all columns to
+    // the query.
+    if ($use_groupby || empty($this->definition['add fields to query'])) {
+      return;
+    }
+
+    $this->add_additional_fields(array('revision_id'));
+  }
+
+  /**
+   * Determine if the field table should be added to the query.
+   */
+  function add_field_table($use_groupby) {
+    // Grouping is enabled, or we are explicitly required to do this.
+    if ($use_groupby || !empty($this->definition['add fields to query'])) {
+      return TRUE;
+    }
+    // This a multiple value field, but "group multiple values" is not checked.
+    if ($this->multiple && !$this->options['group_rows']) {
+      return TRUE;
+    }
+    return FALSE;
+  }
+
+  /**
+   * Determine if this field is click sortable.
+   */
+  function click_sortable() {
+    // Not click sortable in any case.
+    if (empty($this->definition['click sortable'])) {
+      return FALSE;
+    }
+    // A field is not click sortable if it's a multiple field with
+    // "group multiple values" checked, since a click sort in that case would
+    // add a join to the field table, which would produce unwanted duplicates.
+    if ($this->multiple && $this->options['group_rows']) {
+      return FALSE;
+    }
+    return TRUE;
+  }
+
+  /**
+   * Called to determine what to tell the clicksorter.
+   */
+  function click_sort($order) {
+    // No column selected, can't continue.
+    if (empty($this->options['click_sort_column'])) {
+      return;
+    }
+
+    $this->ensure_my_table();
+    $column = _field_sql_storage_columnname($this->definition['field_name'], $this->options['click_sort_column']);
+    if (!isset($this->aliases[$column])) {
+      // Column is not in query; add a sort on it (without adding the column).
+      $this->aliases[$column] = $this->table_alias . '.' . $column;
+    }
+    $this->query->add_orderby(NULL, NULL, $order, $this->aliases[$column]);
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    // option_definition runs before init/construct, so no $this->field_info
+    $field = field_info_field($this->definition['field_name']);
+    $field_type = field_info_field_types($field['type']);
+    $column_names = array_keys($field['columns']);
+    $default_column = '';
+    // Try to determine a sensible default.
+    if (count($column_names) == 1) {
+      $default_column = $column_names[0];
+    }
+    elseif (in_array('value', $column_names)) {
+      $default_column = 'value';
+    }
+
+    // If the field has a "value" column, we probably need that one.
+    $options['click_sort_column'] = array(
+      'default' => $default_column,
+    );
+    $options['type'] = array(
+      'default' => $field_type['default_formatter'],
+    );
+    $options['settings'] = array(
+      'default' => array(),
+    );
+    $options['group_column'] = array(
+      'default' => $default_column,
+    );
+    $options['group_columns'] = array(
+      'default' => array(),
+    );
+
+    // Options used for multiple value fields.
+    $options['group_rows'] = array(
+      'default' => TRUE,
+      'bool' => TRUE,
+    );
+    // If we know the exact number of allowed values, then that can be
+    // the default. Otherwise, default to 'all'.
+    $options['delta_limit'] = array(
+      'default' => ($field['cardinality'] > 1) ? $field['cardinality'] : 'all',
+    );
+    $options['delta_offset'] = array(
+      'default' => 0,
+    );
+    $options['delta_reversed'] = array(
+      'default' => FALSE,
+      'bool' => TRUE,
+    );
+    $options['delta_first_last'] = array(
+      'default' => FALSE,
+      'bool' => TRUE,
+    );
+
+    $options['multi_type'] = array(
+      'default' => 'separator'
+    );
+    $options['separator'] = array(
+      'default' => ', '
+    );
+
+    $options['field_api_classes'] = array(
+      'default' => FALSE,
+      'bool' => TRUE,
+    );
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $field = $this->field_info;
+    $formatters = _field_view_formatter_options($field['type']);
+    $column_names = array_keys($field['columns']);
+
+    // If this is a multiple value field, add its options.
+    if ($this->multiple) {
+      $this->multiple_options_form($form, $form_state);
+    }
+
+    // No need to ask the user anything if the field has only one column.
+    if (count($field['columns']) == 1) {
+      $form['click_sort_column'] = array(
+        '#type' => 'value',
+        '#value' => isset($column_names[0]) ? $column_names[0] : '',
+      );
+    }
+    else {
+      $form['click_sort_column'] = array(
+        '#type' => 'select',
+        '#title' => t('Column used for click sorting'),
+        '#options' => drupal_map_assoc($column_names),
+        '#default_value' => $this->options['click_sort_column'],
+        '#description' => t('Used by Style: Table to determine the actual column to click sort the field on. The default is usually fine.'),
+        '#fieldset' => 'more',
+      );
+    }
+
+    $form['type'] = array(
+      '#type' => 'select',
+      '#title' => t('Formatter'),
+      '#options' => $formatters,
+      '#default_value' => $this->options['type'],
+      '#ajax' => array(
+        'path' => views_ui_build_form_url($form_state),
+      ),
+      '#submit' => array('views_ui_config_item_form_submit_temporary'),
+      '#executes_submit_callback' => TRUE,
+    );
+
+    $form['field_api_classes'] = array(
+      '#title' => t('Use field template'),
+      '#type' => 'checkbox',
+      '#default_value' => $this->options['field_api_classes'],
+      '#description' => t('If checked, field api classes will be added using field.tpl.php (or equivalent). This is not recommended unless your CSS depends upon these classes. If not checked, template will not be used.'),
+      '#fieldset' => 'style_settings',
+      '#weight' => 20,
+    );
+
+    if ($this->multiple) {
+      $form['field_api_classes']['#description'] .= ' ' . t('Checking this option will cause the group Display Type and Separator values to be ignored.');
+    }
+
+    // Get the currently selected formatter.
+    $format = $this->options['type'];
+
+    $formatter = field_info_formatter_types($format);
+    $settings = $this->options['settings'] + field_info_formatter_settings($format);
+
+    // Provide an instance array for hook_field_formatter_settings_form().
+    ctools_include('fields');
+    $instance = ctools_fields_fake_field_instance($this->definition['field_name'], '_dummy', $formatter, $settings);
+
+    // Store the settings in a '_dummy' view mode.
+    $instance['display']['_dummy'] = array(
+      'type' => $format,
+      'settings' => $settings,
+    );
+
+    // Get the settings form.
+    $settings_form = array('#value' => array());
+    $function = $formatter['module'] . '_field_formatter_settings_form';
+    if (function_exists($function)) {
+      $settings_form = $function($field, $instance, '_dummy', $form, $form_state);
+    }
+    $form['settings'] = $settings_form;
+  }
+
+  /**
+   * Provide options for multiple value fields.
+   */
+  function multiple_options_form(&$form, &$form_state) {
+    $field = $this->field_info;
+
+    $form['multiple_field_settings'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Multiple field settings'),
+      '#collapsible' => TRUE,
+      '#collapsed' => TRUE,
+      '#weight' => 5,
+    );
+
+    $form['group_rows'] = array(
+      '#title' => t('Display all values in the same row'),
+      '#type' => 'checkbox',
+      '#default_value' => $this->options['group_rows'],
+      '#description' => t('If checked, multiple values for this field will be shown in the same row. If not checked, each value in this field will create a new row. If using group by, please make sure to group by "Entity ID" for this setting to have any effect.'),
+      '#fieldset' => 'multiple_field_settings',
+    );
+
+    // Make the string translatable by keeping it as a whole rather than
+    // translating prefix and suffix separately.
+    list($prefix, $suffix) = explode('@count', t('Display @count value(s)'));
+
+    if ($field['cardinality'] == FIELD_CARDINALITY_UNLIMITED) {
+      $type = 'textfield';
+      $options = NULL;
+      $size = 5;
+    }
+    else {
+      $type = 'select';
+      $options = drupal_map_assoc(range(1, $field['cardinality']));
+      $size = 1;
+    }
+    $form['multi_type'] = array(
+      '#type' => 'radios',
+      '#title' => t('Display type'),
+      '#options' => array(
+        'ul' => t('Unordered list'),
+        'ol' => t('Ordered list'),
+        'separator' => t('Simple separator'),
+      ),
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[group_rows]"]' => array('checked' => TRUE),
+        ),
+      ),
+      '#default_value' => $this->options['multi_type'],
+      '#fieldset' => 'multiple_field_settings',
+    );
+
+    $form['separator'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Separator'),
+      '#default_value' => $this->options['separator'],
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[group_rows]"]' => array('checked' => TRUE),
+          ':input[name="options[multi_type]"]' => array('value' => 'separator'),
+        ),
+      ),
+      '#fieldset' => 'multiple_field_settings',
+    );
+
+    $form['delta_limit'] = array(
+      '#type' => $type,
+      '#size' => $size,
+      '#field_prefix' => $prefix,
+      '#field_suffix' => $suffix,
+      '#options' => $options,
+      '#default_value' => $this->options['delta_limit'],
+      '#prefix' => '<div class="container-inline">',
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[group_rows]"]' => array('checked' => TRUE),
+        ),
+      ),
+      '#fieldset' => 'multiple_field_settings',
+    );
+
+    list($prefix, $suffix) = explode('@count', t('starting from @count'));
+    $form['delta_offset'] = array(
+      '#type' => 'textfield',
+      '#size' => 5,
+      '#field_prefix' => $prefix,
+      '#field_suffix' => $suffix,
+      '#default_value' => $this->options['delta_offset'],
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[group_rows]"]' => array('checked' => TRUE),
+        ),
+      ),
+      '#description' => t('(first item is 0)'),
+      '#fieldset' => 'multiple_field_settings',
+    );
+    $form['delta_reversed'] = array(
+      '#title' => t('Reversed'),
+      '#type' => 'checkbox',
+      '#default_value' => $this->options['delta_reversed'],
+      '#suffix' => $suffix,
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[group_rows]"]' => array('checked' => TRUE),
+        ),
+      ),
+      '#description' => t('(start from last values)'),
+      '#fieldset' => 'multiple_field_settings',
+    );
+    $form['delta_first_last'] = array(
+      '#title' => t('First and last only'),
+      '#type' => 'checkbox',
+      '#default_value' => $this->options['delta_first_last'],
+      '#suffix' => '</div>',
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[group_rows]"]' => array('checked' => TRUE),
+        ),
+      ),
+      '#fieldset' => 'multiple_field_settings',
+    );
+  }
+
+  /**
+   * Extend the groupby form with group columns.
+   */
+  function groupby_form(&$form, &$form_state) {
+    parent::groupby_form($form, $form_state);
+    // With "field API" fields, the column target of the grouping function
+    // and any additional grouping columns must be specified.
+    $group_columns = array(
+      'entity_id' => t('Entity ID'),
+    ) + drupal_map_assoc(array_keys($this->field_info['columns']), 'ucfirst');
+
+    $form['group_column'] = array(
+      '#type' => 'select',
+      '#title' => t('Group column'),
+      '#default_value' => $this->options['group_column'],
+      '#description' => t('Select the column of this field to apply the grouping function selected above.'),
+      '#options' => $group_columns,
+    );
+
+    $options = drupal_map_assoc(array('bundle', 'language', 'entity_type'), 'ucfirst');
+
+    // Add on defined fields, noting that they're prefixed with the field name.
+    $form['group_columns'] = array(
+      '#type' => 'checkboxes',
+      '#title' => t('Group columns (additional)'),
+      '#default_value' => $this->options['group_columns'],
+      '#description' => t('Select any additional columns of this field to include in the query and to group on.'),
+      '#options' => $options + $group_columns,
+    );
+  }
+
+  function groupby_form_submit(&$form, &$form_state) {
+    parent::groupby_form_submit($form, $form_state);
+    $item =& $form_state['handler']->options;
+
+    // Add settings for "field API" fields.
+    $item['group_column'] = $form_state['values']['options']['group_column'];
+    $item['group_columns'] = array_filter($form_state['values']['options']['group_columns']);
+  }
+
+  /**
+   * Load the entities for all fields that are about to be displayed.
+   */
+  function post_execute(&$values) {
+    if (!empty($values)) {
+      // Divide the entity ids by entity type, so they can be loaded in bulk.
+      $entities_by_type = array();
+      $revisions_by_type = array();
+      foreach ($values as $key => $object) {
+        if (isset($this->aliases['entity_type']) && isset($object->{$this->aliases['entity_type']}) && isset($object->{$this->field_alias}) && !isset($values[$key]->_field_data[$this->field_alias])) {
+          $entity_type = $object->{$this->aliases['entity_type']};
+          if (empty($this->definition['is revision'])) {
+            $entity_id = $object->{$this->field_alias};
+            $entities_by_type[$entity_type][$key] = $entity_id;
+          }
+          else {
+            $revision_id = $object->{$this->field_alias};
+            $entity_id = $object->{$this->aliases['entity_id']};
+            $entities_by_type[$entity_type][$key] = array($entity_id, $revision_id);
+          }
+        }
+      }
+
+      // Load the entities.
+      foreach ($entities_by_type as $entity_type => $entity_ids) {
+        $entity_info = entity_get_info($entity_type);
+        if (empty($this->definition['is revision'])) {
+          $entities = entity_load_multiple($entity_type, $entity_ids);
+          $keys = $entity_ids;
+        }
+        else {
+          // Revisions can't be loaded multiple, so we have to load them
+          // one by one.
+          $entities = array();
+          $keys = array();
+          foreach ($entity_ids as $key => $combined) {
+            list($entity_id, $revision_id) = $combined;
+            $entity = entity_load_multiple($entity_type, array($entity_id), array($entity_info['entity keys']['revision'] => $revision_id));
+            if ($entity) {
+              $entities[$revision_id] = array_shift($entity);
+              $keys[$key] = $revision_id;
+            }
+          }
+        }
+
+        foreach ($keys as $key => $entity_id) {
+          // If this is a revision, load the revision instead.
+          if (isset($entities[$entity_id])) {
+            $values[$key]->_field_data[$this->field_alias] = array(
+              'entity_type' => $entity_type,
+              'entity' => $entities[$entity_id],
+            );
+          }
+        }
+      }
+
+      // Now, transfer the data back into the resultset so it can be easily used.
+      foreach ($values as $row_id => &$value) {
+        $value->{'field_' . $this->options['id']} = $this->set_items($value, $row_id);
+      }
+    }
+  }
+
+  /**
+   * Render all items in this field together.
+   *
+   * When using advanced render, each possible item in the list is rendered
+   * individually. Then the items are all pasted together.
+   */
+  function render_items($items) {
+    if (!empty($items)) {
+      if (!$this->options['group_rows']) {
+        return implode('', $items);
+      }
+
+      if ($this->options['multi_type'] == 'separator') {
+        return implode(filter_xss_admin($this->options['separator']), $items);
+      }
+      else {
+        return theme('item_list',
+          array(
+            'items' => $items,
+            'title' => NULL,
+            'type' => $this->options['multi_type']
+          ));
+      }
+    }
+  }
+
+  function get_items($values) {
+    return $values->{'field_' . $this->options['id']};
+  }
+
+  function get_value($values, $field = NULL) {
+    // Go ahead and render and store in $this->items.
+    $entity = clone $values->_field_data[$this->field_alias]['entity'];
+
+    $entity_type = $values->_field_data[$this->field_alias]['entity_type'];
+    $langcode = $this->field_language($entity_type, $entity);
+    // If we are grouping, copy our group fields into the cloned entity.
+    // It's possible this will cause some weirdness, but there's only
+    // so much we can hope to do.
+    if (!empty($this->group_fields)) {
+      // first, test to see if we have a base value.
+      $base_value = array();
+      // Note: We would copy original values here, but it can cause problems.
+      // For example, text fields store cached filtered values as
+      // 'safe_value' which doesn't appear anywhere in the field definition
+      // so we can't affect it. Other side effects could happen similarly.
+      $data = FALSE;
+      foreach ($this->group_fields as $field_name => $column) {
+        if (property_exists($values, $this->aliases[$column])) {
+          $base_value[$field_name] = $values->{$this->aliases[$column]};
+          if (isset($base_value[$field_name])) {
+            $data = TRUE;
+          }
+        }
+      }
+
+      // If any of our aggregated fields have data, fake it:
+      if ($data) {
+        // Now, overwrite the original value with our aggregated value.
+        // This overwrites it so there is always just one entry.
+        $entity->{$this->definition['field_name']}[$langcode] = array($base_value);
+      }
+      else {
+        $entity->{$this->definition['field_name']}[$langcode] = array();
+      }
+    }
+
+    // The field we are trying to display doesn't exist on this entity.
+    if (!isset($entity->{$this->definition['field_name']})) {
+      return array();
+    }
+
+    // We are supposed to show only certain deltas.
+    if ($this->limit_values && !empty($entity->{$this->definition['field_name']})) {
+      $all_values = !empty($entity->{$this->definition['field_name']}[$langcode]) ? $entity->{$this->definition['field_name']}[$langcode] : array();
+      if ($this->options['delta_reversed']) {
+        $all_values = array_reverse($all_values);
+      }
+
+      // Offset is calculated differently when row grouping for a field is
+      // not enabled. Since there are multiple rows, the delta needs to be
+      // taken into account, so that different values are shown per row.
+      if (!$this->options['group_rows'] && isset($this->aliases['delta']) && isset($values->{$this->aliases['delta']})) {
+        $delta_limit = 1;
+        $offset = $values->{$this->aliases['delta']};
+      }
+      // Single fields don't have a delta available so choose 0.
+      elseif (!$this->options['group_rows'] && !$this->multiple) {
+        $delta_limit = 1;
+        $offset = 0;
+      }
+      else {
+        $delta_limit = $this->options['delta_limit'];
+        $offset = intval($this->options['delta_offset']);
+
+        // We should only get here in this case if there's an offset, and
+        // in that case we're limiting to all values after the offset.
+        if ($delta_limit == 'all') {
+          $delta_limit = count($all_values) - $offset;
+        }
+      }
+
+      // Determine if only the first and last values should be shown
+      $delta_first_last = $this->options['delta_first_last'];
+
+      $new_values = array();
+      for ($i = 0; $i < $delta_limit; $i++) {
+        $new_delta = $offset + $i;
+
+        if (isset($all_values[$new_delta])) {
+          // If first-last option was selected, only use the first and last values
+          if (!$delta_first_last
+            // Use the first value.
+            || $new_delta == $offset
+            // Use the last value.
+            || $new_delta == ($delta_limit + $offset - 1)) {
+            $new_values[] = $all_values[$new_delta];
+          }
+        }
+      }
+      $entity->{$this->definition['field_name']}[$langcode] = $new_values;
+    }
+
+    if ($field == 'entity') {
+      return $entity;
+    }
+    else {
+      return !empty($entity->{$this->definition['field_name']}[$langcode]) ? $entity->{$this->definition['field_name']}[$langcode] : array();
+    }
+  }
+
+  /**
+   * Return an array of items for the field.
+   */
+  function set_items($values, $row_id) {
+    if (empty($values->_field_data[$this->field_alias]) || empty($values->_field_data[$this->field_alias]['entity'])) {
+      return array();
+    }
+
+    $display = array(
+      'type' => $this->options['type'],
+      'settings' => $this->options['settings'],
+      'label' => 'hidden',
+      // Pass the View object in the display so that fields can act on it.
+      'views_view' => $this->view,
+      'views_field' => $this,
+      'views_row_id' => $row_id,
+    );
+
+
+    $entity_type = $values->_field_data[$this->field_alias]['entity_type'];
+    $entity = $this->get_value($values, 'entity');
+    if (!$entity) {
+      return array();
+    }
+
+    $langcode = $this->field_language($entity_type, $entity);
+    $render_array = field_view_field($entity_type, $entity, $this->definition['field_name'], $display, $langcode);
+
+    $items = array();
+    if ($this->options['field_api_classes']) {
+      // Make a copy.
+      $array = $render_array;
+      return array(array('rendered' => drupal_render($render_array)));
+    }
+
+    foreach (element_children($render_array) as $count) {
+      $items[$count]['rendered'] = $render_array[$count];
+      // field_view_field() adds an #access property to the render array that
+      // determines whether or not the current user is allowed to view the
+      // field in the context of the current entity. We need to respect this
+      // parameter when we pull out the children of the field array for
+      // rendering.
+      if (isset($render_array['#access'])) {
+        $items[$count]['rendered']['#access'] = $render_array['#access'];
+      }
+      // Only add the raw field items (for use in tokens) if the current user
+      // has access to view the field content.
+      if ((!isset($items[$count]['rendered']['#access']) || $items[$count]['rendered']['#access']) && !empty($render_array['#items'][$count])) {
+        $items[$count]['raw'] = $render_array['#items'][$count];
+      }
+    }
+    return $items;
+  }
+
+  function render_item($count, $item) {
+    return render($item['rendered']);
+  }
+
+  function document_self_tokens(&$tokens) {
+    $field = $this->field_info;
+    foreach ($field['columns'] as $id => $column) {
+      $tokens['[' . $this->options['id'] . '-' . $id . ']'] = t('Raw @column', array('@column' => $id));
+    }
+  }
+
+  function add_self_tokens(&$tokens, $item) {
+    $field = $this->field_info;
+    foreach ($field['columns'] as $id => $column) {
+      // Use filter_xss_admin because it's user data and we can't be sure it is safe.
+      // We know nothing about the data, though, so we can't really do much else.
+
+      if (isset($item['raw'])) {
+        // If $item['raw'] is an array then we can use as is, if it's an object
+        // we cast it to an array, if it's neither, we can't use it.
+        $raw = is_array($item['raw']) ? $item['raw'] :
+               (is_object($item['raw']) ? (array)$item['raw'] : NULL);
+      }
+      if (isset($raw) && isset($raw[$id]) && is_scalar($raw[$id])) {
+        $tokens['[' . $this->options['id'] . '-' . $id . ']'] = filter_xss_admin($raw[$id]);
+      }
+      else {
+        // Take sure that empty values are replaced as well.
+        $tokens['[' . $this->options['id'] . '-' . $id . ']'] = '';
+      }
+    }
+  }
+
+  /**
+   * Return the language code of the language the field should be displayed in,
+   * according to the settings.
+   */
+  function field_language($entity_type, $entity) {
+    if (field_is_translatable($entity_type, $this->field_info)) {
+      $default_language = language_default()->langcode;
+      $language = str_replace(array('***CURRENT_LANGUAGE***', '***DEFAULT_LANGUAGE***'),
+                              array(drupal_container()->get(LANGUAGE_TYPE_CONTENT)->langcode, $default_language),
+                              $this->view->display_handler->options['field_language']);
+
+      // Give the Field Language API a chance to fallback to a different language
+      // (or LANGUAGE_NOT_SPECIFIED), in case the field has no data for the selected language.
+      // field_view_field() does this as well, but since the returned language code
+      // is used before calling it, the fallback needs to happen explicitly.
+      $language = field_language($entity_type, $entity, $this->field_info['field_name'], $language);
+
+      return $language;
+    }
+    else {
+      return LANGUAGE_NOT_SPECIFIED;
+    }
+  }
+}
diff --git a/lib/Drupal/field/Plugin/views/filter/views_handler_filter_field_list.inc b/lib/Drupal/field/Plugin/views/filter/views_handler_filter_field_list.inc
new file mode 100644
index 000000000000..bc0130d99af4
--- /dev/null
+++ b/lib/Drupal/field/Plugin/views/filter/views_handler_filter_field_list.inc
@@ -0,0 +1,20 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_filter_field_list.
+ */
+
+use Drupal\views\Plugins\views\filter\InOperator;
+
+/**
+ * Filter handler which uses list-fields as options.
+ *
+ * @ingroup views_filter_handlers
+ */
+class views_handler_filter_field_list extends InOperator {
+  function get_value_options() {
+    $field = field_info_field($this->definition['field_name']);
+    $this->value_options = list_allowed_values($field);
+  }
+}
diff --git a/lib/Drupal/field/Plugin/views/relationship/views_handler_relationship_entity_reverse.inc b/lib/Drupal/field/Plugin/views/relationship/views_handler_relationship_entity_reverse.inc
new file mode 100644
index 000000000000..90c3e02e9334
--- /dev/null
+++ b/lib/Drupal/field/Plugin/views/relationship/views_handler_relationship_entity_reverse.inc
@@ -0,0 +1,87 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_relationship_entity_reverse.
+ */
+
+use Drupal\views\Join;
+use Drupal\views\Plugins\views\relationship\RelationshipPluginBase;
+
+/**
+ * A relationship handlers which reverse entity references.
+ *
+ * @ingroup views_relationship_handlers
+ */
+class views_handler_relationship_entity_reverse extends RelationshipPluginBase  {
+  function init(&$view, &$options) {
+    parent::init($view, $options);
+
+    $this->field_info = field_info_field($this->definition['field_name']);
+  }
+
+  /**
+   * Called to implement a relationship in a query.
+   */
+  function query() {
+    $this->ensure_my_table();
+    // First, relate our base table to the current base table to the
+    // field, using the base table's id field to the field's column.
+    $views_data = views_fetch_data($this->table);
+    $left_field = $views_data['table']['base']['field'];
+
+    $first = array(
+      'left_table' => $this->table_alias,
+      'left_field' => $left_field,
+      'table' => $this->definition['field table'],
+      'field' => $this->definition['field field'],
+    );
+    if (!empty($this->options['required'])) {
+      $first['type'] = 'INNER';
+    }
+
+    if (!empty($this->definition['join_extra'])) {
+      $first['extra'] = $this->definition['join_extra'];
+    }
+
+    if (!empty($this->definition['join_handler']) && class_exists($this->definition['join_handler'])) {
+      $first_join = new $this->definition['join_handler'];
+    }
+    else {
+      $first_join = new Join();
+    }
+    $first_join->definition = $first;
+    $first_join->construct();
+    $first_join->adjusted = TRUE;
+
+    $this->first_alias = $this->query->add_table($this->definition['field table'], $this->relationship, $first_join);
+
+    // Second, relate the field table to the entity specified using
+    // the entity id on the field table and the entity's id field.
+    $second = array(
+      'left_table' => $this->first_alias,
+      'left_field' => 'entity_id',
+      'table' => $this->definition['base'],
+      'field' => $this->definition['base field'],
+    );
+
+    if (!empty($this->options['required'])) {
+      $second['type'] = 'INNER';
+    }
+
+    if (!empty($this->definition['join_handler']) && class_exists($this->definition['join_handler'])) {
+      $second_join = new $this->definition['join_handler'];
+    }
+    else {
+      $second_join = new Join();
+    }
+    $second_join->definition = $second;
+    $second_join->construct();
+    $second_join->adjusted = TRUE;
+
+    // use a short alias for this:
+    $alias = $this->definition['field_name'] . '_' . $this->table;
+
+    $this->alias = $this->query->add_relationship($alias, $second_join, $this->definition['base'], $this->relationship);
+  }
+}
diff --git a/lib/Drupal/filter/Plugin/views/field/views_handler_field_filter_format_name.inc b/lib/Drupal/filter/Plugin/views/field/views_handler_field_filter_format_name.inc
new file mode 100644
index 000000000000..0a7bf3b86817
--- /dev/null
+++ b/lib/Drupal/filter/Plugin/views/field/views_handler_field_filter_format_name.inc
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_filter_format_name.
+ */
+
+/**
+ * Field handler to output the name of an input format.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_filter_format_name extends views_handler_field {
+  function construct() {
+    parent::construct();
+    // Be explicit about the table we are using.
+    $this->additional_fields['name'] = array('table' => 'filter_formats', 'field' => 'name');
+  }
+
+  function query() {
+    $this->ensure_my_table();
+    $this->add_additional_fields();
+  }
+
+  function render($values) {
+    $format_name = $this->get_value($values, 'name');
+    if (!$format_name) {
+      // Default or invalid input format.
+      // filter_formats() will reliably return the default format even if the
+      // current user is unprivileged.
+      $format = filter_formats(filter_default_format());
+      return $this->sanitize_value($format->name);
+    }
+    return $this->sanitize_value($format_name);
+  }
+}
diff --git a/lib/Drupal/locale/Plugin/views/argument/views_handler_argument_locale_group.inc b/lib/Drupal/locale/Plugin/views/argument/views_handler_argument_locale_group.inc
new file mode 100644
index 000000000000..7ced836677ad
--- /dev/null
+++ b/lib/Drupal/locale/Plugin/views/argument/views_handler_argument_locale_group.inc
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_argument_locale_group.
+ */
+
+/**
+ * Argument handler to accept a language.
+ *
+ * @ingroup views_argument_handlers
+ */
+class views_handler_argument_locale_group extends views_handler_argument {
+  function construct() {
+    parent::construct('group');
+  }
+
+  /**
+   * Override the behavior of summary_name(). Get the user friendly version
+   * of the group.
+   */
+  function summary_name($data) {
+    return $this->locale_group($data->{$this->name_alias});
+  }
+
+  /**
+   * Override the behavior of title(). Get the user friendly version
+   * of the language.
+   */
+  function title() {
+    return $this->locale_group($this->argument);
+  }
+
+  function locale_group($group) {
+    $groups = module_invoke_all('locale', 'groups');
+    // Sort the list.
+    asort($groups);
+    return isset($groups[$group]) ? $groups[$group] : t('Unknown group');
+  }
+}
diff --git a/lib/Drupal/locale/Plugin/views/argument/views_handler_argument_locale_language.inc b/lib/Drupal/locale/Plugin/views/argument/views_handler_argument_locale_language.inc
new file mode 100644
index 000000000000..316d4b153c91
--- /dev/null
+++ b/lib/Drupal/locale/Plugin/views/argument/views_handler_argument_locale_language.inc
@@ -0,0 +1,38 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_argument_locale_language.
+ */
+
+/**
+ * Argument handler to accept a language.
+ *
+ * @ingroup views_argument_handlers
+ */
+class views_handler_argument_locale_language extends views_handler_argument {
+  function construct() {
+    parent::construct('language');
+  }
+
+  /**
+   * Override the behavior of summary_name(). Get the user friendly version
+   * of the language.
+   */
+  function summary_name($data) {
+    return $this->locale_language($data->{$this->name_alias});
+  }
+
+  /**
+   * Override the behavior of title(). Get the user friendly version
+   * of the language.
+   */
+  function title() {
+    return $this->locale_language($this->argument);
+  }
+
+  function locale_language($langcode) {
+    $languages = views_language_list();
+    return isset($languages[$langcode]) ? $languages[$langcode] : t('Unknown language');
+  }
+}
diff --git a/lib/Drupal/locale/Plugin/views/field/views_handler_field_locale_group.inc b/lib/Drupal/locale/Plugin/views/field/views_handler_field_locale_group.inc
new file mode 100644
index 000000000000..393a9487cfea
--- /dev/null
+++ b/lib/Drupal/locale/Plugin/views/field/views_handler_field_locale_group.inc
@@ -0,0 +1,21 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_locale_group.
+ */
+
+/**
+ * Field handler to translate a group into its readable form.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_locale_group extends views_handler_field {
+  function render($values) {
+    $groups = module_invoke_all('locale', 'groups');
+    // Sort the list.
+    asort($groups);
+    $value = $this->get_value($values);
+    return isset($groups[$value]) ? $groups[$value] : '';
+  }
+}
diff --git a/lib/Drupal/locale/Plugin/views/field/views_handler_field_locale_language.inc b/lib/Drupal/locale/Plugin/views/field/views_handler_field_locale_language.inc
new file mode 100644
index 000000000000..8038e2b3023a
--- /dev/null
+++ b/lib/Drupal/locale/Plugin/views/field/views_handler_field_locale_language.inc
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_locale_language.
+ */
+
+/**
+ * Field handler to translate a language into its readable form.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_locale_language extends views_handler_field {
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['native_language'] = array('default' => FALSE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $form['native_language'] = array(
+      '#title' => t('Native language'),
+      '#type' => 'checkbox',
+      '#default_value' => $this->options['native_language'],
+      '#description' => t('If enabled, the native name of the language will be displayed'),
+    );
+  }
+
+  function render($values) {
+    $languages = locale_language_list(empty($this->options['native_language']) ? 'name' : 'native');
+    $value = $this->get_value($values);
+    return isset($languages[$value]) ? $languages[$value] : '';
+  }
+}
diff --git a/lib/Drupal/locale/Plugin/views/field/views_handler_field_locale_link_edit.inc b/lib/Drupal/locale/Plugin/views/field/views_handler_field_locale_link_edit.inc
new file mode 100644
index 000000000000..378935517f9d
--- /dev/null
+++ b/lib/Drupal/locale/Plugin/views/field/views_handler_field_locale_link_edit.inc
@@ -0,0 +1,60 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_locale_link_edit.
+ */
+
+/**
+ * Field handler to present a link to edit a translation.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_locale_link_edit extends views_handler_field {
+  function construct() {
+    parent::construct();
+    $this->additional_fields['lid'] = 'lid';
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['text'] = array('default' => '', 'translatable' => TRUE);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['text'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Text to display'),
+      '#default_value' => $this->options['text'],
+    );
+    parent::options_form($form, $form_state);
+  }
+
+  function query() {
+    $this->ensure_my_table();
+    $this->add_additional_fields();
+  }
+
+  function access() {
+    // Ensure user has access to edit translations.
+    return user_access('translate interface');
+  }
+
+  function render($values) {
+    $value = $this->get_value($values, 'lid');
+    return $this->render_link($this->sanitize_value($value), $values);
+  }
+
+  function render_link($data, $values) {
+    $text = !empty($this->options['text']) ? $this->options['text'] : t('edit');
+
+    $this->options['alter']['make_link'] = TRUE;
+    $this->options['alter']['path'] = 'admin/build/translate/edit/' . $data;
+    $this->options['alter']['query'] = drupal_get_destination();
+
+    return $text;
+  }
+}
diff --git a/lib/Drupal/locale/Plugin/views/field/views_handler_field_node_language.inc b/lib/Drupal/locale/Plugin/views/field/views_handler_field_node_language.inc
new file mode 100644
index 000000000000..467605b03aa0
--- /dev/null
+++ b/lib/Drupal/locale/Plugin/views/field/views_handler_field_node_language.inc
@@ -0,0 +1,37 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_node_language.
+ */
+
+/**
+ * Field handler to translate a language into its readable form.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_node_language extends views_handler_field_node {
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['native_language'] = array('default' => FALSE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $form['native_language'] = array(
+      '#title' => t('Native language'),
+      '#type' => 'checkbox',
+      '#default_value' => $this->options['native_language'],
+      '#description' => t('If enabled, the native name of the language will be displayed'),
+    );
+  }
+
+  function render($values) {
+    $languages = views_language_list(empty($this->options['native_language']) ? 'name' : 'native');
+    $value = $this->get_value($values);
+    $value = isset($languages[$value]) ? $languages[$value] : '';
+    return $this->render_link($value, $values);
+  }
+}
diff --git a/lib/Drupal/locale/Plugin/views/filter/views_handler_filter_locale_group.inc b/lib/Drupal/locale/Plugin/views/filter/views_handler_filter_locale_group.inc
new file mode 100644
index 000000000000..ba9613223e9d
--- /dev/null
+++ b/lib/Drupal/locale/Plugin/views/filter/views_handler_filter_locale_group.inc
@@ -0,0 +1,25 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_filter_locale_group.
+ */
+
+use Drupal\views\Plugins\views\filter\InOperator;
+
+/**
+ * Filter by locale group.
+ *
+ * @ingroup views_filter_handlers
+ */
+class views_handler_filter_locale_group extends InOperator {
+  function get_value_options() {
+    if (!isset($this->value_options)) {
+      $this->value_title = t('Group');
+      $groups = module_invoke_all('locale', 'groups');
+      // Sort the list.
+      asort($groups);
+      $this->value_options = $groups;
+    }
+  }
+}
diff --git a/lib/Drupal/locale/Plugin/views/filter/views_handler_filter_locale_language.inc b/lib/Drupal/locale/Plugin/views/filter/views_handler_filter_locale_language.inc
new file mode 100644
index 000000000000..9725a3135fb1
--- /dev/null
+++ b/lib/Drupal/locale/Plugin/views/filter/views_handler_filter_locale_language.inc
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_filter_locale_language.
+ */
+
+use Drupal\views\Plugins\views\filter\InOperator;
+
+/**
+ * Filter by language.
+ *
+ * @ingroup views_filter_handlers
+ */
+class views_handler_filter_locale_language extends InOperator {
+  function get_value_options() {
+    if (!isset($this->value_options)) {
+      $this->value_title = t('Language');
+      $languages = array(
+        '***CURRENT_LANGUAGE***' => t("Current user's language"),
+        '***DEFAULT_LANGUAGE***' => t("Default site language"),
+        LANGUAGE_NOT_SPECIFIED => t('No language')
+      );
+      $languages = array_merge($languages, views_language_list());
+      $this->value_options = $languages;
+    }
+  }
+}
diff --git a/lib/Drupal/locale/Plugin/views/filter/views_handler_filter_locale_version.inc b/lib/Drupal/locale/Plugin/views/filter/views_handler_filter_locale_version.inc
new file mode 100644
index 000000000000..d5c1f019b15f
--- /dev/null
+++ b/lib/Drupal/locale/Plugin/views/filter/views_handler_filter_locale_version.inc
@@ -0,0 +1,30 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_filter_locale_version.
+ */
+
+use Drupal\views\Plugins\views\filter\InOperator;
+
+/**
+ * Filter by version.
+ *
+ * @ingroup views_filter_handlers
+ */
+class views_handler_filter_locale_version extends InOperator {
+  function get_value_options() {
+    if (!isset($this->value_options)) {
+      $this->value_title = t('Version');
+      // Enable filtering by the current installed Drupal version.
+      $versions = array('***CURRENT_VERSION***' => t('Current installed version'));
+      $result = db_query('SELECT DISTINCT(version) FROM {locales_source} ORDER BY version');
+      foreach ($result as $row) {
+        if (!empty($row->version)) {
+          $versions[$row->version] = $row->version;
+        }
+      }
+      $this->value_options = $versions;
+    }
+  }
+}
diff --git a/lib/Drupal/locale/Plugin/views/filter/views_handler_filter_node_language.inc b/lib/Drupal/locale/Plugin/views/filter/views_handler_filter_node_language.inc
new file mode 100644
index 000000000000..bff9f6495e8e
--- /dev/null
+++ b/lib/Drupal/locale/Plugin/views/filter/views_handler_filter_node_language.inc
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_filter_node_language.
+ */
+
+use Drupal\views\Plugins\views\filter\InOperator;
+
+/**
+ * Filter by language.
+ *
+ * @ingroup views_filter_handlers
+ */
+class views_handler_filter_node_language extends InOperator {
+  function get_value_options() {
+    if (!isset($this->value_options)) {
+      $this->value_title = t('Language');
+      $languages = array(
+        '***CURRENT_LANGUAGE***' => t("Current user's language"),
+        '***DEFAULT_LANGUAGE***' => t("Default site language"),
+        LANGUAGE_NOT_SPECIFIED => t('No language')
+      );
+      $languages = array_merge($languages, views_language_list());
+      $this->value_options = $languages;
+    }
+  }
+}
diff --git a/lib/Drupal/node/Plugin/views/argument/views_handler_argument_dates_various.inc b/lib/Drupal/node/Plugin/views/argument/views_handler_argument_dates_various.inc
new file mode 100644
index 000000000000..164d70a87e65
--- /dev/null
+++ b/lib/Drupal/node/Plugin/views/argument/views_handler_argument_dates_various.inc
@@ -0,0 +1,178 @@
+<?php
+
+/**
+ * @file
+ * Handlers for various date arguments.
+ *
+ * @ingroup views_argument_handlers
+ */
+
+use Drupal\views\Plugins\views\argument\Date;
+/**
+ * Argument handler for a full date (CCYYMMDD)
+ */
+class views_handler_argument_node_created_fulldate extends Date {
+  /**
+   * Constructor implementation
+   */
+  function construct() {
+    parent::construct();
+    $this->format = 'F j, Y';
+    $this->arg_format = 'Ymd';
+    $this->formula = views_date_sql_format($this->arg_format, "***table***.$this->real_field");
+  }
+
+  /**
+   * Provide a link to the next level of the view
+   */
+  function summary_name($data) {
+    $created = $data->{$this->name_alias};
+    return format_date(strtotime($created . " 00:00:00 UTC"), 'custom', $this->format, 'UTC');
+  }
+
+  /**
+   * Provide a link to the next level of the view
+   */
+  function title() {
+    return format_date(strtotime($this->argument . " 00:00:00 UTC"), 'custom', $this->format, 'UTC');
+  }
+}
+
+/**
+ * Argument handler for a year (CCYY)
+ */
+class views_handler_argument_node_created_year extends Date {
+  /**
+   * Constructor implementation
+   */
+  function construct() {
+    parent::construct();
+    $this->arg_format = 'Y';
+    $this->formula = views_date_sql_extract('YEAR', "***table***.$this->real_field");
+  }
+}
+
+/**
+ * Argument handler for a year plus month (CCYYMM)
+ */
+class views_handler_argument_node_created_year_month extends Date {
+  /**
+   * Constructor implementation
+   */
+  function construct() {
+    parent::construct();
+    $this->format = 'F Y';
+    $this->arg_format = 'Ym';
+    $this->formula = views_date_sql_format($this->arg_format, "***table***.$this->real_field");
+  }
+
+  /**
+   * Provide a link to the next level of the view
+   */
+  function summary_name($data) {
+    $created = $data->{$this->name_alias};
+    return format_date(strtotime($created . "15" . " 00:00:00 UTC"), 'custom', $this->format, 'UTC');
+  }
+
+  /**
+   * Provide a link to the next level of the view
+   */
+  function title() {
+    return format_date(strtotime($this->argument . "15" . " 00:00:00 UTC"), 'custom', $this->format, 'UTC');
+  }
+}
+
+/**
+ * Argument handler for a month (MM)
+ */
+class views_handler_argument_node_created_month extends Date {
+  /**
+   * Constructor implementation
+   */
+  function construct() {
+    parent::construct();
+    $this->formula = views_date_sql_extract('MONTH', "***table***.$this->real_field");
+    $this->format = 'F';
+    $this->arg_format = 'm';
+  }
+
+  /**
+   * Provide a link to the next level of the view
+   */
+  function summary_name($data) {
+    $month = str_pad($data->{$this->name_alias}, 2, '0', STR_PAD_LEFT);
+    return format_date(strtotime("2005" . $month . "15" . " 00:00:00 UTC" ), 'custom', $this->format, 'UTC');
+  }
+
+  /**
+   * Provide a link to the next level of the view
+   */
+  function title() {
+    $month = str_pad($this->argument, 2, '0', STR_PAD_LEFT);
+    return format_date(strtotime("2005" . $month . "15" . " 00:00:00 UTC"), 'custom', $this->format, 'UTC');
+  }
+
+  function summary_argument($data) {
+    // Make sure the argument contains leading zeroes.
+    return str_pad($data->{$this->base_alias}, 2, '0', STR_PAD_LEFT);
+  }
+}
+
+/**
+ * Argument handler for a day (DD)
+ */
+class views_handler_argument_node_created_day extends Date {
+  /**
+   * Constructor implementation
+   */
+  function construct() {
+    parent::construct();
+    $this->formula = views_date_sql_extract('DAY', "***table***.$this->real_field");
+    $this->format = 'j';
+    $this->arg_format = 'd';
+  }
+
+  /**
+   * Provide a link to the next level of the view
+   */
+  function summary_name($data) {
+    $day = str_pad($data->{$this->name_alias}, 2, '0', STR_PAD_LEFT);
+    // strtotime respects server timezone, so we need to set the time fixed as utc time
+    return format_date(strtotime("2005" . "05" . $day . " 00:00:00 UTC"), 'custom', $this->format, 'UTC');
+  }
+
+  /**
+   * Provide a link to the next level of the view
+   */
+  function title() {
+    $day = str_pad($this->argument, 2, '0', STR_PAD_LEFT);
+    return format_date(strtotime("2005" . "05" . $day . " 00:00:00 UTC"), 'custom', $this->format, 'UTC');
+  }
+
+  function summary_argument($data) {
+    // Make sure the argument contains leading zeroes.
+    return str_pad($data->{$this->base_alias}, 2, '0', STR_PAD_LEFT);
+  }
+}
+
+/**
+ * Argument handler for a week.
+ */
+class views_handler_argument_node_created_week extends Date {
+  /**
+   * Constructor implementation
+   */
+  function construct() {
+    parent::construct();
+    $this->arg_format = 'w';
+    $this->formula = views_date_sql_extract('WEEK', "***table***.$this->real_field");
+  }
+
+  /**
+   * Provide a link to the next level of the view
+   */
+  function summary_name($data) {
+    $created = $data->{$this->name_alias};
+    return t('Week @week', array('@week' => $created));
+  }
+}
diff --git a/lib/Drupal/node/Plugin/views/argument/views_handler_argument_node_language.inc b/lib/Drupal/node/Plugin/views/argument/views_handler_argument_node_language.inc
new file mode 100644
index 000000000000..170388a3ef17
--- /dev/null
+++ b/lib/Drupal/node/Plugin/views/argument/views_handler_argument_node_language.inc
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_argument_node_language.
+ */
+
+/**
+ * Argument handler to accept a language.
+ */
+class views_handler_argument_node_language extends views_handler_argument {
+  function construct() {
+    parent::construct('language');
+  }
+
+  /**
+   * Override the behavior of summary_name(). Get the user friendly version
+   * of the language.
+   */
+  function summary_name($data) {
+    return $this->node_language($data->{$this->name_alias});
+  }
+
+  /**
+   * Override the behavior of title(). Get the user friendly version of the
+   * node type.
+   */
+  function title() {
+    return $this->node_language($this->argument);
+  }
+
+  function node_language($langcode) {
+    $languages = views_language_list();
+    return isset($languages[$langcode]) ? $languages[$langcode] : t('Unknown language');
+  }
+}
diff --git a/lib/Drupal/node/Plugin/views/argument/views_handler_argument_node_nid.inc b/lib/Drupal/node/Plugin/views/argument/views_handler_argument_node_nid.inc
new file mode 100644
index 000000000000..b0dbee09667f
--- /dev/null
+++ b/lib/Drupal/node/Plugin/views/argument/views_handler_argument_node_nid.inc
@@ -0,0 +1,24 @@
+<?php
+
+/**
+ * @file
+ * Provide node nid argument handler.
+ */
+
+/**
+ * Argument handler to accept a node id.
+ */
+class views_handler_argument_node_nid extends views_handler_argument_numeric {
+  /**
+   * Override the behavior of title(). Get the title of the node.
+   */
+  function title_query() {
+    $titles = array();
+
+    $result = db_query("SELECT n.title FROM {node} n WHERE n.nid IN (:nids)", array(':nids' => $this->value));
+    foreach ($result as $term) {
+      $titles[] = check_plain($term->title);
+    }
+    return $titles;
+  }
+}
diff --git a/lib/Drupal/node/Plugin/views/argument/views_handler_argument_node_type.inc b/lib/Drupal/node/Plugin/views/argument/views_handler_argument_node_type.inc
new file mode 100644
index 000000000000..ea99d7c64b3b
--- /dev/null
+++ b/lib/Drupal/node/Plugin/views/argument/views_handler_argument_node_type.inc
@@ -0,0 +1,39 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_argument_node_type.
+ */
+
+/**
+ * Argument handler to accept a node type.
+ */
+class views_handler_argument_node_type extends views_handler_argument_string {
+  function construct() {
+    parent::construct('type');
+  }
+
+  /**
+   * Override the behavior of summary_name(). Get the user friendly version
+   * of the node type.
+   */
+  function summary_name($data) {
+    return $this->node_type($data->{$this->name_alias});
+  }
+
+  /**
+   * Override the behavior of title(). Get the user friendly version of the
+   * node type.
+   */
+  function title() {
+    return $this->node_type($this->argument);
+  }
+
+  function node_type($type) {
+    $output = node_type_get_name($type);
+    if (empty($output)) {
+      $output = t('Unknown content type');
+    }
+    return check_plain($output);
+  }
+}
diff --git a/lib/Drupal/node/Plugin/views/argument/views_handler_argument_node_uid_revision.inc b/lib/Drupal/node/Plugin/views/argument/views_handler_argument_node_uid_revision.inc
new file mode 100644
index 000000000000..142882a396da
--- /dev/null
+++ b/lib/Drupal/node/Plugin/views/argument/views_handler_argument_node_uid_revision.inc
@@ -0,0 +1,18 @@
+<?php
+
+/**
+ * @file
+ * Defintion of views_handler_argument_node_uid_revision.
+ */
+
+/**
+ * Filter handler to accept a user id to check for nodes that
+ * user posted or created a revision on.
+ */
+class views_handler_argument_node_uid_revision extends views_handler_argument_comment_user_uid {
+  function query($group_by = FALSE) {
+    $this->ensure_my_table();
+    $placeholder = $this->placeholder();
+    $this->query->add_where_expression(0, "$this->table_alias.uid = $placeholder OR ((SELECT COUNT(*) FROM {node_revision} nr WHERE nr.uid = $placeholder AND nr.nid = $this->table_alias.nid) > 0)", array($placeholder => $this->argument));
+  }
+}
diff --git a/lib/Drupal/node/Plugin/views/argument/views_handler_argument_node_vid.inc b/lib/Drupal/node/Plugin/views/argument/views_handler_argument_node_vid.inc
new file mode 100644
index 000000000000..21532f93d936
--- /dev/null
+++ b/lib/Drupal/node/Plugin/views/argument/views_handler_argument_node_vid.inc
@@ -0,0 +1,26 @@
+<?php
+
+/**
+ * @file
+ * Provide node vid argument handler.
+ */
+
+/**
+ * Argument handler to accept a node revision id.
+ */
+class views_handler_argument_node_vid extends views_handler_argument_numeric {
+  // No constructor is necessary.
+
+  /**
+   * Override the behavior of title(). Get the title of the revision.
+   */
+  function title_query() {
+    $titles = array();
+
+    $result = db_query("SELECT n.title FROM {node_revision} n WHERE n.nid IN (:nids)", array(':nids' => $this->value));
+    foreach ($result as $term) {
+      $titles[] = check_plain($term->title);
+    }
+    return $titles;
+  }
+}
diff --git a/lib/Drupal/node/Plugin/views/argument_default/views_plugin_argument_default_node.inc b/lib/Drupal/node/Plugin/views/argument_default/views_plugin_argument_default_node.inc
new file mode 100644
index 000000000000..b7fb1282a7cd
--- /dev/null
+++ b/lib/Drupal/node/Plugin/views/argument_default/views_plugin_argument_default_node.inc
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * @file
+ * Contains the node from URL argument default plugin.
+ */
+
+use Drupal\views\Plugins\views\argument_default\ArgumentDefaultPluginBase;
+
+/**
+ * Default argument plugin to extract a node via menu_get_object
+ *
+ * This plugin actually has no options so it odes not need to do a great deal.
+ */
+class views_plugin_argument_default_node extends ArgumentDefaultPluginBase {
+  function get_argument() {
+    foreach (range(1, 3) as $i) {
+      $node = menu_get_object('node', $i);
+      if (!empty($node)) {
+        return $node->nid;
+      }
+    }
+
+    if (arg(0) == 'node' && is_numeric(arg(1))) {
+      return arg(1);
+    }
+  }
+}
diff --git a/lib/Drupal/node/Plugin/views/argument_validate/views_plugin_argument_validate_node.inc b/lib/Drupal/node/Plugin/views/argument_validate/views_plugin_argument_validate_node.inc
new file mode 100644
index 000000000000..17d1708060ea
--- /dev/null
+++ b/lib/Drupal/node/Plugin/views/argument_validate/views_plugin_argument_validate_node.inc
@@ -0,0 +1,141 @@
+<?php
+
+/**
+ * @file
+ * Contains the 'node' argument validator plugin.
+ */
+
+use Drupal\views\Plugins\views\argument_validator\ArgumentValidatorPluginBase;
+
+/**
+ * Validate whether an argument is an acceptable node.
+ */
+class views_plugin_argument_validate_node extends ArgumentValidatorPluginBase {
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['types'] = array('default' => array());
+    $options['access'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['access_op'] = array('default' => 'view');
+    $options['nid_type'] = array('default' => 'nid');
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $types = node_type_get_types();
+    $options = array();
+    foreach ($types as $type => $info) {
+      $options[$type] = check_plain(t($info->name));
+    }
+
+    $form['types'] = array(
+      '#type' => 'checkboxes',
+      '#title' => t('Content types'),
+      '#options' => $options,
+      '#default_value' => $this->options['types'],
+      '#description' => t('Choose one or more content types to validate with.'),
+    );
+
+    $form['access'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Validate user has access to the content'),
+      '#default_value' => $this->options['access'],
+    );
+    $form['access_op'] = array(
+      '#type' => 'radios',
+      '#title' => t('Access operation to check'),
+      '#options' => array('view' => t('View'), 'update' => t('Edit'), 'delete' => t('Delete')),
+      '#default_value' => $this->options['access_op'],
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[validate][options][node][access]"]' => array('checked' => TRUE),
+        ),
+      ),
+    );
+
+    $form['nid_type'] = array(
+      '#type' => 'select',
+      '#title' => t('Filter value format'),
+      '#options' => array(
+        'nid' => t('Node ID'),
+        'nids' => t('Node IDs separated by , or +'),
+      ),
+      '#default_value' => $this->options['nid_type'],
+    );
+  }
+
+  function options_submit(&$form, &$form_state, &$options = array()) {
+    // filter trash out of the options so we don't store giant unnecessary arrays
+    $options['types'] = array_filter($options['types']);
+  }
+
+  function convert_options(&$options) {
+    if (!isset($options['types']) && !empty($this->argument->options['validate_argument_node_type'])) {
+      $options['types'] = isset($this->argument->options['validate_argument_node_type']) ? $this->argument->options['validate_argument_node_type'] : array();
+      $options['access'] = !empty($this->argument->options['validate_argument_node_access']);
+      $options['access_op'] = isset($this->argument->options['validate_argument_node_access_op']) ? $this->argument->options['validate_argument_node_access_op'] : 'view';
+      $options['nid_type'] = isset($this->argument->options['validate_argument_nid_type']) ? $this->argument->options['validate_argument_nid_type'] : array();
+    }
+  }
+
+  function validate_argument($argument) {
+    $types = $this->options['types'];
+
+    switch ($this->options['nid_type']) {
+      case 'nid':
+        if (!is_numeric($argument)) {
+          return FALSE;
+        }
+        $node = node_load($argument);
+        if (!$node) {
+          return FALSE;
+        }
+
+        if (!empty($this->options['access'])) {
+          if (!node_access($this->options['access_op'], $node)) {
+            return FALSE;
+          }
+        }
+
+        // Save the title() handlers some work.
+        $this->argument->validated_title = check_plain($node->title);
+
+        if (empty($types)) {
+          return TRUE;
+        }
+
+        return isset($types[$node->type]);
+      break;
+      case 'nids':
+        $nids = new stdClass();
+        $nids->value = array($argument);
+        $nids = views_break_phrase($argument, $nids);
+        if ($nids->value == array(-1)) {
+          return FALSE;
+        }
+
+        $test = drupal_map_assoc($nids->value);
+        $titles = array();
+
+        $result = db_query("SELECT * FROM {node} WHERE nid IN (:nids)", array(':nids' =>  $nids->value));
+        foreach ($result as $node) {
+          if ($types && empty($types[$node->type])) {
+            return FALSE;
+          }
+
+          if (!empty($this->options['access'])) {
+            if (!node_access($this->options['access_op'], $node)) {
+              return FALSE;
+            }
+          }
+
+          $titles[] = check_plain($node->title);
+          unset($test[$node->nid]);
+        }
+
+        $this->argument->validated_title = implode($nids->operator == 'or' ? ' + ' : ', ', $titles);
+        // If this is not empty, we did not find a nid.
+        return empty($test);
+    }
+  }
+}
diff --git a/lib/Drupal/node/Plugin/views/field/views_handler_field_history_user_timestamp.inc b/lib/Drupal/node/Plugin/views/field/views_handler_field_history_user_timestamp.inc
new file mode 100644
index 000000000000..e4964eac801b
--- /dev/null
+++ b/lib/Drupal/node/Plugin/views/field/views_handler_field_history_user_timestamp.inc
@@ -0,0 +1,83 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_history_user_timestamp.
+ */
+
+/**
+ * Field handler to display the marker for new content.
+ *
+ * The handler is named history_user, because of compability reasons, the table
+ * is history.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_history_user_timestamp extends views_handler_field_node {
+  function init(&$view, &$options) {
+    parent::init($view, $options);
+    global $user;
+    if ($user->uid) {
+      $this->additional_fields['created'] = array('table' => 'node', 'field' => 'created');
+      $this->additional_fields['changed'] = array('table' => 'node', 'field' => 'changed');
+      if (module_exists('comment') && !empty($this->options['comments'])) {
+        $this->additional_fields['last_comment'] = array('table' => 'node_comment_statistics', 'field' => 'last_comment_timestamp');
+      }
+    }
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['comments'] = array('default' => FALSE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    if (module_exists('comment')) {
+      $form['comments'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Check for new comments as well'),
+        '#default_value' => !empty($this->options['comments']),
+        '#fieldset' => 'more',
+      );
+    }
+  }
+
+  function query() {
+    // Only add ourselves to the query if logged in.
+    global $user;
+    if (!$user->uid) {
+      return;
+    }
+    parent::query();
+  }
+
+  function render($values) {
+    // Let's default to 'read' state.
+    // This code shadows node_mark, but it reads from the db directly and
+    // we already have that info.
+    $mark = MARK_READ;
+    global $user;
+    if ($user->uid) {
+      $last_read = $this->get_value($values);
+      $created = $this->get_value($values, 'created');
+      $changed = $this->get_value($values, 'changed');
+
+      $last_comment = module_exists('comment') && !empty($this->options['comments']) ?  $this->get_value($values, 'last_comment') : 0;
+
+      if (!$last_read && $created > NODE_NEW_LIMIT) {
+        $mark = MARK_NEW;
+      }
+      elseif ($changed > $last_read && $changed > NODE_NEW_LIMIT) {
+        $mark = MARK_UPDATED;
+      }
+      elseif ($last_comment > $last_read && $last_comment > NODE_NEW_LIMIT) {
+        $mark = MARK_UPDATED;
+      }
+      return $this->render_link(theme('mark', array('type' => $mark)), $values);
+    }
+  }
+}
diff --git a/lib/Drupal/node/Plugin/views/field/views_handler_field_node.inc b/lib/Drupal/node/Plugin/views/field/views_handler_field_node.inc
new file mode 100644
index 000000000000..9785faf71825
--- /dev/null
+++ b/lib/Drupal/node/Plugin/views/field/views_handler_field_node.inc
@@ -0,0 +1,82 @@
+<?php
+
+/**
+ * @file
+ * Contains the basic 'node' field handler.
+ */
+
+use Drupal\views\Plugins\views\field\FieldPluginBase;
+
+/**
+ * Field handler to provide simple renderer that allows linking to a node.
+ * Definition terms:
+ * - link_to_node default: Should this field have the checkbox "link to node" enabled by default.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_node extends FieldPluginBase {
+
+  function init(&$view, &$options) {
+    parent::init($view, $options);
+    // Don't add the additional fields to groupby
+    if (!empty($this->options['link_to_node'])) {
+      $this->additional_fields['nid'] = array('table' => 'node', 'field' => 'nid');
+      if (module_exists('translation')) {
+        $this->additional_fields['language'] = array('table' => 'node', 'field' => 'language');
+      }
+    }
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['link_to_node'] = array('default' => isset($this->definition['link_to_node default']) ? $this->definition['link_to_node default'] : FALSE, 'bool' => TRUE);
+    return $options;
+  }
+
+  /**
+   * Provide link to node option
+   */
+  function options_form(&$form, &$form_state) {
+    $form['link_to_node'] = array(
+      '#title' => t('Link this field to the original piece of content'),
+      '#description' => t("Enable to override this field's links."),
+      '#type' => 'checkbox',
+      '#default_value' => !empty($this->options['link_to_node']),
+    );
+
+    parent::options_form($form, $form_state);
+  }
+
+  /**
+   * Render whatever the data is as a link to the node.
+   *
+   * Data should be made XSS safe prior to calling this function.
+   */
+  function render_link($data, $values) {
+    if (!empty($this->options['link_to_node']) && !empty($this->additional_fields['nid'])) {
+      if ($data !== NULL && $data !== '') {
+        $this->options['alter']['make_link'] = TRUE;
+        $this->options['alter']['path'] = "node/" . $this->get_value($values, 'nid');
+        if (isset($this->aliases['language'])) {
+          $languages = language_list();
+          $language = $this->get_value($values, 'language');
+          if (isset($languages[$language])) {
+            $this->options['alter']['language'] = $languages[$language];
+          }
+          else {
+            unset($this->options['alter']['language']);
+          }
+        }
+      }
+      else {
+        $this->options['alter']['make_link'] = FALSE;
+      }
+    }
+    return $data;
+  }
+
+  function render($values) {
+    $value = $this->get_value($values);
+    return $this->render_link($this->sanitize_value($value), $values);
+  }
+}
diff --git a/lib/Drupal/node/Plugin/views/field/views_handler_field_node_link.inc b/lib/Drupal/node/Plugin/views/field/views_handler_field_node_link.inc
new file mode 100644
index 000000000000..7e9bbd2a8602
--- /dev/null
+++ b/lib/Drupal/node/Plugin/views/field/views_handler_field_node_link.inc
@@ -0,0 +1,48 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_node_link.
+ */
+
+/**
+ * Field handler to present a link to the node.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_node_link extends views_handler_field_entity {
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['text'] = array('default' => '', 'translatable' => TRUE);
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['text'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Text to display'),
+      '#default_value' => $this->options['text'],
+    );
+    parent::options_form($form, $form_state);
+
+    // The path is set by render_link function so don't allow to set it.
+    $form['alter']['path'] = array('#access' => FALSE);
+    $form['alter']['external'] = array('#access' => FALSE);
+  }
+
+  function render($values) {
+    if ($entity = $this->get_value($values)) {
+      return $this->render_link($entity, $values);
+    }
+  }
+
+  function render_link($node, $values) {
+    if (node_access('view', $node)) {
+      $this->options['alter']['make_link'] = TRUE;
+      $this->options['alter']['path'] = "node/$node->nid";
+      $text = !empty($this->options['text']) ? $this->options['text'] : t('view');
+      return $text;
+    }
+  }
+}
diff --git a/lib/Drupal/node/Plugin/views/field/views_handler_field_node_link_delete.inc b/lib/Drupal/node/Plugin/views/field/views_handler_field_node_link_delete.inc
new file mode 100644
index 000000000000..8271c0baca05
--- /dev/null
+++ b/lib/Drupal/node/Plugin/views/field/views_handler_field_node_link_delete.inc
@@ -0,0 +1,31 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_node_link_delete.
+ */
+
+/**
+ * Field handler to present a link to delete a node.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_node_link_delete extends views_handler_field_node_link {
+
+  /**
+   * Renders the link.
+   */
+  function render_link($node, $values) {
+    // Ensure user has access to delete this node.
+    if (!node_access('delete', $node)) {
+      return;
+    }
+
+    $this->options['alter']['make_link'] = TRUE;
+    $this->options['alter']['path'] = "node/$node->nid/delete";
+    $this->options['alter']['query'] = drupal_get_destination();
+
+    $text = !empty($this->options['text']) ? $this->options['text'] : t('delete');
+    return $text;
+  }
+}
diff --git a/lib/Drupal/node/Plugin/views/field/views_handler_field_node_link_edit.inc b/lib/Drupal/node/Plugin/views/field/views_handler_field_node_link_edit.inc
new file mode 100644
index 000000000000..4e8aad00b43c
--- /dev/null
+++ b/lib/Drupal/node/Plugin/views/field/views_handler_field_node_link_edit.inc
@@ -0,0 +1,31 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_node_link_edit.
+ */
+
+/**
+ * Field handler to present a link node edit.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_node_link_edit extends views_handler_field_node_link {
+
+  /**
+   * Renders the link.
+   */
+  function render_link($node, $values) {
+    // Ensure user has access to edit this node.
+    if (!node_access('update', $node)) {
+      return;
+    }
+
+    $this->options['alter']['make_link'] = TRUE;
+    $this->options['alter']['path'] = "node/$node->nid/edit";
+    $this->options['alter']['query'] = drupal_get_destination();
+
+    $text = !empty($this->options['text']) ? $this->options['text'] : t('edit');
+    return $text;
+  }
+}
diff --git a/lib/Drupal/node/Plugin/views/field/views_handler_field_node_path.inc b/lib/Drupal/node/Plugin/views/field/views_handler_field_node_path.inc
new file mode 100644
index 000000000000..f47f85fab99e
--- /dev/null
+++ b/lib/Drupal/node/Plugin/views/field/views_handler_field_node_path.inc
@@ -0,0 +1,47 @@
+<?php
+
+/**
+ * @file
+ * Handler for node path field.
+ */
+
+/**
+ * Field handler to present the path to the node.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_node_path extends views_handler_field {
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['absolute'] = array('default' => FALSE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  function construct() {
+    parent::construct();
+    $this->additional_fields['nid'] = 'nid';
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $form['absolute'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Use absolute link (begins with "http://")'),
+      '#default_value' => $this->options['absolute'],
+      '#description' => t('Enable this option to output an absolute link. Required if you want to use the path as a link destination (as in "output this field as a link" above).'),
+      '#fieldset' => 'alter',
+    );
+  }
+
+  function query() {
+    $this->ensure_my_table();
+    $this->add_additional_fields();
+  }
+
+  function render($values) {
+    $nid = $this->get_value($values, 'nid');
+    return url("node/$nid", array('absolute' => $this->options['absolute']));
+  }
+}
diff --git a/lib/Drupal/node/Plugin/views/field/views_handler_field_node_revision.inc b/lib/Drupal/node/Plugin/views/field/views_handler_field_node_revision.inc
new file mode 100644
index 000000000000..c04693a81552
--- /dev/null
+++ b/lib/Drupal/node/Plugin/views/field/views_handler_field_node_revision.inc
@@ -0,0 +1,71 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_node_revision.
+ */
+
+/**
+ * Contains the basic 'node_revision' field handler.
+ */
+
+/**
+ * A basic node_revision handler.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_node_revision extends views_handler_field_node {
+  function init(&$view, &$options) {
+    parent::init($view, $options);
+    if (!empty($this->options['link_to_node_revision'])) {
+      $this->additional_fields['vid'] = 'vid';
+      $this->additional_fields['nid'] = 'nid';
+      if (module_exists('translation')) {
+        $this->additional_fields['language'] = array('table' => 'node', 'field' => 'language');
+      }
+    }
+  }
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['link_to_node_revision'] = array('default' => FALSE, 'bool' => TRUE);
+    return $options;
+  }
+
+  /**
+   * Provide link to revision option.
+   */
+  function options_form(&$form, &$form_state) {
+    $form['link_to_node_revision'] = array(
+      '#title' => t('Link this field to its content revision'),
+      '#description' => t('This will override any other link you have set.'),
+      '#type' => 'checkbox',
+      '#default_value' => !empty($this->options['link_to_node_revision']),
+    );
+    parent::options_form($form, $form_state);
+  }
+
+  /**
+   * Render whatever the data is as a link to the node.
+   *
+   * Data should be made XSS safe prior to calling this function.
+   */
+  function render_link($data, $values) {
+    if (!empty($this->options['link_to_node_revision']) && $data !== NULL && $data !== '') {
+      $this->options['alter']['make_link'] = TRUE;
+      $nid = $this->get_value($values, 'nid');
+      $vid = $this->get_value($values, 'vid');
+      $this->options['alter']['path'] = "node/" . $nid . '/revisions/' . $vid . '/view';
+      if (module_exists('translation')) {
+        $language = $this->get_value($values, 'language');
+        $languages = language_list();
+        if (isset($languages[$language])) {
+          $this->options['alter']['language'] = $languages[$language];
+        }
+      }
+    }
+    else {
+      return parent::render_link($data, $values);
+    }
+    return $data;
+  }
+}
diff --git a/lib/Drupal/node/Plugin/views/field/views_handler_field_node_revision_link.inc b/lib/Drupal/node/Plugin/views/field/views_handler_field_node_revision_link.inc
new file mode 100644
index 000000000000..69047bbb19d7
--- /dev/null
+++ b/lib/Drupal/node/Plugin/views/field/views_handler_field_node_revision_link.inc
@@ -0,0 +1,66 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_node_revision_link.
+ */
+
+/**
+ * Field handler to present a link to a node revision.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_node_revision_link extends views_handler_field_node_link {
+
+  function construct() {
+    parent::construct();
+    $this->additional_fields['node_vid'] = array('table' => 'node_revision', 'field' => 'vid');
+  }
+
+  function access() {
+    return user_access('view revisions') || user_access('administer nodes');
+  }
+
+  function render_link($data, $values) {
+    list($node, $vid) = $this->get_revision_entity($values, 'view');
+    if (!isset($vid)) {
+      return;
+    }
+
+    // Current revision uses the node view path.
+    $path = 'node/' . $node->nid;
+    if ($node->vid != $vid) {
+      $path .= "/revisions/$vid/view";
+    }
+
+    $this->options['alter']['make_link'] = TRUE;
+    $this->options['alter']['path'] = $path;
+    $this->options['alter']['query'] = drupal_get_destination();
+
+    return !empty($this->options['text']) ? $this->options['text'] : t('view');
+  }
+
+  /**
+   * Returns the revision values of a node.
+   *
+   * @param object $values
+   *   An object containing all retrieved values.
+   * @param string $op
+   *   The operation being performed.
+   *
+   * @return array
+   *   A numerically indexed array containing the current node object and the
+   *   revision ID for this row.
+   */
+  function get_revision_entity($values, $op) {
+    $vid = $this->get_value($values, 'node_vid');
+    $node = $this->get_value($values);
+    // Unpublished nodes ignore access control.
+    $node->status = 1;
+    // Ensure user has access to perform the operation on this node.
+    if (!node_access($op, $node)) {
+      return array($node, NULL);
+    }
+    return array($node, $vid);
+  }
+}
diff --git a/lib/Drupal/node/Plugin/views/field/views_handler_field_node_revision_link_delete.inc b/lib/Drupal/node/Plugin/views/field/views_handler_field_node_revision_link_delete.inc
new file mode 100644
index 000000000000..e0d00a7862c5
--- /dev/null
+++ b/lib/Drupal/node/Plugin/views/field/views_handler_field_node_revision_link_delete.inc
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_node_revision_link_delete.
+ */
+
+/**
+ * Field handler to present link to delete a node revision.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_node_revision_link_delete extends views_handler_field_node_revision_link {
+
+  function access() {
+    return user_access('delete revisions') || user_access('administer nodes');
+  }
+
+  function render_link($data, $values) {
+    list($node, $vid) = $this->get_revision_entity($values, 'delete');
+    if (!isset($vid)) {
+      return;
+    }
+
+    // Current revision cannot be deleted.
+    if ($node->vid == $vid) {
+      return;
+    }
+
+    $this->options['alter']['make_link'] = TRUE;
+    $this->options['alter']['path'] = 'node/' . $node->nid . "/revisions/$vid/delete";
+    $this->options['alter']['query'] = drupal_get_destination();
+
+    return !empty($this->options['text']) ? $this->options['text'] : t('delete');
+  }
+}
diff --git a/lib/Drupal/node/Plugin/views/field/views_handler_field_node_revision_link_revert.inc b/lib/Drupal/node/Plugin/views/field/views_handler_field_node_revision_link_revert.inc
new file mode 100644
index 000000000000..af2044270c89
--- /dev/null
+++ b/lib/Drupal/node/Plugin/views/field/views_handler_field_node_revision_link_revert.inc
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_node_revision_link_revert.
+ */
+
+/**
+ * Field handler to present a link to revert a node to a revision.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_node_revision_link_revert extends views_handler_field_node_revision_link {
+
+  function access() {
+    return user_access('revert revisions') || user_access('administer nodes');
+  }
+
+  function render_link($data, $values) {
+    list($node, $vid) = $this->get_revision_entity($values, 'update');
+    if (!isset($vid)) {
+      return;
+    }
+
+    // Current revision cannot be reverted.
+    if ($node->vid == $vid) {
+      return;
+    }
+
+    $this->options['alter']['make_link'] = TRUE;
+    $this->options['alter']['path'] = 'node/' . $node->nid . "/revisions/$vid/revert";
+    $this->options['alter']['query'] = drupal_get_destination();
+
+    return !empty($this->options['text']) ? $this->options['text'] : t('revert');
+  }
+}
diff --git a/lib/Drupal/node/Plugin/views/field/views_handler_field_node_type.inc b/lib/Drupal/node/Plugin/views/field/views_handler_field_node_type.inc
new file mode 100644
index 000000000000..ba8ee3eb81b3
--- /dev/null
+++ b/lib/Drupal/node/Plugin/views/field/views_handler_field_node_type.inc
@@ -0,0 +1,49 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_node_type.
+ */
+
+/**
+ * Field handler to translate a node type into its readable form.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_node_type extends views_handler_field_node {
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['machine_name'] = array('default' => FALSE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  /**
+   * Provide machine_name option for to node type display.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $form['machine_name'] = array(
+      '#title' => t('Output machine name'),
+      '#description' => t('Display field as the content type machine name.'),
+      '#type' => 'checkbox',
+      '#default_value' => !empty($this->options['machine_name']),
+    );
+  }
+
+  /**
+    * Render node type as human readable name, unless using machine_name option.
+    */
+  function render_name($data, $values) {
+    if ($this->options['machine_name'] != 1 && $data !== NULL && $data !== '') {
+      return t($this->sanitize_value(node_type_get_name($data)));
+    }
+    return $this->sanitize_value($data);
+  }
+
+  function render($values) {
+    $value = $this->get_value($values);
+    return $this->render_link($this->render_name($value, $values), $values);
+  }
+}
diff --git a/lib/Drupal/node/Plugin/views/filter/views_handler_filter_history_user_timestamp.inc b/lib/Drupal/node/Plugin/views/filter/views_handler_filter_history_user_timestamp.inc
new file mode 100644
index 000000000000..fbd0e79a796b
--- /dev/null
+++ b/lib/Drupal/node/Plugin/views/filter/views_handler_filter_history_user_timestamp.inc
@@ -0,0 +1,89 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_filter_history_user_timestamp.
+ */
+
+use Drupal\views\Plugins\views\filter\FilterPluginBase;
+
+/**
+ * Filter for new content.
+ *
+ * The handler is named history_user, because of compability reasons, the table
+ * is history.
+ *
+ * @ingroup views_filter_handlers
+ */
+class views_handler_filter_history_user_timestamp extends FilterPluginBase {
+  // Don't display empty space where the operator would be.
+  var $no_operator = TRUE;
+
+  function expose_form(&$form, &$form_state) {
+    parent::expose_form($form, $form_state);
+    // @todo There are better ways of excluding required and multiple (object flags)
+    unset($form['expose']['required']);
+    unset($form['expose']['multiple']);
+    unset($form['expose']['remember']);
+  }
+
+  function value_form(&$form, &$form_state) {
+    // Only present a checkbox for the exposed filter itself. There's no way
+    // to tell the difference between not checked and the default value, so
+    // specifying the default value via the views UI is meaningless.
+    if (!empty($form_state['exposed'])) {
+      if (isset($this->options['expose']['label'])) {
+        $label = $this->options['expose']['label'];
+      }
+      else {
+        $label = t('Has new content');
+      }
+      $form['value'] = array(
+        '#type' => 'checkbox',
+        '#title' => $label,
+        '#default_value' => $this->value,
+      );
+    }
+  }
+
+  function query() {
+    global $user;
+    // This can only work if we're logged in.
+    if (!$user || !$user->uid) {
+      return;
+    }
+
+    // Don't filter if we're exposed and the checkbox isn't selected.
+    if ((!empty($this->options['exposed'])) && empty($this->value)) {
+      return;
+    }
+
+    // Hey, Drupal kills old history, so nodes that haven't been updated
+    // since NODE_NEW_LIMIT are bzzzzzzzt outta here!
+
+    $limit = REQUEST_TIME - NODE_NEW_LIMIT;
+
+    $this->ensure_my_table();
+    $field = "$this->table_alias.$this->real_field";
+    $node = $this->query->ensure_table('node', $this->relationship);
+
+    $clause = '';
+    $clause2 = '';
+    if (module_exists('comment')) {
+      $ncs = $this->query->ensure_table('node_comment_statistics', $this->relationship);
+      $clause = ("OR $ncs.last_comment_timestamp > (***CURRENT_TIME*** - $limit)");
+      $clause2 = "OR $field < $ncs.last_comment_timestamp";
+    }
+
+    // NULL means a history record doesn't exist. That's clearly new content.
+    // Unless it's very very old content. Everything in the query is already
+    // type safe cause none of it is coming from outside here.
+    $this->query->add_where_expression($this->options['group'], "($field IS NULL AND ($node.changed > (***CURRENT_TIME*** - $limit) $clause)) OR $field < $node.changed $clause2");
+  }
+
+  function admin_summary() {
+    if (!empty($this->options['exposed'])) {
+      return t('exposed');
+    }
+  }
+}
diff --git a/lib/Drupal/node/Plugin/views/filter/views_handler_filter_node_access.inc b/lib/Drupal/node/Plugin/views/filter/views_handler_filter_node_access.inc
new file mode 100644
index 000000000000..ba0490a79b01
--- /dev/null
+++ b/lib/Drupal/node/Plugin/views/filter/views_handler_filter_node_access.inc
@@ -0,0 +1,43 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_filter_node_access.
+ */
+
+use Drupal\views\Plugins\views\filter\FilterPluginBase;
+
+
+/**
+ * Filter by node_access records.
+ *
+ * @ingroup views_filter_handlers
+ */
+class views_handler_filter_node_access extends FilterPluginBase {
+  function admin_summary() { }
+  function operator_form(&$form, &$form_state) { }
+  function can_expose() {
+    return FALSE;
+  }
+
+  /**
+   * See _node_access_where_sql() for a non-views query based implementation.
+   */
+  function query() {
+    if (!user_access('administer nodes')) {
+      $table = $this->ensure_my_table();
+      $grants = db_or();
+      foreach (node_access_grants('view') as $realm => $gids) {
+        foreach ($gids as $gid) {
+          $grants->condition(db_and()
+            ->condition($table . '.gid', $gid)
+            ->condition($table . '.realm', $realm)
+          );
+        }
+      }
+
+      $this->query->add_where('AND', $grants);
+      $this->query->add_where('AND', $table . '.grant_view', 1, '>=');
+    }
+  }
+}
diff --git a/lib/Drupal/node/Plugin/views/filter/views_handler_filter_node_type.inc b/lib/Drupal/node/Plugin/views/filter/views_handler_filter_node_type.inc
new file mode 100644
index 000000000000..48a69e11f34c
--- /dev/null
+++ b/lib/Drupal/node/Plugin/views/filter/views_handler_filter_node_type.inc
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_filter_node_type.
+ */
+
+use Drupal\views\Plugins\views\filter\InOperator;
+
+/**
+ * Filter by node type.
+ *
+ * @ingroup views_filter_handlers
+ */
+class views_handler_filter_node_type extends InOperator {
+  function get_value_options() {
+    if (!isset($this->value_options)) {
+      $this->value_title = t('Content types');
+      $types = node_type_get_types();
+      $options = array();
+      foreach ($types as $type => $info) {
+        $options[$type] = t($info->name);
+      }
+      asort($options);
+      $this->value_options = $options;
+    }
+  }
+}
diff --git a/lib/Drupal/node/Plugin/views/filter/views_handler_filter_node_uid_revision.inc b/lib/Drupal/node/Plugin/views/filter/views_handler_filter_node_uid_revision.inc
new file mode 100644
index 000000000000..4d3d9a70cc62
--- /dev/null
+++ b/lib/Drupal/node/Plugin/views/filter/views_handler_filter_node_uid_revision.inc
@@ -0,0 +1,25 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_filter_node_uid_revision.
+ */
+
+/**
+ * Filter handler to check for revisions a certain user has created.
+ *
+ * @ingroup views_filter_handlers
+ */
+class views_handler_filter_node_uid_revision extends views_handler_filter_user_name {
+  function query($group_by = FALSE) {
+    $this->ensure_my_table();
+
+    $placeholder = $this->placeholder();
+
+    $args = array_values($this->value);
+
+    $this->query->add_where_expression($this->options['group'], "$this->table_alias.uid IN($placeholder) " . $condition . " OR
+      ((SELECT COUNT(*) FROM {node_revision} nr WHERE nr.uid IN($placeholder) AND nr.nid = $this->table_alias.nid) > 0)", array($placeholder => $args),
+      $args);
+  }
+}
diff --git a/lib/Drupal/node/Plugin/views/row/views_plugin_row_node_rss.inc b/lib/Drupal/node/Plugin/views/row/views_plugin_row_node_rss.inc
new file mode 100644
index 000000000000..3d418fb32553
--- /dev/null
+++ b/lib/Drupal/node/Plugin/views/row/views_plugin_row_node_rss.inc
@@ -0,0 +1,176 @@
+<?php
+
+/**
+ * @file
+ * Contains the node RSS row style plugin.
+ */
+
+use Drupal\views\Plugins\views\row\RowPluginBase;
+
+/**
+ * Plugin which performs a node_view on the resulting object
+ * and formats it as an RSS item.
+ */
+class views_plugin_row_node_rss extends RowPluginBase {
+  // Basic properties that let the row style follow relationships.
+  var $base_table = 'node';
+  var $base_field = 'nid';
+
+  // Stores the nodes loaded with pre_render.
+  var $nodes = array();
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['item_length'] = array('default' => 'default');
+    $options['links'] = array('default' => FALSE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  /**
+   * Override init function to convert fulltext view-mode to full.
+   */
+  function init(&$view, &$display, $options = NULL) {
+    parent::init($view, $display, $options);
+
+    if ($this->options['item_length'] == 'fulltext') {
+      $this->options['item_length'] = 'full';
+    }
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $form['item_length'] = array(
+      '#type' => 'select',
+      '#title' => t('Display type'),
+      '#options' => $this->options_form_summary_options(),
+      '#default_value' => $this->options['item_length'],
+    );
+    $form['links'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Display links'),
+      '#default_value' => $this->options['links'],
+    );
+  }
+
+  /**
+   * Return the main options, which are shown in the summary title.
+   */
+  function options_form_summary_options() {
+    $entity_info = entity_get_info('node');
+    $options = array();
+    if (!empty($entity_info['view modes'])) {
+      foreach ($entity_info['view modes'] as $mode => $settings) {
+        $options[$mode] = $settings['label'];
+      }
+    }
+    $options['title'] = t('Title only');
+    $options['default'] = t('Use site default RSS settings');
+    return $options;
+  }
+
+  function summary_title() {
+    $options = $this->options_form_summary_options();
+    return check_plain($options[$this->options['item_length']]);
+  }
+
+
+  function pre_render($values) {
+    $nids = array();
+    foreach ($values as $row) {
+      $nids[] = $row->{$this->field_alias};
+    }
+    if (!empty($nids)) {
+      $this->nodes = node_load_multiple($nids);
+    }
+  }
+
+  function render($row) {
+    // For the most part, this code is taken from node_feed() in node.module
+    global $base_url;
+
+    $nid = $row->{$this->field_alias};
+    if (!is_numeric($nid)) {
+      return;
+    }
+
+    $display_mode = $this->options['item_length'];
+    if ($display_mode == 'default') {
+      $display_mode = variable_get('feed_item_length', 'teaser');
+    }
+
+    // Load the specified node:
+    $node = $this->nodes[$nid];
+    if (empty($node)) {
+      return;
+    }
+
+    $item_text = '';
+
+    $uri = $node->uri();
+    $node->link = url($uri['path'], $uri['options'] + array('absolute' => TRUE));
+    $node->rss_namespaces = array();
+    $node->rss_elements = array(
+      array(
+        'key' => 'pubDate',
+        'value' => gmdate('r', $node->created),
+      ),
+      array(
+        'key' => 'dc:creator',
+        'value' => $node->name,
+      ),
+      array(
+        'key' => 'guid',
+        'value' => $node->nid . ' at ' . $base_url,
+        'attributes' => array('isPermaLink' => 'false'),
+      ),
+    );
+
+    // The node gets built and modules add to or modify $node->rss_elements
+    // and $node->rss_namespaces.
+
+    $build_mode = $display_mode;
+
+    $build = node_view($node, $build_mode);
+    unset($build['#theme']);
+
+    if (!empty($node->rss_namespaces)) {
+      $this->view->style_plugin->namespaces = array_merge($this->view->style_plugin->namespaces, $node->rss_namespaces);
+    }
+    elseif (function_exists('rdf_get_namespaces')) {
+      // Merge RDF namespaces in the XML namespaces in case they are used
+      // further in the RSS content.
+      $xml_rdf_namespaces = array();
+      foreach (rdf_get_namespaces() as $prefix => $uri) {
+        $xml_rdf_namespaces['xmlns:' . $prefix] = $uri;
+      }
+      $this->view->style_plugin->namespaces += $xml_rdf_namespaces;
+    }
+
+    // Hide the links if desired.
+    if (!$this->options['links']) {
+      hide($build['links']);
+    }
+
+    if ($display_mode != 'title') {
+      // We render node contents and force links to be last.
+      $build['links']['#weight'] = 1000;
+      $item_text .= drupal_render($build);
+    }
+
+    $item = new stdClass();
+    $item->description = $item_text;
+    $item->title = $node->title;
+    $item->link = $node->link;
+    $item->elements = $node->rss_elements;
+    $item->nid = $node->nid;
+
+    return theme($this->theme_functions(), array(
+      'view' => $this->view,
+      'options' => $this->options,
+      'row' => $item
+    ));
+  }
+}
diff --git a/lib/Drupal/node/Plugin/views/row/views_plugin_row_node_view.inc b/lib/Drupal/node/Plugin/views/row/views_plugin_row_node_view.inc
new file mode 100644
index 000000000000..1ae2008a5b2b
--- /dev/null
+++ b/lib/Drupal/node/Plugin/views/row/views_plugin_row_node_view.inc
@@ -0,0 +1,110 @@
+<?php
+
+/**
+ * @file
+ * Contains the node view row style plugin.
+ */
+
+use Drupal\views\Plugins\views\row\RowPluginBase;
+
+/**
+ * Plugin which performs a node_view on the resulting object.
+ *
+ * Most of the code on this object is in the theme function.
+ *
+ * @ingroup views_row_plugins
+ */
+class views_plugin_row_node_view extends RowPluginBase {
+  // Basic properties that let the row style follow relationships.
+  var $base_table = 'node';
+  var $base_field = 'nid';
+
+  // Stores the nodes loaded with pre_render.
+  var $nodes = array();
+
+  function init(&$view, &$display, $options = NULL) {
+    parent::init($view, $display, $options);
+    // Handle existing views with the deprecated 'teaser' option.
+    if (isset($this->options['teaser'])) {
+      $this->options['build_mode'] = $this->options['teaser'] ? 'teaser' : 'full';
+    }
+    // Handle existing views which has used build_mode instead of view_mode.
+    if (isset($this->options['build_mode'])) {
+      $this->options['view_mode'] = $this->options['build_mode'];
+    }
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['view_mode'] = array('default' => 'teaser');
+    $options['links'] = array('default' => TRUE, 'bool' => TRUE);
+    $options['comments'] = array('default' => FALSE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $options = $this->options_form_summary_options();
+    $form['view_mode'] = array(
+      '#type' => 'select',
+      '#options' => $options,
+      '#title' => t('View mode'),
+      '#default_value' => $this->options['view_mode'],
+     );
+    $form['links'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Display links'),
+      '#default_value' => $this->options['links'],
+    );
+    $form['comments'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Display comments'),
+      '#default_value' => $this->options['comments'],
+    );
+  }
+
+  /**
+   * Return the main options, which are shown in the summary title.
+   */
+  function options_form_summary_options() {
+    $entity_info = entity_get_info('node');
+    $options = array();
+    if (!empty($entity_info['view modes'])) {
+      foreach ($entity_info['view modes'] as $mode => $settings) {
+        $options[$mode] = $settings['label'];
+      }
+    }
+    if (empty($options)) {
+      $options = array(
+        'teaser' => t('Teaser'),
+        'full' => t('Full content')
+      );
+    }
+
+    return $options;
+  }
+
+  function summary_title() {
+    $options = $this->options_form_summary_options();
+    return check_plain($options[$this->options['view_mode']]);
+  }
+
+  function pre_render($values) {
+    $nids = array();
+    foreach ($values as $row) {
+      $nids[] = $row->{$this->field_alias};
+    }
+    $this->nodes = node_load_multiple($nids);
+  }
+
+  function render($row) {
+    $node = $this->nodes[$row->{$this->field_alias}];
+    $node->view = $this->view;
+    $build = node_view($node, $this->options['view_mode']);
+
+    return drupal_render($build);
+  }
+}
diff --git a/lib/Drupal/search/Plugin/views/argument/views_handler_argument_search.inc b/lib/Drupal/search/Plugin/views/argument/views_handler_argument_search.inc
new file mode 100644
index 000000000000..64175e500b74
--- /dev/null
+++ b/lib/Drupal/search/Plugin/views/argument/views_handler_argument_search.inc
@@ -0,0 +1,103 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_argument_search.
+ */
+
+use Drupal\views\Join;
+use Drupal\views\Plugins\views\argument\ArgumentPluginBase;
+
+/**
+ * Argument that accepts query keys for search.
+ *
+ * @ingroup views_argument_handlers
+ */
+class views_handler_argument_search extends views_handler_argument {
+
+  /**
+   * Take sure that parseSearchExpression is runned and everything is set up for it.
+   *
+   * @param $input
+   *    The search phrase which was input by the user.
+   */
+  function query_parse_search_expression($input) {
+    if (!isset($this->search_query)) {
+      $this->search_query = db_select('search_index', 'i', array('target' => 'slave'))->extend('viewsSearchQuery');
+      $this->search_query->searchExpression($input, $this->view->base_table);
+      $this->search_query->publicParseSearchExpression();
+    }
+  }
+
+  /**
+   * Add this argument to the query.
+   */
+  function query($group_by = FALSE) {
+    $required = FALSE;
+    $this->query_parse_search_expression($this->argument);
+    if (!isset($this->search_query)) {
+      $required = TRUE;
+    }
+    else {
+      $words = $this->search_query->words();
+      if (empty($words)) {
+        $required = TRUE;
+      }
+    }
+    if ($required) {
+      if ($this->operator == 'required') {
+        $this->query->add_where(0, 'FALSE');
+      }
+    }
+    else {
+      $search_index = $this->ensure_my_table();
+
+      $search_condition = db_and();
+
+      // Create a new join to relate the 'search_total' table to our current 'search_index' table.
+      $join = new Join();
+      $join->construct('search_total', $search_index, 'word', 'word');
+      $search_total = $this->query->add_relationship('search_total', $join, $search_index);
+
+      $this->search_score = $this->query->add_field('', "SUM($search_index.score * $search_total.count)", 'score', array('aggregate' => TRUE));
+
+      if (empty($this->query->relationships[$this->relationship])) {
+        $base_table = $this->query->base_table;
+      }
+      else {
+        $base_table = $this->query->relationships[$this->relationship]['base'];
+      }
+      $search_condition->condition("$search_index.type", $base_table);
+
+      if (!$this->search_query->simple()) {
+        $search_dataset = $this->query->add_table('search_dataset');
+        $conditions = $this->search_query->conditions();
+        $condition_conditions =& $conditions->conditions();
+        foreach ($condition_conditions  as $key => &$condition) {
+          // Take sure we just look at real conditions.
+          if (is_numeric($key)) {
+            // Replace the conditions with the table alias of views.
+            $this->search_query->condition_replace_string('d.', "$search_dataset.", $condition);
+          }
+        }
+        $search_conditions =& $search_condition->conditions();
+        $search_conditions = array_merge($search_conditions, $condition_conditions);
+      }
+      else {
+        // Stores each condition, so and/or on the filter level will still work.
+        $or = db_or();
+        foreach ($words as $word) {
+          $or->condition("$search_index.word", $word);
+        }
+
+        $search_condition->condition($or);
+      }
+
+      $this->query->add_where(0, $search_condition);
+      $this->query->add_groupby("$search_index.sid");
+      $matches = $this->search_query->matches();
+      $placeholder = $this->placeholder();
+      $this->query->add_having_expression(0, "COUNT(*) >= $placeholder", array($placeholder => $matches));
+    }
+  }
+}
diff --git a/lib/Drupal/search/Plugin/views/field/views_handler_field_search_score.inc b/lib/Drupal/search/Plugin/views/field/views_handler_field_search_score.inc
new file mode 100644
index 000000000000..97a25c0d33f8
--- /dev/null
+++ b/lib/Drupal/search/Plugin/views/field/views_handler_field_search_score.inc
@@ -0,0 +1,83 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_search_score.
+ */
+
+use Drupal\views\Plugins\views\field\Numeric;
+
+/**
+ * Field handler to provide simple renderer that allows linking to a node.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_search_score extends Numeric {
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['alternate_sort'] = array('default' => '');
+    $options['alternate_order'] = array('default' => 'asc');
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $style_options = $this->view->display_handler->get_option('style_options');
+    if (isset($style_options['default']) && $style_options['default'] == $this->options['id']) {
+      $handlers = $this->view->display_handler->get_handlers('field');
+      $options = array('' => t('No alternate'));
+      foreach ($handlers as $id => $handler) {
+        $options[$id] = $handler->ui_name();
+      }
+
+      $form['alternate_sort'] = array(
+        '#type' => 'select',
+        '#title' => t('Alternative sort'),
+        '#description' => t('Pick an alternative default table sort field to use when the search score field is unavailable.'),
+        '#options' => $options,
+        '#default_value' => $this->options['alternate_sort'],
+      );
+
+      $form['alternate_order'] = array(
+        '#type' => 'select',
+        '#title' => t('Alternate sort order'),
+        '#options' => array('asc' => t('Ascending'), 'desc' => t('Descending')),
+        '#default_value' => $this->options['alternate_order'],
+      );
+    }
+
+    parent::options_form($form, $form_state);
+  }
+
+  function query() {
+    // Check to see if the search filter added 'score' to the table.
+    // Our filter stores it as $handler->search_score -- and we also
+    // need to check its relationship to make sure that we're using the same
+    // one or obviously this won't work.
+    foreach ($this->view->filter as $handler) {
+      if (isset($handler->search_score) && $handler->relationship == $this->relationship) {
+        $this->field_alias = $handler->search_score;
+        $this->table_alias = $handler->table_alias;
+        return;
+      }
+    }
+
+    // Hide this field if no search filter is in place.
+    $this->options['exclude'] = TRUE;
+    if (!empty($this->options['alternate_sort'])) {
+      if (isset($this->view->style_plugin->options['default']) && $this->view->style_plugin->options['default'] == $this->options['id']) {
+        // Since the style handler initiates fields, we plug these values right into the active handler.
+        $this->view->style_plugin->options['default'] = $this->options['alternate_sort'];
+        $this->view->style_plugin->options['order'] = $this->options['alternate_order'];
+      }
+    }
+  }
+
+  function render($values) {
+    // Only render if we exist.
+    if (isset($this->table_alias)) {
+      return parent::render($values);
+    }
+  }
+}
diff --git a/lib/Drupal/search/Plugin/views/filter/views_handler_filter_search.inc b/lib/Drupal/search/Plugin/views/filter/views_handler_filter_search.inc
new file mode 100644
index 000000000000..948361e52b8a
--- /dev/null
+++ b/lib/Drupal/search/Plugin/views/filter/views_handler_filter_search.inc
@@ -0,0 +1,220 @@
+<?php
+
+/**
+ * @file
+ * Contains a search filter handler.
+ */
+
+use Drupal\views\Join;
+use Drupal\search\SearchQuery;
+use Drupal\views\Plugins\views\filter\FilterPluginBase;
+
+/**
+ * Field handler to provide simple renderer that allows linking to a node.
+ *
+ * @ingroup views_filter_handlers
+ */
+class views_handler_filter_search extends FilterPluginBase {
+  var $always_multiple = TRUE;
+
+  /**
+   * Stores a viewsSearchQuery object to be able to use the search.module "api".
+   *
+   * @var viewsSearchQuery
+   */
+  var $search_query = NULL;
+
+  /**
+   * Checks if the search query has been parsed.
+   */
+  var $parsed = FALSE;
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['operator']['default'] = 'optional';
+
+    return $options;
+  }
+
+  /**
+   * Provide simple equality operator
+   */
+  function operator_form(&$form, &$form_state) {
+    $form['operator'] = array(
+      '#type' => 'radios',
+      '#title' => t('On empty input'),
+      '#default_value' => $this->operator,
+      '#options' => array(
+        'optional' => t('Show All'),
+        'required' => t('Show None'),
+      ),
+    );
+  }
+
+  /**
+   * Provide a simple textfield for equality
+   */
+  function value_form(&$form, &$form_state) {
+    $form['value'] = array(
+      '#type' => 'textfield',
+      '#size' => 15,
+      '#default_value' => $this->value,
+      '#attributes' => array('title' => t('Enter the terms you wish to search for.')),
+      '#title' => empty($form_state['exposed']) ? t('Value') : '',
+    );
+  }
+
+  /**
+   * Validate the options form.
+   */
+  function exposed_validate(&$form, &$form_state) {
+    if (!isset($this->options['expose']['identifier'])) {
+      return;
+    }
+
+    $key = $this->options['expose']['identifier'];
+    if (!empty($form_state['values'][$key])) {
+      $this->query_parse_search_expression($form_state['values'][$key]);
+      if (count($this->search_query->words()) == 0) {
+        form_set_error($key, format_plural(variable_get('minimum_word_size', 3), 'You must include at least one positive keyword with 1 character or more.', 'You must include at least one positive keyword with @count characters or more.'));
+      }
+    }
+  }
+
+  /**
+   * Take sure that parseSearchExpression is runned and everything is set up for it.
+   *
+   * @param $input
+   *    The search phrase which was input by the user.
+   */
+  function query_parse_search_expression($input) {
+    if (!isset($this->search_query)) {
+      $this->parsed = TRUE;
+      $this->search_query = db_select('search_index', 'i', array('target' => 'slave'))->extend('viewsSearchQuery');
+      $this->search_query->searchExpression($input, $this->view->base_table);
+      $this->search_query->publicParseSearchExpression();
+    }
+  }
+
+  /**
+   * Add this filter to the query.
+   *
+   * Due to the nature of fapi, the value and the operator have an unintended
+   * level of indirection. You will find them in $this->operator
+   * and $this->value respectively.
+   */
+  function query() {
+    // Since attachment views don't validate the exposed input, parse the search
+    // expression if required.
+    if (!$this->parsed) {
+      $this->query_parse_search_expression($this->value);
+    }
+    $required = FALSE;
+    if (!isset($this->search_query)) {
+      $required = TRUE;
+    }
+    else {
+      $words = $this->search_query->words();
+      if (empty($words)) {
+        $required = TRUE;
+      }
+    }
+    if ($required) {
+      if ($this->operator == 'required') {
+        $this->query->add_where($this->options['group'], 'FALSE');
+      }
+    }
+    else {
+      $search_index = $this->ensure_my_table();
+
+      $search_condition = db_and();
+
+      // Create a new join to relate the 'serach_total' table to our current 'search_index' table.
+      $join = new Join();
+      $join->construct('search_total', $search_index, 'word', 'word');
+      $search_total = $this->query->add_relationship('search_total', $join, $search_index);
+
+      $this->search_score = $this->query->add_field('', "SUM($search_index.score * $search_total.count)", 'score', array('aggregate' => TRUE));
+
+      if (empty($this->query->relationships[$this->relationship])) {
+        $base_table = $this->query->base_table;
+      }
+      else {
+        $base_table = $this->query->relationships[$this->relationship]['base'];
+      }
+      $search_condition->condition("$search_index.type", $base_table);
+      if (!$this->search_query->simple()) {
+        $search_dataset = $this->query->add_table('search_dataset');
+        $conditions = $this->search_query->conditions();
+        $condition_conditions =& $conditions->conditions();
+        foreach ($condition_conditions  as $key => &$condition) {
+          // Take sure we just look at real conditions.
+          if (is_numeric($key)) {
+            // Replace the conditions with the table alias of views.
+            $this->search_query->condition_replace_string('d.', "$search_dataset.", $condition);
+          }
+        }
+        $search_conditions =& $search_condition->conditions();
+        $search_conditions = array_merge($search_conditions, $condition_conditions);
+      }
+      else {
+        // Stores each condition, so and/or on the filter level will still work.
+        $or = db_or();
+        foreach ($words as $word) {
+          $or->condition("$search_index.word", $word);
+        }
+
+        $search_condition->condition($or);
+      }
+
+      $this->query->add_where($this->options['group'], $search_condition);
+      $this->query->add_groupby("$search_index.sid");
+      $matches = $this->search_query->matches();
+      $placeholder = $this->placeholder();
+      $this->query->add_having_expression($this->options['group'], "COUNT(*) >= $placeholder", array($placeholder => $matches));
+    }
+    // Set to NULL to prevent PDO exception when views object is cached.
+    $this->search_query = NULL;
+  }
+}
+
+/**
+ * Extends the core SearchQuery.
+ *
+ * @todo: Make this class PSR-0 compatible.
+ */
+class viewsSearchQuery extends SearchQuery {
+  public function &conditions() {
+    return $this->conditions;
+  }
+  public function words() {
+    return $this->words;
+  }
+
+  public function simple() {
+    return $this->simple;
+  }
+
+  public function matches() {
+    return $this->matches;
+  }
+
+  public function publicParseSearchExpression() {
+    return $this->parseSearchExpression();
+  }
+
+  function condition_replace_string($search, $replace, &$condition) {
+    if ($condition['field'] instanceof DatabaseCondition) {
+      $conditions =& $condition['field']->conditions();
+      foreach ($conditions as $key => &$subcondition) {
+        if (is_numeric($key)) {
+          $this->condition_replace_string($search, $replace, $subcondition);
+        }
+      }
+    }
+    else {
+      $condition['field'] = str_replace($search, $replace, $condition['field']);
+    }
+  }
+}
diff --git a/lib/Drupal/search/Plugin/views/row/views_plugin_row_search_view.inc b/lib/Drupal/search/Plugin/views/row/views_plugin_row_search_view.inc
new file mode 100644
index 000000000000..b33852aea8f2
--- /dev/null
+++ b/lib/Drupal/search/Plugin/views/row/views_plugin_row_search_view.inc
@@ -0,0 +1,41 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_plugin_row_search_view.
+ */
+
+use Drupal\views\Plugins\views\row\RowPluginBase;
+
+/**
+ * Plugin which performs a node_view on the resulting object.
+ */
+class views_plugin_row_search_view extends RowPluginBase {
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['score'] = array('default' => TRUE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['score'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Display score'),
+      '#default_value' => $this->options['score'],
+    );
+  }
+
+  /**
+   * Override the behavior of the render() function.
+   */
+  function render($row) {
+    return theme($this->theme_functions(),
+      array(
+        'view' => $this->view,
+        'options' => $this->options,
+        'row' => $row
+      ));
+  }
+}
diff --git a/lib/Drupal/search/Plugin/views/sort/views_handler_sort_search_score.inc b/lib/Drupal/search/Plugin/views/sort/views_handler_sort_search_score.inc
new file mode 100644
index 000000000000..0282f69ec4b0
--- /dev/null
+++ b/lib/Drupal/search/Plugin/views/sort/views_handler_sort_search_score.inc
@@ -0,0 +1,41 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_sort_search_score.
+ */
+
+use Drupal\views\Plugins\views\sort\SortPluginBase;
+use Drupal\Core\Annotation\Plugin;
+
+/**
+ * Field handler to provide simple renderer that allows linking to a node.
+ *
+ * @ingroup views_sort_handlers
+ */
+
+/**
+ * @Plugin(
+ *   plugin_id = "search_score"
+ * )
+ */
+class views_handler_sort_search_score extends SortPluginBase {
+  function query() {
+    // Check to see if the search filter/argument added 'score' to the table.
+    // Our filter stores it as $handler->search_score -- and we also
+    // need to check its relationship to make sure that we're using the same
+    // one or obviously this won't work.
+    foreach (array('filter', 'argument') as $type) {
+      foreach ($this->view->{$type} as $handler) {
+        if (isset($handler->search_score) && $handler->relationship == $this->relationship) {
+          $this->query->add_orderby(NULL, NULL, $this->options['order'], $handler->search_score);
+          $this->table_alias = $handler->table_alias;
+          return;
+        }
+      }
+    }
+
+    // Do absolutely nothing if there is no filter/argument in place; there is no reason to
+    // sort on the raw scores with this handler.
+  }
+}
diff --git a/lib/Drupal/statistics/Plugin/views/field/views_handler_field_accesslog_path.inc b/lib/Drupal/statistics/Plugin/views/field/views_handler_field_accesslog_path.inc
new file mode 100644
index 000000000000..3ab613a51b27
--- /dev/null
+++ b/lib/Drupal/statistics/Plugin/views/field/views_handler_field_accesslog_path.inc
@@ -0,0 +1,60 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_accesslog_path.
+ */
+
+use Drupal\views\Plugins\views\field\FieldPluginBase;
+
+/**
+ * Field handler to provide simple renderer that turns a URL into a clickable link.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_accesslog_path extends FieldPluginBase {
+  /**
+   * Override init function to provide generic option to link to node.
+   */
+  function init(&$view, &$options) {
+    parent::init($view, $options);
+    if (!empty($this->options['display_as_link'])) {
+      $this->additional_fields['path'] = 'path';
+    }
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['display_as_link'] = array('default' => TRUE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  /**
+   * Provide link to the page being visited.
+   */
+  function options_form(&$form, &$form_state) {
+    $form['display_as_link'] = array(
+      '#title' => t('Display as link'),
+      '#type' => 'checkbox',
+      '#default_value' => !empty($this->options['display_as_link']),
+    );
+    parent::options_form($form, $form_state);
+  }
+
+  function render($values) {
+    $value = $this->get_value($values);
+    return $this->render_link($this->sanitize_value($value), $values);
+  }
+
+  function render_link($data, $values) {
+    if (!empty($this->options['display_as_link'])) {
+      $this->options['alter']['make_link'] = TRUE;
+      $this->options['alter']['path'] = $this->get_value($values, 'path');
+      $this->options['alter']['html'] = TRUE;
+    }
+
+    return $data;
+  }
+}
diff --git a/lib/Drupal/system/Plugin/views/argument/views_handler_argument_file_fid.inc b/lib/Drupal/system/Plugin/views/argument/views_handler_argument_file_fid.inc
new file mode 100644
index 000000000000..aa2d94719353
--- /dev/null
+++ b/lib/Drupal/system/Plugin/views/argument/views_handler_argument_file_fid.inc
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_argument_file_fid.
+ */
+
+/**
+ * Argument handler to accept multiple file ids.
+ *
+ * @ingroup views_argument_handlers
+ */
+class views_handler_argument_file_fid extends views_handler_argument_numeric {
+  /**
+   * Override the behavior of title_query(). Get the filenames.
+   */
+  function title_query() {
+    $titles = db_select('file_managed', 'f')
+      ->fields('f', array('filename'))
+      ->condition('fid', $this->value)
+      ->execute()
+      ->fetchCol();
+    foreach ($titles as &$title) {
+      $title = check_plain($title);
+    }
+    return $titles;
+  }
+}
diff --git a/lib/Drupal/system/Plugin/views/field/views_handler_field_file.inc b/lib/Drupal/system/Plugin/views/field/views_handler_field_file.inc
new file mode 100644
index 000000000000..4168acf759f1
--- /dev/null
+++ b/lib/Drupal/system/Plugin/views/field/views_handler_field_file.inc
@@ -0,0 +1,61 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_file.
+ */
+
+/**
+ * Field handler to provide simple renderer that allows linking to a file.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_file extends views_handler_field {
+  /**
+   * Constructor to provide additional field to add.
+   */
+  function init(&$view, &$options) {
+    parent::init($view, $options);
+    if (!empty($options['link_to_file'])) {
+      $this->additional_fields['uri'] = 'uri';
+    }
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['link_to_file'] = array('default' => FALSE, 'bool' => TRUE);
+    return $options;
+  }
+
+  /**
+   * Provide link to file option
+   */
+  function options_form(&$form, &$form_state) {
+    $form['link_to_file'] = array(
+      '#title' => t('Link this field to download the file'),
+      '#description' => t("Enable to override this field's links."),
+      '#type' => 'checkbox',
+      '#default_value' => !empty($this->options['link_to_file']),
+    );
+    parent::options_form($form, $form_state);
+  }
+
+  /**
+   * Render whatever the data is as a link to the file.
+   *
+   * Data should be made XSS safe prior to calling this function.
+   */
+  function render_link($data, $values) {
+    if (!empty($this->options['link_to_file']) && $data !== NULL && $data !== '') {
+      $this->options['alter']['make_link'] = TRUE;
+      $this->options['alter']['path'] = file_create_url($this->get_value($values, 'uri'));
+    }
+
+    return $data;
+  }
+
+  function render($values) {
+    $value = $this->get_value($values);
+    return $this->render_link($this->sanitize_value($value), $values);
+  }
+}
diff --git a/lib/Drupal/system/Plugin/views/field/views_handler_field_file_extension.inc b/lib/Drupal/system/Plugin/views/field/views_handler_field_file_extension.inc
new file mode 100644
index 000000000000..6f9a03fe32fd
--- /dev/null
+++ b/lib/Drupal/system/Plugin/views/field/views_handler_field_file_extension.inc
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_file_extension.
+ */
+
+/**
+ * Returns a pure file extension of the file, for example 'module'.
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_file_extension extends views_handler_field {
+  function render($values) {
+    $value = $this->get_value($values);
+    if (preg_match('/\.([^\.]+)$/', $value, $match)) {
+      return $this->sanitize_value($match[1]);
+    }
+  }
+}
diff --git a/lib/Drupal/system/Plugin/views/field/views_handler_field_file_filemime.inc b/lib/Drupal/system/Plugin/views/field/views_handler_field_file_filemime.inc
new file mode 100644
index 000000000000..318fdcff3222
--- /dev/null
+++ b/lib/Drupal/system/Plugin/views/field/views_handler_field_file_filemime.inc
@@ -0,0 +1,38 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_file_filemime.
+ */
+
+/**
+ * Field handler to add rendering MIME type images as an option on the filemime field.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_file_filemime extends views_handler_field_file {
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['filemime_image'] = array('default' => FALSE, 'bool' => TRUE);
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['filemime_image'] = array(
+      '#title' => t('Display an icon representing the file type, instead of the MIME text (such as "image/jpeg")'),
+      '#type' => 'checkbox',
+      '#default_value' => !empty($this->options['filemime_image']),
+    );
+    parent::options_form($form, $form_state);
+  }
+
+  function render($values) {
+    $data = $values->{$this->field_alias};
+    if (!empty($this->options['filemime_image']) && $data !== NULL && $data !== '') {
+      $fake_file = (object) array('filemime' => $data);
+      $data = theme('file_icon', array('file' => $fake_file));
+    }
+
+    return $this->render_link($data, $values);
+  }
+}
diff --git a/lib/Drupal/system/Plugin/views/field/views_handler_field_file_status.inc b/lib/Drupal/system/Plugin/views/field/views_handler_field_file_status.inc
new file mode 100644
index 000000000000..ac1022c8d905
--- /dev/null
+++ b/lib/Drupal/system/Plugin/views/field/views_handler_field_file_status.inc
@@ -0,0 +1,18 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_file_status.
+ */
+
+/**
+ * Field handler to translate a node type into its readable form.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_file_status extends views_handler_field {
+  function render($values) {
+    $value = $this->get_value($values);
+    return _views_file_status($value);
+  }
+}
diff --git a/lib/Drupal/system/Plugin/views/field/views_handler_field_file_uri.inc b/lib/Drupal/system/Plugin/views/field/views_handler_field_file_uri.inc
new file mode 100644
index 000000000000..334e5051aac6
--- /dev/null
+++ b/lib/Drupal/system/Plugin/views/field/views_handler_field_file_uri.inc
@@ -0,0 +1,35 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_file_uri.
+ */
+
+/**
+ * Field handler to add rendering file paths as file URLs instead of as internal file URIs.
+ */
+class views_handler_field_file_uri extends views_handler_field_file {
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['file_download_path'] = array('default' => FALSE, 'bool' => TRUE);
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['file_download_path'] = array(
+      '#title' => t('Display download path instead of file storage URI'),
+      '#description' => t('This will provide the full download URL rather than the internal filestream address.'),
+      '#type' => 'checkbox',
+      '#default_value' => !empty($this->options['file_download_path']),
+    );
+    parent::options_form($form, $form_state);
+  }
+
+  function render($values) {
+    $data = $values->{$this->field_alias};
+    if (!empty($this->options['file_download_path']) && $data !== NULL && $data !== '') {
+      $data = file_create_url($data);
+    }
+    return $this->render_link($data, $values);
+  }
+}
diff --git a/lib/Drupal/system/Plugin/views/filter/views_handler_filter_file_status.inc b/lib/Drupal/system/Plugin/views/filter/views_handler_filter_file_status.inc
new file mode 100644
index 000000000000..6194395bfac1
--- /dev/null
+++ b/lib/Drupal/system/Plugin/views/filter/views_handler_filter_file_status.inc
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_filter_file_status.
+ */
+
+/**
+ * Filter by file status.
+ *
+ * @ingroup views_filter_handlers
+ */
+class views_handler_filter_file_status extends views_handler_filter_in_operator {
+  function get_value_options() {
+    if (!isset($this->value_options)) {
+      $this->value_options = _views_file_status();
+    }
+  }
+}
diff --git a/lib/Drupal/system/Plugin/views/filter/views_handler_filter_system_type.inc b/lib/Drupal/system/Plugin/views/filter/views_handler_filter_system_type.inc
new file mode 100644
index 000000000000..84d4bcd86ce9
--- /dev/null
+++ b/lib/Drupal/system/Plugin/views/filter/views_handler_filter_system_type.inc
@@ -0,0 +1,21 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_filter_system_type.
+ */
+
+/**
+ * Filter by system type.
+ */
+class views_handler_filter_system_type extends views_handler_filter_in_operator {
+  function get_value_options() {
+    if (!isset($this->value_options)) {
+      $this->value_title = t('Type');
+      // Enable filtering by type.
+      $types = array();
+      $types = db_query('SELECT DISTINCT(type) FROM {system} ORDER BY type')->fetchAllKeyed(0, 0);
+      $this->value_options = $types;
+    }
+  }
+}
diff --git a/lib/Drupal/taxonomy/Plugin/views/argument/views_handler_argument_taxonomy.inc b/lib/Drupal/taxonomy/Plugin/views/argument/views_handler_argument_taxonomy.inc
new file mode 100644
index 000000000000..10fc500b37f9
--- /dev/null
+++ b/lib/Drupal/taxonomy/Plugin/views/argument/views_handler_argument_taxonomy.inc
@@ -0,0 +1,29 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_argument_taxonomy.
+ */
+
+/**
+ * Argument handler for basic taxonomy tid.
+ *
+ * @ingroup views_argument_handlers
+ */
+class views_handler_argument_taxonomy extends views_handler_argument_numeric {
+
+  /**
+   * Override the behavior of title(). Get the title of the node.
+   */
+  function title() {
+    // There might be no valid argument.
+    if ($this->argument) {
+      $term = taxonomy_term_load($this->argument);
+      if (!empty($term)) {
+        return check_plain($term->name);
+      }
+    }
+    // TODO review text
+    return t('No name');
+  }
+}
diff --git a/lib/Drupal/taxonomy/Plugin/views/argument/views_handler_argument_term_node_tid.inc b/lib/Drupal/taxonomy/Plugin/views/argument/views_handler_argument_term_node_tid.inc
new file mode 100644
index 000000000000..f47f08a85a30
--- /dev/null
+++ b/lib/Drupal/taxonomy/Plugin/views/argument/views_handler_argument_term_node_tid.inc
@@ -0,0 +1,49 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_argument_term_node_tid.
+ */
+
+/**
+ * Allow taxonomy term ID(s) as argument.
+ *
+ * @ingroup views_argument_handlers
+ */
+class views_handler_argument_term_node_tid extends views_handler_argument_many_to_one {
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['set_breadcrumb'] = array('default' => FALSE, 'bool' => TRUE);
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $form['set_breadcrumb'] = array(
+      '#type' => 'checkbox',
+      '#title' => t("Set the breadcrumb for the term parents"),
+      '#description' => t('If selected, the breadcrumb trail will include all parent terms, each one linking to this view. Note that this only works if just one term was received.'),
+      '#default_value' => !empty($this->options['set_breadcrumb']),
+    );
+  }
+
+  function set_breadcrumb(&$breadcrumb) {
+    if (empty($this->options['set_breadcrumb']) || !is_numeric($this->argument)) {
+      return;
+    }
+
+    return views_taxonomy_set_breadcrumb($breadcrumb, $this);
+  }
+
+  function title_query() {
+    $titles = array();
+    $result = db_select('taxonomy_term_data', 'td')
+      ->fields('td', array('name'))
+      ->condition('td.tid', $this->value)
+      ->execute();
+    foreach ($result as $term) {
+      $titles[] = check_plain($term->name);
+    }
+    return $titles;
+  }
+}
diff --git a/lib/Drupal/taxonomy/Plugin/views/argument/views_handler_argument_term_node_tid_depth.inc b/lib/Drupal/taxonomy/Plugin/views/argument/views_handler_argument_term_node_tid_depth.inc
new file mode 100644
index 000000000000..5b0b34d8f78c
--- /dev/null
+++ b/lib/Drupal/taxonomy/Plugin/views/argument/views_handler_argument_term_node_tid_depth.inc
@@ -0,0 +1,149 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_argument_term_node_tid_depth.
+ */
+
+/**
+ * Argument handler for taxonomy terms with depth.
+ *
+ * This handler is actually part of the node table and has some restrictions,
+ * because it uses a subquery to find nodes with.
+ *
+ * @ingroup views_argument_handlers
+ */
+class views_handler_argument_term_node_tid_depth extends views_handler_argument {
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['depth'] = array('default' => 0);
+    $options['break_phrase'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['set_breadcrumb'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['use_taxonomy_term_path'] = array('default' => FALSE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['depth'] = array(
+      '#type' => 'weight',
+      '#title' => t('Depth'),
+      '#default_value' => $this->options['depth'],
+      '#description' => t('The depth will match nodes tagged with terms in the hierarchy. For example, if you have the term "fruit" and a child term "apple", with a depth of 1 (or higher) then filtering for the term "fruit" will get nodes that are tagged with "apple" as well as "fruit". If negative, the reverse is true; searching for "apple" will also pick up nodes tagged with "fruit" if depth is -1 (or lower).'),
+    );
+
+    $form['break_phrase'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Allow multiple values'),
+      '#description' => t('If selected, users can enter multiple values in the form of 1+2+3. Due to the number of JOINs it would require, AND will be treated as OR with this filter.'),
+      '#default_value' => !empty($this->options['break_phrase']),
+    );
+
+    $form['set_breadcrumb'] = array(
+      '#type' => 'checkbox',
+      '#title' => t("Set the breadcrumb for the term parents"),
+      '#description' => t('If selected, the breadcrumb trail will include all parent terms, each one linking to this view. Note that this only works if just one term was received.'),
+      '#default_value' => !empty($this->options['set_breadcrumb']),
+    );
+
+    $form['use_taxonomy_term_path'] = array(
+      '#type' => 'checkbox',
+      '#title' => t("Use Drupal's taxonomy term path to create breadcrumb links"),
+      '#description' => t('If selected, the links in the breadcrumb trail will be created using the standard drupal method instead of the custom views method. This is useful if you are using modules like taxonomy redirect to modify your taxonomy term links.'),
+      '#default_value' => !empty($this->options['use_taxonomy_term_path']),
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[set_breadcrumb]"]' => array('checked' => TRUE),
+        ),
+      ),
+    );
+    parent::options_form($form, $form_state);
+  }
+
+  function set_breadcrumb(&$breadcrumb) {
+    if (empty($this->options['set_breadcrumb']) || !is_numeric($this->argument)) {
+      return;
+    }
+
+    return views_taxonomy_set_breadcrumb($breadcrumb, $this);
+  }
+
+  /**
+   * Override default_actions() to remove summary actions.
+   */
+  function default_actions($which = NULL) {
+    if ($which) {
+      if (in_array($which, array('ignore', 'not found', 'empty', 'default'))) {
+        return parent::default_actions($which);
+      }
+      return;
+    }
+    $actions = parent::default_actions();
+    unset($actions['summary asc']);
+    unset($actions['summary desc']);
+    unset($actions['summary asc by count']);
+    unset($actions['summary desc by count']);
+    return $actions;
+  }
+
+  function query($group_by = FALSE) {
+    $this->ensure_my_table();
+
+    if (!empty($this->options['break_phrase'])) {
+      $tids = new stdClass();
+      $tids->value = $this->argument;
+      $tids = views_break_phrase($this->argument, $tids);
+      if ($tids->value == array(-1)) {
+        return FALSE;
+      }
+
+      if (count($tids->value) > 1) {
+        $operator = 'IN';
+      }
+      else {
+        $operator = '=';
+      }
+
+      $tids = $tids->value;
+    }
+    else {
+      $operator = "=";
+      $tids = $this->argument;
+    }
+    // Now build the subqueries.
+    $subquery = db_select('taxonomy_index', 'tn');
+    $subquery->addField('tn', 'nid');
+    $where = db_or()->condition('tn.tid', $tids, $operator);
+    $last = "tn";
+
+    if ($this->options['depth'] > 0) {
+      $subquery->leftJoin('taxonomy_term_hierarchy', 'th', "th.tid = tn.tid");
+      $last = "th";
+      foreach (range(1, abs($this->options['depth'])) as $count) {
+        $subquery->leftJoin('taxonomy_term_hierarchy', "th$count", "$last.parent = th$count.tid");
+        $where->condition("th$count.tid", $tids, $operator);
+        $last = "th$count";
+      }
+    }
+    elseif ($this->options['depth'] < 0) {
+      foreach (range(1, abs($this->options['depth'])) as $count) {
+        $subquery->leftJoin('taxonomy_term_hierarchy', "th$count", "$last.tid = th$count.parent");
+        $where->condition("th$count.tid", $tids, $operator);
+        $last = "th$count";
+      }
+    }
+
+    $subquery->condition($where);
+    $this->query->add_where(0, "$this->table_alias.$this->real_field", $subquery, 'IN');
+  }
+
+  function title() {
+    $term = taxonomy_term_load($this->argument);
+    if (!empty($term)) {
+      return check_plain($term->name);
+    }
+    // TODO review text
+    return t('No name');
+  }
+}
diff --git a/lib/Drupal/taxonomy/Plugin/views/argument/views_handler_argument_term_node_tid_depth_modifier.inc b/lib/Drupal/taxonomy/Plugin/views/argument/views_handler_argument_term_node_tid_depth_modifier.inc
new file mode 100644
index 000000000000..2f9dd4e7b728
--- /dev/null
+++ b/lib/Drupal/taxonomy/Plugin/views/argument/views_handler_argument_term_node_tid_depth_modifier.inc
@@ -0,0 +1,64 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_argument_term_node_tid_depth_modif.
+ */
+
+/**
+ * Argument handler for to modify depth for a previous term.
+ *
+ * This handler is actually part of the node table and has some restrictions,
+ * because it uses a subquery to find nodes with.
+ *
+ * @ingroup views_argument_handlers
+ */
+class views_handler_argument_term_node_tid_depth_modifier extends views_handler_argument {
+  function options_form(&$form, &$form_state) { }
+  function query($group_by = FALSE) { }
+  function pre_query() {
+    // We don't know our argument yet, but it's based upon our position:
+    $argument = isset($this->view->args[$this->position]) ? $this->view->args[$this->position] : NULL;
+    if (!is_numeric($argument)) {
+      return;
+    }
+
+    if ($argument > 10) {
+      $argument = 10;
+    }
+
+    if ($argument < -10) {
+      $argument = -10;
+    }
+
+    // figure out which argument preceded us.
+    $keys = array_reverse(array_keys($this->view->argument));
+    $skip = TRUE;
+    foreach ($keys as $key) {
+      if ($key == $this->options['id']) {
+        $skip = FALSE;
+        continue;
+      }
+
+      if ($skip) {
+        continue;
+      }
+
+      if (empty($this->view->argument[$key])) {
+        continue;
+      }
+
+      if (isset($handler)) {
+        unset($handler);
+      }
+
+      $handler = &$this->view->argument[$key];
+      if (empty($handler->definition['accept depth modifier'])) {
+        continue;
+      }
+
+      // Finally!
+      $handler->options['depth'] = $argument;
+    }
+  }
+}
diff --git a/lib/Drupal/taxonomy/Plugin/views/argument/views_handler_argument_vocabulary_machine_name.inc b/lib/Drupal/taxonomy/Plugin/views/argument/views_handler_argument_vocabulary_machine_name.inc
new file mode 100644
index 000000000000..2ec835b2dce4
--- /dev/null
+++ b/lib/Drupal/taxonomy/Plugin/views/argument/views_handler_argument_vocabulary_machine_name.inc
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_argument_vocabulary_machine_name.
+ */
+
+use Drupal\views\Plugins\views\argument\String;
+
+/**
+ * Argument handler to accept a vocabulary machine name.
+ *
+ * @ingroup views_argument_handlers
+ */
+class views_handler_argument_vocabulary_machine_name extends String {
+  /**
+   * Override the behavior of title(). Get the name of the vocabulary..
+   */
+  function title() {
+    $title = db_query("SELECT v.name FROM {taxonomy_vocabulary} v WHERE v.machine_name = :machine_name", array(':machine_name' => $this->argument))->fetchField();
+
+    if (empty($title)) {
+      return t('No vocabulary');
+    }
+
+    return check_plain($title);
+  }
+}
diff --git a/lib/Drupal/taxonomy/Plugin/views/argument/views_handler_argument_vocabulary_vid.inc b/lib/Drupal/taxonomy/Plugin/views/argument/views_handler_argument_vocabulary_vid.inc
new file mode 100644
index 000000000000..eba45978b783
--- /dev/null
+++ b/lib/Drupal/taxonomy/Plugin/views/argument/views_handler_argument_vocabulary_vid.inc
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_argument_vocabulary_vid.
+ */
+
+use Drupal\views\Plugins\views\argument\Numeric;
+
+/**
+ * Argument handler to accept a vocabulary id.
+ *
+ * @ingroup views_argument_handlers
+ */
+class views_handler_argument_vocabulary_vid extends Numeric {
+  /**
+   * Override the behavior of title(). Get the name of the vocabulary.
+   */
+  function title() {
+    $title = db_query("SELECT v.name FROM {taxonomy_vocabulary} v WHERE v.vid = :vid", array(':vid' => $this->argument))->fetchField();
+
+    if (empty($title)) {
+      return t('No vocabulary');
+    }
+
+    return check_plain($title);
+  }
+}
diff --git a/lib/Drupal/taxonomy/Plugin/views/argument_default/views_plugin_argument_default_taxonomy_tid.inc b/lib/Drupal/taxonomy/Plugin/views/argument_default/views_plugin_argument_default_taxonomy_tid.inc
new file mode 100644
index 000000000000..7ffb595efe38
--- /dev/null
+++ b/lib/Drupal/taxonomy/Plugin/views/argument_default/views_plugin_argument_default_taxonomy_tid.inc
@@ -0,0 +1,156 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_plugin_argument_default_taxonomy_tid.
+ */
+
+/**
+ * Taxonomy tid default argument.
+ */
+class views_plugin_argument_default_taxonomy_tid extends views_plugin_argument_default {
+  function init(&$view, &$argument, $options) {
+    parent::init($view, $argument, $options);
+
+    // Convert legacy vids option to machine name vocabularies.
+    if (!empty($this->options['vids'])) {
+      $vocabularies = taxonomy_vocabulary_get_names();
+      foreach ($this->options['vids'] as $vid) {
+        if (isset($vocabularies[$vid], $vocabularies[$vid]->machine_name)) {
+          $this->options['vocabularies'][$vocabularies[$vid]->machine_name] = $vocabularies[$vid]->machine_name;
+        }
+      }
+    }
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['term_page'] = array('default' => TRUE, 'bool' => TRUE);
+    $options['node'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['anyall'] = array('default' => ',');
+    $options['limit'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['vocabularies'] = array('default' => array());
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['term_page'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Load default filter from term page'),
+      '#default_value' => $this->options['term_page'],
+    );
+    $form['node'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Load default filter from node page, that\'s good for related taxonomy blocks'),
+      '#default_value' => $this->options['node'],
+    );
+
+    $form['limit'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Limit terms by vocabulary'),
+      '#default_value'=> $this->options['limit'],
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[argument_default][taxonomy_tid][node]"]' => array('checked' => TRUE),
+        ),
+      ),
+    );
+
+    $options = array();
+    $vocabularies = taxonomy_vocabulary_get_names();
+    foreach ($vocabularies as $voc) {
+      $options[$voc->machine_name] = check_plain($voc->name);
+    }
+
+    $form['vocabularies'] = array(
+      '#type' => 'checkboxes',
+      '#title' => t('Vocabularies'),
+      '#options' => $options,
+      '#default_value' => $this->options['vocabularies'],
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[argument_default][taxonomy_tid][limit]"]' => array('checked' => TRUE),
+          ':input[name="options[argument_default][taxonomy_tid][node]"]' => array('checked' => TRUE),
+        ),
+      ),
+    );
+
+    $form['anyall'] = array(
+      '#type' => 'radios',
+      '#title' => t('Multiple-value handling'),
+      '#default_value'=> $this->options['anyall'],
+      '#process' => array('form_process_radios', 'ctools_dependent_process'),
+      '#options' => array(
+        ',' => t('Filter to items that share all terms'),
+        '+' => t('Filter to items that share any term'),
+      ),
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[argument_default][taxonomy_tid][node]"]' => array('checked' => TRUE),
+        ),
+      ),
+    );
+  }
+
+  function options_submit(&$form, &$form_state, &$options = array()) {
+    // Filter unselected items so we don't unnecessarily store giant arrays.
+    $options['vocabularies'] = array_filter($options['vocabularies']);
+  }
+
+  function get_argument() {
+    // Load default argument from taxonomy page.
+    if (!empty($this->options['term_page'])) {
+      if (arg(0) == 'taxonomy' && arg(1) == 'term' && is_numeric(arg(2))) {
+        return arg(2);
+      }
+    }
+    // Load default argument from node.
+    if (!empty($this->options['node'])) {
+      foreach (range(1, 3) as $i) {
+        $node = menu_get_object('node', $i);
+        if (!empty($node)) {
+          break;
+        }
+      }
+      // Just check, if a node could be detected.
+      if ($node) {
+        $taxonomy = array();
+        $fields = field_info_instances('node', $node->type);
+        foreach ($fields as $name => $info) {
+          $field_info = field_info_field($name);
+          if ($field_info['type'] == 'taxonomy_term_reference') {
+            $items = field_get_items('node', $node, $name);
+            if (is_array($items)) {
+              foreach ($items as $item) {
+                $taxonomy[$item['tid']] = $field_info['settings']['allowed_values'][0]['vocabulary'];
+              }
+            }
+          }
+        }
+        if (!empty($this->options['limit'])) {
+          $tids = array();
+          // filter by vocabulary
+          foreach ($taxonomy as $tid => $vocab) {
+            if (!empty($this->options['vocabularies'][$vocab])) {
+              $tids[] = $tid;
+            }
+          }
+          return implode($this->options['anyall'], $tids);
+        }
+        // Return all tids.
+        else {
+          return implode($this->options['anyall'], array_keys($taxonomy));
+        }
+      }
+    }
+
+    // If the current page is a view that takes tid as an argument,
+    // find the tid argument and return it.
+    $views_page = views_get_page_view();
+    if ($views_page && isset($views_page->argument['tid'])) {
+      return $views_page->argument['tid']->argument;
+    }
+  }
+}
diff --git a/lib/Drupal/taxonomy/Plugin/views/argument_validate/views_plugin_argument_validate_taxonomy_term.inc b/lib/Drupal/taxonomy/Plugin/views/argument_validate/views_plugin_argument_validate_taxonomy_term.inc
new file mode 100644
index 000000000000..a324a011704b
--- /dev/null
+++ b/lib/Drupal/taxonomy/Plugin/views/argument_validate/views_plugin_argument_validate_taxonomy_term.inc
@@ -0,0 +1,222 @@
+<?php
+
+/**
+ * @file
+ * Contains the 'taxonomy term' argument validator plugin.
+ */
+
+/**
+ * Validate whether an argument is an acceptable node.
+ */
+class views_plugin_argument_validate_taxonomy_term extends views_plugin_argument_validate {
+  function init(&$view, &$argument, $options) {
+    parent::init($view, $argument, $options);
+
+    // Convert legacy vids option to machine name vocabularies.
+    if (!empty($this->options['vids'])) {
+      $vocabularies = taxonomy_vocabulary_get_names();
+      foreach ($this->options['vids'] as $vid) {
+        if (isset($vocabularies[$vid], $vocabularies[$vid]->machine_name)) {
+          $this->options['vocabularies'][$vocabularies[$vid]->machine_name] = $vocabularies[$vid]->machine_name;
+        }
+      }
+    }
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['vocabularies'] = array('default' => array());
+    $options['type'] = array('default' => 'tid');
+    $options['transform'] = array('default' => FALSE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $vocabularies = taxonomy_vocabulary_get_names();
+    $options = array();
+    foreach ($vocabularies as $voc) {
+      $options[$voc->machine_name] = check_plain($voc->name);
+    }
+
+    $form['vocabularies'] = array(
+      '#type' => 'checkboxes',
+      '#prefix' => '<div id="edit-options-validate-argument-vocabulary-wrapper">',
+      '#suffix' => '</div>',
+      '#title' => t('Vocabularies'),
+      '#options' => $options,
+      '#default_value' => $this->options['vocabularies'],
+      '#description' => t('If you wish to validate for specific vocabularies, check them; if none are checked, all terms will pass.'),
+    );
+
+    $form['type'] = array(
+      '#type' => 'select',
+      '#title' => t('Filter value type'),
+      '#options' => array(
+        'tid' => t('Term ID'),
+        'tids' => t('Term IDs separated by , or +'),
+        'name' => t('Term name'),
+        'convert' => t('Term name converted to Term ID'),
+      ),
+      '#default_value' => $this->options['type'],
+      '#description' => t('Select the form of this filter value; if using term name, it is generally more efficient to convert it to a term ID and use Taxonomy: Term ID rather than Taxonomy: Term Name" as the filter.'),
+    );
+
+    $form['transform'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Transform dashes in URL to spaces in term name filter values'),
+      '#default_value' => $this->options['transform'],
+    );
+  }
+
+  function options_submit(&$form, &$form_state, &$options = array()) {
+    // Filter unselected items so we don't unnecessarily store giant arrays.
+    $options['vocabularies'] = array_filter($options['vocabularies']);
+  }
+
+  function convert_options(&$options) {
+    if (!isset($options['vocabularies']) && !empty($this->argument->options['validate_argument_vocabulary'])) {
+      $options['vocabularies'] = $this->argument->options['validate_argument_vocabulary'];
+      $options['type'] = $this->argument->options['validate_argument_type'];
+      $options['transform'] = isset($this->argument->options['validate_argument_transform']) ? $this->argument->options['validate_argument_transform'] : FALSE;
+    }
+  }
+
+  function validate_argument($argument) {
+    $vocabularies = array_filter($this->options['vocabularies']);
+    $type = $this->options['type'];
+    $transform = $this->options['transform'];
+
+    switch ($type) {
+      case 'tid':
+        if (!is_numeric($argument)) {
+          return FALSE;
+        }
+
+        $query = db_select('taxonomy_term_data', 'td');
+        $query->leftJoin('taxonomy_vocabulary', 'tv', 'td.vid = tv.vid');
+        $query->fields('td');
+        $query->fields('tv', array('machine_name'));
+        $query->condition('td.tid', $argument);
+        $query->addTag('term_access');
+        $term = $query->execute()->fetchObject();
+        if (!$term) {
+          return FALSE;
+        }
+        $this->argument->validated_title = check_plain($term->name);
+        return empty($vocabularies) || !empty($vocabularies[$term->machine_name]);
+
+      case 'tids':
+        // An empty argument is not a term so doesn't pass.
+        if (empty($argument)) {
+          return FALSE;
+        }
+
+        $tids = new stdClass();
+        $tids->value = $argument;
+        $tids = views_break_phrase($argument, $tids);
+        if ($tids->value == array(-1)) {
+          return FALSE;
+        }
+
+        $test = drupal_map_assoc($tids->value);
+        $titles = array();
+
+        // check, if some tids already verified
+        static $validated_cache = array();
+        foreach ($test as $tid) {
+          if (isset($validated_cache[$tid])) {
+            if ($validated_cache[$tid] === FALSE) {
+              return FALSE;
+            }
+            else {
+              $titles[] = $validated_cache[$tid];
+              unset($test[$tid]);
+            }
+          }
+        }
+
+        // if unverified tids left - verify them and cache results
+        if (count($test)) {
+          $query = db_select('taxonomy_term_data', 'td');
+          $query->leftJoin('taxonomy_vocabulary', 'tv', 'td.vid = tv.vid');
+          $query->fields('td');
+          $query->fields('tv', array('machine_name'));
+          $query->condition('td.tid', $test);
+
+          $result = $query->execute();
+
+          foreach ($result as $term) {
+            if ($vocabularies && empty($vocabularies[$term->machine_name])) {
+              $validated_cache[$term->tid] = FALSE;
+              return FALSE;
+            }
+
+            $titles[] = $validated_cache[$term->tid] = check_plain($term->name);
+            unset($test[$term->tid]);
+          }
+        }
+
+        // Remove duplicate titles
+        $titles = array_unique($titles);
+
+        $this->argument->validated_title = implode($tids->operator == 'or' ? ' + ' : ', ', $titles);
+        // If this is not empty, we did not find a tid.
+        return empty($test);
+
+      case 'name':
+      case 'convert':
+        $query = db_select('taxonomy_term_data', 'td');
+        $query->leftJoin('taxonomy_vocabulary', 'tv', 'td.vid = tv.vid');
+        $query->fields('td');
+        $query->fields('tv', array('machine_name'));
+        if (!empty($vocabularies)) {
+          $query->condition('tv.machine_name', $vocabularies);
+        }
+        if ($transform) {
+          $query->where("replace(td.name, ' ', '-') = :name", array(':name' => $argument));
+        }
+        else {
+          $query->condition('td.name', $argument);
+        }
+        $term = $query->execute()->fetchObject();
+
+        if ($term && (empty($vocabularies) || !empty($vocabularies[$term->machine_name]))) {
+          if ($type == 'convert') {
+            $this->argument->argument = $term->tid;
+          }
+          $this->argument->validated_title = check_plain($term->name);
+          return TRUE;
+        }
+        return FALSE;
+    }
+  }
+
+  function process_summary_arguments(&$args) {
+    $type = $this->options['type'];
+    $transform = $this->options['transform'];
+    $vocabularies = array_filter($this->options['vocabularies']);
+
+    if ($type == 'convert') {
+      $arg_keys = array_flip($args);
+
+      $query = db_select('taxonomy_term_data', 'td');
+      $query->condition('tid', $args);
+      $query->addField('td', 'tid', 'tid');
+      if (!empty($vocabularies)) {
+        $query->leftJoin('taxonomy_vocabulary', 'tv', 'td.vid = tv.vid');
+        $query->condition('tv.machine_name', $vocabularies);
+      }
+      if ($transform) {
+        $query->addExpression("REPLACE(td.name, ' ', '-')", 'name');
+      }
+      else {
+        $query->addField('td', 'name', 'name');
+      }
+
+      foreach ($query->execute()->fetchAllKeyed() as $tid => $term) {
+        $args[$arg_keys[$tid]] = $term;
+      }
+    }
+  }
+}
diff --git a/lib/Drupal/taxonomy/Plugin/views/field/views_handler_field_taxonomy.inc b/lib/Drupal/taxonomy/Plugin/views/field/views_handler_field_taxonomy.inc
new file mode 100644
index 000000000000..05ee45d324e1
--- /dev/null
+++ b/lib/Drupal/taxonomy/Plugin/views/field/views_handler_field_taxonomy.inc
@@ -0,0 +1,86 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_taxonomy.
+ */
+
+/**
+ * Field handler to provide simple renderer that allows linking to a taxonomy
+ * term.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_taxonomy extends views_handler_field {
+  /**
+   * Constructor to provide additional field to add.
+   *
+   * This constructer assumes the taxonomy_term_data table. If using another
+   * table, we'll need to be more specific.
+   */
+  function construct() {
+    parent::construct();
+    $this->additional_fields['vid'] = 'vid';
+    $this->additional_fields['tid'] = 'tid';
+    $this->additional_fields['vocabulary_machine_name'] = array(
+      'table' => 'taxonomy_vocabulary',
+      'field' => 'machine_name',
+    );
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['link_to_taxonomy'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['convert_spaces'] = array('default' => FALSE, 'bool' => TRUE);
+    return $options;
+  }
+
+  /**
+   * Provide link to taxonomy option
+   */
+  function options_form(&$form, &$form_state) {
+    $form['link_to_taxonomy'] = array(
+      '#title' => t('Link this field to its taxonomy term page'),
+      '#description' => t("Enable to override this field's links."),
+      '#type' => 'checkbox',
+      '#default_value' => !empty($this->options['link_to_taxonomy']),
+    );
+     $form['convert_spaces'] = array(
+      '#title' => t('Convert spaces in term names to hyphens'),
+      '#description' => t('This allows links to work with Views taxonomy term arguments.'),
+      '#type' => 'checkbox',
+      '#default_value' => !empty($this->options['convert_spaces']),
+    );
+    parent::options_form($form, $form_state);
+  }
+
+  /**
+   * Render whatever the data is as a link to the taxonomy.
+   *
+   * Data should be made XSS safe prior to calling this function.
+   */
+  function render_link($data, $values) {
+    $tid = $this->get_value($values, 'tid');
+    if (!empty($this->options['link_to_taxonomy']) && !empty($tid) && $data !== NULL && $data !== '') {
+      $term = entity_create('taxonomy_term', array(
+        'tid' => $tid,
+        'vid' => $this->get_value($values, 'vid'),
+        'vocabulary_machine_name' => $values->{$this->aliases['vocabulary_machine_name']},
+      ));
+      $this->options['alter']['make_link'] = TRUE;
+      $uri = $term->uri();
+      $this->options['alter']['path'] = $uri['path'];
+    }
+
+    if (!empty($this->options['convert_spaces'])) {
+      $data = str_replace(' ', '-', $data);
+    }
+
+    return $data;
+  }
+
+  function render($values) {
+    $value = $this->get_value($values);
+    return $this->render_link($this->sanitize_value($value), $values);
+  }
+}
diff --git a/lib/Drupal/taxonomy/Plugin/views/field/views_handler_field_term_link_edit.inc b/lib/Drupal/taxonomy/Plugin/views/field/views_handler_field_term_link_edit.inc
new file mode 100644
index 000000000000..5605b9fe070f
--- /dev/null
+++ b/lib/Drupal/taxonomy/Plugin/views/field/views_handler_field_term_link_edit.inc
@@ -0,0 +1,60 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_term_link_edit.
+ */
+
+/**
+ * Field handler to present a term edit link.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_term_link_edit extends views_handler_field {
+  function construct() {
+    parent::construct();
+    $this->additional_fields['tid'] = 'tid';
+    $this->additional_fields['vid'] = 'vid';
+    $this->additional_fields['vocabulary_machine_name'] = array(
+      'table' => 'taxonomy_vocabulary',
+      'field' => 'machine_name',
+    );
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['text'] = array('default' => '', 'translatable' => TRUE);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['text'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Text to display'),
+      '#default_value' => $this->options['text'],
+    );
+    parent::options_form($form, $form_state);
+  }
+
+  function query() {
+    $this->ensure_my_table();
+    $this->add_additional_fields();
+  }
+
+  function render($values) {
+    // Mock a term object for taxonomy_term_access(). Use machine name and
+    // vid to ensure compatibility with vid based and machine name based
+    // access checks. See http://drupal.org/node/995156
+    $term = entity_create('taxonomy_term', array(
+      'vid' => $values->{$this->aliases['vid']},
+      'vocabulary_machine_name' => $values->{$this->aliases['vocabulary_machine_name']},
+    ));
+    if (taxonomy_term_access('edit', $term)) {
+      $text = !empty($this->options['text']) ? $this->options['text'] : t('edit');
+      $tid = $this->get_value($values, 'tid');
+      return l($text, 'taxonomy/term/'. $tid . '/edit', array('query' => drupal_get_destination()));
+    }
+  }
+}
diff --git a/lib/Drupal/taxonomy/Plugin/views/field/views_handler_field_term_node_tid.inc b/lib/Drupal/taxonomy/Plugin/views/field/views_handler_field_term_node_tid.inc
new file mode 100644
index 000000000000..ca46c1d7bed5
--- /dev/null
+++ b/lib/Drupal/taxonomy/Plugin/views/field/views_handler_field_term_node_tid.inc
@@ -0,0 +1,148 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_term_node_tid.
+ */
+
+/**
+ * Field handler to display all taxonomy terms of a node.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_term_node_tid extends views_handler_field_prerender_list {
+  function init(&$view, &$options) {
+    parent::init($view, $options);
+    // @todo: Wouldn't it be possible to use $this->base_table and no if here?
+    if ($view->base_table == 'node_revision') {
+      $this->additional_fields['nid'] = array('table' => 'node_revision', 'field' => 'nid');
+    }
+    else {
+      $this->additional_fields['nid'] = array('table' => 'node', 'field' => 'nid');
+    }
+
+    // Convert legacy vids option to machine name vocabularies.
+    if (!empty($this->options['vids'])) {
+      $vocabularies = taxonomy_vocabulary_get_names();
+      foreach ($this->options['vids'] as $vid) {
+        if (isset($vocabularies[$vid], $vocabularies[$vid]->machine_name)) {
+          $this->options['vocabularies'][$vocabularies[$vid]->machine_name] = $vocabularies[$vid]->machine_name;
+        }
+      }
+    }
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['link_to_taxonomy'] = array('default' => TRUE, 'bool' => TRUE);
+    $options['limit'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['vocabularies'] = array('default' => array());
+
+    return $options;
+  }
+
+  /**
+   * Provide "link to term" option.
+   */
+  function options_form(&$form, &$form_state) {
+    $form['link_to_taxonomy'] = array(
+      '#title' => t('Link this field to its term page'),
+      '#type' => 'checkbox',
+      '#default_value' => !empty($this->options['link_to_taxonomy']),
+    );
+
+    $form['limit'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Limit terms by vocabulary'),
+      '#default_value'=> $this->options['limit'],
+    );
+
+    $options = array();
+    $vocabularies = taxonomy_vocabulary_get_names();
+    foreach ($vocabularies as $voc) {
+      $options[$voc->machine_name] = check_plain($voc->name);
+    }
+
+    $form['vocabularies'] = array(
+      '#type' => 'checkboxes',
+      '#title' => t('Vocabularies'),
+      '#options' => $options,
+      '#default_value' => $this->options['vocabularies'],
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[limit]"]' => array('checked' => TRUE),
+        ),
+      ),
+
+    );
+
+    parent::options_form($form, $form_state);
+  }
+
+  /**
+   * Add this term to the query
+   */
+  function query() {
+    $this->add_additional_fields();
+  }
+
+  function pre_render(&$values) {
+    $this->field_alias = $this->aliases['nid'];
+    $nids = array();
+    foreach ($values as $result) {
+      if (!empty($result->{$this->aliases['nid']})) {
+        $nids[] = $result->{$this->aliases['nid']};
+      }
+    }
+
+    if ($nids) {
+      $query = db_select('taxonomy_term_data', 'td');
+      $query->innerJoin('taxonomy_index', 'tn', 'td.tid = tn.tid');
+      $query->innerJoin('taxonomy_vocabulary', 'tv', 'td.vid = tv.vid');
+      $query->fields('td');
+      $query->addField('tn', 'nid', 'node_nid');
+      $query->addField('tv', 'name', 'vocabulary');
+      $query->addField('tv', 'machine_name', 'vocabulary_machine_name');
+      $query->orderby('td.weight');
+      $query->orderby('td.name');
+      $query->condition('tn.nid', $nids);
+      $query->addTag('term_access');
+      $vocabs = array_filter($this->options['vocabularies']);
+      if (!empty($this->options['limit']) && !empty($vocabs)) {
+        $query->condition('tv.machine_name', $vocabs);
+      }
+      $result = $query->execute();
+
+      foreach ($result as $term) {
+        $this->items[$term->node_nid][$term->tid]['name'] = check_plain($term->name);
+        $this->items[$term->node_nid][$term->tid]['tid'] = $term->tid;
+        $this->items[$term->node_nid][$term->tid]['vocabulary_machine_name'] = check_plain($term->vocabulary_machine_name);
+        $this->items[$term->node_nid][$term->tid]['vocabulary'] = check_plain($term->vocabulary);
+
+        if (!empty($this->options['link_to_taxonomy'])) {
+          $this->items[$term->node_nid][$term->tid]['make_link'] = TRUE;
+          $this->items[$term->node_nid][$term->tid]['path'] = 'taxonomy/term/' . $term->tid;
+        }
+      }
+    }
+  }
+
+  function render_item($count, $item) {
+    return $item['name'];
+  }
+
+  function document_self_tokens(&$tokens) {
+    $tokens['[' . $this->options['id'] . '-tid' . ']'] = t('The taxonomy term ID for the term.');
+    $tokens['[' . $this->options['id'] . '-name' . ']'] = t('The taxonomy term name for the term.');
+    $tokens['[' . $this->options['id'] . '-vocabulary-machine-name' . ']'] = t('The machine name for the vocabulary the term belongs to.');
+    $tokens['[' . $this->options['id'] . '-vocabulary' . ']'] = t('The name for the vocabulary the term belongs to.');
+  }
+
+  function add_self_tokens(&$tokens, $item) {
+    foreach(array('tid', 'name', 'vocabulary_machine_name', 'vocabulary') as $token) {
+      // Replace _ with - for the vocabulary machine name.
+      $tokens['[' . $this->options['id'] . '-' . str_replace('_', '-', $token). ']'] = isset($item[$token]) ? $item[$token] : '';
+    }
+  }
+}
diff --git a/lib/Drupal/taxonomy/Plugin/views/filter/views_handler_filter_term_node_tid.inc b/lib/Drupal/taxonomy/Plugin/views/filter/views_handler_filter_term_node_tid.inc
new file mode 100644
index 000000000000..8945edc0d941
--- /dev/null
+++ b/lib/Drupal/taxonomy/Plugin/views/filter/views_handler_filter_term_node_tid.inc
@@ -0,0 +1,364 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_filter_term_node_tid.
+ */
+
+/**
+ * Filter by term id.
+ *
+ * @ingroup views_filter_handlers
+ */
+class views_handler_filter_term_node_tid extends views_handler_filter_many_to_one {
+  // Stores the exposed input for this filter.
+  var $validated_exposed_input = NULL;
+
+  function init(&$view, &$options) {
+    parent::init($view, $options);
+    if (!empty($this->definition['vocabulary'])) {
+      $this->options['vocabulary'] = $this->definition['vocabulary'];
+    }
+
+    // Convert legacy vid option to machine name vocabulary.
+    if (isset($this->options['vid']) && !empty($this->options['vid']) & empty($this->options['vocabulary'])) {
+      $vocabularies = taxonomy_vocabulary_get_names();
+      $vid = $this->options['vid'];
+      if (isset($vocabularies[$vid], $vocabularies[$vid]->machine_name)) {
+        $this->options['vocabulary'] = $vocabularies[$vid]->machine_name;
+      }
+    }
+  }
+
+  function has_extra_options() { return TRUE; }
+
+  function get_value_options() { /* don't overwrite the value options */ }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['type'] = array('default' => 'textfield');
+    $options['limit'] = array('default' => TRUE, 'bool' => TRUE);
+    $options['vocabulary'] = array('default' => 0);
+    $options['hierarchy'] = array('default' => 0);
+    $options['error_message'] = array('default' => TRUE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  function extra_options_form(&$form, &$form_state) {
+    $vocabularies = taxonomy_vocabulary_get_names();
+    $options = array();
+    foreach ($vocabularies as $voc) {
+      $options[$voc->machine_name] = check_plain($voc->name);
+    }
+
+    if ($this->options['limit']) {
+      // We only do this when the form is displayed.
+      if (empty($this->options['vocabulary'])) {
+        $first_vocabulary = reset($vocabularies);
+        $this->options['vocabulary'] = $first_vocabulary->machine_name;
+      }
+
+      if (empty($this->definition['vocabulary'])) {
+        $form['vocabulary'] = array(
+          '#type' => 'radios',
+          '#title' => t('Vocabulary'),
+          '#options' => $options,
+          '#description' => t('Select which vocabulary to show terms for in the regular options.'),
+          '#default_value' => $this->options['vocabulary'],
+        );
+      }
+    }
+
+    $form['type'] = array(
+      '#type' => 'radios',
+      '#title' => t('Selection type'),
+      '#options' => array('select' => t('Dropdown'), 'textfield' => t('Autocomplete')),
+      '#default_value' => $this->options['type'],
+    );
+
+    $form['hierarchy'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Show hierarchy in dropdown'),
+      '#default_value' => !empty($this->options['hierarchy']),
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[type]"]' => array('value' => 'select'),
+        ),
+      ),
+    );
+  }
+
+  function value_form(&$form, &$form_state) {
+    $vocabulary = taxonomy_vocabulary_machine_name_load($this->options['vocabulary']);
+    if (empty($vocabulary) && $this->options['limit']) {
+      $form['markup'] = array(
+        '#markup' => '<div class="form-item">' . t('An invalid vocabulary is selected. Please change it in the options.') . '</div>',
+      );
+      return;
+    }
+
+    if ($this->options['type'] == 'textfield') {
+      $default = '';
+      if ($this->value) {
+        $result = db_select('taxonomy_term_data', 'td')
+          ->fields('td')
+          ->condition('td.tid', $this->value)
+          ->execute();
+        foreach ($result as $term) {
+          if ($default) {
+            $default .= ', ';
+          }
+          $default .= $term->name;
+        }
+      }
+
+      $form['value'] = array(
+        '#title' => $this->options['limit'] ? t('Select terms from vocabulary @voc', array('@voc' => $vocabulary->name)) : t('Select terms'),
+        '#type' => 'textfield',
+        '#default_value' => $default,
+      );
+
+      if ($this->options['limit']) {
+        $form['value']['#autocomplete_path'] = 'admin/views/ajax/autocomplete/taxonomy/' . $vocabulary->vid;
+      }
+    }
+    else {
+      if (!empty($this->options['hierarchy']) && $this->options['limit']) {
+        $tree = taxonomy_get_tree($vocabulary->vid);
+        $options = array();
+
+        if ($tree) {
+          foreach ($tree as $term) {
+            $choice = new stdClass();
+            $choice->option = array($term->tid => str_repeat('-', $term->depth) . $term->name);
+            $options[] = $choice;
+          }
+        }
+      }
+      else {
+        $options = array();
+        $query = db_select('taxonomy_term_data', 'td');
+        $query->innerJoin('taxonomy_vocabulary', 'tv', 'td.vid = tv.vid');
+        $query->fields('td');
+        $query->orderby('tv.weight');
+        $query->orderby('tv.name');
+        $query->orderby('td.weight');
+        $query->orderby('td.name');
+        $query->addTag('term_access');
+        if ($this->options['limit']) {
+          $query->condition('tv.machine_name', $vocabulary->machine_name);
+        }
+        $result = $query->execute();
+        foreach ($result as $term) {
+          $options[$term->tid] = $term->name;
+        }
+      }
+
+      $default_value = (array) $this->value;
+
+      if (!empty($form_state['exposed'])) {
+        $identifier = $this->options['expose']['identifier'];
+
+        if (!empty($this->options['expose']['reduce'])) {
+          $options = $this->reduce_value_options($options);
+
+          if (!empty($this->options['expose']['multiple']) && empty($this->options['expose']['required'])) {
+            $default_value = array();
+          }
+        }
+
+        if (empty($this->options['expose']['multiple'])) {
+          if (empty($this->options['expose']['required']) && (empty($default_value) || !empty($this->options['expose']['reduce']))) {
+            $default_value = 'All';
+          }
+          elseif (empty($default_value)) {
+            $keys = array_keys($options);
+            $default_value = array_shift($keys);
+          }
+          // Due to #1464174 there is a chance that array('') was saved in the admin ui.
+          // Let's choose a safe default value.
+          elseif ($default_value == array('')) {
+            $default_value = 'All';
+          }
+          else {
+            $copy = $default_value;
+            $default_value = array_shift($copy);
+          }
+        }
+      }
+      $form['value'] = array(
+        '#type' => 'select',
+        '#title' => $this->options['limit'] ? t('Select terms from vocabulary @voc', array('@voc' => $vocabulary->name)) : t('Select terms'),
+        '#multiple' => TRUE,
+        '#options' => $options,
+        '#size' => min(9, count($options)),
+        '#default_value' => $default_value,
+      );
+
+      if (!empty($form_state['exposed']) && isset($identifier) && !isset($form_state['input'][$identifier])) {
+        $form_state['input'][$identifier] = $default_value;
+      }
+    }
+
+
+    if (empty($form_state['exposed'])) {
+      // Retain the helper option
+      $this->helper->options_form($form, $form_state);
+    }
+  }
+
+  function value_validate($form, &$form_state) {
+    // We only validate if they've chosen the text field style.
+    if ($this->options['type'] != 'textfield') {
+      return;
+    }
+
+    $values = drupal_explode_tags($form_state['values']['options']['value']);
+    $tids = $this->validate_term_strings($form['value'], $values);
+
+    if ($tids) {
+      $form_state['values']['options']['value'] = $tids;
+    }
+  }
+
+  function accept_exposed_input($input) {
+    if (empty($this->options['exposed'])) {
+      return TRUE;
+    }
+
+    // If view is an attachment and is inheriting exposed filters, then assume
+    // exposed input has already been validated
+    if (!empty($this->view->is_attachment) && $this->view->display_handler->uses_exposed()) {
+      $this->validated_exposed_input = (array) $this->view->exposed_raw_input[$this->options['expose']['identifier']];
+    }
+
+    // If it's non-required and there's no value don't bother filtering.
+    if (!$this->options['expose']['required'] && empty($this->validated_exposed_input)) {
+      return FALSE;
+    }
+
+    $rc = parent::accept_exposed_input($input);
+    if ($rc) {
+      // If we have previously validated input, override.
+      if (isset($this->validated_exposed_input)) {
+        $this->value = $this->validated_exposed_input;
+      }
+    }
+
+    return $rc;
+  }
+
+  function exposed_validate(&$form, &$form_state) {
+    if (empty($this->options['exposed'])) {
+      return;
+    }
+
+    $identifier = $this->options['expose']['identifier'];
+
+    // We only validate if they've chosen the text field style.
+    if ($this->options['type'] != 'textfield') {
+      if ($form_state['values'][$identifier] != 'All')  {
+        $this->validated_exposed_input = (array) $form_state['values'][$identifier];
+      }
+      return;
+    }
+
+    if (empty($this->options['expose']['identifier'])) {
+      return;
+    }
+
+    $values = drupal_explode_tags($form_state['values'][$identifier]);
+
+    $tids = $this->validate_term_strings($form[$identifier], $values);
+    if ($tids) {
+      $this->validated_exposed_input = $tids;
+    }
+  }
+
+  /**
+   * Validate the user string. Since this can come from either the form
+   * or the exposed filter, this is abstracted out a bit so it can
+   * handle the multiple input sources.
+   *
+   * @param $form
+   *   The form which is used, either the views ui or the exposed filters.
+   * @param $values
+   *   The taxonomy names which will be converted to tids.
+   *
+   * @return array
+   *   The taxonomy ids fo all validated terms.
+   */
+  function validate_term_strings(&$form, $values) {
+    if (empty($values)) {
+      return array();
+    }
+
+    $tids = array();
+    $names = array();
+    $missing = array();
+    foreach ($values as $value) {
+      $missing[strtolower($value)] = TRUE;
+      $names[] = $value;
+    }
+
+    if (!$names) {
+      return FALSE;
+    }
+
+    $query = db_select('taxonomy_term_data', 'td');
+    $query->innerJoin('taxonomy_vocabulary', 'tv', 'td.vid = tv.vid');
+    $query->fields('td');
+    $query->condition('td.name', $names);
+    $query->condition('tv.machine_name', $this->options['vocabulary']);
+    $query->addTag('term_access');
+    $result = $query->execute();
+    foreach ($result as $term) {
+      unset($missing[strtolower($term->name)]);
+      $tids[] = $term->tid;
+    }
+
+    if ($missing && !empty($this->options['error_message'])) {
+      form_error($form, format_plural(count($missing), 'Unable to find term: @terms', 'Unable to find terms: @terms', array('@terms' => implode(', ', array_keys($missing)))));
+    }
+    elseif ($missing && empty($this->options['error_message'])) {
+      $tids = array(0);
+    }
+
+    return $tids;
+  }
+
+  function value_submit($form, &$form_state) {
+    // prevent array_filter from messing up our arrays in parent submit.
+  }
+
+  function expose_form(&$form, &$form_state) {
+    parent::expose_form($form, $form_state);
+    if ($this->options['type'] != 'select') {
+      unset($form['expose']['reduce']);
+    }
+    $form['error_message'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Display error message'),
+      '#default_value' => !empty($this->options['error_message']),
+    );
+  }
+
+  function admin_summary() {
+    // set up $this->value_options for the parent summary
+    $this->value_options = array();
+
+    if ($this->value) {
+      $this->value = array_filter($this->value);
+      $result = db_select('taxonomy_term_data', 'td')
+        ->fields('td')
+        ->condition('td.tid', $this->value)
+        ->execute();
+      foreach ($result as $term) {
+        $this->value_options[$term->tid] = $term->name;
+      }
+    }
+    return parent::admin_summary();
+  }
+}
diff --git a/lib/Drupal/taxonomy/Plugin/views/filter/views_handler_filter_term_node_tid_depth.inc b/lib/Drupal/taxonomy/Plugin/views/filter/views_handler_filter_term_node_tid_depth.inc
new file mode 100644
index 000000000000..fe12780f423d
--- /dev/null
+++ b/lib/Drupal/taxonomy/Plugin/views/filter/views_handler_filter_term_node_tid_depth.inc
@@ -0,0 +1,100 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_filter_term_node_tid_depth.
+ */
+
+/**
+ * Filter handler for taxonomy terms with depth.
+ *
+ * This handler is actually part of the node table and has some restrictions,
+ * because it uses a subquery to find nodes with.
+ *
+ * @ingroup views_filter_handlers
+ */
+class views_handler_filter_term_node_tid_depth extends views_handler_filter_term_node_tid {
+  function operator_options($which = 'title') {
+    return array(
+      'or' => t('Is one of'),
+    );
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['depth'] = array('default' => 0);
+
+    return $options;
+  }
+
+  function extra_options_form(&$form, &$form_state) {
+    parent::extra_options_form($form, $form_state);
+
+    $form['depth'] = array(
+      '#type' => 'weight',
+      '#title' => t('Depth'),
+      '#default_value' => $this->options['depth'],
+      '#description' => t('The depth will match nodes tagged with terms in the hierarchy. For example, if you have the term "fruit" and a child term "apple", with a depth of 1 (or higher) then filtering for the term "fruit" will get nodes that are tagged with "apple" as well as "fruit". If negative, the reverse is true; searching for "apple" will also pick up nodes tagged with "fruit" if depth is -1 (or lower).'),
+    );
+  }
+
+  function query() {
+    // If no filter values are present, then do nothing.
+    if (count($this->value) == 0) {
+      return;
+    }
+    elseif (count($this->value) == 1) {
+      // Somethis $this->value is an array with a single element so convert it.
+      if (is_array($this->value)) {
+        $this->value = current($this->value);
+      }
+      $operator = '=';
+    }
+    else {
+      $operator = 'IN';# " IN (" . implode(', ', array_fill(0, sizeof($this->value), '%d')) . ")";
+    }
+
+    // The normal use of ensure_my_table() here breaks Views.
+    // So instead we trick the filter into using the alias of the base table.
+    // See http://drupal.org/node/271833
+    // If a relationship is set, we must use the alias it provides.
+    if (!empty($this->relationship)) {
+      $this->table_alias = $this->relationship;
+    }
+    // If no relationship, then use the alias of the base table.
+    elseif (isset($this->query->table_queue[$this->query->base_table]['alias'])) {
+      $this->table_alias = $this->query->table_queue[$this->query->base_table]['alias'];
+    }
+    // This should never happen, but if it does, we fail quietly.
+    else {
+      return;
+    }
+
+    // Now build the subqueries.
+    $subquery = db_select('taxonomy_index', 'tn');
+    $subquery->addField('tn', 'nid');
+    $where = db_or()->condition('tn.tid', $this->value, $operator);
+    $last = "tn";
+
+    if ($this->options['depth'] > 0) {
+      $subquery->leftJoin('taxonomy_term_hierarchy', 'th', "th.tid = tn.tid");
+      $last = "th";
+      foreach (range(1, abs($this->options['depth'])) as $count) {
+        $subquery->leftJoin('taxonomy_term_hierarchy', "th$count", "$last.parent = th$count.tid");
+        $where->condition("th$count.tid", $this->value, $operator);
+        $last = "th$count";
+      }
+    }
+    elseif ($this->options['depth'] < 0) {
+      foreach (range(1, abs($this->options['depth'])) as $count) {
+        $subquery->leftJoin('taxonomy_term_hierarchy', "th$count", "$last.tid = th$count.parent");
+        $where->condition("th$count.tid", $this->value, $operator);
+        $last = "th$count";
+      }
+    }
+
+    $subquery->condition($where);
+    $this->query->add_where($this->options['group'], "$this->table_alias.$this->real_field", $subquery, 'IN');
+  }
+}
diff --git a/lib/Drupal/taxonomy/Plugin/views/filter/views_handler_filter_vocabulary_machine_name.inc b/lib/Drupal/taxonomy/Plugin/views/filter/views_handler_filter_vocabulary_machine_name.inc
new file mode 100644
index 000000000000..18754b2270f0
--- /dev/null
+++ b/lib/Drupal/taxonomy/Plugin/views/filter/views_handler_filter_vocabulary_machine_name.inc
@@ -0,0 +1,25 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_filter_vocabulary_machine_name.
+ */
+
+/**
+ * Filter by vocabulary machine name.
+ *
+ * @ingroup views_filter_handlers
+ */
+class views_handler_filter_vocabulary_machine_name extends views_handler_filter_in_operator {
+  function get_value_options() {
+    if (isset($this->value_options)) {
+      return;
+    }
+
+    $this->value_options = array();
+    $vocabularies = taxonomy_vocabulary_get_names();
+    foreach ($vocabularies as $voc) {
+      $this->value_options[$voc->machine_name] = $voc->name;
+    }
+  }
+}
diff --git a/lib/Drupal/taxonomy/Plugin/views/filter/views_handler_filter_vocabulary_vid.inc b/lib/Drupal/taxonomy/Plugin/views/filter/views_handler_filter_vocabulary_vid.inc
new file mode 100644
index 000000000000..f2c4ccd3ab94
--- /dev/null
+++ b/lib/Drupal/taxonomy/Plugin/views/filter/views_handler_filter_vocabulary_vid.inc
@@ -0,0 +1,25 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_filter_vocabulary_vid.
+ */
+
+/**
+ * Filter by vocabulary id.
+ *
+ * @ingroup views_filter_handlers
+ */
+class views_handler_filter_vocabulary_vid extends views_handler_filter_in_operator {
+  function get_value_options() {
+    if (isset($this->value_options)) {
+      return;
+    }
+
+    $this->value_options = array();
+    $vocabularies = taxonomy_vocabulary_get_names();
+    foreach ($vocabularies as $voc) {
+      $this->value_options[$voc->vid] = $voc->name;
+    }
+  }
+}
diff --git a/lib/Drupal/taxonomy/Plugin/views/relationship/views_handler_relationship_node_term_data.inc b/lib/Drupal/taxonomy/Plugin/views/relationship/views_handler_relationship_node_term_data.inc
new file mode 100644
index 000000000000..f50867a7e0f4
--- /dev/null
+++ b/lib/Drupal/taxonomy/Plugin/views/relationship/views_handler_relationship_node_term_data.inc
@@ -0,0 +1,98 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_relationship_node_term_data.
+ */
+
+use Drupal\views\Join;
+use Drupal\views\Plugins\views\relationship\RelationshipPluginBase;
+
+/**
+ * Relationship handler to return the taxonomy terms of nodes.
+ *
+ * @ingroup views_relationship_handlers
+ */
+class views_handler_relationship_node_term_data extends RelationshipPluginBase  {
+  function init(&$view, &$options) {
+    parent::init($view, $options);
+
+    // Convert legacy vids option to machine name vocabularies.
+    if (!empty($this->options['vids'])) {
+      $vocabularies = taxonomy_vocabulary_get_names();
+      foreach ($this->options['vids'] as $vid) {
+        if (isset($vocabularies[$vid], $vocabularies[$vid]->machine_name)) {
+          $this->options['vocabularies'][$vocabularies[$vid]->machine_name] = $vocabularies[$vid]->machine_name;
+        }
+      }
+    }
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['vocabularies'] = array('default' => array());
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $vocabularies = taxonomy_vocabulary_get_names();
+    $options = array();
+    foreach ($vocabularies as $voc) {
+      $options[$voc->machine_name] = check_plain($voc->name);
+    }
+
+    $form['vocabularies'] = array(
+      '#type' => 'checkboxes',
+      '#title' => t('Vocabularies'),
+      '#options' => $options,
+      '#default_value' => $this->options['vocabularies'],
+      '#description' => t('Choose which vocabularies you wish to relate. Remember that every term found will create a new record, so this relationship is best used on just one vocabulary that has only one term per node.'),
+    );
+    parent::options_form($form, $form_state);
+  }
+
+  /**
+   * Called to implement a relationship in a query.
+   */
+  function query() {
+    $this->ensure_my_table();
+
+    $def = $this->definition;
+    $def['table'] = 'taxonomy_term_data';
+
+    if (!array_filter($this->options['vocabularies'])) {
+      $term_node = $this->query->add_table('taxonomy_index', $this->relationship);
+      $def['left_table'] = 'taxonomy_index';
+      $def['left_field'] = 'tid';
+      $def['field'] = 'tid';
+      $def['type'] = empty($this->options['required']) ? 'LEFT' : 'INNER';
+    }
+    else {
+      // If vocabularies are supplied join a subselect instead
+      $def['left_table'] = $this->table_alias;
+      $def['left_field'] = 'nid';
+      $def['field'] = 'nid';
+      $def['type'] = empty($this->options['required']) ? 'LEFT' : 'INNER';
+
+      $query = db_select('taxonomy_term_data', 'td');
+      $query->addJoin($def['type'], 'taxonomy_vocabulary', 'tv', 'td.vid = tv.vid');
+      $query->addJoin($def['type'], 'taxonomy_index', 'tn', 'tn.tid = td.tid');
+      $query->condition('tv.machine_name', array_filter($this->options['vocabularies']));
+      $query->addTag('term_access');
+      $query->fields('td');
+      $query->fields('tn', array('nid'));
+      $def['table formula'] = $query;
+    }
+
+    $join = new Join();
+
+    $join->definition = $def;
+    $join->construct();
+    $join->adjusted = TRUE;
+
+    // use a short alias for this:
+    $alias = $def['table'] . '_' . $this->table;
+
+    $this->alias = $this->query->add_relationship($alias, $join, 'taxonomy_term_data', $this->relationship);
+  }
+}
diff --git a/lib/Drupal/translation/Plugin/views/argument/views_handler_argument_node_tnid.inc b/lib/Drupal/translation/Plugin/views/argument/views_handler_argument_node_tnid.inc
new file mode 100644
index 000000000000..61e9ebabfa03
--- /dev/null
+++ b/lib/Drupal/translation/Plugin/views/argument/views_handler_argument_node_tnid.inc
@@ -0,0 +1,26 @@
+<?php
+
+/**
+ * @file
+ * Provide node tnid argument handler.
+ */
+
+/**
+ * Argument handler to accept a node translation id.
+ *
+ * @ingroup views_argument_handlers
+ */
+class views_handler_argument_node_tnid extends views_handler_argument_numeric {
+  /**
+   * Override the behavior of title(). Get the title of the node.
+   */
+  function title_query() {
+    $titles = array();
+
+    $result = db_query("SELECT n.title FROM {node} n WHERE n.tnid IN (:tnids)", array(':tnids' => $this->value));
+    foreach ($result as $term) {
+      $titles[] = check_plain($term->title);
+    }
+    return $titles;
+  }
+}
diff --git a/lib/Drupal/translation/Plugin/views/field/views_handler_field_node_link_translate.inc b/lib/Drupal/translation/Plugin/views/field/views_handler_field_node_link_translate.inc
new file mode 100644
index 000000000000..3e30725c9dcc
--- /dev/null
+++ b/lib/Drupal/translation/Plugin/views/field/views_handler_field_node_link_translate.inc
@@ -0,0 +1,29 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_node_link_translate.
+ */
+
+/**
+ * Field handler to present a link node translate.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_node_link_translate extends views_handler_field_node_link {
+  function render_link($data, $values) {
+    // ensure user has access to edit this node.
+    $node = $this->get_value($values);
+    $node->status = 1; // unpublished nodes ignore access control
+    if (empty($node->language) || !translation_supported_type($node->type) || !node_access('view', $node) || !user_access('translate content')) {
+      return;
+    }
+
+    $this->options['alter']['make_link'] = TRUE;
+    $this->options['alter']['path'] = "node/$node->nid/translate";
+    $this->options['alter']['query'] = drupal_get_destination();
+
+    $text = !empty($this->options['text']) ? $this->options['text'] : t('translate');
+    return $text;
+  }
+}
diff --git a/lib/Drupal/translation/Plugin/views/field/views_handler_field_node_translation_link.inc b/lib/Drupal/translation/Plugin/views/field/views_handler_field_node_translation_link.inc
new file mode 100644
index 000000000000..eb3a1ac4f791
--- /dev/null
+++ b/lib/Drupal/translation/Plugin/views/field/views_handler_field_node_translation_link.inc
@@ -0,0 +1,49 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_node_translation_link.
+ */
+
+/**
+ * Field handler to present a link to the node.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_node_translation_link extends views_handler_field {
+  function construct() {
+    parent::construct();
+    $this->additional_fields['nid'] = 'nid';
+    $this->additional_fields['tnid'] = 'tnid';
+    $this->additional_fields['title'] = 'title';
+    $this->additional_fields['language'] = 'language';
+  }
+
+  function query() {
+    $this->ensure_my_table();
+    $this->add_additional_fields();
+  }
+
+  function render($values) {
+    $value = $this->get_value($values, 'tnid');
+    return $this->render_link($this->sanitize_value($value), $values);
+  }
+
+  function render_link($data, $values) {
+    $language_interface = drupal_container()->get(LANGUAGE_TYPE_INTERFACE);
+
+    $tnid = $this->get_value($values, 'tnid');
+    // Only load translations if the node isn't in the current language.
+    if ($this->get_value($values, 'language') != $language_interface->langcode) {
+      $translations = translation_node_get_translations($tnid);
+      if (isset($translations[$language_interface->langcode])) {
+        $values->{$this->aliases['nid']} = $translations[$language_interface->langcode]->nid;
+        $values->{$this->aliases['title']} = $translations[$language_interface->langcode]->title;
+      }
+    }
+
+    $this->options['alter']['make_link'] = TRUE;
+    $this->options['alter']['path'] = "node/" . $this->get_value($values, 'nid');
+    return $this->get_value($values, 'title');
+  }
+}
diff --git a/lib/Drupal/translation/Plugin/views/filter/views_handler_filter_node_tnid.inc b/lib/Drupal/translation/Plugin/views/filter/views_handler_filter_node_tnid.inc
new file mode 100644
index 000000000000..ed4d6a9a7a26
--- /dev/null
+++ b/lib/Drupal/translation/Plugin/views/filter/views_handler_filter_node_tnid.inc
@@ -0,0 +1,45 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_filter_node_tnid.
+ */
+
+/**
+ * Filter by whether the node is the original translation.
+ *
+ * @ingroup views_filter_handlers
+ */
+class views_handler_filter_node_tnid extends views_handler_filter {
+  function admin_summary() { }
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['operator']['default'] = 1;
+
+    return $options;
+  }
+
+  /**
+   * Provide simple boolean operator
+   */
+  function operator_form(&$form, &$form_state) {
+    $form['operator'] = array(
+      '#type' => 'radios',
+      '#title' => t('Include untranslated content'),
+      '#default_value' => $this->operator,
+      '#options' => array(
+        1 => t('Yes'),
+        0 => t('No'),
+      ),
+    );
+  }
+
+  function can_expose() { return FALSE; }
+
+  function query() {
+    $table = $this->ensure_my_table();
+    // Select for source translations (tnid = nid). Conditionally, also accept either untranslated nodes (tnid = 0).
+    $this->query->add_where_expression($this->options['group'], "$table.tnid = $table.nid" . ($this->operator ? " OR $table.tnid = 0" : ''));
+  }
+}
diff --git a/lib/Drupal/translation/Plugin/views/filter/views_handler_filter_node_tnid_child.inc b/lib/Drupal/translation/Plugin/views/filter/views_handler_filter_node_tnid_child.inc
new file mode 100644
index 000000000000..51316eb332be
--- /dev/null
+++ b/lib/Drupal/translation/Plugin/views/filter/views_handler_filter_node_tnid_child.inc
@@ -0,0 +1,22 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_filter_node_tnid_child.
+ */
+
+/**
+ * Filter by whether the node is not the original translation.
+ *
+ * @ingroup views_filter_handlers
+ */
+class views_handler_filter_node_tnid_child extends views_handler_filter {
+  function admin_summary() { }
+  function operator_form(&$form, &$form_state) { }
+  function can_expose() { return FALSE; }
+
+  function query() {
+    $table = $this->ensure_my_table();
+    $this->query->add_where_expression($this->options['group'], "$table.tnid <> $table.nid AND $table.tnid > 0");
+  }
+}
diff --git a/lib/Drupal/translation/Plugin/views/relationship/views_handler_relationship_translation.inc b/lib/Drupal/translation/Plugin/views/relationship/views_handler_relationship_translation.inc
new file mode 100644
index 000000000000..ef27dca7cf17
--- /dev/null
+++ b/lib/Drupal/translation/Plugin/views/relationship/views_handler_relationship_translation.inc
@@ -0,0 +1,106 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_relationship_translation.
+ */
+
+use Drupal\views\Join;
+use Drupal\views\Plugins\views\relationship\RelationshipPluginBase;
+
+/**
+ * Handles relationships for content translation sets and provides multiple
+ * options.
+ *
+ * @ingroup views_relationship_handlers
+ */
+class views_handler_relationship_translation extends RelationshipPluginBase {
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['language'] = array('default' => 'current');
+
+    return $options;
+  }
+
+  /**
+   * Add a translation selector.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $options = array(
+      'all' => t('All'),
+      'current' => t('Current language'),
+      'default' => t('Default language'),
+    );
+    $options = array_merge($options, locale_language_list());
+    $form['language'] = array(
+      '#type' => 'select',
+      '#options' => $options,
+      '#default_value' => $this->options['language'],
+      '#title' => t('Translation option'),
+      '#description' => t('The translation options allows you to select which translation or translations in a translation set join on. Select "Current language" or "Default language" to join on the translation in the current or default language respectively. Select a specific language to join on a translation in that language. If you select "All", each translation will create a new row, which may appear to cause duplicates.'),
+    );
+  }
+
+  /**
+   * Called to implement a relationship in a query.
+   */
+  function query() {
+    // Figure out what base table this relationship brings to the party.
+    $table_data = views_fetch_data($this->definition['base']);
+    $base_field = empty($this->definition['base field']) ? $table_data['table']['base']['field'] : $this->definition['base field'];
+
+    $this->ensure_my_table();
+
+    $def = $this->definition;
+    $def['table'] = $this->definition['base'];
+    $def['field'] = $base_field;
+    $def['left_table'] = $this->table_alias;
+    $def['left_field'] = $this->field;
+    if (!empty($this->options['required'])) {
+      $def['type'] = 'INNER';
+    }
+
+    $def['extra'] = array();
+    if ($this->options['language'] != 'all') {
+      switch ($this->options['language']) {
+        case 'current':
+          $def['extra'][] = array(
+            'field' => 'language',
+            'value' => '***CURRENT_LANGUAGE***',
+          );
+          break;
+        case 'default':
+          $def['extra'][] = array(
+            'field' => 'language',
+            'value' => '***DEFAULT_LANGUAGE***',
+          );
+          break;
+        // Other values will be the language codes.
+        default:
+          $def['extra'][] = array(
+            'field' => 'language',
+            'value' => $this->options['language'],
+          );
+          break;
+      }
+    }
+
+    if (!empty($def['join_handler']) && class_exists($def['join_handler'])) {
+      $join = new $def['join_handler'];
+    }
+    else {
+      $join = new Join();
+    }
+
+    $join->definition = $def;
+    $join->construct();
+    $join->adjusted = TRUE;
+
+    // use a short alias for this:
+    $alias = $def['table'] . '_' . $this->table;
+
+    $this->alias = $this->query->add_relationship($alias, $join, $this->definition['base'], $this->relationship);
+  }
+}
diff --git a/lib/Drupal/user/Plugin/views/argument/views_handler_argument_user_uid.inc b/lib/Drupal/user/Plugin/views/argument/views_handler_argument_user_uid.inc
new file mode 100644
index 000000000000..1ded1984c9c0
--- /dev/null
+++ b/lib/Drupal/user/Plugin/views/argument/views_handler_argument_user_uid.inc
@@ -0,0 +1,35 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_argument_user_uid.
+ */
+
+use Drupal\views\Plugins\views\argument\Numeric;
+
+/**
+ * Argument handler to accept a user id.
+ *
+ * @ingroup views_argument_handlers
+ */
+class views_handler_argument_user_uid extends Numeric {
+  /**
+   * Override the behavior of title(). Get the name of the user.
+   *
+   * @return array
+   *    A list of usernames.
+   */
+  function title_query() {
+    if (!$this->argument) {
+      return array(variable_get('anonymous', t('Anonymous')));
+    }
+
+    $titles = array();
+
+    $result = db_query("SELECT u.name FROM {users} u WHERE u.uid IN (:uids)", array(':uids' => $this->value));
+    foreach ($result as $term) {
+      $titles[] = check_plain($term->name);
+    }
+    return $titles;
+  }
+}
diff --git a/lib/Drupal/user/Plugin/views/argument/views_handler_argument_users_roles_rid.inc b/lib/Drupal/user/Plugin/views/argument/views_handler_argument_users_roles_rid.inc
new file mode 100644
index 000000000000..7502a2fe096e
--- /dev/null
+++ b/lib/Drupal/user/Plugin/views/argument/views_handler_argument_users_roles_rid.inc
@@ -0,0 +1,25 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_argument_users_roles_rid.
+ */
+
+use Drupal\views\Plugins\views\argument\ManyToOne;
+
+/**
+ * Allow role ID(s) as argument.
+ *
+ * @ingroup views_argument_handlers
+ */
+class views_handler_argument_users_roles_rid extends ManyToOne {
+  function title_query() {
+    $titles = array();
+
+    $result = db_query("SELECT name FROM {role} WHERE rid IN (:rids)", array(':rids' => $this->value));
+    foreach ($result as $term) {
+      $titles[] = check_plain($term->name);
+    }
+    return $titles;
+  }
+}
diff --git a/lib/Drupal/user/Plugin/views/argument_default/views_plugin_argument_default_current_user.inc b/lib/Drupal/user/Plugin/views/argument_default/views_plugin_argument_default_current_user.inc
new file mode 100644
index 000000000000..0b10ec066fdd
--- /dev/null
+++ b/lib/Drupal/user/Plugin/views/argument_default/views_plugin_argument_default_current_user.inc
@@ -0,0 +1,20 @@
+<?php
+
+/**
+ * @file
+ * Contains the current user argument default plugin.
+ */
+
+use Drupal\views\Plugins\views\argument_default\ArgumentDefaultPluginBase;
+
+/**
+ * Default argument plugin to extract the global $user
+ *
+ * This plugin actually has no options so it odes not need to do a great deal.
+ */
+class views_plugin_argument_default_current_user extends ArgumentDefaultPluginBase {
+  function get_argument() {
+    global $user;
+    return $user->uid;
+  }
+}
diff --git a/lib/Drupal/user/Plugin/views/argument_default/views_plugin_argument_default_user.inc b/lib/Drupal/user/Plugin/views/argument_default/views_plugin_argument_default_user.inc
new file mode 100644
index 000000000000..02764f21ff7e
--- /dev/null
+++ b/lib/Drupal/user/Plugin/views/argument_default/views_plugin_argument_default_user.inc
@@ -0,0 +1,79 @@
+<?php
+
+/**
+ * @file
+ * Contains the user from URL argument default plugin.
+ */
+
+use Drupal\views\Plugins\views\argument_default\ArgumentDefaultPluginBase;
+
+/**
+ * Default argument plugin to extract a user via menu_get_object.
+ */
+class views_plugin_argument_default_user extends ArgumentDefaultPluginBase {
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['user'] = array('default' => '', 'bool' => TRUE, 'translatable' => FALSE);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['user'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Also look for a node and use the node author'),
+      '#default_value' => $this->options['user'],
+    );
+  }
+
+  function convert_options(&$options) {
+    if (!isset($options['user']) && isset($this->argument->options['default_argument_user'])) {
+      $options['user'] = $this->argument->options['default_argument_user'];
+    }
+  }
+
+  function get_argument() {
+    foreach (range(1, 3) as $i) {
+      $user = menu_get_object('user', $i);
+      if (!empty($user)) {
+        return $user->uid;
+      }
+    }
+
+    foreach (range(1, 3) as $i) {
+      $user = menu_get_object('user_uid_optional', $i);
+      if (!empty($user)) {
+        return $user->uid;
+      }
+    }
+
+    if (!empty($this->options['user'])) {
+      foreach (range(1, 3) as $i) {
+        $node = menu_get_object('node', $i);
+        if (!empty($node)) {
+          return $node->uid;
+        }
+      }
+    }
+
+    if (arg(0) == 'user' && is_numeric(arg(1))) {
+      return arg(1);
+    }
+
+    if (!empty($this->options['user'])) {
+      if (arg(0) == 'node' && is_numeric(arg(1))) {
+        $node = node_load(arg(1));
+        if ($node) {
+          return $node->uid;
+        }
+      }
+    }
+
+    // If the current page is a view that takes uid as an argument, return the uid.
+    $view = views_get_page_view();
+
+    if ($view && isset($view->argument['uid'])) {
+      return $view->argument['uid']->argument;
+    }
+  }
+}
diff --git a/lib/Drupal/user/Plugin/views/argument_validate/views_plugin_argument_validate_user.inc b/lib/Drupal/user/Plugin/views/argument_validate/views_plugin_argument_validate_user.inc
new file mode 100644
index 000000000000..74eb23f06420
--- /dev/null
+++ b/lib/Drupal/user/Plugin/views/argument_validate/views_plugin_argument_validate_user.inc
@@ -0,0 +1,142 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_plugin_argument_validate_user.
+ */
+
+use Drupal\views\Plugins\views\argument_validator\ArgumentValidatorPluginBase;
+
+/**
+ * Validate whether an argument is a valid user.
+ *
+ * This supports either numeric arguments (UID) or strings (username) and
+ * converts either one into the user's UID.  This validator also sets the
+ * argument's title to the username.
+ */
+class views_plugin_argument_validate_user extends ArgumentValidatorPluginBase {
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['type'] = array('default' => 'uid');
+    $options['restrict_roles'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['roles'] = array('default' => array());
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['type'] = array(
+      '#type' => 'radios',
+      '#title' => t('Type of user filter value to allow'),
+      '#options' => array(
+        'uid' => t('Only allow numeric UIDs'),
+        'name' => t('Only allow string usernames'),
+        'either' => t('Allow both numeric UIDs and string usernames'),
+      ),
+      '#default_value' => $this->options['type'],
+    );
+
+    $form['restrict_roles'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Restrict user based on role'),
+      '#default_value' => $this->options['restrict_roles'],
+    );
+
+    $form['roles'] = array(
+      '#type' => 'checkboxes',
+      '#title' => t('Restrict to the selected roles'),
+      '#options' => array_map('check_plain', user_roles(TRUE)),
+      '#default_value' => $this->options['roles'],
+      '#description' => t('If no roles are selected, users from any role will be allowed.'),
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[validate][options][user][restrict_roles]"]' => array('checked' => TRUE),
+        ),
+      ),
+    );
+  }
+
+  function options_submit(&$form, &$form_state, &$options = array()) {
+    // filter trash out of the options so we don't store giant unnecessary arrays
+    $options['roles'] = array_filter($options['roles']);
+  }
+
+  function convert_options(&$options) {
+    if (!isset($options['type']) && isset($this->argument->options['validate_user_argument_type'])) {
+      $options['type'] = $this->argument->options['validate_user_argument_type'];
+      $options['restrict_roles'] = $this->argument->options['validate_user_restrict_roles'];
+      $options['roles'] = $this->argument->options['validate_user_roles'];
+    }
+  }
+
+  function validate_argument($argument) {
+    $type = $this->options['type'];
+    // is_numeric() can return false positives, so we ensure it's an integer.
+    // However, is_integer() will always fail, since $argument is a string.
+    if (is_numeric($argument) && $argument == (int)$argument) {
+      if ($type == 'uid' || $type == 'either') {
+        if ($argument == $GLOBALS['user']->uid) {
+          // If you assign an object to a variable in PHP, the variable
+          // automatically acts as a reference, not a copy, so we use
+          // clone to ensure that we don't actually mess with the
+          // real global $user object.
+          $account = clone $GLOBALS['user'];
+        }
+        $where = 'uid = :argument';
+      }
+    }
+    else {
+      if ($type == 'name' || $type == 'either') {
+        $name = !empty($GLOBALS['user']->name) ? $GLOBALS['user']->name : variable_get('anonymous', t('Anonymous'));
+        if ($argument == $name) {
+          $account = clone $GLOBALS['user'];
+        }
+        $where = "name = :argument";
+      }
+    }
+
+    // If we don't have a WHERE clause, the argument is invalid.
+    if (empty($where)) {
+      return FALSE;
+    }
+
+    if (!isset($account)) {
+      $query = "SELECT uid, name FROM {users} WHERE $where";
+      $account = db_query($query, array(':argument' => $argument))->fetchObject();
+    }
+    if (empty($account)) {
+      // User not found.
+      return FALSE;
+    }
+
+    // See if we're filtering users based on roles.
+    if (!empty($this->options['restrict_roles']) && !empty($this->options['roles'])) {
+      $roles = $this->options['roles'];
+      $account->roles = array();
+      $account->roles[] = $account->uid ? DRUPAL_AUTHENTICATED_RID : DRUPAL_ANONYMOUS_RID;
+      $result = db_query('SELECT rid FROM {users_roles} WHERE uid = :uid', array(':uid' => $account->uid));
+      foreach ($result as $role) {
+        $account->roles[] = $role->rid;
+      }
+      if (!(bool) array_intersect($account->roles, $roles)) {
+        return FALSE;
+      }
+    }
+
+    $this->argument->argument = $account->uid;
+    $this->argument->validated_title = check_plain(user_format_name($account));
+    return TRUE;
+  }
+
+  function process_summary_arguments(&$args) {
+    // If the validation says the input is an username, we should reverse the
+    // argument so it works for example for generation summary urls.
+    $uids_arg_keys = array_flip($args);
+    if ($this->options['type'] == 'name') {
+      $users = user_load_multiple($args);
+      foreach ($users as $uid => $account) {
+        $args[$uids_arg_keys[$uid]] = $account->name;
+      }
+    }
+  }
+}
diff --git a/lib/Drupal/user/Plugin/views/field/views_handler_field_user.inc b/lib/Drupal/user/Plugin/views/field/views_handler_field_user.inc
new file mode 100644
index 000000000000..f6b15b5bc112
--- /dev/null
+++ b/lib/Drupal/user/Plugin/views/field/views_handler_field_user.inc
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_user.
+ */
+
+/**
+ * Field handler to provide simple renderer that allows linking to a user.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_user extends views_handler_field {
+  /**
+   * Override init function to provide generic option to link to user.
+   */
+  function init(&$view, &$data) {
+    parent::init($view, $data);
+    if (!empty($this->options['link_to_user'])) {
+      $this->additional_fields['uid'] = 'uid';
+    }
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['link_to_user'] = array('default' => TRUE, 'bool' => TRUE);
+    return $options;
+  }
+
+  /**
+   * Provide link to node option
+   */
+  function options_form(&$form, &$form_state) {
+    $form['link_to_user'] = array(
+      '#title' => t('Link this field to its user'),
+      '#description' => t("Enable to override this field's links."),
+      '#type' => 'checkbox',
+      '#default_value' => $this->options['link_to_user'],
+    );
+    parent::options_form($form, $form_state);
+  }
+
+  function render_link($data, $values) {
+    if (!empty($this->options['link_to_user']) && user_access('access user profiles') && ($uid = $this->get_value($values, 'uid')) && $data !== NULL && $data !== '') {
+      $this->options['alter']['make_link'] = TRUE;
+      $this->options['alter']['path'] = "user/" . $uid;
+    }
+    return $data;
+  }
+
+  function render($values) {
+    $value = $this->get_value($values);
+    return $this->render_link($this->sanitize_value($value), $values);
+  }
+}
diff --git a/lib/Drupal/user/Plugin/views/field/views_handler_field_user_language.inc b/lib/Drupal/user/Plugin/views/field/views_handler_field_user_language.inc
new file mode 100644
index 000000000000..e29da31a14db
--- /dev/null
+++ b/lib/Drupal/user/Plugin/views/field/views_handler_field_user_language.inc
@@ -0,0 +1,39 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_user_language.
+ */
+
+/**
+ * Views field handler for user language.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_user_language extends views_handler_field_user {
+
+  function render_link($data, $values) {
+    $uid = $this->get_value($values, 'uid');
+    if (!empty($this->options['link_to_user'])) {
+      $uid = $this->get_value($values, 'uid');
+      if (user_access('access user profiles') && $uid) {
+        $this->options['alter']['make_link'] = TRUE;
+        $this->options['alter']['path'] = 'user/' . $uid;
+      }
+    }
+    if (empty($data)) {
+      $lang = language_default();
+    }
+    else {
+      $lang = language_list();
+      $lang = $lang[$data];
+    }
+
+    return $this->sanitize_value($lang->name);
+  }
+
+  function render($values) {
+    $value = $this->get_value($values);
+    return $this->render_link($this->sanitize_value($value), $values);
+  }
+}
diff --git a/lib/Drupal/user/Plugin/views/field/views_handler_field_user_link.inc b/lib/Drupal/user/Plugin/views/field/views_handler_field_user_link.inc
new file mode 100644
index 000000000000..03b5e0d4ae2f
--- /dev/null
+++ b/lib/Drupal/user/Plugin/views/field/views_handler_field_user_link.inc
@@ -0,0 +1,58 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_user_link.
+ */
+
+/**
+ * Field handler to present a link to the user.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_user_link extends views_handler_field {
+  function construct() {
+    parent::construct();
+    $this->additional_fields['uid'] = 'uid';
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['text'] = array('default' => '', 'translatable' => TRUE);
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['text'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Text to display'),
+      '#default_value' => $this->options['text'],
+    );
+    parent::options_form($form, $form_state);
+  }
+
+  // An example of field level access control.
+  function access() {
+    return user_access('access user profiles');
+  }
+
+  function query() {
+    $this->ensure_my_table();
+    $this->add_additional_fields();
+  }
+
+  function render($values) {
+    $value = $this->get_value($values, 'uid');
+    return $this->render_link($this->sanitize_value($value), $values);
+  }
+
+  function render_link($data, $values) {
+    $text = !empty($this->options['text']) ? $this->options['text'] : t('view');
+
+    $this->options['alter']['make_link'] = TRUE;
+    $this->options['alter']['path'] = "user/" . $data;
+
+    return $text;
+  }
+
+}
diff --git a/lib/Drupal/user/Plugin/views/field/views_handler_field_user_link_cancel.inc b/lib/Drupal/user/Plugin/views/field/views_handler_field_user_link_cancel.inc
new file mode 100644
index 000000000000..d66f98f8e007
--- /dev/null
+++ b/lib/Drupal/user/Plugin/views/field/views_handler_field_user_link_cancel.inc
@@ -0,0 +1,33 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_user_link_cancel.
+ */
+
+/**
+ * Field handler to present a link to user cancel.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_user_link_cancel extends views_handler_field_user_link {
+
+  function render_link($data, $values) {
+    $uid = $values->{$this->aliases['uid']};
+
+    // Build a pseudo account object to be able to check the access.
+    $account = entity_create('user', array());
+    $account->uid = $uid;
+
+    if ($uid && user_cancel_access($account)) {
+      $this->options['alter']['make_link'] = TRUE;
+
+      $text = !empty($this->options['text']) ? $this->options['text'] : t('cancel');
+
+      $this->options['alter']['path'] = "user/$uid/cancel";
+      $this->options['alter']['query'] = drupal_get_destination();
+
+      return $text;
+    }
+  }
+}
diff --git a/lib/Drupal/user/Plugin/views/field/views_handler_field_user_link_edit.inc b/lib/Drupal/user/Plugin/views/field/views_handler_field_user_link_edit.inc
new file mode 100644
index 000000000000..252cecdb05b7
--- /dev/null
+++ b/lib/Drupal/user/Plugin/views/field/views_handler_field_user_link_edit.inc
@@ -0,0 +1,30 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_user_link_edit.
+ */
+
+/**
+ * Field handler to present a link to user edit.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_user_link_edit extends views_handler_field_user_link {
+  function render_link($data, $values) {
+    // Build a pseudo account object to be able to check the access.
+    $account = entity_create('user', array());
+    $account->uid = $data;
+
+    if ($data && user_edit_access($account)) {
+      $this->options['alter']['make_link'] = TRUE;
+
+      $text = !empty($this->options['text']) ? $this->options['text'] : t('edit');
+
+      $this->options['alter']['path'] = "user/$data/edit";
+      $this->options['alter']['query'] = drupal_get_destination();
+
+      return $text;
+    }
+  }
+}
diff --git a/lib/Drupal/user/Plugin/views/field/views_handler_field_user_mail.inc b/lib/Drupal/user/Plugin/views/field/views_handler_field_user_mail.inc
new file mode 100644
index 000000000000..82d193388c37
--- /dev/null
+++ b/lib/Drupal/user/Plugin/views/field/views_handler_field_user_mail.inc
@@ -0,0 +1,44 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_user_mail.
+ */
+
+/**
+ * Field handler to provide acess control for the email field.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_user_mail extends views_handler_field_user {
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['link_to_user'] = array('default' => 'mailto');
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $form['link_to_user'] = array(
+      '#title' => t('Link this field'),
+      '#type' => 'radios',
+      '#options' => array(
+        0 => t('No link'),
+        'user' => t('To the user'),
+        'mailto' => t("With a mailto:"),
+      ),
+      '#default_value' => $this->options['link_to_user'],
+    );
+  }
+
+  function render_link($data, $values) {
+    parent::render_link($data, $values);
+
+    if ($this->options['link_to_user'] == 'mailto') {
+      $this->options['alter']['make_link'] = TRUE;
+      $this->options['alter']['path'] = "mailto:" . $data;
+    }
+
+    return $data;
+  }
+}
diff --git a/lib/Drupal/user/Plugin/views/field/views_handler_field_user_name.inc b/lib/Drupal/user/Plugin/views/field/views_handler_field_user_name.inc
new file mode 100644
index 000000000000..8947db1aa21e
--- /dev/null
+++ b/lib/Drupal/user/Plugin/views/field/views_handler_field_user_name.inc
@@ -0,0 +1,85 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_user_name.
+ */
+
+/**
+ * Field handler to provide simple renderer that allows using a themed user link.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_user_name extends views_handler_field_user {
+  /**
+   * Add uid in the query so we can test for anonymous if needed.
+   */
+  function init(&$view, &$data) {
+    parent::init($view, $data);
+    if (!empty($this->options['overwrite_anonymous']) || !empty($this->options['format_username'])) {
+      $this->additional_fields['uid'] = 'uid';
+    }
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['overwrite_anonymous'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['anonymous_text'] = array('default' => '', 'translatable' => TRUE);
+    $options['format_username'] = array('default' => TRUE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['format_username'] = array(
+      '#title' => t('Use formatted username'),
+      '#type' => 'checkbox',
+      '#default_value' => !empty($this->options['format_username']),
+      '#description' => t('If checked, the username will be formatted by the system. If unchecked, it will be displayed raw.'),
+      '#fieldset' => 'more',
+    );
+    $form['overwrite_anonymous'] = array(
+      '#title' => t('Overwrite the value to display for anonymous users'),
+      '#type' => 'checkbox',
+      '#default_value' => !empty($this->options['overwrite_anonymous']),
+      '#description' => t('Enable to display different text for anonymous users.'),
+      '#fieldset' => 'more',
+    );
+    $form['anonymous_text'] = array(
+      '#title' => t('Text to display for anonymous users'),
+      '#type' => 'textfield',
+      '#default_value' => $this->options['anonymous_text'],
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[overwrite_anonymous]"]' => array('checked' => TRUE),
+        ),
+      ),
+      '#fieldset' => 'more',
+    );
+
+    parent::options_form($form, $form_state);
+  }
+
+  function render_link($data, $values) {
+    $account = entity_create('user', array());
+    $account->uid = $this->get_value($values, 'uid');
+    $account->name = $this->get_value($values);
+    if (!empty($this->options['link_to_user']) || !empty($this->options['overwrite_anonymous'])) {
+      if (!empty($this->options['overwrite_anonymous']) && !$account->uid) {
+        // This is an anonymous user, and we're overriting the text.
+        return check_plain($this->options['anonymous_text']);
+      }
+      elseif (!empty($this->options['link_to_user'])) {
+        $account->name = $this->get_value($values);
+        return theme('username', array('account' => $account));
+      }
+    }
+    // If we want a formatted username, do that.
+    if (!empty($this->options['format_username'])) {
+      return user_format_name($account);
+    }
+    // Otherwise, there's no special handling, so return the data directly.
+    return $data;
+  }
+}
diff --git a/lib/Drupal/user/Plugin/views/field/views_handler_field_user_permissions.inc b/lib/Drupal/user/Plugin/views/field/views_handler_field_user_permissions.inc
new file mode 100644
index 000000000000..edc9c44615eb
--- /dev/null
+++ b/lib/Drupal/user/Plugin/views/field/views_handler_field_user_permissions.inc
@@ -0,0 +1,68 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_user_permissions.
+ */
+
+/**
+ * Field handler to provide a list of permissions.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_user_permissions extends views_handler_field_prerender_list {
+  function construct() {
+    parent::construct();
+    $this->additional_fields['uid'] = array('table' => 'users', 'field' => 'uid');
+  }
+
+  function query() {
+    $this->add_additional_fields();
+    $this->field_alias = $this->aliases['uid'];
+  }
+
+  function pre_render(&$values) {
+    $uids = array();
+    $this->items = array();
+
+    foreach ($values as $result) {
+      $uids[] = $this->get_value($result, NULL, TRUE);
+    }
+
+    if ($uids) {
+      // Get a list of all the modules implementing a hook_permission() and sort by
+      // display name.
+      $module_info = system_get_info('module');
+      $modules = array();
+      foreach (module_implements('permission') as $module) {
+        $modules[$module] = $module_info[$module]['name'];
+      }
+      asort($modules);
+
+      $permissions = module_invoke_all('permission');
+
+      $result = db_query("SELECT u.uid, u.rid, rp.permission FROM {role_permission} rp INNER JOIN {users_roles} u ON u.rid = rp.rid WHERE u.uid IN (:uids) AND rp.module IN (:modules) ORDER BY rp.permission",
+        array(':uids' => $uids, ':modules' => array_keys($modules)));
+
+      foreach ($result as $perm) {
+        $this->items[$perm->uid][$perm->permission]['permission'] = $permissions[$perm->permission]['title'];
+      }
+    }
+  }
+
+  function render_item($count, $item) {
+    return $item['permission'];
+  }
+
+  /*
+  function document_self_tokens(&$tokens) {
+    $tokens['[' . $this->options['id'] . '-role' . ']'] = t('The name of the role.');
+    $tokens['[' . $this->options['id'] . '-rid' . ']'] = t('The role ID of the role.');
+  }
+
+  function add_self_tokens(&$tokens, $item) {
+    $tokens['[' . $this->options['id'] . '-role' . ']'] = $item['role'];
+    $tokens['[' . $this->options['id'] . '-rid' . ']'] = $item['rid'];
+  }
+  */
+}
diff --git a/lib/Drupal/user/Plugin/views/field/views_handler_field_user_picture.inc b/lib/Drupal/user/Plugin/views/field/views_handler_field_user_picture.inc
new file mode 100644
index 000000000000..4bc80c62b3ba
--- /dev/null
+++ b/lib/Drupal/user/Plugin/views/field/views_handler_field_user_picture.inc
@@ -0,0 +1,116 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_user_picture.
+ */
+
+use Drupal\views\Plugins\views\field\FieldPluginBase;
+
+/**
+ * Field handler to provide simple renderer that allows using a themed user link.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_user_picture extends FieldPluginBase {
+  function construct() {
+    parent::construct();
+    $this->additional_fields['uid'] = 'uid';
+    $this->additional_fields['name'] = 'name';
+    $this->additional_fields['mail'] = 'mail';
+  }
+
+  function element_type($none_supported = FALSE, $default_empty = FALSE, $inline = FALSE) {
+    if ($inline) {
+      return 'span';
+    }
+    if ($none_supported) {
+      if ($this->options['element_type'] === '0') {
+        return '';
+      }
+    }
+    if ($this->options['element_type']) {
+      return check_plain($this->options['element_type']);
+    }
+    if ($default_empty) {
+      return '';
+    }
+    if (isset($this->definition['element type'])) {
+      return $this->definition['element type'];
+    }
+
+    return 'div';
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['link_photo_to_profile'] = array('default' => TRUE, 'bool' => TRUE);
+    $options['image_style'] = array('default' => '');
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $form['link_photo_to_profile'] = array(
+      '#title' => t("Link to user's profile"),
+      '#description' => t("Link the user picture to the user's profile"),
+      '#type' => 'checkbox',
+      '#default_value' => $this->options['link_photo_to_profile'],
+    );
+
+    if (module_exists('image')) {
+      $styles = image_styles();
+      $style_options = array('' => t('Default'));
+      foreach ($styles as $style) {
+        $style_options[$style['name']] = $style['name'];
+      }
+
+      $form['image_style'] = array(
+        '#title' => t('Image style'),
+        '#description' => t('Using <em>Default</em> will use the site-wide image style for user pictures set in the <a href="!account-settings">Account settings</a>.', array('!account-settings' => url('admin/config/people/accounts', array('fragment' => 'edit-personalization')))),
+        '#type' => 'select',
+        '#options' => $style_options,
+        '#default_value' => $this->options['image_style'],
+      );
+    }
+  }
+
+  function render($values) {
+    if ($this->options['image_style'] && module_exists('image')) {
+      // @todo: Switch to always using theme('user_picture') when it starts
+      // supporting image styles. See http://drupal.org/node/1021564
+      if ($picture_fid = $this->get_value($values)) {
+        $picture = file_load($picture_fid);
+        $picture_filepath = $picture->uri;
+      }
+      else {
+        $picture_filepath = variable_get('user_picture_default', '');
+      }
+      if (file_valid_uri($picture_filepath)) {
+        $output = theme('image_style', array('style_name' => $this->options['image_style'], 'path' => $picture_filepath));
+        if ($this->options['link_photo_to_profile'] && user_access('access user profiles')) {
+          $uid = $this->get_value($values, 'uid');
+          $output = l($output, "user/$uid", array('html' => TRUE));
+        }
+      }
+      else {
+        $output = '';
+      }
+    }
+    else {
+      // Fake an account object.
+      $account = entity_create('user', array());
+      if ($this->options['link_photo_to_profile']) {
+        // Prevent template_preprocess_user_picture from adding a link
+        // by not setting the uid.
+        $account->uid = $this->get_value($values, 'uid');
+      }
+      $account->name = $this->get_value($values, 'name');
+      $account->mail = $this->get_value($values, 'mail');
+      $account->picture = $this->get_value($values);
+      $output = theme('user_picture', array('account' => $account));
+    }
+
+    return $output;
+  }
+}
diff --git a/lib/Drupal/user/Plugin/views/field/views_handler_field_user_roles.inc b/lib/Drupal/user/Plugin/views/field/views_handler_field_user_roles.inc
new file mode 100644
index 000000000000..6ee5062ab50d
--- /dev/null
+++ b/lib/Drupal/user/Plugin/views/field/views_handler_field_user_roles.inc
@@ -0,0 +1,59 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_user_roles.
+ */
+
+use Drupal\views\Plugins\views\field\PrerenderList;
+
+/**
+ * Field handler to provide a list of roles.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_user_roles extends PrerenderList {
+  function construct() {
+    parent::construct();
+    $this->additional_fields['uid'] = array('table' => 'users', 'field' => 'uid');
+  }
+
+  function query() {
+    $this->add_additional_fields();
+    $this->field_alias = $this->aliases['uid'];
+  }
+
+  function pre_render(&$values) {
+    $uids = array();
+    $this->items = array();
+
+    foreach ($values as $result) {
+      $uids[] = $this->get_value($result, NULL, TRUE);
+    }
+
+    if ($uids) {
+      $result = db_query("SELECT u.uid, u.rid, r.name FROM {role} r INNER JOIN {users_roles} u ON u.rid = r.rid WHERE u.uid IN (:uids) ORDER BY r.name",
+        array(':uids' => $uids));
+      foreach ($result as $role) {
+        $this->items[$role->uid][$role->rid]['role'] = check_plain($role->name);
+        $this->items[$role->uid][$role->rid]['rid'] = $role->rid;
+      }
+    }
+  }
+
+  function render_item($count, $item) {
+    return $item['role'];
+  }
+
+  function document_self_tokens(&$tokens) {
+    $tokens['[' . $this->options['id'] . '-role' . ']'] = t('The name of the role.');
+    $tokens['[' . $this->options['id'] . '-rid' . ']'] = t('The role machine-name of the role.');
+  }
+
+  function add_self_tokens(&$tokens, $item) {
+    if (!empty($item['role'])) {
+      $tokens['[' . $this->options['id'] . '-role' . ']'] = $item['role'];
+      $tokens['[' . $this->options['id'] . '-rid' . ']'] = $item['rid'];
+    }
+  }
+}
diff --git a/lib/Drupal/user/Plugin/views/filter/views_handler_filter_user_current.inc b/lib/Drupal/user/Plugin/views/filter/views_handler_filter_user_current.inc
new file mode 100644
index 000000000000..8ac8ba8579b2
--- /dev/null
+++ b/lib/Drupal/user/Plugin/views/filter/views_handler_filter_user_current.inc
@@ -0,0 +1,38 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_filter_user_current.
+ */
+
+use Drupal\views\Plugins\views\filter\BooleanOperator;
+
+/**
+ * Filter handler for the current user.
+ *
+ * @ingroup views_filter_handlers
+ */
+class views_handler_filter_user_current extends BooleanOperator {
+  function construct() {
+    parent::construct();
+    $this->value_value = t('Is the logged in user');
+  }
+
+  function query() {
+    $this->ensure_my_table();
+
+    $field = $this->table_alias . '.' . $this->real_field . ' ';
+    $or = db_or();
+
+    if (empty($this->value)) {
+      $or->condition($field, '***CURRENT_USER***', '<>');
+      if ($this->accept_null) {
+        $or->isNull($field);
+      }
+    }
+    else {
+      $or->condition($field, '***CURRENT_USER***', '=');
+    }
+    $this->query->add_where($this->options['group'], $or);
+  }
+}
diff --git a/lib/Drupal/user/Plugin/views/filter/views_handler_filter_user_name.inc b/lib/Drupal/user/Plugin/views/filter/views_handler_filter_user_name.inc
new file mode 100644
index 000000000000..fc883f34e478
--- /dev/null
+++ b/lib/Drupal/user/Plugin/views/filter/views_handler_filter_user_name.inc
@@ -0,0 +1,152 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_filter_user_name.
+ */
+
+use Drupal\views\Plugins\views\filter\InOperator;
+
+/**
+ * Filter handler for usernames.
+ *
+ * @ingroup views_filter_handlers
+ */
+class views_handler_filter_user_name extends InOperator {
+  var $always_multiple = TRUE;
+
+  function value_form(&$form, &$form_state) {
+    $values = array();
+    if ($this->value) {
+      $result = db_query("SELECT * FROM {users} u WHERE uid IN (:uids)", array(':uids' => $this->value));
+      foreach ($result as $account) {
+        if ($account->uid) {
+          $values[] = $account->name;
+        }
+        else {
+          $values[] = 'Anonymous'; // Intentionally NOT translated.
+        }
+      }
+    }
+
+    sort($values);
+    $default_value = implode(', ', $values);
+    $form['value'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Usernames'),
+      '#description' => t('Enter a comma separated list of user names.'),
+      '#default_value' => $default_value,
+      '#autocomplete_path' => 'admin/views/ajax/autocomplete/user',
+    );
+
+    if (!empty($form_state['exposed']) && !isset($form_state['input'][$this->options['expose']['identifier']])) {
+      $form_state['input'][$this->options['expose']['identifier']] = $default_value;
+    }
+  }
+
+  function value_validate($form, &$form_state) {
+    $values = drupal_explode_tags($form_state['values']['options']['value']);
+    $uids = $this->validate_user_strings($form['value'], $values);
+
+    if ($uids) {
+      $form_state['values']['options']['value'] = $uids;
+    }
+  }
+
+  function accept_exposed_input($input) {
+    $rc = parent::accept_exposed_input($input);
+
+    if ($rc) {
+      // If we have previously validated input, override.
+      if (isset($this->validated_exposed_input)) {
+        $this->value = $this->validated_exposed_input;
+      }
+    }
+
+    return $rc;
+  }
+
+  function exposed_validate(&$form, &$form_state) {
+    if (empty($this->options['exposed'])) {
+      return;
+    }
+
+    if (empty($this->options['expose']['identifier'])) {
+      return;
+    }
+
+    $identifier = $this->options['expose']['identifier'];
+    $values = drupal_explode_tags($form_state['values'][$identifier]);
+
+    $uids = $this->validate_user_strings($form[$identifier], $values);
+
+    if ($uids) {
+      $this->validated_exposed_input = $uids;
+    }
+  }
+
+  /**
+   * Validate the user string. Since this can come from either the form
+   * or the exposed filter, this is abstracted out a bit so it can
+   * handle the multiple input sources.
+   */
+  function validate_user_strings(&$form, $values) {
+    $uids = array();
+    $placeholders = array();
+    $args = array();
+    $results = array();
+    foreach ($values as $value) {
+      if (strtolower($value) == 'anonymous') {
+        $uids[] = 0;
+      }
+      else {
+        $missing[strtolower($value)] = TRUE;
+        $args[] = $value;
+        $placeholders[] = "'%s'";
+      }
+    }
+
+    if (!$args) {
+      return $uids;
+    }
+
+    $result = db_query("SELECT * FROM {users} WHERE name IN (:names)", array(':names' => $args));
+    foreach ($result as $account) {
+      unset($missing[strtolower($account->name)]);
+      $uids[] = $account->uid;
+    }
+
+    if ($missing) {
+      form_error($form, format_plural(count($missing), 'Unable to find user: @users', 'Unable to find users: @users', array('@users' => implode(', ', array_keys($missing)))));
+    }
+
+    return $uids;
+  }
+
+  function value_submit($form, &$form_state) {
+    // prevent array filter from removing our anonymous user.
+  }
+
+  // Override to do nothing.
+  function get_value_options() { }
+
+  function admin_summary() {
+    // set up $this->value_options for the parent summary
+    $this->value_options = array();
+
+    if ($this->value) {
+      $result = db_query("SELECT * FROM {users} u WHERE uid IN (:uids)", array(':uids' => $this->value));
+
+      foreach ($result as $account) {
+        if ($account->uid) {
+          $this->value_options[$account->uid] = $account->name;
+        }
+        else {
+          $this->value_options[$account->uid] = 'Anonymous'; // Intentionally NOT translated.
+        }
+      }
+    }
+
+    return parent::admin_summary();
+  }
+}
diff --git a/lib/Drupal/user/Plugin/views/filter/views_handler_filter_user_permissions.inc b/lib/Drupal/user/Plugin/views/filter/views_handler_filter_user_permissions.inc
new file mode 100644
index 000000000000..14c2aeaabc71
--- /dev/null
+++ b/lib/Drupal/user/Plugin/views/filter/views_handler_filter_user_permissions.inc
@@ -0,0 +1,37 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_filter_user_permissions.
+ */
+
+use Drupal\views\Plugins\views\filter\ManyToOne;
+
+/**
+ * Filter handler for user roles.
+ *
+ * @ingroup views_filter_handlers
+ */
+class views_handler_filter_user_permissions extends ManyToOne {
+  function get_value_options() {
+    $module_info = system_get_info('module');
+
+    // Get a list of all the modules implementing a hook_permission() and sort by
+    // display name.
+    $modules = array();
+    foreach (module_implements('permission') as $module) {
+      $modules[$module] = $module_info[$module]['name'];
+    }
+    asort($modules);
+
+    $this->value_options = array();
+    foreach ($modules as $module => $display_name) {
+      if ($permissions = module_invoke($module, 'permission')) {
+        foreach ($permissions as $perm => $perm_item) {
+          // @todo: group by module but views_handler_filter_many_to_one does not support this.
+          $this->value_options[$perm] = check_plain(strip_tags($perm_item['title']));
+        }
+      }
+    }
+  }
+}
diff --git a/lib/Drupal/user/Plugin/views/filter/views_handler_filter_user_roles.inc b/lib/Drupal/user/Plugin/views/filter/views_handler_filter_user_roles.inc
new file mode 100644
index 000000000000..e0f96d8e29e9
--- /dev/null
+++ b/lib/Drupal/user/Plugin/views/filter/views_handler_filter_user_roles.inc
@@ -0,0 +1,30 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_filter_user_roles.
+ */
+
+use Drupal\views\Plugins\views\filter\ManyToOne;
+
+/**
+ * Filter handler for user roles.
+ *
+ * @ingroup views_filter_handlers
+ */
+class views_handler_filter_user_roles extends ManyToOne {
+  function get_value_options() {
+    $this->value_options = user_roles(TRUE);
+    unset($this->value_options[DRUPAL_AUTHENTICATED_RID]);
+  }
+
+  /**
+   * Override empty and not empty operator labels to be clearer for user roles.
+   */
+  function operators() {
+    $operators = parent::operators();
+    $operators['empty']['title'] = t("Only has the 'authenticated user' role");
+    $operators['not empty']['title'] = t("Has roles in addition to 'authenticated user'");
+    return $operators;
+  }
+}
diff --git a/lib/Drupal/user/Plugin/views/row/views_plugin_row_user_view.inc b/lib/Drupal/user/Plugin/views/row/views_plugin_row_user_view.inc
new file mode 100644
index 000000000000..336d4d91dacc
--- /dev/null
+++ b/lib/Drupal/user/Plugin/views/row/views_plugin_row_user_view.inc
@@ -0,0 +1,83 @@
+<?php
+
+/**
+ * @file
+ * Contains the user view row plugin.
+ */
+
+use Drupal\views\Plugins\views\row\RowPluginBase;
+
+/**
+ * A row plugin which renders a user via user_view.
+ *
+ * @ingroup views_row_plugins
+ */
+class views_plugin_row_user_view extends RowPluginBase {
+  var $base_table = 'users';
+  var $base_field = 'uid';
+
+  // Store the users to be used for pre_render.
+  var $users = array();
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['view_mode'] = array('default' => 'full');
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $options = $this->options_form_summary_options();
+    $form['view_mode'] = array(
+      '#type' => 'select',
+      '#options' => $options,
+      '#title' => t('View mode'),
+      '#default_value' => $this->options['view_mode'],
+     );
+    $form['help']['#markup'] = t("Display the user with standard user view. It might be necessary to add a user-profile.tpl.php in your themes template folder, because the default <a href=\"@user-profile-api-link\">user-profile</a>e template don't show the username per default.", array('@user-profile-api-link' => url('http://api.drupal.org/api/drupal/modules--user--user-profile.tpl.php/7')));
+  }
+
+
+    /**
+     * Return the main options, which are shown in the summary title.
+     */
+    function options_form_summary_options() {
+      $entity_info = entity_get_info('user');
+      $options = array();
+      if (!empty($entity_info['view modes'])) {
+        foreach ($entity_info['view modes'] as $mode => $settings) {
+          $options[$mode] = $settings['label'];
+        }
+      }
+      if (empty($options)) {
+        $options = array(
+          'full' => t('User account')
+        );
+      }
+
+      return $options;
+    }
+
+    function summary_title() {
+      $options = $this->options_form_summary_options();
+      return check_plain($options[$this->options['view_mode']]);
+    }
+
+  function pre_render($values) {
+    $uids = array();
+    foreach ($values as $row) {
+      $uids[] = $row->{$this->field_alias};
+    }
+    $this->users = user_load_multiple($uids);
+  }
+
+  function render($row) {
+    $account = $this->users[$row->{$this->field_alias}];
+    $account->view = $this->view;
+    $build = user_view($account, $this->options['view_mode']);
+
+    return drupal_render($build);
+  }
+}
-- 
GitLab