diff --git a/core/modules/node/lib/Drupal/node/Plugin/views/argument_validator/Node.php b/core/modules/node/lib/Drupal/node/Plugin/views/argument_validator/Node.php
deleted file mode 100644
index 41f49a8..0000000
--- a/core/modules/node/lib/Drupal/node/Plugin/views/argument_validator/Node.php
+++ /dev/null
@@ -1,141 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\node\Plugin\views\argument_validator\Node.
- */
-
-namespace Drupal\node\Plugin\views\argument_validator;
-
-use Drupal\views\Plugin\views\argument_validator\ArgumentValidatorPluginBase;
-
-/**
- * Validate whether an argument is an acceptable node.
- *
- * @ViewsArgumentValidator(
- *   id = "node",
- *   title = @Translation("Content")
- * )
- */
-class Node extends ArgumentValidatorPluginBase {
-
-  protected function defineOptions() {
-    $options = parent::defineOptions();
-    $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;
-  }
-
-  public function buildOptionsForm(&$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'],
-    );
-  }
-
-  public function submitOptionsForm(&$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']);
-  }
-
-  public function validateArgument($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'])) {
-            return FALSE;
-          }
-        }
-
-        // Save the title() handlers some work.
-        $this->argument->validated_title = check_plain($node->label());
-
-        if (empty($types)) {
-          return TRUE;
-        }
-
-        return isset($types[$node->getType()]);
-
-      case 'nids':
-        $nids = new stdClass();
-        $nids->value = array($argument);
-        $nids = $this->breakPhrase($argument, $nids);
-        if ($nids->value == array(-1)) {
-          return FALSE;
-        }
-
-        $test = array_combine($nids->value, $nids->value);
-        $titles = array();
-
-        $nodes = node_load_multiple($nids->value);
-        foreach ($nodes as $node) {
-          if ($types && empty($types[$node->getType()])) {
-            return FALSE;
-          }
-
-          if (!empty($this->options['access'])) {
-            if (!$node->access($this->options['access_op'])) {
-              return FALSE;
-            }
-          }
-
-          $titles[] = check_plain($node->label());
-          unset($test[$node->id()]);
-        }
-
-        $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/core/modules/user/lib/Drupal/user/Plugin/views/argument_validator/User.php b/core/modules/user/lib/Drupal/user/Plugin/views/argument_validator/User.php
index d385236..8d2cb30 100644
--- a/core/modules/user/lib/Drupal/user/Plugin/views/argument_validator/User.php
+++ b/core/modules/user/lib/Drupal/user/Plugin/views/argument_validator/User.php
@@ -7,9 +7,9 @@
 
 namespace Drupal\user\Plugin\views\argument_validator;
 
-use Drupal\Core\Database\Connection;
-use Drupal\views\Plugin\views\argument_validator\ArgumentValidatorPluginBase;
-use Symfony\Component\DependencyInjection\ContainerInterface;
+use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\user\UserInterface;
+use Drupal\views\Plugin\views\argument_validator\Entity;
 
 /**
  * Validate whether an argument is a valid user.
@@ -17,66 +17,41 @@
  * 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.
- *
- * @ViewsArgumentValidator(
- *   id = "user",
- *   title = @Translation("User")
- * )
  */
-class User extends ArgumentValidatorPluginBase {
+class User extends Entity {
 
   /**
-   * Database Service Object.
+   * The user storage controller.
    *
-   * @var \Drupal\Core\Database\Connection
+   * @var \Drupal\Core\Entity\EntityStorageControllerInterface
    */
-  protected $database;
+  protected $userStorage;
 
   /**
-   * Constructs a Drupal\Component\Plugin\PluginBase object.
-   *
-   * @param array $configuration
-   *   A configuration array containing information about the plugin instance.
-   * @param string $plugin_id
-   *   The plugin_id for the plugin instance.
-   * @param array $plugin_definition
-   *   The plugin implementation definition.
-   * @param \Drupal\Core\Database\Connection $database
-   *   Database Service Object.
+   * {@inheritdoc}
    */
-  public function __construct(array $configuration, $plugin_id, array $plugin_definition, Connection $database) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition);
+  public function __construct(array $configuration, $plugin_id, array $plugin_definition, EntityManagerInterface $entity_manager) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_manager);
 
-    $this->database = $database;
+    $this->userStorage = $entity_manager->getStorageController('user');
   }
 
   /**
    * {@inheritdoc}
    */
-  public static function create(ContainerInterface $container, array $configuration, $plugin_id, array $plugin_definition) {
-    return new static($configuration, $plugin_id, $plugin_definition, $container->get('database'));
-  }
-
   protected function defineOptions() {
     $options = parent::defineOptions();
-    $options['type'] = array('default' => 'uid');
     $options['restrict_roles'] = array('default' => FALSE, 'bool' => TRUE);
     $options['roles'] = array('default' => array());
 
     return $options;
   }
 
+  /**
+   * {@inheritdoc}
+   */
   public function buildOptionsForm(&$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'],
-    );
+    parent::buildOptionsForm($form, $form_state);
 
     $form['restrict_roles'] = array(
       '#type' => 'checkbox',
@@ -98,79 +73,29 @@ public function buildOptionsForm(&$form, &$form_state) {
     );
   }
 
