diff --git a/core/lib/Drupal/Core/Field/FieldDefinition.php b/core/lib/Drupal/Core/Field/FieldDefinition.php
index 0829820..45d745f 100644
--- a/core/lib/Drupal/Core/Field/FieldDefinition.php
+++ b/core/lib/Drupal/Core/Field/FieldDefinition.php
@@ -8,7 +8,6 @@
 namespace Drupal\Core\Field;
 
 use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\TypedData\DataDefinition;
 use Drupal\Core\TypedData\ListDefinition;
 
 /**
@@ -17,6 +16,22 @@
 class FieldDefinition extends ListDefinition implements FieldDefinitionInterface {
 
   /**
+   * The field type.
+   *
+   * @var string
+   */
+  protected $type;
+
+  /**
+   * An array of field property definitions.
+   *
+   * @var \Drupal\Core\TypedData\DataDefinitionInterface[]
+   *
+   * @see \Drupal\Core\TypedData\ComplexDataDefinitionInterface::getPropertyDefinitions()
+   */
+  protected $propertyDefinitions;
+
+  /**
    * Creates a new field definition.
    *
    * @param string $type
@@ -26,7 +41,10 @@ class FieldDefinition extends ListDefinition implements FieldDefinitionInterface
    *   A new field definition object.
    */
   public static function create($type) {
-    return new static(array(), DataDefinition::create('field_item:' . $type));
+    $field_definition = new static(array());
+    $field_definition->type = $type;
+    $field_definition->itemDefinition = FieldItemDefinition::create($field_definition);
+    return $field_definition;
   }
 
   /**
@@ -54,10 +72,7 @@ public function setName($name) {
    * {@inheritdoc}
    */
   public function getType() {
-    $data_type = $this->getItemDefinition()->getDataType();
-    // Cut of the leading field_item: prefix from 'field_item:FIELD_TYPE'.
-    $parts = explode(':', $data_type);
-    return $parts[1];
+    return $this->type;
   }
 
   /**
@@ -107,13 +122,6 @@ public function setSetting($setting_name, $value) {
   /**
    * {@inheritdoc}
    */
