diff --git a/core/core.services.yml b/core/core.services.yml
index 8fdb3055779bd578a8632c00bcf37af911636cda..e40ef9e3538cc7fd25749573cb0d7c5645f7147e 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -348,6 +348,9 @@ services:
     arguments: ['@config.manager', '@entity.manager']
     tags:
       - { name: event_subscriber }
+  plugin.manager.entity_reference_selection:
+    class: Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManager
+    parent: default_plugin_manager
   plugin.manager.block:
     class: Drupal\Core\Block\BlockManager
     parent: default_plugin_manager
diff --git a/core/modules/entity_reference/src/Annotation/EntityReferenceSelection.php b/core/lib/Drupal/Core/Entity/Annotation/EntityReferenceSelection.php
similarity index 71%
rename from core/modules/entity_reference/src/Annotation/EntityReferenceSelection.php
rename to core/lib/Drupal/Core/Entity/Annotation/EntityReferenceSelection.php
index dbf6a5174ae164e2146ceadfa6d34fe6563c180e..96e2283736488b0169f922d60c496fb163c1dbf4 100644
--- a/core/modules/entity_reference/src/Annotation/EntityReferenceSelection.php
+++ b/core/lib/Drupal/Core/Entity/Annotation/EntityReferenceSelection.php
@@ -2,25 +2,25 @@
 
 /**
  * @file
- * Contains \Drupal\entity_reference\Annotation\EntityReferenceSelection.
+ * Contains \Drupal\Core\Entity\Annotation\EntityReferenceSelection.
  */
 
-namespace Drupal\entity_reference\Annotation;
+namespace Drupal\Core\Entity\Annotation;
 
 use Drupal\Component\Annotation\Plugin;
 
 /**
  * Defines an EntityReferenceSelection plugin annotation object.
  *
- * Plugin Namespace: Plugin\entity_reference\selection
+ * Plugin Namespace: Plugin\EntityReferenceSelection
  *
  * For a working example, see
- * \Drupal\comment\Plugin\entity_reference\selection\CommentSelection
+ * \Drupal\comment\Plugin\EntityReferenceSelection\CommentSelection
  *
- * @see \Drupal\entity_reference\Plugin\Type\SelectionPluginManager
- * @see \Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface
- * @see \Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase
- * @see \Drupal\entity_reference\Plugin\Derivative\SelectionBase
+ * @see \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManager
+ * @see \Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface
+ * @see \Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase
+ * @see \Drupal\Core\Entity\Plugin\Derivative\SelectionBase
  * @see plugin_api
  *
  * @Annotation
diff --git a/core/modules/entity_reference/src/Plugin/Type/Selection/SelectionInterface.php b/core/lib/Drupal/Core/Entity/EntityReferenceSelection/SelectionInterface.php
similarity index 70%
rename from core/modules/entity_reference/src/Plugin/Type/Selection/SelectionInterface.php
rename to core/lib/Drupal/Core/Entity/EntityReferenceSelection/SelectionInterface.php
index eb3b8aeabfc9bd014b2a16f487c70a9a65c6e894..793279ee065cfd2906cc92f46444d6a4f533ba44 100644
--- a/core/modules/entity_reference/src/Plugin/Type/Selection/SelectionInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityReferenceSelection/SelectionInterface.php
@@ -2,25 +2,25 @@
 
 /**
  * @file
- * Contains \Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface.
+ * Contains \Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface.
  */
 
-namespace Drupal\entity_reference\Plugin\Type\Selection;
+namespace Drupal\Core\Entity\EntityReferenceSelection;
 
 use Drupal\Core\Database\Query\SelectInterface;
-use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Plugin\PluginFormInterface;
 
 /**
  * Interface definition for Entity Reference Selection plugins.
  *
- * @see \Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase
- * @see \Drupal\entity_reference\Plugin\Type\SelectionPluginManager
- * @see \Drupal\entity_reference\Annotation\EntityReferenceSelection
- * @see \Drupal\entity_reference\Plugin\Derivative\SelectionBase
+ * @see \Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase
+ * @see \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManager
+ * @see \Drupal\Core\Entity\Annotation\EntityReferenceSelection
+ * @see \Drupal\Core\Entity\Plugin\Derivative\SelectionBase
  * @see plugin_api
  */
