diff --git a/core/lib/Drupal/Core/TypedData/AllowedValuesInterface.php b/core/lib/Drupal/Core/TypedData/AllowedValuesInterface.php
new file mode 100644
index 0000000..6715625
--- /dev/null
+++ b/core/lib/Drupal/Core/TypedData/AllowedValuesInterface.php
@@ -0,0 +1,75 @@
+<?php
+/**
+ * @file
+ * Contains \Drupal\Core\TypedData\AllowedValuesInterface.
+ */
+
+namespace Drupal\Core\TypedData;
+
+/**
+ * Interface for retrieving allowed values.
+ *
+ * While allowed values define the values that are allowed to be set by a user,
+ * possible values specify which values existing data might have.
+ *
+ * For example, in an workflow scenario the allowed options for a state field
+ * might depend on the currently set state, while possible options are all
+ * states. Thus allowed values would be used during any editing context, while
+ * possible values would be used for presenting filtering options in a search.
+ */
+interface AllowedValuesInterface {
+
+  /**
+   * Returns an array of allowed values.
+   *
+   * @param object $account
+   *   (optional) The user account for which to generate the allowed values.
+   *
+   * @return array
+   *   An array allowed values.
+   */
+  public function getValues($account = NULL);
+
+  /**
+   * Returns an array of allowed options.
+   *
+   * @param object $account
+   *   (optional) The user account for which to generate the allowed options.
+   *
+   * @return array
+   *   The array of allowed options for the object; e.g. for display within a
+   *   widget. This is either a flat array of option labels keyed by values, or
+   *   a multi-dimensional array of option groups; i.e., an array of flat option
+   *   arrays, keyed by option group label. Labels should NOT be sanitized.
+   *
+   * @see Drupal\Core\TypedData\AllowedValuesInterface::getValues()
+   */
+  public function getOptions($account = NULL);
+
+  /**
+   * Returns an array of possible values.
+   *
+   * @param object $account
+   *   (optional) The user account for which to generate the possible values.
+   *
+   * @return array
+   *   An array of possible values.
+   */
+  public function getPossibleValues($account = NULL);
+
+  /**
+   * Returns an array of possible options.
+   *
+   * @param object $account
+   *   (optional) The user account for which to generate the possible options.
+   *
+   * @return array
+   *   The array of possible options for the object; e.g. for display within a
+   *   widget. This is either a flat array of option labels keyed by values, or
+   *   a multi-dimensional array of option groups; i.e., an array of flat option
+   *   arrays, keyed by option group label. Labels should NOT be sanitized.
+   *
+   * @see Drupal\Core\TypedData\AllowedValuesInterface::getOptions()
+   */
+  public function getPossibleOptions($account = NULL);
+}
diff --git a/core/lib/Drupal/Core/TypedData/TypedDataManager.php b/core/lib/Drupal/Core/TypedData/TypedDataManager.php
index c0f81b9..f6a99c5 100644
--- a/core/lib/Drupal/Core/TypedData/TypedDataManager.php
+++ b/core/lib/Drupal/Core/TypedData/TypedDataManager.php
@@ -368,6 +368,14 @@ public function getConstraints($definition) {
     if (!empty($definition['required']) && empty($definition['constraints']['NotNull'])) {
       $constraints[] = $validation_manager->create('NotNull', array());
     }
+
+    // If the definition provides a class check for further validation criteria.
+    $class = isset($definition['class']) ? $definition['class'] : $type_definition['class'];
+    // Check if the class provides allowed values.
+    if (array_key_exists('Drupal\Core\TypedData\AllowedValuesInterface', class_implements($class))) {
+      $constraints[] = $validation_manager->create('AllowedValues', array());
+    }
+
     return $constraints;
   }
 }
diff --git a/core/lib/Drupal/Core/TypedData/Validation/Metadata.php b/core/lib/Drupal/Core/TypedData/Validation/Metadata.php
index 106f2d0..73bfc8b 100644
--- a/core/lib/Drupal/Core/TypedData/Validation/Metadata.php
+++ b/core/lib/Drupal/Core/TypedData/Validation/Metadata.php
@@ -91,4 +91,14 @@ public function getPropertyName() {
   public function getPropertyValue($container) {
     return $this->typedData->getValue();
   }
+
+  /**
+   * Returns the typed data object.
+   *
+   * @return \Drupal\Core\TypedData\TypedDataInterface
+   *   The typed data object.
+   */
+  public function getTypedData() {
+    return $this->typedData;
+  }
 }
