diff --git a/core/lib/Drupal/Core/Entity/Annotation/FieldType.php b/core/lib/Drupal/Core/Entity/Annotation/FieldType.php
index 1de71b5..6934677 100644
--- a/core/lib/Drupal/Core/Entity/Annotation/FieldType.php
+++ b/core/lib/Drupal/Core/Entity/Annotation/FieldType.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\Core\Entity\Annotation;
 
-use Drupal\Component\Annotation\Plugin;
+use Drupal\Core\TypedData\Annotation\DataType;
 
 /**
  * Defines a FieldType annotation object.
@@ -17,7 +17,7 @@
  *
  * @Annotation
  */
-class FieldType extends Plugin {
+class FieldType extends DataType {
 
   /**
    * The plugin ID.
@@ -103,8 +103,6 @@ class FieldType extends Plugin {
   /**
    * A boolean stating that fields of this type are configurable.
    *
-   * @todo: Make field module respect this.
-   *
    * @var boolean
    */
   public $configurable = TRUE;
@@ -112,10 +110,16 @@ class FieldType extends Plugin {
   /**
    * A boolean stating that fields of this type cannot be created through the UI.
    *
-   * If TRUE, fields of this type can only be created programmatically.
+   * If TRUE or the field type is not configurable, fields of this type can only
+   * be created programmatically.
    *
    * @var boolean
    */
   public $no_ui = FALSE;
 
+  /**
+   * {@inheritdoc}
+   */
+  public $list_class;
+
 }
diff --git a/core/lib/Drupal/Core/Entity/Entity.php b/core/lib/Drupal/Core/Entity/Entity.php
index 34aa09d..23701f4 100644
--- a/core/lib/Drupal/Core/Entity/Entity.php
+++ b/core/lib/Drupal/Core/Entity/Entity.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\Core\Entity;
 
-use Drupal\Core\Entity\Plugin\DataType\EntityReferenceItem;
 use Drupal\Core\Language\Language;
 use Drupal\Core\Session\AccountInterface;
 
diff --git a/core/lib/Drupal/Core/Entity/EntityManager.php b/core/lib/Drupal/Core/Entity/EntityManager.php
index e9808d2..a334582 100644
--- a/core/lib/Drupal/Core/Entity/EntityManager.php
+++ b/core/lib/Drupal/Core/Entity/EntityManager.php
@@ -478,8 +478,16 @@ public function getFieldDefinitions($entity_type, $bundle = NULL) {
       }
       else {
         $class = $this->factory->getPluginClass($entity_type, $this->getDefinition($entity_type));
+
+        $base_definitions = $class::baseFieldDefinitions($entity_type);
+        foreach ($base_definitions as &$base_definition) {
+          // Support old-style field types to avoid that all base field
+          // definitions need to be changed.
+          // @todo: Remove after https://drupal.org/node/2047229.
+          $base_definition['type'] = preg_replace('/(.+)_field/', 'field_item:$1', $base_definition['type']);
+        }
         $this->entityFieldInfo[$entity_type] = array(
-          'definitions' => $class::baseFieldDefinitions($entity_type),
+          'definitions' => $base_definitions,
           // Contains definitions of optional (per-bundle) fields.
           'optional' => array(),
           // An array keyed by bundle name containing the optional fields added
diff --git a/core/lib/Drupal/Core/Entity/Field/FieldTypePluginManager.php b/core/lib/Drupal/Core/Entity/Field/FieldTypePluginManager.php
index ad29168..df1f19d 100644
--- a/core/lib/Drupal/Core/Entity/Field/FieldTypePluginManager.php
+++ b/core/lib/Drupal/Core/Entity/Field/FieldTypePluginManager.php
@@ -8,6 +8,7 @@
 
 namespace Drupal\Core\Entity\Field;
 
+use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Language\LanguageManager;
@@ -25,7 +26,6 @@ class FieldTypePluginManager extends DefaultPluginManager {
   protected $defaults = array(
     'settings' => array(),
     'instance_settings' => array(),
-    'list_class' => '\Drupal\field\Plugin\Type\FieldType\ConfigFieldItemList',
   );
 
   /**
@@ -52,6 +52,21 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac
   }
 
   /**
+   * {@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
@@ -81,4 +96,24 @@ public function getDefaultInstanceSettings($type) {
     return isset($info['instance_settings']) ? $info['instance_settings'] : array();
   }
 
+  /**
+   * Gets the definition of all field types.
+   *
+   * @param bool $configurable
+   *   (optional) Whether to return only configurable field types. Defaults to
+   *   FALSE.
+   *
+   * @return array
+   *   An array of field type definitions.
+   */
+  public function getDefinitions($configurable = FALSE) {
+    $definitions = parent::getDefinitions();
+    if ($configurable) {
+      return array_filter($this->definitions, function ($definition) {
+        return $definition['configurable'];
+      });
+    }
+    return $definitions;
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Entity/Plugin/DataType/EmailItem.php b/core/lib/Drupal/Core/Entity/Plugin/DataType/EmailItem.php
deleted file mode 100644
index 6d1dba6..0000000
--- a/core/lib/Drupal/Core/Entity/Plugin/DataType/EmailItem.php
+++ /dev/null
@@ -1,57 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Entity\Plugin\DataType\EmailItem.
- */
-
-namespace Drupal\Core\Entity\Plugin\DataType;
-
-use Drupal\Core\TypedData\Annotation\DataType;
-use Drupal\Core\Annotation\Translation;
-use Drupal\Core\Entity\Field\FieldItemBase;
-use Drupal\field\Plugin\field\field_type\LegacyConfigFieldItem;
-
-/**
- * Defines the 'email_field' entity field item.
- *
- * @DataType(
- *   id = "email_field",
- *   label = @Translation("E-mail field item"),
- *   description = @Translation("An entity field containing an e-mail value."),
- *   list_class = "\Drupal\Core\Entity\Field\FieldItemList"
- * )
- */
-class EmailItem extends LegacyConfigFieldItem {
-
-  /**
-   * Definitions of the contained properties.
-   *
-   * @see EmailItem::getPropertyDefinitions()
-   *
-   * @var array
-   */
-  static $propertyDefinitions;
-
-  /**
-   * Implements ComplexDataInterface::getPropertyDefinitions().
-   */
-  public function getPropertyDefinitions() {
-
-    if (!isset(static::$propertyDefinitions)) {
-      static::$propertyDefinitions['value'] = array(
-        'type' => 'email',
-        'label' => t('E-mail value'),
-      );
-    }
-    return static::$propertyDefinitions;
-  }
-
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isEmpty() {
-    return $this->value === NULL || $this->value === '';
-  }
-}
diff --git a/core/lib/Drupal/Core/Entity/Plugin/DataType/BooleanItem.php b/core/lib/Drupal/Core/Entity/Plugin/field/field_type/BooleanItem.php
similarity index 65%
rename from core/lib/Drupal/Core/Entity/Plugin/DataType/BooleanItem.php
rename to core/lib/Drupal/Core/Entity/Plugin/field/field_type/BooleanItem.php
index 31e3ec8..b0d9427 100644
--- a/core/lib/Drupal/Core/Entity/Plugin/DataType/BooleanItem.php
+++ b/core/lib/Drupal/Core/Entity/Plugin/field/field_type/BooleanItem.php
@@ -2,23 +2,21 @@
 
 /**
  * @file
- * Contains \Drupal\Core\Entity\Plugin\DataType\BooleanItem.
+ * Contains \Drupal\Core\Entity\Plugin\field\field_type\BooleanItem.
  */
 
-namespace Drupal\Core\Entity\Plugin\DataType;
+namespace Drupal\Core\Entity\Plugin\field\field_type;
 
-use Drupal\Core\TypedData\Annotation\DataType;
-use Drupal\Core\Annotation\Translation;
 use Drupal\Core\Entity\Field\FieldItemBase;
 
 /**
- * Defines the 'boolean_field' entity field item.
+ * Defines the 'boolean' entity field type.
  *
- * @DataType(
- *   id = "boolean_field",
- *   label = @Translation("Boolean field item"),
+ * @FieldType(
+ *   id = "boolean",
+ *   label = @Translation("Boolean"),
  *   description = @Translation("An entity field containing a boolean value."),
- *   list_class = "\Drupal\Core\Entity\Field\FieldItemList"
+ *   configurable = FALSE
  * )
  */
 class BooleanItem extends FieldItemBase {
diff --git a/core/lib/Drupal/Core/Entity/Plugin/DataType/DateItem.php b/core/lib/Drupal/Core/Entity/Plugin/field/field_type/DateItem.php
similarity index 65%
rename from core/lib/Drupal/Core/Entity/Plugin/DataType/DateItem.php
rename to core/lib/Drupal/Core/Entity/Plugin/field/field_type/DateItem.php
index e6f462f..96a0791 100644
--- a/core/lib/Drupal/Core/Entity/Plugin/DataType/DateItem.php
+++ b/core/lib/Drupal/Core/Entity/Plugin/field/field_type/DateItem.php
@@ -2,23 +2,21 @@
 
 /**
  * @file
- * Contains \Drupal\Core\Entity\Plugin\DataType\DateItem.
+ * Contains \Drupal\Core\Entity\Plugin\field\field_type\DateItem.
  */
 
-namespace Drupal\Core\Entity\Plugin\DataType;
+namespace Drupal\Core\Entity\Plugin\field\field_type;
 
-use Drupal\Core\TypedData\Annotation\DataType;
-use Drupal\Core\Annotation\Translation;
 use Drupal\Core\Entity\Field\FieldItemBase;
 
 /**
- * Defines the 'date_field' entity field item.
+ * Defines the 'date' entity field type.
  *
- * @DataType(
- *   id = "date_field",
- *   label = @Translation("Date field item"),
+ * @FieldType(
+ *   id = "date",
+ *   label = @Translation("Date"),
  *   description = @Translation("An entity field containing a date value."),
- *   list_class = "\Drupal\Core\Entity\Field\FieldItemList"
+ *   configurable = FALSE
  * )
  */
 class DateItem extends FieldItemBase {
diff --git a/core/modules/email/lib/Drupal/email/Plugin/field/field_type/ConfigurableEmailItem.php b/core/lib/Drupal/Core/Entity/Plugin/field/field_type/EmailItem.php
similarity index 61%
rename from core/modules/email/lib/Drupal/email/Plugin/field/field_type/ConfigurableEmailItem.php
rename to core/lib/Drupal/Core/Entity/Plugin/field/field_type/EmailItem.php
index b346c4b..e1b70b6 100644
--- a/core/modules/email/lib/Drupal/email/Plugin/field/field_type/ConfigurableEmailItem.php
+++ b/core/lib/Drupal/Core/Entity/Plugin/field/field_type/EmailItem.php
@@ -2,28 +2,55 @@
 
 /**
  * @file
- * Contains \Drupal\email\Plugin\field\field_type\ConfigurableEmailItem.
+ * Contains \Drupal\Core\Entity\Plugin\field\field_type\EmailItem.
  */
 
-namespace Drupal\email\Plugin\field\field_type;
+namespace Drupal\Core\Entity\Plugin\field\field_type;
 
-use Drupal\Core\Entity\Annotation\FieldType;
-use Drupal\Core\Annotation\Translation;
-use Drupal\Core\Entity\Plugin\DataType\EmailItem;
 use Drupal\field\FieldInterface;
+use Drupal\field\Plugin\Type\FieldType\ConfigFieldItemBase;
 
 /**
- * Plugin implementation of the 'email' field type.
+ * Defines the 'email' entity field type.
  *
  * @FieldType(
  *   id = "email",
  *   label = @Translation("E-mail"),
- *   description = @Translation("This field stores an e-mail address in the database."),
- *   default_widget = "email_default",
- *   default_formatter = "email_mailto"
+ *   description = @Translation("An entity field containing an e-mail value.")
  * )
  */
-class ConfigurableEmailItem extends EmailItem {
+class EmailItem extends ConfigFieldItemBase {
+
+  /**
+   * Definitions of the contained properties.
+   *
+   * @see EmailItem::getPropertyDefinitions()
+   *
+   * @var array
+   */
+  static $propertyDefinitions;
+
+  /**
+   * Implements ComplexDataInterface::getPropertyDefinitions().
+   */
+  public function getPropertyDefinitions() {
+
+    if (!isset(static::$propertyDefinitions)) {
+      static::$propertyDefinitions['value'] = array(
+        'type' => 'email',
+        'label' => t('E-mail value'),
+      );
+    }
+    return static::$propertyDefinitions;
+  }
+
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isEmpty() {
+    return $this->value === NULL || $this->value === '';
+  }
 
   /**
    * Defines the max length for an email address
diff --git a/core/lib/Drupal/Core/Entity/Plugin/DataType/EntityReferenceItem.php b/core/lib/Drupal/Core/Entity/Plugin/field/field_type/EntityReferenceItem.php
similarity index 92%
rename from core/lib/Drupal/Core/Entity/Plugin/DataType/EntityReferenceItem.php
rename to core/lib/Drupal/Core/Entity/Plugin/field/field_type/EntityReferenceItem.php
index 5654747..5e37050 100644
--- a/core/lib/Drupal/Core/Entity/Plugin/DataType/EntityReferenceItem.php
+++ b/core/lib/Drupal/Core/Entity/Plugin/field/field_type/EntityReferenceItem.php
@@ -2,10 +2,10 @@
 
 /**
  * @file
- * Contains \Drupal\Core\Entity\Plugin\DataType\EntityReferenceItem.
+ * Contains \Drupal\Core\Entity\Plugin\field\field_type\EntityReferenceItem.
  */
 
-namespace Drupal\Core\Entity\Plugin\DataType;
+namespace Drupal\Core\Entity\Plugin\field\field_type;
 
 use Drupal\Core\TypedData\Annotation\DataType;
 use Drupal\Core\Annotation\Translation;
@@ -13,7 +13,7 @@
 use Drupal\Core\TypedData\TypedDataInterface;
 
 /**
- * Defines the 'entity_reference_item' entity field item.
+ * Defines the 'entity_reference' entity field type.
  *
  * Supported settings (below the definition's 'settings' key) are:
  * - target_type: The entity type to reference. Required.
@@ -21,11 +21,11 @@
  *   may be referenced. May be set to an single bundle, or to an array of
  *   allowed bundles.
  *
- * @DataType(
- *   id = "entity_reference_field",
- *   label = @Translation("Entity reference field item"),
+ * @FieldType(
+ *   id = "entity_reference",
+ *   label = @Translation("Entity reference"),
  *   description = @Translation("An entity field containing an entity reference."),
- *   list_class = "\Drupal\Core\Entity\Field\FieldItemList",
+ *   configurable = FALSE,
  *   constraints = {"ValidReference" = TRUE}
  * )
  */
diff --git a/core/lib/Drupal/Core/Entity/Plugin/DataType/FloatItem.php b/core/lib/Drupal/Core/Entity/Plugin/field/field_type/FloatItem.php
similarity index 66%
rename from core/lib/Drupal/Core/Entity/Plugin/DataType/FloatItem.php
rename to core/lib/Drupal/Core/Entity/Plugin/field/field_type/FloatItem.php
index 5cd50f9..1dc4713 100644
--- a/core/lib/Drupal/Core/Entity/Plugin/DataType/FloatItem.php
+++ b/core/lib/Drupal/Core/Entity/Plugin/field/field_type/FloatItem.php
@@ -2,23 +2,21 @@
 
 /**
  * @file
- * Contains \Drupal\Core\Entity\Plugin\DataType\FloatItem.
+ * Contains \Drupal\Core\Entity\Plugin\field\field_type\FloatItem.
  */
 
-namespace Drupal\Core\Entity\Plugin\DataType;
+namespace Drupal\Core\Entity\Plugin\field\field_type;
 
-use Drupal\Core\TypedData\Annotation\DataType;
-use Drupal\Core\Annotation\Translation;
 use Drupal\Core\Entity\Field\FieldItemBase;
 
 /**
- * Defines the 'float_field' entity field item.
+ * Defines the 'float' entity field type.
  *
- * @DataType(
- *   id = "float_field",
- *   label = @Translation("Float field item"),
+ * @FieldType(
+ *   id = "float",
+ *   label = @Translation("Float"),
  *   description = @Translation("An entity field containing an float value."),
- *   list_class = "\Drupal\Core\Entity\Field\Field"
+ *   configurable = FALSE
  * )
  */
 class FloatItem extends FieldItemBase {
diff --git a/core/lib/Drupal/Core/Entity/Plugin/DataType/IntegerItem.php b/core/lib/Drupal/Core/Entity/Plugin/field/field_type/IntegerItem.php
similarity index 65%
rename from core/lib/Drupal/Core/Entity/Plugin/DataType/IntegerItem.php
rename to core/lib/Drupal/Core/Entity/Plugin/field/field_type/IntegerItem.php
index 6bd8cf8..e42ac21 100644
--- a/core/lib/Drupal/Core/Entity/Plugin/DataType/IntegerItem.php
+++ b/core/lib/Drupal/Core/Entity/Plugin/field/field_type/IntegerItem.php
@@ -2,23 +2,21 @@
 
 /**
  * @file
- * Contains \Drupal\Core\Entity\Plugin\DataType\IntegerItem.
+ * Contains \Drupal\Core\Entity\Plugin\field\field_type\IntegerItem.
  */
 
-namespace Drupal\Core\Entity\Plugin\DataType;
+namespace Drupal\Core\Entity\Plugin\field\field_type;
 
-use Drupal\Core\TypedData\Annotation\DataType;
-use Drupal\Core\Annotation\Translation;
 use Drupal\Core\Entity\Field\FieldItemBase;
 
 /**
- * Defines the 'integer_field' entity field item.
+ * Defines the 'integer' entity field type.
  *
- * @DataType(
- *   id = "integer_field",
- *   label = @Translation("Integer field item"),
+ * @FieldType(
+ *   id = "integer",
+ *   label = @Translation("Integer"),
  *   description = @Translation("An entity field containing an integer value."),
- *   list_class = "\Drupal\Core\Entity\Field\FieldItemList"
+ *   configurable = FALSE
  * )
  */
 class IntegerItem extends FieldItemBase {
diff --git a/core/lib/Drupal/Core/Entity/Plugin/DataType/LanguageItem.php b/core/lib/Drupal/Core/Entity/Plugin/field/field_type/LanguageItem.php
similarity index 87%
rename from core/lib/Drupal/Core/Entity/Plugin/DataType/LanguageItem.php
rename to core/lib/Drupal/Core/Entity/Plugin/field/field_type/LanguageItem.php
index b156a34..17eabdb 100644
--- a/core/lib/Drupal/Core/Entity/Plugin/DataType/LanguageItem.php
+++ b/core/lib/Drupal/Core/Entity/Plugin/field/field_type/LanguageItem.php
@@ -2,24 +2,22 @@
 
 /**
  * @file
- * Contains \Drupal\Core\Entity\Plugin\DataType\LanguageItem.
+ * Contains \Drupal\Core\Entity\Plugin\field\field_type\LanguageItem.
  */
 
-namespace Drupal\Core\Entity\Plugin\DataType;
+namespace Drupal\Core\Entity\Plugin\field\field_type;
 
-use Drupal\Core\TypedData\Annotation\DataType;
-use Drupal\Core\Annotation\Translation;
 use Drupal\Core\Entity\Field\FieldItemBase;
 use Drupal\Core\Language\Language;
 
 /**
- * Defines the 'language_field' entity field item.
+ * Defines the 'language' entity field item.
  *
- * @DataType(
- *   id = "language_field",
- *   label = @Translation("Language field item"),
+ * @FieldType(
+ *   id = "language",
+ *   label = @Translation("Language"),
  *   description = @Translation("An entity field referencing a language."),
- *   list_class = "\Drupal\Core\Entity\Field\FieldItemList",
+ *   configurable = FALSE,
  *   constraints = {
  *     "ComplexData" = {
  *       "value" = {"Length" = {"max" = 12}}
diff --git a/core/lib/Drupal/Core/Entity/Plugin/DataType/StringItem.php b/core/lib/Drupal/Core/Entity/Plugin/field/field_type/StringItem.php
similarity index 65%
rename from core/lib/Drupal/Core/Entity/Plugin/DataType/StringItem.php
rename to core/lib/Drupal/Core/Entity/Plugin/field/field_type/StringItem.php
index a243567..1e5237c 100644
--- a/core/lib/Drupal/Core/Entity/Plugin/DataType/StringItem.php
+++ b/core/lib/Drupal/Core/Entity/Plugin/field/field_type/StringItem.php
@@ -2,23 +2,21 @@
 
 /**
  * @file
- * Contains \Drupal\Core\Entity\Plugin\DataType\StringItem.
+ * Contains \Drupal\Core\Entity\Plugin\field\field_type\StringItem.
  */
 
-namespace Drupal\Core\Entity\Plugin\DataType;
+namespace Drupal\Core\Entity\Plugin\field\field_type;
 
-use Drupal\Core\TypedData\Annotation\DataType;
-use Drupal\Core\Annotation\Translation;
 use Drupal\Core\Entity\Field\FieldItemBase;
 
 /**
- * Defines the 'string_field' entity field item.
+ * Defines the 'string' entity field type.
  *
- * @DataType(
- *   id = "string_field",
- *   label = @Translation("String field item"),
+ * @FieldType(
+ *   id = "string",
+ *   label = @Translation("String"),
  *   description = @Translation("An entity field containing a string value."),
- *   list_class = "\Drupal\Core\Entity\Field\FieldItemList"
+ *   configurable = FALSE
  * )
  */
 class StringItem extends FieldItemBase {
diff --git a/core/lib/Drupal/Core/Entity/Plugin/DataType/UriItem.php b/core/lib/Drupal/Core/Entity/Plugin/field/field_type/UriItem.php
similarity index 64%
rename from core/lib/Drupal/Core/Entity/Plugin/DataType/UriItem.php
rename to core/lib/Drupal/Core/Entity/Plugin/field/field_type/UriItem.php
index 6ce5970..9c1cabd 100644
--- a/core/lib/Drupal/Core/Entity/Plugin/DataType/UriItem.php
+++ b/core/lib/Drupal/Core/Entity/Plugin/field/field_type/UriItem.php
@@ -2,23 +2,21 @@
 
 /**
  * @file
- * Contains \Drupal\Core\Entity\Plugin\DataType\UriItem.
+ * Contains \Drupal\Core\Entity\Plugin\field\field_type\UriItem.
  */
 
-namespace Drupal\Core\Entity\Plugin\DataType;
+namespace Drupal\Core\Entity\Plugin\field\field_type;
 
-use Drupal\Core\TypedData\Annotation\DataType;
-use Drupal\Core\Annotation\Translation;
 use Drupal\Core\Entity\Field\FieldItemBase;
 
 /**
- * Defines the 'uri_field' entity field item.
+ * Defines the 'uri' entity field type.
  *
- * @DataType(
- *   id = "uri_field",
- *   label = @Translation("URI field item"),
+ * @FieldType(
+ *   id = "uri",
+ *   label = @Translation("URI"),
  *   description = @Translation("An entity field containing a URI."),
- *   list_class = "\Drupal\Core\Entity\Field\FieldItemList"
+ *   configurable = FALSE
  * )
  */
 class UriItem extends FieldItemBase {
diff --git a/core/lib/Drupal/Core/Entity/Plugin/DataType/UuidItem.php b/core/lib/Drupal/Core/Entity/Plugin/field/field_type/UuidItem.php
similarity index 60%
rename from core/lib/Drupal/Core/Entity/Plugin/DataType/UuidItem.php
rename to core/lib/Drupal/Core/Entity/Plugin/field/field_type/UuidItem.php
index 3e28741..2b3d6ea 100644
--- a/core/lib/Drupal/Core/Entity/Plugin/DataType/UuidItem.php
+++ b/core/lib/Drupal/Core/Entity/Plugin/field/field_type/UuidItem.php
@@ -2,24 +2,21 @@
 
 /**
  * @file
- * Contains \Drupal\Core\Entity\Plugin\DataType\UuidItem.
+ * Contains \Drupal\Core\Entity\Plugin\field\field_type\UuidItem.
  */
 
-namespace Drupal\Core\Entity\Plugin\DataType;
-
-use Drupal\Core\TypedData\Annotation\DataType;
-use Drupal\Core\Annotation\Translation;
+namespace Drupal\Core\Entity\Plugin\field\field_type;
 
 /**
- * Defines the 'uuid_field' entity field item.
+ * Defines the 'uuid' entity field type.
  *
  * The field uses a newly generated UUID as default value.
  *
- * @DataType(
- *   id = "uuid_field",
- *   label = @Translation("UUID field item"),
+ * @FieldType(
+ *   id = "uuid",
+ *   label = @Translation("UUID"),
  *   description = @Translation("An entity field containing a UUID."),
- *   list_class = "\Drupal\Core\Entity\Field\FieldItemList",
+ *   configurable = FALSE,
  *   constraints = {
  *     "ComplexData" = {
  *       "value" = {"Length" = {"max" = 128}}
diff --git a/core/modules/comment/lib/Drupal/comment/CommentFieldName.php b/core/modules/comment/lib/Drupal/comment/CommentFieldName.php
index 24bbff7..9f6daa8 100644
--- a/core/modules/comment/lib/Drupal/comment/CommentFieldName.php
+++ b/core/modules/comment/lib/Drupal/comment/CommentFieldName.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\comment;
 
-use Drupal\Core\Entity\Plugin\DataType\StringItem;
+use Drupal\Core\Entity\Plugin\field\field_type\StringItem;
 
 /**
  * The field item for the 'fieldname' field.
diff --git a/core/modules/comment/lib/Drupal/comment/Plugin/field/field_type/CommentItem.php b/core/modules/comment/lib/Drupal/comment/Plugin/field/field_type/CommentItem.php
index 432534f..7cefb45 100644
--- a/core/modules/comment/lib/Drupal/comment/Plugin/field/field_type/CommentItem.php
+++ b/core/modules/comment/lib/Drupal/comment/Plugin/field/field_type/CommentItem.php
@@ -51,11 +51,8 @@ public function getPropertyDefinitions() {
           'label' => t('Comment status value'),
         ),
         'cid' => array(
-          'type' => 'entity_reference_field',
+          'type' => 'integer',
           'label' => t('Last comment ID'),
-          'settings' => array(
-            'target_type' => 'comment',
-          ),
         ),
         'last_comment_timestamp' => array(
           'label' => t('Last comment timestamp'),
@@ -68,11 +65,8 @@ public function getPropertyDefinitions() {
           'type' => 'string',
         ),
         'last_comment_uid' => array(
-          'type' => 'entity_reference_field',
+          'type' => 'integer',
           'label' => t('Last comment user ID'),
-          'settings' => array(
-            'target_type' => 'user',
-          ),
         ),
         'comment_count' => array(
           'label' => t('Number of comments'),
diff --git a/core/modules/email/email.module b/core/modules/email/email.module
index 5a5f116..d77df82 100644
--- a/core/modules/email/email.module
+++ b/core/modules/email/email.module
@@ -31,9 +31,13 @@ function email_help($path, $arg) {
  * Implements hook_field_info_alter().
  */
 function email_field_info_alter(&$info) {
+ $info['email']['default_widget'] = 'email_default';
   if (\Drupal::moduleHandler()->moduleExists('text')) {
     $info['email']['default_formatter'] = 'text_plain';
   }
+  else {
+    $info['email']['default_formatter'] = 'email_mailto';
+  }
 }
 
 /**
diff --git a/core/modules/entity_reference/entity_reference.module b/core/modules/entity_reference/entity_reference.module
index 7b379e4..273251d 100644
--- a/core/modules/entity_reference/entity_reference.module
+++ b/core/modules/entity_reference/entity_reference.module
@@ -15,11 +15,16 @@
  * Implements hook_field_info_alter().
  */
 function entity_reference_field_info_alter(&$info) {
-  if (!\Drupal::moduleHandler()->moduleExists('node')) {
-    // Fall back to another primary entity type if the Node module is not
-    // available.
-    $info['entity_reference']['settings']['target_type'] = 'user';
-  }
+  // Make the entity reference field configurable.
+  $info['entity_reference']['configurable'] = TRUE;
+  $info['entity_reference']['class'] = '\Drupal\entity_reference\Plugin\field\field_type\ConfigurableEntityReferenceItem';
+  $info['entity_reference']['list_class'] = '\Drupal\field\Plugin\Type\FieldType\ConfigFieldItemList';
+  $info['entity_reference']['settings']['target_type'] = \Drupal::moduleHandler()->moduleExists('node') ? 'node' : 'user';
+  $info['entity_reference']['instance_settings']['handler'] = 'default';
+  $info['entity_reference']['instance_settings']['handler_settings'] = array();
+  $info['entity_reference']['default_widget'] = 'entity_reference_autocomplete';
+  $info['entity_reference']['default_formatter'] = 'entity_reference_label';
+  $info['entity_reference']['constraints'] = array('ValidReference' => TRUE);
 }
 
 /**
@@ -27,7 +32,7 @@ function entity_reference_field_info_alter(&$info) {
  *
  * Set the "target_type" property definition for entity reference fields.
  *
- * @see \Drupal\Core\Entity\Plugin\DataType\EntityReferenceItem::getPropertyDefinitions()
+ * @see \Drupal\Core\Entity\Plugin\field\field_type\EntityReferenceItem::getPropertyDefinitions()
  *
  * @param array $info
  *   The property info array as returned by hook_entity_field_info().
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/field_type/ConfigurableEntityReferenceItem.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/field_type/ConfigurableEntityReferenceItem.php
index 96dbdc3..d0c702c 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/field_type/ConfigurableEntityReferenceItem.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/field_type/ConfigurableEntityReferenceItem.php
@@ -7,33 +7,13 @@
 
 namespace Drupal\entity_reference\Plugin\field\field_type;
 
-use Drupal\Core\Annotation\Translation;
-use Drupal\Core\Entity\Annotation\FieldType;
-use Drupal\Core\Entity\Field\Type\EntityReferenceItem;
 use Drupal\field\Plugin\Type\FieldType\ConfigEntityReferenceItemBase;
-use Drupal\field\Plugin\Type\FieldType\ConfigFieldItemBase;
 use Drupal\field\Plugin\Type\FieldType\ConfigFieldItemInterface;
 use Drupal\field\FieldInterface;
 
 /**
  * Plugin implementation of the 'entity_reference' field type.
  *
- * @FieldType(
- *   id = "entity_reference",
- *   label = @Translation("Entity Reference"),
- *   description = @Translation("This field references another entity."),
- *   settings = {
- *     "target_type" = "node"
- *   },
- *   instance_settings = {
- *     "handler" = "default",
- *     "handler_settings" = { }
- *   },
- *   default_widget = "entity_reference_autocomplete",
- *   default_formatter = "entity_reference_label",
- *   constraints = {"ValidReference" = TRUE}
- * )
- *
  * Extends the Core 'entity_reference' entity field item with properties for
  * revision ids, labels (for autocreate) and access.
  *
@@ -88,7 +68,7 @@ public function preSave() {
     $entity = $this->get('entity')->getValue();
     $target_id = $this->get('target_id')->getValue();
 
-    if (empty($target_id) && !empty($entity) && $entity->isNew()) {
+    if (!$target_id && !empty($entity) && $entity->isNew()) {
       $entity->save();
       $this->set('target_id', $entity->id());
     }
diff --git a/core/modules/field/field.module b/core/modules/field/field.module
index 84fd041..9be4601 100644
--- a/core/modules/field/field.module
+++ b/core/modules/field/field.module
@@ -101,17 +101,21 @@ function field_help($path, $arg) {
       $field_widgets = \Drupal::service('plugin.manager.field.widget')->getDefinitions();
       $field_types = \Drupal::service('plugin.manager.entity.field.field_type')->getDefinitions();
       foreach (array_merge($field_types, $field_widgets) as $field_module) {
-        $modules[] = $field_module['provider'];
+        $providers[] = $field_module['provider'];
       }
-      $modules = array_unique($modules);
-      sort($modules);
-      foreach ($modules as $module) {
-        $display = $info[$module]['name'];
-        if (\Drupal::moduleHandler()->implementsHook($module, 'help')) {
-          $items[] = l($display, 'admin/help/' . $module);
-        }
-        else {
-          $items[] = $display;
+      $providers = array_unique($providers);
+      sort($providers);
+      foreach ($providers as $provider) {
+        // Skip plugins provided by core components as they do not implement
+        // hook_help().
+        if (isset($info[$provider]['name'])) {
+          $display = $info[$provider]['name'];
+          if (\Drupal::moduleHandler()->implementsHook($provider, 'help')) {
+            $items[] = l($display, 'admin/help/' . $provider);
+          }
+          else {
+            $items[] = $display;
+          }
         }
       }
       $item_list = array(
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 6b3c137..18cb2e0 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
@@ -7,7 +7,7 @@
 
 namespace Drupal\field\Plugin\Type\FieldType;
 
-use Drupal\Core\Entity\Plugin\DataType\EntityReferenceItem;
+use Drupal\Core\Entity\Plugin\field\field_type\EntityReferenceItem;
 use Drupal\field\Plugin\Type\FieldType\ConfigFieldItemInterface;
 use Drupal\field\FieldInterface;
 use Drupal\field\FieldInstanceInterface;
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 32bea80..eca3358 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
@@ -40,7 +40,15 @@ public function getFieldDefinition() {
     if (!isset($this->instance)) {
       $entity = $this->getEntity();
       $instances = FieldAPI::fieldInfo()->getBundleInstances($entity->entityType(), $entity->bundle());
-      $this->instance = $instances[$this->getName()];
+      if (isset($instances[$this->getName()])) {
+        $this->instance = $instances[$this->getName()];
+      }
+      else {
+        // For base fields, fall back to the parent implementation.
+        // @todo: Inject the field definition with
+        //   https://drupal.org/node/2047229.
+        return parent::getFieldDefinition();
+      }
     }
     return $this->instance;
   }
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/LegacyFieldTypeDiscoveryDecorator.php b/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/LegacyFieldTypeDiscoveryDecorator.php
index c21a3f6..d170085 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/LegacyFieldTypeDiscoveryDecorator.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/LegacyFieldTypeDiscoveryDecorator.php
@@ -63,11 +63,10 @@ public function getDefinitions() {
       $function = $module . '_field_info';
       if (function_exists($function)) {
         foreach ($function() as $plugin_id => $definition) {
-          $definition += array(
-            'id' => $plugin_id,
-            'provider' => $module,
-            'list_class' => '\Drupal\field\Plugin\field\field_type\LegacyConfigFieldItemList',
-          );
+          $definition['id'] = $plugin_id;
+          $definition['provider'] = $module;
+          $definition['configurable'] = TRUE;
+          $definition['list_class'] = '\Drupal\field\Plugin\field\field_type\LegacyConfigFieldItemList';
           $definitions[$plugin_id] = $definition;
         }
       }
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 1a8f65e..035bfa8 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
@@ -8,6 +8,7 @@
 namespace Drupal\field_ui\Tests;
 
 use Drupal\Core\Language\Language;
+use Drupal\Component\Utility\String;
 
 /**
  * Tests the functionality of the 'Manage fields' screen.
@@ -411,7 +412,7 @@ function testHiddenFields() {
 
     // Check that the field type is not available in the 'add new field' row.
     $this->drupalGet($bundle_path);
-    $this->assertFalse($this->xpath('//select[@id="edit-add-new-field-type"]//option[@value="hidden_test_field"]'), "The 'add new field' select respects field types 'no_ui' property.");
+    $this->assertFalse($this->xpath('//select[@id="edit-fields-add-new-field-type"]//option[@value="hidden_test_field"]'), "The 'add new field' select respects field types 'no_ui' property.");
 
     // Create a field and an instance programmatically.
     $field_name = 'hidden_test_field';
@@ -435,13 +436,24 @@ function testHiddenFields() {
     // Check that the newly added instance appears on the 'Manage Fields'
     // screen.
     $this->drupalGet($bundle_path);
-    $this->assertFieldByXPath('//table[@id="field-overview"]//td[1]', $instance['label'], 'Field was created and appears in the overview page.');
+    $this->assertFieldByXPath('//table[@id="field-overview"]//tr[@id="hidden-test-field"]//td[1]', $instance['label'], 'Field was created and appears in the overview page.');
 
     // Check that the instance does not appear in the 're-use existing field' row
     // on other bundles.
     $bundle_path = 'admin/structure/types/manage/article/fields/';
     $this->drupalGet($bundle_path);
     $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();
+    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)));
+      }
+      else {
+        $this->assertFalse($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 no available.', array('@field_type' => $field_type)));
+      }
+    }
   }
 
   /**
diff --git a/core/modules/file/lib/Drupal/file/Plugin/field/field_type/FileItem.php b/core/modules/file/lib/Drupal/file/Plugin/field/field_type/FileItem.php
index fc6be34..eb12619 100644
--- a/core/modules/file/lib/Drupal/file/Plugin/field/field_type/FileItem.php
+++ b/core/modules/file/lib/Drupal/file/Plugin/field/field_type/FileItem.php
@@ -9,7 +9,7 @@
 
 use Drupal\Core\Annotation\Translation;
 use Drupal\Core\Entity\Annotation\FieldType;
-use Drupal\Core\Entity\Plugin\DataType\EntityReferenceItem;
+use Drupal\Core\Entity\Plugin\field\field_type\EntityReferenceItem;
 use Drupal\field\FieldInterface;
 use Drupal\field\Plugin\Type\FieldType\ConfigFieldItemInterface;
 
diff --git a/core/modules/hal/lib/Drupal/hal/Normalizer/EntityReferenceItemNormalizer.php b/core/modules/hal/lib/Drupal/hal/Normalizer/EntityReferenceItemNormalizer.php
index a4f54f0..a7ab95b 100644
--- a/core/modules/hal/lib/Drupal/hal/Normalizer/EntityReferenceItemNormalizer.php
+++ b/core/modules/hal/lib/Drupal/hal/Normalizer/EntityReferenceItemNormalizer.php
@@ -19,7 +19,7 @@ class EntityReferenceItemNormalizer extends FieldItemNormalizer implements UuidR
    *
    * @var string
    */
-  protected $supportedInterfaceOrClass = 'Drupal\Core\Entity\Plugin\DataType\EntityReferenceItem';
+  protected $supportedInterfaceOrClass = 'Drupal\Core\Entity\Plugin\field\field_type\EntityReferenceItem';
 
   /**
    * Implements \Symfony\Component\Serializer\Normalizer\NormalizerInterface::normalize()
diff --git a/core/modules/node/tests/modules/node_access_test/node_access_test.module b/core/modules/node/tests/modules/node_access_test/node_access_test.module
index 793c595..923bcb0 100644
--- a/core/modules/node/tests/modules/node_access_test/node_access_test.module
+++ b/core/modules/node/tests/modules/node_access_test/node_access_test.module
@@ -83,7 +83,7 @@ function node_access_test_permission() {
 function node_access_test_entity_field_info($entity_type) {
   if ($entity_type === 'node') {
     $info['definitions']['private'] = array(
-      'type' => 'boolean_field',
+      'type' => 'field_item:boolean',
       'label' => t('Private'),
       'computed' => TRUE,
       'list' => TRUE,
diff --git a/core/modules/path/lib/Drupal/path/Plugin/DataType/PathItem.php b/core/modules/path/lib/Drupal/path/Plugin/field/field_type/PathItem.php
similarity index 70%
rename from core/modules/path/lib/Drupal/path/Plugin/DataType/PathItem.php
rename to core/modules/path/lib/Drupal/path/Plugin/field/field_type/PathItem.php
index 11059b5..db9b4f5 100644
--- a/core/modules/path/lib/Drupal/path/Plugin/DataType/PathItem.php
+++ b/core/modules/path/lib/Drupal/path/Plugin/field/field_type/PathItem.php
@@ -2,23 +2,21 @@
 
 /**
  * @file
- * Contains \Drupal\path\Plugin\DataType\PathItem.
+ * Contains \Drupal\path\Plugin\field\field_type\PathItem.
  */
 
-namespace Drupal\path\Plugin\DataType;
+namespace Drupal\path\Plugin\field\field_type;
 
-use Drupal\Core\TypedData\Annotation\DataType;
-use Drupal\Core\Annotation\Translation;
 use Drupal\Core\Entity\Field\FieldItemBase;
 
 /**
- * Defines the 'path_field' entity field item.
+ * Defines the 'path' entity field type.
  *
- * @DataType(
- *   id = "path_field",
- *   label = @Translation("Path field item"),
+ * @FieldType(
+ *   id = "path",
+ *   label = @Translation("Path"),
  *   description = @Translation("An entity field containing a path alias and related data."),
- *   list_class = "\Drupal\Core\Entity\Field\FieldItemList"
+ *   configurable = FALSE
  * )
  */
 class PathItem extends FieldItemBase {
diff --git a/core/modules/path/path.module b/core/modules/path/path.module
index 1cdcc49..c7d6b26 100644
--- a/core/modules/path/path.module
+++ b/core/modules/path/path.module
@@ -217,7 +217,7 @@ function path_form_taxonomy_term_form_alter(&$form, $form_state) {
 function path_entity_field_info($entity_type) {
   if ($entity_type === 'taxonomy_term' || $entity_type === 'node') {
     $info['definitions']['path'] = array(
-      'type' => 'path_field',
+      'type' => 'field_item:path',
       'label' => t('The path alias'),
       'computed' => TRUE,
       'list' => TRUE,
diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php
index 7f6c87e..79a143d 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php
@@ -355,8 +355,8 @@ protected function checkIntrospection($entity_type) {
     // @todo: Make this work without having to create entity objects.
     $entity = entity_create($entity_type, array());
     $definitions = $entity->getPropertyDefinitions();
-    $this->assertEqual($definitions['name']['type'], 'string_field', $entity_type .': Name field found.');
-    $this->assertEqual($definitions['user_id']['type'], 'entity_reference_field', $entity_type .': User field found.');
+    $this->assertEqual($definitions['name']['type'], 'field_item:string', $entity_type .': Name field found.');
+    $this->assertEqual($definitions['user_id']['type'], 'field_item:entity_reference', $entity_type .': User field found.');
     $this->assertEqual($definitions['field_test_text']['type'], 'field_item:text', $entity_type .': Test-text-field field found.');
 
     // Test introspecting an entity object.
@@ -364,8 +364,8 @@ protected function checkIntrospection($entity_type) {
     $entity = entity_create($entity_type, array());
 
     $definitions = $entity->getPropertyDefinitions();
-    $this->assertEqual($definitions['name']['type'], 'string_field', $entity_type .': Name field found.');
-    $this->assertEqual($definitions['user_id']['type'], 'entity_reference_field', $entity_type .': User field found.');
+    $this->assertEqual($definitions['name']['type'], 'field_item:string', $entity_type .': Name field found.');
+    $this->assertEqual($definitions['user_id']['type'], 'field_item:entity_reference', $entity_type .': User field found.');
     $this->assertEqual($definitions['field_test_text']['type'], 'field_item:text', $entity_type .': Test-text-field field found.');
 
     $name_properties = $entity->name->getPropertyDefinitions();
@@ -536,7 +536,7 @@ public function testEntityConstraintValidation() {
     $entity->save();
     // Create a reference field item and let it reference the entity.
     $definition = array(
-      'type' => 'entity_reference_field',
+      'type' => 'field_item:entity_reference',
       'settings' => array(
         'target_type' => 'entity_test',
       ),
@@ -563,7 +563,7 @@ public function testEntityConstraintValidation() {
 
     // Test bundle validation.
     $definition = array(
-      'type' => 'entity_reference_field',
+      'type' => 'field_item:entity_reference',
       'settings' => array(
         'target_type' => 'node',
         'target_bundle' => 'article',
diff --git a/core/modules/system/lib/Drupal/system/Tests/TypedData/TypedDataTest.php b/core/modules/system/lib/Drupal/system/Tests/TypedData/TypedDataTest.php
index f8b5306..e90a4a3 100644
--- a/core/modules/system/lib/Drupal/system/Tests/TypedData/TypedDataTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/TypedData/TypedDataTest.php
@@ -548,7 +548,7 @@ public function testTypedDataValidation() {
     // Test validating property containers and make sure the NotNull and Null
     // constraints work with typed data containers.
     $definition = array(
-      'type' => 'integer_field',
+      'type' => 'field_item:integer',
       'constraints' => array(
         'NotNull' => array(),
       ),
@@ -569,7 +569,7 @@ public function testTypedDataValidation() {
 
     // Test the Null constraint with typed data containers.
     $definition = array(
-      'type' => 'float_field',
+      'type' => 'field_item:float',
       'constraints' => array(
         'Null' => array(),
       ),
@@ -605,7 +605,7 @@ public function testTypedDataValidation() {
     // Test validating a list of a values and make sure property paths starting
     // with "0" are created.
     $definition = array(
-      'type' => 'integer_field',
+      'type' => 'field_item:integer',
       'list' => TRUE,
     );
     $violations = $this->typedData->create($definition, array(array('value' => 10)))->validate();
diff --git a/core/modules/user/lib/Drupal/user/Entity/User.php b/core/modules/user/lib/Drupal/user/Entity/User.php
index d8dc8e4..6949c39 100644
--- a/core/modules/user/lib/Drupal/user/Entity/User.php
+++ b/core/modules/user/lib/Drupal/user/Entity/User.php
@@ -58,6 +58,13 @@ public function id() {
   /**
    * {@inheritdoc}
    */
+  public function isNew() {
+    return !empty($this->enforceIsNew) || $this->id() === NULL;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   static function preCreate(EntityStorageControllerInterface $storage_controller, array &$values) {
     parent::preCreate($storage_controller, $values);
 
diff --git a/core/modules/user/lib/Drupal/user/Tests/UserValidationTest.php b/core/modules/user/lib/Drupal/user/Tests/UserValidationTest.php
index 99aaecb..46037f8 100644
--- a/core/modules/user/lib/Drupal/user/Tests/UserValidationTest.php
+++ b/core/modules/user/lib/Drupal/user/Tests/UserValidationTest.php
@@ -108,10 +108,12 @@ function testValidation() {
 
     $mail = $this->randomName(EMAIL_MAX_LENGTH - 11) . '@example.com';
     $user->set('mail', $mail);
+    // @todo: There are two separate violations in case of an invalid e-mail.
+    //   Unifiy field item and field property constraints.
     $violations = $user->validate();
-    $this->assertEqual(count($violations), 1, 'Violation found when email is too long');
+    $this->assertEqual(count($violations), 2, 'Violations found when email is too long');
     $this->assertEqual($violations[0]->getPropertyPath(), 'mail.0.value');
-    $this->assertEqual($violations[0]->getMessage(), t('This value is not a valid email address.'));
+    $this->assertEqual($violations[1]->getMessage(), t('This value is not a valid email address.'));
 
     // Provoke a e-mail collision with an exsiting user.
     $user->set('mail', 'existing@exmaple.com');