-interface SelectionInterface {
+interface SelectionInterface extends PluginFormInterface {
 
   /**
    * Returns a list of referenceable entities.
@@ -78,15 +78,4 @@ public function validateAutocompleteInput($input, &$element, FormStateInterface
    */
   public function entityQueryAlter(SelectInterface $query);
 
-  /**
-   * Generates the settings form for this selection.
-   *
-   * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
-   *   The definition of the field to which the selection is associated.
-   *
-   * @return array
-   *   A Form API array.
-   */
-  public static function settingsForm(FieldDefinitionInterface $field_definition);
-
 }
diff --git a/core/lib/Drupal/Core/Entity/EntityReferenceSelection/SelectionPluginManager.php b/core/lib/Drupal/Core/Entity/EntityReferenceSelection/SelectionPluginManager.php
new file mode 100644
index 0000000000000000000000000000000000000000..089dee807a6dbb7ac210a73e631cfb03e2dc5175
--- /dev/null
+++ b/core/lib/Drupal/Core/Entity/EntityReferenceSelection/SelectionPluginManager.php
@@ -0,0 +1,102 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManager.
+ */
+
+namespace Drupal\Core\Entity\EntityReferenceSelection;
+
+use Drupal\Component\Plugin\FallbackPluginManagerInterface;
+use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Plugin\DefaultPluginManager;
+
+/**
+ * Plugin type manager for Entity Reference Selection plugins.
+ *
+ * @see \Drupal\Core\Entity\Annotation\EntityReferenceSelection
+ * @see \Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface
+ * @see \Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase
+ * @see \Drupal\Core\Entity\Plugin\Derivative\SelectionBase
+ * @see plugin_api
+ */
+class SelectionPluginManager extends DefaultPluginManager implements SelectionPluginManagerInterface, FallbackPluginManagerInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
+    $this->alterInfo('entity_reference_selection');
+    $this->setCacheBackend($cache_backend, 'entity_reference_selection_plugins');
+
+    parent::__construct('Plugin/EntityReferenceSelection', $namespaces, $module_handler, 'Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface', 'Drupal\Core\Entity\Annotation\EntityReferenceSelection');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getInstance(array $options) {
+    if (!isset($options['target_type'])) {
+      throw new \InvalidArgumentException("Missing required 'target_type' property for a EntityReferenceSelection plugin.");
+    }
+
+    // Initialize default options.
+    $options += array(
+      'handler' => 'default',
+      'handler_settings' => array(),
+    );
+
+    // Get all available selection plugins for this entity type.
+    $selection_handler_groups = $this->getSelectionGroups($options['target_type']);
+
+    // Sort the selection plugins by weight and select the best match.
+    uasort($selection_handler_groups[$options['handler']], array('Drupal\Component\Utility\SortArray', 'sortByWeightElement'));
+    end($selection_handler_groups[$options['handler']]);
+    $plugin_id = key($selection_handler_groups[$options['handler']]);
+
+    return $this->createInstance($plugin_id, $options);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getSelectionGroups($entity_type_id) {
+    $plugins = array();
+    $definitions = $this->getDefinitions();
+
+    // Do not display the 'broken' plugin in the UI.
+    unset($definitions['broken']);
+
+    foreach ($definitions as $plugin_id => $plugin) {
+      if (empty($plugin['entity_types']) || in_array($entity_type_id, $plugin['entity_types'])) {
+        $plugins[$plugin['group']][$plugin_id] = $plugin;
+      }
+    }
+
+    return $plugins;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getSelectionHandler(FieldDefinitionInterface $field_definition, EntityInterface $entity = NULL) {
+    $options = array(
+      'target_type' => $field_definition->getFieldStorageDefinition()->getSetting('target_type'),
+      'handler' => $field_definition->getSetting('handler'),
+      'handler_settings' => $field_definition->getSetting('handler_settings'),
+      'entity' => $entity,
+    );
+    return $this->getInstance($options);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFallbackPluginId($plugin_id, array $configuration = array()) {
+    return 'broken';
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Entity/EntityReferenceSelection/SelectionPluginManagerInterface.php b/core/lib/Drupal/Core/Entity/EntityReferenceSelection/SelectionPluginManagerInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..81d555d8d0994407296dba99048896b6fd1ba2d2
--- /dev/null
+++ b/core/lib/Drupal/Core/Entity/EntityReferenceSelection/SelectionPluginManagerInterface.php
@@ -0,0 +1,43 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface.
+ */
+
+namespace Drupal\Core\Entity\EntityReferenceSelection;
+
+use Drupal\Component\Plugin\PluginManagerInterface;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
+
+/**
+ * Defines an interface for the entity reference selection plugin manager.
+ */
+interface SelectionPluginManagerInterface extends PluginManagerInterface {
+
+  /**
+   * Returns selection plugins that can reference a specific entity type.
+   *
+   * @param string $entity_type_id
+   *   A Drupal entity type ID.
+   *
+   * @return array
+   *   An array of selection plugins grouped by selection group.
+   */
+  public function getSelectionGroups($entity_type_id);
+
+  /**
+   * Gets the selection handler for a given entity_reference field.
+   *
+   * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
+   *   The field definition for the operation.
+   * @param \Drupal\Core\Entity\EntityInterface $entity
+   *   (optional) The entity for the operation. Defaults to NULL.
+   *
+   * @return \Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface
+   *   The selection plugin.
+   */
+  public function getSelectionHandler(FieldDefinitionInterface $field_definition, EntityInterface $entity = NULL);
+
+}
diff --git a/core/lib/Drupal/Core/Entity/Plugin/Derivative/SelectionBase.php b/core/lib/Drupal/Core/Entity/Plugin/Derivative/SelectionBase.php
new file mode 100644
index 0000000000000000000000000000000000000000..075249454f692881c3c3d0438870d6db4623a57c
--- /dev/null
+++ b/core/lib/Drupal/Core/Entity/Plugin/Derivative/SelectionBase.php
@@ -0,0 +1,65 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Entity\Plugin\Derivative\SelectionBase.
+ */
+
+namespace Drupal\Core\Entity\Plugin\Derivative;
+
+use Drupal\Component\Plugin\Derivative\DeriverBase;
+use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Provides derivative plugins for Entity Reference Selection plugins.
+ *
+ * @see \Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase
+ * @see \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManager
+ * @see \Drupal\Core\Entity\Annotation\EntityReferenceSelection
+ * @see \Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface
+ * @see plugin_api
+ */
+class SelectionBase extends DeriverBase implements ContainerDeriverInterface {
+
+  /**
+   * The entity manager
+   *
+   * @var \Drupal\Core\Entity\EntityManagerInterface
+   */
+  protected $entityManager;
+
+  /**
+   * Creates an SelectionBase object.
+   *
+   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+   *   The entity manager.
+   */
+  public function __construct(EntityManagerInterface $entity_manager) {
+    $this->entityManager = $entity_manager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, $base_plugin_id) {
+    return new static(
+      $container->get('entity.manager')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDerivativeDefinitions($base_plugin_definition) {
+    foreach ($this->entityManager->getDefinitions() as $entity_type_id => $entity_type) {
+      $this->derivatives[$entity_type_id] = $base_plugin_definition;
+      $this->derivatives[$entity_type_id]['entity_types'] = array($entity_type_id);
+      $this->derivatives[$entity_type_id]['label'] = t('@entity_type selection', array('@entity_type' => $entity_type->getLabel()));
+      $this->derivatives[$entity_type_id]['base_plugin_label'] = (string) $base_plugin_definition['label'];
+    }
+    return parent::getDerivativeDefinitions($base_plugin_definition);
+  }
+
+}
diff --git a/core/modules/entity_reference/src/Plugin/entity_reference/selection/Broken.php b/core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/Broken.php
similarity index 66%
rename from core/modules/entity_reference/src/Plugin/entity_reference/selection/Broken.php
rename to core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/Broken.php
index 4ddde95f344fe733540b76438cb5069d00fb1335..aae79bbcd53b658fea2d3ad0f7f62410c8388844 100644
--- a/core/modules/entity_reference/src/Plugin/entity_reference/selection/Broken.php
+++ b/core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/Broken.php
@@ -2,12 +2,13 @@
 
 /**
  * @file
- * Contains \Drupal\entity_reference\Plugin\Type\Selection\SelectionBroken.
+ * Contains \Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBroken.
  */
 
-namespace Drupal\entity_reference\Plugin\Type\Selection;
+namespace Drupal\Core\Entity\Plugin\EntityReferenceSelection;
 
 use Drupal\Core\Database\Query\SelectInterface;
+use Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface;
 use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Form\FormStateInterface;
 
@@ -19,18 +20,28 @@
  *   label = @Translation("Broken/Missing")
  * )
  */
-class SelectionBroken implements SelectionInterface {
+class Broken implements SelectionInterface {
 
   /**
    * {@inheritdoc}
    */
-  public static function settingsForm(FieldDefinitionInterface $field_definition) {
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
     $form['selection_handler'] = array(
       '#markup' => t('The selected selection handler is broken.'),
     );
     return $form;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { }
+
   /**
    * {@inheritdoc}
    */
diff --git a/core/modules/entity_reference/src/Plugin/entity_reference/selection/SelectionBase.php b/core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/SelectionBase.php
similarity index 60%
rename from core/modules/entity_reference/src/Plugin/entity_reference/selection/SelectionBase.php
rename to core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/SelectionBase.php
index c2b877bc37dce126c5af71f441b5d89a612b72a6..a6b559cfbaf0a8b350dd759555eca1fe4e873e61 100644
--- a/core/modules/entity_reference/src/Plugin/entity_reference/selection/SelectionBase.php
+++ b/core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/SelectionBase.php
@@ -2,18 +2,22 @@
 
 /**
  * @file
- * Contains \Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase.
+ * Contains \Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase.
  */
 
-namespace Drupal\entity_reference\Plugin\entity_reference\selection;
+namespace Drupal\Core\Entity\Plugin\EntityReferenceSelection;
 
 use Drupal\Component\Utility\String;
 use Drupal\Core\Database\Query\AlterableInterface;
 use Drupal\Core\Database\Query\SelectInterface;
-use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface;
+use Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Plugin\PluginBase;
+use Drupal\Core\Session\AccountInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Default plugin implementation of the Entity Reference Selection plugin.
@@ -21,10 +25,10 @@
  * Also serves as a base class for specific types of Entity Reference
  * Selection plugins.
  *
- * @see \Drupal\entity_reference\Plugin\Type\SelectionPluginManager
- * @see \Drupal\entity_reference\Annotation\EntityReferenceSelection
- * @see \Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface
- * @see \Drupal\entity_reference\Plugin\Derivative\SelectionBase
+ * @see \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManager
+ * @see \Drupal\Core\Entity\Annotation\EntityReferenceSelection
+ * @see \Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface
+ * @see \Drupal\Core\Entity\Plugin\Derivative\SelectionBase
  * @see plugin_api
  *
  * @EntityReferenceSelection(
@@ -32,42 +36,78 @@
  *   label = @Translation("Default"),
  *   group = "default",
  *   weight = 0,
- *   deriver = "Drupal\entity_reference\Plugin\Derivative\SelectionBase"
+ *   deriver = "Drupal\Core\Entity\Plugin\Derivative\SelectionBase"
  * )
  */
-class SelectionBase implements SelectionInterface {
+class SelectionBase extends PluginBase implements SelectionInterface, ContainerFactoryPluginInterface {
 
   /**
-   * The field definition.
+   * The entity manager.
    *
-   * @var \Drupal\Core\Field\FieldDefinitionInterface
+   * @var \Drupal\Core\Entity\EntityManagerInterface
    */
-  protected $fieldDefinition;
+  protected $entityManager;
 
   /**
-   * The entity object, or NULL
+   * The module handler service.
    *
-   * @var \Drupal\Core\Entity\EntityInterface|null
+   * @var \Drupal\Core\Extension\ModuleHandlerInterface
    */
-  protected $entity;
+  protected $moduleHandler;
 
   /**
-   * Constructs a SelectionBase object.
+   * The current user.
+   *
+   * @var \Drupal\Core\Session\AccountInterface
+   */
+  protected $currentUser;
+
+  /**
+   * Constructs a new SelectionBase object.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+   *   The entity manager service.
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler service.
+   * @param \Drupal\Core\Session\AccountInterface $current_user
+   *   The current user.
    */
-  public function __construct(FieldDefinitionInterface $field_definition, EntityInterface $entity = NULL) {
-    $this->fieldDefinition = $field_definition;
-    $this->entity = $entity;
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $entity_manager, ModuleHandlerInterface $module_handler, AccountInterface $current_user) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+
+    $this->entityManager = $entity_manager;
+    $this->moduleHandler = $module_handler;
+    $this->currentUser = $current_user;
   }
 
   /**
    * {@inheritdoc}
    */
-  public static function settingsForm(FieldDefinitionInterface $field_definition) {
-    $entity_manager = \Drupal::entityManager();
-    $entity_type_id = $field_definition->getSetting('target_type');
-    $selection_handler_settings = $field_definition->getSetting('handler_settings') ?: array();
-    $entity_type = $entity_manager->getDefinition($entity_type_id);
-    $bundles = $entity_manager->getBundleInfo($entity_type_id);
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('entity.manager'),
+      $container->get('module_handler'),
+      $container->get('current_user')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    $entity_type_id = $this->configuration['target_type'];
+    $selection_handler_settings = $this->configuration['handler_settings'];
+    $entity_type = $this->entityManager->getDefinition($entity_type_id);
+    $bundles = $this->entityManager->getBundleInfo($entity_type_id);
 
     // Merge-in default values.
     $selection_handler_settings += array(
@@ -84,13 +124,13 @@ public static function settingsForm(FieldDefinitionInterface $field_definition)
         $bundle_options[$bundle_name] = $bundle_info['label'];
       }
 
-      $target_bundles_title = t('Bundles');
+      $target_bundles_title = $this->t('Bundles');
       // Default core entity types with sensible labels.
       if ($entity_type_id == 'node') {
-        $target_bundles_title = t('Content types');
+        $target_bundles_title = $this->t('Content types');
       }
       elseif ($entity_type_id == 'taxonomy_term') {
-        $target_bundles_title = t('Vocabularies');
+        $target_bundles_title = $this->t('Vocabularies');
       }
 
       $form['target_bundles'] = array(
@@ -114,7 +154,7 @@ public static function settingsForm(FieldDefinitionInterface $field_definition)
     if ($entity_type->isSubclassOf('\Drupal\Core\Entity\FieldableEntityInterface')) {
       $fields = array();
       foreach (array_keys($bundles) as $bundle) {
-        $bundle_fields = array_filter($entity_manager->getFieldDefinitions($entity_type_id, $bundle), function ($field_definition) {
+        $bundle_fields = array_filter($this->entityManager->getFieldDefinitions($entity_type_id, $bundle), function ($field_definition) {
           return !$field_definition->isComputed();
         });
         foreach ($bundle_fields as $field_name => $field_definition) {
@@ -125,20 +165,20 @@ public static function settingsForm(FieldDefinitionInterface $field_definition)
           // @todo: Use property labels instead of the column name.
           if (count($columns) > 1) {
             foreach ($columns as $column_name => $column_info) {
-              $fields[$field_name . '.' . $column_name] = t('@label (@column)', array('@label' => $field_definition->getLabel(), '@column' => $column_name));
+              $fields[$field_name . '.' . $column_name] = $this->t('@label (@column)', array('@label' => $field_definition->getLabel(), '@column' => $column_name));
             }
           }
           else {
-            $fields[$field_name] = t('@label', array('@label' => $field_definition->getLabel()));
+            $fields[$field_name] = $this->t('@label', array('@label' => $field_definition->getLabel()));
           }
         }
       }
 
       $form['sort']['field'] = array(
         '#type' => 'select',
-        '#title' => t('Sort by'),
+        '#title' => $this->t('Sort by'),
         '#options' => array(
-          '_none' => t('- None -'),
+          '_none' => $this->t('- None -'),
         ) + $fields,
         '#ajax' => TRUE,
         '#limit_validation_errors' => array(),
@@ -159,11 +199,11 @@ public static function settingsForm(FieldDefinitionInterface $field_definition)
 
         $form['sort']['settings']['direction'] = array(
           '#type' => 'select',
-          '#title' => t('Sort direction'),
+          '#title' => $this->t('Sort direction'),
           '#required' => TRUE,
           '#options' => array(
-            'ASC' => t('Ascending'),
-            'DESC' => t('Descending'),
+            'ASC' => $this->t('Ascending'),
+            'DESC' => $this->t('Descending'),
           ),
           '#default_value' => $selection_handler_settings['sort']['direction'],
         );
@@ -173,11 +213,21 @@ public static function settingsForm(FieldDefinitionInterface $field_definition)
     return $form;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { }
+
   /**
    * {@inheritdoc}
    */
   public function getReferenceableEntities($match = NULL, $match_operator = 'CONTAINS', $limit = 0) {
-    $target_type = $this->fieldDefinition->getSetting('target_type');
+    $target_type = $this->configuration['target_type'];
 
     $query = $this->buildEntityQuery($match, $match_operator);
     if ($limit > 0) {
@@ -216,8 +266,8 @@ public function countReferenceableEntities($match = NULL, $match_operator = 'CON
   public function validateReferenceableEntities(array $ids) {
     $result = array();
     if ($ids) {
-      $target_type = $this->fieldDefinition->getSetting('target_type');
-      $entity_type = \Drupal::entityManager()->getDefinition($target_type);
+      $target_type = $this->configuration['target_type'];
+      $entity_type = $this->entityManager->getDefinition($target_type);
       $query = $this->buildEntityQuery();
       $result = $query
         ->condition($entity_type->getKey('id'), $ids, 'IN')
@@ -243,13 +293,13 @@ public function validateAutocompleteInput($input, &$element, FormStateInterface
     if (empty($entities)) {
       if ($strict) {
         // Error if there are no entities available for a required field.
-        $form_state->setError($element, t('There are no entities matching "%value".', $params));
+        $form_state->setError($element, $this->t('There are no entities matching "%value".', $params));
       }
     }
     elseif (count($entities) > 5) {
       $params['@id'] = key($entities);
       // Error if there are more than 5 matching entities.
-      $form_state->setError($element, t('Many entities are called %value. Specify the one you want by appending the id in parentheses, like "@value (@id)".', $params));
+      $form_state->setError($element, $this->t('Many entities are called %value. Specify the one you want by appending the id in parentheses, like "@value (@id)".', $params));
     }
     elseif (count($entities) > 1) {
       // More helpful error if there are only a few matching entities.
@@ -258,7 +308,7 @@ public function validateAutocompleteInput($input, &$element, FormStateInterface
         $multiples[] = $name . ' (' . $id . ')';
       }
       $params['@id'] = $id;
-      $form_state->setError($element, t('Multiple entities match this reference; "%multiple". Specify the one you want by appending the id in parentheses, like "@value (@id)".', array('%multiple' => implode('", "', $multiples))));
+      $form_state->setError($element, $this->t('Multiple entities match this reference; "%multiple". Specify the one you want by appending the id in parentheses, like "@value (@id)".', array('%multiple' => implode('", "', $multiples))));
     }
     else {
       // Take the one and only matching entity.
@@ -280,11 +330,11 @@ public function validateAutocompleteInput($input, &$element, FormStateInterface
    *   it.
    */
   public function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
-    $target_type = $this->fieldDefinition->getSetting('target_type');
-    $handler_settings = $this->fieldDefinition->getSetting('handler_settings');
-    $entity_type = \Drupal::entityManager()->getDefinition($target_type);
+    $target_type = $this->configuration['target_type'];
+    $handler_settings = $this->configuration['handler_settings'];
+    $entity_type = $this->entityManager->getDefinition($target_type);
 
-    $query = \Drupal::entityQuery($target_type);
+    $query = $this->entityManager->getStorage($target_type)->getQuery();
     if (!empty($handler_settings['target_bundles'])) {
       $query->condition($entity_type->getKey('bundle'), $handler_settings['target_bundles'], 'IN');
     }
@@ -294,16 +344,14 @@ public function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
     }
 
     // Add entity-access tag.
-    $query->addTag($this->fieldDefinition->getSetting('target_type') . '_access');
+    $query->addTag($target_type . '_access');
 
     // Add the Selection handler for
     // entity_reference_query_entity_reference_alter().
     $query->addTag('entity_reference');
-    $query->addMetaData('field_definition', $this->fieldDefinition);
     $query->addMetaData('entity_reference_selection_handler', $this);
 
     // Add the sort option.
-    $handler_settings = $this->fieldDefinition->getSetting('handler_settings');
     if (!empty($handler_settings['sort'])) {
       $sort_settings = $handler_settings['sort'];
       if ($sort_settings['field'] != '_none') {
@@ -333,10 +381,11 @@ protected function reAlterQuery(AlterableInterface $query, $tag, $base_table) {
 
     $query->alterTags = array($tag => TRUE);
     $query->alterMetaData['base_table'] = $base_table;
-    \Drupal::moduleHandler()->alter(array('query', 'query_' . $tag), $query);
+    $this->moduleHandler->alter(array('query', 'query_' . $tag), $query);
 
     // Restore the tags and metadata.
     $query->alterTags = $old_tags;
     $query->alterMetaData = $old_metadata;
   }
+
 }
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php
index 946645d97c3d4de8360b8271c5d080e09db7671f..e03750de19b65ea6297c3bdae41e10790c255a0e 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php
@@ -243,7 +243,7 @@ public function preSave() {
    * {@inheritdoc}
    */
   public static function generateSampleValue(FieldDefinitionInterface $field_definition) {
-    $manager = \Drupal::service('plugin.manager.entity_reference.selection');
+    $manager = \Drupal::service('plugin.manager.entity_reference_selection');
     if ($referenceable = $manager->getSelectionHandler($field_definition)->getReferenceableEntities()) {
       $group = array_rand($referenceable);
       $values['target_id'] = array_rand($referenceable[$group]);
diff --git a/core/modules/comment/src/Plugin/entity_reference/selection/CommentSelection.php b/core/modules/comment/src/Plugin/EntityReferenceSelection/CommentSelection.php
similarity index 81%
rename from core/modules/comment/src/Plugin/entity_reference/selection/CommentSelection.php
rename to core/modules/comment/src/Plugin/EntityReferenceSelection/CommentSelection.php
index b6f63a0bb185a7252a9fed73ee05a4fa486a5767..ae34eba836d9cac471be2e67134c973969ed9283 100644
--- a/core/modules/comment/src/Plugin/entity_reference/selection/CommentSelection.php
+++ b/core/modules/comment/src/Plugin/EntityReferenceSelection/CommentSelection.php
@@ -2,20 +2,20 @@
 
 /**
  * @file
- * Contains \Drupal\comment\Plugin\entity_reference\selection\CommentSelection.
+ * Contains \Drupal\comment\Plugin\EntityReferenceSelection\CommentSelection.
  */
 
-namespace Drupal\comment\Plugin\entity_reference\selection;
+namespace Drupal\comment\Plugin\EntityReferenceSelection;
 
 use Drupal\Core\Database\Query\SelectInterface;
+use Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase;
 use Drupal\comment\CommentInterface;
-use Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase;
 
 /**
  * Provides specific access control for the comment entity type.
  *
  * @EntityReferenceSelection(
- *   id = "comment_default",
+ *   id = "default:comment",
  *   label = @Translation("Comment selection"),
  *   entity_types = {"comment"},
  *   group = "default",
@@ -33,7 +33,7 @@ public function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
     // Adding the 'comment_access' tag is sadly insufficient for comments:
     // core requires us to also know about the concept of 'published' and
     // 'unpublished'.
-    if (!\Drupal::currentUser()->hasPermission('administer comments')) {
+    if (!$this->currentUser->hasPermission('administer comments')) {
       $query->condition('status', CommentInterface::PUBLISHED);
     }
     return $query;
@@ -61,8 +61,9 @@ public function entityQueryAlter(SelectInterface $query) {
     // Passing the query to node_query_node_access_alter() is sadly
     // insufficient for nodes.
     // @see SelectionEntityTypeNode::entityQueryAlter()
-    if (!\Drupal::currentUser()->hasPermission('bypass node access') && !count(\Drupal::moduleHandler()->getImplementations('node_grants'))) {
+    if (!$this->currentUser->hasPermission('bypass node access') && !count($this->moduleHandler->getImplementations('node_grants'))) {
       $query->condition($node_alias . '.status', 1);
     }
   }
+
 }
diff --git a/core/modules/entity_reference/entity_reference.module b/core/modules/entity_reference/entity_reference.module
index 63749987b4bcf2244058c501dea28b044ff63661..b1b0619f685af5cfc99fb88d12a95926276e63a7 100644
--- a/core/modules/entity_reference/entity_reference.module
+++ b/core/modules/entity_reference/entity_reference.module
@@ -201,7 +201,7 @@ function entity_reference_query_entity_reference_alter(AlterableInterface $query
  * @param int $cardinality
  *   The cardinality of the field.
  *
- * @see \Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase::settingsForm()
+ * @see \Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase::buildConfigurationForm()
  */
 function entity_reference_create_field($entity_type, $bundle, $field_name, $field_label, $target_entity_type, $selection_handler = 'default', $selection_handler_settings = array(), $cardinality = 1) {
   // Look for or add the specified field to the requested entity bundle.
diff --git a/core/modules/entity_reference/entity_reference.services.yml b/core/modules/entity_reference/entity_reference.services.yml
index bdfb45c35bb410651aee13eade0687603d00ced0..680cdf2cfdfd3321c4d2fc3ad80a293ef32c81b3 100644
--- a/core/modules/entity_reference/entity_reference.services.yml
+++ b/core/modules/entity_reference/entity_reference.services.yml
@@ -1,7 +1,4 @@
 services:
-  plugin.manager.entity_reference.selection:
-    class: Drupal\entity_reference\Plugin\Type\SelectionPluginManager
-    parent: default_plugin_manager
   entity_reference.autocomplete:
     class: Drupal\entity_reference\EntityReferenceAutocomplete
-    arguments: ['@entity.manager', '@plugin.manager.entity_reference.selection']
+    arguments: ['@entity.manager', '@plugin.manager.entity_reference_selection']
diff --git a/core/modules/entity_reference/src/ConfigurableEntityReferenceItem.php b/core/modules/entity_reference/src/ConfigurableEntityReferenceItem.php
index cbbac447b1d738c881dadefdac428bd5dd5ffd04..5f0f75d739448f8141bdd541c7935d6cf2312eb5 100644
--- a/core/modules/entity_reference/src/ConfigurableEntityReferenceItem.php
+++ b/core/modules/entity_reference/src/ConfigurableEntityReferenceItem.php
@@ -80,7 +80,7 @@ public function getSettableValues(AccountInterface $account = NULL) {
    */
   public function getSettableOptions(AccountInterface $account = NULL) {
     $field_definition = $this->getFieldDefinition();
-    if (!$options = \Drupal::service('plugin.manager.entity_reference.selection')->getSelectionHandler($field_definition, $this->getEntity())->getReferenceableEntities()) {
+    if (!$options = \Drupal::service('plugin.manager.entity_reference_selection')->getSelectionHandler($field_definition, $this->getEntity())->getReferenceableEntities()) {
       return array();
     }
 
@@ -138,17 +138,18 @@ public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
     $field = $form_state->get('field');
 
     // Get all selection plugins for this entity type.
-    $selection_plugins = \Drupal::service('plugin.manager.entity_reference.selection')->getSelectionGroups($this->getSetting('target_type'));
-    $handler_groups = array_keys($selection_plugins);
-
-    $handlers = \Drupal::service('plugin.manager.entity_reference.selection')->getDefinitions();
+    $selection_plugins = \Drupal::service('plugin.manager.entity_reference_selection')->getSelectionGroups($this->getSetting('target_type'));
     $handlers_options = array();
-    foreach ($handlers as $plugin_id => $plugin) {
+    foreach (array_keys($selection_plugins) as $selection_group_id) {
       // We only display base plugins (e.g. 'default', 'views', ...) and not
-      // entity type specific plugins (e.g. 'default_node', 'default_user',
+      // entity type specific plugins (e.g. 'default:node', 'default:user',
       // ...).
-      if (in_array($plugin_id, $handler_groups)) {
-        $handlers_options[$plugin_id] = String::checkPlain($plugin['label']);
+      if (array_key_exists($selection_group_id, $selection_plugins[$selection_group_id])) {
+        $handlers_options[$selection_group_id] = String::checkPlain($selection_plugins[$selection_group_id][$selection_group_id]['label']);
+      }
+      elseif (array_key_exists($selection_group_id . ':' . $this->getSetting('target_type'), $selection_plugins[$selection_group_id])) {
+        $selection_group_plugin = $selection_group_id . ':' . $this->getSetting('target_type');
+        $handlers_options[$selection_group_id] = String::checkPlain($selection_plugins[$selection_group_id][$selection_group_plugin]['base_plugin_label']);
       }
     }
 
@@ -191,8 +192,8 @@ public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
       '#attributes' => array('class' => array('entity_reference-settings')),
     );
 
-    $handler = \Drupal::service('plugin.manager.entity_reference.selection')->getSelectionHandler($field);
-    $form['handler']['handler_settings'] += $handler->settingsForm($field);
+    $handler = \Drupal::service('plugin.manager.entity_reference_selection')->getSelectionHandler($field);
+    $form['handler']['handler_settings'] += $handler->buildConfigurationForm(array(), $form_state);
 
     return $form;
   }
@@ -209,6 +210,9 @@ public static function fieldSettingsFormValidate(array $form, FormStateInterface
     if ($form_state->hasValue('field')) {
       $form_state->unsetValue(array('field', 'settings', 'handler_submit'));
       $form_state->get('field')->settings = $form_state->getValue(['field', 'settings']);
+
+      $handler = \Drupal::service('plugin.manager.entity_reference_selection')->getSelectionHandler($form_state->get('field'));
+      $handler->validateConfigurationForm($form, $form_state);
     }
   }
 
diff --git a/core/modules/entity_reference/src/EntityReferenceAutocomplete.php b/core/modules/entity_reference/src/EntityReferenceAutocomplete.php
index ffc9995a423c59d849aaaff67de5ca42ada3dc45..f0a615792183bef5397eb4d5af53d8ad8670febd 100644
--- a/core/modules/entity_reference/src/EntityReferenceAutocomplete.php
+++ b/core/modules/entity_reference/src/EntityReferenceAutocomplete.php
@@ -10,9 +10,8 @@
 use Drupal\Component\Utility\String;
 use Drupal\Component\Utility\Tags;
 use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface;
 use Drupal\Core\Field\FieldDefinitionInterface;
-use Drupal\entity_reference\Plugin\Type\SelectionPluginManager;
-use Drupal\field\FieldConfigInterface;
 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
 
 /**
@@ -30,7 +29,7 @@ class EntityReferenceAutocomplete {
   /**
    * The Entity reference selection handler plugin manager.
    *
-   * @var \Drupal\entity_reference\Plugin\Type\SelectionPluginManager
+   * @var \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface
    */
   protected $selectionHandlerManager;
 
@@ -39,10 +38,10 @@ class EntityReferenceAutocomplete {
    *
    * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
    *   The entity manager.
-   * @param \Drupal\entity_reference\Plugin\Type\SelectionPluginManager $selection_manager
+   * @param \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface $selection_manager
    *   The Entity reference selection handler plugin manager.
    */
-  public function __construct(EntityManagerInterface $entity_manager, SelectionPluginManager $selection_manager) {
+  public function __construct(EntityManagerInterface $entity_manager, SelectionPluginManagerInterface $selection_manager) {
     $this->entityManager = $entity_manager;
     $this->selectionHandlerManager = $selection_manager;
   }
diff --git a/core/modules/entity_reference/src/Plugin/Derivative/SelectionBase.php b/core/modules/entity_reference/src/Plugin/Derivative/SelectionBase.php
deleted file mode 100644
index 7091f5cb5efd8fa67741db47f24653687f83ccdf..0000000000000000000000000000000000000000
--- a/core/modules/entity_reference/src/Plugin/Derivative/SelectionBase.php
+++ /dev/null
@@ -1,41 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\entity_reference\Plugin\Derivative\SelectionBase.
- */
-
-namespace Drupal\entity_reference\Plugin\Derivative;
-
-use Drupal\Component\Plugin\Derivative\DeriverBase;
-
-/**
- * Provides derivative plugins for Entity Reference Selection plugins.
- *
- * @see \Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase
- * @see \Drupal\entity_reference\Plugin\Type\SelectionPluginManager
- * @see \Drupal\entity_reference\Annotation\EntityReferenceSelection
- * @see \Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface
- * @see plugin_api
- */
-class SelectionBase extends DeriverBase {
-  /**
-   * {@inheritdoc}
-   */
-  public function getDerivativeDefinitions($base_plugin_definition) {
-    $supported_entities = array(
-      'comment',
-      'file',
-      'node',
-      'taxonomy_term',
-      'user'
-    );
-    foreach (\Drupal::entityManager()->getDefinitions() as $entity_type_id => $entity_type) {
-      if (!in_array($entity_type_id, $supported_entities)) {
-        $this->derivatives[$entity_type_id] = $base_plugin_definition;
-        $this->derivatives[$entity_type_id]['label'] = t('@entity_type selection', array('@entity_type' => $entity_type->getLabel()));
-      }
-    }
-    return parent::getDerivativeDefinitions($base_plugin_definition);
-  }
-}
diff --git a/core/modules/entity_reference/src/Plugin/Field/FieldWidget/AutocompleteTagsWidget.php b/core/modules/entity_reference/src/Plugin/Field/FieldWidget/AutocompleteTagsWidget.php
index 4972eeefc3ffd9675f73cf47550d345f4a7703a3..f7b5ff39a2172329eb2ff7441c75945668957c90 100644
--- a/core/modules/entity_reference/src/Plugin/Field/FieldWidget/AutocompleteTagsWidget.php
+++ b/core/modules/entity_reference/src/Plugin/Field/FieldWidget/AutocompleteTagsWidget.php
@@ -44,7 +44,7 @@ public static function defaultSettings() {
   public function elementValidate($element, FormStateInterface $form_state, $form) {
     $value = array();
     // If a value was entered into the autocomplete.
-    $handler = \Drupal::service('plugin.manager.entity_reference.selection')->getSelectionHandler($this->fieldDefinition);
+    $handler = \Drupal::service('plugin.manager.entity_reference_selection')->getSelectionHandler($this->fieldDefinition);
     $bundles = entity_get_bundles($this->getFieldSetting('target_type'));
     $auto_create = $this->getSelectionHandlerSetting('auto_create');
 
diff --git a/core/modules/entity_reference/src/Plugin/Field/FieldWidget/AutocompleteWidget.php b/core/modules/entity_reference/src/Plugin/Field/FieldWidget/AutocompleteWidget.php
index b8b8fcd72afc4d9838d31989233041c275e19fb8..1e33d801d67cf7fdda76db5d5e3a0b2447c6861e 100644
--- a/core/modules/entity_reference/src/Plugin/Field/FieldWidget/AutocompleteWidget.php
+++ b/core/modules/entity_reference/src/Plugin/Field/FieldWidget/AutocompleteWidget.php
@@ -64,7 +64,7 @@ public function elementValidate($element, FormStateInterface $form_state, $form)
       if ($value === NULL) {
         // Try to get a match from the input string when the user didn't use the
         // autocomplete but filled in a value manually.
-        $handler = \Drupal::service('plugin.manager.entity_reference.selection')->getSelectionHandler($this->fieldDefinition);
+        $handler = \Drupal::service('plugin.manager.entity_reference_selection')->getSelectionHandler($this->fieldDefinition);
         $value = $handler->validateAutocompleteInput($element['#value'], $element, $form_state, $form, !$auto_create);
       }
 
diff --git a/core/modules/entity_reference/src/Plugin/Type/SelectionPluginManager.php b/core/modules/entity_reference/src/Plugin/Type/SelectionPluginManager.php
deleted file mode 100644
index 786359399f7317b566ca232569ef170286bc29b9..0000000000000000000000000000000000000000
--- a/core/modules/entity_reference/src/Plugin/Type/SelectionPluginManager.php
+++ /dev/null
@@ -1,115 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\entity_reference\Plugin\Type\SelectionPluginManager.
- */
-
-namespace Drupal\entity_reference\Plugin\Type;
-
-use Drupal\Component\Plugin\Factory\ReflectionFactory;
-use Drupal\Component\Plugin\FallbackPluginManagerInterface;
-use Drupal\Core\Cache\CacheBackendInterface;
-use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Field\FieldDefinitionInterface;
-use Drupal\Core\Extension\ModuleHandlerInterface;
-use Drupal\Core\Plugin\DefaultPluginManager;
-use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
-
-/**
- * Plugin type manager for Entity Reference Selection plugins.
- *
- * @see \Drupal\entity_reference\Annotation\EntityReferenceSelection
- * @see \Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface
- * @see \Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase
- * @see \Drupal\entity_reference\Plugin\Derivative\SelectionBase
- * @see plugin_api
- */
-class SelectionPluginManager extends DefaultPluginManager implements FallbackPluginManagerInterface {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
-    $this->discovery = new AnnotatedClassDiscovery('Plugin/entity_reference/selection', $namespaces, 'Drupal\entity_reference\Annotation\EntityReferenceSelection');
-
-    // We're not using the parent constructor because we use a different factory
-    // method and don't need the derivative discovery decorator.
-    $this->factory = new ReflectionFactory($this, '\Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface');
-
-    $this->moduleHandler = $module_handler;
-    $this->alterInfo('entity_reference_selection');
-    $this->setCacheBackend($cache_backend, 'entity_reference_selection_plugins');
-  }
-
-  /**
-   * Overrides \Drupal\Component\Plugin\PluginManagerBase::getInstance().
-   */
-  public function getInstance(array $options) {
-    $selection_handler = $options['field_definition']->getSetting('handler');
-    $target_entity_type = $options['field_definition']->getSetting('target_type');
-
-    // Get all available selection plugins for this entity type.
-    $selection_handler_groups = $this->getSelectionGroups($target_entity_type);
-
-    // Sort the selection plugins by weight and select the best match.
-    uasort($selection_handler_groups[$selection_handler], array('Drupal\Component\Utility\SortArray', 'sortByWeightElement'));
-    end($selection_handler_groups[$selection_handler]);
-    $plugin_id = key($selection_handler_groups[$selection_handler]);
-
-    return $this->createInstance($plugin_id, $options);
-  }
-
-  /**
-   * Returns a list of selection plugins that can reference a specific entity
-   * type.
-   *
-   * @param string $entity_type
-   *   A Drupal entity type.
-   *
-   * @return array
-   *   An array of selection plugins grouped by selection group.
-   */
-  public function getSelectionGroups($entity_type) {
-    $plugins = array();
-    $definitions = $this->getDefinitions();
-
-    // Do not display the 'broken' plugin in the UI.
-    unset($definitions['broken']);
-
-    foreach ($definitions as $plugin_id => $plugin) {
-      if (empty($plugin['entity_types']) || in_array($entity_type, $plugin['entity_types'])) {
-        $plugins[$plugin['group']][$plugin_id] = $plugin;
-      }
-    }
-
-    return $plugins;
-  }
-
-  /**
-   * Gets the selection handler for a given entity_reference field.
-   *
-   * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
-   *   The field definition for the operation.
-   * @param \Drupal\Core\Entity\EntityInterface $entity
-   *   The entity for the operation.
-   *
-   * @return \Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface
-   *   The selection plugin.
-   */
-  public function getSelectionHandler(FieldDefinitionInterface $field_definition, EntityInterface $entity = NULL) {
-    $options = array(
-      'field_definition' => $field_definition,
-      'entity' => $entity,
-    );
-    return $this->getInstance($options);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFallbackPluginId($plugin_id, array $configuration = array()) {
-    return 'broken';
-  }
-
-}
diff --git a/core/modules/entity_reference/src/Tests/EntityReferenceAdminTest.php b/core/modules/entity_reference/src/Tests/EntityReferenceAdminTest.php
index 3bda42941e6aba275770a407ac8cd7bc71b83ea4..5d75d3fa1603d41849e238e642d27f31b2bd2453 100644
--- a/core/modules/entity_reference/src/Tests/EntityReferenceAdminTest.php
+++ b/core/modules/entity_reference/src/Tests/EntityReferenceAdminTest.php
@@ -118,6 +118,26 @@ public function testFieldAdminHandler() {
     // The first 'Edit' link is for the Body field.
     $this->clickLink(t('Edit'), 1);
     $this->drupalPostForm(NULL, array(), t('Save settings'));
+
+    // Switch the target type to 'taxonomy_term' and check that the settings
+    // specific to its selection handler are displayed.
+    $field_name = 'node.' . $this->type . '.field_test';
+    $edit = array(
+      'field_storage[settings][target_type]' => 'taxonomy_term',
+    );
+    $this->drupalPostForm($bundle_path . '/fields/' . $field_name . '/storage', $edit, t('Save field settings'));
+    $this->drupalGet($bundle_path . '/fields/' . $field_name);
+    $this->assertFieldByName('field[settings][handler_settings][auto_create]');
+
+    // Switch the target type to 'user' and check that the settings specific to
+    // its selection handler are displayed.
+    $field_name = 'node.' . $this->type . '.field_test';
+    $edit = array(
+      'field_storage[settings][target_type]' => 'user',
+    );
+    $this->drupalPostForm($bundle_path . '/fields/' . $field_name . '/storage', $edit, t('Save field settings'));
+    $this->drupalGet($bundle_path . '/fields/' . $field_name);
+    $this->assertFieldByName('field[settings][handler_settings][filter][type]', '_none');
   }
 
 
diff --git a/core/modules/entity_reference/src/Tests/Views/SelectionTest.php b/core/modules/entity_reference/src/Tests/Views/SelectionTest.php
index 26cc00effccac747693c5e5f650bce1611b1b47b..5e98176ec7a6397e4862020b5794eb678e005b26 100644
--- a/core/modules/entity_reference/src/Tests/Views/SelectionTest.php
+++ b/core/modules/entity_reference/src/Tests/Views/SelectionTest.php
@@ -103,7 +103,7 @@ protected function assertResults(array $result) {
    */
   public function testSelectionHandler() {
     // Get values from selection handler.
-    $handler = $this->container->get('plugin.manager.entity_reference.selection')->getSelectionHandler($this->field);
+    $handler = $this->container->get('plugin.manager.entity_reference_selection')->getSelectionHandler($this->field);
     $result = $handler->getReferenceableEntities();
     $this->assertResults($result);
   }
@@ -140,7 +140,7 @@ public function testSelectionHandlerRelationship() {
     $view->save();
 
     // Get values from the selection handler.
-    $handler = $this->container->get('plugin.manager.entity_reference.selection')->getSelectionHandler($this->field);
+    $handler = $this->container->get('plugin.manager.entity_reference_selection')->getSelectionHandler($this->field);
     $result = $handler->getReferenceableEntities();
     $this->assertResults($result);
   }
diff --git a/core/modules/file/src/Plugin/entity_reference/selection/FileSelection.php b/core/modules/file/src/Plugin/EntityReferenceSelection/FileSelection.php
similarity index 71%
rename from core/modules/file/src/Plugin/entity_reference/selection/FileSelection.php
rename to core/modules/file/src/Plugin/EntityReferenceSelection/FileSelection.php
index dced1b1e07cf6e355fec4e8002aec3712e9b70ee..8c139808cbdd5d176661df4b53beece47d881067 100644
--- a/core/modules/file/src/Plugin/entity_reference/selection/FileSelection.php
+++ b/core/modules/file/src/Plugin/EntityReferenceSelection/FileSelection.php
@@ -2,18 +2,18 @@
 
 /**
  * @file
- * Contains \Drupal\file\Plugin\Type\selection\FileSelection.
+ * Contains \Drupal\file\Plugin\EntityReferenceSelection\FileSelection.
  */
 
-namespace Drupal\file\Plugin\entity_reference\selection;
+namespace Drupal\file\Plugin\EntityReferenceSelection;
 
-use Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase;
+use Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase;
 
 /**
  * Provides specific access control for the file entity type.
  *
  * @EntityReferenceSelection(
- *   id = "file_default",
+ *   id = "default:file",
  *   label = @Translation("File selection"),
  *   entity_types = {"file"},
  *   group = "default",
@@ -30,4 +30,5 @@ public function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
     $query->condition('status', FILE_STATUS_PERMANENT);
     return $query;
   }
+
 }
diff --git a/core/modules/node/src/Plugin/entity_reference/selection/NodeSelection.php b/core/modules/node/src/Plugin/EntityReferenceSelection/NodeSelection.php
similarity index 71%
rename from core/modules/node/src/Plugin/entity_reference/selection/NodeSelection.php
rename to core/modules/node/src/Plugin/EntityReferenceSelection/NodeSelection.php
index f850270cd8db5532b1906bbba2ba8fc3aa4c7093..e71d04e76d01fa9184c4ad42722fcec47f194859 100644
--- a/core/modules/node/src/Plugin/entity_reference/selection/NodeSelection.php
+++ b/core/modules/node/src/Plugin/EntityReferenceSelection/NodeSelection.php
@@ -2,18 +2,18 @@
 
 /**
  * @file
- * Contains \Drupal\node\Plugin\Type\selection\NodeSelection.
+ * Contains \Drupal\node\Plugin\EntityReferenceSelection\NodeSelection.
  */
 
-namespace Drupal\node\Plugin\entity_reference\selection;
+namespace Drupal\node\Plugin\EntityReferenceSelection;
 
-use Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase;
+use Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase;
 
 /**
  * Provides specific access control for the node entity type.
  *
  * @EntityReferenceSelection(
- *   id = "node_default",
+ *   id = "default:node",
  *   label = @Translation("Node selection"),
  *   entity_types = {"node"},
  *   group = "default",
@@ -32,9 +32,10 @@ public function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
     // 'unpublished'. We need to do that as long as there are no access control
     // modules in use on the site. As long as one access control module is there,
     // it is supposed to handle this check.
-    if (!\Drupal::currentUser()->hasPermission('bypass node access') && !count(\Drupal::moduleHandler()->getImplementations('node_grants'))) {
+    if (!$this->currentUser->hasPermission('bypass node access') && !count($this->moduleHandler->getImplementations('node_grants'))) {
       $query->condition('status', NODE_PUBLISHED);
     }
     return $query;
   }
+
 }
diff --git a/core/modules/entity_reference/src/Tests/EntityReferenceSelectionAccessTest.php b/core/modules/system/src/Tests/Entity/EntityReferenceSelection/EntityReferenceSelectionAccessTest.php
similarity index 80%
rename from core/modules/entity_reference/src/Tests/EntityReferenceSelectionAccessTest.php
rename to core/modules/system/src/Tests/Entity/EntityReferenceSelection/EntityReferenceSelectionAccessTest.php
index 591e61947b5f05a80c68da62aae4ab23722eafb6..5caeae3e8aac3f7a9d5d69052b4431e0a7654e99 100644
--- a/core/modules/entity_reference/src/Tests/EntityReferenceSelectionAccessTest.php
+++ b/core/modules/system/src/Tests/Entity/EntityReferenceSelection/EntityReferenceSelectionAccessTest.php
@@ -2,13 +2,12 @@
 
 /**
  * @file
- * Contains \Drupal\entity_reference\Tests\EntityReferenceSelectionAccessTest.
+ * Contains \Drupal\system\Tests\Entity\EntityReferenceSelection\EntityReferenceSelectionAccessTest.
  */
 
-namespace Drupal\entity_reference\Tests;
+namespace Drupal\system\Tests\Entity\EntityReferenceSelection;
 
 use Drupal\Component\Utility\String;
-use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\comment\CommentInterface;
 use Drupal\simpletest\WebTestBase;
@@ -20,7 +19,12 @@
  */
 class EntityReferenceSelectionAccessTest extends WebTestBase {
 
-  public static $modules = array('node', 'comment', 'entity_reference', 'entity_test');
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('node', 'comment');
 
   protected function setUp() {
     parent::setUp();
@@ -29,8 +33,18 @@ protected function setUp() {
     $this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article'));
   }
 
-  protected function assertReferenceable(FieldDefinitionInterface $field_definition, $tests, $handler_name) {
-    $handler = \Drupal::service('plugin.manager.entity_reference.selection')->getSelectionHandler($field_definition);
+  /**
+   * Checks that a selection plugin returns the expected results.
+   *
+   * @param array $selection_options
+   *   An array of options as required by entity reference selection plugins.
+   * @param array $tests
+   *   An array of tests to run.
+   * @param string $handler_name
+   *   The name of the entity type selection handler being tested.
+   */
+  protected function assertReferenceable(array $selection_options, $tests, $handler_name) {
+    $handler = \Drupal::service('plugin.manager.entity_reference_selection')->getInstance($selection_options);
 
     foreach ($tests as $test) {
       foreach ($test['arguments'] as $arguments) {
@@ -55,30 +69,13 @@ protected function assertReferenceable(FieldDefinitionInterface $field_definitio
    * Test the node-specific overrides of the entity handler.
    */
   public function testNodeHandler() {
-    // Create a field.
-    $field_storage = entity_create('field_storage_config', array(
-      'field_name' => 'test_field',
-      'entity_type' => 'entity_test',
-      'translatable' => FALSE,
-      'entity_types' => array(),
-      'settings' => array(
-        'target_type' => 'node',
-      ),
-      'type' => 'entity_reference',
-      'cardinality' => '1',
-    ));
-    $field_storage->save();
-    $field = entity_create('field_config', array(
-      'field_storage' => $field_storage,
-      'bundle' => 'test_bundle',
-      'settings' => array(
-        'handler' => 'default',
-        'handler_settings' => array(
-          'target_bundles' => array(),
-        ),
-      ),
-    ));
-    $field->save();
+    $selection_options = array(
+      'target_type' => 'node',
+      'handler' => 'default',
+      'handler_settings' => array(
+        'target_bundles' => array(),
+      ),
+    );
 
     // Build a set of test data.
     // Titles contain HTML-special characters to test escaping.
@@ -162,7 +159,7 @@ public function testNodeHandler() {
         'result' => array(),
       ),
     );
-    $this->assertReferenceable($field, $referenceable_tests, 'Node handler');
+    $this->assertReferenceable($selection_options, $referenceable_tests, 'Node handler');
 
     // Test as an admin.
     $admin_user = $this->drupalCreateUser(array('access content', 'bypass node access'));
@@ -191,36 +188,20 @@ public function testNodeHandler() {
         ),
       ),
     );
-    $this->assertReferenceable($field, $referenceable_tests, 'Node handler (admin)');
+    $this->assertReferenceable($selection_options, $referenceable_tests, 'Node handler (admin)');
   }
 
   /**
    * Test the user-specific overrides of the entity handler.
    */
   public function testUserHandler() {
-    // Create a field.
-    $field_storage = entity_create('field_storage_config', array(
-      'field_name' => 'test_field',
-      'entity_type' => 'entity_test',
-      'translatable' => FALSE,
-      'settings' => array(
-        'target_type' => 'user',
-      ),
-      'type' => 'entity_reference',
-      'cardinality' => '1',
-    ));
-    $field_storage->save();
-    $field = entity_create('field_config', array(
-      'field_storage' => $field_storage,
-      'bundle' => 'test_bundle',
-      'settings' => array(
-        'handler' => 'default',
-        'handler_settings' => array(
-          'target_bundles' => array(),
-        ),
-      ),
-    ));
-    $field->save();
+    $selection_options = array(
+      'target_type' => 'user',
+      'handler' => 'default',
+      'handler_settings' => array(
+        'target_bundles' => array(),
+      ),
+    );
 
     // Build a set of test data.
     $user_values = array(
@@ -296,7 +277,7 @@ public function testUserHandler() {
         'result' => array(),
       ),
     );
-    $this->assertReferenceable($field, $referenceable_tests, 'User handler');
+    $this->assertReferenceable($selection_options, $referenceable_tests, 'User handler');
 
     \Drupal::currentUser()->setAccount($users['admin']);
     $referenceable_tests = array(
@@ -335,37 +316,20 @@ public function testUserHandler() {
         ),
       ),
     );
-    $this->assertReferenceable($field, $referenceable_tests, 'User handler (admin)');
+    $this->assertReferenceable($selection_options, $referenceable_tests, 'User handler (admin)');
   }
 
   /**
    * Test the comment-specific overrides of the entity handler.
    */
   public function testCommentHandler() {
-    // Create a field.
-    $field_storage = entity_create('field_storage_config', array(
-      'field_name' => 'test_field',
-      'entity_type' => 'entity_test',
-      'translatable' => FALSE,
-      'entity_types' => array(),
-      'settings' => array(
-        'target_type' => 'comment',
-      ),
-      'type' => 'entity_reference',
-      'cardinality' => '1',
-    ));
-    $field_storage->save();
-    $field = entity_create('field_config', array(
-      'field_storage' => $field_storage,
-      'bundle' => 'test_bundle',
-      'settings' => array(
-        'handler' => 'default',
-        'handler_settings' => array(
-          'target_bundles' => array(),
-        ),
-      ),
-    ));
-    $field->save();
+    $selection_options = array(
+      'target_type' => 'comment',
+      'handler' => 'default',
+      'handler_settings' => array(
+        'target_bundles' => array(),
+      ),
+    );
 
     // Build a set of test data.
     $node_values = array(
@@ -474,7 +438,7 @@ public function testCommentHandler() {
         'result' => array(),
       ),
     );
-    $this->assertReferenceable($field, $referenceable_tests, 'Comment handler');
+    $this->assertReferenceable($selection_options, $referenceable_tests, 'Comment handler');
 
     // Test as a comment admin.
     $admin_user = $this->drupalCreateUser(array('access content', 'access comments', 'administer comments'));
@@ -492,7 +456,7 @@ public function testCommentHandler() {
         ),
       ),
     );
-    $this->assertReferenceable($field, $referenceable_tests, 'Comment handler (comment admin)');
+    $this->assertReferenceable($selection_options, $referenceable_tests, 'Comment handler (comment admin)');
 
     // Test as a node and comment admin.
     $admin_user = $this->drupalCreateUser(array('access content', 'access comments', 'administer comments', 'bypass node access'));
@@ -511,6 +475,7 @@ public function testCommentHandler() {
         ),
       ),
     );
-    $this->assertReferenceable($field, $referenceable_tests, 'Comment handler (comment + node admin)');
+    $this->assertReferenceable($selection_options, $referenceable_tests, 'Comment handler (comment + node admin)');
   }
+
 }
diff --git a/core/modules/entity_reference/src/Tests/EntityReferenceSelectionSortTest.php b/core/modules/system/src/Tests/Entity/EntityReferenceSelection/EntityReferenceSelectionSortTest.php
similarity index 63%
rename from core/modules/entity_reference/src/Tests/EntityReferenceSelectionSortTest.php
rename to core/modules/system/src/Tests/Entity/EntityReferenceSelection/EntityReferenceSelectionSortTest.php
index c0b3b35f6d58bb2791af8809d0327288d071173c..9370ddea6dbc3f9daff733b1d533dc3461d89c6c 100644
--- a/core/modules/entity_reference/src/Tests/EntityReferenceSelectionSortTest.php
+++ b/core/modules/system/src/Tests/Entity/EntityReferenceSelection/EntityReferenceSelectionSortTest.php
@@ -2,28 +2,42 @@
 
 /**
  * @file
- * Contains \Drupal\entity_reference\Tests\EntityReferenceSelectionSortTest.
+ * Contains \Drupal\system\Tests\Entity\EntityReferenceSelection\EntityReferenceSelectionSortTest.
  */
 
-namespace Drupal\entity_reference\Tests;
+namespace Drupal\system\Tests\Entity\EntityReferenceSelection;
 
 use Drupal\Component\Utility\String;
-use Drupal\simpletest\WebTestBase;
+use Drupal\node\Entity\Node;
+use Drupal\node\Entity\NodeType;
+use Drupal\system\Tests\Entity\EntityUnitTestBase;
 
 /**
  * Tests sorting referenced items.
  *
  * @group entity_reference
  */
-class EntityReferenceSelectionSortTest extends WebTestBase {
+class EntityReferenceSelectionSortTest extends EntityUnitTestBase {
 
-  public static $modules = array('node', 'entity_reference', 'entity_test');
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('node');
 
   protected function setUp() {
     parent::setUp();
 
     // Create an Article node type.
-    $this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article'));
+    $article = NodeType::create(array(
+      'type' => 'article',
+    ));
+    $article->save();
+
+    // Test as a non-admin.
+    $normal_user = $this->createUser(array(), array('access content'));
+    \Drupal::currentUser()->setAccount($normal_user);
   }
 
   /**
@@ -47,37 +61,6 @@ public function testSort() {
       'required' => FALSE,
     ))->save();
 
-
-    // Create a field.
-    $field_storage = entity_create('field_storage_config', array(
-      'field_name' => 'test_field',
-      'entity_type' => 'entity_test',
-      'translatable' => FALSE,
-      'settings' => array(
-        'target_type' => 'node',
-      ),
-      'type' => 'entity_reference',
-      'cardinality' => 1,
-    ));
-    $field_storage->save();
-    $field = entity_create('field_config', array(
-      'field_storage' => $field_storage,
-      'entity_type' => 'entity_test',
-      'bundle' => 'test_bundle',
-      'settings' => array(
-        'handler' => 'default',
-        'handler_settings' => array(
-          'target_bundles' => array(),
-          // Add sorting.
-          'sort' => array(
-            'field' => 'field_text.value',
-            'direction' => 'DESC',
-          ),
-        ),
-      ),
-    ));
-    $field->save();
-
     // Build a set of test data.
     $node_values = array(
       'published1' => array(
@@ -107,17 +90,25 @@ public function testSort() {
     $nodes = array();
     $node_labels = array();
     foreach ($node_values as $key => $values) {
-      $node = entity_create('node', $values);
+      $node = Node::create($values);
       $node->save();
       $nodes[$key] = $node;
       $node_labels[$key] = String::checkPlain($node->label());
     }
 
-    // Test as a non-admin.
-    $normal_user = $this->drupalCreateUser(array('access content'));
-    \Drupal::currentUser()->setAccount($normal_user);
-
-    $handler = $this->container->get('plugin.manager.entity_reference.selection')->getSelectionHandler($field);
+    $selection_options = array(
+      'target_type' => 'node',
+      'handler' => 'default',
+      'handler_settings' => array(
+        'target_bundles' => array(),
+        // Add sorting.
+        'sort' => array(
+          'field' => 'field_text.value',
+          'direction' => 'DESC',
+        ),
+      ),
+    );
+    $handler = $this->container->get('plugin.manager.entity_reference_selection')->getInstance($selection_options);
 
     // Not only assert the result, but make sure the keys are sorted as
     // expected.
@@ -128,12 +119,12 @@ public function testSort() {
     );
     $this->assertIdentical($result['article'], $expected_result, 'Query sorted by field returned expected values.');
 
-    // Assert sort by property.
-    $field->settings['handler_settings']['sort'] = array(
+    // Assert sort by base field.
+    $selection_options['handler_settings']['sort'] = array(
       'field' => 'nid',
       'direction' => 'ASC',
     );
-    $handler = $this->container->get('plugin.manager.entity_reference.selection')->getSelectionHandler($field);
+    $handler = $this->container->get('plugin.manager.entity_reference_selection')->getInstance($selection_options);
     $result = $handler->getReferenceableEntities();
     $expected_result = array(
       $nodes['published1']->id() => $node_labels['published1'],
@@ -141,4 +132,5 @@ public function testSort() {
     );
     $this->assertIdentical($result['article'], $expected_result, 'Query sorted by property returned expected values.');
   }
+
 }
diff --git a/core/modules/taxonomy/src/Plugin/entity_reference/selection/TermSelection.php b/core/modules/taxonomy/src/Plugin/EntityReferenceSelection/TermSelection.php
similarity index 61%
rename from core/modules/taxonomy/src/Plugin/entity_reference/selection/TermSelection.php
rename to core/modules/taxonomy/src/Plugin/EntityReferenceSelection/TermSelection.php
index 5d4469fc84a1339b651f318abd2416c184bfdcdd..9bb31b124af1a2b8cc07bb3542c6d79e6aa87234 100644
--- a/core/modules/taxonomy/src/Plugin/entity_reference/selection/TermSelection.php
+++ b/core/modules/taxonomy/src/Plugin/EntityReferenceSelection/TermSelection.php
@@ -2,22 +2,22 @@
 
 /**
  * @file
- * Contains \Drupal\taxonomy\Plugin\entity_reference\selection\TermSelection.
+ * Contains \Drupal\taxonomy\Plugin\EntityReferenceSelection\TermSelection.
  */
 
-namespace Drupal\taxonomy\Plugin\entity_reference\selection;
+namespace Drupal\taxonomy\Plugin\EntityReferenceSelection;
 
 use Drupal\Component\Utility\String;
 use Drupal\Core\Database\Query\SelectInterface;
-use Drupal\Core\Field\FieldDefinitionInterface;
-use Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase;
+use Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase;
+use Drupal\Core\Form\FormStateInterface;
 use Drupal\taxonomy\Entity\Vocabulary;
 
 /**
  * Provides specific access control for the taxonomy_term entity type.
  *
  * @EntityReferenceSelection(
- *   id = "taxonomy_term_default",
+ *   id = "default:taxonomy_term",
  *   label = @Translation("Taxonomy Term selection"),
  *   entity_types = {"taxonomy_term"},
  *   group = "default",
@@ -36,15 +36,14 @@ public function entityQueryAlter(SelectInterface $query) {
   /**
    * {@inheritdoc}
    */
-  public static function settingsForm(FieldDefinitionInterface $field_definition) {
-    $form = parent::settingsForm($field_definition);
-    $selection_handler_settings = $field_definition->getSetting('handler_settings');
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    $form = parent::buildConfigurationForm($form, $form_state);
 
     // @todo: Currently allow auto-create only on taxonomy terms.
     $form['auto_create'] = array(
       '#type' => 'checkbox',
-      '#title' => t("Create referenced entities if they don't already exist"),
-      '#default_value' => isset($selection_handler_settings['auto_create']) ? $selection_handler_settings['auto_create'] : FALSE,
+      '#title' => $this->t("Create referenced entities if they don't already exist"),
+      '#default_value' => isset($this->configuration['handler_settings']['auto_create']) ? $this->configuration['handler_settings']['auto_create'] : FALSE,
     );
     return $form;
 
@@ -60,13 +59,13 @@ public function getReferenceableEntities($match = NULL, $match_operator = 'CONTA
 
     $options = array();
 
-    $bundles = entity_get_bundles('taxonomy_term');
-    $handler_settings = $this->fieldDefinition->getSetting('handler_settings');
+    $bundles = $this->entityManager->getBundleInfo('taxonomy_term');
+    $handler_settings = $this->configuration['handler_settings'];
     $bundle_names = !empty($handler_settings['target_bundles']) ? $handler_settings['target_bundles'] : array_keys($bundles);
 
     foreach ($bundle_names as $bundle) {
       if ($vocabulary = Vocabulary::load($bundle)) {
-        if ($terms = taxonomy_get_tree($vocabulary->id(), 0, NULL, TRUE)) {
+        if ($terms = $this->entityManager->getStorage('taxonomy_term')->loadTree($vocabulary->id(), 0, NULL, TRUE)) {
           foreach ($terms as $term) {
             $options[$vocabulary->id()][$term->id()] = str_repeat('-', $term->depth) . String::checkPlain($term->getName());
           }
@@ -76,4 +75,5 @@ public function getReferenceableEntities($match = NULL, $match_operator = 'CONTA
 
     return $options;
   }
+
 }
diff --git a/core/modules/taxonomy/src/Tests/TermEntityReferenceTest.php b/core/modules/taxonomy/src/Tests/TermEntityReferenceTest.php
index 5f4e9300351f37e4a62cdc488ab46ca262a922d7..fc452ff08ab552757f1bfd8eb97b300dde085560 100644
--- a/core/modules/taxonomy/src/Tests/TermEntityReferenceTest.php
+++ b/core/modules/taxonomy/src/Tests/TermEntityReferenceTest.php
@@ -69,7 +69,7 @@ function testSelectionTestVocabularyRestriction() {
     ));
     $field->save();
 
-    $handler = $this->container->get('plugin.manager.entity_reference.selection')->getSelectionHandler($field);
+    $handler = $this->container->get('plugin.manager.entity_reference_selection')->getSelectionHandler($field);
     $result = $handler->getReferenceableEntities();
 
     $expected_result = array(
diff --git a/core/modules/user/src/Plugin/entity_reference/selection/UserSelection.php b/core/modules/user/src/Plugin/EntityReferenceSelection/UserSelection.php
similarity index 58%
rename from core/modules/user/src/Plugin/entity_reference/selection/UserSelection.php
rename to core/modules/user/src/Plugin/EntityReferenceSelection/UserSelection.php
index 5705feff4563a7da7d8904878a95cddd88f82ee0..7d4849db5bb5308d4a2414d54eec65e1c113e445 100644
--- a/core/modules/user/src/Plugin/entity_reference/selection/UserSelection.php
+++ b/core/modules/user/src/Plugin/EntityReferenceSelection/UserSelection.php
@@ -2,21 +2,25 @@
 
 /**
  * @file
- * Contains \Drupal\user\Plugin\entity_reference\selection\UserSelection.
+ * Contains \Drupal\user\Plugin\EntityReferenceSelection\UserSelection.
  */
 
-namespace Drupal\user\Plugin\entity_reference\selection;
+namespace Drupal\user\Plugin\EntityReferenceSelection;
 
-use Drupal\Core\Database\Database;
+use Drupal\Core\Database\Connection;
 use Drupal\Core\Database\Query\SelectInterface;
-use Drupal\Core\Field\FieldDefinitionInterface;
-use Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase;
+use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Session\AccountInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Provides specific access control for the user entity type.
  *
  * @EntityReferenceSelection(
- *   id = "user_default",
+ *   id = "default:user",
  *   label = @Translation("User selection"),
  *   entity_types = {"user"},
  *   group = "default",
@@ -25,11 +29,57 @@
  */
 class UserSelection extends SelectionBase {
 
+  /**
+   * The database connection.
+   *
+   * @var \Drupal\Core\Database\Connection
+   */
+  protected $connection;
+
+  /**
+   * Constructs a new UserSelection object.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+   *   The entity manager service.
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler service.
+   * @param \Drupal\Core\Session\AccountInterface $current_user
+   *   The current user.
+   * @param \Drupal\Core\Database\Connection $connection
+   *   The database connection.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $entity_manager, ModuleHandlerInterface $module_handler, AccountInterface $current_user, Connection $connection) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_manager, $module_handler, $current_user);
+
+    $this->connection = $connection;
+  }
+
   /**
    * {@inheritdoc}
    */
-  public static function settingsForm(FieldDefinitionInterface $field_definition) {
-    $selection_handler_settings = $field_definition->getSetting('handler_settings');
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('entity.manager'),
+      $container->get('module_handler'),
+      $container->get('current_user'),
+      $container->get('database')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    $selection_handler_settings = $this->configuration['handler_settings'];
 
     // Merge in default values.
     $selection_handler_settings += array(
@@ -41,10 +91,10 @@ public static function settingsForm(FieldDefinitionInterface $field_definition)
     // Add user specific filter options.
     $form['filter']['type'] = array(
       '#type' => 'select',
-      '#title' => t('Filter by'),
+      '#title' => $this->t('Filter by'),
       '#options' => array(
-        '_none' => t('- None -'),
-        'role' => t('User role'),
+        '_none' => $this->t('- None -'),
+        'role' => $this->t('User role'),
       ),
       '#ajax' => TRUE,
       '#limit_validation_errors' => array(),
@@ -65,14 +115,14 @@ public static function settingsForm(FieldDefinitionInterface $field_definition)
 
       $form['filter']['settings']['role'] = array(
         '#type' => 'checkboxes',
-        '#title' => t('Restrict to the selected roles'),
+        '#title' => $this->t('Restrict to the selected roles'),
         '#required' => TRUE,
         '#options' => array_diff_key(user_role_names(TRUE), array(DRUPAL_AUTHENTICATED_RID => DRUPAL_AUTHENTICATED_RID)),
         '#default_value' => $selection_handler_settings['filter']['role'],
       );
     }
 
-    $form += parent::settingsForm($field_definition);
+    $form += parent::buildConfigurationForm($form, $form_state);
 
     return $form;
   }
@@ -89,14 +139,14 @@ public function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
     }
 
     // Filter by role.
-    $handler_settings = $this->fieldDefinition->getSetting('handler_settings');
+    $handler_settings = $this->configuration['handler_settings'];
     if (!empty($handler_settings['filter']['role'])) {
       $query->condition('roles', $handler_settings['filter']['role'], 'IN');
     }
 
     // Adding the permission check is sadly insufficient for users: core
     // requires us to also know about the concept of 'blocked' and 'active'.
-    if (!\Drupal::currentUser()->hasPermission('administer users')) {
+    if (!$this->currentUser->hasPermission('administer users')) {
       $query->condition('status', 1);
     }
     return $query;
@@ -106,7 +156,7 @@ public function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
    * {@inheritdoc}
    */
   public function entityQueryAlter(SelectInterface $query) {
-    if (\Drupal::currentUser()->hasPermission('administer users')) {
+    if ($this->currentUser->hasPermission('administer users')) {
       // In addition, if the user is administrator, we need to make sure to
       // match the anonymous user, that doesn't actually have a name in the
       // database.
@@ -128,7 +178,7 @@ public function entityQueryAlter(SelectInterface $query) {
           // field, and concatenate the field and the condition separately.
           $value_part = db_and();
           $value_part->condition('anonymous_name', $condition['value'], $condition['operator']);
-          $value_part->compile(Database::getConnection(), $query);
+          $value_part->compile($this->connection, $query);
           $or->condition(db_and()
             ->where(str_replace('anonymous_name', ':anonymous_name', (string) $value_part), $value_part->arguments() + array(':anonymous_name' => user_format_name(user_load(0))))
             ->condition('base_table.uid', 0)
@@ -138,4 +188,5 @@ public function entityQueryAlter(SelectInterface $query) {
       }
     }
   }
+
 }
diff --git a/core/modules/views/src/Plugin/entity_reference/selection/ViewsSelection.php b/core/modules/views/src/Plugin/EntityReferenceSelection/ViewsSelection.php
similarity index 65%
rename from core/modules/views/src/Plugin/entity_reference/selection/ViewsSelection.php
rename to core/modules/views/src/Plugin/EntityReferenceSelection/ViewsSelection.php
index f933ea217ca7c29a3336766804d92dd713818813..4c0d889181f5293fc91da197d36b85646ccd1712 100644
--- a/core/modules/views/src/Plugin/entity_reference/selection/ViewsSelection.php
+++ b/core/modules/views/src/Plugin/EntityReferenceSelection/ViewsSelection.php
@@ -2,17 +2,20 @@
 
 /**
  * @file
- * Contains \Drupal\views\Plugin\entity_reference\selection\ViewsSelection.
+ * Contains \Drupal\views\Plugin\EntityReferenceSelection\ViewsSelection.
  */
 
-namespace Drupal\views\Plugin\entity_reference\selection;
+namespace Drupal\views\Plugin\EntityReferenceSelection;
 
 use Drupal\Core\Database\Query\SelectInterface;
-use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface;
+use Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Plugin\PluginBase;
+use Drupal\Core\Url;
 use Drupal\views\Views;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Plugin implementation of the 'selection' entity_reference.
@@ -24,47 +27,62 @@
  *   weight = 0
  * )
  */
-class ViewsSelection implements SelectionInterface {
+class ViewsSelection extends PluginBase implements SelectionInterface, ContainerFactoryPluginInterface {
 
   /**
-   * The field definition.
+   * The entity manager.
    *
-   * @var \Drupal\Core\Field\FieldDefinitionInterface
+   * @var \Drupal\Core\Entity\EntityManagerInterface
    */
-  protected $fieldDefinition;
+  protected $entityManager;
 
   /**
-   * The entity object, or NULL
+   * The loaded View object.
    *
-   * @var \Drupal\Core\Entity\EntityInterface|null
+   * @var \Drupal\views\ViewExecutable;
    */
-  protected $entity;
+  protected $view;
 
   /**
-   * The loaded View object.
+   * Constructs a new ViewsSelection object.
    *
-   * @var \Drupal\views\ViewExecutable;
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+   *   The entity manager service.
    */
-  protected $view;
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $entity_manager) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+
+    $this->entityManager = $entity_manager;
+  }
 
   /**
-   * Constructs a View selection handler.
+   * {@inheritdoc}
    */
-  public function __construct(FieldDefinitionInterface $field_definition, EntityInterface $entity = NULL) {
-    $this->fieldDefinition = $field_definition;
-    $this->entity = $entity;
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('entity.manager')
+    );
   }
 
   /**
    * {@inheritdoc}
    */
-  public static function settingsForm(FieldDefinitionInterface $field_definition) {
-    $selection_handler_settings = $field_definition->getSetting('handler_settings') ?: array();
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    $selection_handler_settings = $this->configuration['handler_settings'];
     $view_settings = !empty($selection_handler_settings['view']) ? $selection_handler_settings['view'] : array();
     $displays = Views::getApplicableViews('entity_reference_display');
     // Filter views that list the entity type we want, and group the separate
     // displays by view.
-    $entity_type = \Drupal::entityManager()->getDefinition($field_definition->getSetting('target_type'));
+    $entity_type = $this->entityManager->getDefinition($this->configuration['target_type']);
     $options = array();
     foreach ($displays as $data) {
       list($view, $display_id) = $data;
@@ -79,40 +97,49 @@ public static function settingsForm(FieldDefinitionInterface $field_definition)
     // into 'view_name' and 'view_display' in the final submitted values, so
     // we massage the data at validate time on the wrapping element (not
     // ideal).
-    $plugin = new static($field_definition);
-    $form['view']['#element_validate'] = array(array($plugin, 'settingsFormValidate'));
+    $form['view']['#element_validate'] = array(array(get_called_class(), 'settingsFormValidate'));
 
     if ($options) {
       $default = !empty($view_settings['view_name']) ? $view_settings['view_name'] . ':' . $view_settings['display_name'] : NULL;
       $form['view']['view_and_display'] = array(
         '#type' => 'select',
-        '#title' => t('View used to select the entities'),
+        '#title' => $this->t('View used to select the entities'),
         '#required' => TRUE,
         '#options' => $options,
         '#default_value' => $default,
-        '#description' => '<p>' . t('Choose the view and display that select the entities that can be referenced.<br />Only views with a display of type "Entity Reference" are eligible.') . '</p>',
+        '#description' => '<p>' . $this->t('Choose the view and display that select the entities that can be referenced.<br />Only views with a display of type "Entity Reference" are eligible.') . '</p>',
       );
 
       $default = !empty($view_settings['arguments']) ? implode(', ', $view_settings['arguments']) : '';
       $form['view']['arguments'] = array(
         '#type' => 'textfield',
-        '#title' => t('View arguments'),
+        '#title' => $this->t('View arguments'),
         '#default_value' => $default,
         '#required' => FALSE,
-        '#description' => t('Provide a comma separated list of arguments to pass to the view.'),
+        '#description' => $this->t('Provide a comma separated list of arguments to pass to the view.'),
       );
     }
     else {
       $form['view']['no_view_help'] = array(
-        '#markup' => '<p>' . t('No eligible views were found. <a href="@create">Create a view</a> with an <em>Entity Reference</em> display, or add such a display to an <a href="@existing">existing view</a>.', array(
-          '@create' => \Drupal::url('views_ui.add'),
-          '@existing' => \Drupal::url('entity.view.collection'),
+        '#markup' => '<p>' . $this->t('No eligible views were found. <a href="@create">Create a view</a> with an <em>Entity Reference</em> display, or add such a display to an <a href="@existing">existing view</a>.', array(
+          '@create' => Url::fromRoute('views_ui.add'),
+          '@existing' => Url::fromRoute('entity.view.collection'),
         )) . '</p>',
       );
     }
     return $form;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { }
+
   /**
    * Initializes a view.
    *
@@ -131,14 +158,14 @@ public static function settingsForm(FieldDefinitionInterface $field_definition)
    *   Return TRUE if the view was initialized, FALSE otherwise.
    */
   protected function initializeView($match = NULL, $match_operator = 'CONTAINS', $limit = 0, $ids = NULL) {
-    $handler_settings = $this->fieldDefinition->getSetting('handler_settings');
+    $handler_settings = $this->configuration['handler_settings'];
     $view_name = $handler_settings['view']['view_name'];
     $display_name = $handler_settings['view']['display_name'];
 
     // Check that the view is valid and the display still exists.
     $this->view = Views::getView($view_name);
     if (!$this->view || !$this->view->access($display_name)) {
-      drupal_set_message(t('The reference view %view_name used in the %field_name field cannot be found.', array('%view_name' => $view_name, '%field_name' => $this->fieldDefinition->getLabel())), 'warning');
+      drupal_set_message(t('The reference view %view_name cannot be found.', array('%view_name' => $view_name)), 'warning');
       return FALSE;
     }
     $this->view->setDisplay($display_name);
@@ -158,7 +185,7 @@ protected function initializeView($match = NULL, $match_operator = 'CONTAINS', $
    * {@inheritdoc}
    */
   public function getReferenceableEntities($match = NULL, $match_operator = 'CONTAINS', $limit = 0) {
-    $handler_settings = $this->fieldDefinition->getSetting('handler_settings');
+    $handler_settings = $this->configuration['handler_settings'];
     $display_name = $handler_settings['view']['display_name'];
     $arguments = $handler_settings['view']['arguments'];
     $result = array();
@@ -189,7 +216,7 @@ public function countReferenceableEntities($match = NULL, $match_operator = 'CON
    * {@inheritdoc}
    */
   public function validateReferenceableEntities(array $ids) {
-    $handler_settings = $this->fieldDefinition->getSetting('handler_settings');
+    $handler_settings = $this->configuration['handler_settings'];
     $display_name = $handler_settings['view']['display_name'];
     $arguments = $handler_settings['view']['arguments'];
     $result = array();
@@ -222,7 +249,7 @@ public function settingsFormValidate($element, FormStateInterface $form_state, $
       list($view, $display) = explode(':', $element['view_and_display']['#value']);
     }
     else {
-      $form_state->setError($element, t('The views entity selection mode requires a view.'));
+      $form_state->setError($element, $this->t('The views entity selection mode requires a view.'));
       return;
     }