diff --git a/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/AllowedValuesConstraint.php b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/AllowedValuesConstraint.php
new file mode 100644
index 0000000..08f9279
--- /dev/null
+++ b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/AllowedValuesConstraint.php
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Validation\Constraint\AllowedValuesConstraint.
+ */
+
+namespace Drupal\Core\Validation\Plugin\Validation\Constraint;
+
+use Symfony\Component\Validator\Constraints\Choice;
+use Drupal\Component\Annotation\Plugin;
+use Drupal\Core\Annotation\Translation;
+
+/**
+ * Checks for the value being allowed.
+ *
+ * @Plugin(
+ *   id = "AllowedValues",
+ *   label = @Translation("Allowed values", context = "Validation")
+ * )
+ *
+ * @see \Drupal\Core\TypedData\AllowedValuesInterface
+ */
+class AllowedValuesConstraint extends Choice {
+
+  public $minMessage = 'You must select at least %limit choice.|You must select at least %limit choices.';
+  public $maxMessage = 'You must select at most %limit choice.|You must select at most %limit choices.';
+}
diff --git a/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/AllowedValuesConstraintValidator.php b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/AllowedValuesConstraintValidator.php
new file mode 100644
index 0000000..8003fec
--- /dev/null
+++ b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/AllowedValuesConstraintValidator.php
@@ -0,0 +1,29 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Validation\Plugin\Validation\Constraint\AllowedValuesConstraintValidator.
+ */
+
+namespace Drupal\Core\Validation\Plugin\Validation\Constraint;
+
+use Drupal\Core\TypedData\AllowedValuesInterface;
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Constraints\ChoiceValidator;
+
+/**
+ * Validates the AllowedValues constraint.
+ */
+class AllowedValuesConstraintValidator extends ChoiceValidator {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validate($value, Constraint $constraint) {
+    if ($this->context->getMetadata()->getTypedData() instanceof AllowedValuesInterface) {
+      $allowed_values = $this->context->getMetadata()->getTypedData()->getValues();
+      $constraint->choices = $allowed_values;
+    }
+    return parent::validate($value, $constraint);
+  }
+}
diff --git a/core/modules/edit/lib/Drupal/edit/Tests/EditTestBase.php b/core/modules/edit/lib/Drupal/edit/Tests/EditTestBase.php
index 649f033..c288284 100644
--- a/core/modules/edit/lib/Drupal/edit/Tests/EditTestBase.php
+++ b/core/modules/edit/lib/Drupal/edit/Tests/EditTestBase.php
@@ -19,7 +19,7 @@ class EditTestBase extends DrupalUnitTestBase {
    *
    * @var array
    */
-  public static $modules = array('system', 'entity', 'entity_test', 'field', 'field_sql_storage', 'field_test', 'number', 'text', 'edit');
+  public static $modules = array('system', 'entity', 'entity_test', 'field', 'field_sql_storage', 'field_test', 'number', 'filter', 'user', 'text', 'edit');
   /**
    * Sets the default field storage backend for fields created during tests.
    */
@@ -28,7 +28,7 @@ function setUp() {
 
     $this->installSchema('system', 'variable');
     $this->installSchema('entity_test', array('entity_test', 'entity_test_rev'));
-    $this->installConfig(array('field'));
+    $this->installConfig(array('field', 'filter'));
   }
 
   /**
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 7406134..40b6781 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
@@ -147,6 +147,20 @@ public function instanceSettingsForm(array $form, array &$form_state) {
   }
 
   /**
+   * Returns options provided via hook_options_list().
+   *
+   * @see \Drupal\Core\TypedData\AllowedValuesInterface
+   */
+  public function getOptions() {
+    $definition = $this->getPluginDefinition();
+    $callback = "{$definition['module']}_options_list";
+    if (function_exists($callback)) {
+      $entity = $this->getParent()->getParent();
+      return $callback($this->getInstance(), $entity);
+    }
+  }
+
+  /**
    * Returns the legacy callback for a given field type "hook".
    *
    * Copied from \Drupal\field\Plugin\field\field_type\LegacyConfigFieldItem,
diff --git a/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigFieldItem.php b/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigFieldItem.php
index 0f122b6..58e83d4 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigFieldItem.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigFieldItem.php
@@ -107,6 +107,20 @@ public function prepareCache() {
   }
 
   /**
+   * Returns options provided via hook_options_list().
+   *
+   * @see \Drupal\Core\TypedData\AllowedValuesInterface
+   */
+  public function getOptions() {
+    $definition = $this->getPluginDefinition();
+    $callback = "{$definition['module']}_options_list";
+    if (function_exists($callback)) {
+      $entity = $this->getParent()->getParent();
+      return $callback($this->getInstance(), $entity);
+    }
+  }
+
+  /**
    * Returns the legacy callback for a given field type "hook".
    *
    * @param string $hook
diff --git a/core/modules/filter/filter.module b/core/modules/filter/filter.module
index 8938dd9..9fba418 100644
--- a/core/modules/filter/filter.module
+++ b/core/modules/filter/filter.module
@@ -9,6 +9,7 @@
 use Drupal\Core\Language\Language;
 use Drupal\Core\Template\Attribute;
 use Drupal\filter\Plugin\Core\Entity\FilterFormat;
+use Drupal\Core\TypedData\Primitive;
 
 /**
  * Non-HTML markup language filters that generate HTML.
@@ -117,6 +118,19 @@ function filter_element_info() {
 }
 
 /**
+ * Implements hook_data_type_info().
+ */
+function filter_data_type_info() {
+  return array(
+    'filter_format' => array(
+      'label' => t('Filter format'),
+      'class' => 'Drupal\filter\Type\FilterFormat',
+      'primitive type' => Primitive::STRING,
+    ),
+  );
+}
+
+/**
  * Implements hook_menu().
  */
 function filter_menu() {
diff --git a/core/modules/filter/lib/Drupal/filter/Tests/FilterAPITest.php b/core/modules/filter/lib/Drupal/filter/Tests/FilterAPITest.php
index f32d30b..08dabf1 100644
--- a/core/modules/filter/lib/Drupal/filter/Tests/FilterAPITest.php
+++ b/core/modules/filter/lib/Drupal/filter/Tests/FilterAPITest.php
@@ -7,14 +7,17 @@
 
 namespace Drupal\filter\Tests;
 
-use Drupal\simpletest\DrupalUnitTestBase;
+use Drupal\Core\TypedData\AllowedValuesInterface;
+use Drupal\filter\Type\FilterFormat;
+use Drupal\system\Tests\Entity\EntityUnitTestBase;
+use Symfony\Component\Validator\ConstraintViolationListInterface;
 
 /**
  * Tests the behavior of Filter's API.
  */
-class FilterAPITest extends DrupalUnitTestBase {
+class FilterAPITest extends EntityUnitTestBase {
 
-  public static $modules = array('system', 'filter', 'filter_test');
+  public static $modules = array('system', 'filter', 'filter_test', 'user');
 
   public static function getInfo() {
     return array(
@@ -27,7 +30,8 @@ public static function getInfo() {
   function setUp() {
     parent::setUp();
 
-    $this->installConfig(array('system'));
+    $this->installConfig(array('system', 'filter'));
+    $this->installSchema('user', array('users_roles'));
 
     // Create Filtered HTML format.
     $filtered_html_format = entity_create('filter_format', array(
@@ -184,4 +188,86 @@ function testFilterFormatAPI() {
     );
   }
 
+  /**
+   * Tests the function of the typed data type.
+   */
+  function testTypedDataAPI() {
+    $definition = array('type' => 'filter_format');
+    $data = \Drupal::typedData()->create($definition);
+
+    $this->assertTrue($data instanceof AllowedValuesInterface, 'Typed data object implements \Drupal\Core\TypedData\AllowedValuesInterface');
+
+    $filtered_html_user = $this->createUser(array('uid' => 2), array(
+      filter_permission_name(filter_format_load('filtered_html')),
+    ));
+
+    // Test with anonymous user.
+    $GLOBALS['user'] = drupal_anonymous_user();
+
+    $available_values = $data->getPossibleValues();
+    $this->assertEqual($available_values, array('filtered_html', 'full_html', 'plain_text'));
+    $available_options = $data->getPossibleOptions();
+    $expected_available_options = array(
+      'filtered_html' => 'Filtered HTML',
+      'full_html' => 'Full HTML',
+      'plain_text' => 'Plain text',
+    );
+    $this->assertEqual($available_options, $expected_available_options);
+    $allowed_values = $data->getValues();
+    $this->assertEqual($allowed_values, array('plain_text'));
+    $allowed_options = $data->getOptions();
+    $this->assertEqual($allowed_options, array('plain_text' => 'Plain text'));
+
+    $data->setValue('foo');
+    $violations = $data->validate();
+    $this->assertFilterFormatViolation($violations, 'foo');
+
+    // Make sure the information provided by a violation is correct.
+    $violation = $violations[0];
+    $this->assertEqual($violation->getRoot(), $data, 'Violation root is filter format.');
+    $this->assertEqual($violation->getPropertyPath(), '', 'Violation property path is correct.');
+    $this->assertEqual($violation->getInvalidValue(), 'foo', 'Violation contains invalid value.');
+
+    $data->setValue('plain_text');
+    $violations = $data->validate();
+    $this->assertEqual(count($violations), 0, "No validation violation for format 'plain_text' found");
+
+    // Anonymous doesn't have access to the 'filtered_html' format.
+    $data->setValue('filtered_html');
+    $violations = $data->validate();
+    $this->assertFilterFormatViolation($violations, 'filtered_html');
+
+    // Set user with access to 'filtered_html' format.
+    $GLOBALS['user'] = $filtered_html_user;
+    $violations = $data->validate();
+    $this->assertEqual(count($violations), 0, "No validation violation for accessible format 'filtered_html' found.");
+
+    $allowed_values = $data->getValues();
+    $this->assertEqual($allowed_values, array('filtered_html', 'plain_text'));
+    $allowed_options = $data->getOptions();
+    $expected_allowed_options = array(
+      'filtered_html' => 'Filtered HTML',
+      'plain_text' => 'Plain text',
+    );
+    $this->assertEqual($allowed_options, $expected_allowed_options);
+  }
+
+  /**
+   * Checks if an expected violation exists in the given violations.
+   *
+   * @param \Symfony\Component\Validator\ConstraintViolationListInterface $violations
+   *   The violations to assert.
+   * @param mixed $invalid_value
+   *   The expected invalid value.
+   */
+  public function assertFilterFormatViolation(ConstraintViolationListInterface $violations, $invalid_value) {
+    $filter_format_violation_found = FALSE;
+    foreach ($violations as $violation) {
+      if ($violation->getRoot() instanceof FilterFormat && $violation->getInvalidValue() === $invalid_value) {
+        $filter_format_violation_found = TRUE;
+        break;
+      }
+    }
+    $this->assertTrue($filter_format_violation_found, format_string('Validation violation for invalid value "%invalid_value" found', array('%invalid_value' => $invalid_value)));
+  }
 }
diff --git a/core/modules/filter/lib/Drupal/filter/Type/FilterFormat.php b/core/modules/filter/lib/Drupal/filter/Type/FilterFormat.php
new file mode 100644
index 0000000..c3fc852
--- /dev/null
+++ b/core/modules/filter/lib/Drupal/filter/Type/FilterFormat.php
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\filter\Type\FilterFormat.
+ */
+
+namespace Drupal\filter\Type;
+
+use Drupal\Core\TypedData\Type\String;
+use Drupal\Core\TypedData\AllowedValuesInterface;
+
+/**
+ * The filter format data type.
+ */
+class FilterFormat extends String implements AllowedValuesInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPossibleValues($account = NULL) {
+    return array_keys($this->getPossibleOptions());
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPossibleOptions($account = NULL) {
+    $values = array();
+    foreach (filter_formats() as $format) {
+      $values[$format->id()] = $format->label();
+    }
+    return $values;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getValues($account = NULL) {
+    return array_keys($this->getOptions($account));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getOptions($user = NULL) {
+    $user = empty($user) ? $GLOBALS['user'] : $user;
+    $values = array();
+    // @todo: Avoid calling functions but move to injected dependencies.
+    foreach (filter_formats($user) as $format) {
+      $values[$format->id()] = $format->label();
+    }
+    return $values;
+  }
+}
diff --git a/core/modules/hal/lib/Drupal/hal/Tests/NormalizerTestBase.php b/core/modules/hal/lib/Drupal/hal/Tests/NormalizerTestBase.php
index ae7e582..118a313 100644
--- a/core/modules/hal/lib/Drupal/hal/Tests/NormalizerTestBase.php
+++ b/core/modules/hal/lib/Drupal/hal/Tests/NormalizerTestBase.php
@@ -30,7 +30,7 @@
    *
    * @var array
    */
-  public static $modules = array('entity', 'entity_test', 'entity_reference', 'field', 'field_sql_storage', 'hal', 'language', 'rest', 'serialization', 'system', 'text', 'user');
+  public static $modules = array('entity', 'entity_test', 'entity_reference', 'field', 'field_sql_storage', 'hal', 'language', 'rest', 'serialization', 'system', 'text', 'user', 'filter');
 
   /**
    * The mock serializer.
diff --git a/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php b/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php
index f6801c0..cc27f07 100644
--- a/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php
+++ b/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php
@@ -12,6 +12,13 @@
 
 /**
  * Base class for the 'options_*' widgets.
+ *
+ * Field types willing to enable one or several of the widgets defined in
+ * options.module (select, radios/checkboxes, on/off checkbox) need to
+ * implement the AllowedValuesInterface to specify the list of options to
+ * display in the widgets.
+ *
+ * @see \Drupal\Core\TypedData\AllowedValuesInterface
  */
 abstract class OptionsWidgetBase extends WidgetBase {
 
@@ -106,17 +113,19 @@ public static function validateElement(array $element, array &$form_state) {
   /**
    * Returns the array of options for the widget.
    *
+   * @param int $delta
+   *   (optional) The delta of the item to get options for. Defaults to 0.
+   *
    * @return array
    *   The array of options for the widget.
    */
-  protected function getOptions() {
+  protected function getOptions($delta = 0) {
     if (!isset($this->options)) {
       $module_handler = \Drupal::moduleHandler();
 
       // Get the list of options from the field type module, and sanitize them.
-      $field_type_info = field_info_field_types($this->fieldDefinition->getFieldType());
-      $module = $field_type_info['module'];
-      $options = (array) $module_handler->invoke($module, 'options_list', array($this->fieldDefinition, $this->entity));
+      $items = $this->entity->getNGEntity()->get($this->fieldDefinition->getFieldName());
+      $options = $items[$delta]->getOptions();
 
       // Add an empty option if the widget needs one.
       if ($empty_option = $this->getEmptyOption()) {
@@ -157,13 +166,14 @@ protected function getOptions() {
    *
    * @param array $items
    *   The field values.
-   *
+   * @param int $delta
+   *   (optional) The delta of the item to get options for. Defaults to 0.
    * @return array
    *   The array of corresponding selected options.
    */
-  protected function getSelectedOptions(array $items) {
+  protected function getSelectedOptions(array $items, $delta = 0) {
     // We need to check against a flat list of options.
-    $flat_options = $this->flattenOptions($this->getOptions());
+    $flat_options = $this->flattenOptions($this->getOptions($delta));
 
     $selected_options = array();
     foreach ($items as $item) {
diff --git a/core/modules/options/lib/Drupal/options/Plugin/field/widget/SelectWidget.php b/core/modules/options/lib/Drupal/options/Plugin/field/widget/SelectWidget.php
index b17a448..4ca9ed2 100644
--- a/core/modules/options/lib/Drupal/options/Plugin/field/widget/SelectWidget.php
+++ b/core/modules/options/lib/Drupal/options/Plugin/field/widget/SelectWidget.php
@@ -35,8 +35,8 @@ public function formElement(array $items, $delta, array $element, $langcode, arr
 
     $element += array(
       '#type' => 'select',
-      '#options' => $this->getOptions(),
-      '#default_value' => $this->getSelectedOptions($items),
+      '#options' => $this->getOptions($delta),
+      '#default_value' => $this->getSelectedOptions($items, $delta),
       // Do not display a 'multiple' select box if there is only one option.
       '#multiple' => $this->multiple && count($this->options) > 1,
     );
diff --git a/core/modules/options/options.api.php b/core/modules/options/options.api.php
index 5e8c694..152ed70 100644
--- a/core/modules/options/options.api.php
+++ b/core/modules/options/options.api.php
@@ -6,66 +6,6 @@
  */
 
 /**
- * Returns the list of options to be displayed for a field.
- *
- * Field types willing to enable one or several of the widgets defined in
- * options.module (select, radios/checkboxes, on/off checkbox) need to
- * implement this hook to specify the list of options to display in the
- * widgets.
- *
- * @param \Drupal\Core\Entity\Field\FieldDefinitionInterface $field_definition
- *   The field definition.
- * @param \Drupal\Core\Entity\EntityInterface $entity
- *   The entity object the field is attached to.
- *
- * @return
- *   The array of options for the field. Array keys are the values to be
- *   stored, and should be of the data type (string, number...) expected by
- *   the first 'column' for the field type. Array values are the labels to
- *   display within the widgets. The labels should NOT be sanitized,
- *   options.module takes care of sanitation according to the needs of each
- *   widget. The HTML tags defined in _field_filter_xss_allowed_tags() are
- *   allowed, other tags will be filtered.
- */
-function hook_options_list(\Drupal\Core\Entity\Field\FieldDefinitionInterface $field_definition, \Drupal\Core\Entity\EntityInterface $entity) {
-  // Sample structure.
-  $options = array(
-    0 => t('Zero'),
-    1 => t('One'),
-    2 => t('Two'),
-    3 => t('Three'),
-  );
-
-  // Sample structure with groups. Only one level of nesting is allowed. This
-  // is only supported by the 'options_select' widget. Other widgets will
-  // flatten the array.
-  $options = array(
-    t('First group') => array(
-      0 => t('Zero'),
-    ),
-    t('Second group') => array(
-      1 => t('One'),
-      2 => t('Two'),
-    ),
-    3 => t('Three'),
-  );
-
-  // In actual implementations, the array of options will most probably depend
-  // on properties of the field. Example from taxonomy.module:
-  $options = array();
-  foreach ($field_definition->getFieldSetting('allowed_values') as $tree) {
-    $terms = taxonomy_get_tree($tree['vid'], $tree['parent'], NULL, TRUE);
-    if ($terms) {
-      foreach ($terms as $term) {
-        $options[$term->id()] = str_repeat('-', $term->depth) . $term->label();
-      }
-    }
-  }
-
-  return $options;
-}
-
-/**
  * Alters the list of options to be displayed for a field.
  *
  * This hook can notably be used to change the label of the empty option.
diff --git a/core/modules/serialization/lib/Drupal/serialization/Tests/NormalizerTestBase.php b/core/modules/serialization/lib/Drupal/serialization/Tests/NormalizerTestBase.php
index 74fa8d9..b7710cf 100644
--- a/core/modules/serialization/lib/Drupal/serialization/Tests/NormalizerTestBase.php
+++ b/core/modules/serialization/lib/Drupal/serialization/Tests/NormalizerTestBase.php
@@ -16,7 +16,7 @@
    *
    * @var array
    */
-  public static $modules = array('serialization', 'system', 'entity', 'field', 'entity_test', 'text', 'field_sql_storage');
+  public static $modules = array('serialization', 'system', 'entity', 'field', 'entity_test', 'text', 'filter', 'field_sql_storage');
 
   protected function setUp() {
     parent::setUp();
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 8e7eea4..aa65a91 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php
@@ -11,6 +11,7 @@
 use Drupal\Core\Entity\Field\FieldInterface;
 use Drupal\Core\Entity\Field\FieldItemInterface;
 use Drupal\Core\Language\Language;
+use Drupal\Core\TypedData\Type\String;
 use Drupal\Core\TypedData\TypedDataInterface;
 
 /**
@@ -382,7 +383,7 @@ protected function assertIntrospection($entity_type) {
 
     $textfield_properties = $entity->field_test_text->getPropertyDefinitions();
     $this->assertEqual($textfield_properties['value']['type'], 'string', $entity_type .': String value property of the test-text field found.');
-    $this->assertEqual($textfield_properties['format']['type'], 'string', $entity_type .': String format field of the test-text field found.');
+    $this->assertEqual($textfield_properties['format']['type'], 'filter_format', $entity_type .': String format field of the test-text field found.');
     $this->assertEqual($textfield_properties['processed']['type'], 'string', $entity_type .': String processed property of the test-text field found.');
 
     // @todo: Once the user entity has definitions, continue testing getting
@@ -507,7 +508,8 @@ protected function assertDataStructureInterfaces($entity_type) {
    */
   public function getContainedStrings(TypedDataInterface $wrapper, $depth, array &$strings) {
 
-    if ($wrapper->getType() == 'string') {
+    // @todo Switch to check StringInterface as soon as it is in place.
+    if ($wrapper instanceof String) {
       $strings[] = $wrapper->getValue();
     }
 
diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUnitTestBase.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUnitTestBase.php
index 664b09c..3111bb7 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUnitTestBase.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUnitTestBase.php
@@ -19,7 +19,7 @@
    *
    * @var array
    */
-  public static $modules = array('entity', 'user', 'system', 'field', 'text', 'field_sql_storage', 'entity_test');
+  public static $modules = array('entity', 'user', 'system', 'field', 'text', 'filter', 'field_sql_storage', 'entity_test');
 
   public function setUp() {
     parent::setUp();
diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityValidationTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityValidationTest.php
index f1a0fdb..a6d362d 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityValidationTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityValidationTest.php
@@ -133,6 +133,19 @@ protected function checkValidation($entity_type) {
     $this->assertEqual($violation->getRoot(), $test_entity, 'Violation root is entity.');
     $this->assertEqual($violation->getPropertyPath(), 'name.0.value', 'Violation property path is correct.');
     $this->assertEqual($violation->getInvalidValue(), $test_entity->name->value, 'Violation contains invalid value.');
+
+
+    $test_entity = clone $entity;
+    $test_entity->field_test_text->format = $this->randomString(33);
+    $violations = $test_entity->validate();
+    $this->assertEqual($violations->count(), 1, 'Validation failed.');
+    $this->assertEqual($violations[0]->getMessage(), t('The value you selected is not a valid choice.'));
+
+    // Make sure the information provided by a violation is correct.
+    $violation = $violations[0];
+    $this->assertEqual($violation->getRoot(), $test_entity, 'Violation root is entity.');
+    $this->assertEqual($violation->getPropertyPath(), 'field_test_text.0.format', 'Violation property path is correct.');
+    $this->assertEqual($violation->getInvalidValue(), $test_entity->field_test_text->format, 'Violation contains invalid value.');
   }
 
 }
diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/FieldAccessTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/FieldAccessTest.php
index a5db46a..27834a3 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Entity/FieldAccessTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Entity/FieldAccessTest.php
@@ -19,7 +19,7 @@ class FieldAccessTest extends DrupalUnitTestBase {
    *
    * @var array
    */
-  public static $modules = array('entity', 'entity_test', 'field', 'field_sql_storage', 'system', 'text', 'user');
+  public static $modules = array('entity', 'entity_test', 'field', 'field_sql_storage', 'system', 'text', 'filter', 'user');
 
   /**
    * Holds the currently active global user ID that initiated the test run.
diff --git a/core/modules/text/lib/Drupal/text/Plugin/field/field_type/TextItemBase.php b/core/modules/text/lib/Drupal/text/Plugin/field/field_type/TextItemBase.php
index 17f2ba3..f5d1419 100644
--- a/core/modules/text/lib/Drupal/text/Plugin/field/field_type/TextItemBase.php
+++ b/core/modules/text/lib/Drupal/text/Plugin/field/field_type/TextItemBase.php
@@ -32,7 +32,7 @@ public function getPropertyDefinitions() {
         'label' => t('Text value'),
       );
       static::$propertyDefinitions['format'] = array(
-        'type' => 'string',
+        'type' => 'filter_format',
         'label' => t('Text format'),
       );
       static::$propertyDefinitions['processed'] = array(
diff --git a/core/modules/text/lib/Drupal/text/Tests/Formatter/TextPlainUnitTest.php b/core/modules/text/lib/Drupal/text/Tests/Formatter/TextPlainUnitTest.php
index 0a2b900..2733c05 100644
--- a/core/modules/text/lib/Drupal/text/Tests/Formatter/TextPlainUnitTest.php
+++ b/core/modules/text/lib/Drupal/text/Tests/Formatter/TextPlainUnitTest.php
@@ -26,7 +26,7 @@ class TextPlainUnitTest extends DrupalUnitTestBase {
    *
    * @var array
    */
-  public static $modules = array('entity', 'field', 'field_sql_storage', 'text', 'entity_test', 'system');
+  public static $modules = array('entity', 'field', 'field_sql_storage', 'text', 'entity_test', 'system', 'filter');
 
   /**
    * Contains rendered content.