+  /**
+   * {@inheritdoc}
+   */
   public function submitOptionsForm(&$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']);
   }
 
-  public function validateArgument($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']->id()) {
-          // 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'];
-        }
-        $condition = 'uid';
-      }
-    }
-    else {
-      if ($type == 'name' || $type == 'either') {
-        $name = $GLOBALS['user']->getUserName() ?: \Drupal::config('user.settings')->get('anonymous');
-        if ($argument == $name) {
-          $account = clone $GLOBALS['user'];
-        }
-        $condition = 'name';
-      }
-    }
-
-    // If we don't have a WHERE clause, the argument is invalid.
-    if (empty($condition)) {
-      return FALSE;
-    }
-
-    if (!isset($account)) {
-      $uid = $this->database->select('users', 'u')
-        ->fields('u', array('uid'))
-        ->condition($condition, $argument)
-        ->execute()
-        ->fetchField();
-
-      if ($uid === FALSE) {
-        // User not found.
-        return FALSE;
-      }
-    }
-    $account = user_load($uid);
+  /**
+   * {@inheritdoc}
+   */
+  public function validateEntity(UserInterface $account) {
 
+    $role_check = TRUE;
     // See if we're filtering users based on roles.
     if (!empty($this->options['restrict_roles']) && !empty($this->options['roles'])) {
       $roles = $this->options['roles'];
       if (!(bool) array_intersect($account->getRoles(), $roles)) {
-        return FALSE;
+        $role_check =  FALSE;
       }
     }
 
-    $this->argument->argument = $account->id();
-    $this->argument->validated_title = check_plain(user_format_name($account));
-    return TRUE;
-  }
-
-  public function processSummaryArguments(&$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->label();
-      }
-    }
+    return $role_check && parent::validateEntity($account);
   }
 
 }
diff --git a/core/modules/user/lib/Drupal/user/Plugin/views/argument_validator/UserName.php b/core/modules/user/lib/Drupal/user/Plugin/views/argument_validator/UserName.php
new file mode 100644
index 0000000..728430c
--- /dev/null
+++ b/core/modules/user/lib/Drupal/user/Plugin/views/argument_validator/UserName.php
@@ -0,0 +1,81 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\user\Plugin\views\argument_validator\UserName.
+ */
+
+namespace Drupal\user\Plugin\views\argument_validator;
+
+/**
+ * Validates whether a user name is valid.
+ *
+ * @ViewsArgumentValidator(
+ *   id = "user_name",
+ *   title = @Translation("User name"),
+ *   entity_type = "user"
+ * )
+ */
+class UserName extends User {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildOptionsForm(&$form, &$form_state) {
+    parent::buildOptionsForm($form, $form_state);
+
+    $entity_type = $this->entityManager->getDefinition('user');
+
+    $form['multiple']['#options'] = array(
+      0 => t('Single name', array('%type' => $entity_type->getLabel())),
+      1 => t('One or more names separated by , or +', array('%type' => $entity_type->getLabel())),
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateArgument($argument) {
+    if ($this->options['multiple']) {
+      // At this point only interested in individual IDs no matter what type,
+      // just splitting by the allowed delimiters.
+      $names = array_filter(preg_split('/[,+ ]/', $argument));
+    }
+    elseif ($argument) {
+      $names = array($argument);
+    }
+    // No specified argument should be invalid.
+    else {
+      return FALSE;
+    }
+
+    $accounts = $this->userStorage->loadByProperties(array('name' => $names));
+
+    // If there are no accounts, return FALSE now. As we will not enter the
+    // loop below otherwise.
+    if (empty($accounts)) {
+      return FALSE;
+    }
+
+    // Validate each account. If any fails break out and return false.
+    foreach ($accounts as $account) {
+      if (!in_array($account->getUserName(), $names) || $this->validateEntity($account)) {
+        return FALSE;
+      }
+    }
+
+    return TRUE;
+  }
+
+  public function processSummaryArguments(&$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);
+    $users = $this->userStorage->loadMultiple($args);
+
+    foreach ($users as $uid => $account) {
+      $args[$uids_arg_keys[$uid]] = $account->label();
+    }
+  }
+
+}
diff --git a/core/modules/user/user.views.inc b/core/modules/user/user.views.inc
index 1a3a736..44c1cb3 100644
--- a/core/modules/user/user.views.inc
+++ b/core/modules/user/user.views.inc
@@ -380,3 +380,12 @@ function user_views_data_alter(&$data) {
     ),
   );
 }
+
+/**
+ * Implements hook_views_plugins_argument_validator_alter().
+ */
+function user_views_plugins_argument_validator_alter(array &$plugins) {
+  $plugins['entity:user']['title'] = t('User ID');
+  $plugins['entity:user']['class'] = 'Drupal\user\Plugin\views\argument_validator\User';
+  $plugins['entity:user']['provider'] = 'user';
+}
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/argument_validator/Entity.php b/core/modules/views/lib/Drupal/views/Plugin/views/argument_validator/Entity.php
index d5daf4b..53aee4c 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/argument_validator/Entity.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/argument_validator/Entity.php
@@ -170,7 +170,6 @@ public function validateArgument($argument) {
     }
     // No specified argument should be invalid.
     else {
-      $ids = array();
       return FALSE;
     }
 