-  public function getPropertyNames() {
-    return array_keys(\Drupal::typedData()->create($this->getItemDefinition())->getPropertyDefinitions());
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public function isTranslatable() {
     return !empty($this->definition['translatable']);
   }
@@ -201,4 +209,69 @@ public function getDefaultValue(EntityInterface $entity) {
     return $this->getSetting('default_value');
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getPropertyDefinition($name) {
+    if (!isset($this->propertyDefinitions)) {
+      $this->getPropertyDefinitions();
+    }
+    if (isset($this->propertyDefinitions[$name])) {
+      return $this->propertyDefinitions[$name];
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPropertyDefinitions() {
+    if (!isset($this->propertyDefinitions)) {
+      $class = $this->getFieldItemClass();
+      $this->propertyDefinitions = $class::propertyDefinitions($this);
+    }
+    return $this->propertyDefinitions;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPropertyNames() {
+    return array_keys($this->getPropertyDefinitions());
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getMainPropertyName() {
+    $class = $this->getFieldItemClass();
+    return $class::getMainPropertyName();
+  }
+
+  /**
+   * Helper to retrieve the field item class.
+   *
+   * @todo: Remove once getClass() adds in defaults. See
+   * https://drupal.org/node/2116341.
+   */
+  protected function getFieldItemClass() {
+    if ($class = $this->itemDefinition->getClass()) {
+      return $class;
+    }
+    else {
+      $type_definition = \Drupal::typedData()
+        ->getDefinition($this->itemDefinition->getDataType());
+      return $type_definition['class'];
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function __sleep() {
+    // Do not serialized the statically cached property definitions.
+    $vars = get_object_vars($this);
+    unset($vars['propertyDefinitions']);
+    return array_keys($vars);
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Field/FieldDefinitionInterface.php b/core/lib/Drupal/Core/Field/FieldDefinitionInterface.php
index 76f0ef9..4e95165 100644
--- a/core/lib/Drupal/Core/Field/FieldDefinitionInterface.php
+++ b/core/lib/Drupal/Core/Field/FieldDefinitionInterface.php
@@ -209,4 +209,36 @@ public function isMultiple();
    */
   public function getDefaultValue(EntityInterface $entity);
 
+  /**
+   * Gets the definition of a contained property.
+   *
+   * @param string $name
+   *   The name of property.
+   *
+   * @return \Drupal\Core\TypedData\DataDefinitionInterface|null
+   *   The definition of the property or NULL if the property does not exist.
+   */
+  public function getPropertyDefinition($name);
+
+  /**
+   * Gets an array of property definitions of contained properties.
+   *
+   * @return \Drupal\Core\TypedData\DataDefinitionInterface[]
+   *   An array of property definitions of contained properties, keyed by
+   *   property name.
+   */
+  public function getPropertyDefinitions();
+
+  /**
+   * Returns the name of the main property, if any.
+   *
+   * Some field items consist mainly of one main property, e.g. the value of a
+   * text field or the @code target_id @endcode of an entity reference. If the
+   * field item has no main property, the method returns NULL.
+   *
+   * @return string|null
+   *   The name of the value property, or NULL if there is none.
+   */
+  public function getMainPropertyName();
+
 }
diff --git a/core/lib/Drupal/Core/Field/FieldItemDefinition.php b/core/lib/Drupal/Core/Field/FieldItemDefinition.php
new file mode 100644
index 0000000..377a895
--- /dev/null
+++ b/core/lib/Drupal/Core/Field/FieldItemDefinition.php
@@ -0,0 +1,63 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Field\FieldItemDefinition.
+ */
+
+namespace Drupal\Core\Field;
+
+use Drupal\Core\TypedData\ComplexDataDefinitionBase;
+use Drupal\Core\TypedData\ComplexDataDefinitionInterface;
+use Drupal\Core\TypedData\DataDefinition;
+
+/**
+ * A class for defining field items.
+ */
+class FieldItemDefinition extends DataDefinition implements ComplexDataDefinitionInterface {
+
+  /**
+   * The field definition the item definition belongs to.
+   *
+   * @var \Drupal\Core\Field\FieldDefinitionInterface
+   */
+  protected $fieldDefinition;
+
+  /**
+   * Creates a new field item definition.
+   *
+   * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
+   *   The field definition the item definition belongs to.
+   *
+   * @return static
+   *   A new FieldItemDefinition object.
+   */
+  public static function create($field_definition) {
+    $definition['type'] = 'field_item:' . $field_definition->getType();
+    $item_definition = new static($definition);
+    $item_definition->fieldDefinition = $field_definition;
+    return $item_definition;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPropertyDefinition($name) {
+    return $this->fieldDefinition->getPropertyDefinition($name);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPropertyDefinitions() {
+    return $this->fieldDefinition->getPropertyDefinitions();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getMainPropertyName() {
+    return $this->fieldDefinition->getMainPropertyName();
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Field/FieldItemInterface.php b/core/lib/Drupal/Core/Field/FieldItemInterface.php
index 2cdd0c3..f378b86 100644
--- a/core/lib/Drupal/Core/Field/FieldItemInterface.php
+++ b/core/lib/Drupal/Core/Field/FieldItemInterface.php
@@ -24,6 +24,17 @@
 interface FieldItemInterface extends ComplexDataInterface {
 
   /**
+   * Defines field item properties.
+   *
+   * @return \Drupal\Core\TypedData\DataDefinitionInterface[]
+   *   An array of property definitions of contained properties, keyed by
+   *   property name.
+   *
+   * @see \Drupal\Core\Field\FieldItemDefinition
+   */
+  public static function propertyDefinitions(FieldDefinitionInterface $field_definition);
+
+  /**
    * Gets the entity that field belongs to.
    *
    * @return \Drupal\Core\Entity\EntityInterface
@@ -136,20 +147,4 @@ public function delete();
    */
   public function deleteRevision();
 
-  /**
-   * Returns the name of the main property, if any.
-   *
-   * Some field items consist mainly of one main property, e.g. the value of a
-   * text field or the @code target_id @endcode of an entity reference. If the
-   * field item has no main property, the method returns NULL.
-   *
-   * @return string|null
-   *   The name of the value property, or NULL if there is none.
-   *
-   * @todo: Move this to ComplexDataInterface once we improved Typed data to do
-   *   not enforce having all methods on the data objects.
-   *   https://drupal.org/node/2002134
-   */
-  public function getMainPropertyName();
-
 }
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/BooleanItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/BooleanItem.php
index 2a15e4d..5a83b98 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/BooleanItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/BooleanItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\Field\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldItemBase;
 use Drupal\Core\TypedData\DataDefinition;
 
@@ -25,11 +26,11 @@ class BooleanItem extends FieldItemBase {
   /**
    * {@inheritdoc}
    */
-  public static function getPropertyDefinitions(FieldDefinitionInterface $field_definition) {
-    $property_definitions['value'] = DataDefinition::create('boolean')
+  public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
+    $properties['value'] = DataDefinition::create('boolean')
       ->setLabel(t('Boolean value'));
 
-    return $property_definitions;
+    return $properties;
   }
 
 }
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/DateItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/DateItem.php
index 56df178..0652582 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/DateItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/DateItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\Field\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldItemBase;
 
 /**
@@ -24,12 +25,12 @@ class DateItem extends FieldItemBase {
   /**
    * {@inheritdoc}
    */
-  public static function getPropertyDefinitions(FieldDefinitionInterface $field_definition) {
-    $property_definitions['value'] = array(
+  public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
+    $properties['value'] = array(
       'type' => 'date',
       'label' => t('Date value'),
     );
 
-    return $property_definitions;
+    return $properties;
   }
 }
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EmailItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EmailItem.php
index fa2448d..09aea19 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EmailItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EmailItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\Field\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldItemBase;
 use Drupal\Core\TypedData\DataDefinition;
 
@@ -25,11 +26,11 @@ class EmailItem extends FieldItemBase {
   /**
    * {@inheritdoc}
    */
-  public static function getPropertyDefinitions(FieldDefinitionInterface $field_definition) {
-    $property_definitions['value'] = DataDefinition::create('email')
+  public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
+    $properties['value'] = DataDefinition::create('email')
       ->setLabel(t('E-mail value'));
 
-    return $property_definitions;
+    return $properties;
   }
 
 
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php
index 0896336..f1623c8 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\Field\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldItemBase;
 use Drupal\Core\TypedData\DataDefinition;
 
@@ -32,7 +33,7 @@ class EntityReferenceItem extends FieldItemBase {
   /**
    * {@inheritdoc}
    */
-  public static function getPropertyDefinitions(FieldDefinitionInterface $field_definition) {
+  public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
     $settings = $field_definition->getSettings();
     $target_type = $settings['target_type'];
 
@@ -40,18 +41,18 @@ public static function getPropertyDefinitions(FieldDefinitionInterface $field_de
     if (is_subclass_of($target_type_info['class'], '\Drupal\Core\Entity\ContentEntityInterface')) {
       // @todo: Lookup the entity type's ID data type and use it here.
       // https://drupal.org/node/2107249
-      $property_definitions['target_id'] = DataDefinition::create('integer')
+      $properties['target_id'] = DataDefinition::create('integer')
         ->setLabel(t('Entity ID'))
         ->setConstraints(array(
           'Range' => array('min' => 0),
         ));
     }
     else {
-      $property_definitions['target_id'] = DataDefinition::create('string')
+      $properties['target_id'] = DataDefinition::create('string')
         ->setLabel(t('Entity ID'));
     }
 
-    $property_definitions['entity'] = DataDefinition::create('entity_reference')
+    $properties['entity'] = DataDefinition::create('entity_reference')
       ->setLabel(t('Entity'))
       ->setDescription(t('The referenced entity'))
       // The entity object is computed out of the entity ID.
@@ -62,10 +63,10 @@ public static function getPropertyDefinitions(FieldDefinitionInterface $field_de
       ));
 
     if (isset($settings['target_bundle'])) {
-      $property_definitions['entity']->addConstraint('Bundle', $settings['target_bundle']);
+      $properties['entity']->addConstraint('Bundle', $settings['target_bundle']);
     }
 
-    return $property_definitions;
+    return $properties;
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/FloatItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/FloatItem.php
index 93c3fd8..421acc5 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/FloatItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/FloatItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\Field\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldItemBase;
 use Drupal\Core\TypedData\DataDefinition;
 
@@ -25,10 +26,10 @@ class FloatItem extends FieldItemBase {
   /**
    * {@inheritdoc}
    */
-  public static function getPropertyDefinitions(FieldDefinitionInterface $field_definition) {
-    $property_definitions['value'] = DataDefinition::create('float')
+  public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
+    $properties['value'] = DataDefinition::create('float')
       ->setLabel(t('Float value'));
 
-    return $property_definitions;
+    return $properties;
   }
 }
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/IntegerItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/IntegerItem.php
index 5a606ec..68b5d45 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/IntegerItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/IntegerItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\Field\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldItemBase;
 use Drupal\Core\TypedData\DataDefinition;
 
@@ -25,10 +26,10 @@ class IntegerItem extends FieldItemBase {
   /**
    * {@inheritdoc}
    */
-  public static function getPropertyDefinitions(FieldDefinitionInterface $field_definition) {
-    $property_definitions['value'] = DataDefinition::create('integer')
+  public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
+    $properties['value'] = DataDefinition::create('integer')
       ->setLabel(t('Integer value'));
 
-    return $property_definitions;
+    return $properties;
   }
 }
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php
index 53f2769..fee72c2 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\Field\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldItemBase;
 use Drupal\Core\Language\Language;
 use Drupal\Core\TypedData\DataDefinition;
@@ -31,18 +32,18 @@ class LanguageItem extends FieldItemBase {
   /**
    * {@inheritdoc}
    */
-  public static function getPropertyDefinitions(FieldDefinitionInterface $field_definition) {
-    $property_definitions['value'] = DataDefinition::create('string')
+  public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
+    $properties['value'] = DataDefinition::create('string')
       ->setLabel(t('Language code'));
 
-    $property_definitions['language'] = DataDefinition::create('language_reference')
+    $properties['language'] = DataDefinition::create('language_reference')
       ->setLabel(t('Language object'))
       ->setDescription(t('The referenced language'))
       // The language object is retrieved via the language code.
       ->setComputed(TRUE)
       ->setReadOnly(FALSE);
 
-    return $property_definitions;
+    return $properties;
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php
index 4a224fc..7c653f7 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\Field\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldItemBase;
 use Drupal\Core\TypedData\DataDefinition;
 
@@ -25,10 +26,10 @@ class StringItem extends FieldItemBase {
   /**
    * {@inheritdoc}
    */
-  public static function getPropertyDefinitions(FieldDefinitionInterface $field_definition) {
-    $property_definitions['value'] = DataDefinition::create('string')
+  public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
+    $properties['value'] = DataDefinition::create('string')
       ->setLabel(t('Text value'));
 
-    return $property_definitions;
+    return $properties;
   }
 }
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UriItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UriItem.php
index f3c0bf7..ebb8e2f 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UriItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UriItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\Field\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldItemBase;
 use Drupal\Core\TypedData\DataDefinition;
 
@@ -25,11 +26,11 @@ class UriItem extends FieldItemBase {
   /**
    * {@inheritdoc}
    */
-  public static function getPropertyDefinitions(FieldDefinitionInterface $field_definition) {
-    $property_definitions['value'] = DataDefinition::create('uri')
+  public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
+    $properties['value'] = DataDefinition::create('uri')
       ->setLabel(t('URI value'));
 
-    return $property_definitions;
+    return $properties;
   }
 
 }
diff --git a/core/lib/Drupal/Core/TypedData/ComplexDataDefinitionBase.php b/core/lib/Drupal/Core/TypedData/ComplexDataDefinitionBase.php
index 68d7f6d..9be93e2 100644
--- a/core/lib/Drupal/Core/TypedData/ComplexDataDefinitionBase.php
+++ b/core/lib/Drupal/Core/TypedData/ComplexDataDefinitionBase.php
@@ -10,7 +10,7 @@
 /**
  * Base class for complex data definitions.
  */
-abstract class ComplexDataDefinitionBase implements ComplexDataDefinitionInterface {
+abstract class ComplexDataDefinitionBase extends DataDefinition implements ComplexDataDefinitionInterface {
 
   /**
    * An array of data definitions.
@@ -31,9 +31,13 @@ public function getPropertyDefinition($name) {
     if (isset($this->propertyDefinitions[$name])) {
       return $this->propertyDefinitions[$name];
     }
-    else {
-      return NULL;
-    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getMainPropertyName() {
+    return NULL;
   }
 
   /**
diff --git a/core/lib/Drupal/Core/TypedData/ComplexDataDefinitionInterface.php b/core/lib/Drupal/Core/TypedData/ComplexDataDefinitionInterface.php
index 9c38513..dbdad24 100644
--- a/core/lib/Drupal/Core/TypedData/ComplexDataDefinitionInterface.php
+++ b/core/lib/Drupal/Core/TypedData/ComplexDataDefinitionInterface.php
@@ -9,7 +9,6 @@
 
 /**
  * Interface for complex data definitions.
- *
  */
 interface ComplexDataDefinitionInterface extends DataDefinitionInterface  {
 
@@ -33,4 +32,16 @@ public function getPropertyDefinition($name);
    */
   public function getPropertyDefinitions();
 
+  /**
+   * Returns the name of the main property, if any.
+   *
+   * Some field items consist mainly of one main property, e.g. the value of a
+   * text field or the @code target_id @endcode of an entity reference. If the
+   * field item has no main property, the method returns NULL.
+   *
+   * @return string|null
+   *   The name of the value property, or NULL if there is none.
+   */
+  public function getMainPropertyName();
+
 }
diff --git a/core/lib/Drupal/Core/TypedData/ComplexDataInterface.php b/core/lib/Drupal/Core/TypedData/ComplexDataInterface.php
index 76886be..438ea6e 100644
--- a/core/lib/Drupal/Core/TypedData/ComplexDataInterface.php
+++ b/core/lib/Drupal/Core/TypedData/ComplexDataInterface.php
@@ -91,25 +91,25 @@ public function getPropertyValues();
    */
   public function setPropertyValues($values);
 
-//  /**
-//   * Gets the definition of a contained property.
-//   *
-//   * @param string $name
-//   *   The name of property.
-//   *
-//   * @return array|FALSE
-//   *   The definition of the property or FALSE if the property does not exist.
-//   */
-//  public function getPropertyDefinition($name);
-//
-//  /**
-//   * Gets an array of property definitions of contained properties.
-//   *
-//   * @return \Drupal\Core\TypedData\DataDefinitionInterface[]
-//   *   An array of property definitions of contained properties, keyed by
-//   *   property name.
-//   */
-//  public function getPropertyDefinitions();
+  /**
+   * Gets the definition of a contained property.
+   *
+   * @param string $name
+   *   The name of property.
+   *
+   * @return array|FALSE
+   *   The definition of the property or FALSE if the property does not exist.
+   */
+  public function getPropertyDefinition($name);
+
+  /**
+   * Gets an array of property definitions of contained properties.
+   *
+   * @return \Drupal\Core\TypedData\DataDefinitionInterface[]
+   *   An array of property definitions of contained properties, keyed by
+   *   property name.
+   */
+  public function getPropertyDefinitions();
 
   /**
    * Determines whether the data structure is empty.
diff --git a/core/lib/Drupal/Core/TypedData/ListDefinition.php b/core/lib/Drupal/Core/TypedData/ListDefinition.php
index 231a0fc..761b594 100644
--- a/core/lib/Drupal/Core/TypedData/ListDefinition.php
+++ b/core/lib/Drupal/Core/TypedData/ListDefinition.php
@@ -34,12 +34,10 @@ public static function create($item_type) {
 
   /**
    * {@inheritdoc}
-   *
-   * @param
    */
   public function __construct(array $definition = array(), DataDefinitionInterface $item_definition = NULL) {
-    parent::__construct($definition);
-    $this->itemDefinition = isset($item_definition) ? $item_definition : DataDefinition::create('any');
+    $this->definition = $definition;
+    $this->itemDefinition = $item_definition;
   }
 
   /**
diff --git a/core/lib/Drupal/Core/TypedData/MapDefinition.php b/core/lib/Drupal/Core/TypedData/MapDefinition.php
new file mode 100644
index 0000000..f3f968b
--- /dev/null
+++ b/core/lib/Drupal/Core/TypedData/MapDefinition.php
@@ -0,0 +1,74 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\TypedData\MapDefinition.
+ */
+
+namespace Drupal\Core\TypedData;
+
+/**
+ * Data definition class for maps.
+ */
+class MapDefinition extends ComplexDataDefinitionBase {
+
+  /**
+   * The name of the main property, or NULL if there is none.
+   *
+   * @var string
+   */
+  protected $mainPropertyName = NULL;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPropertyDefinitions() {
+    if (!isset($this->propertyDefinitions)) {
+      $this->propertyDefinitions = array();
+    }
+    return $this->propertyDefinitions;
+  }
+
+  /**
+   * Sets the definition of a map property.
+   *
+   * @param string $name
+   *   The name of the property to define.
+   * @param \Drupal\Core\TypedData\DataDefinitionInterface|null $definition
+   *   (optional) The property definition to set, or NULL to unset it.
+   *
+   * @return static
+   *   The object itself for chaining.
+   */
+  public function setPropertyDefinition($name, DataDefinitionInterface $definition = NULL) {
+    if (isset($definition)) {
+      $this->propertyDefinitions[$name] = $definition;
+    }
+    else {
+      unset($this->propertyDefinitions[$name]);
+    }
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getMainPropertyName() {
+    return $this->mainPropertyName;
+  }
+
+  /**
+   * Sets the main property name.
+   *
+   * @param string|null $name
+   *   The name of the main property, or NULL if there is none.
+   *
+   * @return static
+   *   The object itself for chaining.
+   */
+  public function setMainPropertyName($name) {
+    $this->mainPropertyName = $name;
+    return $this;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php b/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php
index 133e43d..7f614d6 100644
--- a/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php
+++ b/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php
@@ -7,9 +7,6 @@
 
 namespace Drupal\Core\TypedData\Plugin\DataType;
 
-use Drupal\Core\TypedData\Annotation\DataType;
-use Drupal\Core\Annotation\Translation;
-use Drupal\Core\TypedData\DataDefinition;
 use Drupal\Core\TypedData\TypedData;
 use Drupal\Core\TypedData\ComplexDataInterface;
 
@@ -31,6 +28,13 @@
 class Map extends TypedData implements \IteratorAggregate, ComplexDataInterface {
 
   /**
+   * The data definition.
+   *
+   * @var \Drupal\Core\TypedData\ComplexDataDefinitionInterface
+   */
+  protected $definition;
+
+  /**
    * An array of values for the contained properties.
    *
    * @var array
@@ -45,15 +49,18 @@ class Map extends TypedData implements \IteratorAggregate, ComplexDataInterface
   protected $properties = array();
 
   /**
-   * Implements \Drupal\Core\TypedData\ComplexDataInterface::getPropertyDefinitions().
+   * {@inheritdoc}
+   */
+  public function getPropertyDefinitions() {
+    return $this->definition->getPropertyDefinitions();
+  }
+
+  /**
+   * {@inheritdoc}
    */
-//  public function getPropertyDefinitions() {
-//    $definitions = array();
-//    foreach ($this->values as $name => $value) {
-//      $definitions[$name] = DataDefinition::create('any');
-//    }
-//    return $definitions;
-//  }
+  public function getPropertyDefinition($name) {
+    return $this->definition->getPropertyDefinition($name);
+  }
 
   /**
    * Overrides \Drupal\Core\TypedData\TypedData::getValue().
@@ -130,7 +137,7 @@ public function get($property_name) {
    * Implements \Drupal\Core\TypedData\ComplexDataInterface::set().
    */
   public function set($property_name, $value, $notify = TRUE) {
-    if ($this->getPropertyDefinition($property_name)) {
+    if ($this->definition->getPropertyDefinition($property_name)) {
       $this->get($property_name)->setValue($value, $notify);
     }
     else {
@@ -184,19 +191,6 @@ public function getIterator() {
   }
 
   /**
-   * Implements \Drupal\Core\TypedData\ComplexDataInterface::getPropertyDefinition().
-   */
-//  public function getPropertyDefinition($name) {
-//    $definitions = $this->getPropertyDefinitions();
-//    if (isset($definitions[$name])) {
-//      return $definitions[$name];
-//    }
-//    else {
-//      return FALSE;
-//    }
-//  }
-
-  /**
    * Implements \Drupal\Core\TypedData\ComplexDataInterface::isEmpty().
    */
   public function isEmpty() {
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index 8debaef..fb8821d 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -895,7 +895,7 @@ function comment_translation_configuration_element_submit($form, &$form_state) {
 /**
  * Implements hook_entity_load().
  *
- * @see \Drupal\comment\Plugin\Field\FieldType\CommentItem::getPropertyDefinitions()
+ * @see \Drupal\comment\Plugin\Field\FieldType\CommentItem::getPropertyDefinitions(propertyDefinitions
  */
 function comment_entity_load($entities, $entity_type) {
   if (!\Drupal::service('comment.manager')->getFields($entity_type)) {
diff --git a/core/modules/comment/lib/Drupal/comment/CommentFieldName.php b/core/modules/comment/lib/Drupal/comment/CommentFieldName.php
index 9cb56b5..75d4498 100644
--- a/core/modules/comment/lib/Drupal/comment/CommentFieldName.php
+++ b/core/modules/comment/lib/Drupal/comment/CommentFieldName.php
@@ -19,13 +19,13 @@ class CommentFieldName extends StringItem {
   /**
    * {@inheritdoc}
    */
-  public static function getPropertyDefinitions(FieldDefinitionInterface $field_definition) {
-    $property_definitions['value'] = DataDefinition::create('string')
+  public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
+    $properties['value'] = DataDefinition::create('string')
       ->setLabel(t('String value'))
       ->setClass('\Drupal\comment\CommentFieldNameValue')
       ->setComputed(TRUE);
 
-    return $property_definitions;
+    return $properties;
   }
 
 }
diff --git a/core/modules/comment/lib/Drupal/comment/Plugin/Field/FieldType/CommentItem.php b/core/modules/comment/lib/Drupal/comment/Plugin/Field/FieldType/CommentItem.php
index 0e6a2d1..df787ad 100644
--- a/core/modules/comment/lib/Drupal/comment/Plugin/Field/FieldType/CommentItem.php
+++ b/core/modules/comment/lib/Drupal/comment/Plugin/Field/FieldType/CommentItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\comment\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\TypedData\DataDefinition;
 use Drupal\field\FieldInterface;
 use Drupal\Core\Field\ConfigFieldItemBase;
@@ -35,29 +36,29 @@ class CommentItem extends ConfigFieldItemBase {
   /**
    * {@inheritdoc}
    */
-  public static function getPropertyDefinitions(FieldDefinitionInterface $field_definition) {
-    $property_definitions['status'] = DataDefinition::create('integer')
+  public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
+    $properties['status'] = DataDefinition::create('integer')
       ->setLabel(t('Comment status value'));
 
-    $property_definitions['cid'] = DataDefinition::create('integer')
+    $properties['cid'] = DataDefinition::create('integer')
       ->setLabel(t('Last comment ID'));
 
-    $property_definitions['last_comment_timestamp'] = DataDefinition::create('integer')
+    $properties['last_comment_timestamp'] = DataDefinition::create('integer')
       ->setLabel(t('Last comment timestamp'))
       ->setDescription(t('The time that the last comment was created.'));
 
-    $property_definitions['last_comment_name'] = DataDefinition::create('string')
+    $properties['last_comment_name'] = DataDefinition::create('string')
       ->setLabel(t('Last comment name'))
       ->setDescription(t('The name of the user posting the last comment.'));
 
-    $property_definitions['last_comment_uid'] = DataDefinition::create('integer')
+    $properties['last_comment_uid'] = DataDefinition::create('integer')
       ->setLabel(t('Last comment user ID'));
 
-    $property_definitions['comment_count'] = DataDefinition::create('integer')
+    $properties['comment_count'] = DataDefinition::create('integer')
       ->setLabel(t('Number of comments'))
       ->setDescription(t('The number of comments.'));
 
-    return $property_definitions;
+    return $properties;
   }
 
   /**
diff --git a/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldType/DateTimeItem.php b/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldType/DateTimeItem.php
index 17b6281..d3ebf25 100644
--- a/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldType/DateTimeItem.php
+++ b/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldType/DateTimeItem.php
@@ -8,6 +8,7 @@
 namespace Drupal\datetime\Plugin\Field\FieldType;
 
 use Drupal\Core\Datetime\DrupalDateTime;
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\PrepareCacheInterface;
 use Drupal\Core\TypedData\DataDefinition;
 use Drupal\field\FieldInterface;
@@ -35,18 +36,18 @@ class DateTimeItem extends ConfigFieldItemBase implements PrepareCacheInterface
   /**
    * {@inheritdoc}
    */
-  public static function getPropertyDefinitions(FieldDefinitionInterface $field_definition) {
-    $property_definitions['value'] = DataDefinition::create('datetime_iso8601')
+  public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
+    $properties['value'] = DataDefinition::create('datetime_iso8601')
       ->setLabel(t('Date value'));
 
-    $property_definitions['date'] = DataDefinition::create('datetime_computed')
+    $properties['date'] = DataDefinition::create('datetime_computed')
       ->setLabel(t('Computed date'))
       ->setDescription(t('The computed DateTime object.'))
       ->setComputed(TRUE)
       ->setClass('\Drupal\datetime\DateTimeComputed')
       ->setSetting('date source', 'value');
 
-    return $property_definitions;
+    return $properties;
   }
 
   /**
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/ConfigurableEntityReferenceItem.php b/core/modules/entity_reference/lib/Drupal/entity_reference/ConfigurableEntityReferenceItem.php
index 533610d..ea4a83b 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/ConfigurableEntityReferenceItem.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/ConfigurableEntityReferenceItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\entity_reference;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\TypedData\DataDefinition;
 use Drupal\field\FieldInterface;
 use Drupal\Core\Field\ConfigEntityReferenceItemBase;
@@ -29,7 +30,7 @@ class ConfigurableEntityReferenceItem extends ConfigEntityReferenceItemBase impl
   /**
    * Definitions of the contained properties.
    *
-   * @see ConfigurableEntityReferenceItem::getPropertyDefinitions()
+   * @see ConfigurableEntityReferenceItem::getPropertyDefinitions(propertyDefinitions
    *
    * @var array
    */
@@ -38,29 +39,20 @@ class ConfigurableEntityReferenceItem extends ConfigEntityReferenceItemBase impl
   /**
    * {@inheritdoc}
    */
-  public function getPropertyDefinitions() {
-    $settings = $this->definition->getSettings();
-    $target_type = $settings['target_type'];
-
-    // Definitions vary by entity type and bundle, so key them accordingly.
-    $key = $target_type . ':';
-    $key .= isset($settings['target_bundle']) ? $settings['target_bundle'] : '';
-
-    if (!isset(static::$propertyDefinitions[$key])) {
-      // Call the parent to define the target_id and entity properties.
-      parent::getPropertyDefinitions();
-
-      // Only add the revision ID property if the target entity type supports
-      // revisions.
-      $target_type_info = \Drupal::entityManager()->getDefinition($target_type);
-      if (!empty($target_type_info['entity_keys']['revision']) && !empty($target_type_info['revision_table'])) {
-        static::$propertyDefinitions[$key]['revision_id'] = DataDefinition::create('integer')
-          ->setLabel(t('Revision ID'))
-          ->setConstraints(array('Range' => array('min' => 0)));
-      }
-    }
+  public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
+    // Call the parent to define the target_id and entity properties.
+    $properties = parent::propertyDefinitions($field_definition);
 
-    return static::$propertyDefinitions[$key];
+    // Only add the revision ID property if the target entity type supports
+    // revisions.
+    $target_type = $field_definition->getSetting('target_type');
+    $target_type_info = \Drupal::entityManager()->getDefinition($target_type);
+    if (!empty($target_type_info['entity_keys']['revision']) && !empty($target_type_info['revision_table'])) {
+      $properties['revision_id'] = DataDefinition::create('integer')
+        ->setLabel(t('Revision ID'))
+        ->addConstraint('Range', array('min' => 0));
+    }
+    return $properties;
   }
 
   /**
diff --git a/core/modules/field/lib/Drupal/field/Entity/Field.php b/core/modules/field/lib/Drupal/field/Entity/Field.php
index e1f89e2..d63b988 100644
--- a/core/modules/field/lib/Drupal/field/Entity/Field.php
+++ b/core/modules/field/lib/Drupal/field/Entity/Field.php
@@ -11,7 +11,7 @@
 use Drupal\Core\Config\Entity\ConfigEntityBase;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityStorageControllerInterface;
-use Drupal\Core\TypedData\DataDefinition;
+use Drupal\Core\Field\FieldItemDefinition;
 use Drupal\field\FieldException;
 use Drupal\field\FieldInterface;
 
@@ -192,6 +192,15 @@ class Field extends ConfigEntityBase implements FieldInterface {
   public $original = NULL;
 
   /**
+   * An array of field property definitions.
+   *
+   * @var \Drupal\Core\TypedData\DataDefinitionInterface[]
+   *
+   * @see \Drupal\Core\TypedData\ComplexDataDefinitionInterface::getPropertyDefinitions()
+   */
+  protected $propertyDefinitions;
+
+  /**
    * The data definition of a field item.
    *
    * @var \Drupal\Core\TypedData\DataDefinition
@@ -551,14 +560,6 @@ public function getSetting($setting_name) {
   /**
    * {@inheritdoc}
    */
-  public function getPropertyNames() {
-    $schema = $this->getSchema();
-    return array_keys($schema['columns']);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public function isTranslatable() {
     return $this->translatable;
   }
@@ -754,10 +755,65 @@ public function getConstraint($constraint_name) {
    */
   public function getItemDefinition() {
     if (!isset($this->itemDefinition)) {
-      $this->itemDefinition = DataDefinition::create('field_item:' . $this->type)
+      $this->itemDefinition = FieldItemDefinition::create($this)
         ->setSettings($this->getSettings());
     }
     return $this->itemDefinition;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getPropertyDefinition($name) {
+    if (!isset($this->propertyDefinitions)) {
+      $this->getPropertyDefinitions();
+    }
+    if (isset($this->propertyDefinitions[$name])) {
+      return $this->propertyDefinitions[$name];
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPropertyDefinitions() {
+    if (!isset($this->propertyDefinitions)) {
+      $class = $this->getFieldItemClass();
+      $this->propertyDefinitions = $class::propertyDefinitions($this);
+    }
+    return $this->propertyDefinitions;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPropertyNames() {
+    return array_keys($this->getPropertyDefinitions());
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getMainPropertyName() {
+    $class = $this->getFieldItemClass();
+    return $class::getMainPropertyName();
+  }
+
+  /**
+   * Helper to retrieve the field item class.
+   *
+   * @todo: Remove once getClass() adds in defaults. See
+   * https://drupal.org/node/2116341.
+   */
+  protected function getFieldItemClass() {
+    if ($class = $this->getItemDefinition()->getClass()) {
+      return $class;
+    }
+    else {
+      $type_definition = \Drupal::typedData()
+        ->getDefinition($this->getItemDefinition()->getDataType());
+      return $type_definition['class'];
+    }
+  }
+
 }
diff --git a/core/modules/field/lib/Drupal/field/Entity/FieldInstance.php b/core/modules/field/lib/Drupal/field/Entity/FieldInstance.php
index 7c2e381..2fc1ddd 100644
--- a/core/modules/field/lib/Drupal/field/Entity/FieldInstance.php
+++ b/core/modules/field/lib/Drupal/field/Entity/FieldInstance.php
@@ -10,6 +10,7 @@
 use Drupal\Core\Config\Entity\ConfigEntityBase;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityStorageControllerInterface;
+use Drupal\Core\Field\FieldItemDefinition;
 use Drupal\field\FieldException;
 use Drupal\Core\TypedData\DataDefinition;
 use Drupal\field\FieldInstanceInterface;
@@ -496,14 +497,6 @@ public function getSetting($setting_name) {
   /**
    * {@inheritdoc}
    */
-  public function getPropertyNames() {
-    $schema = $this->field->getSchema();
-    return array_keys($schema['columns']);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public function isTranslatable() {
     return $this->field->translatable;
   }
@@ -676,9 +669,37 @@ public function getConstraint($constraint_name) {
    */
   public function getItemDefinition() {
     if (!isset($this->itemDefinition)) {
-      $this->itemDefinition = DataDefinition::create('field_item:' . $this->field->type)
+      $this->itemDefinition = FieldItemDefinition::create($this)
         ->setSettings($this->getSettings());
     }
     return $this->itemDefinition;
   }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPropertyDefinition($name) {
+    return $this->field->getPropertyDefinition($name);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPropertyDefinitions() {
+    return $this->field->getPropertyDefinitions();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPropertyNames() {
+    return $this->field->getPropertyNames();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getMainPropertyName() {
+    return $this->field->getMainPropertyName();
+  }
 }
diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldType/HiddenTestItem.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldType/HiddenTestItem.php
index eb90d2c..700efde 100644
--- a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldType/HiddenTestItem.php
+++ b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldType/HiddenTestItem.php
@@ -27,11 +27,11 @@ class HiddenTestItem extends TestItem {
   /**
    * {@inheritdoc}
    */
-  public static function getPropertyDefinitions(FieldDefinitionInterface $field_definition) {
-    $property_definitions['value'] = DataDefinition::create('integer')
+  public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
+    $properties['value'] = DataDefinition::create('integer')
       ->setLabel(t('Test integer value'));
 
-    return $property_definitions;
+    return $properties;
   }
 
 }
diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldType/ShapeItem.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldType/ShapeItem.php
index 0f8463e..f20940e 100644
--- a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldType/ShapeItem.php
+++ b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldType/ShapeItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\field_test\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\TypedData\DataDefinition;
 use Drupal\field\FieldInterface;
 use Drupal\Core\Field\ConfigFieldItemBase;
@@ -30,14 +31,14 @@ class ShapeItem extends ConfigFieldItemBase {
   /**
    * {@inheritdoc}
    */
-  public static function getPropertyDefinitions(FieldDefinitionInterface $field_definition) {
-    $property_definitions['shape'] = DataDefinition::create('string')
+  public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
+    $properties['shape'] = DataDefinition::create('string')
       ->setLabel(t('Shape'));
 
-    $property_definitions['color'] = DataDefinition::create('string')
+    $properties['color'] = DataDefinition::create('string')
       ->setLabel(t('Color'));
 
-    return $property_definitions;
+    return $properties;
   }
 
   /**
diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldType/TestItem.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldType/TestItem.php
index 79b1d19..36a70e2 100644
--- a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldType/TestItem.php
+++ b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldType/TestItem.php
@@ -9,6 +9,7 @@
 
 use Drupal\Core\Entity\Annotation\FieldType;
 use Drupal\Core\Annotation\Translation;
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\PrepareCacheInterface;
 use Drupal\Core\TypedData\DataDefinition;
 use Drupal\field\FieldInterface;
@@ -39,11 +40,11 @@ class TestItem extends ConfigFieldItemBase implements PrepareCacheInterface {
   /**
    * {@inheritdoc}
    */
-  public static function getPropertyDefinitions(FieldDefinitionInterface $field_definition) {
-    $property_definitions['value'] = DataDefinition::create('integer')
+  public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
+    $properties['value'] = DataDefinition::create('integer')
       ->setLabel(t('Test integer value'));
 
-    return $property_definitions;
+    return $properties;
   }
 
   /**
diff --git a/core/modules/file/lib/Drupal/file/Plugin/Field/FieldType/FileItem.php b/core/modules/file/lib/Drupal/file/Plugin/Field/FieldType/FileItem.php
index 0fa96b6..3167780 100644
--- a/core/modules/file/lib/Drupal/file/Plugin/Field/FieldType/FileItem.php
+++ b/core/modules/file/lib/Drupal/file/Plugin/Field/FieldType/FileItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\file\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
 use Drupal\Core\TypedData\DataDefinition;
 use Drupal\field\FieldInterface;
@@ -20,6 +21,7 @@
  *   label = @Translation("File"),
  *   description = @Translation("This field stores the ID of a file as an integer value."),
  *   settings = {
+ *     "target_type" = "file",
  *     "display_field" = "0",
  *     "display_default" = "0",
  *     "uri_scheme" = ""
@@ -78,19 +80,16 @@ public static function schema(FieldInterface $field) {
   /**
    * {@inheritdoc}
    */
-  public static function getPropertyDefinitions(FieldDefinitionInterface $field_definition) {
-    // @todo Setting this here is weird, move it to the annotation.
-    $field_definition->setSetting('target_type', 'file');
+  public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
+    $properties = parent::propertyDefinitions($field_definition);
 
-    $property_definitions = parent::getPropertyDefinitions($field_definition);
-
-    $property_definitions['display'] = DataDefinition::create('boolean')
+    $properties['display'] = DataDefinition::create('boolean')
       ->setLabel(t('Flag to control whether this file should be displayed when viewing content'));
 
-    $property_definitions['description'] = DataDefinition::create('string')
+    $properties['description'] = DataDefinition::create('string')
       ->setLabel(t('A description of the file'));
 
-    return $property_definitions;
+    return $properties;
   }
 
   /**
diff --git a/core/modules/image/lib/Drupal/image/Plugin/Field/FieldType/ImageItem.php b/core/modules/image/lib/Drupal/image/Plugin/Field/FieldType/ImageItem.php
index 87cf05e..6f3ea70 100644
--- a/core/modules/image/lib/Drupal/image/Plugin/Field/FieldType/ImageItem.php
+++ b/core/modules/image/lib/Drupal/image/Plugin/Field/FieldType/ImageItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\image\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\TypedData\DataDefinition;
 use Drupal\field\FieldInterface;
 use Drupal\file\Plugin\Field\FieldType\FileItem;
@@ -19,6 +20,7 @@
  *   label = @Translation("Image"),
  *   description = @Translation("This field stores the ID of an image file as an integer value."),
  *   settings = {
+ *     "target_type" = "file",
  *     "uri_scheme" = "",
  *     "default_image" = {
  *       "fid" = NULL,
@@ -117,25 +119,22 @@ public static function schema(FieldInterface $field) {
   /**
    * {@inheritdoc}
    */
-  public static function getPropertyDefinitions(FieldDefinitionInterface $field_definition) {
-    // @todo Setting this here is weird, move it to the annotation.
-    $field_definition->setSetting('target_type', 'file');
+  public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
+    $properties = parent::propertyDefinitions($field_definition);
 
-    $property_definitions = parent::getPropertyDefinitions($field_definition);
-
-    $property_definitions['alt'] = DataDefinition::create('string')
+    $properties['alt'] = DataDefinition::create('string')
       ->setLabel(t("Alternative image text, for the image's 'alt' attribute."));
 
-    $property_definitions['title'] = DataDefinition::create('string')
+    $properties['title'] = DataDefinition::create('string')
       ->setLabel(t("Image title text, for the image's 'title' attribute."));
 
-    $property_definitions['width'] = DataDefinition::create('integer')
+    $properties['width'] = DataDefinition::create('integer')
       ->setLabel(t('The width of the image in pixels.'));
 
-    $property_definitions['height'] = DataDefinition::create('integer')
+    $properties['height'] = DataDefinition::create('integer')
       ->setLabel(t('The height of the image in pixels.'));
 
-    return $property_definitions;
+    return $properties;
   }
 
   /**
diff --git a/core/modules/link/lib/Drupal/link/Plugin/Field/FieldType/LinkItem.php b/core/modules/link/lib/Drupal/link/Plugin/Field/FieldType/LinkItem.php
index d158505..0784931 100644
--- a/core/modules/link/lib/Drupal/link/Plugin/Field/FieldType/LinkItem.php
+++ b/core/modules/link/lib/Drupal/link/Plugin/Field/FieldType/LinkItem.php
@@ -8,6 +8,7 @@
 namespace Drupal\link\Plugin\Field\FieldType;
 
 use Drupal\Core\Field\ConfigFieldItemBase;
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\TypedData\DataDefinition;
 use Drupal\field\FieldInterface;
 
@@ -30,17 +31,17 @@ class LinkItem extends ConfigFieldItemBase {
   /**
    * {@inheritdoc}
    */
-  public static function getPropertyDefinitions(FieldDefinitionInterface $field_definition) {
-    $property_definitions['url'] = DataDefinition::create('uri')
+  public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
+    $properties['url'] = DataDefinition::create('uri')
       ->setLabel(t('URL'));
 
-    $property_definitions['title'] = DataDefinition::create('string')
+    $properties['title'] = DataDefinition::create('string')
       ->setLabel(t('Link text'));
 
-    $property_definitions['attributes'] = DataDefinition::create('map')
+    $properties['attributes'] = DataDefinition::create('map')
       ->setLabel(t('Attributes'));
 
-    return $property_definitions;
+    return $properties;
   }
 
   /**
diff --git a/core/modules/number/lib/Drupal/number/Plugin/Field/FieldType/DecimalItem.php b/core/modules/number/lib/Drupal/number/Plugin/Field/FieldType/DecimalItem.php
index 205fd88..6083706 100644
--- a/core/modules/number/lib/Drupal/number/Plugin/Field/FieldType/DecimalItem.php
+++ b/core/modules/number/lib/Drupal/number/Plugin/Field/FieldType/DecimalItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\number\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\TypedData\DataDefinition;
 use Drupal\field\FieldInterface;
 use Drupal\Component\Utility\MapArray;
@@ -37,11 +38,11 @@ class DecimalItem extends NumberItemBase {
   /**
    * {@inheritdoc}
    */
-  public static function getPropertyDefinitions(FieldDefinitionInterface $field_definition) {
-    $property_definitions['value'] = DataDefinition::create('string')
+  public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
+    $properties['value'] = DataDefinition::create('string')
       ->setLabel(t('Decimal value'));
 
-    return $property_definitions;
+    return $properties;
   }
 
   /**
diff --git a/core/modules/number/lib/Drupal/number/Plugin/Field/FieldType/FloatItem.php b/core/modules/number/lib/Drupal/number/Plugin/Field/FieldType/FloatItem.php
index 89c57f1..ccbe819 100644
--- a/core/modules/number/lib/Drupal/number/Plugin/Field/FieldType/FloatItem.php
+++ b/core/modules/number/lib/Drupal/number/Plugin/Field/FieldType/FloatItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\number\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\TypedData\DataDefinition;
 use Drupal\field\FieldInterface;
 
@@ -32,11 +33,11 @@ class FloatItem extends NumberItemBase {
   /**
    * {@inheritdoc}
    */
-  public static function getPropertyDefinitions(FieldDefinitionInterface $field_definition) {
-    $property_definitions['value'] = DataDefinition::create('float')
+  public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
+    $properties['value'] = DataDefinition::create('float')
       ->setLabel(t('Float value'));
 
-    return $property_definitions;
+    return $properties;
   }
 
   /**
diff --git a/core/modules/number/lib/Drupal/number/Plugin/Field/FieldType/IntegerItem.php b/core/modules/number/lib/Drupal/number/Plugin/Field/FieldType/IntegerItem.php
index 6523113..a8cf839 100644
--- a/core/modules/number/lib/Drupal/number/Plugin/Field/FieldType/IntegerItem.php
+++ b/core/modules/number/lib/Drupal/number/Plugin/Field/FieldType/IntegerItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\number\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\TypedData\DataDefinition;
 use Drupal\field\FieldInterface;
 
@@ -32,11 +33,11 @@ class IntegerItem extends NumberItemBase {
   /**
    * {@inheritdoc}
    */
-  public static function getPropertyDefinitions(FieldDefinitionInterface $field_definition) {
-    $property_definitions['value'] = DataDefinition::create('integer')
+  public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
+    $properties['value'] = DataDefinition::create('integer')
       ->setLabel(t('Integer value'));
 
-    return $property_definitions;
+    return $properties;
   }
 
   /**
diff --git a/core/modules/options/lib/Drupal/options/Type/ListFloatItem.php b/core/modules/options/lib/Drupal/options/Type/ListFloatItem.php
index 3224c20..12d0c85 100644
--- a/core/modules/options/lib/Drupal/options/Type/ListFloatItem.php
+++ b/core/modules/options/lib/Drupal/options/Type/ListFloatItem.php
@@ -19,11 +19,11 @@ class ListFloatItem extends LegacyConfigFieldItem {
   /**
    * {@inheritdoc}
    */
-  public static function getPropertyDefinitions(FieldDefinitionInterface $field_definition) {
-    $property_definitions['value'] = DataDefinition::create('float')
+  public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
+    $properties['value'] = DataDefinition::create('float')
       ->setLabel(t('Float value'));
 
-    return $property_definitions;
+    return $properties;
   }
 
 }
diff --git a/core/modules/options/lib/Drupal/options/Type/ListIntegerItem.php b/core/modules/options/lib/Drupal/options/Type/ListIntegerItem.php
index 82f665b..cd9bc81 100644
--- a/core/modules/options/lib/Drupal/options/Type/ListIntegerItem.php
+++ b/core/modules/options/lib/Drupal/options/Type/ListIntegerItem.php
@@ -19,11 +19,11 @@ class ListIntegerItem extends LegacyConfigFieldItem {
   /**
    * {@inheritdoc}
    */
-  public static function getPropertyDefinitions(FieldDefinitionInterface $field_definition) {
-    $property_definitions['value'] = DataDefinition::create('integer')
+  public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
+    $properties['value'] = DataDefinition::create('integer')
       ->setLabel(t('Integer value'));
 
-    return $property_definitions;
+    return $properties;
   }
 
 }
diff --git a/core/modules/options/lib/Drupal/options/Type/ListTextItem.php b/core/modules/options/lib/Drupal/options/Type/ListTextItem.php
index fdbb250..41ea0db 100644
--- a/core/modules/options/lib/Drupal/options/Type/ListTextItem.php
+++ b/core/modules/options/lib/Drupal/options/Type/ListTextItem.php
@@ -19,11 +19,11 @@ class ListTextItem extends LegacyConfigFieldItem {
   /**
    * Implements ComplexDataInterface::getPropertyDefinitions().
    */
-  public static function getPropertyDefinitions(FieldDefinitionInterface $field_definition) {
-    $property_definitions['value'] = DataDefinition::create('string')
+  public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
+    $properties['value'] = DataDefinition::create('string')
       ->setLabel(t('Text value'));
 
-    return $property_definitions;
+    return $properties;
   }
 
 }
diff --git a/core/modules/path/lib/Drupal/path/Plugin/Field/FieldType/PathItem.php b/core/modules/path/lib/Drupal/path/Plugin/Field/FieldType/PathItem.php
index bd85424..c89ea05 100644
--- a/core/modules/path/lib/Drupal/path/Plugin/Field/FieldType/PathItem.php
+++ b/core/modules/path/lib/Drupal/path/Plugin/Field/FieldType/PathItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\path\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldItemBase;
 use Drupal\Core\TypedData\DataDefinition;
 
@@ -25,14 +26,14 @@ class PathItem extends FieldItemBase {
   /**
    * {@inheritdoc}
    */
-  public static function getPropertyDefinitions(FieldDefinitionInterface $field_definition) {
-    $property_definitions['alias'] = DataDefinition::create('string')
+  public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
+    $properties['alias'] = DataDefinition::create('string')
       ->setLabel(t('Path alias'));
 
-    $property_definitions['pid'] = DataDefinition::create('string')
+    $properties['pid'] = DataDefinition::create('string')
       ->setLabel(t('Path id'));
 
-    return $property_definitions;
+    return $properties;
   }
 
 }
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 90a7229..0dd4801 100644
--- a/core/modules/system/lib/Drupal/system/Tests/TypedData/TypedDataTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/TypedData/TypedDataTest.php
@@ -10,6 +10,8 @@
 use Drupal\Core\Field\FieldDefinition;
 use Drupal\Core\TypedData\DataDefinition;
 use Drupal\Core\TypedData\ListDefinition;
+use Drupal\Core\TypedData\MapDefinition;
+use Drupal\Core\TypedData\Plugin\DataType\Map;
 use Drupal\simpletest\DrupalUnitTestBase;
 use Drupal\Core\Datetime\DrupalDateTime;
 
@@ -410,9 +412,12 @@ public function testTypedDataMaps() {
       'two' => 'zwei',
       'three' => 'drei',
     );
-    $typed_data = $this->createTypedData(array(
-      'type' => 'map',
-    ), $value);
+    $definition = MapDefinition::create('map')
+      ->setPropertyDefinition('one', DataDefinition::create('string'))
+      ->setPropertyDefinition('two', DataDefinition::create('string'))
+      ->setPropertyDefinition('three', DataDefinition::create('string'));
+
+    $typed_data = $this->createTypedData($definition, $value);
 
     // Test iterating.
     $count = 0;
@@ -424,9 +429,9 @@ public function testTypedDataMaps() {
 
     // Test retrieving metadata.
     $this->assertEqual(array_keys($typed_data->getPropertyDefinitions()), array_keys($value));
-    $definition = $typed_data->getPropertyDefinition('one');
-    $this->assertEqual($definition->getDataType(), 'any');
-    $this->assertFalse($typed_data->getPropertyDefinition('invalid'));
+    $definition = $typed_data->getDefinition()->getPropertyDefinition('one');
+    $this->assertEqual($definition->getDataType(), 'string');
+    $this->assertNull($typed_data->getDefinition()->getPropertyDefinition('invalid'));
 
     // Test getting and setting properties.
     $this->assertEqual($typed_data->get('one')->getValue(), 'eins');
@@ -450,8 +455,11 @@ public function testTypedDataMaps() {
     $this->assertEqual($typed_data->get('two')->getValue(), 'zwei');
     $this->assertEqual($typed_data->get('three')->getValue(), 'drei');
 
+    // Test setting a not defined property. It shouldn't show up in the
+    // properties, but be kept in the values.
     $typed_data->setValue(array('foo' => 'bar'));
-    $this->assertEqual(array_keys($typed_data->getProperties()), array('foo'));
+    $this->assertEqual(array_keys($typed_data->getProperties()), array('one', 'two', 'three'));
+    $this->assertEqual(array_keys($typed_data->getValue()), array('foo', 'one', 'two', 'three'));
 
     // Test getting the string representation.
     $typed_data->setValue(array('one' => 'eins', 'two' => '', 'three' => 'drei'));
@@ -492,10 +500,11 @@ public function testTypedDataMaps() {
       $this->pass('Exception thrown:' . $e->getMessage());
     }
 
-    // Test adding a new entry to the map.
+    // Test adding a new property to the map.
+    $typed_data->getDefinition()->setPropertyDefinition('zero', DataDefinition::create('any'));
     $typed_data->set('zero', 'null');
     $this->assertEqual($typed_data->get('zero')->getValue(), 'null');
-    $definition = $typed_data->getPropertyDefinition('zero');
+    $definition = $typed_data->get('zero')->getDefinition();
     $this->assertEqual($definition->getDataType(), 'any', 'Definition for a new map entry returned.');
   }
 
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldType/TaxonomyTermReferenceItem.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldType/TaxonomyTermReferenceItem.php
index fb0e537..583de24 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldType/TaxonomyTermReferenceItem.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldType/TaxonomyTermReferenceItem.php
@@ -23,6 +23,7 @@
  *   label = @Translation("Term Reference"),
  *   description = @Translation("This field stores a reference to a taxonomy term."),
  *   settings = {
+ *     "target_type" = "taxonomy_term",
  *     "options_list_callback" = NULL,
  *     "allowed_values" = {
  *       {
@@ -79,14 +80,6 @@ public function getSettableOptions(AccountInterface $account = NULL) {
   /**
    * {@inheritdoc}
    */
-  public function getPropertyDefinitions() {
-    $this->definition['settings']['target_type'] = 'taxonomy_term';
-    return parent::getPropertyDefinitions();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public static function schema(FieldInterface $field) {
     return array(
       'columns' => array(
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Type/TaxonomyTermReferenceItem.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Type/TaxonomyTermReferenceItem.php
deleted file mode 100644
index e805954..0000000
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Type/TaxonomyTermReferenceItem.php
+++ /dev/null
@@ -1,27 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\taxonomy\Type\TaxonomyTermReferenceItem.
- */
-
-namespace Drupal\taxonomy\Type;
-
-use Drupal\Core\Field\ConfigEntityReferenceItemBase;
-use Drupal\Core\Field\FieldDefinitionInterface;
-
-/**
- * Defines the 'taxonomy_term_reference' entity field item.
- */
-class TaxonomyTermReferenceItem extends ConfigEntityReferenceItemBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getPropertyDefinitions(FieldDefinitionInterface $field_definition) {
-    // @todo Setting this here is weird, move it to the annotation.
-    $field_definition->setSetting('target_type', 'taxonomy_term');
-    return parent::getPropertyDefinitions($field_definition);
-  }
-
-}
diff --git a/core/modules/telephone/lib/Drupal/telephone/Plugin/Field/FieldType/TelephoneItem.php b/core/modules/telephone/lib/Drupal/telephone/Plugin/Field/FieldType/TelephoneItem.php
index 11490b8..80cb1b9 100644
--- a/core/modules/telephone/lib/Drupal/telephone/Plugin/Field/FieldType/TelephoneItem.php
+++ b/core/modules/telephone/lib/Drupal/telephone/Plugin/Field/FieldType/TelephoneItem.php
@@ -8,6 +8,7 @@
 namespace Drupal\telephone\Plugin\Field\FieldType;
 
 use Drupal\Core\Field\ConfigFieldItemBase;
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\TypedData\DataDefinition;
 use Drupal\field\FieldInterface;
 
@@ -42,11 +43,11 @@ public static function schema(FieldInterface $field) {
   /**
    * {@inheritdoc}
    */
-  public static function getPropertyDefinitions(FieldDefinitionInterface $field_definition) {
-    $property_definitions['value'] = DataDefinition::create('string')
+  public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
+    $properties['value'] = DataDefinition::create('string')
       ->setLabel(t('Telephone number'));
 
-    return $property_definitions;
+    return $properties;
   }
 
   /**
diff --git a/core/modules/text/lib/Drupal/text/Plugin/Field/FieldType/TextItemBase.php b/core/modules/text/lib/Drupal/text/Plugin/Field/FieldType/TextItemBase.php
index 5ad9280..643b5b7 100644
--- a/core/modules/text/lib/Drupal/text/Plugin/Field/FieldType/TextItemBase.php
+++ b/core/modules/text/lib/Drupal/text/Plugin/Field/FieldType/TextItemBase.php
@@ -20,21 +20,21 @@
   /**
    * {@inheritdoc}
    */
-  public static function getPropertyDefinitions(FieldDefinitionInterface $field_definition) {
-    $property_definitions['value'] = DataDefinition::create('string')
+  public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
+    $properties['value'] = DataDefinition::create('string')
       ->setLabel(t('Text value'));
 
-    $property_definitions['format'] = DataDefinition::create('filter_format')
+    $properties['format'] = DataDefinition::create('filter_format')
       ->setLabel(t('Text format'));
 
-    $property_definitions['processed'] = DataDefinition::create('string')
+    $properties['processed'] = DataDefinition::create('string')
       ->setLabel(t('Processed text'))
       ->setDescription(t('The text value with the text format applied.'))
       ->setComputed(TRUE)
       ->setClass('\Drupal\text\TextProcessed')
       ->setSetting('text source', 'value');
 
-    return $property_definitions;
+    return $properties;
   }
 
   /**
diff --git a/core/modules/text/lib/Drupal/text/Plugin/Field/FieldType/TextWithSummaryItem.php b/core/modules/text/lib/Drupal/text/Plugin/Field/FieldType/TextWithSummaryItem.php
index b52e6fe..1e0b7c7 100644
--- a/core/modules/text/lib/Drupal/text/Plugin/Field/FieldType/TextWithSummaryItem.php
+++ b/core/modules/text/lib/Drupal/text/Plugin/Field/FieldType/TextWithSummaryItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\text\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\TypedData\DataDefinition;
 use Drupal\field\FieldInterface;
 
@@ -30,20 +31,20 @@ class TextWithSummaryItem extends TextItemBase {
   /**
    * {@inheritdoc}
    */
-  public static function getPropertyDefinitions(FieldDefinitionInterface $field_definition) {
-    $property_definitions = parent::getPropertyDefinitions($field_definition);
+  public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
+    $properties = parent::propertyDefinitions($field_definition);
 
-    $property_definitions['summary'] = DataDefinition::create('string')
+    $properties['summary'] = DataDefinition::create('string')
       ->setLabel(t('Summary text value'));
 
-    $property_definitions['summary_processed'] = DataDefinition::create('string')
+    $properties['summary_processed'] = DataDefinition::create('string')
       ->setLabel(t('Processed summary text'))
       ->setDescription(t('The summary text value with the text format applied.'))
       ->setComputed(TRUE)
       ->setClass('\Drupal\text\TextProcessed')
       ->setSetting('text source', 'summary');
 
-    return $property_definitions;
+    return $properties;
   }
 
   /**
