diff --git a/core/core.services.yml b/core/core.services.yml
index 465d145..9afeed2 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -38,6 +38,13 @@ services:
     factory_method: get
     factory_service: cache_factory
     arguments: [entity]
+  cache.field:
+    class: Drupal\Core\Cache\CacheBackendInterface
+    tags:
+      - { name: cache.bin }
+    factory_method: get
+    factory_service: cache_factory
+    arguments: [field]
   cache.menu:
     class: Drupal\Core\Cache\CacheBackendInterface
     tags:
@@ -163,9 +170,15 @@ services:
     arguments: ['@container.namespaces', '@service_container', '@module_handler', '@cache.cache', '@language_manager', '@string_translation']
   plugin.manager.entity:
     alias: entity.manager
-  plugin.manager.entity.field.field_type:
-    class: Drupal\Core\Entity\Field\FieldTypePluginManager
-    arguments: ['@container.namespaces', '@cache.entity', '@language_manager', '@module_handler']
+  plugin.manager.field.field_type:
+    class: Drupal\Core\Field\FieldTypePluginManager
+    arguments: ['@container.namespaces', '@cache.field', '@language_manager', '@module_handler']
+  plugin.manager.field.widget:
+    class: Drupal\Core\Field\WidgetPluginManager
+    arguments: ['@container.namespaces', '@cache.field', '@module_handler', '@language_manager', '@plugin.manager.field.field_type']
+  plugin.manager.field.formatter:
+    class: Drupal\Core\Field\FormatterPluginManager
+    arguments: ['@container.namespaces', '@cache.field', '@module_handler', '@language_manager', '@plugin.manager.field.field_type']
   plugin.manager.archiver:
     class: Drupal\Core\Archiver\ArchiverManager
     arguments: ['@container.namespaces', '@cache.cache', '@language_manager', '@module_handler']
diff --git a/core/lib/Drupal/Core/Entity/Annotation/FieldType.php b/core/lib/Drupal/Core/Entity/Annotation/FieldType.php
deleted file mode 100644
index d9a1a3f..0000000
--- a/core/lib/Drupal/Core/Entity/Annotation/FieldType.php
+++ /dev/null
@@ -1,122 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Entity\Annotation\FieldType.
- */
-
-namespace Drupal\Core\Entity\Annotation;
-
-use Drupal\Core\TypedData\Annotation\DataType;
-
-/**
- * Defines a FieldType annotation object.
- *
- * Additional annotation keys for field types can be defined in
- * hook_field_info_alter().
- *
- * @Annotation
- */
-class FieldType extends DataType {
-
-  /**
-   * The plugin ID.
-   *
-   * @var string
-   */
-  public $id;
-
-  /**
-   * The name of the module providing the field type plugin.
-   *
-   * @var string
-   */
-  public $module;
-
-  /**
-   * The human-readable name of the field type.
-   *
-   * @ingroup plugin_translatable
-   *
-   * @var \Drupal\Core\Annotation\Translation
-   */
-  public $label;
-
-  /**
-   * A short human readable description for the field type.
-   *
-   * @ingroup plugin_translatable
-   *
-   * @var \Drupal\Core\Annotation\Translation
-   */
-  public $description;
-
-  /**
-   * An array of field-level settings available for the field type.
-   *
-   * Keys are the names of the settings, and values are the default values for
-   * those settings.
-   *
-   * @var array
-   */
-  public $settings;
-
-  /**
-   * An array of instance-level settings available for the field type.
-   *
-   * Keys are the names of the settings, and values are the default values for
-   * those settings.
-   *
-   * Instance-level settings can have different values on each field instance,
-   * and thus allow greater flexibility than field-level settings. It is
-   * recommended to put settings at the instance level whenever possible.
-   * Notable exceptions: settings acting on the storage schema, or settings that
-   * Views needs to use across field instances (for example, settings defining
-   * the list of allowed values for the field).
-   *
-   * @var array
-   */
-  public $instance_settings;
-
-  /**
-   * The plugin_id of the default widget for this field type.
-   *
-   * This widget must be available whenever the field type is available (i.e.
-   * provided by the field type module, or by a module the field type module
-   * depends on).
-   *
-   * @var string
-   */
-  public $default_widget;
-
-  /**
-   * The plugin_id of the default formatter for this field type.
-   *
-   * This formatter must be available whenever the field type is available (i.e.
-   * provided by the field type module, or by a module the field type module
-   * depends on).
-   *
-   * @var string
-   */
-  public $default_formatter;
-
-  /**
-   * A boolean stating that fields of this type are configurable.
-   *
-   * @var boolean
-   */
-  public $configurable = TRUE;
-
-  /**
-   * A boolean stating that fields of this type cannot be created through the UI.
-   *
-   * @var boolean
-   */
-  public $no_ui = FALSE;
-
-  /**
-   * {@inheritdoc}
-   */
-  public $list_class;
-
-}
diff --git a/core/lib/Drupal/Core/Entity/Field/FieldTypePluginManager.php b/core/lib/Drupal/Core/Entity/Field/FieldTypePluginManager.php
deleted file mode 100644
index 734608e..0000000
--- a/core/lib/Drupal/Core/Entity/Field/FieldTypePluginManager.php
+++ /dev/null
@@ -1,111 +0,0 @@
-<?php
-
-/**
- * @file
- *
- * Contains \Drupal\Core\Entity\Field\FieldTypePluginManager.
- */
-
-namespace Drupal\Core\Entity\Field;
-
-use Drupal\Core\Cache\CacheBackendInterface;
-use Drupal\Core\Extension\ModuleHandlerInterface;
-use Drupal\Core\Language\LanguageManager;
-use Drupal\Core\Plugin\DefaultPluginManager;
-use Drupal\field\Plugin\Type\FieldType\LegacyFieldTypeDiscoveryDecorator;
-
-/**
- * Plugin manager for 'field type' plugins.
- */
-class FieldTypePluginManager extends DefaultPluginManager {
-
-  /**
-   * {@inheritdoc}
-   */
-  protected $defaults = array(
-    'settings' => array(),
-    'instance_settings' => array(),
-  );
-
-  /**
-   * Constructs the FieldTypePluginManager object
-   *
-   * @param \Traversable $namespaces
-   *   An object that implements \Traversable which contains the root paths
-   *   keyed by the corresponding namespace to look for plugin implementations.
-   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
-   *   Cache backend instance to use.
-   * @param \Drupal\Core\Language\LanguageManager $language_manager
-   *   The language manager.
-   * @param \Drupal\Core\Extension\ModuleHandlerInterface
-   *   The module handler.
-   */
-  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler) {
-    parent::__construct('Plugin/field/field_type', $namespaces, 'Drupal\Core\Entity\Annotation\FieldType');
-    $this->alterInfo($module_handler, 'field_info');
-    $this->setCacheBackend($cache_backend, $language_manager, 'field_types_plugins');
-
-    // @todo Remove once all core field types have been converted (see
-    // http://drupal.org/node/2014671).
-    $this->discovery = new LegacyFieldTypeDiscoveryDecorator($this->discovery, $module_handler);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function processDefinition(&$definition, $plugin_id) {
-    parent::processDefinition($definition, $plugin_id);
-    if (!isset($definition['list_class'])) {
-      if ($definition['configurable']) {
-        $definition['list_class'] = '\Drupal\field\Plugin\Type\FieldType\ConfigFieldItemList';
-      }
-      else {
-        $definition['list_class'] = '\Drupal\Core\Entity\Field\FieldItemList';
-      }
-    }
-  }
-
-  /**
-   * Returns the default field-level settings for a field type.
-   *
-   * @param string $type
-   *   A field type name.
-   *
-   * @return array
-   *   The type's default settings, as provided by the plugin
-   *   definition, or an empty array if type or settings are undefined.
-   */
-  public function getDefaultSettings($type) {
-    $info = $this->getDefinition($type);
-    return isset($info['settings']) ? $info['settings'] : array();
-  }
-
-  /**
-   * Returns the default instance-level settings for a field type.
-   *
-   * @param string $type
-   *   A field type name.
-   *
-   * @return array
-   *   The instance's default settings, as provided by the plugin
-   *   definition, or an empty array if type or settings are undefined.
-   */
-  public function getDefaultInstanceSettings($type) {
-    $info = $this->getDefinition($type);
-    return isset($info['instance_settings']) ? $info['instance_settings'] : array();
-  }
-
-  /**
-   * Gets the definition of all field types that are configurable.
-   *
-   * @return array
-   *   An array of field type definitions.
-   */
-  public function getConfigurableDefinitions() {
-    $definitions = $this->getDefinitions();
-    return array_filter($definitions, function ($definition) {
-      return $definition['configurable'];
-    });
-  }
-
-}
diff --git a/core/lib/Drupal/Core/Entity/Plugin/DataType/Deriver/FieldItemDeriver.php b/core/lib/Drupal/Core/Entity/Plugin/DataType/Deriver/FieldItemDeriver.php
index 60b47f9..5e287f7 100644
--- a/core/lib/Drupal/Core/Entity/Plugin/DataType/Deriver/FieldItemDeriver.php
+++ b/core/lib/Drupal/Core/Entity/Plugin/DataType/Deriver/FieldItemDeriver.php
@@ -56,7 +56,7 @@ public function __construct($base_plugin_id, PluginManagerInterface $field_type_
   public static function create(ContainerInterface $container, $base_plugin_id) {
     return new static(
       $base_plugin_id,
-      $container->get('plugin.manager.entity.field.field_type')
+      $container->get('plugin.manager.field.field_type')
     );
   }
 
diff --git a/core/lib/Drupal/Core/Field/Annotation/FieldFormatter.php b/core/lib/Drupal/Core/Field/Annotation/FieldFormatter.php
new file mode 100644
index 0000000..1ef899e
--- /dev/null
+++ b/core/lib/Drupal/Core/Field/Annotation/FieldFormatter.php
@@ -0,0 +1,78 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Field\Annotation\FieldFormatter.
+ */
+
+namespace Drupal\Core\Field\Annotation;
+
+use Drupal\Component\Annotation\Plugin;
+
+/**
+ * Defines a FieldFormatter annotation object.
+ *
+ * Formatters handle the display of field values. Formatter hooks are typically
+ * called by the Field Attach API field_attach_prepare_view() and
+ * field_attach_view() functions.
+ *
+ * Additional annotation keys for formatters can be defined in
+ * hook_field_formatter_info_alter().
+ *
+ * @Annotation
+ *
+ * @see \Drupal\Core\Field\FormatterPluginManager
+ * @see \Drupal\Core\Field\FormatterInterface
+ */
+class FieldFormatter extends Plugin {
+
+  /**
+   * The plugin ID.
+   *
+   * @var string
+   */
+  public $id;
+
+  /**
+   * The human-readable name of the formatter type.
+   *
+   * @ingroup plugin_translatable
+   *
+   * @var \Drupal\Core\Annotation\Translation
+   */
+  public $label;
+
+  /**
+   * A short description of the formatter type.
+   *
+   * @ingroup plugin_translatable
+   *
+   * @var \Drupal\Core\Annotation\Translation
+   */
+  public $description;
+
+  /**
+   * The name of the field formatter class.
+   *
+   * This is not provided manually, it will be added by the discovery mechanism.
+   *
+   * @var string
+   */
+  public $class;
+
+  /**
+   * An array of field types the formatter supports.
+   *
+   * @var array
+   */
+  public $field_types = array();
+
+  /**
+   * An array whose keys are the names of the settings available to the
+   * formatter type, and whose values are the default values for those settings.
+   *
+   * @var array
+   */
+  public $settings = array();
+
+}
diff --git a/core/lib/Drupal/Core/Field/Annotation/FieldType.php b/core/lib/Drupal/Core/Field/Annotation/FieldType.php
new file mode 100644
index 0000000..90d0cf7
--- /dev/null
+++ b/core/lib/Drupal/Core/Field/Annotation/FieldType.php
@@ -0,0 +1,122 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Entity\Annotation\FieldType.
+ */
+
+namespace Drupal\Core\Field\Annotation;
+
+use Drupal\Core\TypedData\Annotation\DataType;
+
+/**
+ * Defines a FieldType annotation object.
+ *
+ * Additional annotation keys for field types can be defined in
+ * hook_field_info_alter().
+ *
+ * @Annotation
+ */
+class FieldType extends DataType {
+
+  /**
+   * The plugin ID.
+   *
+   * @var string
+   */
+  public $id;
+
+  /**
+   * The name of the module providing the field type plugin.
+   *
+   * @var string
+   */
+  public $module;
+
+  /**
+   * The human-readable name of the field type.
+   *
+   * @ingroup plugin_translatable
+   *
+   * @var \Drupal\Core\Annotation\Translation
+   */
+  public $label;
+
+  /**
+   * A short human readable description for the field type.
+   *
+   * @ingroup plugin_translatable
+   *
+   * @var \Drupal\Core\Annotation\Translation
+   */
+  public $description;
+
+  /**
+   * An array of field-level settings available for the field type.
+   *
+   * Keys are the names of the settings, and values are the default values for
+   * those settings.
+   *
+   * @var array
+   */
+  public $settings;
+
+  /**
+   * An array of instance-level settings available for the field type.
+   *
+   * Keys are the names of the settings, and values are the default values for
+   * those settings.
+   *
+   * Instance-level settings can have different values on each field instance,
+   * and thus allow greater flexibility than field-level settings. It is
+   * recommended to put settings at the instance level whenever possible.
+   * Notable exceptions: settings acting on the storage schema, or settings that
+   * Views needs to use across field instances (for example, settings defining
+   * the list of allowed values for the field).
+   *
+   * @var array
+   */
+  public $instance_settings;
+
+  /**
+   * The plugin_id of the default widget for this field type.
+   *
+   * This widget must be available whenever the field type is available (i.e.
+   * provided by the field type module, or by a module the field type module
+   * depends on).
+   *
+   * @var string
+   */
+  public $default_widget;
+
+  /**
+   * The plugin_id of the default formatter for this field type.
+   *
+   * This formatter must be available whenever the field type is available (i.e.
+   * provided by the field type module, or by a module the field type module
+   * depends on).
+   *
+   * @var string
+   */
+  public $default_formatter;
+
+  /**
+   * A boolean stating that fields of this type are configurable.
+   *
+   * @var boolean
+   */
+  public $configurable = TRUE;
+
+  /**
+   * A boolean stating that fields of this type cannot be created through the UI.
+   *
+   * @var boolean
+   */
+  public $no_ui = FALSE;
+
+  /**
+   * {@inheritdoc}
+   */
+  public $list_class;
+
+}
diff --git a/core/lib/Drupal/Core/Field/Annotation/FieldWidget.php b/core/lib/Drupal/Core/Field/Annotation/FieldWidget.php
new file mode 100644
index 0000000..982c92e
--- /dev/null
+++ b/core/lib/Drupal/Core/Field/Annotation/FieldWidget.php
@@ -0,0 +1,91 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\field\Annotation\FieldWidget.
+ */
+
+namespace Drupal\Core\Field\Annotation;
+
+use Drupal\Component\Annotation\Plugin;
+
+/**
+ * Defines a FieldWidget annotation object.
+ *
+ * Widgets handle how fields are displayed in edit forms.
+ *
+ * Additional annotation keys for widgets can be defined in
+ * hook_field_widget_info_alter().
+ *
+ * @Annotation
+ *
+ * @see \Drupal\Core\Field\WidgetPluginManager
+ * @see \Drupal\Core\Field\WidgetInterface
+ */
+class FieldWidget extends Plugin {
+
+  /**
+   * The plugin ID.
+   *
+   * @var string
+   */
+  public $id;
+
+  /**
+   * The human-readable name of the widget type.
+   *
+   * @ingroup plugin_translatable
+   *
+   * @var \Drupal\Core\Annotation\Translation
+   */
+  public $label;
+
+  /**
+   * A short description of the widget type.
+   *
+   * @ingroup plugin_translatable
+   *
+   * @var \Drupal\Core\Annotation\Translation
+   */
+  public $description;
+
+  /**
+   * The name of the widget class.
+   *
+   * This is not provided manually, it will be added by the discovery mechanism.
+   *
+   * @var string
+   */
+  public $class;
+
+  /**
+   * An array of field types the widget supports.
+   *
+   * @var array
+   */
+  public $field_types = array();
+
+  /**
+   * An array whose keys are the names of the settings available to the widget
+   * type, and whose values are the default values for those settings.
+   *
+   * @var array
+   */
+  public $settings = array();
+
+  /**
+   * Does the field widget handles multiple values at once.
+   *
+   * @var bool
+   */
+  public $multiple_values = FALSE;
+
+  /**
+   * An integer to determine the weight of this widget relative to other widgets
+   * in the Field UI when selecting a widget for a given field instance.
+   *
+   * @var int optional
+   */
+  public $weight = NULL;
+
+}
diff --git a/core/lib/Drupal/Core/Field/FieldTypePluginManager.php b/core/lib/Drupal/Core/Field/FieldTypePluginManager.php
new file mode 100644
index 0000000..1e0900a
--- /dev/null
+++ b/core/lib/Drupal/Core/Field/FieldTypePluginManager.php
@@ -0,0 +1,110 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Field\FieldTypePluginManager.
+ */
+
+namespace Drupal\Core\Field;
+
+use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Language\LanguageManager;
+use Drupal\Core\Plugin\DefaultPluginManager;
+use Drupal\field\Plugin\Type\FieldType\LegacyFieldTypeDiscoveryDecorator;
+
+/**
+ * Plugin manager for 'field type' plugins.
+ */
+class FieldTypePluginManager extends DefaultPluginManager {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaults = array(
+    'settings' => array(),
+    'instance_settings' => array(),
+  );
+
+  /**
+   * Constructs the FieldTypePluginManager object
+   *
+   * @param \Traversable $namespaces
+   *   An object that implements \Traversable which contains the root paths
+   *   keyed by the corresponding namespace to look for plugin implementations.
+   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
+   *   Cache backend instance to use.
+   * @param \Drupal\Core\Language\LanguageManager $language_manager
+   *   The language manager.
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface
+   *   The module handler.
+   */
+  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler) {
+    parent::__construct('Plugin/field/field_type', $namespaces, 'Drupal\Core\Field\Annotation\FieldType');
+    $this->alterInfo($module_handler, 'field_info');
+    $this->setCacheBackend($cache_backend, $language_manager, 'field_types_plugins');
+
+    // @todo Remove once all core field types have been converted (see
+    // http://drupal.org/node/2014671).
+    $this->discovery = new LegacyFieldTypeDiscoveryDecorator($this->discovery, $module_handler);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function processDefinition(&$definition, $plugin_id) {
+    parent::processDefinition($definition, $plugin_id);
+    if (!isset($definition['list_class'])) {
+      if ($definition['configurable']) {
+        $definition['list_class'] = '\Drupal\field\Plugin\Type\FieldType\ConfigFieldItemList';
+      }
+      else {
+        $definition['list_class'] = '\Drupal\Core\Entity\Field\FieldItemList';
+      }
+    }
+  }
+
+  /**
+   * Returns the default field-level settings for a field type.
+   *
+   * @param string $type
+   *   A field type name.
+   *
+   * @return array
+   *   The type's default settings, as provided by the plugin
+   *   definition, or an empty array if type or settings are undefined.
+   */
+  public function getDefaultSettings($type) {
+    $info = $this->getDefinition($type);
+    return isset($info['settings']) ? $info['settings'] : array();
+  }
+
+  /**
+   * Returns the default instance-level settings for a field type.
+   *
+   * @param string $type
+   *   A field type name.
+   *
+   * @return array
+   *   The instance's default settings, as provided by the plugin
+   *   definition, or an empty array if type or settings are undefined.
+   */
+  public function getDefaultInstanceSettings($type) {
+    $info = $this->getDefinition($type);
+    return isset($info['instance_settings']) ? $info['instance_settings'] : array();
+  }
+
+  /**
+   * Gets the definition of all field types that are configurable.
+   *
+   * @return array
+   *   An array of field type definitions.
+   */
+  public function getConfigurableDefinitions() {
+    $definitions = $this->getDefinitions();
+    return array_filter($definitions, function ($definition) {
+      return $definition['configurable'];
+    });
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Field/FormatterBase.php b/core/lib/Drupal/Core/Field/FormatterBase.php
new file mode 100644
index 0000000..361cd07
--- /dev/null
+++ b/core/lib/Drupal/Core/Field/FormatterBase.php
@@ -0,0 +1,161 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Field\FormatterBase.
+ */
+
+namespace Drupal\Core\Field;
+
+use Drupal\Core\Entity\Field\FieldDefinitionInterface;
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+use Drupal\field\Plugin\PluginSettingsBase;
+
+/**
+ * Base class for 'Field formatter' plugin implementations.
+ */
+abstract class FormatterBase extends PluginSettingsBase implements FormatterInterface {
+
+  /**
+   * The field definition.
+   *
+   * @var \Drupal\Core\Entity\Field\FieldDefinitionInterface
+   */
+  protected $fieldDefinition;
+
+  /**
+   * The formatter settings.
+   *
+   * @var array
+   */
+  protected $settings;
+
+  /**
+   * The label display setting.
+   *
+   * @var string
+   */
+  protected $label;
+
+  /**
+   * The view mode.
+   *
+   * @var string
+   */
+  protected $viewMode;
+
+  /**
+   * Constructs a FormatterBase object.
+   *
+   * @param string $plugin_id
+   *   The plugin_id for the formatter.
+   * @param array $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Entity\Field\FieldDefinitionInterface $field_definition
+   *   The definition of the field to which the formatter is associated.
+   * @param array $settings
+   *   The formatter settings.
+   * @param string $label
+   *   The formatter label display setting.
+   * @param string $view_mode
+   *   The view mode.
+   */
+  public function __construct($plugin_id, array $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode) {
+    parent::__construct(array(), $plugin_id, $plugin_definition);
+
+    $this->fieldDefinition = $field_definition;
+    $this->settings = $settings;
+    $this->label = $label;
+    $this->viewMode = $view_mode;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function view(FieldItemListInterface $items) {
+    $addition = array();
+
+    $elements = $this->viewElements($items);
+    if ($elements) {
+      $entity = $items->getEntity();
+      $entity_type = $entity->entityType();
+      $field_name = $this->fieldDefinition->getFieldName();
+      $info = array(
+        '#theme' => 'field',
+        '#title' => $this->fieldDefinition->getFieldLabel(),
+        '#access' => $items->access('view'),
+        '#label_display' => $this->label,
+        '#view_mode' => $this->viewMode,
+        '#language' => $items->getLangcode(),
+        '#field_name' => $field_name,
+        '#field_type' => $this->fieldDefinition->getFieldType(),
+        '#field_translatable' => $this->fieldDefinition->isFieldTranslatable(),
+        '#entity_type' => $entity_type,
+        '#bundle' => $entity->bundle(),
+        '#object' => $entity,
+        '#items' => $items->getValue(TRUE),
+        '#formatter' => $this->getPluginId(),
+        '#cache' => array('tags' => array())
+      );
+
+      // Gather cache tags from reference fields.
+      foreach ($items as $item) {
+        if (isset($item->format)) {
+          $info['#cache']['tags']['filter_format'] = $item->format;
+        }
+
+        if (isset($item->entity)) {
+          $info['#cache']['tags'][$item->entity->entityType()][] = $item->entity->id();
+          $info['#cache']['tags'][$item->entity->entityType() . '_view'] = TRUE;
+        }
+      }
+
+      $addition[$field_name] = array_merge($info, $elements);
+    }
+
+    return $addition;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    return array();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    return array();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function prepareView(array $entities_items) { }
+
+  /**
+   * Returns the array of field settings.
+   *
+   * @return array
+   *   The array of settings.
+   */
+  protected function getFieldSettings() {
+    return $this->fieldDefinition->getFieldSettings();
+  }
+
+  /**
+   * Returns the value of a field setting.
+   *
+   * @param string $setting_name
+   *   The setting name.
+   *
+   * @return mixed
+   *   The setting value.
+   */
+  protected function getFieldSetting($setting_name) {
+    return $this->fieldDefinition->getFieldSetting($setting_name);
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Field/FormatterInterface.php b/core/lib/Drupal/Core/Field/FormatterInterface.php
new file mode 100644
index 0000000..b28e2e1
--- /dev/null
+++ b/core/lib/Drupal/Core/Field/FormatterInterface.php
@@ -0,0 +1,91 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Field\FormatterInterface.
+ */
+
+namespace Drupal\Core\Field;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+use Drupal\field\Plugin\PluginSettingsInterface;
+
+/**
+ * Interface definition for field widget plugins.
+ */
+interface FormatterInterface extends PluginSettingsInterface {
+
+  /**
+   * Returns a form to configure settings for the formatter.
+   *
+   * Invoked from \Drupal\field_ui\Form\FieldInstanceEditForm to allow
+   * administrators to configure the formatter. The field_ui module takes care
+   * of handling submitted form values.
+   *
+   * @param array $form
+   *   The form where the settings form is being included in.
+   * @param array $form_state
+   *   An associative array containing the current state of the form.
+   *
+   * @return array
+   *   The form elements for the formatter settings.
+   */
+  public function settingsForm(array $form, array &$form_state);
+
+  /**
+   * Returns a short summary for the current formatter settings.
+   *
+   * If an empty result is returned, a UI can still be provided to display
+   * a settings form in case the formatter has configurable settings.
+   *
+   * @return array()
+   *   A short summary of the formatter settings.
+   */
+  public function settingsSummary();
+
+  /**
+   * Allows formatters to load information for field values being displayed.
+   *
+   * This should be used when a formatter needs to load additional information
+   * from the database in order to render a field, for example a reference
+   * field that displays properties of the referenced entities such as name or
+   * type.
+   *
+   * This method operates on multiple entities. The $entities and $items
+   * parameters are arrays keyed by entity ID. For performance reasons,
+   * information for all involved entities should be loaded in a single query
+   * where possible.
+   *
+   * Changes or additions to field values are done by alterings the $items
+   * parameter by reference.
+   *
+   * @param array $entities_items
+   *   Array of field values (Drupal\Core\Entity\Field\FieldItemListInterface),
+   *   keyed by entity ID.
+   */
+  public function prepareView(array $entities_items);
+
+  /**
+   * Builds a renderable array for one field on one entity instance.
+   *
+   * @param \Drupal\Core\Entity\Field\FieldItemListInterface $items
+   *   The field values to be rendered.
+   *
+   * @return array
+   *   A renderable array for a themed field with its label and all its values.
+   */
+  public function view(FieldItemListInterface $items);
+
+  /**
+   * Builds a renderable array for a field value.
+   *
+   * @param \Drupal\Core\Entity\Field\FieldItemListInterface $items
+   *   The field values to be rendered.
+   *
+   * @return array
+   *   A renderable array for $items, as an array of child elements keyed by
+   *   numeric indexes starting from 0.
+   */
+  public function viewElements(FieldItemListInterface $items);
+
+}
diff --git a/core/lib/Drupal/Core/Field/FormatterPluginManager.php b/core/lib/Drupal/Core/Field/FormatterPluginManager.php
new file mode 100644
index 0000000..4a7b16b
--- /dev/null
+++ b/core/lib/Drupal/Core/Field/FormatterPluginManager.php
@@ -0,0 +1,203 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Field\FormatterPluginManager.
+ */
+
+namespace Drupal\Core\Field;
+
+use Drupal\Component\Plugin\Factory\DefaultFactory;
+use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Language\LanguageManager;
+use Drupal\Core\Plugin\DefaultPluginManager;
+
+/**
+ * Plugin type manager for field formatters.
+ */
+class FormatterPluginManager extends DefaultPluginManager {
+
+  /**
+   * An array of formatter options for each field type.
+   *
+   * @var array
+   */
+  protected $formatterOptions;
+
+  /**
+   * The field type manager to define field.
+   *
+   * @var \Drupal\Core\Field\FieldTypePluginManager
+   */
+  protected $fieldTypeManager;
+
+  /**
+   * Constructs a FormatterPluginManager object.
+   *
+   * @param \Traversable $namespaces
+   *   An object that implements \Traversable which contains the root paths
+   *   keyed by the corresponding namespace to look for plugin implementations.
+   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
+   *   Cache backend instance to use.
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler.
+   * @param \Drupal\Core\Language\LanguageManager $language_manager
+   *   The language manager.
+   * @param \Drupal\Core\Field\FieldTypePluginManager $field_type_manager
+   *   The 'field type' plugin manager.
+   */
+  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, LanguageManager $language_manager, FieldTypePluginManager $field_type_manager) {
+
+    parent::__construct('Plugin/Field/FieldFormatter', $namespaces, 'Drupal\Core\Field\Annotation\FieldFormatter');
+
+    $this->setCacheBackend($cache_backend, $language_manager, 'field_formatter_types_plugins');
+    $this->alterInfo($module_handler, 'field_formatter_info');
+    $this->fieldTypeManager = $field_type_manager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function createInstance($plugin_id, array $configuration) {
+    $plugin_definition = $this->getDefinition($plugin_id);
+    $plugin_class = DefaultFactory::getPluginClass($plugin_id, $plugin_definition);
+
+    // @todo This is copied from \Drupal\Core\Plugin\Factory\ContainerFactory.
+    //   Find a way to restore sanity to
+    //   \Drupal\Core\Field\FormatterBase::__construct().
+    // If the plugin provides a factory method, pass the container to it.
+    if (is_subclass_of($plugin_class, 'Drupal\Core\Plugin\ContainerFactoryPluginInterface')) {
+      return $plugin_class::create(\Drupal::getContainer(), $configuration, $plugin_id, $plugin_definition);
+    }
+
+    return new $plugin_class($plugin_id, $plugin_definition, $configuration['field_definition'], $configuration['settings'], $configuration['label'], $configuration['view_mode']);
+  }
+
+  /**
+   * Overrides PluginManagerBase::getInstance().
+   *
+   * @param array $options
+   *   An array with the following key/value pairs:
+   *   - field_definition: (FieldDefinitionInterface) The field definition.
+   *   - view_mode: (string) The view mode.
+   *   - prepare: (bool, optional) Whether default values should get merged in
+   *     the 'configuration' array. Defaults to TRUE.
+   *   - configuration: (array) the configuration for the formatter. The
+   *     following key value pairs are allowed, and are all optional if
+   *     'prepare' is TRUE:
+   *     - label: (string) Position of the label. The default 'field' theme
+   *       implementation supports the values 'inline', 'above' and 'hidden'.
+   *       Defaults to 'above'.
+   *     - type: (string) The formatter to use. Defaults to the
+   *       'default_formatter' for the field type, The default formatter will
+   *       also be used if the requested formatter is not available.
+   *     - settings: (array) Settings specific to the formatter. Each setting
+   *       defaults to the default value specified in the formatter definition.
+   *
+   * @return \Drupal\Core\Field\FormatterInterface
+   *   A formatter object.
+   */
+  public function getInstance(array $options) {
+    $configuration = $options['configuration'];
+    $field_definition = $options['field_definition'];
+    $field_type = $field_definition->getFieldType();
+
+    // Fill in default configuration if needed.
+    if (!isset($options['prepare']) || $options['prepare'] == TRUE) {
+      $configuration = $this->prepareConfiguration($field_type, $configuration);
+    }
+
+    $plugin_id = $configuration['type'];
+
+    // Switch back to default formatter if either:
+    // - $type_info doesn't exist (the widget type is unknown),
+    // - the field type is not allowed for the widget.
+    $definition = $this->getDefinition($configuration['type']);
+    if (!isset($definition['class']) || !in_array($field_type, $definition['field_types'])) {
+      // Grab the default widget for the field type.
+      $field_type_definition = $this->fieldTypeManager->getDefinition($field_type);
+      $plugin_id = $field_type_definition['default_formatter'];
+    }
+
+    $configuration += array(
+      'field_definition' => $field_definition,
+      'view_mode' => $options['view_mode'],
+    );
+    return $this->createInstance($plugin_id, $configuration);
+  }
+
+  /**
+   * Merges default values for formatter configuration.
+   *
+   * @param string $field_type
+   *   The field type.
+   * @param array $properties
+   *   An array of formatter configuration.
+   *
+   * @return array
+   *   The display properties with defaults added.
+   */
+  public function prepareConfiguration($field_type, array $configuration) {
+    // Fill in defaults for missing properties.
+    $configuration += array(
+      'label' => 'above',
+      'settings' => array(),
+    );
+    // If no formatter is specified, use the default formatter.
+    if (!isset($configuration['type'])) {
+      $field_type = $this->fieldTypeManager->getDefinition($field_type);
+      $configuration['type'] = $field_type['default_formatter'];
+    }
+    // Fill in default settings values for the formatter.
+    $configuration['settings'] += $this->getDefaultSettings($configuration['type']);
+
+    return $configuration;
+  }
+
+  /**
+   * Returns an array of formatter options for a field type.
+   *
+   * @param string|null $field_type
+   *   (optional) The name of a field type, or NULL to retrieve all formatters.
+   *
+   * @return array
+   *   If no field type is provided, returns a nested array of all formatters,
+   *   keyed by field type.
+   */
+  public function getOptions($field_type = NULL) {
+    if (!isset($this->formatterOptions)) {
+      $field_types = $this->fieldTypeManager->getDefinitions();
+      $options = array();
+      foreach ($this->getDefinitions() as $name => $formatter) {
+        foreach ($formatter['field_types'] as $formatter_field_type) {
+          // Check that the field type exists.
+          if (isset($field_types[$formatter_field_type])) {
+            $options[$formatter_field_type][$name] = $formatter['label'];
+          }
+        }
+      }
+      $this->formatterOptions = $options;
+    }
+    if ($field_type) {
+      return !empty($this->formatterOptions[$field_type]) ? $this->formatterOptions[$field_type] : array();
+    }
+    return $this->formatterOptions;
+  }
+
+  /**
+   * Returns the default settings of a field formatter.
+   *
+   * @param string $type
+   *   A field formatter type name.
+   *
+   * @return array
+   *   The formatter type's default settings, as provided by the plugin
+   *   definition, or an empty array if type or settings are undefined.
+   */
+  public function getDefaultSettings($type) {
+    $info = $this->getDefinition($type);
+    return isset($info['settings']) ? $info['settings'] : array();
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Field/WidgetBase.php b/core/lib/Drupal/Core/Field/WidgetBase.php
new file mode 100644
index 0000000..c25523d
--- /dev/null
+++ b/core/lib/Drupal/Core/Field/WidgetBase.php
@@ -0,0 +1,450 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Field\WidgetBase.
+ */
+
+namespace Drupal\Core\Field;
+
+use Drupal\Component\Utility\NestedArray;
+use Drupal\Core\Entity\Field\FieldDefinitionInterface;
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+use Drupal\field\Plugin\PluginSettingsBase;
+use Symfony\Component\Validator\ConstraintViolationInterface;
+
+/**
+ * Base class for 'Field widget' plugin implementations.
+ */
+abstract class WidgetBase extends PluginSettingsBase implements WidgetInterface {
+
+  /**
+   * The field definition.
+   *
+   * @var \Drupal\Core\Entity\Field\FieldDefinitionInterface
+   */
+  protected $fieldDefinition;
+
+  /**
+   * The widget settings.
+   *
+   * @var array
+   */
+  protected $settings;
+
+  /**
+   * Constructs a WidgetBase object.
+   *
+   * @param array $plugin_id
+   *   The plugin_id for the widget.
+   * @param array $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Entity\Field\FieldDefinitionInterface $field_definition
+   *   The definition of the field to which the widget is associated.
+   * @param array $settings
+   *   The widget settings.
+   */
+  public function __construct($plugin_id, array $plugin_definition, FieldDefinitionInterface $field_definition, array $settings) {
+    parent::__construct(array(), $plugin_id, $plugin_definition);
+    $this->fieldDefinition = $field_definition;
+    $this->settings = $settings;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function form(FieldItemListInterface $items, array &$form, array &$form_state, $get_delta = NULL) {
+    $field_name = $this->fieldDefinition->getFieldName();
+    $parents = $form['#parents'];
+
+    // Store field information in $form_state.
+    if (!field_form_get_state($parents, $field_name, $form_state)) {
+      $field_state = array(
+        'items_count' => count($items),
+        'array_parents' => array(),
+        'constraint_violations' => array(),
+      );
+      field_form_set_state($parents, $field_name, $form_state, $field_state);
+    }
+
+    // Collect widget elements.
+    $elements = array();
+
+    // If the widget is handling multiple values (e.g Options), or if we are
+    // displaying an individual element, just get a single form element and make
+    // it the $delta value.
+    $definition = $this->getPluginDefinition();
+    if (isset($get_delta) || $definition['multiple_values']) {
+      $delta = isset($get_delta) ? $get_delta : 0;
+      $element = array(
+        '#title' => check_plain($this->fieldDefinition->getFieldLabel()),
+        '#description' => field_filter_xss(\Drupal::token()->replace($this->fieldDefinition->getFieldDescription())),
+      );
+      $element = $this->formSingleElement($items, $delta, $element, $form, $form_state);
+
+      if ($element) {
+        if (isset($get_delta)) {
+          // If we are processing a specific delta value for a field where the
+          // field module handles multiples, set the delta in the result.
+          $elements[$delta] = $element;
+        }
+        else {
+          // For fields that handle their own processing, we cannot make
+          // assumptions about how the field is structured, just merge in the
+          // returned element.
+          $elements = $element;
+        }
+      }
+    }
+    // If the widget does not handle multiple values itself, (and we are not
+    // displaying an individual element), process the multiple value form.
+    else {
+      $elements = $this->formMultipleElements($items, $form, $form_state);
+    }
+
+    // Populate the 'array_parents' information in $form_state['field'] after
+    // the form is built, so that we catch changes in the form structure performed
+    // in alter() hooks.
+    $elements['#after_build'][] = 'field_form_element_after_build';
+    $elements['#field_name'] = $field_name;
+    $elements['#field_parents'] = $parents;
+    // Enforce the structure of submitted values.
+    $elements['#parents'] = array_merge($parents, array($field_name));
+    // Most widgets need their internal structure preserved in submitted values.
+    $elements += array('#tree' => TRUE);
+
+    $return = array(
+      $field_name => array(
+        // Aid in theming of widgets by rendering a classified container.
+        '#type' => 'container',
+        // Assign a different parent, to keep the main id for the widget itself.
+        '#parents' => array_merge($parents, array($field_name . '_wrapper')),
+        '#attributes' => array(
+          'class' => array(
+            'field-type-' . drupal_html_class($this->fieldDefinition->getFieldType()),
+            'field-name-' . drupal_html_class($field_name),
+            'field-widget-' . drupal_html_class($this->getPluginId()),
+          ),
+        ),
+        '#access' => $items->access('edit'),
+        'widget' => $elements,
+      ),
+    );
+
+    return $return;
+  }
+
+  /**
+   * Special handling to create form elements for multiple values.
+   *
+   * Handles generic features for multiple fields:
+   * - number of widgets
+   * - AHAH-'add more' button
+   * - table display and drag-n-drop value reordering
+   */
+  protected function formMultipleElements(FieldItemListInterface $items, array &$form, array &$form_state) {
+    $field_name = $this->fieldDefinition->getFieldName();
+    $cardinality = $this->fieldDefinition->getFieldCardinality();
+    $parents = $form['#parents'];
+
+    // Determine the number of widgets to display.
+    switch ($cardinality) {
+      case FIELD_CARDINALITY_UNLIMITED:
+        $field_state = field_form_get_state($parents, $field_name, $form_state);
+        $max = $field_state['items_count'];
+        $is_multiple = TRUE;
+        break;
+
+      default:
+        $max = $cardinality - 1;
+        $is_multiple = ($cardinality > 1);
+        break;
+    }
+
+    $id_prefix = implode('-', array_merge($parents, array($field_name)));
+    $wrapper_id = drupal_html_id($id_prefix . '-add-more-wrapper');
+
+    $title = check_plain($this->fieldDefinition->getFieldLabel());
+    $description = field_filter_xss(\Drupal::token()->replace($this->fieldDefinition->getFieldDescription()));
+
+    $elements = array();
+
+    for ($delta = 0; $delta <= $max; $delta++) {
+      // For multiple fields, title and description are handled by the wrapping
+      // table.
+      $element = array(
+        '#title' => $is_multiple ? '' : $title,
+        '#description' => $is_multiple ? '' : $description,
+      );
+      $element = $this->formSingleElement($items, $delta, $element, $form, $form_state);
+
+      if ($element) {
+        // Input field for the delta (drag-n-drop reordering).
+        if ($is_multiple) {
+          // We name the element '_weight' to avoid clashing with elements
+          // defined by widget.
+          $element['_weight'] = array(
+            '#type' => 'weight',
+            '#title' => t('Weight for row @number', array('@number' => $delta + 1)),
+            '#title_display' => 'invisible',
+            // Note: this 'delta' is the FAPI #type 'weight' element's property.
+            '#delta' => $max,
+            '#default_value' => $items[$delta]->_weight ?: $delta,
+            '#weight' => 100,
+          );
+        }
+
+        $elements[$delta] = $element;
+      }
+    }
+
+    if ($elements) {
+      $elements += array(
+        '#theme' => 'field_multiple_value_form',
+        '#field_name' => $field_name,
+        '#cardinality' => $cardinality,
+        '#required' => $this->fieldDefinition->isFieldRequired(),
+        '#title' => $title,
+        '#description' => $description,
+        '#prefix' => '<div id="' . $wrapper_id . '">',
+        '#suffix' => '</div>',
+        '#max_delta' => $max,
+      );
+
+      // Add 'add more' button, if not working with a programmed form.
+      if ($cardinality == FIELD_CARDINALITY_UNLIMITED && empty($form_state['programmed'])) {
+        $elements['add_more'] = array(
+          '#type' => 'submit',
+          '#name' => strtr($id_prefix, '-', '_') . '_add_more',
+          '#value' => t('Add another item'),
+          '#attributes' => array('class' => array('field-add-more-submit')),
+          '#limit_validation_errors' => array(array_merge($parents, array($field_name))),
+          '#submit' => array('field_add_more_submit'),
+          '#ajax' => array(
+              'callback' => 'field_add_more_js',
+              'wrapper' => $wrapper_id,
+              'effect' => 'fade',
+          ),
+        );
+      }
+    }
+
+    return $elements;
+  }
+
+  /**
+   * Generates the form element for a single copy of the widget.
+   */
+  protected function formSingleElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
+    $entity = $items->getEntity();
+
+    $element += array(
+      '#entity_type' => $entity->entityType(),
+      '#bundle' => $entity->bundle(),
+      '#entity' => $entity,
+      '#field_name' => $this->fieldDefinition->getFieldName(),
+      '#language' => $items->getLangcode(),
+      '#field_parents' => $form['#parents'],
+      // Only the first widget should be required.
+      '#required' => $delta == 0 && $this->fieldDefinition->isFieldRequired(),
+      '#delta' => $delta,
+      '#weight' => $delta,
+    );
+
+    $element = $this->formElement($items, $delta, $element, $form, $form_state);
+
+    if ($element) {
+      // Allow modules to alter the field widget form element.
+      $context = array(
+        'form' => $form,
+        'widget' => $this,
+        'items' => $items,
+        'delta' => $delta,
+        'default' => !empty($entity->field_ui_default_value),
+      );
+      drupal_alter(array('field_widget_form', 'field_widget_' . $this->getPluginId() . '_form'), $element, $form_state, $context);
+    }
+
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function extractFormValues(FieldItemListInterface $items, array $form, array &$form_state) {
+    $field_name = $this->fieldDefinition->getFieldName();
+
+    // Extract the values from $form_state['values'].
+    $path = array_merge($form['#parents'], array($field_name));
+    $key_exists = NULL;
+    $values = NestedArray::getValue($form_state['values'], $path, $key_exists);
+
+    if ($key_exists) {
+      // Remove the 'value' of the 'add more' button.
+      unset($values['add_more']);
+
+      // Let the widget turn the submitted values into actual field values.
+      // Make sure the '_weight' entries are persisted in the process.
+      $weights = array();
+      // Check that $values[0] is an array, because if it's a string, then in
+      // PHP 5.3, ['_weight'] returns the first character.
+      if (isset($values[0]) && is_array($values[0]) && isset($values[0]['_weight'])) {
+        foreach ($values as $delta => $value) {
+          $weights[$delta] = $value['_weight'];
+        }
+      }
+      $items->setValue($this->massageFormValues($values, $form, $form_state));
+
+      foreach ($items as $delta => $item) {
+        // Put back the weight.
+        if (isset($weights[$delta])) {
+          $item->_weight = $weights[$delta];
+        }
+        // The tasks below are going to reshuffle deltas. Keep track of the
+        // original deltas for correct reporting of errors in flagErrors().
+        $item->_original_delta = $delta;
+      }
+
+      // Account for drag-n-drop reordering.
+      $this->sortItems($items);
+
+      // Remove empty values.
+      $items->filterEmptyValues();
+
+      // Put delta mapping in $form_state, so that flagErrors() can use it.
+      $field_state = field_form_get_state($form['#parents'], $field_name, $form_state);
+      foreach ($items as $delta => $item) {
+        $field_state['original_deltas'][$delta] = $item->_original_delta;
+        unset($item->_original_delta);
+      }
+      field_form_set_state($form['#parents'], $field_name, $form_state, $field_state);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function flagErrors(FieldItemListInterface $items, array $form, array &$form_state) {
+    $field_name = $this->fieldDefinition->getFieldName();
+
+    $field_state = field_form_get_state($form['#parents'], $field_name, $form_state);
+
+    if (!empty($field_state['constraint_violations'])) {
+      // Locate the correct element in the the form.
+      $element = NestedArray::getValue($form_state['complete_form'], $field_state['array_parents']);
+
+      // Only set errors if the element is accessible.
+      if (!isset($element['#access']) || $element['#access']) {
+        $definition = $this->getPluginDefinition();
+        $is_multiple = $definition['multiple_values'];
+
+        $violations_by_delta = array();
+        foreach ($field_state['constraint_violations'] as $violation) {
+          // Separate violations by delta.
+          $property_path = explode('.', $violation->getPropertyPath());
+          $delta = array_shift($property_path);
+          $violation->arrayPropertyPath = $property_path;
+          $violations_by_delta[$delta][] = $violation;
+        }
+
+        foreach ($violations_by_delta as $delta => $delta_violations) {
+          // For a multiple-value widget, pass all errors to the main widget.
+          // For single-value widgets, pass errors by delta.
+          if ($is_multiple) {
+            $delta_element = $element;
+          }
+          else {
+            $original_delta = $field_state['original_deltas'][$delta];
+            $delta_element = $element[$original_delta];
+          }
+          foreach ($delta_violations as $violation) {
+            // @todo: Pass $violation->arrayPropertyPath as property path.
+            $error_element = $this->errorElement($delta_element, $violation, $form, $form_state);
+            if ($error_element !== FALSE) {
+              form_error($error_element, $violation->getMessage());
+            }
+          }
+        }
+        // Reinitialize the errors list for the next submit.
+        $field_state['constraint_violations'] = array();
+        field_form_set_state($form['#parents'], $field_name, $form_state, $field_state);
+      }
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    return array();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    return array();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function errorElement(array $element, ConstraintViolationInterface $error, array $form, array &$form_state) {
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function massageFormValues(array $values, array $form, array &$form_state) {
+    return $values;
+  }
+
+  /**
+   * Sorts submitted field values according to drag-n-drop reordering.
+   *
+   * @param \Drupal\Core\Entity\Field\FieldItemListInterface $items
+   *   The field values.
+   */
+  protected function sortItems(FieldItemListInterface $items) {
+    $cardinality = $this->fieldDefinition->getFieldCardinality();
+    $is_multiple = ($cardinality == FIELD_CARDINALITY_UNLIMITED) || ($cardinality > 1);
+    if ($is_multiple && isset($items[0]->_weight)) {
+      $itemValues = $items->getValue(TRUE);
+      usort($itemValues, function ($a, $b) {
+        $a_weight = (is_array($a) ? $a['_weight'] : 0);
+        $b_weight = (is_array($b) ? $b['_weight'] : 0);
+        return $a_weight - $b_weight;
+      });
+      $items->setValue($itemValues);
+      // Remove the '_weight' entries.
+      foreach ($items as $item) {
+        unset($item->_weight);
+      }
+    }
+  }
+
+  /**
+   * Returns the array of field settings.
+   *
+   * @return array
+   *   The array of settings.
+   */
+  protected function getFieldSettings() {
+    return $this->fieldDefinition->getFieldSettings();
+  }
+
+  /**
+   * Returns the value of a field setting.
+   *
+   * @param string $setting_name
+   *   The setting name.
+   *
+   * @return mixed
+   *   The setting value.
+   */
+  protected function getFieldSetting($setting_name) {
+    return $this->fieldDefinition->getFieldSetting($setting_name);
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Field/WidgetBaseInterface.php b/core/lib/Drupal/Core/Field/WidgetBaseInterface.php
new file mode 100644
index 0000000..3baf452
--- /dev/null
+++ b/core/lib/Drupal/Core/Field/WidgetBaseInterface.php
@@ -0,0 +1,73 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Field\WidgetBaseInterface.
+ */
+
+namespace Drupal\Core\Field;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+use Drupal\field\Plugin\PluginSettingsInterface;
+
+/**
+ * Base interface definition for "Field widget" plugins.
+ *
+ * This interface details base wrapping methods that most widget implementations
+ * will want to directly inherit from Drupal\Core\Field\WidgetBase.
+ * See Drupal\Core\Field\WidgetInterface for methods that will more
+ * likely be overriden.
+ */
+interface WidgetBaseInterface extends PluginSettingsInterface {
+
+  /**
+   * Creates a form element for a field.
+   *
+   * If the entity associated with the form is new (i.e., $entity->isNew() is
+   * TRUE), the 'default value', if any, is pre-populated. Also allows other
+   * modules to alter the form element by implementing their own hooks.
+   *
+   * @param \Drupal\Core\Entity\Field\FieldItemListInterface $items
+   *   An array of the field values. When creating a new entity this may be NULL
+   *   or an empty array to use default values.
+   * @param array $form
+   *   An array representing the form that the editing element will be attached
+   *   to.
+   * @param array $form_state
+   *   An array containing the current state of the form.
+   * @param int $get_delta
+   *   Used to get only a specific delta value of a multiple value field.
+   *
+   * @return array
+   *   The form element array created for this field.
+   */
+  public function form(FieldItemListInterface $items, array &$form, array &$form_state, $get_delta = NULL);
+
+  /**
+   * Extracts field values from submitted form values.
+   *
+   * @param \Drupal\Core\Entity\Field\FieldItemListInterface $items
+   *   The field values. This parameter is altered by reference to receive the
+   *   incoming form values.
+   * @param array $form
+   *   The form structure where field elements are attached to. This might be a
+   *   full form structure, or a sub-element of a larger form.
+   * @param array $form_state
+   *   The form state.
+   */
+  public function extractFormValues(FieldItemListInterface $items, array $form, array &$form_state);
+
+  /**
+   * Reports field-level validation errors against actual form elements.
+   *
+   * @param \Drupal\Core\Entity\Field\FieldItemListInterface $items
+   *   The field values.
+   * @param array $form
+   *   The form structure where field elements are attached to. This might be a
+   *   full form structure, or a sub-element of a larger form.
+   * @param array $form_state
+   *   The form state.
+   */
+  public function flagErrors(FieldItemListInterface $items, array $form, array &$form_state);
+
+}
diff --git a/core/lib/Drupal/Core/Field/WidgetFactory.php b/core/lib/Drupal/Core/Field/WidgetFactory.php
new file mode 100644
index 0000000..49a252a
--- /dev/null
+++ b/core/lib/Drupal/Core/Field/WidgetFactory.php
@@ -0,0 +1,25 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Field\WidgetFactory.
+ */
+
+namespace Drupal\Core\Field;
+
+use Drupal\Component\Plugin\Factory\DefaultFactory;
+
+/**
+ * Factory class for the Widget plugin type.
+ */
+class WidgetFactory extends DefaultFactory {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function createInstance($plugin_id, array $configuration) {
+    $plugin_definition = $this->discovery->getDefinition($plugin_id);
+    $plugin_class = static::getPluginClass($plugin_id, $plugin_definition);
+    return new $plugin_class($plugin_id, $plugin_definition, $configuration['field_definition'], $configuration['settings']);
+  }
+}
diff --git a/core/lib/Drupal/Core/Field/WidgetInterface.php b/core/lib/Drupal/Core/Field/WidgetInterface.php
new file mode 100644
index 0000000..da17c9a
--- /dev/null
+++ b/core/lib/Drupal/Core/Field/WidgetInterface.php
@@ -0,0 +1,160 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Field\WidgetInterface.
+ */
+
+namespace Drupal\Core\Field;
+
+use Drupal\Core\Field\WidgetBaseInterface;
+use Symfony\Component\Validator\ConstraintViolationInterface;
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+
+/**
+ * Interface definition for field widget plugins.
+ *
+ * This interface details the methods that most plugin implementations will want
+ * to override. See Drupal\Core\Field\WidgetBaseInterface for base
+ * wrapping methods that should most likely be inherited directly from
+ * Drupal\Core\Field\WidgetBase..
+ */
+interface WidgetInterface extends WidgetBaseInterface {
+
+  /**
+   * Returns a form to configure settings for the widget.
+   *
+   * Invoked from \Drupal\field_ui\Form\FieldInstanceEditForm to allow
+   * administrators to configure the widget. The field_ui module takes care of
+   * handling submitted form values.
+   *
+   * @param array $form
+   *   The form where the settings form is being included in.
+   * @param array $form_state
+   *   An associative array containing the current state of the form.
+   *
+   * @return array
+   *   The form definition for the widget settings.
+   */
+  public function settingsForm(array $form, array &$form_state);
+
+  /**
+   * Returns a short summary for the current widget settings.
+   *
+   * If an empty result is returned, a UI can still be provided to display
+   * a settings form in case the widget has configurable settings.
+   *
+   * @return array
+   *   A short summary of the widget settings.
+   */
+  public function settingsSummary();
+
+  /**
+   * Returns the form for a single field widget.
+   *
+   * Field widget form elements should be based on the passed-in $element, which
+   * contains the base form element properties derived from the field
+   * configuration.
+   *
+   * The BaseWidget methods will set the weight, field name and delta values for
+   * each form element. If there are multiple values for this field, the
+   * formElement() method will be called as many times as needed.
+   *
+   * Other modules may alter the form element provided by this function using
+   * hook_field_widget_form_alter() or
+   * hook_field_widget_WIDGET_TYPE_form_alter().
+   *
+   * The FAPI element callbacks (such as #process, #element_validate,
+   * #value_callback...) used by the widget do not have access to the original
+   * $field_definition passed to the widget's constructor. Therefore, if any
+   * information is needed from that definition by those callbacks, the widget
+   * implementing this method, or a hook_field_widget[_WIDGET_TYPE]_form_alter()
+   * implementation, must extract the needed properties from the field
+   * definition and set them as ad-hoc $element['#custom'] properties, for later
+   * use by its element callbacks.
+   *
+   * @param \Drupal\Core\Entity\Field\FieldItemListInterface $items
+   *   Array of default values for this field.
+   * @param int $delta
+   *   The order of this item in the array of subelements (0, 1, 2, etc).
+   * @param array $element
+   *   A form element array containing basic properties for the widget:
+   *   - #entity_type: The name of the entity the field is attached to.
+   *   - #bundle: The name of the field bundle the field is contained in.
+   *   - #entity: The entity the field is attached to.
+   *   - #field_name: The name of the field.
+   *   - #language: The language the field is being edited in.
+   *   - #field_parents: The 'parents' space for the field in the form. Most
+   *       widgets can simply overlook this property. This identifies the
+   *       location where the field values are placed within
+   *       $form_state['values'], and is used to access processing information
+   *       for the field through the field_form_get_state() and
+   *       field_form_set_state() functions.
+   *   - #title: The sanitized element label for the field instance, ready for
+   *     output.
+   *   - #description: The sanitized element description for the field instance,
+   *     ready for output.
+   *   - #required: A Boolean indicating whether the element value is required;
+   *     for required multiple value fields, only the first widget's values are
+   *     required.
+   *   - #delta: The order of this item in the array of subelements; see $delta
+   *     above.
+   * @param string $form
+   *   The form structure where widgets are being attached to. This might be a
+   *   full form structure, or a sub-element of a larger form.
+   * @param string $form_state
+   *   An associative array containing the current state of the form.
+   *
+   * @return array
+   *   The form elements for a single widget for this field.
+   *
+   * @see hook_field_widget_form_alter()
+   * @see hook_field_widget_WIDGET_TYPE_form_alter()
+   */
+  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state);
+
+  /**
+   * Assigns a field-level validation error to the right widget sub-element.
+   *
+   * Depending on the widget's internal structure, a field-level validation
+   * error needs to be flagged on the right sub-element.
+   *
+   * @param array $element
+   *   An array containing the form element for the widget, as generated by
+   *   formElement().
+   * @param \Symfony\Component\Validator\ConstraintViolationInterface $violation
+   *   A constraint violation reported during the validation phase.
+   * @param array $form
+   *   The form structure where field elements are attached to. This might be a
+   *   full form structure, or a sub-element of a larger form.
+   * @param array $form_state
+   *   An associative array containing the current state of the form.
+   *
+   * @return array|bool
+   *   The element on which the error should be flagged, or FALSE to completely
+   *   ignore the violation (use with care!).
+   */
+  public function errorElement(array $element, ConstraintViolationInterface $violation, array $form, array &$form_state);
+
+  /**
+   * Massages the form values into the format expected for field values.
+   *
+   * @param array $values
+   *   The submitted form values produced by the widget.
+   *   - If the widget does not manage multiple values itself, the array holds
+   *     the values generated by the multiple copies of the $element generated
+   *     by the formElement() method, keyed by delta.
+   *   - If the widget manages multiple values, the array holds the values
+   *     of the form element generated by the formElement() method.
+   * @param array $form
+   *   The form structure where field elements are attached to. This might be a
+   *   full form structure, or a sub-element of a larger form.
+   * @param array $form_state
+   *   The form state.
+   *
+   * @return array
+   *   An array of field values, keyed by delta.
+   */
+  public function massageFormValues(array $values, array $form, array &$form_state);
+
+}
diff --git a/core/lib/Drupal/Core/Field/WidgetPluginManager.php b/core/lib/Drupal/Core/Field/WidgetPluginManager.php
new file mode 100644
index 0000000..d670073
--- /dev/null
+++ b/core/lib/Drupal/Core/Field/WidgetPluginManager.php
@@ -0,0 +1,207 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Field\WidgetPluginManager.
+ */
+
+namespace Drupal\Core\Field;
+
+use Drupal\Component\Plugin\Factory\DefaultFactory;
+use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Language\LanguageManager;
+use Drupal\Core\Plugin\DefaultPluginManager;
+
+/**
+ * Plugin type manager for field widgets.
+ */
+class WidgetPluginManager extends DefaultPluginManager {
+
+  /**
+   * The field type manager to define field.
+   *
+   * @var \Drupal\Core\Field\FieldTypePluginManager
+   */
+  protected $fieldTypeManager;
+
+  /**
+   * An array of widget options for each field type.
+   *
+   * @var array
+   */
+  protected $widgetOptions;
+
+  /**
+   * Constructs a WidgetPluginManager object.
+   *
+   * @param \Traversable $namespaces
+   *   An object that implements \Traversable which contains the root paths
+   *   keyed by the corresponding namespace to look for plugin implementations.
+   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
+   *   Cache backend instance to use.
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler.
+   * @param \Drupal\Core\Language\LanguageManager $language_manager
+   *   The language manager.
+   * @param \Drupal\Core\Field\FieldTypePluginManager $field_type_manager
+   *   The 'field type' plugin manager.
+   */
+  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, LanguageManager $language_manager, FieldTypePluginManager $field_type_manager) {
+    parent::__construct('Plugin/Field/FieldWidget', $namespaces, 'Drupal\Core\Field\Annotation\FieldWidget');
+
+    $this->setCacheBackend($cache_backend, $language_manager, 'field_widget_types_plugins');
+    $this->alterInfo($module_handler, 'field_widget_info');
+
+    $this->factory = new WidgetFactory($this);
+    $this->fieldTypeManager = $field_type_manager;
+  }
+
+  /**
+   * Overrides PluginManagerBase::getInstance().
+   *
+   * @param array $options
+   *   An array with the following key/value pairs:
+   *   - field_definition: (FieldDefinitionInterface) The field definition.
+   *   - form_mode: (string) The form mode.
+   *   - prepare: (bool, optional) Whether default values should get merged in
+   *     the 'configuration' array. Defaults to TRUE.
+   *   - configuration: (array) the configuration for the widget. The
+   *     following key value pairs are allowed, and are all optional if
+   *     'prepare' is TRUE:
+   *     - type: (string) The widget to use. Defaults to the
+   *       'default_widget' for the field type. The default widget will also be
+   *       used if the requested widget is not available.
+   *     - settings: (array) Settings specific to the widget. Each setting
+   *       defaults to the default value specified in the widget definition.
+   *
+   * @return \Drupal\Core\Field\WidgetInterface
+   *   A Widget object.
+   */
+  public function getInstance(array $options) {
+    // Fill in defaults for missing properties.
+    $options += array(
+      'configuration' => array(),
+      'prepare' => TRUE,
+    );
+
+    $configuration = $options['configuration'];
+    $field_definition = $options['field_definition'];
+    $field_type = $field_definition->getFieldType();
+
+    // Fill in default configuration if needed.
+    if ($options['prepare']) {
+      $configuration = $this->prepareConfiguration($field_type, $configuration);
+    }
+
+    $plugin_id = $configuration['type'];
+
+    // Switch back to default widget if either:
+    // - $type_info doesn't exist (the widget type is unknown),
+    // - the field type is not allowed for the widget.
+    $definition = $this->getDefinition($configuration['type']);
+    if (!isset($definition['class']) || !in_array($field_type, $definition['field_types'])) {
+      // Grab the default widget for the field type.
+      $field_type_definition = $this->fieldTypeManager->getDefinition($field_type);
+      $plugin_id = $field_type_definition['default_widget'];
+    }
+
+    $configuration += array(
+      'field_definition' => $field_definition,
+    );
+    return $this->createInstance($plugin_id, $configuration);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function createInstance($plugin_id, array $configuration = array()) {
+    $plugin_definition = $this->getDefinition($plugin_id);
+    $plugin_class = DefaultFactory::getPluginClass($plugin_id, $plugin_definition);
+
+    // If the plugin provides a factory method, pass the container to it.
+    if (is_subclass_of($plugin_class, 'Drupal\Core\Plugin\ContainerFactoryPluginInterface')) {
+      return $plugin_class::create(\Drupal::getContainer(), $configuration, $plugin_id, $plugin_definition);
+    }
+
+    return new $plugin_class($plugin_id, $plugin_definition, $configuration['field_definition'], $configuration['settings']);
+  }
+
+
+  /**
+   * Merges default values for widget configuration.
+   *
+   * @param string $field_type
+   *   The field type.
+   * @param array $configuration
+   *   An array of widget configuration.
+   *
+   * @return array
+   *   The display properties with defaults added.
+   */
+  public function prepareConfiguration($field_type, array $configuration) {
+    // Fill in defaults for missing properties.
+    $configuration += array(
+      'settings' => array(),
+    );
+    // If no widget is specified, use the default widget.
+    if (!isset($configuration['type'])) {
+      $field_type = $this->fieldTypeManager->getDefinition($field_type);
+      $configuration['type'] = $field_type['default_widget'];
+    }
+    // Fill in default settings values for the widget.
+    $configuration['settings'] += $this->getDefaultSettings($configuration['type']);
+
+    return $configuration;
+  }
+
+  /**
+   * Returns an array of widget type options for a field type.
+   *
+   * @param string|null $field_type
+   *   (optional) The name of a field type, or NULL to retrieve all widget
+   *   options. Defaults to NULL.
+   *
+   * @return array
+   *   If no field type is provided, returns a nested array of all widget types,
+   *   keyed by field type human name.
+   */
+  public function getOptions($field_type = NULL) {
+    if (!isset($this->widgetOptions)) {
+      $options = array();
+      $field_types = $this->fieldTypeManager->getDefinitions();
+      $widget_types = $this->getDefinitions();
+      uasort($widget_types, 'drupal_sort_weight');
+      foreach ($widget_types as $name => $widget_type) {
+        foreach ($widget_type['field_types'] as $widget_field_type) {
+          // Check that the field type exists.
+          if (isset($field_types[$widget_field_type])) {
+            $options[$widget_field_type][$name] = $widget_type['label'];
+          }
+        }
+      }
+      $this->widgetOptions = $options;
+    }
+    if (isset($field_type)) {
+      return !empty($this->widgetOptions[$field_type]) ? $this->widgetOptions[$field_type] : array();
+    }
+
+    return $this->widgetOptions;
+  }
+
+  /**
+   * Returns the default settings of a field widget.
+   *
+   * @param string $type
+   *   A field widget type name.
+   *
+   * @return array
+   *   The widget type's default settings, as provided by the plugin
+   *   definition, or an empty array if type or settings are undefined.
+   */
+  public function getDefaultSettings($type) {
+    $info = $this->getDefinition($type);
+    return isset($info['settings']) ? $info['settings'] : array();
+  }
+
+}
diff --git a/core/lib/Drupal/Core/TypedData/AllowedValuesInterface.php b/core/lib/Drupal/Core/TypedData/AllowedValuesInterface.php
index bc58989..9abe52d 100644
--- a/core/lib/Drupal/Core/TypedData/AllowedValuesInterface.php
+++ b/core/lib/Drupal/Core/TypedData/AllowedValuesInterface.php
@@ -24,7 +24,7 @@
  * as structured options arrays that can be used in an Options widget such as a
  * select box or checkboxes.
  *
- * @see \Drupal\options\Plugin\field\widget\OptionsWidgetBase
+ * @see \Drupal\options\Plugin\Field\FieldWidget\OptionsWidgetBase
  */
 interface AllowedValuesInterface {
 
diff --git a/core/modules/comment/lib/Drupal/comment/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php b/core/modules/comment/lib/Drupal/comment/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php
new file mode 100644
index 0000000..18ec31e
--- /dev/null
+++ b/core/modules/comment/lib/Drupal/comment/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php
@@ -0,0 +1,157 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\comment\Plugin\Field\FieldFormatter\CommentDefaultFormatter.
+ */
+
+namespace Drupal\comment\Plugin\Field\FieldFormatter;
+
+use Drupal\comment\CommentStorageControllerInterface;
+use Drupal\Core\Entity\EntityRenderControllerInterface;
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\Core\Entity\Field\FieldDefinitionInterface;
+use Drupal\Core\Field\FormatterBase;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Provides a default comment formatter.
+ *
+ * @FieldFormatter(
+ *   id = "comment_default",
+ *   module = "comment",
+ *   label = @Translation("Comment list"),
+ *   field_types = {
+ *     "comment"
+ *   }
+ * )
+ */
+class CommentDefaultFormatter extends FormatterBase implements ContainerFactoryPluginInterface {
+
+  /**
+   * The comment storage controller.
+   *
+   * @var \Drupal\comment\CommentStorageControllerInterface
+   */
+  protected $storageController;
+
+  /**
+   * The current user.
+   *
+   * @var \Drupal\Core\Session\AccountInterface
+   */
+  protected $currentUser;
+
+  /**
+   * The comment render controller.
+   *
+   * @var \Drupal\Core\Entity\EntityRenderControllerInterface
+   */
+  protected $renderController;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, array $plugin_definition) {
+    return new static(
+      $plugin_id,
+      $plugin_definition,
+      $configuration['field_definition'],
+      $configuration['settings'],
+      $configuration['label'],
+      $configuration['view_mode'],
+      $container->get('current_user'),
+      $container->get('entity.manager')->getStorageController('comment'),
+      $container->get('entity.manager')->getRenderController('comment')
+    );
+  }
+
+  /**
+   * Constructs a new CommentDefaultFormatter.
+   *
+   * @param string $plugin_id
+   *   The plugin_id for the formatter.
+   * @param array $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Entity\Field\FieldDefinitionInterface $field_definition
+   *   The definition of the field to which the formatter is associated.
+   * @param array $settings
+   *   The formatter settings.
+   * @param string $label
+   *   The formatter label display setting.
+   * @param string $view_mode
+   *   The view mode.
+   * @param \Drupal\Core\Session\AccountInterface $current_user
+   *   The current user.
+   * @param \Drupal\comment\CommentStorageControllerInterface
+   *   The comment storage controller.
+   * @param \Drupal\Core\Entity\EntityRenderControllerInterface
+   *   The comment render controller.
+   */
+  public function __construct($plugin_id, array $plugin_definition,  FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, AccountInterface $current_user, CommentStorageControllerInterface $comment_storage_controller, EntityRenderControllerInterface $comment_render_controller) {
+    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode);
+    $this->renderController = $comment_render_controller;
+    $this->storageController = $comment_storage_controller;
+    $this->currentUser = $current_user;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+    $elements = array();
+    $output = array();
+
+    $field_name = $this->fieldDefinition->getFieldName();
+    $entity = $items->getEntity();
+
+    $status = $items->status;
+
+    if ($status != COMMENT_HIDDEN && empty($entity->in_preview) &&
+      // Comments are added to the search results and search index by
+      // comment_node_update_index() instead of by this formatter, so don't
+      // return anything if the view mode is search_index or search_result.
+      !in_array($this->viewMode, array('search_result', 'search_index'))) {
+      $comment_settings = $this->getFieldSettings();
+
+      // Only attempt to render comments if the entity has visible comments.
+      // Unpublished comments are not included in
+      // $entity->get($field_name)->comment_count, but unpublished comments
+      // should display if the user is an administrator.
+      if ((($entity->get($field_name)->comment_count && $this->currentUser->hasPermission('access comments')) ||
+        $this->currentUser->hasPermission('administer comments'))) {
+        $mode = $comment_settings['default_mode'];
+        $comments_per_page = $comment_settings['per_page'];
+        if ($cids = comment_get_thread($entity, $field_name, $mode, $comments_per_page)) {
+          $comments = $this->storageController->loadMultiple($cids);
+          comment_prepare_thread($comments);
+          $build = $this->renderController->viewMultiple($comments);
+          $build['pager']['#theme'] = 'pager';
+          $output['comments'] = $build;
+        }
+      }
+
+      // Append comment form if the comments are open and the form is set to
+      // display below the entity.
+      if ($status == COMMENT_OPEN && $comment_settings['form_location'] == COMMENT_FORM_BELOW) {
+        // Only show the add comment form if the user has permission.
+        if ($this->currentUser->hasPermission('post comments')) {
+          $output['comment_form'] = comment_add($entity, $field_name);
+        }
+      }
+
+      $elements[] = $output + array(
+        '#theme' => 'comment_wrapper__' . $entity->entityType() . '__' . $entity->bundle() . '__' . $field_name,
+        '#entity' => $entity,
+        '#display_mode' => $this->getFieldSetting('default_mode'),
+        'comments' => array(),
+        'comment_form' => array(),
+      );
+    }
+
+    return $elements;
+  }
+
+}
diff --git a/core/modules/comment/lib/Drupal/comment/Plugin/Field/FieldWidget/CommentWidget.php b/core/modules/comment/lib/Drupal/comment/Plugin/Field/FieldWidget/CommentWidget.php
new file mode 100644
index 0000000..1d6fd8b
--- /dev/null
+++ b/core/modules/comment/lib/Drupal/comment/Plugin/Field/FieldWidget/CommentWidget.php
@@ -0,0 +1,105 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\comment\Plugin\Field\FieldWidget\CommentWidget.
+ */
+
+namespace Drupal\comment\Plugin\Field\FieldWidget;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+use Drupal\Core\Field\WidgetBase;
+
+/**
+ * Provides a default comment widget.
+ *
+ * @FieldWidget(
+ *   id = "comment_default",
+ *   label = @Translation("Comment"),
+ *   field_types = {
+ *     "comment"
+ *   }
+ * )
+ */
+class CommentWidget extends WidgetBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
+    $field = $this->fieldDefinition;
+    $entity = $items->getParent();
+
+    // Get default value from the field instance.
+    $field_default_values = $this->fieldDefinition->getFieldDefaultValue($entity);
+    $status = $items->status;
+
+    $element['status'] = array(
+      '#type' => 'radios',
+      '#title' => t('Comments'),
+      '#title_display' => 'invisible',
+      '#default_value' => $status,
+      '#options' => array(
+        COMMENT_OPEN => t('Open'),
+        COMMENT_CLOSED => t('Closed'),
+        COMMENT_HIDDEN => t('Hidden'),
+      ),
+      COMMENT_OPEN => array(
+        '#description' => t('Users with the "Post comments" permission can post comments.'),
+      ),
+      COMMENT_CLOSED => array(
+        '#description' => t('Users cannot post comments, but existing comments will be displayed.'),
+      ),
+      COMMENT_HIDDEN => array(
+        '#description' => t('Comments are hidden from view.'),
+      ),
+    );
+    // If the entity doesn't have any comments, the "hidden" option makes no
+    // sense, so don't even bother presenting it to the user unless this is the
+    // default value widget on the field settings form.
+    if ($element['#field_parents'] != array('default_value_input') && !$entity->get($field->getFieldName())->comment_count) {
+      $element['status'][COMMENT_HIDDEN]['#access'] = FALSE;
+      // Also adjust the description of the "closed" option.
+      $element['status'][COMMENT_CLOSED]['#description'] = t('Users cannot post comments.');
+    }
+    // If the advanced settings tabs-set is available (normally rendered in the
+    // second column on wide-resolutions), place the field as a details element
+    // in this tab-set.
+    if (isset($form['advanced'])) {
+      $element += array(
+        '#type' => 'details',
+        // Collapse this field when the selected value is the same as stored in
+        // default values for the field instance.
+        '#collapsed' => ($items->status == $field_default_values[0]['status']),
+        '#group' => 'advanced',
+        '#attributes' => array(
+          'class' => array('comment-' . drupal_html_class($element['#entity_type']) . '-settings-form'),
+        ),
+        '#attached' => array(
+          'library' => array('comment', 'drupal.comment'),
+        ),
+      );
+    }
+
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function massageFormValues(array $values, array $form, array &$form_state) {
+    // Add default values for statistics properties because we don't want to
+    // have them in form.
+    foreach ($values as &$value) {
+      $value += array(
+        'cid' => 0,
+        'last_comment_timestamp' => 0,
+        'last_comment_name' => '',
+        'last_comment_uid' => 0,
+        'comment_count' => 0,
+      );
+    }
+    return $values;
+  }
+
+}
diff --git a/core/modules/comment/lib/Drupal/comment/Plugin/field/formatter/CommentDefaultFormatter.php b/core/modules/comment/lib/Drupal/comment/Plugin/field/formatter/CommentDefaultFormatter.php
deleted file mode 100644
index 98c89d5..0000000
--- a/core/modules/comment/lib/Drupal/comment/Plugin/field/formatter/CommentDefaultFormatter.php
+++ /dev/null
@@ -1,157 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\comment\Plugin\field\formatter\CommentDefaultFormatter.
- */
-
-namespace Drupal\comment\Plugin\field\formatter;
-
-use Drupal\comment\CommentStorageControllerInterface;
-use Drupal\Core\Entity\EntityRenderControllerInterface;
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\Core\Session\AccountInterface;
-use Drupal\Core\Entity\Field\FieldDefinitionInterface;
-use Drupal\field\Plugin\Type\Formatter\FormatterBase;
-use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Provides a default comment formatter.
- *
- * @FieldFormatter(
- *   id = "comment_default",
- *   module = "comment",
- *   label = @Translation("Comment list"),
- *   field_types = {
- *     "comment"
- *   }
- * )
- */
-class CommentDefaultFormatter extends FormatterBase implements ContainerFactoryPluginInterface {
-
-  /**
-   * The comment storage controller.
-   *
-   * @var \Drupal\comment\CommentStorageControllerInterface
-   */
-  protected $storageController;
-
-  /**
-   * The current user.
-   *
-   * @var \Drupal\Core\Session\AccountInterface
-   */
-  protected $currentUser;
-
-  /**
-   * The comment render controller.
-   *
-   * @var \Drupal\Core\Entity\EntityRenderControllerInterface
-   */
-  protected $renderController;
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container, array $configuration, $plugin_id, array $plugin_definition) {
-    return new static(
-      $plugin_id,
-      $plugin_definition,
-      $configuration['field_definition'],
-      $configuration['settings'],
-      $configuration['label'],
-      $configuration['view_mode'],
-      $container->get('current_user'),
-      $container->get('entity.manager')->getStorageController('comment'),
-      $container->get('entity.manager')->getRenderController('comment')
-    );
-  }
-
-  /**
-   * Constructs a new CommentDefaultFormatter.
-   *
-   * @param string $plugin_id
-   *   The plugin_id for the formatter.
-   * @param array $plugin_definition
-   *   The plugin implementation definition.
-   * @param \Drupal\Core\Entity\Field\FieldDefinitionInterface $field_definition
-   *   The definition of the field to which the formatter is associated.
-   * @param array $settings
-   *   The formatter settings.
-   * @param string $label
-   *   The formatter label display setting.
-   * @param string $view_mode
-   *   The view mode.
-   * @param \Drupal\Core\Session\AccountInterface $current_user
-   *   The current user.
-   * @param \Drupal\comment\CommentStorageControllerInterface
-   *   The comment storage controller.
-   * @param \Drupal\Core\Entity\EntityRenderControllerInterface
-   *   The comment render controller.
-   */
-  public function __construct($plugin_id, array $plugin_definition,  FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, AccountInterface $current_user, CommentStorageControllerInterface $comment_storage_controller, EntityRenderControllerInterface $comment_render_controller) {
-    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode);
-    $this->renderController = $comment_render_controller;
-    $this->storageController = $comment_storage_controller;
-    $this->currentUser = $current_user;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function viewElements(FieldItemListInterface $items) {
-    $elements = array();
-    $output = array();
-
-    $field_name = $this->fieldDefinition->getFieldName();
-    $entity = $items->getEntity();
-
-    $status = $items->status;
-
-    if ($status != COMMENT_HIDDEN && empty($entity->in_preview) &&
-      // Comments are added to the search results and search index by
-      // comment_node_update_index() instead of by this formatter, so don't
-      // return anything if the view mode is search_index or search_result.
-      !in_array($this->viewMode, array('search_result', 'search_index'))) {
-      $comment_settings = $this->getFieldSettings();
-
-      // Only attempt to render comments if the entity has visible comments.
-      // Unpublished comments are not included in
-      // $entity->get($field_name)->comment_count, but unpublished comments
-      // should display if the user is an administrator.
-      if ((($entity->get($field_name)->comment_count && $this->currentUser->hasPermission('access comments')) ||
-        $this->currentUser->hasPermission('administer comments'))) {
-        $mode = $comment_settings['default_mode'];
-        $comments_per_page = $comment_settings['per_page'];
-        if ($cids = comment_get_thread($entity, $field_name, $mode, $comments_per_page)) {
-          $comments = $this->storageController->loadMultiple($cids);
-          comment_prepare_thread($comments);
-          $build = $this->renderController->viewMultiple($comments);
-          $build['pager']['#theme'] = 'pager';
-          $output['comments'] = $build;
-        }
-      }
-
-      // Append comment form if the comments are open and the form is set to
-      // display below the entity.
-      if ($status == COMMENT_OPEN && $comment_settings['form_location'] == COMMENT_FORM_BELOW) {
-        // Only show the add comment form if the user has permission.
-        if ($this->currentUser->hasPermission('post comments')) {
-          $output['comment_form'] = comment_add($entity, $field_name);
-        }
-      }
-
-      $elements[] = $output + array(
-        '#theme' => 'comment_wrapper__' . $entity->entityType() . '__' . $entity->bundle() . '__' . $field_name,
-        '#entity' => $entity,
-        '#display_mode' => $this->getFieldSetting('default_mode'),
-        'comments' => array(),
-        'comment_form' => array(),
-      );
-    }
-
-    return $elements;
-  }
-
-}
diff --git a/core/modules/comment/lib/Drupal/comment/Plugin/field/widget/CommentWidget.php b/core/modules/comment/lib/Drupal/comment/Plugin/field/widget/CommentWidget.php
deleted file mode 100644
index b1da3b0..0000000
--- a/core/modules/comment/lib/Drupal/comment/Plugin/field/widget/CommentWidget.php
+++ /dev/null
@@ -1,105 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\comment\Plugin\field\widget\CommentWidget.
- */
-
-namespace Drupal\comment\Plugin\field\widget;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\field\Plugin\Type\Widget\WidgetBase;
-
-/**
- * Provides a default comment widget.
- *
- * @FieldWidget(
- *   id = "comment_default",
- *   label = @Translation("Comment"),
- *   field_types = {
- *     "comment"
- *   }
- * )
- */
-class CommentWidget extends WidgetBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
-    $field = $this->fieldDefinition;
-    $entity = $items->getParent();
-
-    // Get default value from the field instance.
-    $field_default_values = $this->fieldDefinition->getFieldDefaultValue($entity);
-    $status = $items->status;
-
-    $element['status'] = array(
-      '#type' => 'radios',
-      '#title' => t('Comments'),
-      '#title_display' => 'invisible',
-      '#default_value' => $status,
-      '#options' => array(
-        COMMENT_OPEN => t('Open'),
-        COMMENT_CLOSED => t('Closed'),
-        COMMENT_HIDDEN => t('Hidden'),
-      ),
-      COMMENT_OPEN => array(
-        '#description' => t('Users with the "Post comments" permission can post comments.'),
-      ),
-      COMMENT_CLOSED => array(
-        '#description' => t('Users cannot post comments, but existing comments will be displayed.'),
-      ),
-      COMMENT_HIDDEN => array(
-        '#description' => t('Comments are hidden from view.'),
-      ),
-    );
-    // If the entity doesn't have any comments, the "hidden" option makes no
-    // sense, so don't even bother presenting it to the user unless this is the
-    // default value widget on the field settings form.
-    if ($element['#field_parents'] != array('default_value_input') && !$entity->get($field->getFieldName())->comment_count) {
-      $element['status'][COMMENT_HIDDEN]['#access'] = FALSE;
-      // Also adjust the description of the "closed" option.
-      $element['status'][COMMENT_CLOSED]['#description'] = t('Users cannot post comments.');
-    }
-    // If the advanced settings tabs-set is available (normally rendered in the
-    // second column on wide-resolutions), place the field as a details element
-    // in this tab-set.
-    if (isset($form['advanced'])) {
-      $element += array(
-        '#type' => 'details',
-        // Collapse this field when the selected value is the same as stored in
-        // default values for the field instance.
-        '#collapsed' => ($items->status == $field_default_values[0]['status']),
-        '#group' => 'advanced',
-        '#attributes' => array(
-          'class' => array('comment-' . drupal_html_class($element['#entity_type']) . '-settings-form'),
-        ),
-        '#attached' => array(
-          'library' => array('comment', 'drupal.comment'),
-        ),
-      );
-    }
-
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function massageFormValues(array $values, array $form, array &$form_state) {
-    // Add default values for statistics properties because we don't want to
-    // have them in form.
-    foreach ($values as &$value) {
-      $value += array(
-        'cid' => 0,
-        'last_comment_timestamp' => 0,
-        'last_comment_name' => '',
-        'last_comment_uid' => 0,
-        'comment_count' => 0,
-      );
-    }
-    return $values;
-  }
-
-}
diff --git a/core/modules/datetime/datetime.module b/core/modules/datetime/datetime.module
index c6d9af0..da33989 100644
--- a/core/modules/datetime/datetime.module
+++ b/core/modules/datetime/datetime.module
@@ -171,7 +171,7 @@ function datetime_datelist_widget_validate(&$element, &$form_state) {
  * Sets a default value for an empty date field.
  *
  * Callback for $instance['default_value_function'], as implemented by
- * Drupal\datetime\Plugin\field\widget\DateTimeDatepicker.
+ * Drupal\datetime\Plugin\Field\FieldWidget\DateTimeDatepicker.
  *
  * @param $entity_type
  *
diff --git a/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldFormatter/DatetimeDefaultFormatter.php b/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldFormatter/DatetimeDefaultFormatter.php
new file mode 100644
index 0000000..757f650
--- /dev/null
+++ b/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldFormatter/DatetimeDefaultFormatter.php
@@ -0,0 +1,182 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\datetime\Plugin\Field\FieldFormatter\DateTimeDefaultFormatter.
+ */
+
+namespace Drupal\datetime\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Datetime\Date;
+use Drupal\Core\Datetime\DrupalDateTime;
+use Drupal\Core\Entity\EntityStorageControllerInterface;
+use Drupal\Core\Entity\Field\FieldDefinitionInterface;
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Field\FormatterBase;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Plugin implementation of the 'datetime_default' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "datetime_default",
+ *   label = @Translation("Default"),
+ *   field_types = {
+ *     "datetime"
+ *   },
+ *   settings = {
+ *     "format_type" = "medium",
+ *   }
+ * )
+ */
+class DateTimeDefaultFormatter extends FormatterBase implements ContainerFactoryPluginInterface {
+
+  /**
+   * The date service.
+   *
+   * @var \Drupal\Core\Datetime\Date
+   */
+  protected $dateService;
+
+  /**
+   * The date storage controller.
+   *
+   * @var \Drupal\Core\Entity\EntityStorageControllerInterface
+   */
+  protected $dateStorage;
+
+  /**
+   * Constructs a new DateTimeDefaultFormatter.
+   *
+   * @param string $plugin_id
+   *   The plugin_id for the formatter.
+   * @param array $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Entity\Field\FieldDefinitionInterface $field_definition
+   *   The definition of the field to which the formatter is associated.
+   * @param array $settings
+   *   The formatter settings.
+   * @param string $label
+   *   The formatter label display setting.
+   * @param string $view_mode
+   *   The view mode.
+   * @param \Drupal\Core\Datetime\Date $date_service
+   *   The date service.
+   * @param \Drupal\Core\Entity\EntityStorageControllerInterface $date_storage
+   *   The date storage controller.
+   */
+  public function __construct($plugin_id, array $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, Date $date_service, EntityStorageControllerInterface $date_storage) {
+    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode);
+
+    $this->dateService = $date_service;
+    $this->dateStorage = $date_storage;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, array $plugin_definition) {
+    return new static(
+      $plugin_id,
+      $plugin_definition,
+      $configuration['field_definition'],
+      $configuration['settings'],
+      $configuration['label'],
+      $configuration['view_mode'],
+      $container->get('date'),
+      $container->get('entity.manager')->getStorageController('date_format')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+
+    $elements = array();
+
+    foreach ($items as $delta => $item) {
+
+      $formatted_date = '';
+      $iso_date = '';
+
+      if ($item->date) {
+        $date = $item->date;
+        // Create the ISO date in Universal Time.
+        $iso_date = $date->format("Y-m-d\TH:i:s") . 'Z';
+
+        // The formatted output will be in local time.
+        $date->setTimeZone(timezone_open(drupal_get_user_timezone()));
+        if ($this->getFieldSetting('datetime_type') == 'date') {
+          // A date without time will pick up the current time, use the default.
+          datetime_date_default_time($date);
+        }
+        $formatted_date = $this->dateFormat($date);
+      }
+
+      // Display the date using theme datetime.
+      // @todo How should RDFa attributes be added to this?
+      $elements[$delta] = array(
+        '#theme' => 'datetime',
+        '#text' => $formatted_date,
+        '#html' => FALSE,
+        '#attributes' => array(
+          'datetime' => $iso_date,
+          'property' => array('dc:date'),
+          'datatype' => 'xsd:dateTime',
+        ),
+      );
+    }
+
+    return $elements;
+
+  }
+
+  /**
+   * Creates a formatted date value as a string.
+   *
+   * @param object $date
+   *   A date object.
+   *
+   * @return string
+   *   A formatted date string using the chosen format.
+   */
+  function dateFormat($date) {
+    $format_type = $this->getSetting('format_type');
+    return $this->dateService->format($date->getTimestamp(), $format_type);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    $time = new DrupalDateTime();
+    $format_types = $this->dateStorage->loadMultiple();
+    foreach ($format_types as $type => $type_info) {
+      $format = $this->dateService->format($time->format('U'), $type);
+      $options[$type] = $type_info->label() . ' (' . $format . ')';
+    }
+
+    $elements['format_type'] = array(
+      '#type' => 'select',
+      '#title' => t('Date format'),
+      '#description' => t("Choose a format for displaying the date. Be sure to set a format appropriate for the field, i.e. omitting time for a field that only has a date."),
+      '#options' => $options,
+      '#default_value' => $this->getSetting('format_type'),
+    );
+
+    return $elements;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = array();
+    $date = new DrupalDateTime();
+    $summary[] = t('Format: @display', array('@display' => $this->dateFormat($date, FALSE)));
+    return $summary;
+  }
+
+}
diff --git a/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldFormatter/DatetimePlainFormatter.php b/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldFormatter/DatetimePlainFormatter.php
new file mode 100644
index 0000000..a52b78d
--- /dev/null
+++ b/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldFormatter/DatetimePlainFormatter.php
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\datetime\Plugin\Field\FieldFormatter\DateTimePlainFormatter.
+ */
+
+namespace Drupal\datetime\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Field\FormatterBase;
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+
+/**
+ * Plugin implementation of the 'datetime_plain' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "datetime_plain",
+ *   label = @Translation("Plain"),
+ *   field_types = {
+ *     "datetime"
+ *   }
+ *)
+ */
+class DateTimePlainFormatter extends FormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+
+    $elements = array();
+
+    foreach ($items as $delta => $item) {
+
+      $output = '';
+      if (!empty($item->date)) {
+        // The date was created and verified during field_load(), so it is safe
+        // to use without further inspection.
+        $date = $item->date;
+        $date->setTimeZone(timezone_open(drupal_get_user_timezone()));
+        $format = DATETIME_DATETIME_STORAGE_FORMAT;
+        if ($this->getFieldSetting('datetime_type') == 'date') {
+          // A date without time will pick up the current time, use the default.
+          datetime_date_default_time($date);
+          $format = DATETIME_DATE_STORAGE_FORMAT;
+        }
+        $output = $date->format($format);
+      }
+      $elements[$delta] = array('#markup' => $output);
+    }
+
+    return $elements;
+  }
+
+}
diff --git a/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldWidget/DatetimeDatelistWidget.php b/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldWidget/DatetimeDatelistWidget.php
new file mode 100644
index 0000000..417e185
--- /dev/null
+++ b/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldWidget/DatetimeDatelistWidget.php
@@ -0,0 +1,200 @@
+<?php
+/**
+ * @file
+ * Contains \Drupal\datetime\Plugin\Field\FieldWidget\DateTimeDatelistWidget.
+ */
+
+namespace Drupal\datetime\Plugin\Field\FieldWidget;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+use Drupal\Core\Field\WidgetBase;
+use Drupal\Core\Entity\Field\FieldDefinitionInterface;
+use Drupal\field\FieldInstanceInterface;
+use Drupal\datetime\DateHelper;
+
+/**
+ * Plugin implementation of the 'datetime_datelist' widget.
+ *
+ * @FieldWidget(
+ *   id = "datetime_datelist",
+ *   label = @Translation("Select list"),
+ *   field_types = {
+ *     "datetime"
+ *   },
+ *   settings = {
+ *     "increment" = 15,
+ *     "date_order" = "YMD",
+ *     "time_type" = "24",
+ *   }
+ * )
+ */
+class DateTimeDatelistWidget extends WidgetBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function __construct($plugin_id, array $plugin_definition, FieldDefinitionInterface $field_definition, array $settings) {
+    // Identify the function used to set the default value.
+    // @todo Make this work for both configurable and nonconfigurable fields:
+    //   https://drupal.org/node/1989468.
+    if ($field_definition instanceof FieldInstanceInterface) {
+      $field_definition->default_value_function = $this->defaultValueFunction();
+    }
+    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings);
+  }
+
+  /**
+   * Returns the callback used to set a date default value.
+   *
+   * @return string
+   *   The name of the callback to use when setting a default date value.
+   */
+  public function defaultValueFunction() {
+    return 'datetime_default_value';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
+    $date_order = $this->getSetting('date_order');
+    $time_type = $this->getSetting('time_type');
+    $increment = $this->getSetting('increment');
+
+    // We're nesting some sub-elements inside the parent, so we
+    // need a wrapper. We also need to add another #title attribute
+    // at the top level for ease in identifying this item in error
+    // messages. We don't want to display this title because the
+    // actual title display is handled at a higher level by the Field
+    // module.
+
+    $element['#theme_wrappers'][] = 'datetime_wrapper';
+    $element['#attributes']['class'][] = 'container-inline';
+    $element['#element_validate'][] = 'datetime_datelist_widget_validate';
+
+    // Identify the type of date and time elements to use.
+    switch ($this->getFieldSetting('datetime_type')) {
+      case 'date':
+        $storage_format = DATETIME_DATE_STORAGE_FORMAT;
+        $type_type = 'none';
+        break;
+
+      default:
+        $storage_format = DATETIME_DATETIME_STORAGE_FORMAT;
+        break;
+    }
+
+    // Set up the date part order array.
+    switch ($date_order) {
+      case 'YMD':
+        $date_part_order = array('year', 'month', 'day');
+        break;
+
+      case 'MDY':
+        $date_part_order = array('month', 'day', 'year');
+        break;
+
+      case 'DMY':
+        $date_part_order = array('day', 'month', 'year');
+        break;
+    }
+    switch ($time_type) {
+       case '24':
+         $date_part_order = array_merge($date_part_order, array('hour', 'minute'));
+         break;
+
+       case '12':
+         $date_part_order = array_merge($date_part_order, array('hour', 'minute', 'ampm'));
+         break;
+
+       case 'none':
+         break;
+    }
+
+    $element['value'] = array(
+      '#type' => 'datelist',
+      '#default_value' => NULL,
+      '#date_increment' => $increment,
+      '#date_part_order'=> $date_part_order,
+      '#date_timezone' => drupal_get_user_timezone(),
+      '#required' => $element['#required'],
+    );
+
+    // Set the storage and widget options so the validation can use them. The
+    // validator will not have access to the field definition.
+    $element['value']['#date_storage_format'] = $storage_format;
+
+    if ($items[$delta]->date) {
+      $date = $items[$delta]->date;
+      // The date was created and verified during field_load(), so it is safe to
+      // use without further inspection.
+      $date->setTimezone( new \DateTimeZone($element['value']['#date_timezone']));
+      if ($this->getFieldSetting('datetime_type') == 'date') {
+        // A date without time will pick up the current time, use the default
+        // time.
+        datetime_date_default_time($date);
+      }
+      $element['value']['#default_value'] = $date;
+    }
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  function settingsForm(array $form, array &$form_state) {
+    $element = parent::settingsForm($form, $form_state);
+
+    $element['date_order'] = array(
+      '#type' => 'select',
+      '#title' => t('Date part order'),
+      '#default_value' => $this->getSetting('date_order'),
+      '#options' => array('MDY' => t('Month/Day/Year'), 'DMY' => t('Day/Month/Year'), 'YMD' => t('Year/Month/Day')),
+    );
+
+    if ($this->getFieldSetting('datetime_type') == 'datetime') {
+      $element['time_type'] = array(
+        '#type' => 'select',
+        '#title' => t('Time type'),
+        '#default_value' => $this->getSetting('time_type'),
+        '#options' => array('24' => t('24 hour time'), '12' => t('12 hour time')),
+      );
+    }
+    else {
+      $element['time_type'] = array(
+        '#type' => 'hidden',
+        '#value' => 'none',
+      );
+    }
+
+    $element['increment'] = array(
+      '#type' => 'select',
+      '#title' => t('Time increments'),
+      '#default_value' => $this->getSetting('increment'),
+      '#options' => array(
+        1 => t('1 minute'),
+        5 => t('5 minute'),
+        10 => t('10 minute'),
+        15 => t('15 minute'),
+        30 => t('30 minute')),
+    );
+
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = array();
+
+    $summary[] = t('Date part order: !order', array('!order' => $this->getSetting('date_order')));
+    if ($this->getFieldSetting('datetime_type') == 'datetime') {
+      $summary[] = t('Time type: !time_type', array('!time_type' => $this->getSetting('time_type')));
+    }
+    $summary[] = t('Time increments: !increment', array('!increment' => $this->getSetting('increment')));
+
+    return $summary;
+  }
+
+}
diff --git a/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldWidget/DatetimeDefaultWidget.php b/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldWidget/DatetimeDefaultWidget.php
new file mode 100644
index 0000000..90fb488
--- /dev/null
+++ b/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldWidget/DatetimeDefaultWidget.php
@@ -0,0 +1,131 @@
+<?php
+/**
+ * @file
+ * Contains \Drupal\datetime\Plugin\Field\FieldWidget\DateTimeDefaultWidget.
+ */
+
+namespace Drupal\datetime\Plugin\Field\FieldWidget;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+use Drupal\Core\Field\WidgetBase;
+use Drupal\Core\Entity\Field\FieldDefinitionInterface;
+use Drupal\field\FieldInstanceInterface;
+
+/**
+ * Plugin implementation of the 'datetime_default' widget.
+ *
+ * @FieldWidget(
+ *   id = "datetime_default",
+ *   label = @Translation("Date and time"),
+ *   field_types = {
+ *     "datetime"
+ *   }
+ * )
+ */
+class DateTimeDefaultWidget extends WidgetBase {
+
+  /**
+   * The date format storage.
+   *
+   * @var \Drupal\Core\Entity\EntityStorageControllerInterface
+   */
+  protected $dateStorage;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function __construct($plugin_id, array $plugin_definition, FieldDefinitionInterface $field_definition, array $settings) {
+    // Identify the function used to set the default value.
+    // @todo Make this work for both configurable and nonconfigurable fields:
+    //   https://drupal.org/node/1989468.
+    if ($field_definition instanceof FieldInstanceInterface) {
+      $field_definition->default_value_function = $this->defaultValueFunction();
+    }
+    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings);
+
+    // @todo Inject this once https://drupal.org/node/2035317 is in.
+    $this->dateStorage = \Drupal::entityManager()->getStorageController('date_format');
+  }
+
+  /**
+   * Return the callback used to set a date default value.
+   *
+   * @return string
+   *   The name of the callback to use when setting a default date value.
+   */
+  public function defaultValueFunction() {
+    return 'datetime_default_value';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
+    $format_type = datetime_default_format_type();
+
+    // We are nesting some sub-elements inside the parent, so we need a wrapper.
+    // We also need to add another #title attribute at the top level for ease in
+    // identifying this item in error messages. We do not want to display this
+    // title because the actual title display is handled at a higher level by
+    // the Field module.
+
+    $element['#theme_wrappers'][] = 'datetime_wrapper';
+    $element['#attributes']['class'][] = 'container-inline';
+    $element['#element_validate'][] = 'datetime_datetime_widget_validate';
+
+    // Identify the type of date and time elements to use.
+    switch ($this->getFieldSetting('datetime_type')) {
+      case 'date':
+        $date_type = 'date';
+        $time_type = 'none';
+        $date_format = $this->dateStorage->load('html_date')->getPattern($format_type);
+        $time_format = '';
+        $element_format = $date_format;
+        $storage_format = DATETIME_DATE_STORAGE_FORMAT;
+        break;
+
+      default:
+        $date_type = 'date';
+        $time_type = 'time';
+        $date_format = $this->dateStorage->load('html_date')->getPattern($format_type);
+        $time_format = $this->dateStorage->load('html_time')->getPattern($format_type);
+        $element_format = $date_format . ' ' . $time_format;
+        $storage_format = DATETIME_DATETIME_STORAGE_FORMAT;
+        break;
+    }
+
+    $element['value'] = array(
+      '#type' => 'datetime',
+      '#default_value' => NULL,
+      '#date_increment' => 1,
+      '#date_date_format'=>  $date_format,
+      '#date_date_element' => $date_type,
+      '#date_date_callbacks' => array(),
+      '#date_time_format' => $time_format,
+      '#date_time_element' => $time_type,
+      '#date_time_callbacks' => array(),
+      '#date_timezone' => drupal_get_user_timezone(),
+      '#required' => $element['#required'],
+    );
+
+    // Set the storage and widget options so the validation can use them. The
+    // validator will not have access to the field definition.
+    $element['value']['#date_element_format'] = $element_format;
+    $element['value']['#date_storage_format'] = $storage_format;
+    if ($items[$delta]->date) {
+      $date = $items[$delta]->date;
+      // The date was created and verified during field_load(), so it is safe to
+      // use without further inspection.
+      $date->setTimezone(new \DateTimeZone($element['value']['#date_timezone']));
+      if ($this->getFieldSetting('datetime_type') == 'date') {
+        // A date without time will pick up the current time, use the default
+        // time.
+        datetime_date_default_time($date);
+      }
+      $element['value']['#default_value'] = $date;
+    }
+
+    return $element;
+  }
+
+}
diff --git a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/formatter/DatetimeDefaultFormatter.php b/core/modules/datetime/lib/Drupal/datetime/Plugin/field/formatter/DatetimeDefaultFormatter.php
deleted file mode 100644
index 71315d0..0000000
--- a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/formatter/DatetimeDefaultFormatter.php
+++ /dev/null
@@ -1,182 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\datetime\Plugin\field\formatter\DateTimeDefaultFormatter.
- */
-
-namespace Drupal\datetime\Plugin\field\formatter;
-
-use Drupal\Core\Datetime\Date;
-use Drupal\Core\Datetime\DrupalDateTime;
-use Drupal\Core\Entity\EntityStorageControllerInterface;
-use Drupal\Core\Entity\Field\FieldDefinitionInterface;
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
-use Drupal\field\Plugin\Type\Formatter\FormatterBase;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Plugin implementation of the 'datetime_default' formatter.
- *
- * @FieldFormatter(
- *   id = "datetime_default",
- *   label = @Translation("Default"),
- *   field_types = {
- *     "datetime"
- *   },
- *   settings = {
- *     "format_type" = "medium",
- *   }
- * )
- */
-class DateTimeDefaultFormatter extends FormatterBase implements ContainerFactoryPluginInterface {
-
-  /**
-   * The date service.
-   *
-   * @var \Drupal\Core\Datetime\Date
-   */
-  protected $dateService;
-
-  /**
-   * The date storage controller.
-   *
-   * @var \Drupal\Core\Entity\EntityStorageControllerInterface
-   */
-  protected $dateStorage;
-
-  /**
-   * Constructs a new DateTimeDefaultFormatter.
-   *
-   * @param string $plugin_id
-   *   The plugin_id for the formatter.
-   * @param array $plugin_definition
-   *   The plugin implementation definition.
-   * @param \Drupal\Core\Entity\Field\FieldDefinitionInterface $field_definition
-   *   The definition of the field to which the formatter is associated.
-   * @param array $settings
-   *   The formatter settings.
-   * @param string $label
-   *   The formatter label display setting.
-   * @param string $view_mode
-   *   The view mode.
-   * @param \Drupal\Core\Datetime\Date $date_service
-   *   The date service.
-   * @param \Drupal\Core\Entity\EntityStorageControllerInterface $date_storage
-   *   The date storage controller.
-   */
-  public function __construct($plugin_id, array $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, Date $date_service, EntityStorageControllerInterface $date_storage) {
-    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode);
-
-    $this->dateService = $date_service;
-    $this->dateStorage = $date_storage;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container, array $configuration, $plugin_id, array $plugin_definition) {
-    return new static(
-      $plugin_id,
-      $plugin_definition,
-      $configuration['field_definition'],
-      $configuration['settings'],
-      $configuration['label'],
-      $configuration['view_mode'],
-      $container->get('date'),
-      $container->get('entity.manager')->getStorageController('date_format')
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function viewElements(FieldItemListInterface $items) {
-
-    $elements = array();
-
-    foreach ($items as $delta => $item) {
-
-      $formatted_date = '';
-      $iso_date = '';
-
-      if ($item->date) {
-        $date = $item->date;
-        // Create the ISO date in Universal Time.
-        $iso_date = $date->format("Y-m-d\TH:i:s") . 'Z';
-
-        // The formatted output will be in local time.
-        $date->setTimeZone(timezone_open(drupal_get_user_timezone()));
-        if ($this->getFieldSetting('datetime_type') == 'date') {
-          // A date without time will pick up the current time, use the default.
-          datetime_date_default_time($date);
-        }
-        $formatted_date = $this->dateFormat($date);
-      }
-
-      // Display the date using theme datetime.
-      // @todo How should RDFa attributes be added to this?
-      $elements[$delta] = array(
-        '#theme' => 'datetime',
-        '#text' => $formatted_date,
-        '#html' => FALSE,
-        '#attributes' => array(
-          'datetime' => $iso_date,
-          'property' => array('dc:date'),
-          'datatype' => 'xsd:dateTime',
-        ),
-      );
-    }
-
-    return $elements;
-
-  }
-
-  /**
-   * Creates a formatted date value as a string.
-   *
-   * @param object $date
-   *   A date object.
-   *
-   * @return string
-   *   A formatted date string using the chosen format.
-   */
-  function dateFormat($date) {
-    $format_type = $this->getSetting('format_type');
-    return $this->dateService->format($date->getTimestamp(), $format_type);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsForm(array $form, array &$form_state) {
-    $time = new DrupalDateTime();
-    $format_types = $this->dateStorage->loadMultiple();
-    foreach ($format_types as $type => $type_info) {
-      $format = $this->dateService->format($time->format('U'), $type);
-      $options[$type] = $type_info->label() . ' (' . $format . ')';
-    }
-
-    $elements['format_type'] = array(
-      '#type' => 'select',
-      '#title' => t('Date format'),
-      '#description' => t("Choose a format for displaying the date. Be sure to set a format appropriate for the field, i.e. omitting time for a field that only has a date."),
-      '#options' => $options,
-      '#default_value' => $this->getSetting('format_type'),
-    );
-
-    return $elements;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    $summary = array();
-    $date = new DrupalDateTime();
-    $summary[] = t('Format: @display', array('@display' => $this->dateFormat($date, FALSE)));
-    return $summary;
-  }
-
-}
diff --git a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/formatter/DatetimePlainFormatter.php b/core/modules/datetime/lib/Drupal/datetime/Plugin/field/formatter/DatetimePlainFormatter.php
deleted file mode 100644
index 978e007..0000000
--- a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/formatter/DatetimePlainFormatter.php
+++ /dev/null
@@ -1,55 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\datetime\Plugin\field\formatter\DateTimePlainFormatter.
- */
-
-namespace Drupal\datetime\Plugin\field\formatter;
-
-use Drupal\field\Plugin\Type\Formatter\FormatterBase;
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-
-/**
- * Plugin implementation of the 'datetime_plain' formatter.
- *
- * @FieldFormatter(
- *   id = "datetime_plain",
- *   label = @Translation("Plain"),
- *   field_types = {
- *     "datetime"
- *   }
- *)
- */
-class DateTimePlainFormatter extends FormatterBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function viewElements(FieldItemListInterface $items) {
-
-    $elements = array();
-
-    foreach ($items as $delta => $item) {
-
-      $output = '';
-      if (!empty($item->date)) {
-        // The date was created and verified during field_load(), so it is safe
-        // to use without further inspection.
-        $date = $item->date;
-        $date->setTimeZone(timezone_open(drupal_get_user_timezone()));
-        $format = DATETIME_DATETIME_STORAGE_FORMAT;
-        if ($this->getFieldSetting('datetime_type') == 'date') {
-          // A date without time will pick up the current time, use the default.
-          datetime_date_default_time($date);
-          $format = DATETIME_DATE_STORAGE_FORMAT;
-        }
-        $output = $date->format($format);
-      }
-      $elements[$delta] = array('#markup' => $output);
-    }
-
-    return $elements;
-  }
-
-}
diff --git a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDatelistWidget.php b/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDatelistWidget.php
deleted file mode 100644
index 7bfd26a..0000000
--- a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDatelistWidget.php
+++ /dev/null
@@ -1,200 +0,0 @@
-<?php
-/**
- * @file
- * Contains \Drupal\datetime\Plugin\field\widget\DateTimeDatelistWidget.
- */
-
-namespace Drupal\datetime\Plugin\field\widget;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\field\Plugin\Type\Widget\WidgetBase;
-use Drupal\Core\Entity\Field\FieldDefinitionInterface;
-use Drupal\field\FieldInstanceInterface;
-use Drupal\datetime\DateHelper;
-
-/**
- * Plugin implementation of the 'datetime_datelist' widget.
- *
- * @FieldWidget(
- *   id = "datetime_datelist",
- *   label = @Translation("Select list"),
- *   field_types = {
- *     "datetime"
- *   },
- *   settings = {
- *     "increment" = 15,
- *     "date_order" = "YMD",
- *     "time_type" = "24",
- *   }
- * )
- */
-class DateTimeDatelistWidget extends WidgetBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function __construct($plugin_id, array $plugin_definition, FieldDefinitionInterface $field_definition, array $settings) {
-    // Identify the function used to set the default value.
-    // @todo Make this work for both configurable and nonconfigurable fields:
-    //   https://drupal.org/node/1989468.
-    if ($field_definition instanceof FieldInstanceInterface) {
-      $field_definition->default_value_function = $this->defaultValueFunction();
-    }
-    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings);
-  }
-
-  /**
-   * Returns the callback used to set a date default value.
-   *
-   * @return string
-   *   The name of the callback to use when setting a default date value.
-   */
-  public function defaultValueFunction() {
-    return 'datetime_default_value';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
-    $date_order = $this->getSetting('date_order');
-    $time_type = $this->getSetting('time_type');
-    $increment = $this->getSetting('increment');
-
-    // We're nesting some sub-elements inside the parent, so we
-    // need a wrapper. We also need to add another #title attribute
-    // at the top level for ease in identifying this item in error
-    // messages. We don't want to display this title because the
-    // actual title display is handled at a higher level by the Field
-    // module.
-
-    $element['#theme_wrappers'][] = 'datetime_wrapper';
-    $element['#attributes']['class'][] = 'container-inline';
-    $element['#element_validate'][] = 'datetime_datelist_widget_validate';
-
-    // Identify the type of date and time elements to use.
-    switch ($this->getFieldSetting('datetime_type')) {
-      case 'date':
-        $storage_format = DATETIME_DATE_STORAGE_FORMAT;
-        $type_type = 'none';
-        break;
-
-      default:
-        $storage_format = DATETIME_DATETIME_STORAGE_FORMAT;
-        break;
-    }
-
-    // Set up the date part order array.
-    switch ($date_order) {
-      case 'YMD':
-        $date_part_order = array('year', 'month', 'day');
-        break;
-
-      case 'MDY':
-        $date_part_order = array('month', 'day', 'year');
-        break;
-
-      case 'DMY':
-        $date_part_order = array('day', 'month', 'year');
-        break;
-    }
-    switch ($time_type) {
-       case '24':
-         $date_part_order = array_merge($date_part_order, array('hour', 'minute'));
-         break;
-
-       case '12':
-         $date_part_order = array_merge($date_part_order, array('hour', 'minute', 'ampm'));
-         break;
-
-       case 'none':
-         break;
-    }
-
-    $element['value'] = array(
-      '#type' => 'datelist',
-      '#default_value' => NULL,
-      '#date_increment' => $increment,
-      '#date_part_order'=> $date_part_order,
-      '#date_timezone' => drupal_get_user_timezone(),
-      '#required' => $element['#required'],
-    );
-
-    // Set the storage and widget options so the validation can use them. The
-    // validator will not have access to the field definition.
-    $element['value']['#date_storage_format'] = $storage_format;
-
-    if ($items[$delta]->date) {
-      $date = $items[$delta]->date;
-      // The date was created and verified during field_load(), so it is safe to
-      // use without further inspection.
-      $date->setTimezone( new \DateTimeZone($element['value']['#date_timezone']));
-      if ($this->getFieldSetting('datetime_type') == 'date') {
-        // A date without time will pick up the current time, use the default
-        // time.
-        datetime_date_default_time($date);
-      }
-      $element['value']['#default_value'] = $date;
-    }
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  function settingsForm(array $form, array &$form_state) {
-    $element = parent::settingsForm($form, $form_state);
-
-    $element['date_order'] = array(
-      '#type' => 'select',
-      '#title' => t('Date part order'),
-      '#default_value' => $this->getSetting('date_order'),
-      '#options' => array('MDY' => t('Month/Day/Year'), 'DMY' => t('Day/Month/Year'), 'YMD' => t('Year/Month/Day')),
-    );
-
-    if ($this->getFieldSetting('datetime_type') == 'datetime') {
-      $element['time_type'] = array(
-        '#type' => 'select',
-        '#title' => t('Time type'),
-        '#default_value' => $this->getSetting('time_type'),
-        '#options' => array('24' => t('24 hour time'), '12' => t('12 hour time')),
-      );
-    }
-    else {
-      $element['time_type'] = array(
-        '#type' => 'hidden',
-        '#value' => 'none',
-      );
-    }
-
-    $element['increment'] = array(
-      '#type' => 'select',
-      '#title' => t('Time increments'),
-      '#default_value' => $this->getSetting('increment'),
-      '#options' => array(
-        1 => t('1 minute'),
-        5 => t('5 minute'),
-        10 => t('10 minute'),
-        15 => t('15 minute'),
-        30 => t('30 minute')),
-    );
-
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    $summary = array();
-
-    $summary[] = t('Date part order: !order', array('!order' => $this->getSetting('date_order')));
-    if ($this->getFieldSetting('datetime_type') == 'datetime') {
-      $summary[] = t('Time type: !time_type', array('!time_type' => $this->getSetting('time_type')));
-    }
-    $summary[] = t('Time increments: !increment', array('!increment' => $this->getSetting('increment')));
-
-    return $summary;
-  }
-
-}
diff --git a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDefaultWidget.php b/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDefaultWidget.php
deleted file mode 100644
index 69400d5..0000000
--- a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDefaultWidget.php
+++ /dev/null
@@ -1,131 +0,0 @@
-<?php
-/**
- * @file
- * Contains \Drupal\datetime\Plugin\field\widget\DateTimeDefaultWidget.
- */
-
-namespace Drupal\datetime\Plugin\field\widget;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\field\Plugin\Type\Widget\WidgetBase;
-use Drupal\Core\Entity\Field\FieldDefinitionInterface;
-use Drupal\field\FieldInstanceInterface;
-
-/**
- * Plugin implementation of the 'datetime_default' widget.
- *
- * @FieldWidget(
- *   id = "datetime_default",
- *   label = @Translation("Date and time"),
- *   field_types = {
- *     "datetime"
- *   }
- * )
- */
-class DateTimeDefaultWidget extends WidgetBase {
-
-  /**
-   * The date format storage.
-   *
-   * @var \Drupal\Core\Entity\EntityStorageControllerInterface
-   */
-  protected $dateStorage;
-
-  /**
-   * {@inheritdoc}
-   */
-  public function __construct($plugin_id, array $plugin_definition, FieldDefinitionInterface $field_definition, array $settings) {
-    // Identify the function used to set the default value.
-    // @todo Make this work for both configurable and nonconfigurable fields:
-    //   https://drupal.org/node/1989468.
-    if ($field_definition instanceof FieldInstanceInterface) {
-      $field_definition->default_value_function = $this->defaultValueFunction();
-    }
-    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings);
-
-    // @todo Inject this once https://drupal.org/node/2035317 is in.
-    $this->dateStorage = \Drupal::entityManager()->getStorageController('date_format');
-  }
-
-  /**
-   * Return the callback used to set a date default value.
-   *
-   * @return string
-   *   The name of the callback to use when setting a default date value.
-   */
-  public function defaultValueFunction() {
-    return 'datetime_default_value';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
-    $format_type = datetime_default_format_type();
-
-    // We are nesting some sub-elements inside the parent, so we need a wrapper.
-    // We also need to add another #title attribute at the top level for ease in
-    // identifying this item in error messages. We do not want to display this
-    // title because the actual title display is handled at a higher level by
-    // the Field module.
-
-    $element['#theme_wrappers'][] = 'datetime_wrapper';
-    $element['#attributes']['class'][] = 'container-inline';
-    $element['#element_validate'][] = 'datetime_datetime_widget_validate';
-
-    // Identify the type of date and time elements to use.
-    switch ($this->getFieldSetting('datetime_type')) {
-      case 'date':
-        $date_type = 'date';
-        $time_type = 'none';
-        $date_format = $this->dateStorage->load('html_date')->getPattern($format_type);
-        $time_format = '';
-        $element_format = $date_format;
-        $storage_format = DATETIME_DATE_STORAGE_FORMAT;
-        break;
-
-      default:
-        $date_type = 'date';
-        $time_type = 'time';
-        $date_format = $this->dateStorage->load('html_date')->getPattern($format_type);
-        $time_format = $this->dateStorage->load('html_time')->getPattern($format_type);
-        $element_format = $date_format . ' ' . $time_format;
-        $storage_format = DATETIME_DATETIME_STORAGE_FORMAT;
-        break;
-    }
-
-    $element['value'] = array(
-      '#type' => 'datetime',
-      '#default_value' => NULL,
-      '#date_increment' => 1,
-      '#date_date_format'=>  $date_format,
-      '#date_date_element' => $date_type,
-      '#date_date_callbacks' => array(),
-      '#date_time_format' => $time_format,
-      '#date_time_element' => $time_type,
-      '#date_time_callbacks' => array(),
-      '#date_timezone' => drupal_get_user_timezone(),
-      '#required' => $element['#required'],
-    );
-
-    // Set the storage and widget options so the validation can use them. The
-    // validator will not have access to the field definition.
-    $element['value']['#date_element_format'] = $element_format;
-    $element['value']['#date_storage_format'] = $storage_format;
-    if ($items[$delta]->date) {
-      $date = $items[$delta]->date;
-      // The date was created and verified during field_load(), so it is safe to
-      // use without further inspection.
-      $date->setTimezone(new \DateTimeZone($element['value']['#date_timezone']));
-      if ($this->getFieldSetting('datetime_type') == 'date') {
-        // A date without time will pick up the current time, use the default
-        // time.
-        datetime_date_default_time($date);
-      }
-      $element['value']['#default_value'] = $date;
-    }
-
-    return $element;
-  }
-
-}
diff --git a/core/modules/edit/lib/Drupal/edit/EditorSelector.php b/core/modules/edit/lib/Drupal/edit/EditorSelector.php
index b59a68c..50f113c 100644
--- a/core/modules/edit/lib/Drupal/edit/EditorSelector.php
+++ b/core/modules/edit/lib/Drupal/edit/EditorSelector.php
@@ -10,7 +10,7 @@
 use Drupal\Component\Plugin\PluginManagerInterface;
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Entity\Field\FieldDefinitionInterface;
-use Drupal\field\Plugin\Type\Formatter\FormatterPluginManager;
+use Drupal\Core\Field\FormatterPluginManager;
 
 /**
  * Selects an in-place editor (an Editor plugin) for a field.
@@ -27,7 +27,7 @@ class EditorSelector implements EditorSelectorInterface {
   /**
    * The manager for formatter plugins.
    *
-   * @var \Drupal\field\Plugin\Type\Formatter\FormatterPluginManager.
+   * @var \Drupal\Core\Field\FormatterPluginManager.
    */
   protected $formatterManager;
 
@@ -43,7 +43,7 @@ class EditorSelector implements EditorSelectorInterface {
    *
    * @param \Drupal\Component\Plugin\PluginManagerInterface
    *   The manager for editor plugins.
-   * @param \Drupal\field\Plugin\Type\Formatter\FormatterPluginManager
+   * @param \Drupal\Core\Field\FormatterPluginManager
    *   The manager for formatter plugins.
    */
   public function __construct(PluginManagerInterface $editor_manager, FormatterPluginManager $formatter_manager) {
diff --git a/core/modules/email/lib/Drupal/email/Plugin/Field/FieldFormatter/MailToFormatter.php b/core/modules/email/lib/Drupal/email/Plugin/Field/FieldFormatter/MailToFormatter.php
new file mode 100644
index 0000000..38b3c08
--- /dev/null
+++ b/core/modules/email/lib/Drupal/email/Plugin/Field/FieldFormatter/MailToFormatter.php
@@ -0,0 +1,43 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\email\Plugin\Field\FieldFormatter\MailToFormatter.
+ */
+
+namespace Drupal\email\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Field\FormatterBase;
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+
+/**
+ * Plugin implementation of the 'email_mailto' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "email_mailto",
+ *   label = @Translation("Email"),
+ *   field_types = {
+ *     "email"
+ *   }
+ * )
+ */
+class MailToFormatter extends FormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+    $elements = array();
+
+    foreach ($items as $delta => $item) {
+      $elements[$delta] = array(
+        '#type' => 'link',
+        '#title' => $item->value,
+        '#href' => 'mailto:' . $item->value,
+      );
+    }
+
+    return $elements;
+  }
+
+}
diff --git a/core/modules/email/lib/Drupal/email/Plugin/Field/FieldWidget/EmailDefaultWidget.php b/core/modules/email/lib/Drupal/email/Plugin/Field/FieldWidget/EmailDefaultWidget.php
new file mode 100644
index 0000000..33a9820
--- /dev/null
+++ b/core/modules/email/lib/Drupal/email/Plugin/Field/FieldWidget/EmailDefaultWidget.php
@@ -0,0 +1,71 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\email\Plugin\Field\FieldWidget\EmailDefaultWidget.
+ */
+
+namespace Drupal\email\Plugin\Field\FieldWidget;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+use Drupal\Core\Field\WidgetBase;
+
+/**
+ * Plugin implementation of the 'email_default' widget.
+ *
+ * @FieldWidget(
+ *   id = "email_default",
+ *   label = @Translation("E-mail"),
+ *   field_types = {
+ *     "email"
+ *   },
+ *   settings = {
+ *     "placeholder" = ""
+ *   }
+ * )
+ */
+class EmailDefaultWidget extends WidgetBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    $element['placeholder'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Placeholder'),
+      '#default_value' => $this->getSetting('placeholder'),
+      '#description' => t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'),
+    );
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = array();
+
+    $placeholder = $this->getSetting('placeholder');
+    if (!empty($placeholder)) {
+      $summary[] = t('Placeholder: @placeholder', array('@placeholder' => $placeholder));
+    }
+    else {
+      $summary[] = t('No placeholder');
+    }
+
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
+    $element['value'] = $element + array(
+      '#type' => 'email',
+      '#default_value' => isset($items[$delta]->value) ? $items[$delta]->value : NULL,
+      '#placeholder' => $this->getSetting('placeholder'),
+    );
+    return $element;
+  }
+
+}
diff --git a/core/modules/email/lib/Drupal/email/Plugin/field/formatter/MailToFormatter.php b/core/modules/email/lib/Drupal/email/Plugin/field/formatter/MailToFormatter.php
deleted file mode 100644
index 6c30d27..0000000
--- a/core/modules/email/lib/Drupal/email/Plugin/field/formatter/MailToFormatter.php
+++ /dev/null
@@ -1,43 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\email\Plugin\field\formatter\MailToFormatter.
- */
-
-namespace Drupal\email\Plugin\field\formatter;
-
-use Drupal\field\Plugin\Type\Formatter\FormatterBase;
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-
-/**
- * Plugin implementation of the 'email_mailto' formatter.
- *
- * @FieldFormatter(
- *   id = "email_mailto",
- *   label = @Translation("Email"),
- *   field_types = {
- *     "email"
- *   }
- * )
- */
-class MailToFormatter extends FormatterBase {
-
-  /**
-   * Implements Drupal\field\Plugin\Type\Formatter\FormatterInterface::viewElements().
-   */
-  public function viewElements(FieldItemListInterface $items) {
-    $elements = array();
-
-    foreach ($items as $delta => $item) {
-      $elements[$delta] = array(
-        '#type' => 'link',
-        '#title' => $item->value,
-        '#href' => 'mailto:' . $item->value,
-      );
-    }
-
-    return $elements;
-  }
-
-}
diff --git a/core/modules/email/lib/Drupal/email/Plugin/field/widget/EmailDefaultWidget.php b/core/modules/email/lib/Drupal/email/Plugin/field/widget/EmailDefaultWidget.php
deleted file mode 100644
index 8735265..0000000
--- a/core/modules/email/lib/Drupal/email/Plugin/field/widget/EmailDefaultWidget.php
+++ /dev/null
@@ -1,71 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\email\Plugin\field\widget\EmailDefaultWidget.
- */
-
-namespace Drupal\email\Plugin\field\widget;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\field\Plugin\Type\Widget\WidgetBase;
-
-/**
- * Plugin implementation of the 'email_default' widget.
- *
- * @FieldWidget(
- *   id = "email_default",
- *   label = @Translation("E-mail"),
- *   field_types = {
- *     "email"
- *   },
- *   settings = {
- *     "placeholder" = ""
- *   }
- * )
- */
-class EmailDefaultWidget extends WidgetBase {
-
-  /**
-   * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::settingsForm().
-   */
-  public function settingsForm(array $form, array &$form_state) {
-    $element['placeholder'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Placeholder'),
-      '#default_value' => $this->getSetting('placeholder'),
-      '#description' => t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'),
-    );
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    $summary = array();
-
-    $placeholder = $this->getSetting('placeholder');
-    if (!empty($placeholder)) {
-      $summary[] = t('Placeholder: @placeholder', array('@placeholder' => $placeholder));
-    }
-    else {
-      $summary[] = t('No placeholder');
-    }
-
-    return $summary;
-  }
-
-  /**
-   * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::formElement().
-   */
-  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
-    $element['value'] = $element + array(
-      '#type' => 'email',
-      '#default_value' => isset($items[$delta]->value) ? $items[$delta]->value : NULL,
-      '#placeholder' => $this->getSetting('placeholder'),
-    );
-    return $element;
-  }
-
-}
diff --git a/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayTest.php b/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayTest.php
index c8f38f7..5fe5f89 100644
--- a/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayTest.php
+++ b/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayTest.php
@@ -156,7 +156,7 @@ public function testFieldComponent() {
 
     // Check that providing no options results in default values being used.
     $display->setComponent($field_name);
-    $field_type_info = \Drupal::service('plugin.manager.entity.field.field_type')->getDefinition($field->type);
+    $field_type_info = \Drupal::service('plugin.manager.field.field_type')->getDefinition($field->type);
     $default_formatter = $field_type_info['default_formatter'];
     $formatter_settings =  \Drupal::service('plugin.manager.field.formatter')->getDefinition($default_formatter);
     $expected = array(
diff --git a/core/modules/entity/lib/Drupal/entity/Tests/EntityFormDisplayTest.php b/core/modules/entity/lib/Drupal/entity/Tests/EntityFormDisplayTest.php
index 84bbe11..a364b3f 100644
--- a/core/modules/entity/lib/Drupal/entity/Tests/EntityFormDisplayTest.php
+++ b/core/modules/entity/lib/Drupal/entity/Tests/EntityFormDisplayTest.php
@@ -78,7 +78,7 @@ public function testFieldComponent() {
 
     // Check that providing no options results in default values being used.
     $form_display->setComponent($field_name);
-    $field_type_info = \Drupal::service('plugin.manager.entity.field.field_type')->getDefinition($field->type);
+    $field_type_info = \Drupal::service('plugin.manager.field.field_type')->getDefinition($field->type);
     $default_widget = $field_type_info['default_widget'];
     $widget_settings = \Drupal::service('plugin.manager.field.widget')->getDefinition($default_widget);
     $expected = array(
diff --git a/core/modules/entity_reference/entity_reference.module b/core/modules/entity_reference/entity_reference.module
index fb78bfa..a9bd8fc 100644
--- a/core/modules/entity_reference/entity_reference.module
+++ b/core/modules/entity_reference/entity_reference.module
@@ -223,7 +223,7 @@ function entity_reference_query_entity_reference_alter(AlterableInterface $query
  */
 function entity_reference_create_instance($entity_type, $bundle, $field_name, $field_label, $target_entity_type, $selection_handler = 'default', $selection_handler_settings = array()) {
   // If a field type we know should exist isn't found, clear the field cache.
-  if (!\Drupal::service('plugin.manager.entity.field.field_type')->getDefinition('entity_reference')) {
+  if (!\Drupal::service('plugin.manager.field.field_type')->getDefinition('entity_reference')) {
     field_cache_clear();
   }
 
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldFormatter/EntityReferenceEntityFormatter.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldFormatter/EntityReferenceEntityFormatter.php
new file mode 100644
index 0000000..0daf4d1
--- /dev/null
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldFormatter/EntityReferenceEntityFormatter.php
@@ -0,0 +1,118 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\entity_reference\Plugin\Field\FieldFormatter\EntityReferenceEntityFormatter.
+ */
+
+namespace Drupal\entity_reference\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+use Drupal\entity_reference\RecursiveRenderingException;
+
+/**
+ * Plugin implementation of the 'entity reference rendered entity' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "entity_reference_entity_view",
+ *   label = @Translation("Rendered entity"),
+ *   description = @Translation("Display the referenced entities rendered by entity_view()."),
+ *   field_types = {
+ *     "entity_reference"
+ *   },
+ *   settings = {
+ *     "view_mode" = "default",
+ *     "link" = FALSE
+ *   }
+ * )
+ */
+class EntityReferenceEntityFormatter extends EntityReferenceFormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    $view_modes = entity_get_view_modes($this->getFieldSetting('target_type'));
+    $options = array('default' => t('Default'));
+    foreach ($view_modes as $view_mode => $view_mode_settings) {
+      $options[$view_mode] = $view_mode_settings['label'];
+    }
+
+    $elements['view_mode'] = array(
+      '#type' => 'select',
+      '#options' => $options,
+      '#title' => t('View mode'),
+      '#default_value' => $this->getSetting('view_mode'),
+      '#required' => TRUE,
+    );
+
+    $elements['links'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Show links'),
+      '#default_value' => $this->getSetting('links'),
+    );
+
+    return $elements;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = array();
+
+    $view_modes = entity_get_view_modes($this->getFieldSetting('target_type'));
+    $view_mode = $this->getSetting('view_mode');
+    if ($view_mode == 'default') {
+      $view_mode = t('Default');
+    }
+    $summary[] = t('Rendered as @mode', array('@mode' => isset($view_modes[$view_mode]['label']) ? $view_modes[$view_mode]['label'] : $view_mode));
+    $summary[] = $this->getSetting('links') ? t('Display links') : t('Do not display links');
+
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+    $view_mode = $this->getSetting('view_mode');
+    $links = $this->getSetting('links');
+
+    $target_type = $this->getFieldSetting('target_type');
+
+    $elements = array();
+
+    foreach ($items as $delta => $item) {
+      if (!$item->access) {
+        // User doesn't have access to the referenced entity.
+        continue;
+      }
+      // Protect ourselves from recursive rendering.
+      static $depth = 0;
+      $depth++;
+      if ($depth > 20) {
+        throw new RecursiveRenderingException(format_string('Recursive rendering detected when rendering entity @entity_type(@entity_id). Aborting rendering.', array('@entity_type' => $item->entity->entityType(), '@entity_id' => $item->target_id)));
+      }
+
+      if (!empty($item->target_id)) {
+        $entity = clone $item->entity;
+        unset($entity->content);
+        $elements[$delta] = entity_view($entity, $view_mode, $item->getLangcode());
+
+        if (empty($links) && isset($result[$delta][$target_type][$item->target_id]['links'])) {
+          // Hide the element links.
+          $elements[$delta][$target_type][$item->target_id]['links']['#access'] = FALSE;
+        }
+      }
+      else {
+        // This is an "auto_create" item.
+        $elements[$delta] = array('#markup' => $item->entity->label());
+      }
+      $depth = 0;
+    }
+
+    return $elements;
+  }
+
+}
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldFormatter/EntityReferenceFormatterBase.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldFormatter/EntityReferenceFormatterBase.php
new file mode 100644
index 0000000..8cf1bf7
--- /dev/null
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldFormatter/EntityReferenceFormatterBase.php
@@ -0,0 +1,93 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\entity_reference\Plugin\Field\FieldFormatter\EntityReferenceFormatterBase.
+ */
+
+namespace Drupal\entity_reference\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Field\FormatterBase;
+
+/**
+ * Parent plugin for entity reference formatters.
+ */
+abstract class EntityReferenceFormatterBase extends FormatterBase {
+
+  /**
+   * {@inheritdoc}
+   *
+   * Mark the accessible IDs a user can see. We do not unset unaccessible
+   * values, as other may want to act on those values, even if they can
+   * not be accessed.
+   */
+  public function prepareView(array $entities_items) {
+    $target_ids = array();
+    $revision_ids = array();
+
+    // Collect every possible entity attached to any of the entities.
+    foreach ($entities_items as $items) {
+      foreach ($items as $item) {
+        if (!empty($item->revision_id)) {
+          $revision_ids[] = $item->revision_id;
+        }
+        elseif (!empty($item->target_id)) {
+          $target_ids[] = $item->target_id;
+        }
+      }
+    }
+
+    $target_type = $this->getFieldSetting('target_type');
+
+    $target_entities = array();
+
+    if ($target_ids) {
+      $target_entities = entity_load_multiple($target_type, $target_ids);
+    }
+
+    if ($revision_ids) {
+      // We need to load the revisions one by-one.
+      foreach ($revision_ids as $revision_id) {
+        $target_entity = entity_revision_load($target_type, $revision_id);
+        // Use the revision ID in the key.
+        $identifier = $target_entity->id() . ':' . $revision_id;
+        $target_entities[$identifier] = $target_entity;
+      }
+    }
+
+    // Iterate through the fieldable entities again to attach the loaded data.
+    foreach ($entities_items as $items) {
+      $rekey = FALSE;
+      foreach ($items as $item) {
+        // If we have a revision ID, the key uses it as well.
+        $identifier = !empty($item->revision_id) ? $item->target_id . ':' . $item->revision_id : $item->target_id;
+        if ($item->target_id !== 0) {
+          if (!isset($target_entities[$identifier])) {
+            // The entity no longer exists, so empty the item.
+            $item->setValue(NULL);
+            $rekey = TRUE;
+            continue;
+          }
+
+          $item->entity = $target_entities[$identifier];
+
+          if (!$item->entity->access('view')) {
+            continue;
+          }
+        }
+        else {
+          // This is an "auto_create" item, just leave the entity in place.
+        }
+
+        // Mark item as accessible.
+        $item->access = TRUE;
+      }
+
+      // Rekey the items array if needed.
+      if ($rekey) {
+        $items->filterEmptyValues();
+      }
+    }
+  }
+
+}
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldFormatter/EntityReferenceIdFormatter.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldFormatter/EntityReferenceIdFormatter.php
new file mode 100644
index 0000000..c951af8
--- /dev/null
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldFormatter/EntityReferenceIdFormatter.php
@@ -0,0 +1,44 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\entity_reference\Plugin\Field\FieldFormatter\EntityReferenceIdFormatter.
+ */
+
+namespace Drupal\entity_reference\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+
+/**
+ * Plugin implementation of the 'entity reference ID' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "entity_reference_entity_id",
+ *   label = @Translation("Entity ID"),
+ *   description = @Translation("Display the ID of the referenced entities."),
+ *   field_types = {
+ *     "entity_reference"
+ *   }
+ * )
+ */
+class EntityReferenceIdFormatter extends EntityReferenceFormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+    $elements = array();
+
+    foreach ($items as $delta => $item) {
+      if (!$item->access) {
+        // User doesn't have access to the referenced entity.
+        continue;
+      }
+      if (!empty($item->entity) && !empty($item->target_id)) {
+        $elements[$delta] = array('#markup' => check_plain($item->target_id));
+      }
+    }
+
+    return $elements;
+  }
+}
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldFormatter/EntityReferenceLabelFormatter.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldFormatter/EntityReferenceLabelFormatter.php
new file mode 100644
index 0000000..a25d1f4
--- /dev/null
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldFormatter/EntityReferenceLabelFormatter.php
@@ -0,0 +1,83 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\entity_reference\Plugin\Field\FieldFormatter\EntityReferenceLabelFormatter.
+ */
+
+namespace Drupal\entity_reference\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+
+/**
+ * Plugin implementation of the 'entity reference label' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "entity_reference_label",
+ *   label = @Translation("Label"),
+ *   description = @Translation("Display the label of the referenced entities."),
+ *   field_types = {
+ *     "entity_reference"
+ *   },
+ *   settings = {
+ *     "link" = TRUE
+ *   }
+ * )
+ */
+class EntityReferenceLabelFormatter extends EntityReferenceFormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    $elements['link'] = array(
+      '#title' => t('Link label to the referenced entity'),
+      '#type' => 'checkbox',
+      '#default_value' => $this->getSetting('link'),
+    );
+
+    return $elements;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = array();
+    $summary[] = $this->getSetting('link') ? t('Link to the referenced entity') : t('No link');
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+    $elements = array();
+
+    foreach ($items as $delta => $item) {
+      if (!$item->access) {
+        // User doesn't have access to the referenced entity.
+        continue;
+      }
+      if ($referenced_entity = $item->entity) {
+        $label = $referenced_entity->label();
+        // If the link is to be displayed and the entity has a uri,
+        // display a link.
+        if ($this->getSetting('link') && $uri = $referenced_entity->uri()) {
+          $elements[$delta] = array(
+            '#type' => 'link',
+            '#title' => $label,
+            '#href' => $uri['path'],
+            '#options' => $uri['options'],
+          );
+        }
+        else {
+          $elements[$delta] = array('#markup' => check_plain($label));
+        }
+      }
+    }
+
+    return $elements;
+  }
+
+}
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldWidget/AutocompleteTagsWidget.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldWidget/AutocompleteTagsWidget.php
new file mode 100644
index 0000000..abcbde4
--- /dev/null
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldWidget/AutocompleteTagsWidget.php
@@ -0,0 +1,75 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\entity_reference\Plugin\Field\FieldWidget\AutocompleteTagsWidget.
+ */
+
+namespace Drupal\entity_reference\Plugin\Field\FieldWidget;
+
+use Drupal\entity_reference\Plugin\Field\FieldWidget\AutocompleteWidgetBase;
+
+/**
+ * Plugin implementation of the 'entity_reference autocomplete-tags' widget.
+ *
+ * @FieldWidget(
+ *   id = "entity_reference_autocomplete_tags",
+ *   label = @Translation("Autocomplete (Tags style)"),
+ *   description = @Translation("An autocomplete text field."),
+ *   field_types = {
+ *     "entity_reference"
+ *   },
+ *   settings = {
+ *     "match_operator" = "CONTAINS",
+ *     "size" = 60,
+ *     "autocomplete_type" = "tags",
+ *     "placeholder" = ""
+ *   },
+ *   multiple_values = TRUE
+ * )
+ */
+class AutocompleteTagsWidget extends AutocompleteWidgetBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function elementValidate($element, &$form_state, $form) {
+    $value = array();
+    // If a value was entered into the autocomplete.
+    $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');
+
+    if (!empty($element['#value'])) {
+      $value = array();
+      foreach (drupal_explode_tags($element['#value']) as $input) {
+        $match = FALSE;
+
+        // Take "label (entity id)', match the id from parenthesis.
+        if (preg_match("/.+\((\d+)\)/", $input, $matches)) {
+          $match = $matches[1];
+        }
+        else {
+          // Try to get a match from the input string when the user didn't use
+          // the autocomplete but filled in a value manually.
+          $match = $handler->validateAutocompleteInput($input, $element, $form_state, $form, !$auto_create);
+        }
+
+        if ($match) {
+          $value[] = array('target_id' => $match);
+        }
+        elseif ($auto_create && (count($this->getSelectionHandlerSetting('target_bundles')) == 1 || count($bundles) == 1)) {
+          // Auto-create item. see entity_reference_field_presave().
+          $value[] = array(
+            'target_id' => 0,
+            'entity' => $this->createNewEntity($input, $element['#autocreate_uid']),
+          );
+        }
+      }
+    };
+    // Change the element['#parents'], so in form_set_value() we
+    // populate the correct key.
+    array_pop($element['#parents']);
+    form_set_value($element, $value, $form_state);
+  }
+}
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldWidget/AutocompleteWidget.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldWidget/AutocompleteWidget.php
new file mode 100644
index 0000000..a30d804
--- /dev/null
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldWidget/AutocompleteWidget.php
@@ -0,0 +1,94 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\entity_reference\Plugin\Field\FieldWidget\AutocompleteWidget.
+ */
+
+namespace Drupal\entity_reference\Plugin\Field\FieldWidget;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+use Drupal\entity_reference\Plugin\Field\FieldWidget\AutocompleteWidgetBase;
+
+/**
+ * Plugin implementation of the 'entity_reference autocomplete' widget.
+ *
+ * @todo: Check if the following statement is still correct
+ * The autocomplete path doesn't have a default here, because it's not the
+ * the two widgets, and the Field API doesn't update default settings when
+ * the widget changes.
+ *
+ * @FieldWidget(
+ *   id = "entity_reference_autocomplete",
+ *   label = @Translation("Autocomplete"),
+ *   description = @Translation("An autocomplete text field."),
+ *   field_types = {
+ *     "entity_reference"
+ *   },
+ *   settings = {
+ *     "match_operator" = "CONTAINS",
+ *     "size" = 60,
+ *     "autocomplete_type" = "single",
+ *     "placeholder" = ""
+ *   }
+ * )
+ */
+class AutocompleteWidget extends AutocompleteWidgetBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
+    // We let the Field API handles multiple values for us, only take care of
+    // the one matching our delta.
+    if (isset($items[$delta])) {
+      $items->setValue(array($items[$delta]->getValue()));
+    }
+    else {
+      $items->setValue(array());
+    }
+
+    return parent::formElement($items, $delta, $element, $form, $form_state);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function elementValidate($element, &$form_state, $form) {
+    $auto_create = $this->getSelectionHandlerSetting('auto_create');
+
+    // If a value was entered into the autocomplete.
+    $value = '';
+    if (!empty($element['#value'])) {
+      // Take "label (entity id)', match the id from parenthesis.
+      // @todo: Lookup the entity type's ID data type and use it here.
+      // https://drupal.org/node/2107249
+      if ($this->isContentReferenced() && preg_match("/.+\((\d+)\)/", $element['#value'], $matches)) {
+        $value = $matches[1];
+      }
+      elseif (preg_match("/.+\(([\w.]+)\)/", $element['#value'], $matches)) {
+        $value = $matches[1];
+      }
+      if (!$value) {
+        // 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);
+        $value = $handler->validateAutocompleteInput($element['#value'], $element, $form_state, $form, !$auto_create);
+      }
+
+      if (!$value && $auto_create && (count($this->getSelectionHandlerSetting('target_bundles')) == 1)) {
+        // Auto-create item. see entity_reference_field_presave().
+        $value = array(
+          'target_id' => 0,
+          'entity' => $this->createNewEntity($element['#value'], $element['#autocreate_uid']),
+          // Keep the weight property.
+          '_weight' => $element['#weight'],
+        );
+        // Change the element['#parents'], so in form_set_value() we
+        // populate the correct key.
+        array_pop($element['#parents']);
+      }
+    }
+    form_set_value($element, $value, $form_state);
+  }
+}
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldWidget/AutocompleteWidgetBase.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldWidget/AutocompleteWidgetBase.php
new file mode 100644
index 0000000..3bcbd94
--- /dev/null
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldWidget/AutocompleteWidgetBase.php
@@ -0,0 +1,207 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\entity_reference\Plugin\Field\FieldWidget\AutocompleteWidgetBase.
+ */
+
+namespace Drupal\entity_reference\Plugin\Field\FieldWidget;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+use Drupal\Core\Field\WidgetBase;
+use Symfony\Component\Validator\ConstraintViolationInterface;
+
+/**
+ * Parent plugin for entity reference autocomplete widgets.
+ */
+abstract class AutocompleteWidgetBase extends WidgetBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    $element['match_operator'] = array(
+      '#type' => 'radios',
+      '#title' => t('Autocomplete matching'),
+      '#default_value' => $this->getSetting('match_operator'),
+      '#options' => array(
+        'STARTS_WITH' => t('Starts with'),
+        'CONTAINS' => t('Contains'),
+      ),
+      '#description' => t('Select the method used to collect autocomplete suggestions. Note that <em>Contains</em> can cause performance issues on sites with thousands of entities.'),
+    );
+    $element['size'] = array(
+      '#type' => 'number',
+      '#title' => t('Size of textfield'),
+      '#default_value' => $this->getSetting('size'),
+      '#min' => 1,
+      '#required' => TRUE,
+    );
+    $element['placeholder'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Placeholder'),
+      '#default_value' => $this->getSetting('placeholder'),
+      '#description' => t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'),
+    );
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = array();
+
+    $summary[] = t('Autocomplete matching: @match_operator', array('@match_operator' => $this->getSetting('match_operator')));
+    $summary[] = t('Textfield size: !size', array('!size' => $this->getSetting('size')));
+    $placeholder = $this->getSetting('placeholder');
+    if (!empty($placeholder)) {
+      $summary[] = t('Placeholder: @placeholder', array('@placeholder' => $placeholder));
+    }
+    else {
+      $summary[] = t('No placeholder');
+    }
+
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
+    global $user;
+
+    $entity = $items->getEntity();
+
+    // Prepare the autocomplete route parameters.
+    $autocomplete_route_parameters = array(
+      'type' => $this->getSetting('autocomplete_type'),
+      'field_name' => $this->fieldDefinition->getFieldName(),
+      'entity_type' => $entity->entityType(),
+      'bundle_name' => $entity->bundle(),
+    );
+
+    if ($entity_id = $entity->id()) {
+      $autocomplete_route_parameters['entity_id'] = $entity_id;
+    }
+
+    $element += array(
+      '#type' => 'textfield',
+      '#maxlength' => 1024,
+      '#default_value' => implode(', ', $this->getLabels($items)),
+      '#autocomplete_route_name' => 'entity_reference.autocomplete',
+      '#autocomplete_route_parameters' => $autocomplete_route_parameters,
+      '#size' => $this->getSetting('size'),
+      '#placeholder' => $this->getSetting('placeholder'),
+      '#element_validate' => array(array($this, 'elementValidate')),
+      // @todo: Use wrapper to get the user if exists or needed.
+      '#autocreate_uid' => isset($entity->uid) ? $entity->uid : $user->id(),
+    );
+
+    return array('target_id' => $element);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function errorElement(array $element, ConstraintViolationInterface $error, array $form, array &$form_state) {
+    return $element['target_id'];
+  }
+
+  /**
+   * Validates an element.
+   */
+  public function elementValidate($element, &$form_state, $form) { }
+
+  /**
+   * Gets the entity labels.
+   */
+  protected function getLabels(FieldItemListInterface $items) {
+    if ($items->isEmpty()) {
+      return array();
+    }
+
+    $entity_ids = array();
+    $entity_labels = array();
+
+    // Build an array of entity IDs.
+    foreach ($items as $item) {
+      $entity_ids[] = $item->target_id;
+    }
+
+    // Load those entities and loop through them to extract their labels.
+    $entities = entity_load_multiple($this->getFieldSetting('target_type'), $entity_ids);
+
+    foreach ($entities as $entity_id => $entity_item) {
+      $label = $entity_item->label();
+      $key = "$label ($entity_id)";
+      // Labels containing commas or quotes must be wrapped in quotes.
+      if (strpos($key, ',') !== FALSE || strpos($key, '"') !== FALSE) {
+        $key = '"' . str_replace('"', '""', $key) . '"';
+      }
+      $entity_labels[] = $key;
+    }
+    return $entity_labels;
+  }
+
+  /**
+   * Creates a new entity from a label entered in the autocomplete input.
+   *
+   * @param string $label
+   *   The entity label.
+   * @param int $uid
+   *   The entity uid.
+   *
+   * @return \Drupal\Core\Entity\EntityInterface
+   */
+  protected function createNewEntity($label, $uid) {
+    $entity_manager = \Drupal::entityManager();
+    $target_type = $this->getFieldSetting('target_type');
+    $target_bundles = $this->getSelectionHandlerSetting('target_bundles');
+
+    // Get the bundle.
+    if (!empty($target_bundles)) {
+      $bundle = reset($target_bundles);
+    }
+    else {
+      $bundles = entity_get_bundles($target_type);
+      $bundle = reset($bundles);
+    }
+
+    $entity_info = $entity_manager->getDefinition($target_type);
+    $bundle_key = $entity_info['entity_keys']['bundle'];
+    $label_key = $entity_info['entity_keys']['label'];
+
+    return $entity_manager->getStorageController($target_type)->create(array(
+      $label_key => $label,
+      $bundle_key => $bundle,
+      'uid' => $uid,
+    ));
+  }
+
+  /**
+   * Returns the value of a setting for the entity reference selection handler.
+   *
+   * @param string $setting_name
+   *   The setting name.
+   *
+   * @return mixed
+   *   The setting value.
+   */
+  protected function getSelectionHandlerSetting($setting_name) {
+    $settings = $this->getFieldSetting('handler_settings');
+    return isset($settings[$setting_name]) ? $settings[$setting_name] : NULL;
+  }
+
+  /**
+   * Checks whether a content entity is referenced.
+   *
+   * @return bool
+   */
+  protected function isContentReferenced() {
+    $target_type = $this->getFieldSetting('target_type');
+    $target_type_info = \Drupal::entityManager()->getDefinition($target_type);
+    return is_subclass_of($target_type_info['class'], '\Drupal\Core\Entity\ContentEntityInterface');
+  }
+
+}
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Type/Selection/SelectionInterface.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Type/Selection/SelectionInterface.php
index 267dd09..f9d94ec 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Type/Selection/SelectionInterface.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Type/Selection/SelectionInterface.php
@@ -59,7 +59,7 @@ public function validateReferenceableEntities(array $ids);
    * @return integer|null
    *   Value of a matching entity ID, or NULL if none.
    *
-   * @see \Drupal\entity_reference\Plugin\field\widget::elementValidate()
+   * @see \Drupal\entity_reference\Plugin\Field\FieldWidget::elementValidate()
    */
   public function validateAutocompleteInput($input, &$element, &$form_state, $form, $strict = TRUE);
 
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/formatter/EntityReferenceEntityFormatter.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/formatter/EntityReferenceEntityFormatter.php
deleted file mode 100644
index 30be80f..0000000
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/formatter/EntityReferenceEntityFormatter.php
+++ /dev/null
@@ -1,119 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\entity_reference\Plugin\field\formatter\EntityReferenceEntityFormatter.
- */
-
-namespace Drupal\entity_reference\Plugin\field\formatter;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\entity_reference\RecursiveRenderingException;
-use Drupal\entity_reference\Plugin\field\formatter\EntityReferenceFormatterBase;
-
-/**
- * Plugin implementation of the 'entity reference rendered entity' formatter.
- *
- * @FieldFormatter(
- *   id = "entity_reference_entity_view",
- *   label = @Translation("Rendered entity"),
- *   description = @Translation("Display the referenced entities rendered by entity_view()."),
- *   field_types = {
- *     "entity_reference"
- *   },
- *   settings = {
- *     "view_mode" = "default",
- *     "link" = FALSE
- *   }
- * )
- */
-class EntityReferenceEntityFormatter extends EntityReferenceFormatterBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsForm(array $form, array &$form_state) {
-    $view_modes = entity_get_view_modes($this->getFieldSetting('target_type'));
-    $options = array('default' => t('Default'));
-    foreach ($view_modes as $view_mode => $view_mode_settings) {
-      $options[$view_mode] = $view_mode_settings['label'];
-    }
-
-    $elements['view_mode'] = array(
-      '#type' => 'select',
-      '#options' => $options,
-      '#title' => t('View mode'),
-      '#default_value' => $this->getSetting('view_mode'),
-      '#required' => TRUE,
-    );
-
-    $elements['links'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Show links'),
-      '#default_value' => $this->getSetting('links'),
-    );
-
-    return $elements;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    $summary = array();
-
-    $view_modes = entity_get_view_modes($this->getFieldSetting('target_type'));
-    $view_mode = $this->getSetting('view_mode');
-    if ($view_mode == 'default') {
-      $view_mode = t('Default');
-    }
-    $summary[] = t('Rendered as @mode', array('@mode' => isset($view_modes[$view_mode]['label']) ? $view_modes[$view_mode]['label'] : $view_mode));
-    $summary[] = $this->getSetting('links') ? t('Display links') : t('Do not display links');
-
-    return $summary;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function viewElements(FieldItemListInterface $items) {
-    $view_mode = $this->getSetting('view_mode');
-    $links = $this->getSetting('links');
-
-    $target_type = $this->getFieldSetting('target_type');
-
-    $elements = array();
-
-    foreach ($items as $delta => $item) {
-      if (!$item->access) {
-        // User doesn't have access to the referenced entity.
-        continue;
-      }
-      // Protect ourselves from recursive rendering.
-      static $depth = 0;
-      $depth++;
-      if ($depth > 20) {
-        throw new RecursiveRenderingException(format_string('Recursive rendering detected when rendering entity @entity_type(@entity_id). Aborting rendering.', array('@entity_type' => $item->entity->entityType(), '@entity_id' => $item->target_id)));
-      }
-
-      if (!empty($item->target_id)) {
-        $entity = clone $item->entity;
-        unset($entity->content);
-        $elements[$delta] = entity_view($entity, $view_mode, $item->getLangcode());
-
-        if (empty($links) && isset($result[$delta][$target_type][$item->target_id]['links'])) {
-          // Hide the element links.
-          $elements[$delta][$target_type][$item->target_id]['links']['#access'] = FALSE;
-        }
-      }
-      else {
-        // This is an "auto_create" item.
-        $elements[$delta] = array('#markup' => $item->entity->label());
-      }
-      $depth = 0;
-    }
-
-    return $elements;
-  }
-
-}
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/formatter/EntityReferenceFormatterBase.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/formatter/EntityReferenceFormatterBase.php
deleted file mode 100644
index a61f49d..0000000
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/formatter/EntityReferenceFormatterBase.php
+++ /dev/null
@@ -1,93 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\entity_reference\Plugin\field\formatter\EntityReferenceFormatterBase.
- */
-
-namespace Drupal\entity_reference\Plugin\field\formatter;
-
-use Drupal\field\Plugin\Type\Formatter\FormatterBase;
-
-/**
- * Parent plugin for entity reference formatters.
- */
-abstract class EntityReferenceFormatterBase extends FormatterBase {
-
-  /**
-   * Overrides \Drupal\field\Plugin\Type\Formatter\FormatterBase::prepareView().
-   *
-   * Mark the accessible IDs a user can see. We do not unset unaccessible
-   * values, as other may want to act on those values, even if they can
-   * not be accessed.
-   */
-  public function prepareView(array $entities_items) {
-    $target_ids = array();
-    $revision_ids = array();
-
-    // Collect every possible entity attached to any of the entities.
-    foreach ($entities_items as $items) {
-      foreach ($items as $item) {
-        if (!empty($item->revision_id)) {
-          $revision_ids[] = $item->revision_id;
-        }
-        elseif (!empty($item->target_id)) {
-          $target_ids[] = $item->target_id;
-        }
-      }
-    }
-
-    $target_type = $this->getFieldSetting('target_type');
-
-    $target_entities = array();
-
-    if ($target_ids) {
-      $target_entities = entity_load_multiple($target_type, $target_ids);
-    }
-
-    if ($revision_ids) {
-      // We need to load the revisions one by-one.
-      foreach ($revision_ids as $revision_id) {
-        $target_entity = entity_revision_load($target_type, $revision_id);
-        // Use the revision ID in the key.
-        $identifier = $target_entity->id() . ':' . $revision_id;
-        $target_entities[$identifier] = $target_entity;
-      }
-    }
-
-    // Iterate through the fieldable entities again to attach the loaded data.
-    foreach ($entities_items as $items) {
-      $rekey = FALSE;
-      foreach ($items as $item) {
-        // If we have a revision ID, the key uses it as well.
-        $identifier = !empty($item->revision_id) ? $item->target_id . ':' . $item->revision_id : $item->target_id;
-        if ($item->target_id !== 0) {
-          if (!isset($target_entities[$identifier])) {
-            // The entity no longer exists, so empty the item.
-            $item->setValue(NULL);
-            $rekey = TRUE;
-            continue;
-          }
-
-          $item->entity = $target_entities[$identifier];
-
-          if (!$item->entity->access('view')) {
-            continue;
-          }
-        }
-        else {
-          // This is an "auto_create" item, just leave the entity in place.
-        }
-
-        // Mark item as accessible.
-        $item->access = TRUE;
-      }
-
-      // Rekey the items array if needed.
-      if ($rekey) {
-        $items->filterEmptyValues();
-      }
-    }
-  }
-
-}
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/formatter/EntityReferenceIdFormatter.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/formatter/EntityReferenceIdFormatter.php
deleted file mode 100644
index f06e963..0000000
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/formatter/EntityReferenceIdFormatter.php
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\entity_reference\Plugin\field\formatter\EntityReferenceIdFormatter.
- */
-
-namespace Drupal\entity_reference\Plugin\field\formatter;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\entity_reference\Plugin\field\formatter\EntityReferenceFormatterBase;
-
-/**
- * Plugin implementation of the 'entity reference ID' formatter.
- *
- * @FieldFormatter(
- *   id = "entity_reference_entity_id",
- *   label = @Translation("Entity ID"),
- *   description = @Translation("Display the ID of the referenced entities."),
- *   field_types = {
- *     "entity_reference"
- *   }
- * )
- */
-class EntityReferenceIdFormatter extends EntityReferenceFormatterBase {
-
-  /**
-   * Overrides \Drupal\entity_reference\Plugin\field\formatter\EntityReferenceFormatterBase::viewElements().
-   */
-  public function viewElements(FieldItemListInterface $items) {
-    $elements = array();
-
-    foreach ($items as $delta => $item) {
-      if (!$item->access) {
-        // User doesn't have access to the referenced entity.
-        continue;
-      }
-      if (!empty($item->entity) && !empty($item->target_id)) {
-        $elements[$delta] = array('#markup' => check_plain($item->target_id));
-      }
-    }
-
-    return $elements;
-  }
-}
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/formatter/EntityReferenceLabelFormatter.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/formatter/EntityReferenceLabelFormatter.php
deleted file mode 100644
index 6d9625e..0000000
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/formatter/EntityReferenceLabelFormatter.php
+++ /dev/null
@@ -1,84 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\entity_reference\Plugin\field\formatter\EntityReferenceLabelFormatter.
- */
-
-namespace Drupal\entity_reference\Plugin\field\formatter;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\entity_reference\Plugin\field\formatter\EntityReferenceFormatterBase;
-
-/**
- * Plugin implementation of the 'entity reference label' formatter.
- *
- * @FieldFormatter(
- *   id = "entity_reference_label",
- *   label = @Translation("Label"),
- *   description = @Translation("Display the label of the referenced entities."),
- *   field_types = {
- *     "entity_reference"
- *   },
- *   settings = {
- *     "link" = TRUE
- *   }
- * )
- */
-class EntityReferenceLabelFormatter extends EntityReferenceFormatterBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsForm(array $form, array &$form_state) {
-    $elements['link'] = array(
-      '#title' => t('Link label to the referenced entity'),
-      '#type' => 'checkbox',
-      '#default_value' => $this->getSetting('link'),
-    );
-
-    return $elements;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    $summary = array();
-    $summary[] = $this->getSetting('link') ? t('Link to the referenced entity') : t('No link');
-    return $summary;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function viewElements(FieldItemListInterface $items) {
-    $elements = array();
-
-    foreach ($items as $delta => $item) {
-      if (!$item->access) {
-        // User doesn't have access to the referenced entity.
-        continue;
-      }
-      if ($referenced_entity = $item->entity) {
-        $label = $referenced_entity->label();
-        // If the link is to be displayed and the entity has a uri,
-        // display a link.
-        if ($this->getSetting('link') && $uri = $referenced_entity->uri()) {
-          $elements[$delta] = array(
-            '#type' => 'link',
-            '#title' => $label,
-            '#href' => $uri['path'],
-            '#options' => $uri['options'],
-          );
-        }
-        else {
-          $elements[$delta] = array('#markup' => check_plain($label));
-        }
-      }
-    }
-
-    return $elements;
-  }
-
-}
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteTagsWidget.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteTagsWidget.php
deleted file mode 100644
index 7f54d9b..0000000
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteTagsWidget.php
+++ /dev/null
@@ -1,75 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\entity_reference\Plugin\field\widget\AutocompleteTagsWidget.
- */
-
-namespace Drupal\entity_reference\Plugin\field\widget;
-
-use Drupal\entity_reference\Plugin\field\widget\AutocompleteWidgetBase;
-
-/**
- * Plugin implementation of the 'entity_reference autocomplete-tags' widget.
- *
- * @FieldWidget(
- *   id = "entity_reference_autocomplete_tags",
- *   label = @Translation("Autocomplete (Tags style)"),
- *   description = @Translation("An autocomplete text field."),
- *   field_types = {
- *     "entity_reference"
- *   },
- *   settings = {
- *     "match_operator" = "CONTAINS",
- *     "size" = 60,
- *     "autocomplete_type" = "tags",
- *     "placeholder" = ""
- *   },
- *   multiple_values = TRUE
- * )
- */
-class AutocompleteTagsWidget extends AutocompleteWidgetBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function elementValidate($element, &$form_state, $form) {
-    $value = array();
-    // If a value was entered into the autocomplete.
-    $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');
-
-    if (!empty($element['#value'])) {
-      $value = array();
-      foreach (drupal_explode_tags($element['#value']) as $input) {
-        $match = FALSE;
-
-        // Take "label (entity id)', match the id from parenthesis.
-        if (preg_match("/.+\((\d+)\)/", $input, $matches)) {
-          $match = $matches[1];
-        }
-        else {
-          // Try to get a match from the input string when the user didn't use
-          // the autocomplete but filled in a value manually.
-          $match = $handler->validateAutocompleteInput($input, $element, $form_state, $form, !$auto_create);
-        }
-
-        if ($match) {
-          $value[] = array('target_id' => $match);
-        }
-        elseif ($auto_create && (count($this->getSelectionHandlerSetting('target_bundles')) == 1 || count($bundles) == 1)) {
-          // Auto-create item. see entity_reference_field_presave().
-          $value[] = array(
-            'target_id' => 0,
-            'entity' => $this->createNewEntity($input, $element['#autocreate_uid']),
-          );
-        }
-      }
-    };
-    // Change the element['#parents'], so in form_set_value() we
-    // populate the correct key.
-    array_pop($element['#parents']);
-    form_set_value($element, $value, $form_state);
-  }
-}
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteWidget.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteWidget.php
deleted file mode 100644
index b45b9b8..0000000
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteWidget.php
+++ /dev/null
@@ -1,94 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\entity_reference\Plugin\field\widget\AutocompleteWidget.
- */
-
-namespace Drupal\entity_reference\Plugin\field\widget;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\entity_reference\Plugin\field\widget\AutocompleteWidgetBase;
-
-/**
- * Plugin implementation of the 'entity_reference autocomplete' widget.
- *
- * @todo: Check if the following statement is still correct
- * The autocomplete path doesn't have a default here, because it's not the
- * the two widgets, and the Field API doesn't update default settings when
- * the widget changes.
- *
- * @FieldWidget(
- *   id = "entity_reference_autocomplete",
- *   label = @Translation("Autocomplete"),
- *   description = @Translation("An autocomplete text field."),
- *   field_types = {
- *     "entity_reference"
- *   },
- *   settings = {
- *     "match_operator" = "CONTAINS",
- *     "size" = 60,
- *     "autocomplete_type" = "single",
- *     "placeholder" = ""
- *   }
- * )
- */
-class AutocompleteWidget extends AutocompleteWidgetBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
-    // We let the Field API handles multiple values for us, only take care of
-    // the one matching our delta.
-    if (isset($items[$delta])) {
-      $items->setValue(array($items[$delta]->getValue()));
-    }
-    else {
-      $items->setValue(array());
-    }
-
-    return parent::formElement($items, $delta, $element, $form, $form_state);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function elementValidate($element, &$form_state, $form) {
-    $auto_create = $this->getSelectionHandlerSetting('auto_create');
-
-    // If a value was entered into the autocomplete.
-    $value = '';
-    if (!empty($element['#value'])) {
-      // Take "label (entity id)', match the id from parenthesis.
-      // @todo: Lookup the entity type's ID data type and use it here.
-      // https://drupal.org/node/2107249
-      if ($this->isContentReferenced() && preg_match("/.+\((\d+)\)/", $element['#value'], $matches)) {
-        $value = $matches[1];
-      }
-      elseif (preg_match("/.+\(([\w.]+)\)/", $element['#value'], $matches)) {
-        $value = $matches[1];
-      }
-      if (!$value) {
-        // 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);
-        $value = $handler->validateAutocompleteInput($element['#value'], $element, $form_state, $form, !$auto_create);
-      }
-
-      if (!$value && $auto_create && (count($this->getSelectionHandlerSetting('target_bundles')) == 1)) {
-        // Auto-create item. see entity_reference_field_presave().
-        $value = array(
-          'target_id' => 0,
-          'entity' => $this->createNewEntity($element['#value'], $element['#autocreate_uid']),
-          // Keep the weight property.
-          '_weight' => $element['#weight'],
-        );
-        // Change the element['#parents'], so in form_set_value() we
-        // populate the correct key.
-        array_pop($element['#parents']);
-      }
-    }
-    form_set_value($element, $value, $form_state);
-  }
-}
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteWidgetBase.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteWidgetBase.php
deleted file mode 100644
index 6e55f2b..0000000
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteWidgetBase.php
+++ /dev/null
@@ -1,207 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\entity_reference\Plugin\field\widget\AutocompleteWidgetBase.
- */
-
-namespace Drupal\entity_reference\Plugin\field\widget;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\field\Plugin\Type\Widget\WidgetBase;
-use Symfony\Component\Validator\ConstraintViolationInterface;
-
-/**
- * Parent plugin for entity reference autocomplete widgets.
- */
-abstract class AutocompleteWidgetBase extends WidgetBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsForm(array $form, array &$form_state) {
-    $element['match_operator'] = array(
-      '#type' => 'radios',
-      '#title' => t('Autocomplete matching'),
-      '#default_value' => $this->getSetting('match_operator'),
-      '#options' => array(
-        'STARTS_WITH' => t('Starts with'),
-        'CONTAINS' => t('Contains'),
-      ),
-      '#description' => t('Select the method used to collect autocomplete suggestions. Note that <em>Contains</em> can cause performance issues on sites with thousands of entities.'),
-    );
-    $element['size'] = array(
-      '#type' => 'number',
-      '#title' => t('Size of textfield'),
-      '#default_value' => $this->getSetting('size'),
-      '#min' => 1,
-      '#required' => TRUE,
-    );
-    $element['placeholder'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Placeholder'),
-      '#default_value' => $this->getSetting('placeholder'),
-      '#description' => t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'),
-    );
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    $summary = array();
-
-    $summary[] = t('Autocomplete matching: @match_operator', array('@match_operator' => $this->getSetting('match_operator')));
-    $summary[] = t('Textfield size: !size', array('!size' => $this->getSetting('size')));
-    $placeholder = $this->getSetting('placeholder');
-    if (!empty($placeholder)) {
-      $summary[] = t('Placeholder: @placeholder', array('@placeholder' => $placeholder));
-    }
-    else {
-      $summary[] = t('No placeholder');
-    }
-
-    return $summary;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
-    global $user;
-
-    $entity = $items->getEntity();
-
-    // Prepare the autocomplete route parameters.
-    $autocomplete_route_parameters = array(
-      'type' => $this->getSetting('autocomplete_type'),
-      'field_name' => $this->fieldDefinition->getFieldName(),
-      'entity_type' => $entity->entityType(),
-      'bundle_name' => $entity->bundle(),
-    );
-
-    if ($entity_id = $entity->id()) {
-      $autocomplete_route_parameters['entity_id'] = $entity_id;
-    }
-
-    $element += array(
-      '#type' => 'textfield',
-      '#maxlength' => 1024,
-      '#default_value' => implode(', ', $this->getLabels($items)),
-      '#autocomplete_route_name' => 'entity_reference.autocomplete',
-      '#autocomplete_route_parameters' => $autocomplete_route_parameters,
-      '#size' => $this->getSetting('size'),
-      '#placeholder' => $this->getSetting('placeholder'),
-      '#element_validate' => array(array($this, 'elementValidate')),
-      // @todo: Use wrapper to get the user if exists or needed.
-      '#autocreate_uid' => isset($entity->uid) ? $entity->uid : $user->id(),
-    );
-
-    return array('target_id' => $element);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function errorElement(array $element, ConstraintViolationInterface $error, array $form, array &$form_state) {
-    return $element['target_id'];
-  }
-
-  /**
-   * Validates an element.
-   */
-  public function elementValidate($element, &$form_state, $form) { }
-
-  /**
-   * Gets the entity labels.
-   */
-  protected function getLabels(FieldItemListInterface $items) {
-    if ($items->isEmpty()) {
-      return array();
-    }
-
-    $entity_ids = array();
-    $entity_labels = array();
-
-    // Build an array of entity IDs.
-    foreach ($items as $item) {
-      $entity_ids[] = $item->target_id;
-    }
-
-    // Load those entities and loop through them to extract their labels.
-    $entities = entity_load_multiple($this->getFieldSetting('target_type'), $entity_ids);
-
-    foreach ($entities as $entity_id => $entity_item) {
-      $label = $entity_item->label();
-      $key = "$label ($entity_id)";
-      // Labels containing commas or quotes must be wrapped in quotes.
-      if (strpos($key, ',') !== FALSE || strpos($key, '"') !== FALSE) {
-        $key = '"' . str_replace('"', '""', $key) . '"';
-      }
-      $entity_labels[] = $key;
-    }
-    return $entity_labels;
-  }
-
-  /**
-   * Creates a new entity from a label entered in the autocomplete input.
-   *
-   * @param string $label
-   *   The entity label.
-   * @param int $uid
-   *   The entity uid.
-   *
-   * @return \Drupal\Core\Entity\EntityInterface
-   */
-  protected function createNewEntity($label, $uid) {
-    $entity_manager = \Drupal::entityManager();
-    $target_type = $this->getFieldSetting('target_type');
-    $target_bundles = $this->getSelectionHandlerSetting('target_bundles');
-
-    // Get the bundle.
-    if (!empty($target_bundles)) {
-      $bundle = reset($target_bundles);
-    }
-    else {
-      $bundles = entity_get_bundles($target_type);
-      $bundle = reset($bundles);
-    }
-
-    $entity_info = $entity_manager->getDefinition($target_type);
-    $bundle_key = $entity_info['entity_keys']['bundle'];
-    $label_key = $entity_info['entity_keys']['label'];
-
-    return $entity_manager->getStorageController($target_type)->create(array(
-      $label_key => $label,
-      $bundle_key => $bundle,
-      'uid' => $uid,
-    ));
-  }
-
-  /**
-   * Returns the value of a setting for the entity reference selection handler.
-   *
-   * @param string $setting_name
-   *   The setting name.
-   *
-   * @return mixed
-   *   The setting value.
-   */
-  protected function getSelectionHandlerSetting($setting_name) {
-    $settings = $this->getFieldSetting('handler_settings');
-    return isset($settings[$setting_name]) ? $settings[$setting_name] : NULL;
-  }
-
-  /**
-   * Checks whether a content entity is referenced.
-   *
-   * @return bool
-   */
-  protected function isContentReferenced() {
-    $target_type = $this->getFieldSetting('target_type');
-    $target_type_info = \Drupal::entityManager()->getDefinition($target_type);
-    return is_subclass_of($target_type_info['class'], '\Drupal\Core\Entity\ContentEntityInterface');
-  }
-
-}
diff --git a/core/modules/field/field.api.php b/core/modules/field/field.api.php
index 8b9bc12..72798b3 100644
--- a/core/modules/field/field.api.php
+++ b/core/modules/field/field.api.php
@@ -153,10 +153,10 @@ function hook_field_info_alter(&$info) {
  * which widget to use.
  *
  * Widgets are Plugins managed by the
- * Drupal\field\Plugin\Type\Widget\WidgetPluginManager class. A widget is
+ * Drupal\Core\Field\WidgetPluginManager class. A widget is
  * implemented by providing a class that implements
- * Drupal\field\Plugin\Type\Widget\WidgetInterface (in most cases, by
- * subclassing Drupal\field\Plugin\Type\Widget\WidgetBase), and provides the
+ * Drupal\Core\Field\WidgetInterface (in most cases, by
+ * subclassing Drupal\Core\Field\WidgetBase), and provides the
  * proper annotation block.
  *
  * Widgets are @link forms_api_reference.html Form API @endlink
@@ -204,7 +204,7 @@ function hook_field_widget_info_alter(array &$info) {
  *   - default: A boolean indicating whether the form is being shown as a dummy
  *     form to set default values.
  *
- * @see \Drupal\field\Plugin\Type\Widget\WidgetBase::formSingleElement()
+ * @see \Drupal\Core\Field\WidgetBase::formSingleElement()
  * @see hook_field_widget_WIDGET_TYPE_form_alter()
  */
 function hook_field_widget_form_alter(&$element, &$form_state, $context) {
@@ -231,7 +231,7 @@ function hook_field_widget_form_alter(&$element, &$form_state, $context) {
  *   An associative array. See hook_field_widget_form_alter() for the structure
  *   and content of the array.
  *
- * @see \Drupal\field\Plugin\Type\Widget\WidgetBase::formSingleElement()
+ * @see \Drupal\Core\Field\WidgetBase::formSingleElement()
  * @see hook_field_widget_form_alter()
  */
 function hook_field_widget_WIDGET_TYPE_form_alter(&$element, &$form_state, $context) {
@@ -258,10 +258,10 @@ function hook_field_widget_WIDGET_TYPE_form_alter(&$element, &$form_state, $cont
  * choose which formatter to use.
  *
  * Formatters are Plugins managed by the
- * Drupal\field\Plugin\Type\Formatter\FormatterPluginManager class. A formatter
+ * Drupal\Core\Field\FormatterPluginManager class. A formatter
  * is implemented by providing a class that implements
- * Drupal\field\Plugin\Type\Formatter\FormatterInterface (in most cases, by
- * subclassing Drupal\field\Plugin\Type\Formatter\FormatterBase), and provides
+ * Drupal\Core\Field\FormatterInterface (in most cases, by
+ * subclassing Drupal\Core\Field\FormatterBase), and provides
  * the proper annotation block.
  *
  * @see field
diff --git a/core/modules/field/field.deprecated.inc b/core/modules/field/field.deprecated.inc
index 0924aec..fe8831f 100644
--- a/core/modules/field/field.deprecated.inc
+++ b/core/modules/field/field.deprecated.inc
@@ -22,16 +22,16 @@
  *   keyed by field type name.
  *
  * @deprecated as of Drupal 8.0. Use
- *   \Drupal::service('plugin.manager.entity.field.field_type')->getDefinition()
+ *   \Drupal::service('plugin.manager.field.field_type')->getDefinition()
  *   or
- *   \Drupal::service('plugin.manager.entity.field.field_type')->getConfigurableDefinitions().
+ *   \Drupal::service('plugin.manager.field.field_type')->getConfigurableDefinitions().
  */
 function field_info_field_types($field_type = NULL) {
   if ($field_type) {
-    return \Drupal::service('plugin.manager.entity.field.field_type')->getDefinition($field_type);
+    return \Drupal::service('plugin.manager.field.field_type')->getDefinition($field_type);
   }
   else {
-    return \Drupal::service('plugin.manager.entity.field.field_type')->getConfigurableDefinitions();
+    return \Drupal::service('plugin.manager.field.field_type')->getConfigurableDefinitions();
   }
 }
 
@@ -46,10 +46,10 @@ function field_info_field_types($field_type = NULL) {
  *   are not defined.
  *
  * @deprecated as of Drupal 8.0. Use
- *   \Drupal::service('plugin.manager.entity.field.field_type')->getDefaultSettings()
+ *   \Drupal::service('plugin.manager.field.field_type')->getDefaultSettings()
  */
 function field_info_field_settings($type) {
-  return \Drupal::service('plugin.manager.entity.field.field_type')->getDefaultSettings($type);
+  return \Drupal::service('plugin.manager.field.field_type')->getDefaultSettings($type);
 }
 
 /**
@@ -63,10 +63,10 @@ function field_info_field_settings($type) {
  *   settings are not defined.
  *
  * @deprecated as of Drupal 8.0. Use
- *   \Drupal::service('plugin.manager.entity.field.field_type')->getDefaultInstanceSettings()
+ *   \Drupal::service('plugin.manager.field.field_type')->getDefaultInstanceSettings()
  */
 function field_info_instance_settings($type) {
-  return \Drupal::service('plugin.manager.entity.field.field_type')->getDefaultInstanceSettings($type);
+  return \Drupal::service('plugin.manager.field.field_type')->getDefaultInstanceSettings($type);
 }
 
 /**
diff --git a/core/modules/field/field.info.inc b/core/modules/field/field.info.inc
index 338dd08..5904ebe 100644
--- a/core/modules/field/field.info.inc
+++ b/core/modules/field/field.info.inc
@@ -37,7 +37,7 @@ function field_info_cache_clear() {
 
   // Clear typed data definitions.
   \Drupal::typedData()->clearCachedDefinitions();
-  \Drupal::service('plugin.manager.entity.field.field_type')->clearCachedDefinitions();
+  \Drupal::service('plugin.manager.field.field_type')->clearCachedDefinitions();
 
   Field::fieldInfo()->flush();
 }
diff --git a/core/modules/field/field.module b/core/modules/field/field.module
index 7621595..cea8e78 100644
--- a/core/modules/field/field.module
+++ b/core/modules/field/field.module
@@ -99,7 +99,7 @@ function field_help($path, $arg) {
       $items = array();
       $info = system_get_info('module');
       $field_widgets = \Drupal::service('plugin.manager.field.widget')->getDefinitions();
-      $field_types = \Drupal::service('plugin.manager.entity.field.field_type')->getConfigurableDefinitions();
+      $field_types = \Drupal::service('plugin.manager.field.field_type')->getConfigurableDefinitions();
       foreach (array_merge($field_types, $field_widgets) as $plugin) {
         $providers[] = $plugin['provider'];
       }
@@ -341,7 +341,7 @@ function field_sync_field_status() {
   // modules.
   $changed = array();
   $modules = $module_handler->getModuleList();
-  $field_types = \Drupal::service('plugin.manager.entity.field.field_type')->getDefinitions();
+  $field_types = \Drupal::service('plugin.manager.field.field_type')->getDefinitions();
   // Set fields with missing field type modules to inactive.
   foreach ($fields as $uuid => &$field) {
     // Associate field types.
diff --git a/core/modules/field/field.services.yml b/core/modules/field/field.services.yml
index c6ef5da..8615517 100644
--- a/core/modules/field/field.services.yml
+++ b/core/modules/field/field.services.yml
@@ -1,17 +1,5 @@
 services:
-  plugin.manager.field.widget:
-    class: Drupal\field\Plugin\Type\Widget\WidgetPluginManager
-    arguments: ['@container.namespaces', '@cache.field', '@module_handler', '@language_manager', '@plugin.manager.entity.field.field_type']
-  plugin.manager.field.formatter:
-    class: Drupal\field\Plugin\Type\Formatter\FormatterPluginManager
-    arguments: ['@container.namespaces', '@cache.field', '@module_handler', '@language_manager', '@plugin.manager.entity.field.field_type']
   field.info:
     class: Drupal\field\FieldInfo
-    arguments: ['@cache.field', '@config.factory', '@module_handler', '@plugin.manager.entity.field.field_type']
-  cache.field:
-    class: Drupal\Core\Cache\CacheBackendInterface
-    tags:
-      - { name: cache.bin }
-    factory_method: get
-    factory_service: cache_factory
-    arguments: [field]
+    arguments: ['@cache.field', '@config.factory', '@module_handler', '@plugin.manager.field.field_type']
+
diff --git a/core/modules/field/field.views.inc b/core/modules/field/field.views.inc
index aecc48c..6d1f488 100644
--- a/core/modules/field/field.views.inc
+++ b/core/modules/field/field.views.inc
@@ -119,7 +119,7 @@ function field_views_field_default_views_data(FieldInterface $field) {
   $data = array();
 
   // Check the field type is available.
-  if (!\Drupal::service('plugin.manager.entity.field.field_type')->getDefinition($field->getFieldType())) {
+  if (!\Drupal::service('plugin.manager.field.field_type')->getDefinition($field->getFieldType())) {
     return $data;
   }
   // Check the field has instances.
diff --git a/core/modules/field/lib/Drupal/field/Annotation/FieldFormatter.php b/core/modules/field/lib/Drupal/field/Annotation/FieldFormatter.php
deleted file mode 100644
index e688a76..0000000
--- a/core/modules/field/lib/Drupal/field/Annotation/FieldFormatter.php
+++ /dev/null
@@ -1,78 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\field\Annotation\FieldFormatter.
- */
-
-namespace Drupal\field\Annotation;
-
-use Drupal\Component\Annotation\Plugin;
-
-/**
- * Defines a FieldFormatter annotation object.
- *
- * Formatters handle the display of field values. Formatter hooks are typically
- * called by the Field Attach API field_attach_prepare_view() and
- * field_attach_view() functions.
- *
- * Additional annotation keys for formatters can be defined in
- * hook_field_formatter_info_alter().
- *
- * @Annotation
- *
- * @see \Drupal\field\Plugin\Type\Formatter\FormatterPluginManager
- * @see \Drupal\field\Plugin\Type\Formatter\FormatterInterface
- */
-class FieldFormatter extends Plugin {
-
-  /**
-   * The plugin ID.
-   *
-   * @var string
-   */
-  public $id;
-
-  /**
-   * The human-readable name of the formatter type.
-   *
-   * @ingroup plugin_translatable
-   *
-   * @var \Drupal\Core\Annotation\Translation
-   */
-  public $label;
-
-  /**
-   * A short description of the formatter type.
-   *
-   * @ingroup plugin_translatable
-   *
-   * @var \Drupal\Core\Annotation\Translation
-   */
-  public $description;
-
-  /**
-   * The name of the field formatter class.
-   *
-   * This is not provided manually, it will be added by the discovery mechanism.
-   *
-   * @var string
-   */
-  public $class;
-
-  /**
-   * An array of field types the formatter supports.
-   *
-   * @var array
-   */
-  public $field_types = array();
-
-  /**
-   * An array whose keys are the names of the settings available to the
-   * formatter type, and whose values are the default values for those settings.
-   *
-   * @var array
-   */
-  public $settings = array();
-
-}
diff --git a/core/modules/field/lib/Drupal/field/Annotation/FieldWidget.php b/core/modules/field/lib/Drupal/field/Annotation/FieldWidget.php
deleted file mode 100644
index 2c8d339..0000000
--- a/core/modules/field/lib/Drupal/field/Annotation/FieldWidget.php
+++ /dev/null
@@ -1,91 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\field\Annotation\FieldWidget.
- */
-
-namespace Drupal\field\Annotation;
-
-use Drupal\Component\Annotation\Plugin;
-
-/**
- * Defines a FieldWidget annotation object.
- *
- * Widgets handle how fields are displayed in edit forms.
- *
- * Additional annotation keys for widgets can be defined in
- * hook_field_widget_info_alter().
- *
- * @Annotation
- *
- * @see \Drupal\field\Plugin\Type\Widget\WidgetPluginManager
- * @see \Drupal\field\Plugin\Type\Widget\WidgetInterface
- */
-class FieldWidget extends Plugin {
-
-  /**
-   * The plugin ID.
-   *
-   * @var string
-   */
-  public $id;
-
-  /**
-   * The human-readable name of the widget type.
-   *
-   * @ingroup plugin_translatable
-   *
-   * @var \Drupal\Core\Annotation\Translation
-   */
-  public $label;
-
-  /**
-   * A short description of the widget type.
-   *
-   * @ingroup plugin_translatable
-   *
-   * @var \Drupal\Core\Annotation\Translation
-   */
-  public $description;
-
-  /**
-   * The name of the widget class.
-   *
-   * This is not provided manually, it will be added by the discovery mechanism.
-   *
-   * @var string
-   */
-  public $class;
-
-  /**
-   * An array of field types the widget supports.
-   *
-   * @var array
-   */
-  public $field_types = array();
-
-  /**
-   * An array whose keys are the names of the settings available to the widget
-   * type, and whose values are the default values for those settings.
-   *
-   * @var array
-   */
-  public $settings = array();
-
-  /**
-   * Does the field widget handles multiple values at once.
-   *
-   * @var bool
-   */
-  public $multiple_values = FALSE;
-
-  /**
-   * An integer to determine the weight of this widget relative to other widgets
-   * in the Field UI when selecting a widget for a given field instance.
-   *
-   * @var int optional
-   */
-  public $weight = NULL;
-
-}
diff --git a/core/modules/field/lib/Drupal/field/Entity/Field.php b/core/modules/field/lib/Drupal/field/Entity/Field.php
index 4496e16..6fb8ab7 100644
--- a/core/modules/field/lib/Drupal/field/Entity/Field.php
+++ b/core/modules/field/lib/Drupal/field/Entity/Field.php
@@ -340,7 +340,7 @@ protected function saveNew() {
     }
 
     // Check that the field type is known.
-    $field_type = \Drupal::service('plugin.manager.entity.field.field_type')->getDefinition($this->type);
+    $field_type = \Drupal::service('plugin.manager.field.field_type')->getDefinition($this->type);
     if (!$field_type) {
       throw new FieldException(format_string('Attempt to create a field of unknown type %type.', array('%type' => $this->type)));
     }
@@ -455,7 +455,7 @@ public function delete() {
   public function getSchema() {
     if (!isset($this->schema)) {
       // Get the schema from the field item class.
-      $definition = \Drupal::service('plugin.manager.entity.field.field_type')->getDefinition($this->type);
+      $definition = \Drupal::service('plugin.manager.field.field_type')->getDefinition($this->type);
       $class = $definition['class'];
       $schema = $class::schema($this);
       // Fill in default values for optional entries.
@@ -525,7 +525,7 @@ public function getFieldSettings() {
     //   maintains its own static cache. However, do some CPU and memory
     //   profiling to see if it's worth statically caching $field_type_info, or
     //   the default field and instance settings, within $this.
-    $field_type_info = \Drupal::service('plugin.manager.entity.field.field_type')->getDefinition($this->type);
+    $field_type_info = \Drupal::service('plugin.manager.field.field_type')->getDefinition($this->type);
 
     $settings = $this->settings + $field_type_info['settings'] + $field_type_info['instance_settings'];
     return $settings;
@@ -536,7 +536,7 @@ public function getFieldSettings() {
    */
   public function getFieldSetting($setting_name) {
     // @todo See getFieldSettings() about potentially statically caching this.
-    $field_type_info = \Drupal::service('plugin.manager.entity.field.field_type')->getDefinition($this->type);
+    $field_type_info = \Drupal::service('plugin.manager.field.field_type')->getDefinition($this->type);
 
     // We assume here that consecutive array_key_exists() is more efficient than
     // calling getFieldSettings() when all we need is a single setting.
diff --git a/core/modules/field/lib/Drupal/field/Entity/FieldInstance.php b/core/modules/field/lib/Drupal/field/Entity/FieldInstance.php
index dea4c95..65013c0 100644
--- a/core/modules/field/lib/Drupal/field/Entity/FieldInstance.php
+++ b/core/modules/field/lib/Drupal/field/Entity/FieldInstance.php
@@ -419,7 +419,7 @@ protected function saveUpdated() {
    * Prepares the instance definition for saving.
    */
   protected function prepareSave() {
-    $field_type_info = \Drupal::service('plugin.manager.entity.field.field_type')->getDefinition($this->field->type);
+    $field_type_info = \Drupal::service('plugin.manager.field.field_type')->getDefinition($this->field->type);
 
     // Set the default instance settings.
     $this->settings += $field_type_info['instance_settings'];
diff --git a/core/modules/field/lib/Drupal/field/FieldInfo.php b/core/modules/field/lib/Drupal/field/FieldInfo.php
index 3e4d6aa..2287e6c 100644
--- a/core/modules/field/lib/Drupal/field/FieldInfo.php
+++ b/core/modules/field/lib/Drupal/field/FieldInfo.php
@@ -9,7 +9,7 @@
 
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Config\ConfigFactory;
-use Drupal\Core\Entity\Field\FieldTypePluginManager;
+use Drupal\Core\Field\FieldTypePluginManager;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\field\FieldInterface;
 use Drupal\field\FieldInstanceInterface;
@@ -50,7 +50,7 @@ class FieldInfo {
   /**
    * The field type manager to define field.
    *
-   * @var \Drupal\Core\Entity\Field\FieldTypePluginManager
+   * @var \Drupal\Core\Field\FieldTypePluginManager
    */
   protected $fieldTypeManager;
 
@@ -133,7 +133,7 @@ class FieldInfo {
    *   The configuration factory object to use.
    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
    *   The module handler class to use for invoking hooks.
-   * @param \Drupal\Core\Entity\Field\FieldTypePluginManager $field_type_manager
+   * @param \Drupal\Core\Field\FieldTypePluginManager $field_type_manager
    *   The 'field type' plugin manager.
    */
   public function __construct(CacheBackendInterface $cache_backend, ConfigFactory $config, ModuleHandlerInterface $module_handler, FieldTypePluginManager $field_type_manager) {
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigEntityReferenceItemBase.php b/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigEntityReferenceItemBase.php
index b0e436f..7fcb046 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigEntityReferenceItemBase.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigEntityReferenceItemBase.php
@@ -80,7 +80,7 @@ public function getPropertyDefinitions() {
    * since we cannot extend it.
    */
   public static function schema(FieldInterface $field) {
-    $definition = \Drupal::service('plugin.manager.entity.field.field_type')->getDefinition($field->type);
+    $definition = \Drupal::service('plugin.manager.field.field_type')->getDefinition($field->type);
     $module = $definition['provider'];
     module_load_install($module);
     $callback = "{$module}_field_schema";
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigFieldItemList.php b/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigFieldItemList.php
index eca3358..47f0d57 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigFieldItemList.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigFieldItemList.php
@@ -132,7 +132,7 @@ public function defaultValuesFormSubmit(array $element, array &$form, array &$fo
    * @param array $form_state
    *   The form state of the (entire) configuration form.
    *
-   * @return \Drupal\field\Plugin\Type\Widget\WidgetInterface
+   * @return \Drupal\Core\Field\WidgetInterface
    *   A Widget object.
    */
   protected function defaultValueWidget(array &$form_state) {
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterBase.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterBase.php
deleted file mode 100644
index 791e7c2..0000000
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterBase.php
+++ /dev/null
@@ -1,161 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\field\Plugin\Type\Formatter\FormatterBase.
- */
-
-namespace Drupal\field\Plugin\Type\Formatter;
-
-use Drupal\Core\Entity\Field\FieldDefinitionInterface;
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\field\Plugin\PluginSettingsBase;
-
-/**
- * Base class for 'Field formatter' plugin implementations.
- */
-abstract class FormatterBase extends PluginSettingsBase implements FormatterInterface {
-
-  /**
-   * The field definition.
-   *
-   * @var \Drupal\Core\Entity\Field\FieldDefinitionInterface
-   */
-  protected $fieldDefinition;
-
-  /**
-   * The formatter settings.
-   *
-   * @var array
-   */
-  protected $settings;
-
-  /**
-   * The label display setting.
-   *
-   * @var string
-   */
-  protected $label;
-
-  /**
-   * The view mode.
-   *
-   * @var string
-   */
-  protected $viewMode;
-
-  /**
-   * Constructs a FormatterBase object.
-   *
-   * @param string $plugin_id
-   *   The plugin_id for the formatter.
-   * @param array $plugin_definition
-   *   The plugin implementation definition.
-   * @param \Drupal\Core\Entity\Field\FieldDefinitionInterface $field_definition
-   *   The definition of the field to which the formatter is associated.
-   * @param array $settings
-   *   The formatter settings.
-   * @param string $label
-   *   The formatter label display setting.
-   * @param string $view_mode
-   *   The view mode.
-   */
-  public function __construct($plugin_id, array $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode) {
-    parent::__construct(array(), $plugin_id, $plugin_definition);
-
-    $this->fieldDefinition = $field_definition;
-    $this->settings = $settings;
-    $this->label = $label;
-    $this->viewMode = $view_mode;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function view(FieldItemListInterface $items) {
-    $addition = array();
-
-    $elements = $this->viewElements($items);
-    if ($elements) {
-      $entity = $items->getEntity();
-      $entity_type = $entity->entityType();
-      $field_name = $this->fieldDefinition->getFieldName();
-      $info = array(
-        '#theme' => 'field',
-        '#title' => $this->fieldDefinition->getFieldLabel(),
-        '#access' => $items->access('view'),
-        '#label_display' => $this->label,
-        '#view_mode' => $this->viewMode,
-        '#language' => $items->getLangcode(),
-        '#field_name' => $field_name,
-        '#field_type' => $this->fieldDefinition->getFieldType(),
-        '#field_translatable' => $this->fieldDefinition->isFieldTranslatable(),
-        '#entity_type' => $entity_type,
-        '#bundle' => $entity->bundle(),
-        '#object' => $entity,
-        '#items' => $items->getValue(TRUE),
-        '#formatter' => $this->getPluginId(),
-        '#cache' => array('tags' => array())
-      );
-
-      // Gather cache tags from reference fields.
-      foreach ($items as $item) {
-        if (isset($item->format)) {
-          $info['#cache']['tags']['filter_format'] = $item->format;
-        }
-
-        if (isset($item->entity)) {
-          $info['#cache']['tags'][$item->entity->entityType()][] = $item->entity->id();
-          $info['#cache']['tags'][$item->entity->entityType() . '_view'] = TRUE;
-        }
-      }
-
-      $addition[$field_name] = array_merge($info, $elements);
-    }
-
-    return $addition;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsForm(array $form, array &$form_state) {
-    return array();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    return array();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function prepareView(array $entities_items) { }
-
-  /**
-   * Returns the array of field settings.
-   *
-   * @return array
-   *   The array of settings.
-   */
-  protected function getFieldSettings() {
-    return $this->fieldDefinition->getFieldSettings();
-  }
-
-  /**
-   * Returns the value of a field setting.
-   *
-   * @param string $setting_name
-   *   The setting name.
-   *
-   * @return mixed
-   *   The setting value.
-   */
-  protected function getFieldSetting($setting_name) {
-    return $this->fieldDefinition->getFieldSetting($setting_name);
-  }
-
-}
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterInterface.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterInterface.php
deleted file mode 100644
index e48828d..0000000
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterInterface.php
+++ /dev/null
@@ -1,91 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\field\Plugin\Type\Formatter\FormatterInterface.
- */
-
-namespace Drupal\field\Plugin\Type\Formatter;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\field\Plugin\PluginSettingsInterface;
-
-/**
- * Interface definition for field widget plugins.
- */
-interface FormatterInterface extends PluginSettingsInterface {
-
-  /**
-   * Returns a form to configure settings for the formatter.
-   *
-   * Invoked from \Drupal\field_ui\Form\FieldInstanceEditForm to allow
-   * administrators to configure the formatter. The field_ui module takes care
-   * of handling submitted form values.
-   *
-   * @param array $form
-   *   The form where the settings form is being included in.
-   * @param array $form_state
-   *   An associative array containing the current state of the form.
-   *
-   * @return array
-   *   The form elements for the formatter settings.
-   */
-  public function settingsForm(array $form, array &$form_state);
-
-  /**
-   * Returns a short summary for the current formatter settings.
-   *
-   * If an empty result is returned, a UI can still be provided to display
-   * a settings form in case the formatter has configurable settings.
-   *
-   * @return array()
-   *   A short summary of the formatter settings.
-   */
-  public function settingsSummary();
-
-  /**
-   * Allows formatters to load information for field values being displayed.
-   *
-   * This should be used when a formatter needs to load additional information
-   * from the database in order to render a field, for example a reference
-   * field that displays properties of the referenced entities such as name or
-   * type.
-   *
-   * This method operates on multiple entities. The $entities and $items
-   * parameters are arrays keyed by entity ID. For performance reasons,
-   * information for all involved entities should be loaded in a single query
-   * where possible.
-   *
-   * Changes or additions to field values are done by alterings the $items
-   * parameter by reference.
-   *
-   * @param array $entities_items
-   *   Array of field values (Drupal\Core\Entity\Field\FieldItemListInterface),
-   *   keyed by entity ID.
-   */
-  public function prepareView(array $entities_items);
-
-  /**
-   * Builds a renderable array for one field on one entity instance.
-   *
-   * @param \Drupal\Core\Entity\Field\FieldItemListInterface $items
-   *   The field values to be rendered.
-   *
-   * @return array
-   *   A renderable array for a themed field with its label and all its values.
-   */
-  public function view(FieldItemListInterface $items);
-
-  /**
-   * Builds a renderable array for a field value.
-   *
-   * @param \Drupal\Core\Entity\Field\FieldItemListInterface $items
-   *   The field values to be rendered.
-   *
-   * @return array
-   *   A renderable array for $items, as an array of child elements keyed by
-   *   numeric indexes starting from 0.
-   */
-  public function viewElements(FieldItemListInterface $items);
-
-}
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php
deleted file mode 100644
index 955bea7..0000000
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php
+++ /dev/null
@@ -1,204 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\field\Plugin\Type\Formatter\FormatterPluginManager..
- */
-
-namespace Drupal\field\Plugin\Type\Formatter;
-
-use Drupal\Component\Plugin\Factory\DefaultFactory;
-use Drupal\Core\Cache\CacheBackendInterface;
-use Drupal\Core\Entity\Field\FieldTypePluginManager;
-use Drupal\Core\Extension\ModuleHandlerInterface;
-use Drupal\Core\Language\LanguageManager;
-use Drupal\Core\Plugin\DefaultPluginManager;
-
-/**
- * Plugin type manager for field formatters.
- */
-class FormatterPluginManager extends DefaultPluginManager {
-
-  /**
-   * An array of formatter options for each field type.
-   *
-   * @var array
-   */
-  protected $formatterOptions;
-
-  /**
-   * The field type manager to define field.
-   *
-   * @var \Drupal\Core\Entity\Field\FieldTypePluginManager
-   */
-  protected $fieldTypeManager;
-
-  /**
-   * Constructs a FormatterPluginManager object.
-   *
-   * @param \Traversable $namespaces
-   *   An object that implements \Traversable which contains the root paths
-   *   keyed by the corresponding namespace to look for plugin implementations.
-   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
-   *   Cache backend instance to use.
-   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
-   *   The module handler.
-   * @param \Drupal\Core\Language\LanguageManager $language_manager
-   *   The language manager.
-   * @param \Drupal\Core\Entity\Field\FieldTypePluginManager $field_type_manager
-   *   The 'field type' plugin manager.
-   */
-  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, LanguageManager $language_manager, FieldTypePluginManager $field_type_manager) {
-
-    parent::__construct('Plugin/field/formatter', $namespaces, 'Drupal\field\Annotation\FieldFormatter');
-
-    $this->setCacheBackend($cache_backend, $language_manager, 'field_formatter_types_plugins');
-    $this->alterInfo($module_handler, 'field_formatter_info');
-    $this->fieldTypeManager = $field_type_manager;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function createInstance($plugin_id, array $configuration) {
-    $plugin_definition = $this->getDefinition($plugin_id);
-    $plugin_class = DefaultFactory::getPluginClass($plugin_id, $plugin_definition);
-
-    // @todo This is copied from \Drupal\Core\Plugin\Factory\ContainerFactory.
-    //   Find a way to restore sanity to
-    //   \Drupal\field\Plugin\Type\Formatter\FormatterBase::__construct().
-    // If the plugin provides a factory method, pass the container to it.
-    if (is_subclass_of($plugin_class, 'Drupal\Core\Plugin\ContainerFactoryPluginInterface')) {
-      return $plugin_class::create(\Drupal::getContainer(), $configuration, $plugin_id, $plugin_definition);
-    }
-
-    return new $plugin_class($plugin_id, $plugin_definition, $configuration['field_definition'], $configuration['settings'], $configuration['label'], $configuration['view_mode']);
-  }
-
-  /**
-   * Overrides PluginManagerBase::getInstance().
-   *
-   * @param array $options
-   *   An array with the following key/value pairs:
-   *   - field_definition: (FieldDefinitionInterface) The field definition.
-   *   - view_mode: (string) The view mode.
-   *   - prepare: (bool, optional) Whether default values should get merged in
-   *     the 'configuration' array. Defaults to TRUE.
-   *   - configuration: (array) the configuration for the formatter. The
-   *     following key value pairs are allowed, and are all optional if
-   *     'prepare' is TRUE:
-   *     - label: (string) Position of the label. The default 'field' theme
-   *       implementation supports the values 'inline', 'above' and 'hidden'.
-   *       Defaults to 'above'.
-   *     - type: (string) The formatter to use. Defaults to the
-   *       'default_formatter' for the field type, The default formatter will
-   *       also be used if the requested formatter is not available.
-   *     - settings: (array) Settings specific to the formatter. Each setting
-   *       defaults to the default value specified in the formatter definition.
-   *
-   * @return \Drupal\field\Plugin\Type\Formatter\FormatterInterface
-   *   A formatter object.
-   */
-  public function getInstance(array $options) {
-    $configuration = $options['configuration'];
-    $field_definition = $options['field_definition'];
-    $field_type = $field_definition->getFieldType();
-
-    // Fill in default configuration if needed.
-    if (!isset($options['prepare']) || $options['prepare'] == TRUE) {
-      $configuration = $this->prepareConfiguration($field_type, $configuration);
-    }
-
-    $plugin_id = $configuration['type'];
-
-    // Switch back to default formatter if either:
-    // - $type_info doesn't exist (the widget type is unknown),
-    // - the field type is not allowed for the widget.
-    $definition = $this->getDefinition($configuration['type']);
-    if (!isset($definition['class']) || !in_array($field_type, $definition['field_types'])) {
-      // Grab the default widget for the field type.
-      $field_type_definition = $this->fieldTypeManager->getDefinition($field_type);
-      $plugin_id = $field_type_definition['default_formatter'];
-    }
-
-    $configuration += array(
-      'field_definition' => $field_definition,
-      'view_mode' => $options['view_mode'],
-    );
-    return $this->createInstance($plugin_id, $configuration);
-  }
-
-  /**
-   * Merges default values for formatter configuration.
-   *
-   * @param string $field_type
-   *   The field type.
-   * @param array $properties
-   *   An array of formatter configuration.
-   *
-   * @return array
-   *   The display properties with defaults added.
-   */
-  public function prepareConfiguration($field_type, array $configuration) {
-    // Fill in defaults for missing properties.
-    $configuration += array(
-      'label' => 'above',
-      'settings' => array(),
-    );
-    // If no formatter is specified, use the default formatter.
-    if (!isset($configuration['type'])) {
-      $field_type = $this->fieldTypeManager->getDefinition($field_type);
-      $configuration['type'] = $field_type['default_formatter'];
-    }
-    // Fill in default settings values for the formatter.
-    $configuration['settings'] += $this->getDefaultSettings($configuration['type']);
-
-    return $configuration;
-  }
-
-  /**
-   * Returns an array of formatter options for a field type.
-   *
-   * @param string|null $field_type
-   *   (optional) The name of a field type, or NULL to retrieve all formatters.
-   *
-   * @return array
-   *   If no field type is provided, returns a nested array of all formatters,
-   *   keyed by field type.
-   */
-  public function getOptions($field_type = NULL) {
-    if (!isset($this->formatterOptions)) {
-      $field_types = $this->fieldTypeManager->getDefinitions();
-      $options = array();
-      foreach ($this->getDefinitions() as $name => $formatter) {
-        foreach ($formatter['field_types'] as $formatter_field_type) {
-          // Check that the field type exists.
-          if (isset($field_types[$formatter_field_type])) {
-            $options[$formatter_field_type][$name] = $formatter['label'];
-          }
-        }
-      }
-      $this->formatterOptions = $options;
-    }
-    if ($field_type) {
-      return !empty($this->formatterOptions[$field_type]) ? $this->formatterOptions[$field_type] : array();
-    }
-    return $this->formatterOptions;
-  }
-
-  /**
-   * Returns the default settings of a field formatter.
-   *
-   * @param string $type
-   *   A field formatter type name.
-   *
-   * @return array
-   *   The formatter type's default settings, as provided by the plugin
-   *   definition, or an empty array if type or settings are undefined.
-   */
-  public function getDefaultSettings($type) {
-    $info = $this->getDefinition($type);
-    return isset($info['settings']) ? $info['settings'] : array();
-  }
-
-}
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php
deleted file mode 100644
index 564ec20..0000000
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php
+++ /dev/null
@@ -1,451 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\field\Plugin\Type\Widget\WidgetBase.
- */
-
-namespace Drupal\field\Plugin\Type\Widget;
-
-use Drupal\Component\Utility\NestedArray;
-use Drupal\Core\Entity\Field\FieldDefinitionInterface;
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\field\FieldInstanceInterface;
-use Drupal\field\Plugin\PluginSettingsBase;
-use Symfony\Component\Validator\ConstraintViolationInterface;
-
-/**
- * Base class for 'Field widget' plugin implementations.
- */
-abstract class WidgetBase extends PluginSettingsBase implements WidgetInterface {
-
-  /**
-   * The field definition.
-   *
-   * @var \Drupal\Core\Entity\Field\FieldDefinitionInterface
-   */
-  protected $fieldDefinition;
-
-  /**
-   * The widget settings.
-   *
-   * @var array
-   */
-  protected $settings;
-
-  /**
-   * Constructs a WidgetBase object.
-   *
-   * @param array $plugin_id
-   *   The plugin_id for the widget.
-   * @param array $plugin_definition
-   *   The plugin implementation definition.
-   * @param \Drupal\Core\Entity\Field\FieldDefinitionInterface $field_definition
-   *   The definition of the field to which the widget is associated.
-   * @param array $settings
-   *   The widget settings.
-   */
-  public function __construct($plugin_id, array $plugin_definition, FieldDefinitionInterface $field_definition, array $settings) {
-    parent::__construct(array(), $plugin_id, $plugin_definition);
-    $this->fieldDefinition = $field_definition;
-    $this->settings = $settings;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function form(FieldItemListInterface $items, array &$form, array &$form_state, $get_delta = NULL) {
-    $field_name = $this->fieldDefinition->getFieldName();
-    $parents = $form['#parents'];
-
-    // Store field information in $form_state.
-    if (!field_form_get_state($parents, $field_name, $form_state)) {
-      $field_state = array(
-        'items_count' => count($items),
-        'array_parents' => array(),
-        'constraint_violations' => array(),
-      );
-      field_form_set_state($parents, $field_name, $form_state, $field_state);
-    }
-
-    // Collect widget elements.
-    $elements = array();
-
-    // If the widget is handling multiple values (e.g Options), or if we are
-    // displaying an individual element, just get a single form element and make
-    // it the $delta value.
-    $definition = $this->getPluginDefinition();
-    if (isset($get_delta) || $definition['multiple_values']) {
-      $delta = isset($get_delta) ? $get_delta : 0;
-      $element = array(
-        '#title' => check_plain($this->fieldDefinition->getFieldLabel()),
-        '#description' => field_filter_xss(\Drupal::token()->replace($this->fieldDefinition->getFieldDescription())),
-      );
-      $element = $this->formSingleElement($items, $delta, $element, $form, $form_state);
-
-      if ($element) {
-        if (isset($get_delta)) {
-          // If we are processing a specific delta value for a field where the
-          // field module handles multiples, set the delta in the result.
-          $elements[$delta] = $element;
-        }
-        else {
-          // For fields that handle their own processing, we cannot make
-          // assumptions about how the field is structured, just merge in the
-          // returned element.
-          $elements = $element;
-        }
-      }
-    }
-    // If the widget does not handle multiple values itself, (and we are not
-    // displaying an individual element), process the multiple value form.
-    else {
-      $elements = $this->formMultipleElements($items, $form, $form_state);
-    }
-
-    // Populate the 'array_parents' information in $form_state['field'] after
-    // the form is built, so that we catch changes in the form structure performed
-    // in alter() hooks.
-    $elements['#after_build'][] = 'field_form_element_after_build';
-    $elements['#field_name'] = $field_name;
-    $elements['#field_parents'] = $parents;
-    // Enforce the structure of submitted values.
-    $elements['#parents'] = array_merge($parents, array($field_name));
-    // Most widgets need their internal structure preserved in submitted values.
-    $elements += array('#tree' => TRUE);
-
-    $return = array(
-      $field_name => array(
-        // Aid in theming of widgets by rendering a classified container.
-        '#type' => 'container',
-        // Assign a different parent, to keep the main id for the widget itself.
-        '#parents' => array_merge($parents, array($field_name . '_wrapper')),
-        '#attributes' => array(
-          'class' => array(
-            'field-type-' . drupal_html_class($this->fieldDefinition->getFieldType()),
-            'field-name-' . drupal_html_class($field_name),
-            'field-widget-' . drupal_html_class($this->getPluginId()),
-          ),
-        ),
-        '#access' => $items->access('edit'),
-        'widget' => $elements,
-      ),
-    );
-
-    return $return;
-  }
-
-  /**
-   * Special handling to create form elements for multiple values.
-   *
-   * Handles generic features for multiple fields:
-   * - number of widgets
-   * - AHAH-'add more' button
-   * - table display and drag-n-drop value reordering
-   */
-  protected function formMultipleElements(FieldItemListInterface $items, array &$form, array &$form_state) {
-    $field_name = $this->fieldDefinition->getFieldName();
-    $cardinality = $this->fieldDefinition->getFieldCardinality();
-    $parents = $form['#parents'];
-
-    // Determine the number of widgets to display.
-    switch ($cardinality) {
-      case FIELD_CARDINALITY_UNLIMITED:
-        $field_state = field_form_get_state($parents, $field_name, $form_state);
-        $max = $field_state['items_count'];
-        $is_multiple = TRUE;
-        break;
-
-      default:
-        $max = $cardinality - 1;
-        $is_multiple = ($cardinality > 1);
-        break;
-    }
-
-    $id_prefix = implode('-', array_merge($parents, array($field_name)));
-    $wrapper_id = drupal_html_id($id_prefix . '-add-more-wrapper');
-
-    $title = check_plain($this->fieldDefinition->getFieldLabel());
-    $description = field_filter_xss(\Drupal::token()->replace($this->fieldDefinition->getFieldDescription()));
-
-    $elements = array();
-
-    for ($delta = 0; $delta <= $max; $delta++) {
-      // For multiple fields, title and description are handled by the wrapping
-      // table.
-      $element = array(
-        '#title' => $is_multiple ? '' : $title,
-        '#description' => $is_multiple ? '' : $description,
-      );
-      $element = $this->formSingleElement($items, $delta, $element, $form, $form_state);
-
-      if ($element) {
-        // Input field for the delta (drag-n-drop reordering).
-        if ($is_multiple) {
-          // We name the element '_weight' to avoid clashing with elements
-          // defined by widget.
-          $element['_weight'] = array(
-            '#type' => 'weight',
-            '#title' => t('Weight for row @number', array('@number' => $delta + 1)),
-            '#title_display' => 'invisible',
-            // Note: this 'delta' is the FAPI #type 'weight' element's property.
-            '#delta' => $max,
-            '#default_value' => $items[$delta]->_weight ?: $delta,
-            '#weight' => 100,
-          );
-        }
-
-        $elements[$delta] = $element;
-      }
-    }
-
-    if ($elements) {
-      $elements += array(
-        '#theme' => 'field_multiple_value_form',
-        '#field_name' => $field_name,
-        '#cardinality' => $cardinality,
-        '#required' => $this->fieldDefinition->isFieldRequired(),
-        '#title' => $title,
-        '#description' => $description,
-        '#prefix' => '<div id="' . $wrapper_id . '">',
-        '#suffix' => '</div>',
-        '#max_delta' => $max,
-      );
-
-      // Add 'add more' button, if not working with a programmed form.
-      if ($cardinality == FIELD_CARDINALITY_UNLIMITED && empty($form_state['programmed'])) {
-        $elements['add_more'] = array(
-          '#type' => 'submit',
-          '#name' => strtr($id_prefix, '-', '_') . '_add_more',
-          '#value' => t('Add another item'),
-          '#attributes' => array('class' => array('field-add-more-submit')),
-          '#limit_validation_errors' => array(array_merge($parents, array($field_name))),
-          '#submit' => array('field_add_more_submit'),
-          '#ajax' => array(
-              'callback' => 'field_add_more_js',
-              'wrapper' => $wrapper_id,
-              'effect' => 'fade',
-          ),
-        );
-      }
-    }
-
-    return $elements;
-  }
-
-  /**
-   * Generates the form element for a single copy of the widget.
-   */
-  protected function formSingleElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
-    $entity = $items->getEntity();
-
-    $element += array(
-      '#entity_type' => $entity->entityType(),
-      '#bundle' => $entity->bundle(),
-      '#entity' => $entity,
-      '#field_name' => $this->fieldDefinition->getFieldName(),
-      '#language' => $items->getLangcode(),
-      '#field_parents' => $form['#parents'],
-      // Only the first widget should be required.
-      '#required' => $delta == 0 && $this->fieldDefinition->isFieldRequired(),
-      '#delta' => $delta,
-      '#weight' => $delta,
-    );
-
-    $element = $this->formElement($items, $delta, $element, $form, $form_state);
-
-    if ($element) {
-      // Allow modules to alter the field widget form element.
-      $context = array(
-        'form' => $form,
-        'widget' => $this,
-        'items' => $items,
-        'delta' => $delta,
-        'default' => !empty($entity->field_ui_default_value),
-      );
-      drupal_alter(array('field_widget_form', 'field_widget_' . $this->getPluginId() . '_form'), $element, $form_state, $context);
-    }
-
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function extractFormValues(FieldItemListInterface $items, array $form, array &$form_state) {
-    $field_name = $this->fieldDefinition->getFieldName();
-
-    // Extract the values from $form_state['values'].
-    $path = array_merge($form['#parents'], array($field_name));
-    $key_exists = NULL;
-    $values = NestedArray::getValue($form_state['values'], $path, $key_exists);
-
-    if ($key_exists) {
-      // Remove the 'value' of the 'add more' button.
-      unset($values['add_more']);
-
-      // Let the widget turn the submitted values into actual field values.
-      // Make sure the '_weight' entries are persisted in the process.
-      $weights = array();
-      // Check that $values[0] is an array, because if it's a string, then in
-      // PHP 5.3, ['_weight'] returns the first character.
-      if (isset($values[0]) && is_array($values[0]) && isset($values[0]['_weight'])) {
-        foreach ($values as $delta => $value) {
-          $weights[$delta] = $value['_weight'];
-        }
-      }
-      $items->setValue($this->massageFormValues($values, $form, $form_state));
-
-      foreach ($items as $delta => $item) {
-        // Put back the weight.
-        if (isset($weights[$delta])) {
-          $item->_weight = $weights[$delta];
-        }
-        // The tasks below are going to reshuffle deltas. Keep track of the
-        // original deltas for correct reporting of errors in flagErrors().
-        $item->_original_delta = $delta;
-      }
-
-      // Account for drag-n-drop reordering.
-      $this->sortItems($items);
-
-      // Remove empty values.
-      $items->filterEmptyValues();
-
-      // Put delta mapping in $form_state, so that flagErrors() can use it.
-      $field_state = field_form_get_state($form['#parents'], $field_name, $form_state);
-      foreach ($items as $delta => $item) {
-        $field_state['original_deltas'][$delta] = $item->_original_delta;
-        unset($item->_original_delta);
-      }
-      field_form_set_state($form['#parents'], $field_name, $form_state, $field_state);
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function flagErrors(FieldItemListInterface $items, array $form, array &$form_state) {
-    $field_name = $this->fieldDefinition->getFieldName();
-
-    $field_state = field_form_get_state($form['#parents'], $field_name, $form_state);
-
-    if (!empty($field_state['constraint_violations'])) {
-      // Locate the correct element in the the form.
-      $element = NestedArray::getValue($form_state['complete_form'], $field_state['array_parents']);
-
-      // Only set errors if the element is accessible.
-      if (!isset($element['#access']) || $element['#access']) {
-        $definition = $this->getPluginDefinition();
-        $is_multiple = $definition['multiple_values'];
-
-        $violations_by_delta = array();
-        foreach ($field_state['constraint_violations'] as $violation) {
-          // Separate violations by delta.
-          $property_path = explode('.', $violation->getPropertyPath());
-          $delta = array_shift($property_path);
-          $violation->arrayPropertyPath = $property_path;
-          $violations_by_delta[$delta][] = $violation;
-        }
-
-        foreach ($violations_by_delta as $delta => $delta_violations) {
-          // For a multiple-value widget, pass all errors to the main widget.
-          // For single-value widgets, pass errors by delta.
-          if ($is_multiple) {
-            $delta_element = $element;
-          }
-          else {
-            $original_delta = $field_state['original_deltas'][$delta];
-            $delta_element = $element[$original_delta];
-          }
-          foreach ($delta_violations as $violation) {
-            // @todo: Pass $violation->arrayPropertyPath as property path.
-            $error_element = $this->errorElement($delta_element, $violation, $form, $form_state);
-            if ($error_element !== FALSE) {
-              form_error($error_element, $violation->getMessage());
-            }
-          }
-        }
-        // Reinitialize the errors list for the next submit.
-        $field_state['constraint_violations'] = array();
-        field_form_set_state($form['#parents'], $field_name, $form_state, $field_state);
-      }
-    }
-  }
-
-  /**
-   * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::settingsForm().
-   */
-  public function settingsForm(array $form, array &$form_state) {
-    return array();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    return array();
-  }
-
-  /**
-   * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::errorElement().
-   */
-  public function errorElement(array $element, ConstraintViolationInterface $error, array $form, array &$form_state) {
-    return $element;
-  }
-
-  /**
-   * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::massageFormValues()
-   */
-  public function massageFormValues(array $values, array $form, array &$form_state) {
-    return $values;
-  }
-
-  /**
-   * Sorts submitted field values according to drag-n-drop reordering.
-   *
-   * @param \Drupal\Core\Entity\Field\FieldItemListInterface $items
-   *   The field values.
-   */
-  protected function sortItems(FieldItemListInterface $items) {
-    $cardinality = $this->fieldDefinition->getFieldCardinality();
-    $is_multiple = ($cardinality == FIELD_CARDINALITY_UNLIMITED) || ($cardinality > 1);
-    if ($is_multiple && isset($items[0]->_weight)) {
-      $itemValues = $items->getValue(TRUE);
-      usort($itemValues, function ($a, $b) {
-        $a_weight = (is_array($a) ? $a['_weight'] : 0);
-        $b_weight = (is_array($b) ? $b['_weight'] : 0);
-        return $a_weight - $b_weight;
-      });
-      $items->setValue($itemValues);
-      // Remove the '_weight' entries.
-      foreach ($items as $item) {
-        unset($item->_weight);
-      }
-    }
-  }
-
-  /**
-   * Returns the array of field settings.
-   *
-   * @return array
-   *   The array of settings.
-   */
-  protected function getFieldSettings() {
-    return $this->fieldDefinition->getFieldSettings();
-  }
-
-  /**
-   * Returns the value of a field setting.
-   *
-   * @param string $setting_name
-   *   The setting name.
-   *
-   * @return mixed
-   *   The setting value.
-   */
-  protected function getFieldSetting($setting_name) {
-    return $this->fieldDefinition->getFieldSetting($setting_name);
-  }
-
-}
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBaseInterface.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBaseInterface.php
deleted file mode 100644
index 110e182..0000000
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBaseInterface.php
+++ /dev/null
@@ -1,73 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\field\Plugin\Type\Widget\WidgetBaseInterface.
- */
-
-namespace Drupal\field\Plugin\Type\Widget;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\field\Plugin\PluginSettingsInterface;
-
-/**
- * Base interface definition for "Field widget" plugins.
- *
- * This interface details base wrapping methods that most widget implementations
- * will want to directly inherit from Drupal\field\Plugin\Type\Widget\WidgetBase.
- * See Drupal\field\Plugin\Type\Widget\WidgetInterface for methods that will more
- * likely be overriden.
- */
-interface WidgetBaseInterface extends PluginSettingsInterface {
-
-  /**
-   * Creates a form element for a field.
-   *
-   * If the entity associated with the form is new (i.e., $entity->isNew() is
-   * TRUE), the 'default value', if any, is pre-populated. Also allows other
-   * modules to alter the form element by implementing their own hooks.
-   *
-   * @param \Drupal\Core\Entity\Field\FieldItemListInterface $items
-   *   An array of the field values. When creating a new entity this may be NULL
-   *   or an empty array to use default values.
-   * @param array $form
-   *   An array representing the form that the editing element will be attached
-   *   to.
-   * @param array $form_state
-   *   An array containing the current state of the form.
-   * @param int $get_delta
-   *   Used to get only a specific delta value of a multiple value field.
-   *
-   * @return array
-   *   The form element array created for this field.
-   */
-  public function form(FieldItemListInterface $items, array &$form, array &$form_state, $get_delta = NULL);
-
-  /**
-   * Extracts field values from submitted form values.
-   *
-   * @param \Drupal\Core\Entity\Field\FieldItemListInterface $items
-   *   The field values. This parameter is altered by reference to receive the
-   *   incoming form values.
-   * @param array $form
-   *   The form structure where field elements are attached to. This might be a
-   *   full form structure, or a sub-element of a larger form.
-   * @param array $form_state
-   *   The form state.
-   */
-  public function extractFormValues(FieldItemListInterface $items, array $form, array &$form_state);
-
-  /**
-   * Reports field-level validation errors against actual form elements.
-   *
-   * @param \Drupal\Core\Entity\Field\FieldItemListInterface $items
-   *   The field values.
-   * @param array $form
-   *   The form structure where field elements are attached to. This might be a
-   *   full form structure, or a sub-element of a larger form.
-   * @param array $form_state
-   *   The form state.
-   */
-  public function flagErrors(FieldItemListInterface $items, array $form, array &$form_state);
-
-}
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetFactory.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetFactory.php
deleted file mode 100644
index 4b7cb6b..0000000
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetFactory.php
+++ /dev/null
@@ -1,25 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\field\Plugin\WidgetFactory.
- */
-
-namespace Drupal\field\Plugin\Type\Widget;
-
-use Drupal\Component\Plugin\Factory\DefaultFactory;
-
-/**
- * Factory class for the Widget plugin type.
- */
-class WidgetFactory extends DefaultFactory {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function createInstance($plugin_id, array $configuration) {
-    $plugin_definition = $this->discovery->getDefinition($plugin_id);
-    $plugin_class = static::getPluginClass($plugin_id, $plugin_definition);
-    return new $plugin_class($plugin_id, $plugin_definition, $configuration['field_definition'], $configuration['settings']);
-  }
-}
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetInterface.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetInterface.php
deleted file mode 100644
index ddab487..0000000
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetInterface.php
+++ /dev/null
@@ -1,159 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\field\Plugin\Type\Widget\WidgetInterface.
- */
-
-namespace Drupal\field\Plugin\Type\Widget;
-
-use Symfony\Component\Validator\ConstraintViolationInterface;
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-
-/**
- * Interface definition for field widget plugins.
- *
- * This interface details the methods that most plugin implementations will want
- * to override. See Drupal\field\Plugin\Type\Widget\WidgetBaseInterface for base
- * wrapping methods that should most likely be inherited directly from
- * Drupal\field\Plugin\Type\Widget\WidgetBase..
- */
-interface WidgetInterface extends WidgetBaseInterface {
-
-  /**
-   * Returns a form to configure settings for the widget.
-   *
-   * Invoked from \Drupal\field_ui\Form\FieldInstanceEditForm to allow
-   * administrators to configure the widget. The field_ui module takes care of
-   * handling submitted form values.
-   *
-   * @param array $form
-   *   The form where the settings form is being included in.
-   * @param array $form_state
-   *   An associative array containing the current state of the form.
-   *
-   * @return array
-   *   The form definition for the widget settings.
-   */
-  public function settingsForm(array $form, array &$form_state);
-
-  /**
-   * Returns a short summary for the current widget settings.
-   *
-   * If an empty result is returned, a UI can still be provided to display
-   * a settings form in case the widget has configurable settings.
-   *
-   * @return array
-   *   A short summary of the widget settings.
-   */
-  public function settingsSummary();
-
-  /**
-   * Returns the form for a single field widget.
-   *
-   * Field widget form elements should be based on the passed-in $element, which
-   * contains the base form element properties derived from the field
-   * configuration.
-   *
-   * The BaseWidget methods will set the weight, field name and delta values for
-   * each form element. If there are multiple values for this field, the
-   * formElement() method will be called as many times as needed.
-   *
-   * Other modules may alter the form element provided by this function using
-   * hook_field_widget_form_alter() or
-   * hook_field_widget_WIDGET_TYPE_form_alter().
-   *
-   * The FAPI element callbacks (such as #process, #element_validate,
-   * #value_callback...) used by the widget do not have access to the original
-   * $field_definition passed to the widget's constructor. Therefore, if any
-   * information is needed from that definition by those callbacks, the widget
-   * implementing this method, or a hook_field_widget[_WIDGET_TYPE]_form_alter()
-   * implementation, must extract the needed properties from the field
-   * definition and set them as ad-hoc $element['#custom'] properties, for later
-   * use by its element callbacks.
-   *
-   * @param \Drupal\Core\Entity\Field\FieldItemListInterface $items
-   *   Array of default values for this field.
-   * @param int $delta
-   *   The order of this item in the array of subelements (0, 1, 2, etc).
-   * @param array $element
-   *   A form element array containing basic properties for the widget:
-   *   - #entity_type: The name of the entity the field is attached to.
-   *   - #bundle: The name of the field bundle the field is contained in.
-   *   - #entity: The entity the field is attached to.
-   *   - #field_name: The name of the field.
-   *   - #language: The language the field is being edited in.
-   *   - #field_parents: The 'parents' space for the field in the form. Most
-   *       widgets can simply overlook this property. This identifies the
-   *       location where the field values are placed within
-   *       $form_state['values'], and is used to access processing information
-   *       for the field through the field_form_get_state() and
-   *       field_form_set_state() functions.
-   *   - #title: The sanitized element label for the field instance, ready for
-   *     output.
-   *   - #description: The sanitized element description for the field instance,
-   *     ready for output.
-   *   - #required: A Boolean indicating whether the element value is required;
-   *     for required multiple value fields, only the first widget's values are
-   *     required.
-   *   - #delta: The order of this item in the array of subelements; see $delta
-   *     above.
-   * @param string $form
-   *   The form structure where widgets are being attached to. This might be a
-   *   full form structure, or a sub-element of a larger form.
-   * @param string $form_state
-   *   An associative array containing the current state of the form.
-   *
-   * @return array
-   *   The form elements for a single widget for this field.
-   *
-   * @see hook_field_widget_form_alter()
-   * @see hook_field_widget_WIDGET_TYPE_form_alter()
-   */
-  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state);
-
-  /**
-   * Assigns a field-level validation error to the right widget sub-element.
-   *
-   * Depending on the widget's internal structure, a field-level validation
-   * error needs to be flagged on the right sub-element.
-   *
-   * @param array $element
-   *   An array containing the form element for the widget, as generated by
-   *   formElement().
-   * @param \Symfony\Component\Validator\ConstraintViolationInterface $violation
-   *   A constraint violation reported during the validation phase.
-   * @param array $form
-   *   The form structure where field elements are attached to. This might be a
-   *   full form structure, or a sub-element of a larger form.
-   * @param array $form_state
-   *   An associative array containing the current state of the form.
-   *
-   * @return array|bool
-   *   The element on which the error should be flagged, or FALSE to completely
-   *   ignore the violation (use with care!).
-   */
-  public function errorElement(array $element, ConstraintViolationInterface $violation, array $form, array &$form_state);
-
-  /**
-   * Massages the form values into the format expected for field values.
-   *
-   * @param array $values
-   *   The submitted form values produced by the widget.
-   *   - If the widget does not manage multiple values itself, the array holds
-   *     the values generated by the multiple copies of the $element generated
-   *     by the formElement() method, keyed by delta.
-   *   - If the widget manages multiple values, the array holds the values
-   *     of the form element generated by the formElement() method.
-   * @param array $form
-   *   The form structure where field elements are attached to. This might be a
-   *   full form structure, or a sub-element of a larger form.
-   * @param array $form_state
-   *   The form state.
-   *
-   * @return array
-   *   An array of field values, keyed by delta.
-   */
-  public function massageFormValues(array $values, array $form, array &$form_state);
-
-}
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetPluginManager.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetPluginManager.php
deleted file mode 100644
index 13a048a..0000000
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetPluginManager.php
+++ /dev/null
@@ -1,208 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\field\Plugin\Type\Widget\WidgetPluginManager.
- */
-
-namespace Drupal\field\Plugin\Type\Widget;
-
-use Drupal\Component\Plugin\Factory\DefaultFactory;
-use Drupal\Core\Cache\CacheBackendInterface;
-use Drupal\Core\Entity\Field\FieldTypePluginManager;
-use Drupal\Core\Extension\ModuleHandlerInterface;
-use Drupal\Core\Language\LanguageManager;
-use Drupal\Core\Plugin\DefaultPluginManager;
-
-/**
- * Plugin type manager for field widgets.
- */
-class WidgetPluginManager extends DefaultPluginManager {
-
-  /**
-   * The field type manager to define field.
-   *
-   * @var \Drupal\Core\Entity\Field\FieldTypePluginManager
-   */
-  protected $fieldTypeManager;
-
-  /**
-   * An array of widget options for each field type.
-   *
-   * @var array
-   */
-  protected $widgetOptions;
-
-  /**
-   * Constructs a WidgetPluginManager object.
-   *
-   * @param \Traversable $namespaces
-   *   An object that implements \Traversable which contains the root paths
-   *   keyed by the corresponding namespace to look for plugin implementations.
-   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
-   *   Cache backend instance to use.
-   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
-   *   The module handler.
-   * @param \Drupal\Core\Language\LanguageManager $language_manager
-   *   The language manager.
-   * @param \Drupal\Core\Entity\Field\FieldTypePluginManager $field_type_manager
-   *   The 'field type' plugin manager.
-   */
-  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, LanguageManager $language_manager, FieldTypePluginManager $field_type_manager) {
-    parent::__construct('Plugin/field/widget', $namespaces, 'Drupal\field\Annotation\FieldWidget');
-
-    $this->setCacheBackend($cache_backend, $language_manager, 'field_widget_types_plugins');
-    $this->alterInfo($module_handler, 'field_widget_info');
-
-    $this->factory = new WidgetFactory($this);
-    $this->fieldTypeManager = $field_type_manager;
-  }
-
-  /**
-   * Overrides PluginManagerBase::getInstance().
-   *
-   * @param array $options
-   *   An array with the following key/value pairs:
-   *   - field_definition: (FieldDefinitionInterface) The field definition.
-   *   - form_mode: (string) The form mode.
-   *   - prepare: (bool, optional) Whether default values should get merged in
-   *     the 'configuration' array. Defaults to TRUE.
-   *   - configuration: (array) the configuration for the widget. The
-   *     following key value pairs are allowed, and are all optional if
-   *     'prepare' is TRUE:
-   *     - type: (string) The widget to use. Defaults to the
-   *       'default_widget' for the field type. The default widget will also be
-   *       used if the requested widget is not available.
-   *     - settings: (array) Settings specific to the widget. Each setting
-   *       defaults to the default value specified in the widget definition.
-   *
-   * @return \Drupal\field\Plugin\Type\Widget\WidgetInterface
-   *   A Widget object.
-   */
-  public function getInstance(array $options) {
-    // Fill in defaults for missing properties.
-    $options += array(
-      'configuration' => array(),
-      'prepare' => TRUE,
-    );
-
-    $configuration = $options['configuration'];
-    $field_definition = $options['field_definition'];
-    $field_type = $field_definition->getFieldType();
-
-    // Fill in default configuration if needed.
-    if ($options['prepare']) {
-      $configuration = $this->prepareConfiguration($field_type, $configuration);
-    }
-
-    $plugin_id = $configuration['type'];
-
-    // Switch back to default widget if either:
-    // - $type_info doesn't exist (the widget type is unknown),
-    // - the field type is not allowed for the widget.
-    $definition = $this->getDefinition($configuration['type']);
-    if (!isset($definition['class']) || !in_array($field_type, $definition['field_types'])) {
-      // Grab the default widget for the field type.
-      $field_type_definition = $this->fieldTypeManager->getDefinition($field_type);
-      $plugin_id = $field_type_definition['default_widget'];
-    }
-
-    $configuration += array(
-      'field_definition' => $field_definition,
-    );
-    return $this->createInstance($plugin_id, $configuration);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function createInstance($plugin_id, array $configuration = array()) {
-    $plugin_definition = $this->getDefinition($plugin_id);
-    $plugin_class = DefaultFactory::getPluginClass($plugin_id, $plugin_definition);
-
-    // If the plugin provides a factory method, pass the container to it.
-    if (is_subclass_of($plugin_class, 'Drupal\Core\Plugin\ContainerFactoryPluginInterface')) {
-      return $plugin_class::create(\Drupal::getContainer(), $configuration, $plugin_id, $plugin_definition);
-    }
-
-    return new $plugin_class($plugin_id, $plugin_definition, $configuration['field_definition'], $configuration['settings']);
-  }
-
-
-  /**
-   * Merges default values for widget configuration.
-   *
-   * @param string $field_type
-   *   The field type.
-   * @param array $configuration
-   *   An array of widget configuration.
-   *
-   * @return array
-   *   The display properties with defaults added.
-   */
-  public function prepareConfiguration($field_type, array $configuration) {
-    // Fill in defaults for missing properties.
-    $configuration += array(
-      'settings' => array(),
-    );
-    // If no widget is specified, use the default widget.
-    if (!isset($configuration['type'])) {
-      $field_type = $this->fieldTypeManager->getDefinition($field_type);
-      $configuration['type'] = $field_type['default_widget'];
-    }
-    // Fill in default settings values for the widget.
-    $configuration['settings'] += $this->getDefaultSettings($configuration['type']);
-
-    return $configuration;
-  }
-
-  /**
-   * Returns an array of widget type options for a field type.
-   *
-   * @param string|null $field_type
-   *   (optional) The name of a field type, or NULL to retrieve all widget
-   *   options. Defaults to NULL.
-   *
-   * @return array
-   *   If no field type is provided, returns a nested array of all widget types,
-   *   keyed by field type human name.
-   */
-  public function getOptions($field_type = NULL) {
-    if (!isset($this->widgetOptions)) {
-      $options = array();
-      $field_types = $this->fieldTypeManager->getDefinitions();
-      $widget_types = $this->getDefinitions();
-      uasort($widget_types, 'drupal_sort_weight');
-      foreach ($widget_types as $name => $widget_type) {
-        foreach ($widget_type['field_types'] as $widget_field_type) {
-          // Check that the field type exists.
-          if (isset($field_types[$widget_field_type])) {
-            $options[$widget_field_type][$name] = $widget_type['label'];
-          }
-        }
-      }
-      $this->widgetOptions = $options;
-    }
-    if (isset($field_type)) {
-      return !empty($this->widgetOptions[$field_type]) ? $this->widgetOptions[$field_type] : array();
-    }
-
-    return $this->widgetOptions;
-  }
-
-  /**
-   * Returns the default settings of a field widget.
-   *
-   * @param string $type
-   *   A field widget type name.
-   *
-   * @return array
-   *   The widget type's default settings, as provided by the plugin
-   *   definition, or an empty array if type or settings are undefined.
-   */
-  public function getDefaultSettings($type) {
-    $info = $this->getDefinition($type);
-    return isset($info['settings']) ? $info['settings'] : array();
-  }
-
-}
diff --git a/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigFieldItem.php b/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigFieldItem.php
index 7d8b735..1c1a19a 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigFieldItem.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigFieldItem.php
@@ -32,7 +32,7 @@
    * {@inheritdoc}
    */
   public static function schema(FieldInterface $field) {
-    $definition = \Drupal::service('plugin.manager.entity.field.field_type')->getDefinition($field->type);
+    $definition = \Drupal::service('plugin.manager.field.field_type')->getDefinition($field->type);
     $module = $definition['provider'];
     module_load_install($module);
     $callback = "{$module}_field_schema";
diff --git a/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php b/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php
index 014647b..7292202 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php
@@ -12,7 +12,7 @@
 use Drupal\Core\Entity\EntityStorageControllerInterface;
 use Drupal\Core\Language\Language;
 use Drupal\Core\Entity\EntityManager;
-use Drupal\field\Plugin\Type\Formatter\FormatterPluginManager;
+use Drupal\Core\Field\FormatterPluginManager;
 use Drupal\views\ViewExecutable;
 use Drupal\views\Plugin\views\display\DisplayPluginBase;
 use Drupal\views\Plugin\views\field\FieldPluginBase;
@@ -81,7 +81,7 @@ class Field extends FieldPluginBase {
   /**
    * The field formatter plugin manager.
    *
-   * @var \Drupal\field\Plugin\Type\Formatter\FormatterPluginManager
+   * @var \Drupal\Core\Field\FormatterPluginManager
    */
   protected $formatterPluginManager;
 
@@ -96,7 +96,7 @@ class Field extends FieldPluginBase {
    *   The plugin implementation definition.
    * @param \Drupal\Core\Entity\EntityManager $entity_manager
    *   The field formatter plugin manager.
-   * @param \Drupal\field\Plugin\Type\Formatter\FormatterPluginManager $formatter_plugin_manager
+   * @param \Drupal\Core\Field\FormatterPluginManager $formatter_plugin_manager
    *   The field formatter plugin manager.
    */
   public function __construct(array $configuration, $plugin_id, array $plugin_definition, EntityManager $entity_manager, FormatterPluginManager $formatter_plugin_manager) {
@@ -316,7 +316,7 @@ protected function defineOptions() {
 
     // defineOptions runs before init/construct, so no $this->field_info
     $field = field_info_field($this->definition['entity_type'], $this->definition['field_name']);
-    $field_type = \Drupal::service('plugin.manager.entity.field.field_type')->getDefinition($field->getFieldType());
+    $field_type = \Drupal::service('plugin.manager.field.field_type')->getDefinition($field->getFieldType());
     $column_names = array_keys($field->getColumns());
     $default_column = '';
     // Try to determine a sensible default.
diff --git a/core/modules/field/lib/Drupal/field/Tests/CrudTest.php b/core/modules/field/lib/Drupal/field/Tests/CrudTest.php
index d050f59..702cbdd 100644
--- a/core/modules/field/lib/Drupal/field/Tests/CrudTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/CrudTest.php
@@ -62,7 +62,7 @@ function testCreateField() {
     $this->assertEqual($field_config['cardinality'], 1, 'Cardinality defaults to 1.');
 
     // Ensure that default settings are present.
-    $field_type = \Drupal::service('plugin.manager.entity.field.field_type')->getDefinition($field_definition['type']);
+    $field_type = \Drupal::service('plugin.manager.field.field_type')->getDefinition($field_definition['type']);
     $this->assertEqual($field_config['settings'], $field_type['settings'], 'Default field settings have been written.');
 
     // Guarantee that the name is unique.
diff --git a/core/modules/field/lib/Drupal/field/Tests/DisplayApiTest.php b/core/modules/field/lib/Drupal/field/Tests/DisplayApiTest.php
index fc0a55a..86e723c 100644
--- a/core/modules/field/lib/Drupal/field/Tests/DisplayApiTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/DisplayApiTest.php
@@ -258,7 +258,7 @@ function testFieldViewValue() {
    * Tests that the prepareView() formatter method still fires for empty values.
    */
   function testFieldEmpty() {
-    // Uses \Drupal\field_test\Plugin\field\formatter\TestFieldEmptyFormatter.
+    // Uses \Drupal\field_test\Plugin\Field\FieldFormatter\TestFieldEmptyFormatter.
     $display = array(
       'label' => 'hidden',
       'type' => 'field_empty_test',
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldHelpTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldHelpTest.php
index 4ea5979..074a009 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldHelpTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldHelpTest.php
@@ -57,7 +57,7 @@ public function testFieldHelp() {
     // Enable the Options, E-mail and Field API Test modules.
     \Drupal::moduleHandler()->install(array('options', 'email', 'field_test'));
     \Drupal::service('plugin.manager.field.widget')->clearCachedDefinitions();
-    \Drupal::service('plugin.manager.entity.field.field_type')->clearCachedDefinitions();
+    \Drupal::service('plugin.manager.field.field_type')->clearCachedDefinitions();
 
     $this->drupalGet('admin/help/field');
     $this->assertLink('Options', 0, 'Options module is listed on the Field help page.');
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php
index 2b1e1ad..021ae40 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php
@@ -24,7 +24,7 @@ function testFieldInfo() {
     // Test that field_test module's fields, widgets, and formatters show up.
 
     $field_test_info = $this->getExpectedFieldTypeDefinition();
-    $info = \Drupal::service('plugin.manager.entity.field.field_type')->getConfigurableDefinitions();
+    $info = \Drupal::service('plugin.manager.field.field_type')->getConfigurableDefinitions();
     foreach ($field_test_info as $t_key => $field_type) {
       foreach ($field_type as $key => $val) {
         $this->assertEqual($info[$t_key][$key], $val, format_string('Field type %t_key key %key is %value', array('%t_key' => $t_key, '%key' => $key, '%value' => print_r($val, TRUE))));
@@ -132,7 +132,7 @@ function testFieldPrepare() {
     $field = field_info_field('entity_test', $field_definition['name']);
 
     // Check that all expected settings are in place.
-    $field_type = \Drupal::service('plugin.manager.entity.field.field_type')->getDefinition($field_definition['type']);
+    $field_type = \Drupal::service('plugin.manager.field.field_type')->getDefinition($field_definition['type']);
     $this->assertEqual($field->settings, $field_type['settings'], 'All expected default field settings are present.');
   }
 
@@ -166,7 +166,7 @@ function testInstancePrepare() {
     $instance = field_info_instance($instance_definition['entity_type'], $instance_definition['field_name'], $instance_definition['bundle']);
 
     // Check that all expected instance settings are in place.
-    $field_type = \Drupal::service('plugin.manager.entity.field.field_type')->getDefinition($field_definition['type']);
+    $field_type = \Drupal::service('plugin.manager.field.field_type')->getDefinition($field_definition['type']);
     $this->assertEqual($instance->settings, $field_type['instance_settings'] , 'All expected instance settings are present.');
   }
 
@@ -285,7 +285,7 @@ function testFieldMap() {
   function testSettingsInfo() {
     $info = $this->getExpectedFieldTypeDefinition();
     foreach ($info as $type => $data) {
-      $field_type_manager = \Drupal::service('plugin.manager.entity.field.field_type');
+      $field_type_manager = \Drupal::service('plugin.manager.field.field_type');
       $this->assertIdentical($field_type_manager->getDefaultSettings($type), $data['settings'], format_string("field settings service returns %type's field settings", array('%type' => $type)));
       $this->assertIdentical($field_type_manager->getDefaultInstanceSettings($type), $data['instance_settings'], format_string("field instance settings service returns %type's field instance settings", array('%type' => $type)));
     }
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php
index 6c7209e..2f88b88 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php
@@ -75,7 +75,7 @@ function testCreateFieldInstance() {
     // applied on write.
     $config = \Drupal::config('field.instance.' . $instance->id())->get();
 
-    $field_type = \Drupal::service('plugin.manager.entity.field.field_type')->getDefinition($this->field_definition['type']);
+    $field_type = \Drupal::service('plugin.manager.field.field_type')->getDefinition($this->field_definition['type']);
 
     // Check that default values are set.
     $this->assertEqual($config['required'], FALSE, 'Required defaults to false.');
diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldDefaultFormatter.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldDefaultFormatter.php
new file mode 100644
index 0000000..71751b3
--- /dev/null
+++ b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldDefaultFormatter.php
@@ -0,0 +1,65 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\field_test\Plugin\field\formatter\TestFieldDefaultFormatter.
+ */
+
+namespace Drupal\field_test\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Field\FormatterBase;
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+
+/**
+ * Plugin implementation of the 'field_test_default' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "field_test_default",
+ *   label = @Translation("Default"),
+ *   description = @Translation("Default formatter"),
+ *   field_types = {
+ *     "test_field"
+ *   },
+ *   settings = {
+ *     "test_formatter_setting" = "dummy test string"
+ *   }
+ * )
+ */
+class TestFieldDefaultFormatter extends FormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    $element['test_formatter_setting'] = array(
+      '#title' => t('Setting'),
+      '#type' => 'textfield',
+      '#size' => 20,
+      '#default_value' => $this->getSetting('test_formatter_setting'),
+      '#required' => TRUE,
+    );
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = array();
+    $summary[] = t('@setting: @value', array('@setting' => 'test_formatter_setting', '@value' => $this->getSetting('test_formatter_setting')));
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+    $elements = array();
+
+    foreach ($items as $delta => $item) {
+      $elements[$delta] = array('#markup' => $this->getSetting('test_formatter_setting') . '|' . $item->value);
+    }
+
+    return $elements;
+  }
+}
diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldEmptyFormatter.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldEmptyFormatter.php
new file mode 100644
index 0000000..16b33f4
--- /dev/null
+++ b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldEmptyFormatter.php
@@ -0,0 +1,49 @@
+<?php
+
+/**
+ * @file
+ *
+ * Contains \Drupal\field_test\Plugin\field\formatter\TestFieldEmptyFormatter.
+ */
+namespace Drupal\field_test\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+use Drupal\Core\Field\FormatterBase;
+
+/**
+ * Plugin implementation of the 'field_empty_test' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "field_empty_test",
+ *   label = @Translation("Field empty test"),
+ *   field_types = {
+ *     "test_field",
+ *   },
+ *   settings = {
+ *     "test_empty_string" = "**EMPTY FIELD**"
+ *   }
+ * )
+ */
+class TestFieldEmptyFormatter extends FormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+    $elements = array();
+
+    if ($items->isEmpty()) {
+      // For fields with no value, just add the configured "empty" value.
+      $elements[0] = array('#markup' => $this->getSetting('test_empty_string'));
+    }
+    else {
+      foreach ($items as $delta => $item) {
+        // This formatter only needs to output raw for testing.
+        $elements[$delta] = array('#markup' => $item->value);
+      }
+    }
+
+    return $elements;
+  }
+
+}
diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldEmptySettingFormatter.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldEmptySettingFormatter.php
new file mode 100644
index 0000000..d09ce94
--- /dev/null
+++ b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldEmptySettingFormatter.php
@@ -0,0 +1,69 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\field_test\Plugin\field\formatter\TestFieldEmptySettingFormatter
+ */
+
+namespace Drupal\field_test\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Field\FormatterBase;
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+
+/**
+ * Plugin implementation of the 'field_empty_setting' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "field_empty_setting",
+ *   label = @Translation("Field empty setting"),
+ *   field_types = {
+ *     "test_field",
+ *   },
+ *   settings = {
+ *     "field_empty_setting" = ""
+ *   }
+ * )
+ */
+class TestFieldEmptySettingFormatter extends FormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    $element['field_empty_setting'] = array(
+      '#title' => t('Setting'),
+      '#type' => 'textfield',
+      '#size' => 20,
+      '#default_value' => $this->getSetting('field_empty_setting'),
+      '#required' => TRUE,
+    );
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = array();
+    $setting = $this->getSetting('field_empty_setting');
+    if (!empty($setting)) {
+      $summary[] = t('Default empty setting now has a value.');
+    }
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+    $elements = array();
+
+    if (!empty($items)) {
+      foreach ($items as $delta => $item) {
+        $elements[$delta] = array('#markup' => $this->getSetting('field_empty_setting'));
+      }
+    }
+
+    return $elements;
+  }
+}
diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldMultipleFormatter.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldMultipleFormatter.php
new file mode 100644
index 0000000..ae302c3
--- /dev/null
+++ b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldMultipleFormatter.php
@@ -0,0 +1,69 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\field_test\Plugin\field\formatter\TestFieldMultipleFormatter.
+ */
+
+namespace Drupal\field_test\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Field\FormatterBase;
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+
+/**
+ * Plugin implementation of the 'field_test_multiple' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "field_test_multiple",
+ *   label = @Translation("Multiple"),
+ *   description = @Translation("Multiple formatter"),
+ *   field_types = {
+ *     "test_field"
+ *   },
+ *   settings = {
+ *     "test_formatter_setting_multiple" = "dummy test string"
+ *   }
+ * )
+ */
+class TestFieldMultipleFormatter extends FormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    $element['test_formatter_setting_multiple'] = array(
+      '#title' => t('Setting'),
+      '#type' => 'textfield',
+      '#size' => 20,
+      '#default_value' => $this->getSetting('test_formatter_setting_multiple'),
+      '#required' => TRUE,
+    );
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = array();
+    $summary[] = t('@setting: @value', array('@setting' => 'test_formatter_setting_multiple', '@value' => $this->getSetting('test_formatter_setting_multiple')));
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+    $elements = array();
+
+    if (!empty($items)) {
+      $array = array();
+      foreach ($items as $delta => $item) {
+        $array[] = $delta . ':' . $item->value;
+      }
+      $elements[0] = array('#markup' => $this->getSetting('test_formatter_setting_multiple') . '|' . implode('|', $array));
+    }
+
+    return $elements;
+  }
+}
diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldPrepareViewFormatter.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldPrepareViewFormatter.php
new file mode 100644
index 0000000..9809261
--- /dev/null
+++ b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldPrepareViewFormatter.php
@@ -0,0 +1,79 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\field_test\Plugin\field\formatter\TestFieldPrepareViewFormatter.
+ */
+
+namespace Drupal\field_test\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Field\FormatterBase;
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+
+/**
+ * Plugin implementation of the 'field_test_with_prepare_view' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "field_test_with_prepare_view",
+ *   label = @Translation("With prepare step"),
+ *   description = @Translation("Tests prepareView() method"),
+ *   field_types = {
+ *     "test_field"
+ *   },
+ *   settings = {
+ *     "test_formatter_setting_additional" = "dummy test string"
+ *   }
+ * )
+ */
+class TestFieldPrepareViewFormatter extends FormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    $element['test_formatter_setting_additional'] = array(
+      '#title' => t('Setting'),
+      '#type' => 'textfield',
+      '#size' => 20,
+      '#default_value' => $this->getSetting('test_formatter_setting_additional'),
+      '#required' => TRUE,
+    );
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = array();
+    $summary[] = t('@setting: @value', array('@setting' => 'test_formatter_setting_additional', '@value' => $this->getSetting('test_formatter_setting_additional')));
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function prepareView(array $entities_items) {
+    foreach ($entities_items as $items) {
+      foreach ($items as $item) {
+        // Don't add anything on empty values.
+        if (!$item->isEmpty()) {
+          $item->additional_formatter_value = $item->value + 1;
+        }
+      }
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+    $elements = array();
+
+    foreach ($items as $delta => $item) {
+      $elements[$delta] = array('#markup' => $this->getSetting('test_formatter_setting_additional') . '|' . $item->value . '|' . $item->additional_formatter_value);
+    }
+
+    return $elements;
+  }
+}
diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldWidget/TestFieldWidget.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldWidget/TestFieldWidget.php
new file mode 100644
index 0000000..6b49956
--- /dev/null
+++ b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldWidget/TestFieldWidget.php
@@ -0,0 +1,72 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\field_test\Plugin\Field\FieldWidget\TestFieldWidget.
+ */
+
+namespace Drupal\field_test\Plugin\Field\FieldWidget;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+use Drupal\Core\Field\WidgetBase;
+use Symfony\Component\Validator\ConstraintViolationInterface;
+
+/**
+ * Plugin implementation of the 'test_field_widget' widget.
+ *
+ * @FieldWidget(
+ *   id = "test_field_widget",
+ *   label = @Translation("Test widget"),
+ *   field_types = {
+ *      "test_field",
+ *      "hidden_test_field"
+ *   },
+ *   settings = {
+ *     "test_widget_setting" = "dummy test string"
+ *   }
+ * )
+ */
+class TestFieldWidget extends WidgetBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    $element['test_widget_setting'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Field test field widget setting'),
+      '#description' => t('A dummy form element to simulate field widget setting.'),
+      '#default_value' => $this->getSetting('test_widget_setting'),
+      '#required' => FALSE,
+    );
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = array();
+    $summary[] = t('@setting: @value', array('@setting' => 'test_widget_setting', '@value' => $this->getSetting('test_widget_setting')));
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
+    $element += array(
+      '#type' => 'textfield',
+      '#default_value' => isset($items[$delta]->value) ? $items[$delta]->value : '',
+    );
+    return array('value' => $element);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function errorElement(array $element, ConstraintViolationInterface $error, array $form, array &$form_state) {
+    return $element['value'];
+  }
+
+}
diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldWidget/TestFieldWidgetMultiple.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldWidget/TestFieldWidgetMultiple.php
new file mode 100644
index 0000000..90750b5
--- /dev/null
+++ b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldWidget/TestFieldWidgetMultiple.php
@@ -0,0 +1,91 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\field_test\Plugin\Field\FieldWidget\TestFieldWidgetMultiple.
+ */
+
+namespace Drupal\field_test\Plugin\Field\FieldWidget;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+use Drupal\Core\Field\WidgetBase;
+use Symfony\Component\Validator\ConstraintViolationInterface;
+
+/**
+ * Plugin implementation of the 'test_field_widget_multiple' widget.
+ *
+ * The 'field_types' entry is left empty, and is populated through
+ * hook_field_widget_info_alter().
+ *
+ * @see field_test_field_widget_info_alter()
+ *
+ * @FieldWidget(
+ *   id = "test_field_widget_multiple",
+ *   label = @Translation("Test widget - multiple"),
+ *   settings = {
+ *     "test_widget_setting_multiple" = "dummy test string"
+ *   },
+ *   multiple_values = TRUE
+ * )
+ */
+class TestFieldWidgetMultiple extends WidgetBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    $element['test_widget_setting_multiple'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Field test field widget setting'),
+      '#description' => t('A dummy form element to simulate field widget setting.'),
+      '#default_value' => $this->getSetting('test_widget_setting_multiple'),
+      '#required' => FALSE,
+    );
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = array();
+    $summary[] = t('@setting: @value', array('@setting' => 'test_widget_setting_multiple', '@value' => $this->getSetting('test_widget_setting_multiple')));
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
+    $values = array();
+    foreach ($items as $delta => $item) {
+      $values[] = $item->value;
+    }
+    $element += array(
+      '#type' => 'textfield',
+      '#default_value' => implode(', ', $values),
+      '#element_validate' => array(array(get_class($this), 'multipleValidate')),
+    );
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function errorElement(array $element, ConstraintViolationInterface $error, array $form, array &$form_state) {
+    return $element;
+  }
+
+  /**
+   * Element validation helper.
+   */
+  public static function multipleValidate($element, &$form_state) {
+    $values = array_map('trim', explode(',', $element['#value']));
+    $items = array();
+    foreach ($values as $value) {
+      $items[] = array('value' => $value);
+    }
+    form_set_value($element, $items, $form_state);
+  }
+
+}
diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/field/formatter/TestFieldDefaultFormatter.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/field/formatter/TestFieldDefaultFormatter.php
deleted file mode 100644
index 66d30ef..0000000
--- a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/field/formatter/TestFieldDefaultFormatter.php
+++ /dev/null
@@ -1,65 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\field_test\Plugin\field\formatter\TestFieldDefaultFormatter.
- */
-
-namespace Drupal\field_test\Plugin\field\formatter;
-
-use Drupal\field\Plugin\Type\Formatter\FormatterBase;
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-
-/**
- * Plugin implementation of the 'field_test_default' formatter.
- *
- * @FieldFormatter(
- *   id = "field_test_default",
- *   label = @Translation("Default"),
- *   description = @Translation("Default formatter"),
- *   field_types = {
- *     "test_field"
- *   },
- *   settings = {
- *     "test_formatter_setting" = "dummy test string"
- *   }
- * )
- */
-class TestFieldDefaultFormatter extends FormatterBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsForm(array $form, array &$form_state) {
-    $element['test_formatter_setting'] = array(
-      '#title' => t('Setting'),
-      '#type' => 'textfield',
-      '#size' => 20,
-      '#default_value' => $this->getSetting('test_formatter_setting'),
-      '#required' => TRUE,
-    );
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    $summary = array();
-    $summary[] = t('@setting: @value', array('@setting' => 'test_formatter_setting', '@value' => $this->getSetting('test_formatter_setting')));
-    return $summary;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function viewElements(FieldItemListInterface $items) {
-    $elements = array();
-
-    foreach ($items as $delta => $item) {
-      $elements[$delta] = array('#markup' => $this->getSetting('test_formatter_setting') . '|' . $item->value);
-    }
-
-    return $elements;
-  }
-}
diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/field/formatter/TestFieldEmptyFormatter.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/field/formatter/TestFieldEmptyFormatter.php
deleted file mode 100644
index cbe79cf..0000000
--- a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/field/formatter/TestFieldEmptyFormatter.php
+++ /dev/null
@@ -1,49 +0,0 @@
-<?php
-
-/**
- * @file
- *
- * Contains \Drupal\field_test\Plugin\field\formatter\TestFieldEmptyFormatter.
- */
-namespace Drupal\field_test\Plugin\field\formatter;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\field\Plugin\Type\Formatter\FormatterBase;
-
-/**
- * Plugin implementation of the 'field_empty_test' formatter.
- *
- * @FieldFormatter(
- *   id = "field_empty_test",
- *   label = @Translation("Field empty test"),
- *   field_types = {
- *     "test_field",
- *   },
- *   settings = {
- *     "test_empty_string" = "**EMPTY FIELD**"
- *   }
- * )
- */
-class TestFieldEmptyFormatter extends FormatterBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function viewElements(FieldItemListInterface $items) {
-    $elements = array();
-
-    if ($items->isEmpty()) {
-      // For fields with no value, just add the configured "empty" value.
-      $elements[0] = array('#markup' => $this->getSetting('test_empty_string'));
-    }
-    else {
-      foreach ($items as $delta => $item) {
-        // This formatter only needs to output raw for testing.
-        $elements[$delta] = array('#markup' => $item->value);
-      }
-    }
-
-    return $elements;
-  }
-
-}
diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/field/formatter/TestFieldEmptySettingFormatter.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/field/formatter/TestFieldEmptySettingFormatter.php
deleted file mode 100644
index ec89567..0000000
--- a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/field/formatter/TestFieldEmptySettingFormatter.php
+++ /dev/null
@@ -1,71 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\field_test\Plugin\field\formatter\TestFieldEmptySettingFormatter
- */
-
-namespace Drupal\field_test\Plugin\field\formatter;
-
-use Drupal\field\Annotation\FieldFormatter;
-use Drupal\Core\Annotation\Translation;
-use Drupal\field\Plugin\Type\Formatter\FormatterBase;
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-
-/**
- * Plugin implementation of the 'field_empty_setting' formatter.
- *
- * @FieldFormatter(
- *   id = "field_empty_setting",
- *   label = @Translation("Field empty setting"),
- *   field_types = {
- *     "test_field",
- *   },
- *   settings = {
- *     "field_empty_setting" = ""
- *   }
- * )
- */
-class TestFieldEmptySettingFormatter extends FormatterBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsForm(array $form, array &$form_state) {
-    $element['field_empty_setting'] = array(
-      '#title' => t('Setting'),
-      '#type' => 'textfield',
-      '#size' => 20,
-      '#default_value' => $this->getSetting('field_empty_setting'),
-      '#required' => TRUE,
-    );
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    $summary = array();
-    $setting = $this->getSetting('field_empty_setting');
-    if (!empty($setting)) {
-      $summary[] = t('Default empty setting now has a value.');
-    }
-    return $summary;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function viewElements(FieldItemListInterface $items) {
-    $elements = array();
-
-    if (!empty($items)) {
-      foreach ($items as $delta => $item) {
-        $elements[$delta] = array('#markup' => $this->getSetting('field_empty_setting'));
-      }
-    }
-
-    return $elements;
-  }
-}
diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/field/formatter/TestFieldMultipleFormatter.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/field/formatter/TestFieldMultipleFormatter.php
deleted file mode 100644
index feed742..0000000
--- a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/field/formatter/TestFieldMultipleFormatter.php
+++ /dev/null
@@ -1,69 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\field_test\Plugin\field\formatter\TestFieldMultipleFormatter.
- */
-
-namespace Drupal\field_test\Plugin\field\formatter;
-
-use Drupal\field\Plugin\Type\Formatter\FormatterBase;
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-
-/**
- * Plugin implementation of the 'field_test_multiple' formatter.
- *
- * @FieldFormatter(
- *   id = "field_test_multiple",
- *   label = @Translation("Multiple"),
- *   description = @Translation("Multiple formatter"),
- *   field_types = {
- *     "test_field"
- *   },
- *   settings = {
- *     "test_formatter_setting_multiple" = "dummy test string"
- *   }
- * )
- */
-class TestFieldMultipleFormatter extends FormatterBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsForm(array $form, array &$form_state) {
-    $element['test_formatter_setting_multiple'] = array(
-      '#title' => t('Setting'),
-      '#type' => 'textfield',
-      '#size' => 20,
-      '#default_value' => $this->getSetting('test_formatter_setting_multiple'),
-      '#required' => TRUE,
-    );
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    $summary = array();
-    $summary[] = t('@setting: @value', array('@setting' => 'test_formatter_setting_multiple', '@value' => $this->getSetting('test_formatter_setting_multiple')));
-    return $summary;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function viewElements(FieldItemListInterface $items) {
-    $elements = array();
-
-    if (!empty($items)) {
-      $array = array();
-      foreach ($items as $delta => $item) {
-        $array[] = $delta . ':' . $item->value;
-      }
-      $elements[0] = array('#markup' => $this->getSetting('test_formatter_setting_multiple') . '|' . implode('|', $array));
-    }
-
-    return $elements;
-  }
-}
diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/field/formatter/TestFieldPrepareViewFormatter.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/field/formatter/TestFieldPrepareViewFormatter.php
deleted file mode 100644
index 1d36638..0000000
--- a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/field/formatter/TestFieldPrepareViewFormatter.php
+++ /dev/null
@@ -1,79 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\field_test\Plugin\field\formatter\TestFieldPrepareViewFormatter.
- */
-
-namespace Drupal\field_test\Plugin\field\formatter;
-
-use Drupal\field\Plugin\Type\Formatter\FormatterBase;
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-
-/**
- * Plugin implementation of the 'field_test_with_prepare_view' formatter.
- *
- * @FieldFormatter(
- *   id = "field_test_with_prepare_view",
- *   label = @Translation("With prepare step"),
- *   description = @Translation("Tests prepareView() method"),
- *   field_types = {
- *     "test_field"
- *   },
- *   settings = {
- *     "test_formatter_setting_additional" = "dummy test string"
- *   }
- * )
- */
-class TestFieldPrepareViewFormatter extends FormatterBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsForm(array $form, array &$form_state) {
-    $element['test_formatter_setting_additional'] = array(
-      '#title' => t('Setting'),
-      '#type' => 'textfield',
-      '#size' => 20,
-      '#default_value' => $this->getSetting('test_formatter_setting_additional'),
-      '#required' => TRUE,
-    );
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    $summary = array();
-    $summary[] = t('@setting: @value', array('@setting' => 'test_formatter_setting_additional', '@value' => $this->getSetting('test_formatter_setting_additional')));
-    return $summary;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function prepareView(array $entities_items) {
-    foreach ($entities_items as $items) {
-      foreach ($items as $item) {
-        // Don't add anything on empty values.
-        if (!$item->isEmpty()) {
-          $item->additional_formatter_value = $item->value + 1;
-        }
-      }
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function viewElements(FieldItemListInterface $items) {
-    $elements = array();
-
-    foreach ($items as $delta => $item) {
-      $elements[$delta] = array('#markup' => $this->getSetting('test_formatter_setting_additional') . '|' . $item->value . '|' . $item->additional_formatter_value);
-    }
-
-    return $elements;
-  }
-}
diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/field/widget/TestFieldWidget.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/field/widget/TestFieldWidget.php
deleted file mode 100644
index bb0d494..0000000
--- a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/field/widget/TestFieldWidget.php
+++ /dev/null
@@ -1,72 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\field_test\Plugin\field\widget\TestFieldWidget.
- */
-
-namespace Drupal\field_test\Plugin\field\widget;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\field\Plugin\Type\Widget\WidgetBase;
-use Symfony\Component\Validator\ConstraintViolationInterface;
-
-/**
- * Plugin implementation of the 'test_field_widget' widget.
- *
- * @FieldWidget(
- *   id = "test_field_widget",
- *   label = @Translation("Test widget"),
- *   field_types = {
- *      "test_field",
- *      "hidden_test_field"
- *   },
- *   settings = {
- *     "test_widget_setting" = "dummy test string"
- *   }
- * )
- */
-class TestFieldWidget extends WidgetBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsForm(array $form, array &$form_state) {
-    $element['test_widget_setting'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Field test field widget setting'),
-      '#description' => t('A dummy form element to simulate field widget setting.'),
-      '#default_value' => $this->getSetting('test_widget_setting'),
-      '#required' => FALSE,
-    );
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    $summary = array();
-    $summary[] = t('@setting: @value', array('@setting' => 'test_widget_setting', '@value' => $this->getSetting('test_widget_setting')));
-    return $summary;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
-    $element += array(
-      '#type' => 'textfield',
-      '#default_value' => isset($items[$delta]->value) ? $items[$delta]->value : '',
-    );
-    return array('value' => $element);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function errorElement(array $element, ConstraintViolationInterface $error, array $form, array &$form_state) {
-    return $element['value'];
-  }
-
-}
diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/field/widget/TestFieldWidgetMultiple.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/field/widget/TestFieldWidgetMultiple.php
deleted file mode 100644
index 736f654..0000000
--- a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/field/widget/TestFieldWidgetMultiple.php
+++ /dev/null
@@ -1,91 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\field_test\Plugin\field\widget\TestFieldWidgetMultiple.
- */
-
-namespace Drupal\field_test\Plugin\field\widget;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\field\Plugin\Type\Widget\WidgetBase;
-use Symfony\Component\Validator\ConstraintViolationInterface;
-
-/**
- * Plugin implementation of the 'test_field_widget_multiple' widget.
- *
- * The 'field_types' entry is left empty, and is populated through
- * hook_field_widget_info_alter().
- *
- * @see field_test_field_widget_info_alter()
- *
- * @FieldWidget(
- *   id = "test_field_widget_multiple",
- *   label = @Translation("Test widget - multiple"),
- *   settings = {
- *     "test_widget_setting_multiple" = "dummy test string"
- *   },
- *   multiple_values = TRUE
- * )
- */
-class TestFieldWidgetMultiple extends WidgetBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsForm(array $form, array &$form_state) {
-    $element['test_widget_setting_multiple'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Field test field widget setting'),
-      '#description' => t('A dummy form element to simulate field widget setting.'),
-      '#default_value' => $this->getSetting('test_widget_setting_multiple'),
-      '#required' => FALSE,
-    );
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    $summary = array();
-    $summary[] = t('@setting: @value', array('@setting' => 'test_widget_setting_multiple', '@value' => $this->getSetting('test_widget_setting_multiple')));
-    return $summary;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
-    $values = array();
-    foreach ($items as $delta => $item) {
-      $values[] = $item->value;
-    }
-    $element += array(
-      '#type' => 'textfield',
-      '#default_value' => implode(', ', $values),
-      '#element_validate' => array(array(get_class($this), 'multipleValidate')),
-    );
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function errorElement(array $element, ConstraintViolationInterface $error, array $form, array &$form_state) {
-    return $element;
-  }
-
-  /**
-   * Element validation helper.
-   */
-  public static function multipleValidate($element, &$form_state) {
-    $values = array_map('trim', explode(',', $element['#value']));
-    $items = array();
-    foreach ($values as $value) {
-      $items[] = array('value' => $value);
-    }
-    form_set_value($element, $items, $form_state);
-  }
-
-}
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php
index ffd83b5..0d68e77 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php
@@ -23,7 +23,7 @@ class DisplayOverview extends DisplayOverviewBase {
   public static function create(ContainerInterface $container) {
     return new static(
       $container->get('entity.manager'),
-      $container->get('plugin.manager.entity.field.field_type'),
+      $container->get('plugin.manager.field.field_type'),
       $container->get('plugin.manager.field.formatter')
     );
   }
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverviewBase.php b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverviewBase.php
index 279a60f..fcc764c 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverviewBase.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverviewBase.php
@@ -9,7 +9,7 @@
 
 use Drupal\Component\Plugin\PluginManagerBase;
 use Drupal\Core\Entity\EntityManager;
-use Drupal\Core\Entity\Field\FieldTypePluginManager;
+use Drupal\Core\Field\FieldTypePluginManager;
 use Drupal\entity\EntityDisplayBaseInterface;
 use Drupal\field\FieldInstanceInterface;
 use Drupal\field_ui\OverviewBase;
@@ -39,7 +39,7 @@
    *
    * @param \Drupal\Core\Entity\EntityManager $entity_manager
    *   The entity manager.
-   * @param \Drupal\Core\Entity\Field\FieldTypePluginManager $field_type_manager
+   * @param \Drupal\Core\Field\FieldTypePluginManager $field_type_manager
    *   The field type manager.
    * @param \Drupal\Component\Plugin\PluginManagerBase $plugin_manager
    *   The widget or formatter plugin manager.
@@ -57,7 +57,7 @@ public function __construct(EntityManager $entity_manager, FieldTypePluginManage
   public static function create(ContainerInterface $container) {
     return new static(
       $container->get('entity.manager'),
-      $container->get('plugin.manager.entity.field.field_type'),
+      $container->get('plugin.manager.field.field_type'),
       $container->get('plugin.manager.field.widget')
     );
   }
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/FieldListController.php b/core/modules/field_ui/lib/Drupal/field_ui/FieldListController.php
index 72edd23..c0d3982 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/FieldListController.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldListController.php
@@ -10,7 +10,7 @@
 use Drupal\Core\Config\Entity\ConfigEntityListController;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityManager;
-use Drupal\Core\Entity\Field\FieldTypePluginManager;
+use Drupal\Core\Field\FieldTypePluginManager;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
@@ -43,7 +43,7 @@ class FieldListController extends ConfigEntityListController {
   /**
    * The field type manager.
    *
-   * @var \Drupal\Core\Entity\Field\FieldTypePluginManager
+   * @var \Drupal\Core\Field\FieldTypePluginManager
    */
   protected $fieldTypeManager;
 
@@ -60,7 +60,7 @@ class FieldListController extends ConfigEntityListController {
    *   The module handler to invoke hooks on.
    * @param \Drupal\field\FieldInfo $field_info
    *   The field info service.
-   * @param \Drupal\Core\Entity\Field\FieldTypePluginManager $field_type_manager
+   * @param \Drupal\Core\Field\FieldTypePluginManager $field_type_manager
    *   The 'field type' plugin manager.
    */
   public function __construct($entity_type, array $entity_info, EntityManager $entity_manager, ModuleHandlerInterface $module_handler, FieldTypePluginManager $field_type_manager) {
@@ -81,7 +81,7 @@ public static function createInstance(ContainerInterface $container, $entity_typ
       $entity_info,
       $container->get('entity.manager'),
       $container->get('module_handler'),
-      $container->get('plugin.manager.entity.field.field_type')
+      $container->get('plugin.manager.field.field_type')
     );
   }
 
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php b/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php
index 01477e1..d7b1550 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php
@@ -8,7 +8,7 @@
 namespace Drupal\field_ui;
 
 use Drupal\Core\Entity\EntityManager;
-use Drupal\Core\Entity\Field\FieldTypePluginManager;
+use Drupal\Core\Field\FieldTypePluginManager;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\field_ui\OverviewBase;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -22,7 +22,7 @@ class FieldOverview extends OverviewBase {
   /**
    *  The field type manager.
    *
-   * @var \Drupal\Core\Entity\Field\FieldTypePluginManager
+   * @var \Drupal\Core\Field\FieldTypePluginManager
    */
   protected $fieldTypeManager;
 
@@ -38,7 +38,7 @@ class FieldOverview extends OverviewBase {
    *
    * @param \Drupal\Core\Entity\EntityManager $entity_manager
    *   The entity manager.
-   * @param \Drupal\Core\Entity\Field\FieldTypePluginManager $field_type_manager
+   * @param \Drupal\Core\Field\FieldTypePluginManager $field_type_manager
    *   The field type manager
    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
    *   The module handler to invoke hooks on.
@@ -55,7 +55,7 @@ public function __construct(EntityManager $entity_manager, FieldTypePluginManage
   public static function create(ContainerInterface $container) {
     return new static(
       $container->get('entity.manager'),
-      $container->get('plugin.manager.entity.field.field_type'),
+      $container->get('plugin.manager.field.field_type'),
       $container->get('module_handler')
     );
   }
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/FormDisplayOverview.php b/core/modules/field_ui/lib/Drupal/field_ui/FormDisplayOverview.php
index 59678d1..a1e8d8b 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/FormDisplayOverview.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/FormDisplayOverview.php
@@ -23,7 +23,7 @@ class FormDisplayOverview extends DisplayOverviewBase {
   public static function create(ContainerInterface $container) {
     return new static(
       $container->get('entity.manager'),
-      $container->get('plugin.manager.entity.field.field_type'),
+      $container->get('plugin.manager.field.field_type'),
       $container->get('plugin.manager.field.widget')
     );
   }
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php
index 3499c61..e3d6e31 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php
@@ -457,7 +457,7 @@ function testHiddenFields() {
     $this->assertFalse($this->xpath('//select[@id="edit-add-existing-field-field-name"]//option[@value=:field_name]', array(':field_name' => $field_name)), "The 're-use existing field' select respects field types 'no_ui' property.");
 
     // Check that non-configurable fields are not available.
-    $field_types = \Drupal::service('plugin.manager.entity.field.field_type')->getDefinitions();
+    $field_types = \Drupal::service('plugin.manager.field.field_type')->getDefinitions();
     foreach ($field_types as $field_type => $definition) {
       if ($definition['configurable'] && empty($definition['no_ui'])) {
         $this->assertTrue($this->xpath('//select[@id="edit-fields-add-new-field-type"]//option[@value=:field_type]', array(':field_type' => $field_type)), String::format('Configurable field type @field_type is available.', array('@field_type' => $field_type)));
diff --git a/core/modules/file/lib/Drupal/file/Plugin/Field/FieldFormatter/FileFormatterBase.php b/core/modules/file/lib/Drupal/file/Plugin/Field/FieldFormatter/FileFormatterBase.php
new file mode 100644
index 0000000..3c45fe4
--- /dev/null
+++ b/core/modules/file/lib/Drupal/file/Plugin/Field/FieldFormatter/FileFormatterBase.php
@@ -0,0 +1,45 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\file\Plugin\field\formatter\FileFormatterBase.
+ */
+
+namespace Drupal\file\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Field\FormatterBase;
+
+/**
+ * Base class for file formatters.
+ */
+abstract class FileFormatterBase extends FormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function prepareView(array $entities_items) {
+    // Remove files specified to not be displayed.
+    $fids = array();
+    foreach ($entities_items as $items) {
+      foreach ($items as $item) {
+        if ($item->isDisplayed() && !empty($item->target_id)) {
+          // Load the files from the files table.
+          $fids[] = $item->target_id;
+        }
+      }
+    }
+
+    if ($fids) {
+      $files = file_load_multiple($fids);
+
+      foreach ($entities_items as $items) {
+        foreach ($items as $item) {
+          // If the file does not exist, mark the entire item as empty.
+          if (!empty($item->target_id)) {
+            $item->entity = isset($files[$item->target_id]) ? $files[$item->target_id] : NULL;
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/core/modules/file/lib/Drupal/file/Plugin/Field/FieldFormatter/GenericFileFormatter.php b/core/modules/file/lib/Drupal/file/Plugin/Field/FieldFormatter/GenericFileFormatter.php
new file mode 100644
index 0000000..e0169e1
--- /dev/null
+++ b/core/modules/file/lib/Drupal/file/Plugin/Field/FieldFormatter/GenericFileFormatter.php
@@ -0,0 +1,52 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\file\Plugin\field\formatter\GenericFileFormatter.
+ */
+
+namespace Drupal\file\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+
+/**
+ * Plugin implementation of the 'file_default' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "file_default",
+ *   label = @Translation("Generic file"),
+ *   field_types = {
+ *     "file"
+ *   }
+ * )
+ */
+class GenericFileFormatter extends FileFormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+    $elements = array();
+
+    foreach ($items as $delta => $item) {
+      if ($item->isDisplayed() && $item->entity) {
+        $elements[$delta] = array(
+          '#theme' => 'file_link',
+          '#file' => $item->entity,
+          '#description' => $item->description,
+        );
+        // Pass field item attributes to the theme function.
+        if (isset($item->_attributes)) {
+          $elements[$delta] += array('#attributes' => array());
+          $elements[$delta]['#attributes'] += $item->_attributes;
+          // Unset field item attributes since they have been included in the
+          // formatter output and should not be rendered in the field template.
+          unset($item->_attributes);
+        }
+      }
+    }
+
+    return $elements;
+  }
+
+}
diff --git a/core/modules/file/lib/Drupal/file/Plugin/Field/FieldFormatter/RSSEnclosureFormatter.php b/core/modules/file/lib/Drupal/file/Plugin/Field/FieldFormatter/RSSEnclosureFormatter.php
new file mode 100644
index 0000000..babb894
--- /dev/null
+++ b/core/modules/file/lib/Drupal/file/Plugin/Field/FieldFormatter/RSSEnclosureFormatter.php
@@ -0,0 +1,49 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\file\Plugin\field\formatter\RSSEnclosureFormatter.
+ */
+
+namespace Drupal\file\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+
+/**
+ * Plugin implementation of the 'file_rss_enclosure' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "file_rss_enclosure",
+ *   label = @Translation("RSS enclosure"),
+ *   field_types = {
+ *     "file"
+ *   }
+ * )
+ */
+class RSSEnclosureFormatter extends FileFormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+    $entity = $items->getEntity();
+    // Add the first file as an enclosure to the RSS item. RSS allows only one
+    // enclosure per item. See: http://en.wikipedia.org/wiki/RSS_enclosure
+    foreach ($items as $item) {
+      if ($item->isDisplayed() && $item->entity) {
+        $file = $item->entity;
+        $entity->rss_elements[] = array(
+          'key' => 'enclosure',
+          'attributes' => array(
+            'url' => file_create_url($file->getFileUri()),
+            'length' => $file->getSize(),
+            'type' => $file->getMimeType(),
+          ),
+        );
+        break;
+      }
+    }
+
+  }
+
+}
diff --git a/core/modules/file/lib/Drupal/file/Plugin/Field/FieldFormatter/TableFormatter.php b/core/modules/file/lib/Drupal/file/Plugin/Field/FieldFormatter/TableFormatter.php
new file mode 100644
index 0000000..e8b1b39
--- /dev/null
+++ b/core/modules/file/lib/Drupal/file/Plugin/Field/FieldFormatter/TableFormatter.php
@@ -0,0 +1,42 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\file\Plugin\field\formatter\TableFormatter.
+ */
+
+namespace Drupal\file\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+
+/**
+ * Plugin implementation of the 'file_table' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "file_table",
+ *   label = @Translation("Table of files"),
+ *   field_types = {
+ *     "file"
+ *   }
+ * )
+ */
+class TableFormatter extends FileFormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+    $elements = array();
+
+    if (!$items->isEmpty()) {
+      // Display all values in a single element.
+      $elements[0] = array(
+        '#theme' => 'file_formatter_table',
+        '#items' => $items,
+      );
+    }
+
+    return $elements;
+  }
+
+}
diff --git a/core/modules/file/lib/Drupal/file/Plugin/Field/FieldFormatter/UrlPlainFormatter.php b/core/modules/file/lib/Drupal/file/Plugin/Field/FieldFormatter/UrlPlainFormatter.php
new file mode 100644
index 0000000..b8633de
--- /dev/null
+++ b/core/modules/file/lib/Drupal/file/Plugin/Field/FieldFormatter/UrlPlainFormatter.php
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\file\Plugin\field\formatter\UrlPlainFormatter.
+ */
+
+namespace Drupal\file\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+
+/**
+ * Plugin implementation of the 'file_url_plain' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "file_url_plain",
+ *   label = @Translation("URL to file"),
+ *   field_types = {
+ *     "file"
+ *   }
+ * )
+ */
+class UrlPlainFormatter extends FileFormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+    $elements = array();
+
+    foreach ($items as $delta => $item) {
+      if ($item->isDisplayed() && $item->entity) {
+        $elements[$delta] = array('#markup' => empty($item->entity) ? '' : file_create_url($item->entity->getFileUri()));
+      }
+    }
+
+    return $elements;
+  }
+
+}
diff --git a/core/modules/file/lib/Drupal/file/Plugin/Field/FieldWidget/FileWidget.php b/core/modules/file/lib/Drupal/file/Plugin/Field/FieldWidget/FileWidget.php
new file mode 100644
index 0000000..2b61e36
--- /dev/null
+++ b/core/modules/file/lib/Drupal/file/Plugin/Field/FieldWidget/FileWidget.php
@@ -0,0 +1,259 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\file\Plugin\Field\FieldWidget\FileWidget.
+ */
+
+namespace Drupal\file\Plugin\Field\FieldWidget;
+
+use Drupal\Core\Field\WidgetBase;
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+
+/**
+ * Plugin implementation of the 'file_generic' widget.
+ *
+ * @FieldWidget(
+ *   id = "file_generic",
+ *   label = @Translation("File"),
+ *   field_types = {
+ *     "file"
+ *   },
+ *   settings = {
+ *     "progress_indicator" = "throbber"
+ *   }
+ * )
+ */
+class FileWidget extends WidgetBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    $element['progress_indicator'] = array(
+      '#type' => 'radios',
+      '#title' => t('Progress indicator'),
+      '#options' => array(
+        'throbber' => t('Throbber'),
+        'bar' => t('Bar with progress meter'),
+      ),
+      '#default_value' => $this->getSetting('progress_indicator'),
+      '#description' => t('The throbber display does not show the status of uploads but takes up less space. The progress bar is helpful for monitoring progress on large uploads.'),
+      '#weight' => 16,
+      '#access' => file_progress_implementation(),
+    );
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = array();
+    $summary[] = t('Progress indicator: @progress_indicator', array('@progress_indicator' => $this->getSetting('progress_indicator')));
+    return $summary;
+  }
+
+  /**
+   * Overrides \Drupal\Core\Field\WidgetBase::formMultipleElements().
+   *
+   * Special handling for draggable multiple widgets and 'add more' button.
+   */
+  protected function formMultipleElements(FieldItemListInterface $items, array &$form, array &$form_state) {
+    $field_name = $this->fieldDefinition->getFieldName();
+    $parents = $form['#parents'];
+
+    // Load the items for form rebuilds from the field state as they might not be
+    // in $form_state['values'] because of validation limitations. Also, they are
+    // only passed in as $items when editing existing entities.
+    $field_state = field_form_get_state($parents, $field_name, $form_state);
+    if (isset($field_state['items'])) {
+      $items->setValue($field_state['items']);
+    }
+
+    // Determine the number of widgets to display.
+    $cardinality = $this->fieldDefinition->getFieldCardinality();
+    switch ($cardinality) {
+      case FIELD_CARDINALITY_UNLIMITED:
+        $max = count($items);
+        $is_multiple = TRUE;
+        break;
+
+      default:
+        $max = $cardinality - 1;
+        $is_multiple = ($cardinality > 1);
+        break;
+    }
+
+    $title = check_plain($this->fieldDefinition->getFieldLabel());
+    $description = field_filter_xss($this->fieldDefinition->getFieldDescription());
+
+    $elements = array();
+
+    $delta = 0;
+    // Add an element for every existing item.
+    foreach ($items as $item) {
+      $element = array(
+        '#title' => $title,
+        '#description' => $description,
+      );
+      $element = $this->formSingleElement($items, $delta, $element, $form, $form_state);
+
+      if ($element) {
+        // Input field for the delta (drag-n-drop reordering).
+        if ($is_multiple) {
+          // We name the element '_weight' to avoid clashing with elements
+          // defined by widget.
+          $element['_weight'] = array(
+            '#type' => 'weight',
+            '#title' => t('Weight for row @number', array('@number' => $delta + 1)),
+            '#title_display' => 'invisible',
+            // Note: this 'delta' is the FAPI #type 'weight' element's property.
+            '#delta' => $max,
+            '#default_value' => $item->_weight ?: $delta,
+            '#weight' => 100,
+          );
+        }
+
+        $elements[$delta] = $element;
+        $delta++;
+      }
+    }
+
+    $empty_single_allowed = ($cardinality == 1 && $delta == 0);
+    $empty_multiple_allowed = ($cardinality == FIELD_CARDINALITY_UNLIMITED || $delta < $cardinality) && empty($form_state['programmed']);
+
+    // Add one more empty row for new uploads except when this is a programmed
+    // multiple form as it is not necessary.
+    if ($empty_single_allowed || $empty_multiple_allowed) {
+      $element = array(
+        '#title' => $title,
+        '#description' => $description,
+      );
+      $element = $this->formSingleElement($items, $delta, $element, $form, $form_state);
+      if ($element) {
+        $element['#required'] = ($element['#required'] && $delta == 0);
+        $elements[$delta] = $element;
+      }
+    }
+
+    if ($is_multiple) {
+      // The group of elements all-together need some extra functionality after
+      // building up the full list (like draggable table rows).
+      $elements['#file_upload_delta'] = $delta;
+      $elements['#type'] = 'details';
+      $elements['#theme'] = 'file_widget_multiple';
+      $elements['#theme_wrappers'] = array('details');
+      $elements['#process'] = array('file_field_widget_process_multiple');
+      $elements['#title'] = $title;
+
+      $elements['#description'] = $description;
+      $elements['#field_name'] = $element['#field_name'];
+      $elements['#language'] = $element['#language'];
+      $elements['#display_field'] = (bool) $this->getFieldSetting('display_field');
+
+      // Add some properties that will eventually be added to the file upload
+      // field. These are added here so that they may be referenced easily
+      // through a hook_form_alter().
+      $elements['#file_upload_title'] = t('Add a new file');
+      $elements['#file_upload_description'] = array(
+        '#theme' => 'file_upload_help',
+        '#description' => '',
+        '#upload_validators' => $elements[0]['#upload_validators'],
+        '#cardinality' => $cardinality,
+      );
+    }
+
+    return $elements;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
+    $field_settings = $this->getFieldSettings();
+
+    // The field settings include defaults for the field type. However, this
+    // widget is a base class for other widgets (e.g., ImageWidget) that may act
+    // on field types without these expected settings.
+    $field_settings += array(
+      'display_default' => NULL,
+      'display_field' => NULL,
+      'description_field' => NULL,
+    );
+
+    $cardinality = $this->fieldDefinition->getFieldCardinality();
+    $defaults = array(
+      'fids' => array(),
+      'display' => (bool) $field_settings['display_default'],
+      'description' => '',
+    );
+
+    // Essentially we use the managed_file type, extended with some
+    // enhancements.
+    $element_info = element_info('managed_file');
+    $element += array(
+      '#type' => 'managed_file',
+      '#upload_location' => $items[$delta]->getUploadLocation(),
+      '#upload_validators' => $items[$delta]->getUploadValidators(),
+      '#value_callback' => 'file_field_widget_value',
+      '#process' => array_merge($element_info['#process'], array('file_field_widget_process')),
+      '#progress_indicator' => $this->getSetting('progress_indicator'),
+      // Allows this field to return an array instead of a single value.
+      '#extended' => TRUE,
+      // Add properties needed by file_field_widget_value() and
+      // file_field_widget_process().
+      '#display_field' => (bool) $field_settings['display_field'],
+      '#display_default' => $field_settings['display_default'],
+      '#description_field' => $field_settings['description_field'],
+      '#cardinality' => $cardinality,
+    );
+
+    $element['#weight'] = $delta;
+
+    // Field stores FID value in a single mode, so we need to transform it for
+    // form element to recognize it correctly.
+    if (!isset($items[$delta]->fids) && isset($items[$delta]->target_id)) {
+      $items[$delta]->fids = array($items[$delta]->target_id);
+    }
+    $element['#default_value'] = $items[$delta]->getValue() + $defaults;
+
+    $default_fids = $element['#extended'] ? $element['#default_value']['fids'] : $element['#default_value'];
+    if (empty($default_fids)) {
+      $file_upload_help = array(
+        '#theme' => 'file_upload_help',
+        '#description' => $element['#description'],
+        '#upload_validators' => $element['#upload_validators'],
+        '#cardinality' => $cardinality,
+      );
+      $element['#description'] = drupal_render($file_upload_help);
+      $element['#multiple'] = $cardinality != 1 ? TRUE : FALSE;
+      if ($cardinality != 1 && $cardinality != -1) {
+        $element['#element_validate'] = array('file_field_widget_multiple_count_validate');
+      }
+    }
+
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function massageFormValues(array $values, array $form, array &$form_state) {
+    // Since file upload widget now supports uploads of more than one file at a
+    // time it always returns an array of fids. We have to translate this to a
+    // single fid, as field expects single value.
+    $new_values = array();
+    foreach ($values as &$value) {
+      foreach ($value['fids'] as $fid) {
+        $new_value = $value;
+        $new_value['target_id'] = $fid;
+        unset($new_value['fids']);
+        $new_values[] = $new_value;
+      }
+    }
+
+    return $new_values;
+  }
+
+}
diff --git a/core/modules/file/lib/Drupal/file/Plugin/field/formatter/FileFormatterBase.php b/core/modules/file/lib/Drupal/file/Plugin/field/formatter/FileFormatterBase.php
deleted file mode 100644
index 306861a..0000000
--- a/core/modules/file/lib/Drupal/file/Plugin/field/formatter/FileFormatterBase.php
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\file\Plugin\field\formatter\FileFormatterBase.
- */
-
-namespace Drupal\file\Plugin\field\formatter;
-
-use Drupal\field\Plugin\Type\Formatter\FormatterBase;
-
-/**
- * Base class for file formatters.
- */
-abstract class FileFormatterBase extends FormatterBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function prepareView(array $entities_items) {
-    // Remove files specified to not be displayed.
-    $fids = array();
-    foreach ($entities_items as $items) {
-      foreach ($items as $item) {
-        if ($item->isDisplayed() && !empty($item->target_id)) {
-          // Load the files from the files table.
-          $fids[] = $item->target_id;
-        }
-      }
-    }
-
-    if ($fids) {
-      $files = file_load_multiple($fids);
-
-      foreach ($entities_items as $items) {
-        foreach ($items as $item) {
-          // If the file does not exist, mark the entire item as empty.
-          if (!empty($item->target_id)) {
-            $item->entity = isset($files[$item->target_id]) ? $files[$item->target_id] : NULL;
-          }
-        }
-      }
-    }
-  }
-}
diff --git a/core/modules/file/lib/Drupal/file/Plugin/field/formatter/GenericFileFormatter.php b/core/modules/file/lib/Drupal/file/Plugin/field/formatter/GenericFileFormatter.php
deleted file mode 100644
index a41d9be..0000000
--- a/core/modules/file/lib/Drupal/file/Plugin/field/formatter/GenericFileFormatter.php
+++ /dev/null
@@ -1,52 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\file\Plugin\field\formatter\GenericFileFormatter.
- */
-
-namespace Drupal\file\Plugin\field\formatter;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-
-/**
- * Plugin implementation of the 'file_default' formatter.
- *
- * @FieldFormatter(
- *   id = "file_default",
- *   label = @Translation("Generic file"),
- *   field_types = {
- *     "file"
- *   }
- * )
- */
-class GenericFileFormatter extends FileFormatterBase {
-
-  /**
-   * Implements \Drupal\field\Plugin\Type\Formatter\FormatterInterface::viewElements().
-   */
-  public function viewElements(FieldItemListInterface $items) {
-    $elements = array();
-
-    foreach ($items as $delta => $item) {
-      if ($item->isDisplayed() && $item->entity) {
-        $elements[$delta] = array(
-          '#theme' => 'file_link',
-          '#file' => $item->entity,
-          '#description' => $item->description,
-        );
-        // Pass field item attributes to the theme function.
-        if (isset($item->_attributes)) {
-          $elements[$delta] += array('#attributes' => array());
-          $elements[$delta]['#attributes'] += $item->_attributes;
-          // Unset field item attributes since they have been included in the
-          // formatter output and should not be rendered in the field template.
-          unset($item->_attributes);
-        }
-      }
-    }
-
-    return $elements;
-  }
-
-}
diff --git a/core/modules/file/lib/Drupal/file/Plugin/field/formatter/RSSEnclosureFormatter.php b/core/modules/file/lib/Drupal/file/Plugin/field/formatter/RSSEnclosureFormatter.php
deleted file mode 100644
index 55e40b7..0000000
--- a/core/modules/file/lib/Drupal/file/Plugin/field/formatter/RSSEnclosureFormatter.php
+++ /dev/null
@@ -1,49 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\file\Plugin\field\formatter\RSSEnclosureFormatter.
- */
-
-namespace Drupal\file\Plugin\field\formatter;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-
-/**
- * Plugin implementation of the 'file_rss_enclosure' formatter.
- *
- * @FieldFormatter(
- *   id = "file_rss_enclosure",
- *   label = @Translation("RSS enclosure"),
- *   field_types = {
- *     "file"
- *   }
- * )
- */
-class RSSEnclosureFormatter extends FileFormatterBase {
-
-  /**
-   * Implements \Drupal\field\Plugin\Type\Formatter\FormatterInterface::viewElements().
-   */
-  public function viewElements(FieldItemListInterface $items) {
-    $entity = $items->getEntity();
-    // Add the first file as an enclosure to the RSS item. RSS allows only one
-    // enclosure per item. See: http://en.wikipedia.org/wiki/RSS_enclosure
-    foreach ($items as $item) {
-      if ($item->isDisplayed() && $item->entity) {
-        $file = $item->entity;
-        $entity->rss_elements[] = array(
-          'key' => 'enclosure',
-          'attributes' => array(
-            'url' => file_create_url($file->getFileUri()),
-            'length' => $file->getSize(),
-            'type' => $file->getMimeType(),
-          ),
-        );
-        break;
-      }
-    }
-
-  }
-
-}
diff --git a/core/modules/file/lib/Drupal/file/Plugin/field/formatter/TableFormatter.php b/core/modules/file/lib/Drupal/file/Plugin/field/formatter/TableFormatter.php
deleted file mode 100644
index 722b60a..0000000
--- a/core/modules/file/lib/Drupal/file/Plugin/field/formatter/TableFormatter.php
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\file\Plugin\field\formatter\TableFormatter.
- */
-
-namespace Drupal\file\Plugin\field\formatter;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-
-/**
- * Plugin implementation of the 'file_table' formatter.
- *
- * @FieldFormatter(
- *   id = "file_table",
- *   label = @Translation("Table of files"),
- *   field_types = {
- *     "file"
- *   }
- * )
- */
-class TableFormatter extends FileFormatterBase {
-
-  /**
-   * Implements \Drupal\field\Plugin\Type\Formatter\FormatterInterface::viewElements().
-   */
-  public function viewElements(FieldItemListInterface $items) {
-    $elements = array();
-
-    if (!$items->isEmpty()) {
-      // Display all values in a single element.
-      $elements[0] = array(
-        '#theme' => 'file_formatter_table',
-        '#items' => $items,
-      );
-    }
-
-    return $elements;
-  }
-
-}
diff --git a/core/modules/file/lib/Drupal/file/Plugin/field/formatter/UrlPlainFormatter.php b/core/modules/file/lib/Drupal/file/Plugin/field/formatter/UrlPlainFormatter.php
deleted file mode 100644
index 4a91979..0000000
--- a/core/modules/file/lib/Drupal/file/Plugin/field/formatter/UrlPlainFormatter.php
+++ /dev/null
@@ -1,40 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\file\Plugin\field\formatter\UrlPlainFormatter.
- */
-
-namespace Drupal\file\Plugin\field\formatter;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-
-/**
- * Plugin implementation of the 'file_url_plain' formatter.
- *
- * @FieldFormatter(
- *   id = "file_url_plain",
- *   label = @Translation("URL to file"),
- *   field_types = {
- *     "file"
- *   }
- * )
- */
-class UrlPlainFormatter extends FileFormatterBase {
-
-  /**
-   * Implements \Drupal\field\Plugin\Type\Formatter\FormatterInterface::viewElements().
-   */
-  public function viewElements(FieldItemListInterface $items) {
-    $elements = array();
-
-    foreach ($items as $delta => $item) {
-      if ($item->isDisplayed() && $item->entity) {
-        $elements[$delta] = array('#markup' => empty($item->entity) ? '' : file_create_url($item->entity->getFileUri()));
-      }
-    }
-
-    return $elements;
-  }
-
-}
diff --git a/core/modules/file/lib/Drupal/file/Plugin/field/widget/FileWidget.php b/core/modules/file/lib/Drupal/file/Plugin/field/widget/FileWidget.php
deleted file mode 100644
index b0ed274..0000000
--- a/core/modules/file/lib/Drupal/file/Plugin/field/widget/FileWidget.php
+++ /dev/null
@@ -1,259 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\file\Plugin\field\widget\FileWidget.
- */
-
-namespace Drupal\file\Plugin\field\widget;
-
-use Drupal\field\Plugin\Type\Widget\WidgetBase;
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-
-/**
- * Plugin implementation of the 'file_generic' widget.
- *
- * @FieldWidget(
- *   id = "file_generic",
- *   label = @Translation("File"),
- *   field_types = {
- *     "file"
- *   },
- *   settings = {
- *     "progress_indicator" = "throbber"
- *   }
- * )
- */
-class FileWidget extends WidgetBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsForm(array $form, array &$form_state) {
-    $element['progress_indicator'] = array(
-      '#type' => 'radios',
-      '#title' => t('Progress indicator'),
-      '#options' => array(
-        'throbber' => t('Throbber'),
-        'bar' => t('Bar with progress meter'),
-      ),
-      '#default_value' => $this->getSetting('progress_indicator'),
-      '#description' => t('The throbber display does not show the status of uploads but takes up less space. The progress bar is helpful for monitoring progress on large uploads.'),
-      '#weight' => 16,
-      '#access' => file_progress_implementation(),
-    );
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    $summary = array();
-    $summary[] = t('Progress indicator: @progress_indicator', array('@progress_indicator' => $this->getSetting('progress_indicator')));
-    return $summary;
-  }
-
-  /**
-   * Overrides \Drupal\field\Plugin\Type\Widget\WidgetBase::formMultipleElements().
-   *
-   * Special handling for draggable multiple widgets and 'add more' button.
-   */
-  protected function formMultipleElements(FieldItemListInterface $items, array &$form, array &$form_state) {
-    $field_name = $this->fieldDefinition->getFieldName();
-    $parents = $form['#parents'];
-
-    // Load the items for form rebuilds from the field state as they might not be
-    // in $form_state['values'] because of validation limitations. Also, they are
-    // only passed in as $items when editing existing entities.
-    $field_state = field_form_get_state($parents, $field_name, $form_state);
-    if (isset($field_state['items'])) {
-      $items->setValue($field_state['items']);
-    }
-
-    // Determine the number of widgets to display.
-    $cardinality = $this->fieldDefinition->getFieldCardinality();
-    switch ($cardinality) {
-      case FIELD_CARDINALITY_UNLIMITED:
-        $max = count($items);
-        $is_multiple = TRUE;
-        break;
-
-      default:
-        $max = $cardinality - 1;
-        $is_multiple = ($cardinality > 1);
-        break;
-    }
-
-    $title = check_plain($this->fieldDefinition->getFieldLabel());
-    $description = field_filter_xss($this->fieldDefinition->getFieldDescription());
-
-    $elements = array();
-
-    $delta = 0;
-    // Add an element for every existing item.
-    foreach ($items as $item) {
-      $element = array(
-        '#title' => $title,
-        '#description' => $description,
-      );
-      $element = $this->formSingleElement($items, $delta, $element, $form, $form_state);
-
-      if ($element) {
-        // Input field for the delta (drag-n-drop reordering).
-        if ($is_multiple) {
-          // We name the element '_weight' to avoid clashing with elements
-          // defined by widget.
-          $element['_weight'] = array(
-            '#type' => 'weight',
-            '#title' => t('Weight for row @number', array('@number' => $delta + 1)),
-            '#title_display' => 'invisible',
-            // Note: this 'delta' is the FAPI #type 'weight' element's property.
-            '#delta' => $max,
-            '#default_value' => $item->_weight ?: $delta,
-            '#weight' => 100,
-          );
-        }
-
-        $elements[$delta] = $element;
-        $delta++;
-      }
-    }
-
-    $empty_single_allowed = ($cardinality == 1 && $delta == 0);
-    $empty_multiple_allowed = ($cardinality == FIELD_CARDINALITY_UNLIMITED || $delta < $cardinality) && empty($form_state['programmed']);
-
-    // Add one more empty row for new uploads except when this is a programmed
-    // multiple form as it is not necessary.
-    if ($empty_single_allowed || $empty_multiple_allowed) {
-      $element = array(
-        '#title' => $title,
-        '#description' => $description,
-      );
-      $element = $this->formSingleElement($items, $delta, $element, $form, $form_state);
-      if ($element) {
-        $element['#required'] = ($element['#required'] && $delta == 0);
-        $elements[$delta] = $element;
-      }
-    }
-
-    if ($is_multiple) {
-      // The group of elements all-together need some extra functionality after
-      // building up the full list (like draggable table rows).
-      $elements['#file_upload_delta'] = $delta;
-      $elements['#type'] = 'details';
-      $elements['#theme'] = 'file_widget_multiple';
-      $elements['#theme_wrappers'] = array('details');
-      $elements['#process'] = array('file_field_widget_process_multiple');
-      $elements['#title'] = $title;
-
-      $elements['#description'] = $description;
-      $elements['#field_name'] = $element['#field_name'];
-      $elements['#language'] = $element['#language'];
-      $elements['#display_field'] = (bool) $this->getFieldSetting('display_field');
-
-      // Add some properties that will eventually be added to the file upload
-      // field. These are added here so that they may be referenced easily
-      // through a hook_form_alter().
-      $elements['#file_upload_title'] = t('Add a new file');
-      $elements['#file_upload_description'] = array(
-        '#theme' => 'file_upload_help',
-        '#description' => '',
-        '#upload_validators' => $elements[0]['#upload_validators'],
-        '#cardinality' => $cardinality,
-      );
-    }
-
-    return $elements;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
-    $field_settings = $this->getFieldSettings();
-
-    // The field settings include defaults for the field type. However, this
-    // widget is a base class for other widgets (e.g., ImageWidget) that may act
-    // on field types without these expected settings.
-    $field_settings += array(
-      'display_default' => NULL,
-      'display_field' => NULL,
-      'description_field' => NULL,
-    );
-
-    $cardinality = $this->fieldDefinition->getFieldCardinality();
-    $defaults = array(
-      'fids' => array(),
-      'display' => (bool) $field_settings['display_default'],
-      'description' => '',
-    );
-
-    // Essentially we use the managed_file type, extended with some
-    // enhancements.
-    $element_info = element_info('managed_file');
-    $element += array(
-      '#type' => 'managed_file',
-      '#upload_location' => $items[$delta]->getUploadLocation(),
-      '#upload_validators' => $items[$delta]->getUploadValidators(),
-      '#value_callback' => 'file_field_widget_value',
-      '#process' => array_merge($element_info['#process'], array('file_field_widget_process')),
-      '#progress_indicator' => $this->getSetting('progress_indicator'),
-      // Allows this field to return an array instead of a single value.
-      '#extended' => TRUE,
-      // Add properties needed by file_field_widget_value() and
-      // file_field_widget_process().
-      '#display_field' => (bool) $field_settings['display_field'],
-      '#display_default' => $field_settings['display_default'],
-      '#description_field' => $field_settings['description_field'],
-      '#cardinality' => $cardinality,
-    );
-
-    $element['#weight'] = $delta;
-
-    // Field stores FID value in a single mode, so we need to transform it for
-    // form element to recognize it correctly.
-    if (!isset($items[$delta]->fids) && isset($items[$delta]->target_id)) {
-      $items[$delta]->fids = array($items[$delta]->target_id);
-    }
-    $element['#default_value'] = $items[$delta]->getValue() + $defaults;
-
-    $default_fids = $element['#extended'] ? $element['#default_value']['fids'] : $element['#default_value'];
-    if (empty($default_fids)) {
-      $file_upload_help = array(
-        '#theme' => 'file_upload_help',
-        '#description' => $element['#description'],
-        '#upload_validators' => $element['#upload_validators'],
-        '#cardinality' => $cardinality,
-      );
-      $element['#description'] = drupal_render($file_upload_help);
-      $element['#multiple'] = $cardinality != 1 ? TRUE : FALSE;
-      if ($cardinality != 1 && $cardinality != -1) {
-        $element['#element_validate'] = array('file_field_widget_multiple_count_validate');
-      }
-    }
-
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function massageFormValues(array $values, array $form, array &$form_state) {
-    // Since file upload widget now supports uploads of more than one file at a
-    // time it always returns an array of fids. We have to translate this to a
-    // single fid, as field expects single value.
-    $new_values = array();
-    foreach ($values as &$value) {
-      foreach ($value['fids'] as $fid) {
-        $new_value = $value;
-        $new_value['target_id'] = $fid;
-        unset($new_value['fids']);
-        $new_values[] = $new_value;
-      }
-    }
-
-    return $new_values;
-  }
-
-}
diff --git a/core/modules/forum/forum.install b/core/modules/forum/forum.install
index 05bda60..3f7d02b 100644
--- a/core/modules/forum/forum.install
+++ b/core/modules/forum/forum.install
@@ -93,7 +93,7 @@ function forum_install() {
  * Implements hook_module_preinstall().
  */
 function forum_module_preinstall($module) {
-  $list_boolean = \Drupal::service('plugin.manager.entity.field.field_type')->getDefinition('list_boolean');
+  $list_boolean = \Drupal::service('plugin.manager.field.field_type')->getDefinition('list_boolean');
   if (empty($list_boolean) && $module == 'forum') {
     // Make sure that the list_boolean field type is available before our
     // default config is installed.
diff --git a/core/modules/image/lib/Drupal/image/Plugin/Field/FieldFormatter/ImageFormatter.php b/core/modules/image/lib/Drupal/image/Plugin/Field/FieldFormatter/ImageFormatter.php
new file mode 100644
index 0000000..b3cf4f2
--- /dev/null
+++ b/core/modules/image/lib/Drupal/image/Plugin/Field/FieldFormatter/ImageFormatter.php
@@ -0,0 +1,134 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\image\Plugin\field\formatter\ImageFormatter.
+ */
+
+namespace Drupal\image\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+
+/**
+ * Plugin implementation of the 'image' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "image",
+ *   label = @Translation("Image"),
+ *   field_types = {
+ *     "image"
+ *   },
+ *   settings = {
+ *     "image_style" = "",
+ *     "image_link" = ""
+ *   }
+ * )
+ */
+class ImageFormatter extends ImageFormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    $image_styles = image_style_options(FALSE);
+    $element['image_style'] = array(
+      '#title' => t('Image style'),
+      '#type' => 'select',
+      '#default_value' => $this->getSetting('image_style'),
+      '#empty_option' => t('None (original image)'),
+      '#options' => $image_styles,
+    );
+
+    $link_types = array(
+      'content' => t('Content'),
+      'file' => t('File'),
+    );
+    $element['image_link'] = array(
+      '#title' => t('Link image to'),
+      '#type' => 'select',
+      '#default_value' => $this->getSetting('image_link'),
+      '#empty_option' => t('Nothing'),
+      '#options' => $link_types,
+    );
+
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = array();
+
+    $image_styles = image_style_options(FALSE);
+    // Unset possible 'No defined styles' option.
+    unset($image_styles['']);
+    // Styles could be lost because of enabled/disabled modules that defines
+    // their styles in code.
+    $image_style_setting = $this->getSetting('image_style');
+    if (isset($image_styles[$image_style_setting])) {
+      $summary[] = t('Image style: @style', array('@style' => $image_styles[$image_style_setting]));
+    }
+    else {
+      $summary[] = t('Original image');
+    }
+
+    $link_types = array(
+      'content' => t('Linked to content'),
+      'file' => t('Linked to file'),
+    );
+    // Display this setting only if image is linked.
+    $image_link_setting = $this->getSetting('image_link');
+    if (isset($link_types[$image_link_setting])) {
+      $summary[] = $link_types[$image_link_setting];
+    }
+
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+    $elements = array();
+
+    $image_link_setting = $this->getSetting('image_link');
+    // Check if the formatter involves a link.
+    if ($image_link_setting == 'content') {
+      $uri = $items->getEntity()->uri();
+    }
+    elseif ($image_link_setting == 'file') {
+      $link_file = TRUE;
+    }
+
+    $image_style_setting = $this->getSetting('image_style');
+    foreach ($items as $delta => $item) {
+      if ($item->entity) {
+        if (isset($link_file)) {
+          $image_uri = $item->entity->getFileUri();
+          $uri = array(
+            'path' => file_create_url($image_uri),
+            'options' => array(),
+          );
+        }
+        $elements[$delta] = array(
+          '#theme' => 'image_formatter',
+          '#item' => $item->getValue(TRUE),
+          '#image_style' => $image_style_setting,
+          '#path' => isset($uri) ? $uri : '',
+        );
+        // Pass field item attributes to the theme function.
+        if (isset($item->_attributes)) {
+          $elements[$delta]['#item'] += array('attributes' => array());
+          $elements[$delta]['#item']['attributes'] += $item->_attributes;
+          // Unset field item attributes since they have been included in the
+          // formatter output and should not be rendered in the field template.
+          unset($item->_attributes);
+        }
+      }
+    }
+
+    return $elements;
+  }
+
+}
diff --git a/core/modules/image/lib/Drupal/image/Plugin/Field/FieldFormatter/ImageFormatterBase.php b/core/modules/image/lib/Drupal/image/Plugin/Field/FieldFormatter/ImageFormatterBase.php
new file mode 100644
index 0000000..c934270
--- /dev/null
+++ b/core/modules/image/lib/Drupal/image/Plugin/Field/FieldFormatter/ImageFormatterBase.php
@@ -0,0 +1,48 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\image\Plugin\field\formatter\ImageFormatterBase.
+ */
+
+namespace Drupal\image\Plugin\Field\FieldFormatter;
+
+use Drupal\field\FieldInstanceInterface;
+use Drupal\file\Plugin\Field\FieldFormatter\FileFormatterBase;
+
+/**
+ * Base class for image file formatters.
+ */
+abstract class ImageFormatterBase extends FileFormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function prepareView(array $entities_items) {
+    parent::prepareView($entities_items);
+
+    // If there are no files specified at all, use the default.
+    foreach ($entities_items as $items) {
+      if ($items->isEmpty()) {
+        // Add the default image if one is found.
+        $fid = $this->getFieldSetting('default_image');
+        // If we are dealing with a configurable field, look in both
+        // instance-level and field-level settings.
+        if (empty($fid) && $this->fieldDefinition instanceof FieldInstanceInterface) {
+          $fid = $this->fieldDefinition->getField()->getFieldSetting('default_image');
+        }
+
+        if ($fid && ($file = file_load($fid))) {
+          $items->setValue(array(array(
+            'is_default' => TRUE,
+            'alt' => '',
+            'title' => '',
+            'entity' => $file,
+            'target_id' => $file->id(),
+          )));
+        }
+      }
+    }
+  }
+
+}
diff --git a/core/modules/image/lib/Drupal/image/Plugin/Field/FieldWidget/ImageWidget.php b/core/modules/image/lib/Drupal/image/Plugin/Field/FieldWidget/ImageWidget.php
new file mode 100644
index 0000000..2febebe
--- /dev/null
+++ b/core/modules/image/lib/Drupal/image/Plugin/Field/FieldWidget/ImageWidget.php
@@ -0,0 +1,131 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\image\Plugin\Field\FieldWidget\ImageWidget.
+ */
+
+namespace Drupal\image\Plugin\Field\FieldWidget;
+
+use Drupal\file\Plugin\Field\FieldWidget\FileWidget;
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+
+/**
+ * Plugin implementation of the 'image_image' widget.
+ *
+ * @FieldWidget(
+ *   id = "image_image",
+ *   label = @Translation("Image"),
+ *   field_types = {
+ *     "image"
+ *   },
+ *   settings = {
+ *     "progress_indicator" = "throbber",
+ *     "preview_image_style" = "thumbnail",
+ *   }
+ * )
+ */
+class ImageWidget extends FileWidget {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    $element = parent::settingsForm($form, $form_state);
+
+    $element['preview_image_style'] = array(
+      '#title' => t('Preview image style'),
+      '#type' => 'select',
+      '#options' => image_style_options(FALSE),
+      '#empty_option' => '<' . t('no preview') . '>',
+      '#default_value' => $this->getSetting('preview_image_style'),
+      '#description' => t('The preview image will be shown while editing the content.'),
+      '#weight' => 15,
+    );
+
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = parent::settingsSummary();
+
+    $image_styles = image_style_options(FALSE);
+    // Unset possible 'No defined styles' option.
+    unset($image_styles['']);
+    // Styles could be lost because of enabled/disabled modules that defines
+    // their styles in code.
+    $image_style_setting = $this->getSetting('preview_image_style');
+    if (isset($image_styles[$image_style_setting])) {
+      $preview_image_style = t('Preview image style: @style', array('@style' => $image_styles[$image_style_setting]));
+    }
+    else {
+      $preview_image_style = t('Original image');
+    }
+
+    array_unshift($summary, $preview_image_style);
+
+    return $summary;
+  }
+
+  /**
+   * Overrides \Drupal\file\Plugin\Field\FieldWidget\FileWidget::formMultipleElements().
+   *
+   * Special handling for draggable multiple widgets and 'add more' button.
+   */
+  protected function formMultipleElements(FieldItemListInterface $items, array &$form, array &$form_state) {
+    $elements = parent::formMultipleElements($items, $form, $form_state);
+
+    $cardinality = $this->fieldDefinition->getFieldCardinality();
+    $file_upload_help = array(
+      '#theme' => 'file_upload_help',
+      '#upload_validators' => $elements[0]['#upload_validators'],
+      '#cardinality' => $cardinality,
+    );
+    if ($cardinality == 1) {
+      // If there's only one field, return it as delta 0.
+      if (empty($elements[0]['#default_value']['fids'])) {
+        $file_upload_help['#description'] = $this->fieldDefinition->getFieldDescription();
+        $elements[0]['#description'] = drupal_render($file_upload_help);
+      }
+    }
+    else {
+      $elements['#file_upload_description'] = drupal_render($file_upload_help);
+    }
+
+    return $elements;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
+    $element = parent::formElement($items, $delta, $element, $form, $form_state);
+
+    $field_settings = $this->getFieldSettings();
+
+    // Add upload resolution validation.
+    if ($field_settings['max_resolution'] || $field_settings['min_resolution']) {
+      $element['#upload_validators']['file_validate_image_resolution'] = array($field_settings['max_resolution'], $field_settings['min_resolution']);
+    }
+
+    // If not using custom extension validation, ensure this is an image.
+    $supported_extensions = array('png', 'gif', 'jpg', 'jpeg');
+    $extensions = isset($element['#upload_validators']['file_validate_extensions'][0]) ? $element['#upload_validators']['file_validate_extensions'][0] : implode(' ', $supported_extensions);
+    $extensions = array_intersect(explode(' ', $extensions), $supported_extensions);
+    $element['#upload_validators']['file_validate_extensions'][0] = implode(' ', $extensions);
+
+    // Add all extra functionality provided by the image widget.
+    $element['#process'][] = 'image_field_widget_process';
+    // Add properties needed by image_field_widget_process().
+    $element['#preview_image_style'] = $this->getSetting('preview_image_style');
+    $element['#title_field'] = $field_settings['title_field'];
+    $element['#alt_field'] = $field_settings['alt_field'];
+    $element['#alt_field_required'] = $field_settings['alt_field_required'];
+
+    return $element;
+  }
+
+}
diff --git a/core/modules/image/lib/Drupal/image/Plugin/field/formatter/ImageFormatter.php b/core/modules/image/lib/Drupal/image/Plugin/field/formatter/ImageFormatter.php
deleted file mode 100644
index 463dc17..0000000
--- a/core/modules/image/lib/Drupal/image/Plugin/field/formatter/ImageFormatter.php
+++ /dev/null
@@ -1,134 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\image\Plugin\field\formatter\ImageFormatter.
- */
-
-namespace Drupal\image\Plugin\field\formatter;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-
-/**
- * Plugin implementation of the 'image' formatter.
- *
- * @FieldFormatter(
- *   id = "image",
- *   label = @Translation("Image"),
- *   field_types = {
- *     "image"
- *   },
- *   settings = {
- *     "image_style" = "",
- *     "image_link" = ""
- *   }
- * )
- */
-class ImageFormatter extends ImageFormatterBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsForm(array $form, array &$form_state) {
-    $image_styles = image_style_options(FALSE);
-    $element['image_style'] = array(
-      '#title' => t('Image style'),
-      '#type' => 'select',
-      '#default_value' => $this->getSetting('image_style'),
-      '#empty_option' => t('None (original image)'),
-      '#options' => $image_styles,
-    );
-
-    $link_types = array(
-      'content' => t('Content'),
-      'file' => t('File'),
-    );
-    $element['image_link'] = array(
-      '#title' => t('Link image to'),
-      '#type' => 'select',
-      '#default_value' => $this->getSetting('image_link'),
-      '#empty_option' => t('Nothing'),
-      '#options' => $link_types,
-    );
-
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    $summary = array();
-
-    $image_styles = image_style_options(FALSE);
-    // Unset possible 'No defined styles' option.
-    unset($image_styles['']);
-    // Styles could be lost because of enabled/disabled modules that defines
-    // their styles in code.
-    $image_style_setting = $this->getSetting('image_style');
-    if (isset($image_styles[$image_style_setting])) {
-      $summary[] = t('Image style: @style', array('@style' => $image_styles[$image_style_setting]));
-    }
-    else {
-      $summary[] = t('Original image');
-    }
-
-    $link_types = array(
-      'content' => t('Linked to content'),
-      'file' => t('Linked to file'),
-    );
-    // Display this setting only if image is linked.
-    $image_link_setting = $this->getSetting('image_link');
-    if (isset($link_types[$image_link_setting])) {
-      $summary[] = $link_types[$image_link_setting];
-    }
-
-    return $summary;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function viewElements(FieldItemListInterface $items) {
-    $elements = array();
-
-    $image_link_setting = $this->getSetting('image_link');
-    // Check if the formatter involves a link.
-    if ($image_link_setting == 'content') {
-      $uri = $items->getEntity()->uri();
-    }
-    elseif ($image_link_setting == 'file') {
-      $link_file = TRUE;
-    }
-
-    $image_style_setting = $this->getSetting('image_style');
-    foreach ($items as $delta => $item) {
-      if ($item->entity) {
-        if (isset($link_file)) {
-          $image_uri = $item->entity->getFileUri();
-          $uri = array(
-            'path' => file_create_url($image_uri),
-            'options' => array(),
-          );
-        }
-        $elements[$delta] = array(
-          '#theme' => 'image_formatter',
-          '#item' => $item->getValue(TRUE),
-          '#image_style' => $image_style_setting,
-          '#path' => isset($uri) ? $uri : '',
-        );
-        // Pass field item attributes to the theme function.
-        if (isset($item->_attributes)) {
-          $elements[$delta]['#item'] += array('attributes' => array());
-          $elements[$delta]['#item']['attributes'] += $item->_attributes;
-          // Unset field item attributes since they have been included in the
-          // formatter output and should not be rendered in the field template.
-          unset($item->_attributes);
-        }
-      }
-    }
-
-    return $elements;
-  }
-
-}
diff --git a/core/modules/image/lib/Drupal/image/Plugin/field/formatter/ImageFormatterBase.php b/core/modules/image/lib/Drupal/image/Plugin/field/formatter/ImageFormatterBase.php
deleted file mode 100644
index 03d2727..0000000
--- a/core/modules/image/lib/Drupal/image/Plugin/field/formatter/ImageFormatterBase.php
+++ /dev/null
@@ -1,48 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\image\Plugin\field\formatter\ImageFormatterBase.
- */
-
-namespace Drupal\image\Plugin\field\formatter;
-
-use Drupal\field\FieldInstanceInterface;
-use Drupal\file\Plugin\field\formatter\FileFormatterBase;
-
-/**
- * Base class for image file formatters.
- */
-abstract class ImageFormatterBase extends FileFormatterBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function prepareView(array $entities_items) {
-    parent::prepareView($entities_items);
-
-    // If there are no files specified at all, use the default.
-    foreach ($entities_items as $items) {
-      if ($items->isEmpty()) {
-        // Add the default image if one is found.
-        $fid = $this->getFieldSetting('default_image');
-        // If we are dealing with a configurable field, look in both
-        // instance-level and field-level settings.
-        if (empty($fid) && $this->fieldDefinition instanceof FieldInstanceInterface) {
-          $fid = $this->fieldDefinition->getField()->getFieldSetting('default_image');
-        }
-
-        if ($fid && ($file = file_load($fid))) {
-          $items->setValue(array(array(
-            'is_default' => TRUE,
-            'alt' => '',
-            'title' => '',
-            'entity' => $file,
-            'target_id' => $file->id(),
-          )));
-        }
-      }
-    }
-  }
-
-}
diff --git a/core/modules/image/lib/Drupal/image/Plugin/field/widget/ImageWidget.php b/core/modules/image/lib/Drupal/image/Plugin/field/widget/ImageWidget.php
deleted file mode 100644
index 9a25789..0000000
--- a/core/modules/image/lib/Drupal/image/Plugin/field/widget/ImageWidget.php
+++ /dev/null
@@ -1,131 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\image\Plugin\field\widget\ImageWidget.
- */
-
-namespace Drupal\image\Plugin\field\widget;
-
-use Drupal\file\Plugin\field\widget\FileWidget;
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-
-/**
- * Plugin implementation of the 'image_image' widget.
- *
- * @FieldWidget(
- *   id = "image_image",
- *   label = @Translation("Image"),
- *   field_types = {
- *     "image"
- *   },
- *   settings = {
- *     "progress_indicator" = "throbber",
- *     "preview_image_style" = "thumbnail",
- *   }
- * )
- */
-class ImageWidget extends FileWidget {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsForm(array $form, array &$form_state) {
-    $element = parent::settingsForm($form, $form_state);
-
-    $element['preview_image_style'] = array(
-      '#title' => t('Preview image style'),
-      '#type' => 'select',
-      '#options' => image_style_options(FALSE),
-      '#empty_option' => '<' . t('no preview') . '>',
-      '#default_value' => $this->getSetting('preview_image_style'),
-      '#description' => t('The preview image will be shown while editing the content.'),
-      '#weight' => 15,
-    );
-
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    $summary = parent::settingsSummary();
-
-    $image_styles = image_style_options(FALSE);
-    // Unset possible 'No defined styles' option.
-    unset($image_styles['']);
-    // Styles could be lost because of enabled/disabled modules that defines
-    // their styles in code.
-    $image_style_setting = $this->getSetting('preview_image_style');
-    if (isset($image_styles[$image_style_setting])) {
-      $preview_image_style = t('Preview image style: @style', array('@style' => $image_styles[$image_style_setting]));
-    }
-    else {
-      $preview_image_style = t('Original image');
-    }
-
-    array_unshift($summary, $preview_image_style);
-
-    return $summary;
-  }
-
-  /**
-   * Overrides \Drupal\file\Plugin\field\widget\FileWidget::formMultipleElements().
-   *
-   * Special handling for draggable multiple widgets and 'add more' button.
-   */
-  protected function formMultipleElements(FieldItemListInterface $items, array &$form, array &$form_state) {
-    $elements = parent::formMultipleElements($items, $form, $form_state);
-
-    $cardinality = $this->fieldDefinition->getFieldCardinality();
-    $file_upload_help = array(
-      '#theme' => 'file_upload_help',
-      '#upload_validators' => $elements[0]['#upload_validators'],
-      '#cardinality' => $cardinality,
-    );
-    if ($cardinality == 1) {
-      // If there's only one field, return it as delta 0.
-      if (empty($elements[0]['#default_value']['fids'])) {
-        $file_upload_help['#description'] = $this->fieldDefinition->getFieldDescription();
-        $elements[0]['#description'] = drupal_render($file_upload_help);
-      }
-    }
-    else {
-      $elements['#file_upload_description'] = drupal_render($file_upload_help);
-    }
-
-    return $elements;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
-    $element = parent::formElement($items, $delta, $element, $form, $form_state);
-
-    $field_settings = $this->getFieldSettings();
-
-    // Add upload resolution validation.
-    if ($field_settings['max_resolution'] || $field_settings['min_resolution']) {
-      $element['#upload_validators']['file_validate_image_resolution'] = array($field_settings['max_resolution'], $field_settings['min_resolution']);
-    }
-
-    // If not using custom extension validation, ensure this is an image.
-    $supported_extensions = array('png', 'gif', 'jpg', 'jpeg');
-    $extensions = isset($element['#upload_validators']['file_validate_extensions'][0]) ? $element['#upload_validators']['file_validate_extensions'][0] : implode(' ', $supported_extensions);
-    $extensions = array_intersect(explode(' ', $extensions), $supported_extensions);
-    $element['#upload_validators']['file_validate_extensions'][0] = implode(' ', $extensions);
-
-    // Add all extra functionality provided by the image widget.
-    $element['#process'][] = 'image_field_widget_process';
-    // Add properties needed by image_field_widget_process().
-    $element['#preview_image_style'] = $this->getSetting('preview_image_style');
-    $element['#title_field'] = $field_settings['title_field'];
-    $element['#alt_field'] = $field_settings['alt_field'];
-    $element['#alt_field_required'] = $field_settings['alt_field_required'];
-
-    return $element;
-  }
-
-}
diff --git a/core/modules/link/lib/Drupal/link/Plugin/Field/FieldFormatter/LinkFormatter.php b/core/modules/link/lib/Drupal/link/Plugin/Field/FieldFormatter/LinkFormatter.php
new file mode 100644
index 0000000..4acfd0c
--- /dev/null
+++ b/core/modules/link/lib/Drupal/link/Plugin/Field/FieldFormatter/LinkFormatter.php
@@ -0,0 +1,195 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\link\Plugin\field\formatter\LinkFormatter.
+ */
+
+namespace Drupal\link\Plugin\Field\FieldFormatter;
+
+use Drupal\Component\Utility\Url;
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+use Drupal\Core\Entity\Field\FieldItemInterface;
+use Drupal\Core\Field\FormatterBase;
+
+/**
+ * Plugin implementation of the 'link' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "link",
+ *   label = @Translation("Link"),
+ *   field_types = {
+ *     "link"
+ *   },
+ *   settings = {
+ *     "trim_length" = "80",
+ *     "url_only" = "",
+ *     "url_plain" = "",
+ *     "rel" = "",
+ *     "target" = ""
+ *   }
+ * )
+ */
+class LinkFormatter extends FormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    $elements = parent::settingsForm($form, $form_state);
+
+    $elements['trim_length'] = array(
+      '#type' => 'number',
+      '#title' => t('Trim link text length'),
+      '#field_suffix' => t('characters'),
+      '#default_value' => $this->getSetting('trim_length'),
+      '#min' => 1,
+      '#description' => t('Leave blank to allow unlimited link text lengths.'),
+    );
+    $elements['url_only'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('URL only'),
+      '#default_value' => $this->getSetting('url_only'),
+      '#access' => $this->getPluginId() == 'link',
+    );
+    $elements['url_plain'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Show URL as plain text'),
+      '#default_value' => $this->getSetting('url_plain'),
+      '#access' => $this->getPluginId() == 'link',
+      '#states' => array(
+        'visible' => array(
+          ':input[name*="url_only"]' => array('checked' => TRUE),
+        ),
+      ),
+    );
+    $elements['rel'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Add rel="nofollow" to links'),
+      '#return_value' => 'nofollow',
+      '#default_value' => $this->getSetting('rel'),
+    );
+    $elements['target'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Open link in new window'),
+      '#return_value' => '_blank',
+      '#default_value' => $this->getSetting('target'),
+    );
+
+    return $elements;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = array();
+
+    $settings = $this->getSettings();
+
+    if (!empty($settings['trim_length'])) {
+      $summary[] = t('Link text trimmed to @limit characters', array('@limit' => $settings['trim_length']));
+    }
+    else {
+      $summary[] = t('Link text not trimmed');
+    }
+    if ($this->getPluginId() == 'link' && !empty($settings['url_only'])) {
+      if (!empty($settings['url_plain'])) {
+        $summary[] = t('Show URL only as plain-text');
+      }
+      else {
+        $summary[] = t('Show URL only');
+      }
+    }
+    if (!empty($settings['rel'])) {
+      $summary[] = t('Add rel="@rel"', array('@rel' => $settings['rel']));
+    }
+    if (!empty($settings['target'])) {
+      $summary[] = t('Open link in new window');
+    }
+
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+    $element = array();
+    $entity = $items->getEntity();
+    $settings = $this->getSettings();
+
+    foreach ($items as $delta => $item) {
+      // By default use the full URL as the link text.
+      $link_title = $item->url;
+
+      // If the title field value is available, use it for the link text.
+      if (empty($settings['url_only']) && !empty($item->title)) {
+        // Unsanitizied token replacement here because $options['html'] is FALSE
+        // by default in l().
+        $link_title = \Drupal::token()->replace($item->title, array($entity->entityType() => $entity), array('sanitize' => FALSE, 'clear' => TRUE));
+      }
+
+      // Trim the link text to the desired length.
+      if (!empty($settings['trim_length'])) {
+        $link_title = truncate_utf8($link_title, $settings['trim_length'], FALSE, TRUE);
+      }
+
+      if (!empty($settings['url_only']) && !empty($settings['url_plain'])) {
+        $element[$delta] = array(
+          '#markup' => check_plain($link_title),
+        );
+      }
+      else {
+        $link = $this->buildLink($item);
+        $element[$delta] = array(
+          '#type' => 'link',
+          '#title' => $link_title,
+          '#href' => $link['path'],
+          '#options' => $link['options'],
+        );
+      }
+    }
+
+    return $element;
+  }
+
+  /**
+   * Builds the link information for a link field item.
+   *
+   * @param \Drupal\Core\Entity\Field\FieldItemInterface $item
+   *   The link field item being rendered.
+   *
+   * @return array
+   *   An array with the following key/value pairs:
+   *   - 'path': a string suitable for the $path parameter in l().
+   *   - 'options': an array suitable for the $options parameter in l().
+   */
+  protected function buildLink(FieldItemInterface $item) {
+    $settings = $this->getSettings();
+
+    // Split out the link into the parts required for url(): path and options.
+    $parsed_url = Url::parse($item->url);
+    $result = array(
+      'path' => $parsed_url['path'],
+      'options' => array(
+        'query' => $parsed_url['query'],
+        'fragment' => $parsed_url['fragment'],
+        'attributes' => $item->attributes,
+      ),
+    );
+
+    // Add optional 'rel' attribute to link options.
+    if (!empty($settings['rel'])) {
+      $result['options']['attributes']['rel'] = $settings['rel'];
+    }
+    // Add optional 'target' attribute to link options.
+    if (!empty($settings['target'])) {
+      $result['options']['attributes']['target'] = $settings['target'];
+    }
+
+    return $result;
+  }
+
+}
+
diff --git a/core/modules/link/lib/Drupal/link/Plugin/Field/FieldFormatter/LinkSeparateFormatter.php b/core/modules/link/lib/Drupal/link/Plugin/Field/FieldFormatter/LinkSeparateFormatter.php
new file mode 100644
index 0000000..f721fdc
--- /dev/null
+++ b/core/modules/link/lib/Drupal/link/Plugin/Field/FieldFormatter/LinkSeparateFormatter.php
@@ -0,0 +1,79 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\link\Plugin\field\formatter\LinkSeparateFormatter.
+ *
+ * @todo
+ * Merge into 'link' formatter once there is a #type like 'item' that
+ * can render a compound label and content outside of a form context.
+ * http://drupal.org/node/1829202
+ */
+
+namespace Drupal\link\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+
+/**
+ * Plugin implementation of the 'link_separate' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "link_separate",
+ *   label = @Translation("Separate link text and URL"),
+ *   field_types = {
+ *     "link"
+ *   },
+ *   settings = {
+ *     "trim_length" = "80",
+ *     "rel" = "",
+ *     "target" = ""
+ *   }
+ * )
+ */
+class LinkSeparateFormatter extends LinkFormatter {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+    $element = array();
+    $entity = $items->getEntity();
+    $settings = $this->getSettings();
+
+    foreach ($items as $delta => $item) {
+      // By default use the full URL as the link text.
+      $link_title = $item->url;
+
+      // If the link text field value is available, use it for the text.
+      if (empty($settings['url_only']) && !empty($item->title)) {
+        // Unsanitized token replacement here because $options['html'] is FALSE
+        // by default in l().
+        $link_title = \Drupal::token()->replace($item->title, array($entity->entityType() => $entity), array('sanitize' => FALSE, 'clear' => TRUE));
+      }
+
+      // The link_separate formatter has two titles; the link text (as in the
+      // field values) and the URL itself. If there is no link text value,
+      // $link_title defaults to the URL, so it needs to be unset.
+      // The URL version may need to be trimmed as well.
+      if (empty($item->title)) {
+        $link_title = NULL;
+      }
+      $url_title = $item->url;
+      if (!empty($settings['trim_length'])) {
+        $link_title = truncate_utf8($link_title, $settings['trim_length'], FALSE, TRUE);
+        $url_title = truncate_utf8($item->url, $settings['trim_length'], FALSE, TRUE);
+      }
+
+      $link = $this->buildLink($item);
+      $element[$delta] = array(
+        '#theme' => 'link_formatter_link_separate',
+        '#title' => $link_title,
+        '#url_title' => $url_title,
+        '#href' => $link['path'],
+        '#options' => $link['options'],
+      );
+    }
+    return $element;
+  }
+}
+
diff --git a/core/modules/link/lib/Drupal/link/Plugin/Field/FieldWidget/LinkWidget.php b/core/modules/link/lib/Drupal/link/Plugin/Field/FieldWidget/LinkWidget.php
new file mode 100644
index 0000000..f8f6881
--- /dev/null
+++ b/core/modules/link/lib/Drupal/link/Plugin/Field/FieldWidget/LinkWidget.php
@@ -0,0 +1,141 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\link\Plugin\Field\FieldWidget\LinkWidget.
+ */
+
+namespace Drupal\link\Plugin\Field\FieldWidget;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+use Drupal\Core\Field\WidgetBase;
+
+/**
+ * Plugin implementation of the 'link' widget.
+ *
+ * @FieldWidget(
+ *   id = "link_default",
+ *   label = @Translation("Link"),
+ *   field_types = {
+ *     "link"
+ *   },
+ *   settings = {
+ *     "placeholder_url" = "",
+ *     "placeholder_title" = ""
+ *   }
+ * )
+ */
+class LinkWidget extends WidgetBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
+    $element['url'] = array(
+      '#type' => 'url',
+      '#title' => t('URL'),
+      '#placeholder' => $this->getSetting('placeholder_url'),
+      '#default_value' => isset($items[$delta]->url) ? $items[$delta]->url : NULL,
+      '#maxlength' => 2048,
+      '#required' => $element['#required'],
+    );
+    $element['title'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Link text'),
+      '#placeholder' => $this->getSetting('placeholder_title'),
+      '#default_value' => isset($items[$delta]->title) ? $items[$delta]->title : NULL,
+      '#maxlength' => 255,
+      '#access' => $this->getFieldSetting('title') != DRUPAL_DISABLED,
+    );
+    // Post-process the title field to make it conditionally required if URL is
+    // non-empty. Omit the validation on the field edit form, since the field
+    // settings cannot be saved otherwise.
+    $is_field_edit_form = ($element['#entity'] === NULL);
+    if (!$is_field_edit_form && $this->getFieldSetting('title') == DRUPAL_REQUIRED) {
+      $element['#element_validate'] = array(array($this, 'validateTitle'));
+    }
+
+    // Exposing the attributes array in the widget is left for alternate and more
+    // advanced field widgets.
+    $element['attributes'] = array(
+      '#type' => 'value',
+      '#tree' => TRUE,
+      '#value' => !empty($items[$delta]->attributes) ? $items[$delta]->attributes : array(),
+      '#attributes' => array('class' => array('link-field-widget-attributes')),
+    );
+
+    // If cardinality is 1, ensure a label is output for the field by wrapping it
+    // in a details element.
+    if ($this->fieldDefinition->getFieldCardinality() == 1) {
+      $element += array(
+        '#type' => 'fieldset',
+      );
+    }
+
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    $elements = parent::settingsForm($form, $form_state);
+
+    $elements['placeholder_url'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Placeholder for URL'),
+      '#default_value' => $this->getSetting('placeholder_url'),
+      '#description' => t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'),
+    );
+    $elements['placeholder_title'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Placeholder for link text'),
+      '#default_value' => $this->getSetting('placeholder_title'),
+      '#description' => t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'),
+      '#states' => array(
+        'invisible' => array(
+          ':input[name="instance[settings][title]"]' => array('value' => DRUPAL_DISABLED),
+        ),
+      ),
+    );
+
+    return $elements;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = array();
+
+    $placeholder_title = $this->getSetting('placeholder_title');
+    $placeholder_url = $this->getSetting('placeholder_url');
+    if (empty($placeholder_title) && empty($placeholder_url)) {
+      $summary[] = t('No placeholders');
+    }
+    else {
+      if (!empty($placeholder_title)) {
+        $summary[] = t('Title placeholder: @placeholder_title', array('@placeholder_title' => $placeholder_title));
+      }
+      if (!empty($placeholder_url)) {
+        $summary[] = t('URL placeholder: @placeholder_url', array('@placeholder_url' => $placeholder_url));
+      }
+    }
+
+    return $summary;
+  }
+
+
+  /**
+   * Form element validation handler for link_field_widget_form().
+   *
+   * Conditionally requires the link title if a URL value was filled in.
+   */
+  function validateTitle(&$element, &$form_state, $form) {
+    if ($element['url']['#value'] !== '' && $element['title']['#value'] === '') {
+      $element['title']['#required'] = TRUE;
+      form_error($element['title'], t('!name field is required.', array('!name' => $element['title']['#title'])));
+    }
+  }
+}
+
diff --git a/core/modules/link/lib/Drupal/link/Plugin/field/formatter/LinkFormatter.php b/core/modules/link/lib/Drupal/link/Plugin/field/formatter/LinkFormatter.php
deleted file mode 100644
index 8600459..0000000
--- a/core/modules/link/lib/Drupal/link/Plugin/field/formatter/LinkFormatter.php
+++ /dev/null
@@ -1,195 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\link\Plugin\field\formatter\LinkFormatter.
- */
-
-namespace Drupal\link\Plugin\field\formatter;
-
-use Drupal\Component\Utility\Url;
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\Core\Entity\Field\FieldItemInterface;
-use Drupal\field\Plugin\Type\Formatter\FormatterBase;
-
-/**
- * Plugin implementation of the 'link' formatter.
- *
- * @FieldFormatter(
- *   id = "link",
- *   label = @Translation("Link"),
- *   field_types = {
- *     "link"
- *   },
- *   settings = {
- *     "trim_length" = "80",
- *     "url_only" = "",
- *     "url_plain" = "",
- *     "rel" = "",
- *     "target" = ""
- *   }
- * )
- */
-class LinkFormatter extends FormatterBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsForm(array $form, array &$form_state) {
-    $elements = parent::settingsForm($form, $form_state);
-
-    $elements['trim_length'] = array(
-      '#type' => 'number',
-      '#title' => t('Trim link text length'),
-      '#field_suffix' => t('characters'),
-      '#default_value' => $this->getSetting('trim_length'),
-      '#min' => 1,
-      '#description' => t('Leave blank to allow unlimited link text lengths.'),
-    );
-    $elements['url_only'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('URL only'),
-      '#default_value' => $this->getSetting('url_only'),
-      '#access' => $this->getPluginId() == 'link',
-    );
-    $elements['url_plain'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Show URL as plain text'),
-      '#default_value' => $this->getSetting('url_plain'),
-      '#access' => $this->getPluginId() == 'link',
-      '#states' => array(
-        'visible' => array(
-          ':input[name*="url_only"]' => array('checked' => TRUE),
-        ),
-      ),
-    );
-    $elements['rel'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Add rel="nofollow" to links'),
-      '#return_value' => 'nofollow',
-      '#default_value' => $this->getSetting('rel'),
-    );
-    $elements['target'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Open link in new window'),
-      '#return_value' => '_blank',
-      '#default_value' => $this->getSetting('target'),
-    );
-
-    return $elements;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    $summary = array();
-
-    $settings = $this->getSettings();
-
-    if (!empty($settings['trim_length'])) {
-      $summary[] = t('Link text trimmed to @limit characters', array('@limit' => $settings['trim_length']));
-    }
-    else {
-      $summary[] = t('Link text not trimmed');
-    }
-    if ($this->getPluginId() == 'link' && !empty($settings['url_only'])) {
-      if (!empty($settings['url_plain'])) {
-        $summary[] = t('Show URL only as plain-text');
-      }
-      else {
-        $summary[] = t('Show URL only');
-      }
-    }
-    if (!empty($settings['rel'])) {
-      $summary[] = t('Add rel="@rel"', array('@rel' => $settings['rel']));
-    }
-    if (!empty($settings['target'])) {
-      $summary[] = t('Open link in new window');
-    }
-
-    return $summary;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function viewElements(FieldItemListInterface $items) {
-    $element = array();
-    $entity = $items->getEntity();
-    $settings = $this->getSettings();
-
-    foreach ($items as $delta => $item) {
-      // By default use the full URL as the link text.
-      $link_title = $item->url;
-
-      // If the title field value is available, use it for the link text.
-      if (empty($settings['url_only']) && !empty($item->title)) {
-        // Unsanitizied token replacement here because $options['html'] is FALSE
-        // by default in l().
-        $link_title = \Drupal::token()->replace($item->title, array($entity->entityType() => $entity), array('sanitize' => FALSE, 'clear' => TRUE));
-      }
-
-      // Trim the link text to the desired length.
-      if (!empty($settings['trim_length'])) {
-        $link_title = truncate_utf8($link_title, $settings['trim_length'], FALSE, TRUE);
-      }
-
-      if (!empty($settings['url_only']) && !empty($settings['url_plain'])) {
-        $element[$delta] = array(
-          '#markup' => check_plain($link_title),
-        );
-      }
-      else {
-        $link = $this->buildLink($item);
-        $element[$delta] = array(
-          '#type' => 'link',
-          '#title' => $link_title,
-          '#href' => $link['path'],
-          '#options' => $link['options'],
-        );
-      }
-    }
-
-    return $element;
-  }
-
-  /**
-   * Builds the link information for a link field item.
-   *
-   * @param \Drupal\Core\Entity\Field\FieldItemInterface $item
-   *   The link field item being rendered.
-   *
-   * @return array
-   *   An array with the following key/value pairs:
-   *   - 'path': a string suitable for the $path parameter in l().
-   *   - 'options': an array suitable for the $options parameter in l().
-   */
-  protected function buildLink(FieldItemInterface $item) {
-    $settings = $this->getSettings();
-
-    // Split out the link into the parts required for url(): path and options.
-    $parsed_url = Url::parse($item->url);
-    $result = array(
-      'path' => $parsed_url['path'],
-      'options' => array(
-        'query' => $parsed_url['query'],
-        'fragment' => $parsed_url['fragment'],
-        'attributes' => $item->attributes,
-      ),
-    );
-
-    // Add optional 'rel' attribute to link options.
-    if (!empty($settings['rel'])) {
-      $result['options']['attributes']['rel'] = $settings['rel'];
-    }
-    // Add optional 'target' attribute to link options.
-    if (!empty($settings['target'])) {
-      $result['options']['attributes']['target'] = $settings['target'];
-    }
-
-    return $result;
-  }
-
-}
-
diff --git a/core/modules/link/lib/Drupal/link/Plugin/field/formatter/LinkSeparateFormatter.php b/core/modules/link/lib/Drupal/link/Plugin/field/formatter/LinkSeparateFormatter.php
deleted file mode 100644
index faeb1ca..0000000
--- a/core/modules/link/lib/Drupal/link/Plugin/field/formatter/LinkSeparateFormatter.php
+++ /dev/null
@@ -1,79 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\link\Plugin\field\formatter\LinkSeparateFormatter.
- *
- * @todo
- * Merge into 'link' formatter once there is a #type like 'item' that
- * can render a compound label and content outside of a form context.
- * http://drupal.org/node/1829202
- */
-
-namespace Drupal\link\Plugin\field\formatter;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-
-/**
- * Plugin implementation of the 'link_separate' formatter.
- *
- * @FieldFormatter(
- *   id = "link_separate",
- *   label = @Translation("Separate link text and URL"),
- *   field_types = {
- *     "link"
- *   },
- *   settings = {
- *     "trim_length" = "80",
- *     "rel" = "",
- *     "target" = ""
- *   }
- * )
- */
-class LinkSeparateFormatter extends LinkFormatter {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function viewElements(FieldItemListInterface $items) {
-    $element = array();
-    $entity = $items->getEntity();
-    $settings = $this->getSettings();
-
-    foreach ($items as $delta => $item) {
-      // By default use the full URL as the link text.
-      $link_title = $item->url;
-
-      // If the link text field value is available, use it for the text.
-      if (empty($settings['url_only']) && !empty($item->title)) {
-        // Unsanitized token replacement here because $options['html'] is FALSE
-        // by default in l().
-        $link_title = \Drupal::token()->replace($item->title, array($entity->entityType() => $entity), array('sanitize' => FALSE, 'clear' => TRUE));
-      }
-
-      // The link_separate formatter has two titles; the link text (as in the
-      // field values) and the URL itself. If there is no link text value,
-      // $link_title defaults to the URL, so it needs to be unset.
-      // The URL version may need to be trimmed as well.
-      if (empty($item->title)) {
-        $link_title = NULL;
-      }
-      $url_title = $item->url;
-      if (!empty($settings['trim_length'])) {
-        $link_title = truncate_utf8($link_title, $settings['trim_length'], FALSE, TRUE);
-        $url_title = truncate_utf8($item->url, $settings['trim_length'], FALSE, TRUE);
-      }
-
-      $link = $this->buildLink($item);
-      $element[$delta] = array(
-        '#theme' => 'link_formatter_link_separate',
-        '#title' => $link_title,
-        '#url_title' => $url_title,
-        '#href' => $link['path'],
-        '#options' => $link['options'],
-      );
-    }
-    return $element;
-  }
-}
-
diff --git a/core/modules/link/lib/Drupal/link/Plugin/field/widget/LinkWidget.php b/core/modules/link/lib/Drupal/link/Plugin/field/widget/LinkWidget.php
deleted file mode 100644
index 142b50e..0000000
--- a/core/modules/link/lib/Drupal/link/Plugin/field/widget/LinkWidget.php
+++ /dev/null
@@ -1,141 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\link\Plugin\field\widget\LinkWidget.
- */
-
-namespace Drupal\link\Plugin\field\widget;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\field\Plugin\Type\Widget\WidgetBase;
-
-/**
- * Plugin implementation of the 'link' widget.
- *
- * @FieldWidget(
- *   id = "link_default",
- *   label = @Translation("Link"),
- *   field_types = {
- *     "link"
- *   },
- *   settings = {
- *     "placeholder_url" = "",
- *     "placeholder_title" = ""
- *   }
- * )
- */
-class LinkWidget extends WidgetBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
-    $element['url'] = array(
-      '#type' => 'url',
-      '#title' => t('URL'),
-      '#placeholder' => $this->getSetting('placeholder_url'),
-      '#default_value' => isset($items[$delta]->url) ? $items[$delta]->url : NULL,
-      '#maxlength' => 2048,
-      '#required' => $element['#required'],
-    );
-    $element['title'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Link text'),
-      '#placeholder' => $this->getSetting('placeholder_title'),
-      '#default_value' => isset($items[$delta]->title) ? $items[$delta]->title : NULL,
-      '#maxlength' => 255,
-      '#access' => $this->getFieldSetting('title') != DRUPAL_DISABLED,
-    );
-    // Post-process the title field to make it conditionally required if URL is
-    // non-empty. Omit the validation on the field edit form, since the field
-    // settings cannot be saved otherwise.
-    $is_field_edit_form = ($element['#entity'] === NULL);
-    if (!$is_field_edit_form && $this->getFieldSetting('title') == DRUPAL_REQUIRED) {
-      $element['#element_validate'] = array(array($this, 'validateTitle'));
-    }
-
-    // Exposing the attributes array in the widget is left for alternate and more
-    // advanced field widgets.
-    $element['attributes'] = array(
-      '#type' => 'value',
-      '#tree' => TRUE,
-      '#value' => !empty($items[$delta]->attributes) ? $items[$delta]->attributes : array(),
-      '#attributes' => array('class' => array('link-field-widget-attributes')),
-    );
-
-    // If cardinality is 1, ensure a label is output for the field by wrapping it
-    // in a details element.
-    if ($this->fieldDefinition->getFieldCardinality() == 1) {
-      $element += array(
-        '#type' => 'fieldset',
-      );
-    }
-
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsForm(array $form, array &$form_state) {
-    $elements = parent::settingsForm($form, $form_state);
-
-    $elements['placeholder_url'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Placeholder for URL'),
-      '#default_value' => $this->getSetting('placeholder_url'),
-      '#description' => t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'),
-    );
-    $elements['placeholder_title'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Placeholder for link text'),
-      '#default_value' => $this->getSetting('placeholder_title'),
-      '#description' => t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'),
-      '#states' => array(
-        'invisible' => array(
-          ':input[name="instance[settings][title]"]' => array('value' => DRUPAL_DISABLED),
-        ),
-      ),
-    );
-
-    return $elements;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    $summary = array();
-
-    $placeholder_title = $this->getSetting('placeholder_title');
-    $placeholder_url = $this->getSetting('placeholder_url');
-    if (empty($placeholder_title) && empty($placeholder_url)) {
-      $summary[] = t('No placeholders');
-    }
-    else {
-      if (!empty($placeholder_title)) {
-        $summary[] = t('Title placeholder: @placeholder_title', array('@placeholder_title' => $placeholder_title));
-      }
-      if (!empty($placeholder_url)) {
-        $summary[] = t('URL placeholder: @placeholder_url', array('@placeholder_url' => $placeholder_url));
-      }
-    }
-
-    return $summary;
-  }
-
-
-  /**
-   * Form element validation handler for link_field_widget_form().
-   *
-   * Conditionally requires the link title if a URL value was filled in.
-   */
-  function validateTitle(&$element, &$form_state, $form) {
-    if ($element['url']['#value'] !== '' && $element['title']['#value'] === '') {
-      $element['title']['#required'] = TRUE;
-      form_error($element['title'], t('!name field is required.', array('!name' => $element['title']['#title'])));
-    }
-  }
-}
-
diff --git a/core/modules/number/lib/Drupal/number/Plugin/Field/FieldFormatter/DefaultNumberFormatter.php b/core/modules/number/lib/Drupal/number/Plugin/Field/FieldFormatter/DefaultNumberFormatter.php
new file mode 100644
index 0000000..7ed5a97
--- /dev/null
+++ b/core/modules/number/lib/Drupal/number/Plugin/Field/FieldFormatter/DefaultNumberFormatter.php
@@ -0,0 +1,97 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\number\Plugin\field\formatter\DefaultNumberFormatter.
+ */
+
+namespace Drupal\number\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Field\FormatterBase;
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+
+/**
+ * Parent plugin for decimal and integer formatters
+ */
+abstract class DefaultNumberFormatter extends FormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    $options = array(
+      ''  => t('- None -'),
+      '.' => t('Decimal point'),
+      ',' => t('Comma'),
+      ' ' => t('Space'),
+      chr(8201) => t('Thin space'),
+      "'" => t('Apostrophe'),
+    );
+    $elements['thousand_separator'] = array(
+      '#type' => 'select',
+      '#title' => t('Thousand marker'),
+      '#options' => $options,
+      '#default_value' => $this->getSetting('thousand_separator'),
+      '#weight' => 0,
+    );
+
+    $elements['prefix_suffix'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Display prefix and suffix.'),
+      '#default_value' => $this->getSetting('prefix_suffix'),
+      '#weight' => 10,
+    );
+
+    return $elements;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = array();
+
+    $summary[] = $this->numberFormat(1234.1234567890);
+    if ($this->getSetting('prefix_suffix')) {
+      $summary[] = t('Display with prefix and suffix.');
+    }
+
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+    $elements = array();
+    $settings = $this->getFieldSettings();
+
+    foreach ($items as $delta => $item) {
+      $output = $this->numberFormat($item->value);
+
+      // Account for prefix and suffix.
+      if ($this->getSetting('prefix_suffix')) {
+        $prefixes = isset($settings['prefix']) ? array_map('field_filter_xss', explode('|', $settings['prefix'])) : array('');
+        $suffixes = isset($settings['suffix']) ? array_map('field_filter_xss', explode('|', $settings['suffix'])) : array('');
+        $prefix = (count($prefixes) > 1) ? format_plural($item->value, $prefixes[0], $prefixes[1]) : $prefixes[0];
+        $suffix = (count($suffixes) > 1) ? format_plural($item->value, $suffixes[0], $suffixes[1]) : $suffixes[0];
+        $output = $prefix . $output . $suffix;
+      }
+
+      $elements[$delta] = array('#markup' => $output);
+    }
+
+    return $elements;
+  }
+
+  /**
+   * Formats a number.
+   *
+   * @param mixed $number
+   *   The numeric value.
+   *
+   * @return string
+   *   The formatted number.
+   */
+  abstract protected function numberFormat($number);
+}
diff --git a/core/modules/number/lib/Drupal/number/Plugin/Field/FieldFormatter/NumberDecimalFormatter.php b/core/modules/number/lib/Drupal/number/Plugin/Field/FieldFormatter/NumberDecimalFormatter.php
new file mode 100644
index 0000000..a911ee1
--- /dev/null
+++ b/core/modules/number/lib/Drupal/number/Plugin/Field/FieldFormatter/NumberDecimalFormatter.php
@@ -0,0 +1,66 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\number\Plugin\field\formatter\NumberDecimalFormatter.
+ */
+
+namespace Drupal\number\Plugin\Field\FieldFormatter;
+
+/**
+ * Plugin implementation of the 'number_decimal' formatter.
+ *
+ * The 'Default' formatter is different for integer fields on the one hand, and
+ * for decimal and float fields on the other hand, in order to be able to use
+ * different settings.
+ *
+ * @FieldFormatter(
+ *   id = "number_decimal",
+ *   label = @Translation("Default"),
+ *   field_types = {
+ *     "number_decimal",
+ *     "number_float"
+ *   },
+ *   settings = {
+ *     "thousand_separator" = "",
+ *     "decimal_separator" = ".",
+ *     "scale" = "2",
+ *     "prefix_suffix" = "TRUE"
+ *   }
+ * )
+ */
+class NumberDecimalFormatter extends DefaultNumberFormatter {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    $elements = parent::settingsForm($form, $form_state);
+
+    $elements['decimal_separator'] = array(
+      '#type' => 'select',
+      '#title' => t('Decimal marker'),
+      '#options' => array('.' => t('Decimal point'), ',' => t('Comma')),
+      '#default_value' => $this->getSetting('decimal_separator'),
+      'weight' => 5,
+    );
+    $elements['scale'] = array(
+      '#type' => 'select',
+      '#title' => t('Scale'),
+      '#options' => drupal_map_assoc(range(0, 10)),
+      '#default_value' => $this->getSetting('scale'),
+      '#description' => t('The number of digits to the right of the decimal.'),
+      'weight' => 6,
+    );
+
+    return $elements;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function numberFormat($number) {
+    return number_format($number, $this->getSetting('scale'), $this->getSetting('decimal_separator'), $this->getSetting('thousand_separator'));
+  }
+
+}
diff --git a/core/modules/number/lib/Drupal/number/Plugin/Field/FieldFormatter/NumberIntegerFormatter.php b/core/modules/number/lib/Drupal/number/Plugin/Field/FieldFormatter/NumberIntegerFormatter.php
new file mode 100644
index 0000000..53ff874
--- /dev/null
+++ b/core/modules/number/lib/Drupal/number/Plugin/Field/FieldFormatter/NumberIntegerFormatter.php
@@ -0,0 +1,38 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\number\Plugin\field\formatter\NumberIntegerFormatter.
+ */
+
+namespace Drupal\number\Plugin\Field\FieldFormatter;
+
+/**
+ * Plugin implementation of the 'number_integer' formatter.
+ *
+ * The 'Default' formatter is different for integer fields on the one hand, and
+ * for decimal and float fields on the other hand, in order to be able to use
+ * different settings.
+ *
+ * @FieldFormatter(
+ *   id = "number_integer",
+ *   label = @Translation("Default"),
+ *   field_types = {
+ *     "number_integer"
+ *   },
+ *   settings = {
+ *     "thousand_separator" = "",
+ *     "prefix_suffix" = "TRUE"
+ *   }
+ * )
+ */
+class NumberIntegerFormatter extends DefaultNumberFormatter {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function numberFormat($number) {
+    return number_format($number, 0, '', $this->getSetting('thousand_separator'));
+  }
+
+}
diff --git a/core/modules/number/lib/Drupal/number/Plugin/Field/FieldFormatter/NumberUnformattedFormatter.php b/core/modules/number/lib/Drupal/number/Plugin/Field/FieldFormatter/NumberUnformattedFormatter.php
new file mode 100644
index 0000000..d208ce3
--- /dev/null
+++ b/core/modules/number/lib/Drupal/number/Plugin/Field/FieldFormatter/NumberUnformattedFormatter.php
@@ -0,0 +1,41 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\number\Plugin\field\formatter\NumberUnformattedFormatter.
+ */
+
+namespace Drupal\number\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Field\FormatterBase;
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+
+/**
+ * Plugin implementation of the 'number_unformatted' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "number_unformatted",
+ *   label = @Translation("Unformatted"),
+ *   field_types = {
+ *     "number_integer",
+ *     "number_decimal",
+ *     "number_float"
+ *   }
+ * )
+ */
+class NumberUnformattedFormatter extends FormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+    $elements = array();
+
+    foreach ($items as $delta => $item) {
+      $elements[$delta] = array('#markup' => $item->value);
+    }
+
+    return $elements;
+  }
+
+}
diff --git a/core/modules/number/lib/Drupal/number/Plugin/Field/FieldWidget/NumberWidget.php b/core/modules/number/lib/Drupal/number/Plugin/Field/FieldWidget/NumberWidget.php
new file mode 100644
index 0000000..7a86e8b
--- /dev/null
+++ b/core/modules/number/lib/Drupal/number/Plugin/Field/FieldWidget/NumberWidget.php
@@ -0,0 +1,114 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\number\Plugin\Field\FieldWidget\NumberWidget.
+ */
+
+namespace Drupal\number\Plugin\Field\FieldWidget;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+use Drupal\Core\Field\WidgetBase;
+use Symfony\Component\Validator\ConstraintViolationInterface;
+
+/**
+ * Plugin implementation of the 'number' widget.
+ *
+ * @FieldWidget(
+ *   id = "number",
+ *   label = @Translation("Text field"),
+ *   field_types = {
+ *     "number_integer",
+ *     "number_decimal",
+ *     "number_float"
+ *   },
+ *   settings = {
+ *     "placeholder" = ""
+ *   }
+ * )
+ */
+class NumberWidget extends WidgetBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    $element['placeholder'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Placeholder'),
+      '#default_value' => $this->getSetting('placeholder'),
+      '#description' => t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'),
+    );
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = array();
+
+    $placeholder = $this->getSetting('placeholder');
+    if (!empty($placeholder)) {
+      $summary[] = t('Placeholder: @placeholder', array('@placeholder' => $placeholder));
+    }
+    else {
+      $summary[] = t('No placeholder');
+    }
+
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
+    $value = isset($items[$delta]->value) ? $items[$delta]->value : NULL;
+    $field_settings = $this->getFieldSettings();
+
+    $element += array(
+      '#type' => 'number',
+      '#default_value' => $value,
+      '#placeholder' => $this->getSetting('placeholder'),
+    );
+
+    // Set the step for floating point and decimal numbers.
+    switch ($this->fieldDefinition->getFieldType()) {
+      case 'number_decimal':
+        $element['#step'] = pow(0.1, $field_settings['scale']);
+        break;
+
+      case 'number_float':
+        $element['#step'] = 'any';
+        break;
+    }
+
+    // Set minimum and maximum.
+    if (is_numeric($field_settings['min'])) {
+      $element['#min'] = $field_settings['min'];
+    }
+    if (is_numeric($field_settings['max'])) {
+      $element['#max'] = $field_settings['max'];
+    }
+
+    // Add prefix and suffix.
+    if ($field_settings['prefix']) {
+      $prefixes = explode('|', $field_settings['prefix']);
+      $element['#field_prefix'] = field_filter_xss(array_pop($prefixes));
+    }
+    if ($field_settings['suffix']) {
+      $suffixes = explode('|', $field_settings['suffix']);
+      $element['#field_suffix'] = field_filter_xss(array_pop($suffixes));
+    }
+
+    return array('value' => $element);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function errorElement(array $element, ConstraintViolationInterface $error, array $form, array &$form_state) {
+    return $element['value'];
+  }
+
+}
diff --git a/core/modules/number/lib/Drupal/number/Plugin/field/formatter/DefaultNumberFormatter.php b/core/modules/number/lib/Drupal/number/Plugin/field/formatter/DefaultNumberFormatter.php
deleted file mode 100644
index 6cec0a6..0000000
--- a/core/modules/number/lib/Drupal/number/Plugin/field/formatter/DefaultNumberFormatter.php
+++ /dev/null
@@ -1,97 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\number\Plugin\field\formatter\DefaultNumberFormatter.
- */
-
-namespace Drupal\number\Plugin\field\formatter;
-
-use Drupal\field\Plugin\Type\Formatter\FormatterBase;
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-
-/**
- * Parent plugin for decimal and integer formatters
- */
-abstract class DefaultNumberFormatter extends FormatterBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsForm(array $form, array &$form_state) {
-    $options = array(
-      ''  => t('- None -'),
-      '.' => t('Decimal point'),
-      ',' => t('Comma'),
-      ' ' => t('Space'),
-      chr(8201) => t('Thin space'),
-      "'" => t('Apostrophe'),
-    );
-    $elements['thousand_separator'] = array(
-      '#type' => 'select',
-      '#title' => t('Thousand marker'),
-      '#options' => $options,
-      '#default_value' => $this->getSetting('thousand_separator'),
-      '#weight' => 0,
-    );
-
-    $elements['prefix_suffix'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Display prefix and suffix.'),
-      '#default_value' => $this->getSetting('prefix_suffix'),
-      '#weight' => 10,
-    );
-
-    return $elements;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    $summary = array();
-
-    $summary[] = $this->numberFormat(1234.1234567890);
-    if ($this->getSetting('prefix_suffix')) {
-      $summary[] = t('Display with prefix and suffix.');
-    }
-
-    return $summary;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function viewElements(FieldItemListInterface $items) {
-    $elements = array();
-    $settings = $this->getFieldSettings();
-
-    foreach ($items as $delta => $item) {
-      $output = $this->numberFormat($item->value);
-
-      // Account for prefix and suffix.
-      if ($this->getSetting('prefix_suffix')) {
-        $prefixes = isset($settings['prefix']) ? array_map('field_filter_xss', explode('|', $settings['prefix'])) : array('');
-        $suffixes = isset($settings['suffix']) ? array_map('field_filter_xss', explode('|', $settings['suffix'])) : array('');
-        $prefix = (count($prefixes) > 1) ? format_plural($item->value, $prefixes[0], $prefixes[1]) : $prefixes[0];
-        $suffix = (count($suffixes) > 1) ? format_plural($item->value, $suffixes[0], $suffixes[1]) : $suffixes[0];
-        $output = $prefix . $output . $suffix;
-      }
-
-      $elements[$delta] = array('#markup' => $output);
-    }
-
-    return $elements;
-  }
-
-  /**
-   * Formats a number.
-   *
-   * @param mixed $number
-   *   The numeric value.
-   *
-   * @return string
-   *   The formatted number.
-   */
-  abstract protected function numberFormat($number);
-}
diff --git a/core/modules/number/lib/Drupal/number/Plugin/field/formatter/NumberDecimalFormatter.php b/core/modules/number/lib/Drupal/number/Plugin/field/formatter/NumberDecimalFormatter.php
deleted file mode 100644
index 8cb6712..0000000
--- a/core/modules/number/lib/Drupal/number/Plugin/field/formatter/NumberDecimalFormatter.php
+++ /dev/null
@@ -1,68 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\number\Plugin\field\formatter\NumberDecimalFormatter.
- */
-
-namespace Drupal\number\Plugin\field\formatter;
-
-use Drupal\number\Plugin\field\formatter\DefaultNumberFormatter;
-
-/**
- * Plugin implementation of the 'number_decimal' formatter.
- *
- * The 'Default' formatter is different for integer fields on the one hand, and
- * for decimal and float fields on the other hand, in order to be able to use
- * different settings.
- *
- * @FieldFormatter(
- *   id = "number_decimal",
- *   label = @Translation("Default"),
- *   field_types = {
- *     "number_decimal",
- *     "number_float"
- *   },
- *   settings = {
- *     "thousand_separator" = "",
- *     "decimal_separator" = ".",
- *     "scale" = "2",
- *     "prefix_suffix" = "TRUE"
- *   }
- * )
- */
-class NumberDecimalFormatter extends DefaultNumberFormatter {
-
-  /**
-   * Overrides Drupal\number\Plugin\field\formatter\DefaultNumberFormatter::settingsForm().
-   */
-  public function settingsForm(array $form, array &$form_state) {
-    $elements = parent::settingsForm($form, $form_state);
-
-    $elements['decimal_separator'] = array(
-      '#type' => 'select',
-      '#title' => t('Decimal marker'),
-      '#options' => array('.' => t('Decimal point'), ',' => t('Comma')),
-      '#default_value' => $this->getSetting('decimal_separator'),
-      'weight' => 5,
-    );
-    $elements['scale'] = array(
-      '#type' => 'select',
-      '#title' => t('Scale'),
-      '#options' => drupal_map_assoc(range(0, 10)),
-      '#default_value' => $this->getSetting('scale'),
-      '#description' => t('The number of digits to the right of the decimal.'),
-      'weight' => 6,
-    );
-
-    return $elements;
-  }
-
-  /**
-   * Overrides Drupal\number\Plugin\field\formatter\DefaultNumberFormatter::numberFormat().
-   */
-  protected function numberFormat($number) {
-    return number_format($number, $this->getSetting('scale'), $this->getSetting('decimal_separator'), $this->getSetting('thousand_separator'));
-  }
-
-}
diff --git a/core/modules/number/lib/Drupal/number/Plugin/field/formatter/NumberIntegerFormatter.php b/core/modules/number/lib/Drupal/number/Plugin/field/formatter/NumberIntegerFormatter.php
deleted file mode 100644
index 1c6538c..0000000
--- a/core/modules/number/lib/Drupal/number/Plugin/field/formatter/NumberIntegerFormatter.php
+++ /dev/null
@@ -1,40 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\number\Plugin\field\formatter\NumberIntegerFormatter.
- */
-
-namespace Drupal\number\Plugin\field\formatter;
-
-use Drupal\number\Plugin\field\formatter\DefaultNumberFormatter;
-
-/**
- * Plugin implementation of the 'number_integer' formatter.
- *
- * The 'Default' formatter is different for integer fields on the one hand, and
- * for decimal and float fields on the other hand, in order to be able to use
- * different settings.
- *
- * @FieldFormatter(
- *   id = "number_integer",
- *   label = @Translation("Default"),
- *   field_types = {
- *     "number_integer"
- *   },
- *   settings = {
- *     "thousand_separator" = "",
- *     "prefix_suffix" = "TRUE"
- *   }
- * )
- */
-class NumberIntegerFormatter extends DefaultNumberFormatter {
-
-  /**
-   * Overrides Drupal\number\Plugin\field\formatter\DefaultNumberFormatter::numberFormat().
-   */
-  protected function numberFormat($number) {
-    return number_format($number, 0, '', $this->getSetting('thousand_separator'));
-  }
-
-}
diff --git a/core/modules/number/lib/Drupal/number/Plugin/field/formatter/NumberUnformattedFormatter.php b/core/modules/number/lib/Drupal/number/Plugin/field/formatter/NumberUnformattedFormatter.php
deleted file mode 100644
index e9ec772..0000000
--- a/core/modules/number/lib/Drupal/number/Plugin/field/formatter/NumberUnformattedFormatter.php
+++ /dev/null
@@ -1,41 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\number\Plugin\field\formatter\NumberUnformattedFormatter.
- */
-
-namespace Drupal\number\Plugin\field\formatter;
-
-use Drupal\field\Plugin\Type\Formatter\FormatterBase;
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-
-/**
- * Plugin implementation of the 'number_unformatted' formatter.
- *
- * @FieldFormatter(
- *   id = "number_unformatted",
- *   label = @Translation("Unformatted"),
- *   field_types = {
- *     "number_integer",
- *     "number_decimal",
- *     "number_float"
- *   }
- * )
- */
-class NumberUnformattedFormatter extends FormatterBase {
-
-  /**
-   * Implements Drupal\field\Plugin\Type\Formatter\FormatterInterface::viewElements().
-   */
-  public function viewElements(FieldItemListInterface $items) {
-    $elements = array();
-
-    foreach ($items as $delta => $item) {
-      $elements[$delta] = array('#markup' => $item->value);
-    }
-
-    return $elements;
-  }
-
-}
diff --git a/core/modules/number/lib/Drupal/number/Plugin/field/widget/NumberWidget.php b/core/modules/number/lib/Drupal/number/Plugin/field/widget/NumberWidget.php
deleted file mode 100644
index cdf2806..0000000
--- a/core/modules/number/lib/Drupal/number/Plugin/field/widget/NumberWidget.php
+++ /dev/null
@@ -1,114 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\number\Plugin\field\widget\NumberWidget.
- */
-
-namespace Drupal\number\Plugin\field\widget;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\field\Plugin\Type\Widget\WidgetBase;
-use Symfony\Component\Validator\ConstraintViolationInterface;
-
-/**
- * Plugin implementation of the 'number' widget.
- *
- * @FieldWidget(
- *   id = "number",
- *   label = @Translation("Text field"),
- *   field_types = {
- *     "number_integer",
- *     "number_decimal",
- *     "number_float"
- *   },
- *   settings = {
- *     "placeholder" = ""
- *   }
- * )
- */
-class NumberWidget extends WidgetBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsForm(array $form, array &$form_state) {
-    $element['placeholder'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Placeholder'),
-      '#default_value' => $this->getSetting('placeholder'),
-      '#description' => t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'),
-    );
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    $summary = array();
-
-    $placeholder = $this->getSetting('placeholder');
-    if (!empty($placeholder)) {
-      $summary[] = t('Placeholder: @placeholder', array('@placeholder' => $placeholder));
-    }
-    else {
-      $summary[] = t('No placeholder');
-    }
-
-    return $summary;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
-    $value = isset($items[$delta]->value) ? $items[$delta]->value : NULL;
-    $field_settings = $this->getFieldSettings();
-
-    $element += array(
-      '#type' => 'number',
-      '#default_value' => $value,
-      '#placeholder' => $this->getSetting('placeholder'),
-    );
-
-    // Set the step for floating point and decimal numbers.
-    switch ($this->fieldDefinition->getFieldType()) {
-      case 'number_decimal':
-        $element['#step'] = pow(0.1, $field_settings['scale']);
-        break;
-
-      case 'number_float':
-        $element['#step'] = 'any';
-        break;
-    }
-
-    // Set minimum and maximum.
-    if (is_numeric($field_settings['min'])) {
-      $element['#min'] = $field_settings['min'];
-    }
-    if (is_numeric($field_settings['max'])) {
-      $element['#max'] = $field_settings['max'];
-    }
-
-    // Add prefix and suffix.
-    if ($field_settings['prefix']) {
-      $prefixes = explode('|', $field_settings['prefix']);
-      $element['#field_prefix'] = field_filter_xss(array_pop($prefixes));
-    }
-    if ($field_settings['suffix']) {
-      $suffixes = explode('|', $field_settings['suffix']);
-      $element['#field_suffix'] = field_filter_xss(array_pop($suffixes));
-    }
-
-    return array('value' => $element);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function errorElement(array $element, ConstraintViolationInterface $error, array $form, array &$form_state) {
-    return $element['value'];
-  }
-
-}
diff --git a/core/modules/options/lib/Drupal/options/Plugin/Field/FieldFormatter/OptionsDefaultFormatter.php b/core/modules/options/lib/Drupal/options/Plugin/Field/FieldFormatter/OptionsDefaultFormatter.php
new file mode 100644
index 0000000..a3f3b0c
--- /dev/null
+++ b/core/modules/options/lib/Drupal/options/Plugin/Field/FieldFormatter/OptionsDefaultFormatter.php
@@ -0,0 +1,52 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\options\Plugin\field\formatter\OptionsDefaultFormatter.
+ */
+
+namespace Drupal\options\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Field\FormatterBase;
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+
+/**
+ * Plugin implementation of the 'list_default' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "list_default",
+ *   label = @Translation("Default"),
+ *   field_types = {
+ *     "list_integer",
+ *     "list_float",
+ *     "list_text",
+ *     "list_boolean"
+ *   }
+ * )
+ */
+class OptionsDefaultFormatter extends FormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+    $elements = array();
+
+    $entity = $items->getEntity();
+    $allowed_values = options_allowed_values($this->fieldDefinition, $entity);
+
+    foreach ($items as $delta => $item) {
+      if (isset($allowed_values[$item->value])) {
+        $output = field_filter_xss($allowed_values[$item->value]);
+      }
+      else {
+        // If no match was found in allowed values, fall back to the key.
+        $output = field_filter_xss($item->value);
+      }
+      $elements[$delta] = array('#markup' => $output);
+    }
+
+    return $elements;
+  }
+
+}
diff --git a/core/modules/options/lib/Drupal/options/Plugin/Field/FieldFormatter/OptionsKeyFormatter.php b/core/modules/options/lib/Drupal/options/Plugin/Field/FieldFormatter/OptionsKeyFormatter.php
new file mode 100644
index 0000000..b50f935
--- /dev/null
+++ b/core/modules/options/lib/Drupal/options/Plugin/Field/FieldFormatter/OptionsKeyFormatter.php
@@ -0,0 +1,42 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\options\Plugin\field\formatter\OptionsKeyFormatter.
+ */
+
+namespace Drupal\options\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Field\FormatterBase;
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+
+/**
+ * Plugin implementation of the 'list_key' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "list_key",
+ *   label = @Translation("Key"),
+ *   field_types = {
+ *     "list_integer",
+ *     "list_float",
+ *     "list_text",
+ *     "list_boolean"
+ *   }
+ * )
+ */
+class OptionsKeyFormatter extends FormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+    $elements = array();
+
+    foreach ($items as $delta => $item) {
+      $elements[$delta] = array('#markup' => field_filter_xss($item->value));
+    }
+
+    return $elements;
+  }
+
+}
diff --git a/core/modules/options/lib/Drupal/options/Plugin/Field/FieldWidget/ButtonsWidget.php b/core/modules/options/lib/Drupal/options/Plugin/Field/FieldWidget/ButtonsWidget.php
new file mode 100644
index 0000000..d42b6a7
--- /dev/null
+++ b/core/modules/options/lib/Drupal/options/Plugin/Field/FieldWidget/ButtonsWidget.php
@@ -0,0 +1,75 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\options\Plugin\Field\FieldWidget\ButtonsWidget.
+ */
+
+namespace Drupal\options\Plugin\Field\FieldWidget;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+use Drupal\options\Plugin\Field\FieldWidget\OptionsWidgetBase;
+
+/**
+ * Plugin implementation of the 'options_buttons' widget.
+ *
+ * @FieldWidget(
+ *   id = "options_buttons",
+ *   label = @Translation("Check boxes/radio buttons"),
+ *   field_types = {
+ *     "list_integer",
+ *     "list_float",
+ *     "list_text",
+ *     "list_boolean"
+ *   },
+ *   multiple_values = TRUE
+ * )
+ */
+class ButtonsWidget extends OptionsWidgetBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
+    $element = parent::formElement($items, $delta, $element, $form, $form_state);
+
+    $options = $this->getOptions($items[$delta]);
+    $selected = $this->getSelectedOptions($items);
+
+    // If required and there is one single option, preselect it.
+    if ($this->required && count($options) == 1) {
+      reset($options);
+      $selected = array(key($options));
+    }
+
+    if ($this->multiple) {
+      $element += array(
+        '#type' => 'checkboxes',
+        '#default_value' => $selected,
+        '#options' => $options,
+      );
+    }
+    else {
+      $element += array(
+        '#type' => 'radios',
+        // Radio buttons need a scalar value. Take the first default value, or
+        // default to NULL so that the form element is properly recognized as
+        // not having a default value.
+        '#default_value' => $selected ? reset($selected) : NULL,
+        '#options' => $options,
+      );
+    }
+
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getEmptyOption() {
+    if (!$this->required && !$this->multiple) {
+      return static::OPTIONS_EMPTY_NONE;
+    }
+  }
+
+}
diff --git a/core/modules/options/lib/Drupal/options/Plugin/Field/FieldWidget/OnOffWidget.php b/core/modules/options/lib/Drupal/options/Plugin/Field/FieldWidget/OnOffWidget.php
new file mode 100644
index 0000000..8cdf65c
--- /dev/null
+++ b/core/modules/options/lib/Drupal/options/Plugin/Field/FieldWidget/OnOffWidget.php
@@ -0,0 +1,80 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\options\Plugin\Field\FieldWidget\OnOffWidget.
+ */
+
+namespace Drupal\options\Plugin\Field\FieldWidget;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+use Drupal\options\Plugin\Field\FieldWidget\OptionsWidgetBase;
+
+/**
+ * Plugin implementation of the 'options_onoff' widget.
+ *
+ * @FieldWidget(
+ *   id = "options_onoff",
+ *   label = @Translation("Single on/off checkbox"),
+ *   field_types = {
+ *     "list_boolean"
+ *   },
+ *   settings = {
+ *     "display_label" = FALSE,
+ *   },
+ *   multiple_values = TRUE
+ * )
+ */
+class OnOffWidget extends OptionsWidgetBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    $element['display_label'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Use field label instead of the "On value" as label'),
+      '#default_value' => $this->getSetting('display_label'),
+      '#weight' => -1,
+    );
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = array();
+
+    $display_label = $this->getSetting('display_label');
+    $summary[] = t('Use field label: @display_label', array('@display_label' => ($display_label ? t('Yes') : 'No')));
+
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
+    $element = parent::formElement($items, $delta, $element, $form, $form_state);
+
+    $options = $this->getOptions($items[$delta]);
+    $selected = $this->getSelectedOptions($items);
+
+    $element += array(
+      '#type' => 'checkbox',
+      '#default_value' => !empty($selected[0]),
+    );
+
+    // Override the title from the incoming $element.
+    if ($this->getSetting('display_label')) {
+      $element['#title'] = $this->fieldDefinition->getFieldLabel();
+    }
+    else {
+      $element['#title'] = isset($options[1]) ? $options[1] : '';
+    }
+
+    return $element;
+  }
+
+}
diff --git a/core/modules/options/lib/Drupal/options/Plugin/Field/FieldWidget/OptionsWidgetBase.php b/core/modules/options/lib/Drupal/options/Plugin/Field/FieldWidget/OptionsWidgetBase.php
new file mode 100644
index 0000000..dbc2f22
--- /dev/null
+++ b/core/modules/options/lib/Drupal/options/Plugin/Field/FieldWidget/OptionsWidgetBase.php
@@ -0,0 +1,235 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\options\Plugin\Field\FieldWidget\OptionsWidgetBase.
+ */
+
+namespace Drupal\options\Plugin\Field\FieldWidget;
+
+use Drupal\Core\Entity\Field\FieldDefinitionInterface;
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+use Drupal\Core\Entity\Field\FieldItemInterface;
+use Drupal\Core\Field\WidgetBase;
+
+/**
+ * Base class for the 'options_*' widgets.
+ *
+ * Field types willing to enable one or several of the widgets defined in
+ * options.module (select, radios/checkboxes, on/off checkbox) need to
+ * implement the AllowedValuesInterface to specify the list of options to
+ * display in the widgets.
+ *
+ * @see \Drupal\Core\TypedData\AllowedValuesInterface
+ */
+abstract class OptionsWidgetBase extends WidgetBase {
+
+  /**
+   * Identifies a 'None' option.
+   */
+  const OPTIONS_EMPTY_NONE = 'option_none';
+
+  /**
+   * Identifies a 'Select a value' option.
+   */
+  const OPTIONS_EMPTY_SELECT = 'option_select';
+
+  /**
+   * Abstract over the actual field columns, to allow different field types to
+   * reuse those widgets.
+   *
+   * @var string
+   */
+  protected $column;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function __construct($plugin_id, array $plugin_definition, FieldDefinitionInterface $field_definition, array $settings) {
+    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings);
+    $property_names = $this->fieldDefinition->getFieldPropertyNames();
+    $this->column = $property_names[0];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
+    // Prepare some properties for the child methods to build the actual form
+    // element.
+    $this->required = $element['#required'];
+    $cardinality = $this->fieldDefinition->getFieldCardinality();
+    $this->multiple = ($cardinality == FIELD_CARDINALITY_UNLIMITED) || ($cardinality > 1);
+    $this->has_value = isset($items[0]->{$this->column});
+
+    // Add our custom validator.
+    $element['#element_validate'][] = array(get_class($this), 'validateElement');
+    $element['#key_column'] = $this->column;
+
+    // The rest of the $element is built by child method implementations.
+
+    return $element;
+  }
+
+  /**
+   * Form validation handler for widget elements.
+   *
+   * @param array $element
+   *   The form element.
+   * @param array $form_state
+   *   The form state.
+   */
+  public static function validateElement(array $element, array &$form_state) {
+    if ($element['#required'] && $element['#value'] == '_none') {
+      form_error($element, t('!name field is required.', array('!name' => $element['#title'])));
+    }
+
+    // Massage submitted form values.
+    // Drupal\Core\Field\WidgetBase::submit() expects values as
+    // an array of values keyed by delta first, then by column, while our
+    // widgets return the opposite.
+
+    if (is_array($element['#value'])) {
+      $values = array_values($element['#value']);
+    }
+    else {
+      $values = array($element['#value']);
+    }
+
+    // Filter out the 'none' option. Use a strict comparison, because
+    // 0 == 'any string'.
+    $index = array_search('_none', $values, TRUE);
+    if ($index !== FALSE) {
+      unset($values[$index]);
+    }
+
+    // Transpose selections from field => delta to delta => field.
+    $items = array();
+    foreach ($values as $value) {
+      $items[] = array($element['#key_column'] => $value);
+    }
+    form_set_value($element, $items, $form_state);
+  }
+
+  /**
+   * Returns the array of options for the widget.
+   *
+   * @param \Drupal\Core\Entity\Field\FieldItemInterface $item
+   *   The field item.
+   *
+   * @return array
+   *   The array of options for the widget.
+   */
+  protected function getOptions(FieldItemInterface $item) {
+    if (!isset($this->options)) {
+      // Limit the settable options for the current user account.
+      $options = $item->getSettableOptions(\Drupal::currentUser());
+
+      // Add an empty option if the widget needs one.
+      if ($empty_option = $this->getEmptyOption()) {
+        switch ($this->getPluginId()) {
+          case 'options_buttons':
+            $label = t('N/A');
+            break;
+
+          case 'options_select':
+            $label = ($empty_option == static::OPTIONS_EMPTY_NONE ? t('- None -') : t('- Select a value -'));
+            break;
+        }
+
+        $options = array('_none' => $label) + $options;
+      }
+
+      $module_handler = \Drupal::moduleHandler();
+      $context = array(
+        'fieldDefinition' => $this->fieldDefinition,
+        'entity' => $item->getEntity(),
+      );
+      $module_handler->alter('options_list', $options, $context);
+
+      array_walk_recursive($options, array($this, 'sanitizeLabel'));
+
+      // Options might be nested ("optgroups"). If the widget does not support
+      // nested options, flatten the list.
+      if (!$this->supportsGroups()) {
+        $options = $this->flattenOptions($options);
+      }
+
+      $this->options = $options;
+    }
+    return $this->options;
+  }
+
+  /**
+   * Determines selected options from the incoming field values.
+   *
+   * @param \Drupal\Core\Entity\Field\FieldItemListInterface $items
+   *   The field values.
+   * @param int $delta
+   *   (optional) The delta of the item to get options for. Defaults to 0.
+   *
+   * @return array
+   *   The array of corresponding selected options.
+   */
+  protected function getSelectedOptions(FieldItemListInterface $items, $delta = 0) {
+    // We need to check against a flat list of options.
+    $flat_options = $this->flattenOptions($this->getOptions($items[$delta]));
+
+    $selected_options = array();
+    foreach ($items as $item) {
+      $value = $item->{$this->column};
+      // Keep the value if it actually is in the list of options (needs to be
+      // checked against the flat list).
+      if (isset($flat_options[$value])) {
+        $selected_options[] = $value;
+      }
+    }
+
+    return $selected_options;
+  }
+
+  /**
+   * Flattens an array of allowed values.
+   *
+   * @param array $array
+   *   A single or multidimensional array.
+   *
+   * @return array
+   *   The flattened array.
+   */
+  protected function flattenOptions(array $array) {
+    $result = array();
+    array_walk_recursive($array, function($a, $b) use (&$result) { $result[$b] = $a; });
+    return $result;
+  }
+
+  /**
+   * Indicates whether the widgets support optgroups.
+   *
+   * @return bool
+   *   TRUE if the widget supports optgroups, FALSE otherwise.
+   */
+  protected function supportsGroups() {
+    return FALSE;
+  }
+
+  /**
+   * Sanitizes a string label to display as an option.
+   *
+   * @param string $label
+   *   The label to sanitize.
+   */
+  static protected function sanitizeLabel(&$label) {
+    // Allow a limited set of HTML tags.
+    $label = field_filter_xss($label);
+  }
+
+  /**
+   * Returns the empty option to add to the list of options, if any.
+   *
+   * @return string|null
+   *   Either static::OPTIONS_EMPTY_NONE, static::OPTIONS_EMPTY_SELECT, or NULL.
+   */
+  protected function getEmptyOption() { }
+
+}
diff --git a/core/modules/options/lib/Drupal/options/Plugin/Field/FieldWidget/SelectWidget.php b/core/modules/options/lib/Drupal/options/Plugin/Field/FieldWidget/SelectWidget.php
new file mode 100644
index 0000000..e4dab67
--- /dev/null
+++ b/core/modules/options/lib/Drupal/options/Plugin/Field/FieldWidget/SelectWidget.php
@@ -0,0 +1,84 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\options\Plugin\Field\FieldWidget\SelectWidget.
+ */
+
+namespace Drupal\options\Plugin\Field\FieldWidget;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+use Drupal\options\Plugin\Field\FieldWidget\OptionsWidgetBase;
+
+/**
+ * Plugin implementation of the 'options_select' widget.
+ *
+ * @FieldWidget(
+ *   id = "options_select",
+ *   label = @Translation("Select list"),
+ *   field_types = {
+ *     "list_integer",
+ *     "list_float",
+ *     "list_text"
+ *   },
+ *   multiple_values = TRUE
+ * )
+ */
+class SelectWidget extends OptionsWidgetBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
+    $element = parent::formElement($items, $delta, $element, $form, $form_state);
+
+    $element += array(
+      '#type' => 'select',
+      '#options' => $this->getOptions($items[$delta]),
+      '#default_value' => $this->getSelectedOptions($items, $delta),
+      // Do not display a 'multiple' select box if there is only one option.
+      '#multiple' => $this->multiple && count($this->options) > 1,
+    );
+
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  static protected function sanitizeLabel(&$label) {
+    // Select form inputs allow unencoded HTML entities, but no HTML tags.
+    $label = strip_tags($label);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function supportsGroups() {
+    return TRUE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getEmptyOption() {
+    if ($this->multiple) {
+      // Multiple select: add a 'none' option for non-required fields.
+      if (!$this->required) {
+        return static::OPTIONS_EMPTY_NONE;
+      }
+    }
+    else {
+      // Single select: add a 'none' option for non-required fields,
+      // and a 'select a value' option for required fields that do not come
+      // with a value selected.
+      if (!$this->required) {
+        return static::OPTIONS_EMPTY_NONE;
+      }
+      if (!$this->has_value) {
+        return static::OPTIONS_EMPTY_SELECT;
+      }
+    }
+  }
+
+}
diff --git a/core/modules/options/lib/Drupal/options/Plugin/field/formatter/OptionsDefaultFormatter.php b/core/modules/options/lib/Drupal/options/Plugin/field/formatter/OptionsDefaultFormatter.php
deleted file mode 100644
index a4ac150..0000000
--- a/core/modules/options/lib/Drupal/options/Plugin/field/formatter/OptionsDefaultFormatter.php
+++ /dev/null
@@ -1,52 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\options\Plugin\field\formatter\OptionsDefaultFormatter.
- */
-
-namespace Drupal\options\Plugin\field\formatter;
-
-use Drupal\field\Plugin\Type\Formatter\FormatterBase;
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-
-/**
- * Plugin implementation of the 'list_default' formatter.
- *
- * @FieldFormatter(
- *   id = "list_default",
- *   label = @Translation("Default"),
- *   field_types = {
- *     "list_integer",
- *     "list_float",
- *     "list_text",
- *     "list_boolean"
- *   }
- * )
- */
-class OptionsDefaultFormatter extends FormatterBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function viewElements(FieldItemListInterface $items) {
-    $elements = array();
-
-    $entity = $items->getEntity();
-    $allowed_values = options_allowed_values($this->fieldDefinition, $entity);
-
-    foreach ($items as $delta => $item) {
-      if (isset($allowed_values[$item->value])) {
-        $output = field_filter_xss($allowed_values[$item->value]);
-      }
-      else {
-        // If no match was found in allowed values, fall back to the key.
-        $output = field_filter_xss($item->value);
-      }
-      $elements[$delta] = array('#markup' => $output);
-    }
-
-    return $elements;
-  }
-
-}
diff --git a/core/modules/options/lib/Drupal/options/Plugin/field/formatter/OptionsKeyFormatter.php b/core/modules/options/lib/Drupal/options/Plugin/field/formatter/OptionsKeyFormatter.php
deleted file mode 100644
index 0c31bda..0000000
--- a/core/modules/options/lib/Drupal/options/Plugin/field/formatter/OptionsKeyFormatter.php
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\options\Plugin\field\formatter\OptionsKeyFormatter.
- */
-
-namespace Drupal\options\Plugin\field\formatter;
-
-use Drupal\field\Plugin\Type\Formatter\FormatterBase;
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-
-/**
- * Plugin implementation of the 'list_key' formatter.
- *
- * @FieldFormatter(
- *   id = "list_key",
- *   label = @Translation("Key"),
- *   field_types = {
- *     "list_integer",
- *     "list_float",
- *     "list_text",
- *     "list_boolean"
- *   }
- * )
- */
-class OptionsKeyFormatter extends FormatterBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function viewElements(FieldItemListInterface $items) {
-    $elements = array();
-
-    foreach ($items as $delta => $item) {
-      $elements[$delta] = array('#markup' => field_filter_xss($item->value));
-    }
-
-    return $elements;
-  }
-
-}
diff --git a/core/modules/options/lib/Drupal/options/Plugin/field/widget/ButtonsWidget.php b/core/modules/options/lib/Drupal/options/Plugin/field/widget/ButtonsWidget.php
deleted file mode 100644
index 75b2904..0000000
--- a/core/modules/options/lib/Drupal/options/Plugin/field/widget/ButtonsWidget.php
+++ /dev/null
@@ -1,74 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\options\Plugin\field\widget\ButtonsWidget.
- */
-
-namespace Drupal\options\Plugin\field\widget;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-
-/**
- * Plugin implementation of the 'options_buttons' widget.
- *
- * @FieldWidget(
- *   id = "options_buttons",
- *   label = @Translation("Check boxes/radio buttons"),
- *   field_types = {
- *     "list_integer",
- *     "list_float",
- *     "list_text",
- *     "list_boolean"
- *   },
- *   multiple_values = TRUE
- * )
- */
-class ButtonsWidget extends OptionsWidgetBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
-    $element = parent::formElement($items, $delta, $element, $form, $form_state);
-
-    $options = $this->getOptions($items[$delta]);
-    $selected = $this->getSelectedOptions($items);
-
-    // If required and there is one single option, preselect it.
-    if ($this->required && count($options) == 1) {
-      reset($options);
-      $selected = array(key($options));
-    }
-
-    if ($this->multiple) {
-      $element += array(
-        '#type' => 'checkboxes',
-        '#default_value' => $selected,
-        '#options' => $options,
-      );
-    }
-    else {
-      $element += array(
-        '#type' => 'radios',
-        // Radio buttons need a scalar value. Take the first default value, or
-        // default to NULL so that the form element is properly recognized as
-        // not having a default value.
-        '#default_value' => $selected ? reset($selected) : NULL,
-        '#options' => $options,
-      );
-    }
-
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function getEmptyOption() {
-    if (!$this->required && !$this->multiple) {
-      return static::OPTIONS_EMPTY_NONE;
-    }
-  }
-
-}
diff --git a/core/modules/options/lib/Drupal/options/Plugin/field/widget/OnOffWidget.php b/core/modules/options/lib/Drupal/options/Plugin/field/widget/OnOffWidget.php
deleted file mode 100644
index 31c9183..0000000
--- a/core/modules/options/lib/Drupal/options/Plugin/field/widget/OnOffWidget.php
+++ /dev/null
@@ -1,79 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\options\Plugin\field\widget\OnOffWidget.
- */
-
-namespace Drupal\options\Plugin\field\widget;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-
-/**
- * Plugin implementation of the 'options_onoff' widget.
- *
- * @FieldWidget(
- *   id = "options_onoff",
- *   label = @Translation("Single on/off checkbox"),
- *   field_types = {
- *     "list_boolean"
- *   },
- *   settings = {
- *     "display_label" = FALSE,
- *   },
- *   multiple_values = TRUE
- * )
- */
-class OnOffWidget extends OptionsWidgetBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsForm(array $form, array &$form_state) {
-    $element['display_label'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Use field label instead of the "On value" as label'),
-      '#default_value' => $this->getSetting('display_label'),
-      '#weight' => -1,
-    );
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    $summary = array();
-
-    $display_label = $this->getSetting('display_label');
-    $summary[] = t('Use field label: @display_label', array('@display_label' => ($display_label ? t('Yes') : 'No')));
-
-    return $summary;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
-    $element = parent::formElement($items, $delta, $element, $form, $form_state);
-
-    $options = $this->getOptions($items[$delta]);
-    $selected = $this->getSelectedOptions($items);
-
-    $element += array(
-      '#type' => 'checkbox',
-      '#default_value' => !empty($selected[0]),
-    );
-
-    // Override the title from the incoming $element.
-    if ($this->getSetting('display_label')) {
-      $element['#title'] = $this->fieldDefinition->getFieldLabel();
-    }
-    else {
-      $element['#title'] = isset($options[1]) ? $options[1] : '';
-    }
-
-    return $element;
-  }
-
-}
diff --git a/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php b/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php
deleted file mode 100644
index 2301789..0000000
--- a/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php
+++ /dev/null
@@ -1,235 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\options\Plugin\field\widget\OptionsWidgetBase.
- */
-
-namespace Drupal\options\Plugin\field\widget;
-
-use Drupal\Core\Entity\Field\FieldDefinitionInterface;
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\Core\Entity\Field\FieldItemInterface;
-use Drupal\field\Plugin\Type\Widget\WidgetBase;
-
-/**
- * Base class for the 'options_*' widgets.
- *
- * Field types willing to enable one or several of the widgets defined in
- * options.module (select, radios/checkboxes, on/off checkbox) need to
- * implement the AllowedValuesInterface to specify the list of options to
- * display in the widgets.
- *
- * @see \Drupal\Core\TypedData\AllowedValuesInterface
- */
-abstract class OptionsWidgetBase extends WidgetBase {
-
-  /**
-   * Identifies a 'None' option.
-   */
-  const OPTIONS_EMPTY_NONE = 'option_none';
-
-  /**
-   * Identifies a 'Select a value' option.
-   */
-  const OPTIONS_EMPTY_SELECT = 'option_select';
-
-  /**
-   * Abstract over the actual field columns, to allow different field types to
-   * reuse those widgets.
-   *
-   * @var string
-   */
-  protected $column;
-
-  /**
-   * {@inheritdoc}
-   */
-  public function __construct($plugin_id, array $plugin_definition, FieldDefinitionInterface $field_definition, array $settings) {
-    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings);
-    $property_names = $this->fieldDefinition->getFieldPropertyNames();
-    $this->column = $property_names[0];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
-    // Prepare some properties for the child methods to build the actual form
-    // element.
-    $this->required = $element['#required'];
-    $cardinality = $this->fieldDefinition->getFieldCardinality();
-    $this->multiple = ($cardinality == FIELD_CARDINALITY_UNLIMITED) || ($cardinality > 1);
-    $this->has_value = isset($items[0]->{$this->column});
-
-    // Add our custom validator.
-    $element['#element_validate'][] = array(get_class($this), 'validateElement');
-    $element['#key_column'] = $this->column;
-
-    // The rest of the $element is built by child method implementations.
-
-    return $element;
-  }
-
-  /**
-   * Form validation handler for widget elements.
-   *
-   * @param array $element
-   *   The form element.
-   * @param array $form_state
-   *   The form state.
-   */
-  public static function validateElement(array $element, array &$form_state) {
-    if ($element['#required'] && $element['#value'] == '_none') {
-      form_error($element, t('!name field is required.', array('!name' => $element['#title'])));
-    }
-
-    // Massage submitted form values.
-    // Drupal\field\Plugin\Type\Widget\WidgetBase::submit() expects values as
-    // an array of values keyed by delta first, then by column, while our
-    // widgets return the opposite.
-
-    if (is_array($element['#value'])) {
-      $values = array_values($element['#value']);
-    }
-    else {
-      $values = array($element['#value']);
-    }
-
-    // Filter out the 'none' option. Use a strict comparison, because
-    // 0 == 'any string'.
-    $index = array_search('_none', $values, TRUE);
-    if ($index !== FALSE) {
-      unset($values[$index]);
-    }
-
-    // Transpose selections from field => delta to delta => field.
-    $items = array();
-    foreach ($values as $value) {
-      $items[] = array($element['#key_column'] => $value);
-    }
-    form_set_value($element, $items, $form_state);
-  }
-
-  /**
-   * Returns the array of options for the widget.
-   *
-   * @param \Drupal\Core\Entity\Field\FieldItemInterface $item
-   *   The field item.
-   *
-   * @return array
-   *   The array of options for the widget.
-   */
-  protected function getOptions(FieldItemInterface $item) {
-    if (!isset($this->options)) {
-      // Limit the settable options for the current user account.
-      $options = $item->getSettableOptions(\Drupal::currentUser());
-
-      // Add an empty option if the widget needs one.
-      if ($empty_option = $this->getEmptyOption()) {
-        switch ($this->getPluginId()) {
-          case 'options_buttons':
-            $label = t('N/A');
-            break;
-
-          case 'options_select':
-            $label = ($empty_option == static::OPTIONS_EMPTY_NONE ? t('- None -') : t('- Select a value -'));
-            break;
-        }
-
-        $options = array('_none' => $label) + $options;
-      }
-
-      $module_handler = \Drupal::moduleHandler();
-      $context = array(
-        'fieldDefinition' => $this->fieldDefinition,
-        'entity' => $item->getEntity(),
-      );
-      $module_handler->alter('options_list', $options, $context);
-
-      array_walk_recursive($options, array($this, 'sanitizeLabel'));
-
-      // Options might be nested ("optgroups"). If the widget does not support
-      // nested options, flatten the list.
-      if (!$this->supportsGroups()) {
-        $options = $this->flattenOptions($options);
-      }
-
-      $this->options = $options;
-    }
-    return $this->options;
-  }
-
-  /**
-   * Determines selected options from the incoming field values.
-   *
-   * @param \Drupal\Core\Entity\Field\FieldItemListInterface $items
-   *   The field values.
-   * @param int $delta
-   *   (optional) The delta of the item to get options for. Defaults to 0.
-   *
-   * @return array
-   *   The array of corresponding selected options.
-   */
-  protected function getSelectedOptions(FieldItemListInterface $items, $delta = 0) {
-    // We need to check against a flat list of options.
-    $flat_options = $this->flattenOptions($this->getOptions($items[$delta]));
-
-    $selected_options = array();
-    foreach ($items as $item) {
-      $value = $item->{$this->column};
-      // Keep the value if it actually is in the list of options (needs to be
-      // checked against the flat list).
-      if (isset($flat_options[$value])) {
-        $selected_options[] = $value;
-      }
-    }
-
-    return $selected_options;
-  }
-
-  /**
-   * Flattens an array of allowed values.
-   *
-   * @param array $array
-   *   A single or multidimensional array.
-   *
-   * @return array
-   *   The flattened array.
-   */
-  protected function flattenOptions(array $array) {
-    $result = array();
-    array_walk_recursive($array, function($a, $b) use (&$result) { $result[$b] = $a; });
-    return $result;
-  }
-
-  /**
-   * Indicates whether the widgets support optgroups.
-   *
-   * @return bool
-   *   TRUE if the widget supports optgroups, FALSE otherwise.
-   */
-  protected function supportsGroups() {
-    return FALSE;
-  }
-
-  /**
-   * Sanitizes a string label to display as an option.
-   *
-   * @param string $label
-   *   The label to sanitize.
-   */
-  static protected function sanitizeLabel(&$label) {
-    // Allow a limited set of HTML tags.
-    $label = field_filter_xss($label);
-  }
-
-  /**
-   * Returns the empty option to add to the list of options, if any.
-   *
-   * @return string|null
-   *   Either static::OPTIONS_EMPTY_NONE, static::OPTIONS_EMPTY_SELECT, or NULL.
-   */
-  protected function getEmptyOption() { }
-
-}
diff --git a/core/modules/options/lib/Drupal/options/Plugin/field/widget/SelectWidget.php b/core/modules/options/lib/Drupal/options/Plugin/field/widget/SelectWidget.php
deleted file mode 100644
index 47e96b4..0000000
--- a/core/modules/options/lib/Drupal/options/Plugin/field/widget/SelectWidget.php
+++ /dev/null
@@ -1,83 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\options\Plugin\field\widget\SelectWidget.
- */
-
-namespace Drupal\options\Plugin\field\widget;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-
-/**
- * Plugin implementation of the 'options_select' widget.
- *
- * @FieldWidget(
- *   id = "options_select",
- *   label = @Translation("Select list"),
- *   field_types = {
- *     "list_integer",
- *     "list_float",
- *     "list_text"
- *   },
- *   multiple_values = TRUE
- * )
- */
-class SelectWidget extends OptionsWidgetBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
-    $element = parent::formElement($items, $delta, $element, $form, $form_state);
-
-    $element += array(
-      '#type' => 'select',
-      '#options' => $this->getOptions($items[$delta]),
-      '#default_value' => $this->getSelectedOptions($items, $delta),
-      // Do not display a 'multiple' select box if there is only one option.
-      '#multiple' => $this->multiple && count($this->options) > 1,
-    );
-
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  static protected function sanitizeLabel(&$label) {
-    // Select form inputs allow unencoded HTML entities, but no HTML tags.
-    $label = strip_tags($label);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function supportsGroups() {
-    return TRUE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function getEmptyOption() {
-    if ($this->multiple) {
-      // Multiple select: add a 'none' option for non-required fields.
-      if (!$this->required) {
-        return static::OPTIONS_EMPTY_NONE;
-      }
-    }
-    else {
-      // Single select: add a 'none' option for non-required fields,
-      // and a 'select a value' option for required fields that do not come
-      // with a value selected.
-      if (!$this->required) {
-        return static::OPTIONS_EMPTY_NONE;
-      }
-      if (!$this->has_value) {
-        return static::OPTIONS_EMPTY_SELECT;
-      }
-    }
-  }
-
-}
diff --git a/core/modules/picture/lib/Drupal/picture/Plugin/Field/FieldFormatter/PictureFormatter.php b/core/modules/picture/lib/Drupal/picture/Plugin/Field/FieldFormatter/PictureFormatter.php
new file mode 100644
index 0000000..88828cc
--- /dev/null
+++ b/core/modules/picture/lib/Drupal/picture/Plugin/Field/FieldFormatter/PictureFormatter.php
@@ -0,0 +1,185 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\picture\Plugin\field\formatter\PictureFormatter.
+ */
+
+namespace Drupal\picture\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+use Drupal\image\Plugin\Field\FieldFormatter\ImageFormatterBase;
+
+/**
+ * Plugin for picture formatter.
+ *
+ * @FieldFormatter(
+ *   id = "picture",
+ *   label = @Translation("Picture"),
+ *   field_types = {
+ *     "image",
+ *   },
+ *   settings = {
+ *     "picture_mapping" = "",
+ *     "fallback_image_style" = "",
+ *     "image_link" = "",
+ *   }
+ * )
+ */
+class PictureFormatter extends ImageFormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    $picture_options = array();
+    $picture_mappings = entity_load_multiple('picture_mapping');
+    if ($picture_mappings && !empty($picture_mappings)) {
+      foreach ($picture_mappings as $machine_name => $picture_mapping) {
+        if ($picture_mapping->hasMappings()) {
+          $picture_options[$machine_name] = $picture_mapping->label();
+        }
+      }
+    }
+
+    $elements['picture_mapping'] = array(
+      '#title' => t('Picture mapping'),
+      '#type' => 'select',
+      '#default_value' => $this->getSetting('picture_mapping'),
+      '#required' => TRUE,
+      '#options' => $picture_options,
+    );
+
+    $image_styles = image_style_options(FALSE);
+    $elements['fallback_image_style'] = array(
+      '#title' => t('Fallback image style'),
+      '#type' => 'select',
+      '#default_value' => $this->getSetting('fallback_image_style'),
+      '#empty_option' => t('Automatic'),
+      '#options' => $image_styles,
+    );
+
+    $link_types = array(
+      'content' => t('Content'),
+      'file' => t('File'),
+    );
+    $elements['image_link'] = array(
+      '#title' => t('Link image to'),
+      '#type' => 'select',
+      '#default_value' => $this->getSetting('image_link'),
+      '#empty_option' => t('Nothing'),
+      '#options' => $link_types,
+    );
+
+    return $elements;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = array();
+
+    $picture_mapping = entity_load('picture_mapping', $this->getSetting('picture_mapping'));
+    if ($picture_mapping) {
+      $summary[] = t('Picture mapping: @picture_mapping', array('@picture_mapping' => $picture_mapping->label()));
+
+      $image_styles = image_style_options(FALSE);
+      unset($image_styles['']);
+      if (isset($image_styles[$this->getSetting('fallback_image_style')])) {
+        $summary[] = t('Fallback Image style: @style', array('@style' => $image_styles[$this->getSetting('fallback_image_style')]));
+      }
+      else {
+        $summary[] = t('Automatic fallback');
+      }
+
+      $link_types = array(
+        'content' => t('Linked to content'),
+        'file' => t('Linked to file'),
+      );
+      // Display this setting only if image is linked.
+      if (isset($link_types[$this->getSetting('image_link')])) {
+        $summary[] = $link_types[$this->getSetting('image_link')];
+      }
+    }
+    else {
+      $summary[] = t('Select a picture mapping.');
+    }
+
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+    $elements = array();
+    // Check if the formatter involves a link.
+    if ($this->getSetting('image_link') == 'content') {
+      $uri = $items->getEntity()->uri();
+    }
+    elseif ($this->getSetting('image_link') == 'file') {
+      $link_file = TRUE;
+    }
+
+    $breakpoint_styles = array();
+    $fallback_image_style = '';
+
+    $picture_mapping = entity_load('picture_mapping', $this->getSetting('picture_mapping'));
+    if ($picture_mapping) {
+      foreach ($picture_mapping->mappings as $breakpoint_name => $multipliers) {
+        // Make sure there are multipliers.
+        if (!empty($multipliers)) {
+          // Make sure that the breakpoint exists and is enabled.
+          // @todo add the following when breakpoint->status is added again:
+          // $picture_mapping->breakpointGroup->breakpoints[$breakpoint_name]->status
+          if (isset($picture_mapping->breakpointGroup->breakpoints[$breakpoint_name])) {
+            $breakpoint = $picture_mapping->breakpointGroup->breakpoints[$breakpoint_name];
+
+            // Determine the enabled multipliers.
+            $multipliers = array_intersect_key($multipliers, $breakpoint->multipliers);
+            foreach ($multipliers as $multiplier => $image_style) {
+              // Make sure the multiplier still exists.
+              if (!empty($image_style)) {
+                // First mapping found is used as fallback.
+                if (empty($fallback_image_style)) {
+                  $fallback_image_style = $image_style;
+                }
+                if (!isset($breakpoint_styles[$breakpoint_name])) {
+                  $breakpoint_styles[$breakpoint_name] = array();
+                }
+                $breakpoint_styles[$breakpoint_name][$multiplier] = $image_style;
+              }
+            }
+          }
+        }
+      }
+    }
+
+    // Check if the user defined a custom fallback image style.
+    if ($this->getSetting('fallback_image_style')) {
+      $fallback_image_style = $this->getSetting('fallback_image_style');
+    }
+
+    foreach ($items as $delta => $item) {
+      if (isset($link_file)) {
+        $uri = array(
+          'path' => file_create_url($item->entity->getFileUri()),
+          'options' => array(),
+        );
+      }
+      $elements[$delta] = array(
+        '#theme' => 'picture_formatter',
+        '#attached' => array('library' => array(
+          array('picture', 'picturefill'),
+        )),
+        '#item' => $item->getValue(TRUE),
+        '#image_style' => $fallback_image_style,
+        '#breakpoints' => $breakpoint_styles,
+        '#path' => isset($uri) ? $uri : '',
+      );
+    }
+
+    return $elements;
+  }
+}
diff --git a/core/modules/picture/lib/Drupal/picture/Plugin/field/formatter/PictureFormatter.php b/core/modules/picture/lib/Drupal/picture/Plugin/field/formatter/PictureFormatter.php
deleted file mode 100644
index f8b2278..0000000
--- a/core/modules/picture/lib/Drupal/picture/Plugin/field/formatter/PictureFormatter.php
+++ /dev/null
@@ -1,185 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\picture\Plugin\field\formatter\PictureFormatter.
- */
-
-namespace Drupal\picture\Plugin\field\formatter;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\image\Plugin\field\formatter\ImageFormatterBase;
-
-/**
- * Plugin for picture formatter.
- *
- * @FieldFormatter(
- *   id = "picture",
- *   label = @Translation("Picture"),
- *   field_types = {
- *     "image",
- *   },
- *   settings = {
- *     "picture_mapping" = "",
- *     "fallback_image_style" = "",
- *     "image_link" = "",
- *   }
- * )
- */
-class PictureFormatter extends ImageFormatterBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsForm(array $form, array &$form_state) {
-    $picture_options = array();
-    $picture_mappings = entity_load_multiple('picture_mapping');
-    if ($picture_mappings && !empty($picture_mappings)) {
-      foreach ($picture_mappings as $machine_name => $picture_mapping) {
-        if ($picture_mapping->hasMappings()) {
-          $picture_options[$machine_name] = $picture_mapping->label();
-        }
-      }
-    }
-
-    $elements['picture_mapping'] = array(
-      '#title' => t('Picture mapping'),
-      '#type' => 'select',
-      '#default_value' => $this->getSetting('picture_mapping'),
-      '#required' => TRUE,
-      '#options' => $picture_options,
-    );
-
-    $image_styles = image_style_options(FALSE);
-    $elements['fallback_image_style'] = array(
-      '#title' => t('Fallback image style'),
-      '#type' => 'select',
-      '#default_value' => $this->getSetting('fallback_image_style'),
-      '#empty_option' => t('Automatic'),
-      '#options' => $image_styles,
-    );
-
-    $link_types = array(
-      'content' => t('Content'),
-      'file' => t('File'),
-    );
-    $elements['image_link'] = array(
-      '#title' => t('Link image to'),
-      '#type' => 'select',
-      '#default_value' => $this->getSetting('image_link'),
-      '#empty_option' => t('Nothing'),
-      '#options' => $link_types,
-    );
-
-    return $elements;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    $summary = array();
-
-    $picture_mapping = entity_load('picture_mapping', $this->getSetting('picture_mapping'));
-    if ($picture_mapping) {
-      $summary[] = t('Picture mapping: @picture_mapping', array('@picture_mapping' => $picture_mapping->label()));
-
-      $image_styles = image_style_options(FALSE);
-      unset($image_styles['']);
-      if (isset($image_styles[$this->getSetting('fallback_image_style')])) {
-        $summary[] = t('Fallback Image style: @style', array('@style' => $image_styles[$this->getSetting('fallback_image_style')]));
-      }
-      else {
-        $summary[] = t('Automatic fallback');
-      }
-
-      $link_types = array(
-        'content' => t('Linked to content'),
-        'file' => t('Linked to file'),
-      );
-      // Display this setting only if image is linked.
-      if (isset($link_types[$this->getSetting('image_link')])) {
-        $summary[] = $link_types[$this->getSetting('image_link')];
-      }
-    }
-    else {
-      $summary[] = t('Select a picture mapping.');
-    }
-
-    return $summary;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function viewElements(FieldItemListInterface $items) {
-    $elements = array();
-    // Check if the formatter involves a link.
-    if ($this->getSetting('image_link') == 'content') {
-      $uri = $items->getEntity()->uri();
-    }
-    elseif ($this->getSetting('image_link') == 'file') {
-      $link_file = TRUE;
-    }
-
-    $breakpoint_styles = array();
-    $fallback_image_style = '';
-
-    $picture_mapping = entity_load('picture_mapping', $this->getSetting('picture_mapping'));
-    if ($picture_mapping) {
-      foreach ($picture_mapping->mappings as $breakpoint_name => $multipliers) {
-        // Make sure there are multipliers.
-        if (!empty($multipliers)) {
-          // Make sure that the breakpoint exists and is enabled.
-          // @todo add the following when breakpoint->status is added again:
-          // $picture_mapping->breakpointGroup->breakpoints[$breakpoint_name]->status
-          if (isset($picture_mapping->breakpointGroup->breakpoints[$breakpoint_name])) {
-            $breakpoint = $picture_mapping->breakpointGroup->breakpoints[$breakpoint_name];
-
-            // Determine the enabled multipliers.
-            $multipliers = array_intersect_key($multipliers, $breakpoint->multipliers);
-            foreach ($multipliers as $multiplier => $image_style) {
-              // Make sure the multiplier still exists.
-              if (!empty($image_style)) {
-                // First mapping found is used as fallback.
-                if (empty($fallback_image_style)) {
-                  $fallback_image_style = $image_style;
-                }
-                if (!isset($breakpoint_styles[$breakpoint_name])) {
-                  $breakpoint_styles[$breakpoint_name] = array();
-                }
-                $breakpoint_styles[$breakpoint_name][$multiplier] = $image_style;
-              }
-            }
-          }
-        }
-      }
-    }
-
-    // Check if the user defined a custom fallback image style.
-    if ($this->getSetting('fallback_image_style')) {
-      $fallback_image_style = $this->getSetting('fallback_image_style');
-    }
-
-    foreach ($items as $delta => $item) {
-      if (isset($link_file)) {
-        $uri = array(
-          'path' => file_create_url($item->entity->getFileUri()),
-          'options' => array(),
-        );
-      }
-      $elements[$delta] = array(
-        '#theme' => 'picture_formatter',
-        '#attached' => array('library' => array(
-          array('picture', 'picturefill'),
-        )),
-        '#item' => $item->getValue(TRUE),
-        '#image_style' => $fallback_image_style,
-        '#breakpoints' => $breakpoint_styles,
-        '#path' => isset($uri) ? $uri : '',
-      );
-    }
-
-    return $elements;
-  }
-}
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldFormatter/EntityReferenceTaxonomyTermRssFormatter.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldFormatter/EntityReferenceTaxonomyTermRssFormatter.php
new file mode 100644
index 0000000..e5c9b77
--- /dev/null
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldFormatter/EntityReferenceTaxonomyTermRssFormatter.php
@@ -0,0 +1,48 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\taxonomy\Plugin\field\formatter\EntityReferenceTaxonomyTermRssFormatter.
+ */
+
+namespace Drupal\taxonomy\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+use Drupal\entity_reference\Plugin\Field\FieldFormatter\EntityReferenceFormatterBase;
+
+/**
+ * Plugin implementation of the 'entity reference taxonomy term RSS' formatter.
+ *
+ * @todo: Have a way to indicate this formatter applies only to taxonomy terms.
+ *
+ * @FieldFormatter(
+ *   id = "entity_reference_rss_category",
+ *   label = @Translation("RSS category"),
+ *   description = @Translation("Display reference to taxonomy term in RSS."),
+ *   field_types = {
+ *     "entity_reference"
+ *   }
+ * )
+ */
+class EntityReferenceTaxonomyTermRssFormatter extends EntityReferenceFormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+    $elements = array();
+    $entity = $items->getEntity();
+
+    foreach ($items as $item) {
+      $entity->rss_elements[] = array(
+        'key' => 'category',
+        'value' => $item->entity->label(),
+        'attributes' => array(
+          'domain' => $item->target_id ? url('taxonomy/term/' . $item->target_id, array('absolute' => TRUE)) : '',
+        ),
+      );
+    }
+
+    return $elements;
+  }
+}
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldFormatter/LinkFormatter.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldFormatter/LinkFormatter.php
new file mode 100644
index 0000000..feb5b90
--- /dev/null
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldFormatter/LinkFormatter.php
@@ -0,0 +1,62 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\taxonomy\Plugin\field\formatter\LinkFormatter.
+ */
+
+namespace Drupal\taxonomy\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+
+/**
+ * Plugin implementation of the 'taxonomy_term_reference_link' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "taxonomy_term_reference_link",
+ *   label = @Translation("Link"),
+ *   field_types = {
+ *     "taxonomy_term_reference"
+ *   }
+ * )
+ */
+class LinkFormatter extends TaxonomyFormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+    $elements = array();
+
+    // Terms without target_id do not exist yet, theme such terms as just their
+    // name.
+    foreach ($items as $delta => $item) {
+      if (!$item->target_id) {
+        $elements[$delta] = array(
+          '#markup' => check_plain($item->entity->label()),
+        );
+      }
+      else {
+        $term = $item->entity;
+        $uri = $term->uri();
+        $elements[$delta] = array(
+          '#type' => 'link',
+          '#title' => $term->label(),
+          '#href' => $uri['path'],
+          '#options' => $uri['options'],
+        );
+
+        if (!empty($item->_attributes)) {
+          $elements[$delta]['#options'] += array('attributes' => array());
+          $elements[$delta]['#options']['attributes'] += $item->_attributes;
+          // Unset field item attributes since they have been included in the
+          // formatter output and should not be rendered in the field template.
+          unset($item->_attributes);
+        }
+      }
+    }
+
+    return $elements;
+  }
+
+}
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldFormatter/PlainFormatter.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldFormatter/PlainFormatter.php
new file mode 100644
index 0000000..a129e88
--- /dev/null
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldFormatter/PlainFormatter.php
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\taxonomy\Plugin\field\formatter\PlainFormatter.
+ */
+
+namespace Drupal\taxonomy\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+
+/**
+ * Plugin implementation of the 'taxonomy_term_reference_plain' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "taxonomy_term_reference_plain",
+ *   label = @Translation("Plain text"),
+ *   field_types = {
+ *     "taxonomy_term_reference"
+ *   }
+ * )
+ */
+class PlainFormatter extends TaxonomyFormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+    $elements = array();
+
+    foreach ($items as $delta => $item) {
+      $elements[$delta] = array(
+        '#markup' => check_plain($item->entity->label()),
+      );
+    }
+
+    return $elements;
+  }
+
+}
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldFormatter/RSSCategoryFormatter.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldFormatter/RSSCategoryFormatter.php
new file mode 100644
index 0000000..b3be14c
--- /dev/null
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldFormatter/RSSCategoryFormatter.php
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\taxonomy\Plugin\field\formatter\RSSCategoryFormatter.
+ */
+
+namespace Drupal\taxonomy\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+
+/**
+ * Plugin implementation of the 'taxonomy_term_reference_rss_category' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "taxonomy_term_reference_rss_category",
+ *   label = @Translation("RSS category"),
+ *   field_types = {
+ *     "taxonomy_term_reference"
+ *   }
+ * )
+ */
+class RSSCategoryFormatter extends TaxonomyFormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+    $entity = $items->getEntity();
+
+    // Terms whose target_id is 'autocreate' do not exist yet and
+    // $item->entity is not set. Theme such terms as just their name.
+    foreach ($items as $item) {
+      if ($item->target_id) {
+        $value = $item->entity->label();
+
+        $uri = $item->entity->uri();
+        $uri['options']['absolute'] = TRUE;
+        $domain = url($uri['path'], $uri['options']);
+      }
+      else {
+        $value = $item->entity->label();
+        $domain = '';
+      }
+      $entity->rss_elements[] = array(
+        'key' => 'category',
+        'value' => $value,
+        'attributes' => array(
+          'domain' => $domain,
+        ),
+      );
+    }
+  }
+
+}
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldFormatter/TaxonomyFormatterBase.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldFormatter/TaxonomyFormatterBase.php
new file mode 100644
index 0000000..fd942d9
--- /dev/null
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldFormatter/TaxonomyFormatterBase.php
@@ -0,0 +1,69 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\taxonomy\Plugin\field\formatter\TaxonomyFormatterBase.
+ */
+
+namespace Drupal\taxonomy\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Field\FormatterBase;
+
+/**
+ * Base class for the taxonomy_term formatters.
+ */
+abstract class TaxonomyFormatterBase extends FormatterBase {
+
+  /**
+   * {@inheritdoc}
+   *
+   * This preloads all taxonomy terms for multiple loaded objects at once and
+   * unsets values for invalid terms that do not exist.
+   */
+  public function prepareView(array $entities_items) {
+    $tids = array();
+
+    // Collect every possible term attached to any of the fieldable entities.
+    foreach ($entities_items as $items) {
+      foreach ($items as $item) {
+        // Force the array key to prevent duplicates.
+        if ($item->target_id !== 0) {
+          $tids[$item->target_id] = $item->target_id;
+        }
+      }
+    }
+    if ($tids) {
+      $terms = entity_load_multiple('taxonomy_term', $tids);
+
+      // Iterate through the fieldable entities again to attach the loaded term
+      // data.
+      foreach ($entities_items as $items) {
+        $rekey = FALSE;
+
+        foreach ($items as $item) {
+          // Check whether the taxonomy term field instance value could be
+          // loaded.
+          if (isset($terms[$item->target_id])) {
+            // Replace the instance value with the term data.
+            $item->entity = $terms[$item->target_id];
+          }
+          // Terms to be created are not in $terms, but are still legitimate.
+          elseif ($item->target_id === 0 && isset($item->entity)) {
+            // Leave the item in place.
+          }
+          // Otherwise, unset the instance value, since the term does not exist.
+          else {
+            $item->setValue(NULL);
+            $rekey = TRUE;
+          }
+        }
+
+        // Rekey the items array if needed.
+        if ($rekey) {
+          $items->filterEmptyValues();
+        }
+      }
+    }
+  }
+
+}
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldWidget/TaxonomyAutocompleteWidget.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldWidget/TaxonomyAutocompleteWidget.php
new file mode 100644
index 0000000..9e7f2e5
--- /dev/null
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldWidget/TaxonomyAutocompleteWidget.php
@@ -0,0 +1,125 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\taxonomy\Plugin\Field\FieldWidget\TaxonomyAutocompleteWidget.
+ */
+
+namespace Drupal\taxonomy\Plugin\Field\FieldWidget;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+use Drupal\Core\Field\WidgetBase;
+
+/**
+ * Plugin implementation of the 'taxonomy_autocomplete' widget.
+ *
+ * @FieldWidget(
+ *   id = "taxonomy_autocomplete",
+ *   label = @Translation("Autocomplete term widget (tagging)"),
+ *   field_types = {
+ *     "taxonomy_term_reference"
+ *   },
+ *   settings = {
+ *     "size" = "60",
+ *     "autocomplete_route_name" = "taxonomy.autocomplete",
+ *     "placeholder" = ""
+ *   },
+ *   multiple_values = TRUE
+ * )
+ */
+class TaxonomyAutocompleteWidget extends WidgetBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    $element['placeholder'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Placeholder'),
+      '#default_value' => $this->getSetting('placeholder'),
+      '#description' => t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'),
+    );
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = array();
+
+    $summary[] = t('Textfield size: !size', array('!size' => $this->getSetting('size')));
+    $placeholder = $this->getSetting('placeholder');
+    if (!empty($placeholder)) {
+      $summary[] = t('Placeholder: @placeholder', array('@placeholder' => $placeholder));
+    }
+    else {
+      $summary[] = t('No placeholder');
+    }
+
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
+    $tags = array();
+    foreach ($items as $item) {
+      $tags[] = isset($item->entity) ? $item->entity : entity_load('taxonomy_term', $item->target_id);
+    }
+    $element += array(
+      '#type' => 'textfield',
+      '#default_value' => taxonomy_implode_tags($tags),
+      '#autocomplete_route_name' => $this->getSetting('autocomplete_route_name'),
+      '#autocomplete_route_parameters' => array(
+        'entity_type' => $items->getEntity()->entityType(),
+        'field_name' => $this->fieldDefinition->getFieldName(),
+      ),
+      '#size' => $this->getSetting('size'),
+      '#placeholder' => $this->getSetting('placeholder'),
+      '#maxlength' => 1024,
+      '#element_validate' => array('taxonomy_autocomplete_validate'),
+    );
+
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function massageFormValues(array $values, array $form, array &$form_state) {
+    // Autocomplete widgets do not send their tids in the form, so we must detect
+    // them here and process them independently.
+    $items = array();
+
+    // Collect candidate vocabularies.
+    foreach ($this->getFieldSetting('allowed_values') as $tree) {
+      if ($vocabulary = entity_load('taxonomy_vocabulary', $tree['vocabulary'])) {
+        $vocabularies[$vocabulary->id()] = $vocabulary;
+      }
+    }
+
+    // Translate term names into actual terms.
+    foreach($values as $value) {
+      // See if the term exists in the chosen vocabulary and return the tid;
+      // otherwise, create a new term.
+      if ($possibilities = entity_load_multiple_by_properties('taxonomy_term', array('name' => trim($value), 'vid' => array_keys($vocabularies)))) {
+        $term = array_pop($possibilities);
+        $item = array('target_id' => $term->id());
+      }
+      else {
+        $vocabulary = reset($vocabularies);
+        $term = entity_create('taxonomy_term', array(
+          'vid' => $vocabulary->id(),
+          'name' => $value,
+        ));
+        $item = array('target_id' => 0, 'entity' => $term);
+      }
+      $items[] = $item;
+    }
+
+    return $items;
+  }
+
+}
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/formatter/EntityReferenceTaxonomyTermRssFormatter.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/formatter/EntityReferenceTaxonomyTermRssFormatter.php
deleted file mode 100644
index 65fae9b..0000000
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/formatter/EntityReferenceTaxonomyTermRssFormatter.php
+++ /dev/null
@@ -1,48 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\taxonomy\Plugin\field\formatter\EntityReferenceTaxonomyTermRssFormatter.
- */
-
-namespace Drupal\taxonomy\Plugin\field\formatter;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\entity_reference\Plugin\field\formatter\EntityReferenceFormatterBase;
-
-/**
- * Plugin implementation of the 'entity reference taxonomy term RSS' formatter.
- *
- * @todo: Have a way to indicate this formatter applies only to taxonomy terms.
- *
- * @FieldFormatter(
- *   id = "entity_reference_rss_category",
- *   label = @Translation("RSS category"),
- *   description = @Translation("Display reference to taxonomy term in RSS."),
- *   field_types = {
- *     "entity_reference"
- *   }
- * )
- */
-class EntityReferenceTaxonomyTermRssFormatter extends EntityReferenceFormatterBase {
-
-  /**
-   * Overrides Drupal\entity_reference\Plugin\field\formatter\EntityReferenceFormatterBase::viewElements().
-   */
-  public function viewElements(FieldItemListInterface $items) {
-    $elements = array();
-    $entity = $items->getEntity();
-
-    foreach ($items as $item) {
-      $entity->rss_elements[] = array(
-        'key' => 'category',
-        'value' => $item->entity->label(),
-        'attributes' => array(
-          'domain' => $item->target_id ? url('taxonomy/term/' . $item->target_id, array('absolute' => TRUE)) : '',
-        ),
-      );
-    }
-
-    return $elements;
-  }
-}
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/formatter/LinkFormatter.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/formatter/LinkFormatter.php
deleted file mode 100644
index d1ca287..0000000
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/formatter/LinkFormatter.php
+++ /dev/null
@@ -1,63 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\taxonomy\Plugin\field\formatter\LinkFormatter.
- */
-
-namespace Drupal\taxonomy\Plugin\field\formatter;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\taxonomy\Plugin\field\formatter\TaxonomyFormatterBase;
-
-/**
- * Plugin implementation of the 'taxonomy_term_reference_link' formatter.
- *
- * @FieldFormatter(
- *   id = "taxonomy_term_reference_link",
- *   label = @Translation("Link"),
- *   field_types = {
- *     "taxonomy_term_reference"
- *   }
- * )
- */
-class LinkFormatter extends TaxonomyFormatterBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function viewElements(FieldItemListInterface $items) {
-    $elements = array();
-
-    // Terms without target_id do not exist yet, theme such terms as just their
-    // name.
-    foreach ($items as $delta => $item) {
-      if (!$item->target_id) {
-        $elements[$delta] = array(
-          '#markup' => check_plain($item->entity->label()),
-        );
-      }
-      else {
-        $term = $item->entity;
-        $uri = $term->uri();
-        $elements[$delta] = array(
-          '#type' => 'link',
-          '#title' => $term->label(),
-          '#href' => $uri['path'],
-          '#options' => $uri['options'],
-        );
-
-        if (!empty($item->_attributes)) {
-          $elements[$delta]['#options'] += array('attributes' => array());
-          $elements[$delta]['#options']['attributes'] += $item->_attributes;
-          // Unset field item attributes since they have been included in the
-          // formatter output and should not be rendered in the field template.
-          unset($item->_attributes);
-        }
-      }
-    }
-
-    return $elements;
-  }
-
-}
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/formatter/PlainFormatter.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/formatter/PlainFormatter.php
deleted file mode 100644
index 3513d12..0000000
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/formatter/PlainFormatter.php
+++ /dev/null
@@ -1,41 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\taxonomy\Plugin\field\formatter\PlainFormatter.
- */
-
-namespace Drupal\taxonomy\Plugin\field\formatter;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\taxonomy\Plugin\field\formatter\TaxonomyFormatterBase;
-
-/**
- * Plugin implementation of the 'taxonomy_term_reference_plain' formatter.
- *
- * @FieldFormatter(
- *   id = "taxonomy_term_reference_plain",
- *   label = @Translation("Plain text"),
- *   field_types = {
- *     "taxonomy_term_reference"
- *   }
- * )
- */
-class PlainFormatter extends TaxonomyFormatterBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function viewElements(FieldItemListInterface $items) {
-    $elements = array();
-
-    foreach ($items as $delta => $item) {
-      $elements[$delta] = array(
-        '#markup' => check_plain($item->entity->label()),
-      );
-    }
-
-    return $elements;
-  }
-
-}
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/formatter/RSSCategoryFormatter.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/formatter/RSSCategoryFormatter.php
deleted file mode 100644
index 6d86b89..0000000
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/formatter/RSSCategoryFormatter.php
+++ /dev/null
@@ -1,56 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\taxonomy\Plugin\field\formatter\RSSCategoryFormatter.
- */
-
-namespace Drupal\taxonomy\Plugin\field\formatter;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\taxonomy\Plugin\field\formatter\TaxonomyFormatterBase;
-
-/**
- * Plugin implementation of the 'taxonomy_term_reference_rss_category' formatter.
- *
- * @FieldFormatter(
- *   id = "taxonomy_term_reference_rss_category",
- *   label = @Translation("RSS category"),
- *   field_types = {
- *     "taxonomy_term_reference"
- *   }
- * )
- */
-class RSSCategoryFormatter extends TaxonomyFormatterBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function viewElements(FieldItemListInterface $items) {
-    $entity = $items->getEntity();
-
-    // Terms whose target_id is 'autocreate' do not exist yet and
-    // $item->entity is not set. Theme such terms as just their name.
-    foreach ($items as $item) {
-      if ($item->target_id) {
-        $value = $item->entity->label();
-
-        $uri = $item->entity->uri();
-        $uri['options']['absolute'] = TRUE;
-        $domain = url($uri['path'], $uri['options']);
-      }
-      else {
-        $value = $item->entity->label();
-        $domain = '';
-      }
-      $entity->rss_elements[] = array(
-        'key' => 'category',
-        'value' => $value,
-        'attributes' => array(
-          'domain' => $domain,
-        ),
-      );
-    }
-  }
-
-}
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/formatter/TaxonomyFormatterBase.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/formatter/TaxonomyFormatterBase.php
deleted file mode 100644
index ef9cf1a..0000000
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/formatter/TaxonomyFormatterBase.php
+++ /dev/null
@@ -1,69 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\taxonomy\Plugin\field\formatter\TaxonomyFormatterBase.
- */
-
-namespace Drupal\taxonomy\Plugin\field\formatter;
-
-use Drupal\field\Plugin\Type\Formatter\FormatterBase;
-
-/**
- * Base class for the taxonomy_term formatters.
- */
-abstract class TaxonomyFormatterBase extends FormatterBase {
-
-  /**
-   * Implements \Drupal\field\Plugin\Type\Formatter\FormatterInterface::prepareView().
-   *
-   * This preloads all taxonomy terms for multiple loaded objects at once and
-   * unsets values for invalid terms that do not exist.
-   */
-  public function prepareView(array $entities_items) {
-    $tids = array();
-
-    // Collect every possible term attached to any of the fieldable entities.
-    foreach ($entities_items as $items) {
-      foreach ($items as $item) {
-        // Force the array key to prevent duplicates.
-        if ($item->target_id !== 0) {
-          $tids[$item->target_id] = $item->target_id;
-        }
-      }
-    }
-    if ($tids) {
-      $terms = entity_load_multiple('taxonomy_term', $tids);
-
-      // Iterate through the fieldable entities again to attach the loaded term
-      // data.
-      foreach ($entities_items as $items) {
-        $rekey = FALSE;
-
-        foreach ($items as $item) {
-          // Check whether the taxonomy term field instance value could be
-          // loaded.
-          if (isset($terms[$item->target_id])) {
-            // Replace the instance value with the term data.
-            $item->entity = $terms[$item->target_id];
-          }
-          // Terms to be created are not in $terms, but are still legitimate.
-          elseif ($item->target_id === 0 && isset($item->entity)) {
-            // Leave the item in place.
-          }
-          // Otherwise, unset the instance value, since the term does not exist.
-          else {
-            $item->setValue(NULL);
-            $rekey = TRUE;
-          }
-        }
-
-        // Rekey the items array if needed.
-        if ($rekey) {
-          $items->filterEmptyValues();
-        }
-      }
-    }
-  }
-
-}
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/widget/TaxonomyAutocompleteWidget.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/widget/TaxonomyAutocompleteWidget.php
deleted file mode 100644
index 77a52b7..0000000
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/widget/TaxonomyAutocompleteWidget.php
+++ /dev/null
@@ -1,125 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\taxonomy\Plugin\field\widget\TaxonomyAutocompleteWidget.
- */
-
-namespace Drupal\taxonomy\Plugin\field\widget;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\field\Plugin\Type\Widget\WidgetBase;
-
-/**
- * Plugin implementation of the 'taxonomy_autocomplete' widget.
- *
- * @FieldWidget(
- *   id = "taxonomy_autocomplete",
- *   label = @Translation("Autocomplete term widget (tagging)"),
- *   field_types = {
- *     "taxonomy_term_reference"
- *   },
- *   settings = {
- *     "size" = "60",
- *     "autocomplete_route_name" = "taxonomy.autocomplete",
- *     "placeholder" = ""
- *   },
- *   multiple_values = TRUE
- * )
- */
-class TaxonomyAutocompleteWidget extends WidgetBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsForm(array $form, array &$form_state) {
-    $element['placeholder'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Placeholder'),
-      '#default_value' => $this->getSetting('placeholder'),
-      '#description' => t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'),
-    );
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    $summary = array();
-
-    $summary[] = t('Textfield size: !size', array('!size' => $this->getSetting('size')));
-    $placeholder = $this->getSetting('placeholder');
-    if (!empty($placeholder)) {
-      $summary[] = t('Placeholder: @placeholder', array('@placeholder' => $placeholder));
-    }
-    else {
-      $summary[] = t('No placeholder');
-    }
-
-    return $summary;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
-    $tags = array();
-    foreach ($items as $item) {
-      $tags[] = isset($item->entity) ? $item->entity : entity_load('taxonomy_term', $item->target_id);
-    }
-    $element += array(
-      '#type' => 'textfield',
-      '#default_value' => taxonomy_implode_tags($tags),
-      '#autocomplete_route_name' => $this->getSetting('autocomplete_route_name'),
-      '#autocomplete_route_parameters' => array(
-        'entity_type' => $items->getEntity()->entityType(),
-        'field_name' => $this->fieldDefinition->getFieldName(),
-      ),
-      '#size' => $this->getSetting('size'),
-      '#placeholder' => $this->getSetting('placeholder'),
-      '#maxlength' => 1024,
-      '#element_validate' => array('taxonomy_autocomplete_validate'),
-    );
-
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function massageFormValues(array $values, array $form, array &$form_state) {
-    // Autocomplete widgets do not send their tids in the form, so we must detect
-    // them here and process them independently.
-    $items = array();
-
-    // Collect candidate vocabularies.
-    foreach ($this->getFieldSetting('allowed_values') as $tree) {
-      if ($vocabulary = entity_load('taxonomy_vocabulary', $tree['vocabulary'])) {
-        $vocabularies[$vocabulary->id()] = $vocabulary;
-      }
-    }
-
-    // Translate term names into actual terms.
-    foreach($values as $value) {
-      // See if the term exists in the chosen vocabulary and return the tid;
-      // otherwise, create a new term.
-      if ($possibilities = entity_load_multiple_by_properties('taxonomy_term', array('name' => trim($value), 'vid' => array_keys($vocabularies)))) {
-        $term = array_pop($possibilities);
-        $item = array('target_id' => $term->id());
-      }
-      else {
-        $vocabulary = reset($vocabularies);
-        $term = entity_create('taxonomy_term', array(
-          'vid' => $vocabulary->id(),
-          'name' => $value,
-        ));
-        $item = array('target_id' => 0, 'entity' => $term);
-      }
-      $items[] = $item;
-    }
-
-    return $items;
-  }
-
-}
diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module
index 2e67b30..f403e81 100644
--- a/core/modules/taxonomy/taxonomy.module
+++ b/core/modules/taxonomy/taxonomy.module
@@ -1031,7 +1031,7 @@ function taxonomy_term_title(Term $term) {
  */
 function taxonomy_autocomplete_validate($element, &$form_state) {
   // Split the values into an array.
-  // @see \Drupal\taxonomy\Plugin\field\widget\TaxonomyAutocompleteWidget:massageFormValues()
+  // @see \Drupal\taxonomy\Plugin\Field\FieldWidget\TaxonomyAutocompleteWidget:massageFormValues()
   $typed_terms = array();
   if ($tags = $element['#value']) {
     $typed_terms = drupal_explode_tags($tags);
diff --git a/core/modules/telephone/lib/Drupal/telephone/Plugin/Field/FieldFormatter/TelephoneLinkFormatter.php b/core/modules/telephone/lib/Drupal/telephone/Plugin/Field/FieldFormatter/TelephoneLinkFormatter.php
new file mode 100644
index 0000000..4cf003b
--- /dev/null
+++ b/core/modules/telephone/lib/Drupal/telephone/Plugin/Field/FieldFormatter/TelephoneLinkFormatter.php
@@ -0,0 +1,81 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\telephone\Plugin\field\formatter\TelephoneLinkFormatter.
+ */
+
+namespace Drupal\telephone\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Field\FormatterBase;
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+
+/**
+ * Plugin implementation of the 'telephone_link' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "telephone_link",
+ *   label = @Translation("Telephone link"),
+ *   field_types = {
+ *     "telephone"
+ *   },
+ *   settings = {
+ *     "title" = ""
+ *   }
+ * )
+ */
+class TelephoneLinkFormatter extends FormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    $elements['title'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Title to replace basic numeric telephone number display.'),
+      '#default_value' => $this->getSetting('title'),
+    );
+
+    return $elements;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = array();
+    $settings = $this->getSettings();
+
+    if (!empty($settings['title'])) {
+      $summary[] = t('Link using text: @title', array('@title' => $settings['title']));
+    }
+    else {
+      $summary[] = t('Link using provided telephone number.');
+    }
+
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+    $element = array();
+    $title_setting = $this->getSetting('title');
+
+    foreach ($items as $delta => $item) {
+      // Render each element as link.
+      $element[$delta] = array(
+        '#type' => 'link',
+        // Use custom title if available, otherwise use the telephone number
+        // itself as title.
+        '#title' => $title_setting ?: $item->value,
+        // Prepend 'tel:' to the telephone number.
+        '#href' => 'tel:' . rawurlencode(preg_replace('/\s+/', '', $item->value)),
+        '#options' => array('external' => TRUE),
+      );
+    }
+
+    return $element;
+  }
+}
diff --git a/core/modules/telephone/lib/Drupal/telephone/Plugin/Field/FieldWidget/TelephoneDefaultWidget.php b/core/modules/telephone/lib/Drupal/telephone/Plugin/Field/FieldWidget/TelephoneDefaultWidget.php
new file mode 100644
index 0000000..20e4089
--- /dev/null
+++ b/core/modules/telephone/lib/Drupal/telephone/Plugin/Field/FieldWidget/TelephoneDefaultWidget.php
@@ -0,0 +1,72 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\telephone\Plugin\Field\FieldWidget\TelephoneDefaultWidget.
+ */
+
+namespace Drupal\telephone\Plugin\Field\FieldWidget;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+use Drupal\Core\Field\WidgetBase;
+
+/**
+ * Plugin implementation of the 'telephone_default' widget.
+ *
+ * @FieldWidget(
+ *   id = "telephone_default",
+ *   label = @Translation("Telephone number"),
+ *   field_types = {
+ *     "telephone"
+ *   },
+ *   settings = {
+ *     "placeholder" = ""
+ *   }
+ * )
+ */
+class TelephoneDefaultWidget extends WidgetBase {
+
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    $element['placeholder'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Placeholder'),
+      '#default_value' => $this->getSetting('placeholder'),
+      '#description' => t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'),
+    );
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = array();
+
+    $placeholder = $this->getSetting('placeholder');
+    if (!empty($placeholder)) {
+      $summary[] = t('Placeholder: @placeholder', array('@placeholder' => $placeholder));
+    }
+    else {
+      $summary[] = t('No placeholder');
+    }
+
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
+    $element['value'] = $element + array(
+      '#type' => 'tel',
+      '#default_value' => isset($items[$delta]->value) ? $items[$delta]->value : NULL,
+      '#placeholder' => $this->getSetting('placeholder'),
+    );
+    return $element;
+  }
+
+}
diff --git a/core/modules/telephone/lib/Drupal/telephone/Plugin/field/formatter/TelephoneLinkFormatter.php b/core/modules/telephone/lib/Drupal/telephone/Plugin/field/formatter/TelephoneLinkFormatter.php
deleted file mode 100644
index dfbb3cd..0000000
--- a/core/modules/telephone/lib/Drupal/telephone/Plugin/field/formatter/TelephoneLinkFormatter.php
+++ /dev/null
@@ -1,81 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\telephone\Plugin\field\formatter\TelephoneLinkFormatter.
- */
-
-namespace Drupal\telephone\Plugin\field\formatter;
-
-use Drupal\field\Plugin\Type\Formatter\FormatterBase;
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-
-/**
- * Plugin implementation of the 'telephone_link' formatter.
- *
- * @FieldFormatter(
- *   id = "telephone_link",
- *   label = @Translation("Telephone link"),
- *   field_types = {
- *     "telephone"
- *   },
- *   settings = {
- *     "title" = ""
- *   }
- * )
- */
-class TelephoneLinkFormatter extends FormatterBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsForm(array $form, array &$form_state) {
-    $elements['title'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Title to replace basic numeric telephone number display.'),
-      '#default_value' => $this->getSetting('title'),
-    );
-
-    return $elements;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    $summary = array();
-    $settings = $this->getSettings();
-
-    if (!empty($settings['title'])) {
-      $summary[] = t('Link using text: @title', array('@title' => $settings['title']));
-    }
-    else {
-      $summary[] = t('Link using provided telephone number.');
-    }
-
-    return $summary;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function viewElements(FieldItemListInterface $items) {
-    $element = array();
-    $title_setting = $this->getSetting('title');
-
-    foreach ($items as $delta => $item) {
-      // Render each element as link.
-      $element[$delta] = array(
-        '#type' => 'link',
-        // Use custom title if available, otherwise use the telephone number
-        // itself as title.
-        '#title' => $title_setting ?: $item->value,
-        // Prepend 'tel:' to the telephone number.
-        '#href' => 'tel:' . rawurlencode(preg_replace('/\s+/', '', $item->value)),
-        '#options' => array('external' => TRUE),
-      );
-    }
-
-    return $element;
-  }
-}
diff --git a/core/modules/telephone/lib/Drupal/telephone/Plugin/field/widget/TelephoneDefaultWidget.php b/core/modules/telephone/lib/Drupal/telephone/Plugin/field/widget/TelephoneDefaultWidget.php
deleted file mode 100644
index a5294d4..0000000
--- a/core/modules/telephone/lib/Drupal/telephone/Plugin/field/widget/TelephoneDefaultWidget.php
+++ /dev/null
@@ -1,72 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\telephone\Plugin\field\widget\TelephoneDefaultWidget.
- */
-
-namespace Drupal\telephone\Plugin\field\widget;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\field\Plugin\Type\Widget\WidgetBase;
-
-/**
- * Plugin implementation of the 'telephone_default' widget.
- *
- * @FieldWidget(
- *   id = "telephone_default",
- *   label = @Translation("Telephone number"),
- *   field_types = {
- *     "telephone"
- *   },
- *   settings = {
- *     "placeholder" = ""
- *   }
- * )
- */
-class TelephoneDefaultWidget extends WidgetBase {
-
-
-  /**
-   * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::settingsForm().
-   */
-  public function settingsForm(array $form, array &$form_state) {
-    $element['placeholder'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Placeholder'),
-      '#default_value' => $this->getSetting('placeholder'),
-      '#description' => t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'),
-    );
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    $summary = array();
-
-    $placeholder = $this->getSetting('placeholder');
-    if (!empty($placeholder)) {
-      $summary[] = t('Placeholder: @placeholder', array('@placeholder' => $placeholder));
-    }
-    else {
-      $summary[] = t('No placeholder');
-    }
-
-    return $summary;
-  }
-
-  /**
-   * Implements \Drupal\field\Plugin\Type\Widget\WidgetInterface::formElement().
-   */
-  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
-    $element['value'] = $element + array(
-      '#type' => 'tel',
-      '#default_value' => isset($items[$delta]->value) ? $items[$delta]->value : NULL,
-      '#placeholder' => $this->getSetting('placeholder'),
-    );
-    return $element;
-  }
-
-}
diff --git a/core/modules/text/lib/Drupal/text/Plugin/Field/FieldFormatter/TextDefaultFormatter.php b/core/modules/text/lib/Drupal/text/Plugin/Field/FieldFormatter/TextDefaultFormatter.php
new file mode 100644
index 0000000..dc81b57
--- /dev/null
+++ b/core/modules/text/lib/Drupal/text/Plugin/Field/FieldFormatter/TextDefaultFormatter.php
@@ -0,0 +1,44 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\text\Plugin\field\formatter\TextDefaultFormatter.
+ */
+
+namespace Drupal\text\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Field\FormatterBase;
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+
+/**
+ * Plugin implementation of the 'text_default' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "text_default",
+ *   label = @Translation("Default"),
+ *   field_types = {
+ *     "text",
+ *     "text_long",
+ *     "text_with_summary"
+ *   },
+ *   edit = {
+ *     "editor" = "direct"
+ *   }
+ * )
+ */
+class TextDefaultFormatter extends FormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+    $elements = array();
+
+    foreach ($items as $delta => $item) {
+      $elements[$delta] = array('#markup' => $item->processed);
+    }
+
+    return $elements;
+  }
+
+}
diff --git a/core/modules/text/lib/Drupal/text/Plugin/Field/FieldFormatter/TextPlainFormatter.php b/core/modules/text/lib/Drupal/text/Plugin/Field/FieldFormatter/TextPlainFormatter.php
new file mode 100644
index 0000000..2616748
--- /dev/null
+++ b/core/modules/text/lib/Drupal/text/Plugin/Field/FieldFormatter/TextPlainFormatter.php
@@ -0,0 +1,46 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\text\Plugin\field\formatter\TextPlainFormatter.
+ */
+
+namespace Drupal\text\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Field\FormatterBase;
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+
+/**
+ * Plugin implementation of the 'text_plain' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "text_plain",
+ *   label = @Translation("Plain text"),
+ *   field_types = {
+ *     "text",
+ *     "text_long",
+ *     "text_with_summary"
+ *   },
+ *   edit = {
+ *     "editor" = "direct"
+ *   }
+ * )
+ */
+class TextPlainFormatter extends FormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+    $elements = array();
+
+    foreach ($items as $delta => $item) {
+      // The text value has no text format assigned to it, so the user input
+      // should equal the output, including newlines.
+      $elements[$delta] = array('#markup' => nl2br(check_plain($item->value)));
+    }
+
+    return $elements;
+  }
+
+}
diff --git a/core/modules/text/lib/Drupal/text/Plugin/Field/FieldFormatter/TextSummaryOrTrimmedFormatter.php b/core/modules/text/lib/Drupal/text/Plugin/Field/FieldFormatter/TextSummaryOrTrimmedFormatter.php
new file mode 100644
index 0000000..baebdc1
--- /dev/null
+++ b/core/modules/text/lib/Drupal/text/Plugin/Field/FieldFormatter/TextSummaryOrTrimmedFormatter.php
@@ -0,0 +1,27 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\text\Plugin\field\formatter\TextSummaryOrTrimmedFormatter.
+ */
+
+namespace Drupal\text\Plugin\Field\FieldFormatter;
+
+/**
+ * Plugin implementation of the 'text_summary_or_trimmed' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "text_summary_or_trimmed",
+ *   label = @Translation("Summary or trimmed"),
+ *   field_types = {
+ *     "text_with_summary"
+ *   },
+ *   settings = {
+ *     "trim_length" = "600"
+ *   },
+ *   edit = {
+ *     "editor" = "form"
+ *   }
+ * )
+ */
+class TextSummaryOrTrimmedFormatter extends TextTrimmedFormatter { }
diff --git a/core/modules/text/lib/Drupal/text/Plugin/Field/FieldFormatter/TextTrimmedFormatter.php b/core/modules/text/lib/Drupal/text/Plugin/Field/FieldFormatter/TextTrimmedFormatter.php
new file mode 100644
index 0000000..d8bd37b
--- /dev/null
+++ b/core/modules/text/lib/Drupal/text/Plugin/Field/FieldFormatter/TextTrimmedFormatter.php
@@ -0,0 +1,82 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\text\Plugin\field\formatter\TextTrimmedFormatter.
+ */
+namespace Drupal\text\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Field\FormatterBase;
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+
+/**
+ * Plugin implementation of the 'text_trimmed'' formatter.
+ *
+ * Note: This class also contains the implementations used by the
+ * 'text_summary_or_trimmed' formatter.
+ *
+ * @see \Drupal\text\Field\Formatter\TextSummaryOrTrimmedFormatter
+ *
+ * @FieldFormatter(
+ *   id = "text_trimmed",
+ *   label = @Translation("Trimmed"),
+ *   field_types = {
+ *     "text",
+ *     "text_long",
+ *     "text_with_summary"
+ *   },
+ *   settings = {
+ *     "trim_length" = "600"
+ *   },
+ *   edit = {
+ *     "editor" = "form"
+ *   }
+ * )
+ */
+class TextTrimmedFormatter extends FormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    $element['trim_length'] = array(
+      '#title' => t('Trim length'),
+      '#type' => 'number',
+      '#default_value' => $this->getSetting('trim_length'),
+      '#min' => 1,
+      '#required' => TRUE,
+    );
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = array();
+    $summary[] = t('Trim length: @trim_length', array('@trim_length' => $this->getSetting('trim_length')));
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items) {
+    $elements = array();
+
+    $text_processing = $this->getFieldSetting('text_processing');
+    foreach ($items as $delta => $item) {
+      if ($this->getPluginId() == 'text_summary_or_trimmed' && !empty($item->summary)) {
+        $output = $item->summary_processed;
+      }
+      else {
+        $output = $item->processed;
+        $output = text_summary($output, $text_processing ? $item->format : NULL, $this->getSetting('trim_length'));
+      }
+      $elements[$delta] = array('#markup' => $output);
+    }
+
+    return $elements;
+  }
+
+}
diff --git a/core/modules/text/lib/Drupal/text/Plugin/Field/FieldWidget/TextareaWidget.php b/core/modules/text/lib/Drupal/text/Plugin/Field/FieldWidget/TextareaWidget.php
new file mode 100644
index 0000000..7383005
--- /dev/null
+++ b/core/modules/text/lib/Drupal/text/Plugin/Field/FieldWidget/TextareaWidget.php
@@ -0,0 +1,103 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\text\Plugin\Field\FieldWidget\TextareaWidget.
+ */
+
+namespace Drupal\text\Plugin\Field\FieldWidget;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+use Drupal\Core\Field\WidgetBase;
+use Symfony\Component\Validator\ConstraintViolationInterface;
+
+/**
+ * Plugin implementation of the 'text_textarea' widget.
+ *
+ * @FieldWidget(
+ *   id = "text_textarea",
+ *   label = @Translation("Text area (multiple rows)"),
+ *   field_types = {
+ *     "text_long"
+ *   },
+ *   settings = {
+ *     "rows" = "5",
+ *     "placeholder" = ""
+ *   }
+ * )
+ */
+class TextareaWidget extends WidgetBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    $element['rows'] = array(
+      '#type' => 'number',
+      '#title' => t('Rows'),
+      '#default_value' => $this->getSetting('rows'),
+      '#required' => TRUE,
+      '#min' => 1,
+    );
+    $element['placeholder'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Placeholder'),
+      '#default_value' => $this->getSetting('placeholder'),
+      '#description' => t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'),
+    );
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = array();
+
+    $summary[] = t('Number of rows: !rows', array('!rows' => $this->getSetting('rows')));
+    $placeholder = $this->getSetting('placeholder');
+    if (!empty($placeholder)) {
+      $summary[] = t('Placeholder: @placeholder', array('@placeholder' => $placeholder));
+    }
+
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
+    $main_widget = $element + array(
+      '#type' => 'textarea',
+      '#default_value' => $items[$delta]->value,
+      '#rows' => $this->getSetting('rows'),
+      '#placeholder' => $this->getSetting('placeholder'),
+      '#attributes' => array('class' => array('text-full')),
+    );
+
+    if ($this->getFieldSetting('text_processing')) {
+      $element = $main_widget;
+      $element['#type'] = 'text_format';
+      $element['#format'] = $items[$delta]->format;
+      $element['#base_type'] = $main_widget['#type'];
+    }
+    else {
+      $element['value'] = $main_widget;
+    }
+
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function errorElement(array $element, ConstraintViolationInterface $violation, array $form, array &$form_state) {
+    if ($violation->arrayPropertyPath == array('format') && isset($element['format']['#access']) && !$element['format']['#access']) {
+      // Ignore validation errors for formats if formats may not be changed,
+      // i.e. when existing formats become invalid. See filter_process_format().
+      return FALSE;
+    }
+    return $element;
+  }
+
+}
diff --git a/core/modules/text/lib/Drupal/text/Plugin/Field/FieldWidget/TextareaWithSummaryWidget.php b/core/modules/text/lib/Drupal/text/Plugin/Field/FieldWidget/TextareaWithSummaryWidget.php
new file mode 100644
index 0000000..e5cbab4
--- /dev/null
+++ b/core/modules/text/lib/Drupal/text/Plugin/Field/FieldWidget/TextareaWithSummaryWidget.php
@@ -0,0 +1,91 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\text\Plugin\Field\FieldWidget\TextareaWithSummaryWidget.
+ */
+
+namespace Drupal\text\Plugin\Field\FieldWidget;
+
+use Drupal\text\Plugin\Field\FieldWidget\TextareaWidget;
+use Symfony\Component\Validator\ConstraintViolationInterface;
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+
+/**
+ * Plugin implementation of the 'text_textarea_with_summary' widget.
+ *
+ * @FieldWidget(
+ *   id = "text_textarea_with_summary",
+ *   label = @Translation("Text area with a summary"),
+ *   field_types = {
+ *     "text_with_summary"
+ *   },
+ *   settings = {
+ *     "rows" = "9",
+ *     "summary_rows" = "3",
+ *     "placeholder" = ""
+ *   }
+ * )
+ */
+class TextareaWithSummaryWidget extends TextareaWidget {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    $element = parent::settingsForm($form, $form_state);
+    $element['summary_rows'] = array(
+      '#type' => 'number',
+      '#title' => t('Summary rows'),
+      '#default_value' => $this->getSetting('summary_rows'),
+      '#required' => TRUE,
+      '#min' => 1,
+    );
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = parent::settingsSummary();
+
+    $summary[] = t('Number of summary rows: !rows', array('!rows' => $this->getSetting('summary_rows')));
+
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
+    $element = parent::formElement($items, $delta, $element, $form, $form_state);
+
+    $display_summary = $items[$delta]->summary || $this->getFieldSetting('display_summary');
+    $element['summary'] = array(
+      '#type' => $display_summary ? 'textarea' : 'value',
+      '#default_value' => $items[$delta]->summary,
+      '#title' => t('Summary'),
+      '#rows' => $this->getSetting('summary_rows'),
+      '#description' => t('Leave blank to use trimmed value of full text as the summary.'),
+      '#attached' => array(
+        'library' => array(array('text', 'drupal.text')),
+      ),
+      '#attributes' => array('class' => array('text-summary')),
+      '#prefix' => '<div class="text-summary-wrapper">',
+      '#suffix' => '</div>',
+      '#weight' => -10,
+    );
+
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function errorElement(array $element, ConstraintViolationInterface $violation, array $form, array &$form_state) {
+    $element = parent::errorElement($element, $violation, $form, $form_state);
+    return ($element === FALSE) ? FALSE : $element[$violation->arrayPropertyPath[0]];
+  }
+
+}
diff --git a/core/modules/text/lib/Drupal/text/Plugin/Field/FieldWidget/TextfieldWidget.php b/core/modules/text/lib/Drupal/text/Plugin/Field/FieldWidget/TextfieldWidget.php
new file mode 100644
index 0000000..ddbc516
--- /dev/null
+++ b/core/modules/text/lib/Drupal/text/Plugin/Field/FieldWidget/TextfieldWidget.php
@@ -0,0 +1,104 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\text\Plugin\Field\FieldWidget\TextfieldWidget.
+ */
+
+namespace Drupal\text\Plugin\Field\FieldWidget;
+
+use Drupal\Core\Entity\Field\FieldItemListInterface;
+use Drupal\Core\Field\WidgetBase;
+use Symfony\Component\Validator\ConstraintViolationInterface;
+
+/**
+ * Plugin implementation of the 'text_textfield' widget.
+ *
+ * @FieldWidget(
+ *   id = "text_textfield",
+ *   label = @Translation("Text field"),
+ *   field_types = {
+ *     "text"
+ *   },
+ *   settings = {
+ *     "size" = "60",
+ *     "placeholder" = ""
+ *   }
+ * )
+ */
+class TextfieldWidget extends WidgetBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    $element['size'] = array(
+      '#type' => 'number',
+      '#title' => t('Size of textfield'),
+      '#default_value' => $this->getSetting('size'),
+      '#required' => TRUE,
+      '#min' => 1,
+    );
+    $element['placeholder'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Placeholder'),
+      '#default_value' => $this->getSetting('placeholder'),
+      '#description' => t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'),
+    );
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = array();
+
+    $summary[] = t('Textfield size: !size', array('!size' => $this->getSetting('size')));
+    $placeholder = $this->getSetting('placeholder');
+    if (!empty($placeholder)) {
+      $summary[] = t('Placeholder: @placeholder', array('@placeholder' => $placeholder));
+    }
+
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
+    $main_widget = $element + array(
+      '#type' => 'textfield',
+      '#default_value' => isset($items[$delta]->value) ? $items[$delta]->value : NULL,
+      '#size' => $this->getSetting('size'),
+      '#placeholder' => $this->getSetting('placeholder'),
+      '#maxlength' => $this->getFieldSetting('max_length'),
+      '#attributes' => array('class' => array('text-full')),
+    );
+
+    if ($this->getFieldSetting('text_processing')) {
+      $element = $main_widget;
+      $element['#type'] = 'text_format';
+      $element['#format'] = isset($items[$delta]->format) ? $items[$delta]->format : NULL;
+      $element['#base_type'] = $main_widget['#type'];
+    }
+    else {
+      $element['value'] = $main_widget;
+    }
+
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function errorElement(array $element, ConstraintViolationInterface $violation, array $form, array &$form_state) {
+    if ($violation->arrayPropertyPath == array('format') && isset($element['format']['#access']) && !$element['format']['#access']) {
+      // Ignore validation errors for formats if formats may not be changed,
+      // i.e. when existing formats become invalid. See filter_process_format().
+      return FALSE;
+    }
+    return $element;
+  }
+
+}
diff --git a/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextDefaultFormatter.php b/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextDefaultFormatter.php
deleted file mode 100644
index 62005b7..0000000
--- a/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextDefaultFormatter.php
+++ /dev/null
@@ -1,44 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\text\Plugin\field\formatter\TextDefaultFormatter.
- */
-
-namespace Drupal\text\Plugin\field\formatter;
-
-use Drupal\field\Plugin\Type\Formatter\FormatterBase;
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-
-/**
- * Plugin implementation of the 'text_default' formatter.
- *
- * @FieldFormatter(
- *   id = "text_default",
- *   label = @Translation("Default"),
- *   field_types = {
- *     "text",
- *     "text_long",
- *     "text_with_summary"
- *   },
- *   edit = {
- *     "editor" = "direct"
- *   }
- * )
- */
-class TextDefaultFormatter extends FormatterBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function viewElements(FieldItemListInterface $items) {
-    $elements = array();
-
-    foreach ($items as $delta => $item) {
-      $elements[$delta] = array('#markup' => $item->processed);
-    }
-
-    return $elements;
-  }
-
-}
diff --git a/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextPlainFormatter.php b/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextPlainFormatter.php
deleted file mode 100644
index 0635472..0000000
--- a/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextPlainFormatter.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\text\Plugin\field\formatter\TextPlainFormatter.
- */
-
-namespace Drupal\text\Plugin\field\formatter;
-
-use Drupal\field\Plugin\Type\Formatter\FormatterBase;
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-
-/**
- * Plugin implementation of the 'text_plain' formatter.
- *
- * @FieldFormatter(
- *   id = "text_plain",
- *   label = @Translation("Plain text"),
- *   field_types = {
- *     "text",
- *     "text_long",
- *     "text_with_summary"
- *   },
- *   edit = {
- *     "editor" = "direct"
- *   }
- * )
- */
-class TextPlainFormatter extends FormatterBase {
-
-  /**
-   * Implements Drupal\field\Plugin\Type\Formatter\FormatterInterface::viewElements().
-   */
-  public function viewElements(FieldItemListInterface $items) {
-    $elements = array();
-
-    foreach ($items as $delta => $item) {
-      // The text value has no text format assigned to it, so the user input
-      // should equal the output, including newlines.
-      $elements[$delta] = array('#markup' => nl2br(check_plain($item->value)));
-    }
-
-    return $elements;
-  }
-
-}
diff --git a/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextSummaryOrTrimmedFormatter.php b/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextSummaryOrTrimmedFormatter.php
deleted file mode 100644
index 18197a8..0000000
--- a/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextSummaryOrTrimmedFormatter.php
+++ /dev/null
@@ -1,27 +0,0 @@
-<?php
-
-/**
- * @file
- *
- * Definition of Drupal\text\Plugin\field\formatter\TextSummaryOrTrimmedFormatter.
- */
-namespace Drupal\text\Plugin\field\formatter;
-
-/**
- * Plugin implementation of the 'text_summary_or_trimmed' formatter.
- *
- * @FieldFormatter(
- *   id = "text_summary_or_trimmed",
- *   label = @Translation("Summary or trimmed"),
- *   field_types = {
- *     "text_with_summary"
- *   },
- *   settings = {
- *     "trim_length" = "600"
- *   },
- *   edit = {
- *     "editor" = "form"
- *   }
- * )
- */
-class TextSummaryOrTrimmedFormatter extends TextTrimmedFormatter { }
diff --git a/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextTrimmedFormatter.php b/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextTrimmedFormatter.php
deleted file mode 100644
index 0597dda..0000000
--- a/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextTrimmedFormatter.php
+++ /dev/null
@@ -1,83 +0,0 @@
-<?php
-
-/**
- * @file
- *
- * Contains \Drupal\text\Plugin\field\formatter\TextTrimmedFormatter.
- */
-namespace Drupal\text\Plugin\field\formatter;
-
-use Drupal\field\Plugin\Type\Formatter\FormatterBase;
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-
-/**
- * Plugin implementation of the 'text_trimmed'' formatter.
- *
- * Note: This class also contains the implementations used by the
- * 'text_summary_or_trimmed' formatter.
- *
- * @see \Drupal\text\Field\Formatter\TextSummaryOrTrimmedFormatter
- *
- * @FieldFormatter(
- *   id = "text_trimmed",
- *   label = @Translation("Trimmed"),
- *   field_types = {
- *     "text",
- *     "text_long",
- *     "text_with_summary"
- *   },
- *   settings = {
- *     "trim_length" = "600"
- *   },
- *   edit = {
- *     "editor" = "form"
- *   }
- * )
- */
-class TextTrimmedFormatter extends FormatterBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsForm(array $form, array &$form_state) {
-    $element['trim_length'] = array(
-      '#title' => t('Trim length'),
-      '#type' => 'number',
-      '#default_value' => $this->getSetting('trim_length'),
-      '#min' => 1,
-      '#required' => TRUE,
-    );
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    $summary = array();
-    $summary[] = t('Trim length: @trim_length', array('@trim_length' => $this->getSetting('trim_length')));
-    return $summary;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function viewElements(FieldItemListInterface $items) {
-    $elements = array();
-
-    $text_processing = $this->getFieldSetting('text_processing');
-    foreach ($items as $delta => $item) {
-      if ($this->getPluginId() == 'text_summary_or_trimmed' && !empty($item->summary)) {
-        $output = $item->summary_processed;
-      }
-      else {
-        $output = $item->processed;
-        $output = text_summary($output, $text_processing ? $item->format : NULL, $this->getSetting('trim_length'));
-      }
-      $elements[$delta] = array('#markup' => $output);
-    }
-
-    return $elements;
-  }
-
-}
diff --git a/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextareaWidget.php b/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextareaWidget.php
deleted file mode 100644
index b4e9f7f..0000000
--- a/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextareaWidget.php
+++ /dev/null
@@ -1,103 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\text\Plugin\field\widget\TextareaWidget.
- */
-
-namespace Drupal\text\Plugin\field\widget;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\field\Plugin\Type\Widget\WidgetBase;
-use Symfony\Component\Validator\ConstraintViolationInterface;
-
-/**
- * Plugin implementation of the 'text_textarea' widget.
- *
- * @FieldWidget(
- *   id = "text_textarea",
- *   label = @Translation("Text area (multiple rows)"),
- *   field_types = {
- *     "text_long"
- *   },
- *   settings = {
- *     "rows" = "5",
- *     "placeholder" = ""
- *   }
- * )
- */
-class TextareaWidget extends WidgetBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsForm(array $form, array &$form_state) {
-    $element['rows'] = array(
-      '#type' => 'number',
-      '#title' => t('Rows'),
-      '#default_value' => $this->getSetting('rows'),
-      '#required' => TRUE,
-      '#min' => 1,
-    );
-    $element['placeholder'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Placeholder'),
-      '#default_value' => $this->getSetting('placeholder'),
-      '#description' => t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'),
-    );
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    $summary = array();
-
-    $summary[] = t('Number of rows: !rows', array('!rows' => $this->getSetting('rows')));
-    $placeholder = $this->getSetting('placeholder');
-    if (!empty($placeholder)) {
-      $summary[] = t('Placeholder: @placeholder', array('@placeholder' => $placeholder));
-    }
-
-    return $summary;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
-    $main_widget = $element + array(
-      '#type' => 'textarea',
-      '#default_value' => $items[$delta]->value,
-      '#rows' => $this->getSetting('rows'),
-      '#placeholder' => $this->getSetting('placeholder'),
-      '#attributes' => array('class' => array('text-full')),
-    );
-
-    if ($this->getFieldSetting('text_processing')) {
-      $element = $main_widget;
-      $element['#type'] = 'text_format';
-      $element['#format'] = $items[$delta]->format;
-      $element['#base_type'] = $main_widget['#type'];
-    }
-    else {
-      $element['value'] = $main_widget;
-    }
-
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function errorElement(array $element, ConstraintViolationInterface $violation, array $form, array &$form_state) {
-    if ($violation->arrayPropertyPath == array('format') && isset($element['format']['#access']) && !$element['format']['#access']) {
-      // Ignore validation errors for formats if formats may not be changed,
-      // i.e. when existing formats become invalid. See filter_process_format().
-      return FALSE;
-    }
-    return $element;
-  }
-
-}
diff --git a/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextareaWithSummaryWidget.php b/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextareaWithSummaryWidget.php
deleted file mode 100644
index b5745ca..0000000
--- a/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextareaWithSummaryWidget.php
+++ /dev/null
@@ -1,90 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\text\Plugin\field\widget\TextareaWithSummaryWidget.
- */
-
-namespace Drupal\text\Plugin\field\widget;
-
-use Symfony\Component\Validator\ConstraintViolationInterface;
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-
-/**
- * Plugin implementation of the 'text_textarea_with_summary' widget.
- *
- * @FieldWidget(
- *   id = "text_textarea_with_summary",
- *   label = @Translation("Text area with a summary"),
- *   field_types = {
- *     "text_with_summary"
- *   },
- *   settings = {
- *     "rows" = "9",
- *     "summary_rows" = "3",
- *     "placeholder" = ""
- *   }
- * )
- */
-class TextareaWithSummaryWidget extends TextareaWidget {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsForm(array $form, array &$form_state) {
-    $element = parent::settingsForm($form, $form_state);
-    $element['summary_rows'] = array(
-      '#type' => 'number',
-      '#title' => t('Summary rows'),
-      '#default_value' => $this->getSetting('summary_rows'),
-      '#required' => TRUE,
-      '#min' => 1,
-    );
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    $summary = parent::settingsSummary();
-
-    $summary[] = t('Number of summary rows: !rows', array('!rows' => $this->getSetting('summary_rows')));
-
-    return $summary;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
-    $element = parent::formElement($items, $delta, $element, $form, $form_state);
-
-    $display_summary = $items[$delta]->summary || $this->getFieldSetting('display_summary');
-    $element['summary'] = array(
-      '#type' => $display_summary ? 'textarea' : 'value',
-      '#default_value' => $items[$delta]->summary,
-      '#title' => t('Summary'),
-      '#rows' => $this->getSetting('summary_rows'),
-      '#description' => t('Leave blank to use trimmed value of full text as the summary.'),
-      '#attached' => array(
-        'library' => array(array('text', 'drupal.text')),
-      ),
-      '#attributes' => array('class' => array('text-summary')),
-      '#prefix' => '<div class="text-summary-wrapper">',
-      '#suffix' => '</div>',
-      '#weight' => -10,
-    );
-
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function errorElement(array $element, ConstraintViolationInterface $violation, array $form, array &$form_state) {
-    $element = parent::errorElement($element, $violation, $form, $form_state);
-    return ($element === FALSE) ? FALSE : $element[$violation->arrayPropertyPath[0]];
-  }
-
-}
diff --git a/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextfieldWidget.php b/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextfieldWidget.php
deleted file mode 100644
index c01cbed..0000000
--- a/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextfieldWidget.php
+++ /dev/null
@@ -1,104 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\text\Plugin\field\widget\TextfieldWidget.
- */
-
-namespace Drupal\text\Plugin\field\widget;
-
-use Drupal\Core\Entity\Field\FieldItemListInterface;
-use Drupal\field\Plugin\Type\Widget\WidgetBase;
-use Symfony\Component\Validator\ConstraintViolationInterface;
-
-/**
- * Plugin implementation of the 'text_textfield' widget.
- *
- * @FieldWidget(
- *   id = "text_textfield",
- *   label = @Translation("Text field"),
- *   field_types = {
- *     "text"
- *   },
- *   settings = {
- *     "size" = "60",
- *     "placeholder" = ""
- *   }
- * )
- */
-class TextfieldWidget extends WidgetBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsForm(array $form, array &$form_state) {
-    $element['size'] = array(
-      '#type' => 'number',
-      '#title' => t('Size of textfield'),
-      '#default_value' => $this->getSetting('size'),
-      '#required' => TRUE,
-      '#min' => 1,
-    );
-    $element['placeholder'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Placeholder'),
-      '#default_value' => $this->getSetting('placeholder'),
-      '#description' => t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'),
-    );
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    $summary = array();
-
-    $summary[] = t('Textfield size: !size', array('!size' => $this->getSetting('size')));
-    $placeholder = $this->getSetting('placeholder');
-    if (!empty($placeholder)) {
-      $summary[] = t('Placeholder: @placeholder', array('@placeholder' => $placeholder));
-    }
-
-    return $summary;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
-    $main_widget = $element + array(
-      '#type' => 'textfield',
-      '#default_value' => isset($items[$delta]->value) ? $items[$delta]->value : NULL,
-      '#size' => $this->getSetting('size'),
-      '#placeholder' => $this->getSetting('placeholder'),
-      '#maxlength' => $this->getFieldSetting('max_length'),
-      '#attributes' => array('class' => array('text-full')),
-    );
-
-    if ($this->getFieldSetting('text_processing')) {
-      $element = $main_widget;
-      $element['#type'] = 'text_format';
-      $element['#format'] = isset($items[$delta]->format) ? $items[$delta]->format : NULL;
-      $element['#base_type'] = $main_widget['#type'];
-    }
-    else {
-      $element['value'] = $main_widget;
-    }
-
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function errorElement(array $element, ConstraintViolationInterface $violation, array $form, array &$form_state) {
-    if ($violation->arrayPropertyPath == array('format') && isset($element['format']['#access']) && !$element['format']['#access']) {
-      // Ignore validation errors for formats if formats may not be changed,
-      // i.e. when existing formats become invalid. See filter_process_format().
-      return FALSE;
-    }
-    return $element;
-  }
-
-}
diff --git a/core/themes/seven/dialog.theme.css b/core/themes/seven/dialog.theme.css
deleted file mode 100644
index c569785..0000000
--- a/core/themes/seven/dialog.theme.css
+++ /dev/null
@@ -1,83 +0,0 @@
-/**
- * Presentational styles for Drupal dialogs.
- */
-
-.ui-dialog {
-  background: transparent;
-  border: 0;
-  position: absolute;
-  z-index: 1260;
-  overflow: visible;
-  padding: 0;
-}
-.ui-dialog .ui-dialog-titlebar {
-  background: rgba(107,107,107,0.65);
-  border-top-left-radius: 5px;
-  border-top-right-radius: 5px;
-  padding: 20px;
-}
-.ui-dialog .ui-dialog-title {
-  font-size: 22px;
-  font-weight: 600;
-  margin: 0;
-  color: #ffffff;
-  -webkit-font-smoothing: antialiased;
-}
-.ui-dialog .ui-dialog-titlebar-close {
-  border: 0;
-  background: none;
-  right: 20px;
-  top: 20px;
-  margin: 0;
-  height: 16px;
-  width: 16px;
-}
-.ui-dialog .ui-icon-closethick {
-  background: url('../../misc/icons/ffffff/ex.svg') 0 0 no-repeat;
-}
-.ui-dialog .ui-dialog-content {
-  background: #ffffff;
-}
-.ui-dialog .ui-dialog-buttonpane {
-  background: #f5f5f2;
-  border-top: 1px solid #bfbfbf;
-  margin: 0;
-  padding: 15px 20px;
-  border-bottom-left-radius: 5px;
-  border-bottom-right-radius: 5px;
-}
-.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
-  margin: 0;
-  padding: 0;
-  float: none;
-}
-.ui-dialog .ui-dialog-buttonpane .ui-button-text-only .ui-button-text {
-  padding: 0;
-}
-
-/* Form action buttons are moved in dialogs. Remove empty space. */
-.ui-dialog .ui-dialog-content .form-actions {
-  padding: 0;
-  margin: 0;
-}
-.ui-dialog .ajax-progress-throbber {
-  /* Can't do center:50% middle: 50%, so approximate it for a typical window size. */
-  left: 49%;
-  position: fixed;
-  top: 48.5%;
-  z-index: 1000;
-  background-color: #232323;
-  background-image: url("loading-small.gif");
-  background-position: center center;
-  background-repeat: no-repeat;
-  border-radius: 7px;
-  height: 24px;
-  opacity: 0.9;
-  padding: 4px;
-  width: 24px;
-}
-.ui-dialog .ajax-progress-throbber .throbber,
-.ui-dialog .ajax-progress-throbber .message {
-  display: none;
-}
-
diff --git a/core/themes/seven/seven.info.yml b/core/themes/seven/seven.info.yml
index 36e51ba..62beff8 100644
--- a/core/themes/seven/seven.info.yml
+++ b/core/themes/seven/seven.info.yml
@@ -12,7 +12,6 @@ stylesheets:
 stylesheets-override:
   - vertical-tabs.css
   - jquery.ui.theme.css
-  - dialog.theme.css
 edit_stylesheets:
   - edit.css
 settings:
diff --git a/core/themes/seven/seven.theme b/core/themes/seven/seven.theme
index 50f2442..3ab8d22 100644
--- a/core/themes/seven/seven.theme
+++ b/core/themes/seven/seven.theme
@@ -161,7 +161,7 @@ function seven_menu_local_action($variables) {
   // See http://drupal.org/node/1849712
   $link['localized_options']['attributes']['class'][] = 'button-action';
 
-  // We require Modernizr for button styling.
+    // We require Modernizr for button styling.
   $libraries = array(
     '#attached' => array(
       'library' => array(
