diff --git a/core/lib/Drupal/Core/Entity/Field/FieldDefinitionInterface.php b/core/lib/Drupal/Core/Entity/Field/FieldDefinitionInterface.php
new file mode 100644
index 0000000..480b93f
--- /dev/null
+++ b/core/lib/Drupal/Core/Entity/Field/FieldDefinitionInterface.php
@@ -0,0 +1,26 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Entity\Field\FieldDefinitionInterface.
+ */
+
+namespace Drupal\Core\Entity\Field;
+
+/**
+ * @todo Document
+ */
+interface FieldDefinitionInterface {
+
+  public function getName();
+  public function getType();
+  public function getSettings();
+  public function getSetting($setting_name);
+  public function getPropertyNames();
+  public function isTranslatable();
+  public function getLabel();
+  public function getDescription();
+  public function getCardinality();
+  public function isRequired();
+
+}
diff --git a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/formatter/DatetimeDefaultFormatter.php b/core/modules/datetime/lib/Drupal/datetime/Plugin/field/formatter/DatetimeDefaultFormatter.php
index d5610f3..f2eff9f 100644
--- a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/formatter/DatetimeDefaultFormatter.php
+++ b/core/modules/datetime/lib/Drupal/datetime/Plugin/field/formatter/DatetimeDefaultFormatter.php
@@ -53,7 +53,7 @@ public function viewElements(EntityInterface $entity, $langcode, array $items) {
 
         // The formatted output will be in local time.
         $date->setTimeZone(timezone_open(drupal_get_user_timezone()));
-        if ($this->field['settings']['datetime_type'] == 'date') {
+        if ($this->getFieldSetting('datetime_type') == 'date') {
           // A date without time will pick up the current time, use the default.
           datetime_date_default_time($date);
         }
diff --git a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/formatter/DatetimePlainFormatter.php b/core/modules/datetime/lib/Drupal/datetime/Plugin/field/formatter/DatetimePlainFormatter.php
index 45a85a2..e385c69 100644
--- a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/formatter/DatetimePlainFormatter.php
+++ b/core/modules/datetime/lib/Drupal/datetime/Plugin/field/formatter/DatetimePlainFormatter.php
@@ -28,7 +28,7 @@
 class DateTimePlainFormatter extends FormatterBase {
 
   /**
-   * Implements Drupal\field\Plugin\Type\Formatter\FormatterInterface::viewElements().
+   * {@inheritdoc}
    */
   public function viewElements(EntityInterface $entity, $langcode, array $items) {
 
@@ -43,7 +43,7 @@ public function viewElements(EntityInterface $entity, $langcode, array $items) {
         $date = $item['date'];
         $date->setTimeZone(timezone_open(drupal_get_user_timezone()));
         $format = DATETIME_DATETIME_STORAGE_FORMAT;
-        if ($this->field['settings']['datetime_type'] == 'date') {
+        if ($this->getFieldSetting('datetime_type') == 'date') {
           // A date without time will pick up the current time, use the default.
           datetime_date_default_time($date);
           $format = DATETIME_DATE_STORAGE_FORMAT;
diff --git a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDatelistWidget.php b/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDatelistWidget.php
index f0d60fe..610f6fd 100644
--- a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDatelistWidget.php
+++ b/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDatelistWidget.php
@@ -11,8 +11,9 @@
 use Drupal\field\Plugin\Type\Widget\WidgetBase;
 use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\Field\FieldDefinitionInterface;
 use Drupal\field\Plugin\PluginSettingsBase;
-use Drupal\field\Plugin\Core\Entity\FieldInstance;
+use Drupal\field\FieldInstanceInterface;
 use Drupal\Core\Datetime\DrupalDateTime;
 use Drupal\datetime\DateHelper;
 
@@ -38,10 +39,14 @@ class DateTimeDatelistWidget extends WidgetBase {
   /**
    * {@inheritdoc}
    */
-  public function __construct($plugin_id, array $plugin_definition, FieldInstance $instance, array $settings) {
+  public function __construct($plugin_id, array $plugin_definition, FieldDefinitionInterface $field_definition, array $settings) {
     // Identify the function used to set the default value.
-    $instance['default_value_function'] = $this->defaultValueFunction();
-    parent::__construct($plugin_id, $plugin_definition, $instance, $settings);
+    // @todo Make this work for both configurable and nonconfigurable fields:
+    //   https://drupal.org/node/1989468.
+    if ($field_definition instanceof FieldInstanceInterface) {
+      $field_definition->default_value_function = $this->defaultValueFunction();
+    }
+    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings);
   }
 
   /**
@@ -55,13 +60,9 @@ public function defaultValueFunction() {
   }
 
   /**
-   * Implements \Drupal\field\Plugin\Type\Widget\WidgetInterface::formElement().
+   * {@inheritdoc}
    */
   public function formElement(array $items, $delta, array $element, $langcode, array &$form, array &$form_state) {
-
-    $field = $this->field;
-    $instance = $this->instance;
-
     $date_order = $this->getSetting('date_order');
     $time_type = $this->getSetting('time_type');
     $increment = $this->getSetting('increment');
@@ -78,7 +79,7 @@ public function formElement(array $items, $delta, array $element, $langcode, arr
     $element['#element_validate'][] = 'datetime_datelist_widget_validate';
 
     // Identify the type of date and time elements to use.
-    switch ($field['settings']['datetime_type']) {
+    switch ($this->getFieldSetting('datetime_type')) {
       case 'date':
         $storage_format = DATETIME_DATE_STORAGE_FORMAT;
         $type_type = 'none';
@@ -126,7 +127,7 @@ public function formElement(array $items, $delta, array $element, $langcode, arr
     );
 
     // Set the storage and widget options so the validation can use them. The
-    // validator will not have access to field or instance settings.
+    // validator will not have access to the field definition.
     $element['value']['#date_storage_format'] = $storage_format;
 
     if (!empty($items[$delta]['date'])) {
@@ -134,7 +135,7 @@ public function formElement(array $items, $delta, array $element, $langcode, arr
       // The date was created and verified during field_load(), so it is safe to
       // use without further inspection.
       $date->setTimezone( new \DateTimeZone($element['value']['#date_timezone']));
-      if ($field['settings']['datetime_type'] == 'date') {
+      if ($this->getFieldSetting('datetime_type') == 'date') {
         // A date without time will pick up the current time, use the default
         // time.
         datetime_date_default_time($date);
@@ -145,22 +146,11 @@ public function formElement(array $items, $delta, array $element, $langcode, arr
   }
 
   /**
-   *
-   *
-   * @param array $form
-   *   The form definition as an array.
-   * @param array $form_state
-   *   The current state of the form as an array.
-   *
-   * @return array
-   *
+   * {@inheritdoc}
    */
   function settingsForm(array $form, array &$form_state) {
     $element = parent::settingsForm($form, $form_state);
 
-    $field = $this->field;
-    $instance = $this->instance;
-
     $element['date_order'] = array(
       '#type' => 'select',
       '#title' => t('Date part order'),
@@ -168,7 +158,7 @@ function settingsForm(array $form, array &$form_state) {
       '#options' => array('MDY' => t('Month/Day/Year'), 'DMY' => t('Day/Month/Year'), 'YMD' => t('Year/Month/Day')),
     );
 
-    if ($field['settings']['datetime_type'] == 'datetime') {
+    if ($this->getFieldSetting('datetime_type') == 'datetime') {
       $element['time_type'] = array(
         '#type' => 'select',
         '#title' => t('Time type'),
diff --git a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDefaultWidget.php b/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDefaultWidget.php
index f0c45c0..79f12bc 100644
--- a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDefaultWidget.php
+++ b/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDefaultWidget.php
@@ -11,8 +11,9 @@
 use Drupal\field\Plugin\Type\Widget\WidgetBase;
 use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\Field\FieldDefinitionInterface;
 use Drupal\field\Plugin\PluginSettingsBase;
-use Drupal\field\Plugin\Core\Entity\FieldInstance;
+use Drupal\field\FieldInstanceInterface;
 use Drupal\Core\Datetime\DrupalDateTime;
 
 /**
@@ -32,10 +33,14 @@ class DateTimeDefaultWidget extends WidgetBase {
   /**
    * {@inheritdoc}
    */
-  public function __construct($plugin_id, array $plugin_definition, FieldInstance $instance, array $settings) {
+  public function __construct($plugin_id, array $plugin_definition, FieldDefinitionInterface $field_definition, array $settings) {
     // Identify the function used to set the default value.
-    $instance['default_value_function'] = $this->defaultValueFunction();
-    parent::__construct($plugin_id, $plugin_definition, $instance, $settings);
+    // @todo Make this work for both configurable and nonconfigurable fields:
+    //   https://drupal.org/node/1989468.
+    if ($field_definition instanceof FieldInstanceInterface) {
+      $field_definition->default_value_function = $this->defaultValueFunction();
+    }
+    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings);
   }
 
   /**
@@ -49,13 +54,9 @@ public function defaultValueFunction() {
   }
 
   /**
-   * Implements \Drupal\field\Plugin\Type\Widget\WidgetInterface::formElement().
-   *
+   * {@inheritdoc}
    */
   public function formElement(array $items, $delta, array $element, $langcode, array &$form, array &$form_state) {
-
-    $field = $this->field;
-    $instance = $this->instance;
     $format_type = datetime_default_format_type();
 
     // We are nesting some sub-elements inside the parent, so we need a wrapper.
@@ -69,7 +70,7 @@ public function formElement(array $items, $delta, array $element, $langcode, arr
     $element['#element_validate'][] = 'datetime_datetime_widget_validate';
 
     // Identify the type of date and time elements to use.
-    switch ($field['settings']['datetime_type']) {
+    switch ($this->getFieldSetting('datetime_type')) {
       case 'date':
         $date_type = 'date';
         $time_type = 'none';
@@ -104,7 +105,7 @@ public function formElement(array $items, $delta, array $element, $langcode, arr
     );
 
     // Set the storage and widget options so the validation can use them. The
-    // validator will not have access to field or instance settings.
+    // validator will not have access to the field definition.
     $element['value']['#date_element_format'] = $element_format;
     $element['value']['#date_storage_format'] = $storage_format;
 
@@ -113,7 +114,7 @@ public function formElement(array $items, $delta, array $element, $langcode, arr
       // The date was created and verified during field_load(), so it is safe to
       // use without further inspection.
       $date->setTimezone(new \DateTimeZone($element['value']['#date_timezone']));
-      if ($field['settings']['datetime_type'] == 'date') {
+      if ($this->getFieldSetting('datetime_type') == 'date') {
         // A date without time will pick up the current time, use the default
         // time.
         datetime_date_default_time($date);
diff --git a/core/modules/edit/lib/Drupal/edit/Access/EditEntityFieldAccessCheck.php b/core/modules/edit/lib/Drupal/edit/Access/EditEntityFieldAccessCheck.php
index f7f0c06..e139d0e 100644
--- a/core/modules/edit/lib/Drupal/edit/Access/EditEntityFieldAccessCheck.php
+++ b/core/modules/edit/lib/Drupal/edit/Access/EditEntityFieldAccessCheck.php
@@ -41,7 +41,7 @@ public function access(Route $route, Request $request) {
    * Implements EntityFieldAccessCheckInterface::accessEditEntityField().
    */
   public function accessEditEntityField(EntityInterface $entity, $field_name) {
-    return $entity->access('update') && field_access('edit', $field_name, $entity->entityType(), $entity);
+    return $entity->access('update') && ($field = field_info_field($field_name)) && field_access('edit', $field, $entity->entityType(), $entity);
   }
 
   /**
diff --git a/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityFormDisplay.php b/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityFormDisplay.php
index 9f6425b..8c72986 100644
--- a/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityFormDisplay.php
+++ b/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityFormDisplay.php
@@ -54,7 +54,7 @@ public function getWidget($field_name) {
     if ($configuration = $this->getComponent($field_name)) {
       $instance = field_info_instance($this->targetEntityType, $field_name, $this->bundle);
       $widget = $this->pluginManager->getInstance(array(
-        'instance' => $instance,
+        'field_definition' => $instance,
         'form_mode' => $this->originalMode,
         // No need to prepare, defaults have been merged in setComponent().
         'prepare' => FALSE,
diff --git a/core/modules/entity_reference/entity_reference.module b/core/modules/entity_reference/entity_reference.module
index 3c68c46..fc4ee5f 100644
--- a/core/modules/entity_reference/entity_reference.module
+++ b/core/modules/entity_reference/entity_reference.module
@@ -8,6 +8,7 @@
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Database\Query\AlterableInterface;
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\Field\FieldDefinitionInterface;
 
 /**
  * Implements hook_field_info().
@@ -80,10 +81,9 @@ function entity_reference_field_widget_info_alter(&$info) {
  *
  * @return \Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface
  */
-function entity_reference_get_selection_handler($field, $instance, EntityInterface $entity = NULL) {
+function entity_reference_get_selection_handler(FieldDefinitionInterface $field_definition, EntityInterface $entity = NULL) {
   $options = array(
-    'field' => $field,
-    'instance' => $instance,
+    'field_definition' => $field_definition,
     'entity' => $entity,
   );
   return drupal_container()->get('plugin.manager.entity_reference.selection')->getInstance($options);
@@ -149,7 +149,7 @@ function entity_reference_field_validate(EntityInterface $entity = NULL, $field,
   }
 
   if ($ids) {
-    $valid_ids = entity_reference_get_selection_handler($field, $instance, $entity)->validateReferencableEntities(array_keys($ids));
+    $valid_ids = entity_reference_get_selection_handler($instance, $entity)->validateReferencableEntities(array_keys($ids));
 
     $invalid_entities = array_diff_key($ids, array_flip($valid_ids));
     if ($invalid_entities) {
@@ -290,7 +290,7 @@ function entity_reference_field_instance_settings_form($field, $instance, $form_
     '#attributes' => array('class' => array('entity_reference-settings')),
   );
 
-  $handler = entity_reference_get_selection_handler($field, $instance);
+  $handler = entity_reference_get_selection_handler($instance);
   $form['handler']['handler_settings'] += $handler->settingsForm($field, $instance);
 
   return $form;
@@ -386,13 +386,13 @@ function entity_reference_settings_ajax_submit($form, &$form_state) {
 /**
  * Implements hook_options_list().
  */
-function entity_reference_options_list($field, $instance, $entity_type = NULL, $entity = NULL) {
-  if (!$options = entity_reference_get_selection_handler($field, $instance, $entity)->getReferencableEntities()) {
+function entity_reference_options_list(FieldDefinitionInterface $field_definition, $entity_type = NULL, $entity = NULL) {
+  if (!$options = entity_reference_get_selection_handler($field_definition, $entity)->getReferencableEntities()) {
     return array();
   }
 
   // Rebuild the array by changing the bundle key into the bundle label.
-  $target_type = $field['settings']['target_type'];
+  $target_type = $field_definition->getSetting('target_type');
   $bundles = entity_get_bundles($target_type);
 
   $return = array();
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/EntityReferenceAutocomplete.php b/core/modules/entity_reference/lib/Drupal/entity_reference/EntityReferenceAutocomplete.php
index 6168bea..6a42b57 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/EntityReferenceAutocomplete.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/EntityReferenceAutocomplete.php
@@ -71,7 +71,7 @@ public function getMatches($field, $instance, $entity_type, $entity_id = '', $pr
         throw new AccessDeniedHttpException();
       }
     }
-    $handler = entity_reference_get_selection_handler($field, $instance, $entity);
+    $handler = entity_reference_get_selection_handler($instance, $entity);
 
     if (isset($string)) {
       // Get an array of matching entities.
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Derivative/SelectionBase.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Derivative/SelectionBase.php
index 9e191bf..55dfe97 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Derivative/SelectionBase.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Derivative/SelectionBase.php
@@ -46,7 +46,7 @@ public function getDerivativeDefinitions(array $base_plugin_definition) {
     foreach (entity_get_info() as $entity_type => $info) {
       if (!in_array($entity_type, $supported_entities)) {
         $this->derivatives[$entity_type] = $base_plugin_definition;
-        $this->derivatives[$entity_type]['label'] = t('@enitty_type selection', array('@entity_type' => $info['label']));
+        $this->derivatives[$entity_type]['label'] = t('@entity_type selection', array('@entity_type' => $info['label']));
       }
     }
     return $this->derivatives;
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Type/Selection/SelectionBroken.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Type/Selection/SelectionBroken.php
index 31c1cb1..d8a73b9 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Type/Selection/SelectionBroken.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Type/Selection/SelectionBroken.php
@@ -15,14 +15,6 @@
 class SelectionBroken implements SelectionInterface {
 
   /**
-   * Constructs a SelectionBroken object.
-   */
-  public function __construct($field, $instance = NULL) {
-    $this->field = $field;
-    $this->instance = $instance;
-  }
-
-  /**
    * Implements SelectionInterface::settingsForm().
    */
   public static function settingsForm(&$field, &$instance) {
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Type/SelectionPluginManager.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Type/SelectionPluginManager.php
index f178242..9166b27 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Type/SelectionPluginManager.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Type/SelectionPluginManager.php
@@ -42,7 +42,7 @@ public function createInstance($plugin_id, array $configuration = array()) {
       return parent::createInstance($plugin_id, $configuration);
     }
     catch (PluginException $e) {
-      return new SelectionBroken($configuration['field'], $configuration['instance']);
+      return new SelectionBroken($configuration['field_definition']);
     }
   }
 
@@ -50,8 +50,8 @@ public function createInstance($plugin_id, array $configuration = array()) {
    * Overrides \Drupal\Component\Plugin\PluginManagerBase::getInstance().
    */
   public function getInstance(array $options) {
-    $selection_handler = $options['instance']['settings']['handler'];
-    $target_entity_type = $options['field']['settings']['target_type'];
+    $selection_handler = $options['field_definition']->getSetting('handler');
+    $target_entity_type = $options['field_definition']->getSetting('target_type');
 
     // Get all available selection plugins for this entity type.
     $selection_handler_groups = $this->getSelectionGroups($target_entity_type);
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/entity_reference/selection/SelectionBase.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/entity_reference/selection/SelectionBase.php
index ab60905..5a2c6de 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/entity_reference/selection/SelectionBase.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/entity_reference/selection/SelectionBase.php
@@ -12,6 +12,7 @@
 use Drupal\Core\Database\Query\AlterableInterface;
 use Drupal\Core\Database\Query\SelectInterface;
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\Field\FieldDefinitionInterface;
 use Drupal\Component\Utility\NestedArray;
 use Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface;
 
@@ -30,18 +31,11 @@
 class SelectionBase implements SelectionInterface {
 
   /**
-   * The field array.
+   * The field definition.
    *
-   * @var array
+   * @var \Drupal\Core\Entity\Field\FieldDefinitionInterface
    */
-  protected $field;
-
-  /**
-   * The instance array.
-   *
-   * @var array
-   */
-  protected $instance;
+  protected $fieldDefinition;
 
   /**
    * The entity object, or NULL
@@ -53,9 +47,8 @@ class SelectionBase implements SelectionInterface {
   /**
    * Constructs a SelectionBase object.
    */
-  public function __construct($field, $instance, EntityInterface $entity = NULL) {
-    $this->field = $field;
-    $this->instance = $instance;
+  public function __construct(FieldDefinitionInterface $field_definition, EntityInterface $entity = NULL) {
+    $this->fieldDefinition = $field_definition;
     $this->entity = $entity;
   }
 
@@ -165,7 +158,7 @@ public static function settingsForm(&$field, &$instance) {
    * Implements SelectionInterface::getReferencableEntities().
    */
   public function getReferencableEntities($match = NULL, $match_operator = 'CONTAINS', $limit = 0) {
-    $target_type = $this->field['settings']['target_type'];
+    $target_type = $this->fieldDefinition->getSetting('target_type');
 
     $query = $this->buildEntityQuery($match, $match_operator);
     if ($limit > 0) {
@@ -204,7 +197,7 @@ public function countReferencableEntities($match = NULL, $match_operator = 'CONT
   public function validateReferencableEntities(array $ids) {
     $result = array();
     if ($ids) {
-      $target_type = $this->field['settings']['target_type'];
+      $target_type = $this->fieldDefinition->getSetting('target_type');
       $entity_info = entity_get_info($target_type);
       $query = $this->buildEntityQuery();
       $result = $query
@@ -264,7 +257,7 @@ public function validateAutocompleteInput($input, &$element, &$form_state, $form
    *   it.
    */
   public function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
-    $target_type = $this->field['settings']['target_type'];
+    $target_type = $this->fieldDefinition->getSetting('target_type');
     $entity_info = entity_get_info($target_type);
 
     $query = \Drupal::entityQuery($target_type);
@@ -277,17 +270,18 @@ public function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
     }
 
     // Add entity-access tag.
-    $query->addTag($this->field['settings']['target_type'] . '_access');
+    $query->addTag($this->fieldDefinition->getSetting('target_type') . '_access');
 
     // Add the Selection handler for
     // entity_reference_query_entity_reference_alter().
     $query->addTag('entity_reference');
-    $query->addMetaData('field', $this->field);
+    $query->addMetaData('field_definition', $this->fieldDefinition);
     $query->addMetaData('entity_reference_selection_handler', $this);
 
     // Add the sort option.
-    if (!empty($this->instance['settings']['handler_settings']['sort'])) {
-      $sort_settings = $this->instance['settings']['handler_settings']['sort'];
+    $handler_settings = $this->fieldDefinition->getSetting('handler_settings');
+    if (!empty($handler_settings['sort'])) {
+      $sort_settings = $handler_settings['sort'];
       if ($sort_settings['field'] != '_none') {
         $query->sort($sort_settings['field'], $sort_settings['direction']);
       }
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/formatter/EntityReferenceEntityFormatter.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/formatter/EntityReferenceEntityFormatter.php
index 647de08..e54bf32 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/formatter/EntityReferenceEntityFormatter.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/formatter/EntityReferenceEntityFormatter.php
@@ -36,7 +36,7 @@ class EntityReferenceEntityFormatter extends EntityReferenceFormatterBase {
    * {@inheritdoc}
    */
   public function settingsForm(array $form, array &$form_state) {
-    $view_modes = entity_get_view_modes($this->field['settings']['target_type']);
+    $view_modes = entity_get_view_modes($this->getFieldSetting('target_type'));
     $options = array();
     foreach ($view_modes as $view_mode => $view_mode_settings) {
       $options[$view_mode] = $view_mode_settings['label'];
@@ -65,7 +65,7 @@ public function settingsForm(array $form, array &$form_state) {
   public function settingsSummary() {
     $summary = array();
 
-    $view_modes = entity_get_view_modes($this->field['settings']['target_type']);
+    $view_modes = entity_get_view_modes($this->getFieldSetting('target_type'));
     $view_mode = $this->getSetting('view_mode');
     $summary[] = t('Rendered as @mode', array('@mode' => isset($view_modes[$view_mode]['label']) ? $view_modes[$view_mode]['label'] : $view_mode));
     $summary[] = $this->getSetting('links') ? t('Display links') : t('Do not display links');
@@ -83,7 +83,7 @@ public function viewElements(EntityInterface $entity, $langcode, array $items) {
     $view_mode = $this->getSetting('view_mode');
     $links = $this->getSetting('links');
 
-    $target_type = $this->field['settings']['target_type'];
+    $target_type = $this->getFieldSetting('target_type');
 
     $elements = array();
 
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteTagsWidget.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteTagsWidget.php
index a88f2ea..a7e0fba 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteTagsWidget.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteTagsWidget.php
@@ -34,14 +34,14 @@
 class AutocompleteTagsWidget extends AutocompleteWidgetBase {
 
   /**
-   * Overrides \Drupal\entity_reference\Plugin\field\widget\AutocompleteWidgetBase::elementValidate()
+   * {@inheritdoc}
    */
   public function elementValidate($element, &$form_state, $form) {
     $value = array();
     // If a value was entered into the autocomplete.
-    $handler = entity_reference_get_selection_handler($this->field, $this->instance);
-    $bundles = entity_get_bundles($this->field['settings']['target_type']);
-    $auto_create = isset($this->instance['settings']['handler_settings']['auto_create']) ? $this->instance['settings']['handler_settings']['auto_create'] : FALSE;
+    $handler = entity_reference_get_selection_handler($this->fieldDefinition);
+    $bundles = entity_get_bundles($this->getFieldSetting('target_type'));
+    $auto_create = $this->getSelectionHandlerSetting('auto_create');
 
     if (!empty($element['#value'])) {
       $entities = drupal_explode_tags($element['#value']);
@@ -62,7 +62,7 @@ public function elementValidate($element, &$form_state, $form) {
         if ($match) {
           $value[] = array('target_id' => $match);
         }
-        elseif ($auto_create && (count($this->instance['settings']['handler_settings']['target_bundles']) == 1 || count($bundles) == 1)) {
+        elseif ($auto_create && (count($this->getSelectionHandlerSetting('target_bundles')) == 1 || count($bundles) == 1)) {
           // Auto-create item. see entity_reference_field_presave().
           $value[] = array('target_id' => 'auto_create', 'label' => $entity);
         }
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteWidget.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteWidget.php
index 57c4b7b..98fc52a 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteWidget.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteWidget.php
@@ -38,7 +38,7 @@
 class AutocompleteWidget extends AutocompleteWidgetBase {
 
   /**
-   * Overrides \Drupal\entity_reference\Plugin\field\widget\AutocompleteWidgetBase::formElement().
+   * {@inheritdoc}
    */
   public function formElement(array $items, $delta, array $element, $langcode, array &$form, array &$form_state) {
     // We let the Field API handles multiple values for us, only take care of
@@ -54,10 +54,10 @@ public function formElement(array $items, $delta, array $element, $langcode, arr
   }
 
   /**
-   * Overrides \Drupal\entity_reference\Plugin\field\widget\AutocompleteWidgetBase::elementValidate()
+   * {@inheritdoc}
    */
   public function elementValidate($element, &$form_state, $form) {
-    $auto_create = isset($this->instance['settings']['handler_settings']['auto_create']) ? $this->instance['settings']['handler_settings']['auto_create'] : FALSE;
+    $auto_create = $this->getSelectionHandlerSetting('auto_create');
 
     // If a value was entered into the autocomplete.
     $value = '';
@@ -69,11 +69,11 @@ public function elementValidate($element, &$form_state, $form) {
       else {
         // Try to get a match from the input string when the user didn't use the
         // autocomplete but filled in a value manually.
-        $handler = entity_reference_get_selection_handler($this->field, $this->instance);
+        $handler = entity_reference_get_selection_handler($this->fieldDefinition);
         $value = $handler->validateAutocompleteInput($element['#value'], $element, $form_state, $form, !$auto_create);
       }
 
-      if (!$value && $auto_create && (count($this->instance['settings']['handler_settings']['target_bundles']) == 1)) {
+      if (!$value && $auto_create && (count($this->getSelectionHandlerSetting('target_bundles')) == 1)) {
         // Auto-create item. see entity_reference_field_presave().
         $value = array(
           'target_id' => 'auto_create',
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteWidgetBase.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteWidgetBase.php
index 6a8df6f..c7edfed 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteWidgetBase.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteWidgetBase.php
@@ -17,7 +17,7 @@
 abstract class AutocompleteWidgetBase extends WidgetBase {
 
   /**
-   * Overrides \Drupal\field\Plugin\Type\Widget\WidgetBase::settingsForm().
+   * {@inheritdoc}
    */
   public function settingsForm(array $form, array &$form_state) {
     $element['match_operator'] = array(
@@ -50,24 +50,14 @@ public function settingsForm(array $form, array &$form_state) {
   }
 
   /**
-   * Implements \Drupal\field\Plugin\Type\Widget\WidgetInterface::formElement().
+   * {@inheritdoc}
    */
   public function formElement(array $items, $delta, array $element, $langcode, array &$form, array &$form_state) {
-    $instance = $this->instance;
-    $field = $this->field;
-    $entity = isset($element['#entity']) ? $element['#entity'] : NULL;
+    $entity = $element['#entity'];
 
     // Prepare the autocomplete path.
     $autocomplete_path = $this->getSetting('autocomplete_path');
-    $autocomplete_path .= '/' . $field['field_name'] . '/' . $instance['entity_type'] . '/' . $instance['bundle'] . '/';
-
-    // Use <NULL> as a placeholder in the URL when we don't have an entity.
-    // Most web servers collapse two consecutive slashes.
-    $id = 'NULL';
-    if ($entity && $entity_id = $entity->id()) {
-      $id = $entity_id;
-    }
-    $autocomplete_path .= $id;
+    $autocomplete_path .= '/' . $this->fieldDefinition->getName() . '/' . $entity->entityType() . '/' . $entity->bundle() . '/' . $entity->id();
 
     $element += array(
       '#type' => 'textfield',
@@ -83,7 +73,7 @@ public function formElement(array $items, $delta, array $element, $langcode, arr
   }
 
   /**
-   * Overrides \Drupal\field\Plugin\Type\Widget\WidgetBase::errorElement().
+   * {@inheritdoc}
    */
   public function errorElement(array $element, array $error, array $form, array &$form_state) {
     return $element['target_id'];
@@ -107,7 +97,7 @@ protected function getLabels(array $items) {
     }
 
     // Load those entities and loop through them to extract their labels.
-    $entities = entity_load_multiple($this->field['settings']['target_type'], $entity_ids);
+    $entities = entity_load_multiple($this->getFieldSetting('target_type'), $entity_ids);
 
     foreach ($entities as $entity_id => $entity_item) {
       $label = $entity_item->label();
@@ -120,4 +110,12 @@ protected function getLabels(array $items) {
     }
     return $entity_labels;
   }
+
+  /**
+   * Returns the value of a setting for the entity reference selection handler.
+   */
+  protected function getSelectionHandlerSetting($setting_name) {
+    $settings = $this->getFieldSetting('handler_settings');
+    return isset($settings[$setting_name]) ? $settings[$setting_name] : NULL;
+  }
 }
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionAccessTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionAccessTest.php
index 9ab172b..19bf2e3 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionAccessTest.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionAccessTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\entity_reference\Tests;
 
+use Drupal\Core\Entity\Field\FieldDefinitionInterface;
 use Drupal\Core\Language\Language;
 use Drupal\simpletest\WebTestBase;
 
@@ -32,8 +33,8 @@ function setUp() {
     $this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article'));
   }
 
-  protected function assertReferencable($field, $instance, $tests, $handler_name) {
-    $handler = entity_reference_get_selection_handler($field, $instance);
+  protected function assertReferencable(FieldDefinitionInterface $field_definition, $tests, $handler_name) {
+    $handler = entity_reference_get_selection_handler($field_definition);
 
     foreach ($tests as $test) {
       foreach ($test['arguments'] as $arguments) {
@@ -58,19 +59,15 @@ protected function assertReferencable($field, $instance, $tests, $handler_name)
    * Test the node-specific overrides of the entity handler.
    */
   public function testNodeHandler() {
-    // Build a fake field instance.
-    $field = array(
+    // Build a fake field definition.
+    $field_definition = array(
       'translatable' => FALSE,
       'entity_types' => array(),
-      'settings' => array(
-        'target_type' => 'node',
-      ),
       'field_name' => 'test_field',
       'type' => 'entity_reference',
       'cardinality' => '1',
-    );
-    $instance = array(
       'settings' => array(
+        'target_type' => 'node',
         'handler' => 'default',
         'handler_settings' => array(
           'target_bundles' => array(),
@@ -160,7 +157,7 @@ public function testNodeHandler() {
         'result' => array(),
       ),
     );
-    $this->assertReferencable($field, $instance, $referencable_tests, 'Node handler');
+    $this->assertReferencable($field_definition, $referencable_tests, 'Node handler');
 
     // Test as an admin.
     $admin_user = $this->drupalCreateUser(array('access content', 'bypass node access'));
@@ -189,26 +186,22 @@ public function testNodeHandler() {
         ),
       ),
     );
-    $this->assertReferencable($field, $instance, $referencable_tests, 'Node handler (admin)');
+    $this->assertReferencable($field_definition, $referencable_tests, 'Node handler (admin)');
   }
 
   /**
    * Test the user-specific overrides of the entity handler.
    */
   public function testUserHandler() {
-    // Build a fake field instance.
-    $field = array(
+    // Build a fake field definition.
+    $field_definition = array(
       'translatable' => FALSE,
       'entity_types' => array(),
-      'settings' => array(
-        'target_type' => 'user',
-      ),
       'field_name' => 'test_field',
       'type' => 'entity_reference',
       'cardinality' => '1',
-    );
-    $instance = array(
       'settings' => array(
+        'target_type' => 'user',
         'handler' => 'default',
         'handler_settings' => array(
           'target_bundles' => array(),
@@ -290,7 +283,7 @@ public function testUserHandler() {
         'result' => array(),
       ),
     );
-    $this->assertReferencable($field, $instance, $referencable_tests, 'User handler');
+    $this->assertReferencable($field_definition, $referencable_tests, 'User handler');
 
     $GLOBALS['user'] = $users['admin'];
     $referencable_tests = array(
@@ -329,26 +322,22 @@ public function testUserHandler() {
         ),
       ),
     );
-    $this->assertReferencable($field, $instance, $referencable_tests, 'User handler (admin)');
+    $this->assertReferencable($field_definition, $referencable_tests, 'User handler (admin)');
   }
 
   /**
    * Test the comment-specific overrides of the entity handler.
    */
   public function testCommentHandler() {
-    // Build a fake field instance.
-    $field = array(
+    // Build a fake field definition.
+    $field_definition = array(
       'translatable' => FALSE,
       'entity_types' => array(),
-      'settings' => array(
-        'target_type' => 'comment',
-      ),
       'field_name' => 'test_field',
       'type' => 'entity_reference',
       'cardinality' => '1',
-    );
-    $instance = array(
       'settings' => array(
+        'target_type' => 'comment',
         'handler' => 'default',
         'handler_settings' => array(
           'target_bundles' => array(),
@@ -454,7 +443,7 @@ public function testCommentHandler() {
         'result' => array(),
       ),
     );
-    $this->assertReferencable($field, $instance, $referencable_tests, 'Comment handler');
+    $this->assertReferencable($field_definition, $referencable_tests, 'Comment handler');
 
     // Test as a comment admin.
     $admin_user = $this->drupalCreateUser(array('access content', 'access comments', 'administer comments'));
@@ -472,7 +461,7 @@ public function testCommentHandler() {
         ),
       ),
     );
-    $this->assertReferencable($field, $instance, $referencable_tests, 'Comment handler (comment admin)');
+    $this->assertReferencable($field_definition, $referencable_tests, 'Comment handler (comment admin)');
 
     // Test as a node and comment admin.
     $admin_user = $this->drupalCreateUser(array('access content', 'access comments', 'administer comments', 'bypass node access'));
@@ -491,6 +480,6 @@ public function testCommentHandler() {
         ),
       ),
     );
-    $this->assertReferencable($field, $instance, $referencable_tests, 'Comment handler (comment + node admin)');
+    $this->assertReferencable($field_definition, $referencable_tests, 'Comment handler (comment + node admin)');
   }
 }
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionSortTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionSortTest.php
index d3245e0..a20c3b7 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionSortTest.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionSortTest.php
@@ -54,20 +54,15 @@ public function testSort() {
     field_create_instance($instance_info);
 
 
-    // Build a fake field instance.
-    $field = array(
+    // Build a fake field definition.
+    $field_definition = array(
       'translatable' => FALSE,
       'entity_types' => array(),
-      'settings' => array(
-        'target_type' => 'node',
-      ),
       'field_name' => 'test_field',
       'type' => 'entity_reference',
       'cardinality' => 1,
-    );
-
-    $instance = array(
       'settings' => array(
+        'target_type' => 'node',
         'handler' => 'default',
         'handler_settings' => array(
           'target_bundles' => array(),
@@ -119,7 +114,7 @@ public function testSort() {
     $normal_user = $this->drupalCreateUser(array('access content'));
     $GLOBALS['user'] = $normal_user;
 
-    $handler = entity_reference_get_selection_handler($field, $instance);
+    $handler = entity_reference_get_selection_handler($field_definition);
 
     // Not only assert the result, but make sure the keys are sorted as
     // expected.
@@ -131,11 +126,11 @@ public function testSort() {
     $this->assertIdentical($result['article'], $expected_result, 'Query sorted by field returned expected values.');
 
     // Assert sort by property.
-    $instance['settings']['handler_settings']['sort'] = array(
+    $field_definition['settings']['handler_settings']['sort'] = array(
       'field' => 'nid',
       'direction' => 'ASC',
     );
-    $handler = entity_reference_get_selection_handler($field, $instance);
+    $handler = entity_reference_get_selection_handler($field_definition);
     $result = $handler->getReferencableEntities();
     $expected_result = array(
       $nodes['published1']->nid => $node_labels['published1'],
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/Views/SelectionTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/Views/SelectionTest.php
index 6998209..e9831d9 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/Views/SelectionTest.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/Views/SelectionTest.php
@@ -39,19 +39,15 @@ public function testSelectionHandler() {
       $nodes[$node->type][$node->nid] = $node->label();
     }
 
-    // Build a fake field instance.
-    $field = array(
+    // Build a fake field definition.
+    $field_definition = array(
       'translatable' => FALSE,
       'entity_types' => array(),
-      'settings' => array(
-        'target_type' => 'node',
-      ),
       'field_name' => 'test_field',
       'type' => 'entity_reference',
       'cardinality' => '1',
-    );
-    $instance = array(
       'settings' => array(
+        'target_type' => 'node',
         'handler' => 'views',
         'handler_settings' => array(
           'target_bundles' => array(),
@@ -65,7 +61,7 @@ public function testSelectionHandler() {
     );
 
     // Get values from selection handler.
-    $handler = entity_reference_get_selection_handler($field, $instance);
+    $handler = entity_reference_get_selection_handler($field_definition);
     $result = $handler->getReferencableEntities();
 
     $success = FALSE;
diff --git a/core/modules/field/field.api.php b/core/modules/field/field.api.php
index 75a99df..2aa4cb2 100644
--- a/core/modules/field/field.api.php
+++ b/core/modules/field/field.api.php
@@ -728,8 +728,9 @@ function hook_field_widget_info_alter(array &$info) {
  *   arguments received by hook_field_widget_form():
  *   - form: The form structure to which widgets are being attached. This may be
  *     a full form structure, or a sub-element of a larger form.
- *   - field: The field structure.
- *   - instance: The field instance structure.
+ *   - field_definition: The field definition.
+ *   - entity_type: The entity type.
+ *   - bundle: The entity bundle.
  *   - langcode: The language associated with $items.
  *   - items: Array of default values for this field.
  *   - delta: The order of this item in the array of subelements (0, 1, 2, etc).
@@ -763,9 +764,9 @@ function hook_field_widget_form_alter(&$element, &$form_state, $context) {
  *   arguments received by hook_field_widget_form():
  *   - "form": The form structure where widgets are being attached to. This
  *     might be a full form structure, or a sub-element of a larger form.
- *   - "field": The field structure.
- *   - "instance": The field instance structure.
- *   - "langcode": The language associated with $items.
+ *   - "field_definition": The field definition.
+ *   - "entity_type": The entity type.
+ *   - "bundle": The entity bundle.
  *   - "items": Array of default values for this field.
  *   - "delta": The order of this item in the array of subelements (0, 1, 2,
  *     etc).
@@ -2076,7 +2077,7 @@ function hook_field_storage_purge(\Drupal\Core\Entity\EntityInterface $entity, $
  *
  * @param $op
  *   The operation to be performed. Possible values: 'edit', 'view'.
- * @param $field
+ * @param \Drupal\field\FieldInterface $field
  *   The field on which the operation is to be performed.
  * @param $entity_type
  *   The type of $entity; for example, 'node' or 'user'.
@@ -2088,7 +2089,7 @@ function hook_field_storage_purge(\Drupal\Core\Entity\EntityInterface $entity, $
  * @return
  *   TRUE if the operation is allowed, and FALSE if the operation is denied.
  */
-function hook_field_access($op, $field, $entity_type, $entity, $account) {
+function hook_field_access($op, \Drupal\field\FieldInterface $field, $entity_type, $entity, $account) {
   if ($field['field_name'] == 'field_of_interest' && $op == 'edit') {
     return user_access('edit field of interest', $account);
   }
diff --git a/core/modules/field/field.attach.inc b/core/modules/field/field.attach.inc
index baa7ff4..6a6faa3 100644
--- a/core/modules/field/field.attach.inc
+++ b/core/modules/field/field.attach.inc
@@ -779,7 +779,6 @@ function _field_invoke_widget_target($form_display) {
  *         '#default_value' => The field value for delta 0,
  *         '#required' => Whether the widget should be marked required,
  *         '#delta' => 0,
- *         '#columns' => The array of field columns,
  *         // The remaining elements in the sub-array depend on the widget.
  *         '#type' => The type of the widget,
  *         ...
@@ -791,7 +790,6 @@ function _field_invoke_widget_target($form_display) {
  *       // Only for multiple widgets:
  *       '#entity_type' => The name of the entity type,
  *       '#bundle' => $instance['bundle'],
- *       '#columns'  => array_keys($field['columns']),
  *       // The remaining elements in the sub-array depend on the widget.
  *       '#type' => The type of the widget,
  *       ...
diff --git a/core/modules/field/field.form.inc b/core/modules/field/field.form.inc
index 203a112..2100332 100644
--- a/core/modules/field/field.form.inc
+++ b/core/modules/field/field.form.inc
@@ -158,8 +158,8 @@ function field_add_more_js($form, $form_state) {
 
   $field_state = field_form_get_state($parents, $field_name, $langcode, $form_state);
 
-  $field = $field_state['field'];
-  if ($field['cardinality'] != FIELD_CARDINALITY_UNLIMITED) {
+  $field_definition = $field_state['field_definition'];
+  if ($field_definition['cardinality'] != FIELD_CARDINALITY_UNLIMITED) {
     return;
   }
 
@@ -260,48 +260,21 @@ function _field_form_state_parents($parents, $field_name, $langcode) {
  * Retrieves the field definition for a widget's helper callbacks.
  *
  * Widget helper element callbacks (such as #process, #element_validate,
- * #value_callback, ...) should use field_widget_field() and
- * field_widget_instance() instead of field_info_field() and
- * field_info_instance() when they need to access field or instance properties.
- * See hook_field_widget_form() for more details.
+ * #value_callback, ...) should use field_widget_field_definition() instead of
+ * field_info_field() and field_info_instance() when they need to access field
+ * or instance properties. See hook_field_widget_form() for more details.
  *
  * @param $element
  *   The structured array for the widget.
  * @param $form_state
  *   The form state.
  *
- * @return
- *   The $field definition array for the current widget.
- *
- * @see field_widget_instance()
- * @see hook_field_widget_form()
- */
-function field_widget_field($element, $form_state) {
-  $field_state = field_form_get_state($element['#field_parents'], $element['#field_name'], $element['#language'], $form_state);
-  return $field_state['field'];
-}
-
-/**
- * Retrieves the instance definition array for a widget's helper callbacks.
- *
- * Widgets helper element callbacks (such as #process, #element_validate,
- * #value_callback, ...) should use field_widget_field() and
- * field_widget_instance() instead of field_info_field() and
- * field_info_instance() when they need to access field or instance properties.
- * See hook_field_widget_form() for more details.
- *
- * @param $element
- *   The structured array for the widget.
- * @param $form_state
- *   The form state.
- *
- * @return
- *   The $instance definition array for the current widget.
+ * @return array
+ *   The field definition array for the current widget.
  *
- * @see field_widget_field()
  * @see hook_field_widget_form()
  */
-function field_widget_instance($element, $form_state) {
+function field_widget_field_definition($element, $form_state) {
   $field_state = field_form_get_state($element['#field_parents'], $element['#field_name'], $element['#language'], $form_state);
-  return $field_state['instance'];
+  return $field_state['field_definition'];
 }
diff --git a/core/modules/field/field.module b/core/modules/field/field.module
index 5b762b5..1ce7ee1 100644
--- a/core/modules/field/field.module
+++ b/core/modules/field/field.module
@@ -7,6 +7,7 @@
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Language\Language;
 use Drupal\Core\Template\Attribute;
+use Drupal\field\FieldInterface;
 
 /*
  * Load all public Field API functions. Drupal currently has no
@@ -805,7 +806,7 @@ function field_view_field(EntityInterface $entity, $field_name, $display_options
     $formatter_manager = drupal_container()->get('plugin.manager.field.formatter');
     $display_options = $formatter_manager->prepareConfiguration($field['type'], $display_options);
     $formatter = $formatter_manager->getInstance(array(
-      'instance' => $instance,
+      'field_definition' => $instance,
       'view_mode' => $view_mode,
       'prepare' => FALSE,
       'configuration' => $display_options,
@@ -924,9 +925,8 @@ function field_has_data($field) {
  *   The operation to be performed. Possible values:
  *   - edit
  *   - view
- * @param array $field
- *   The full field structure array for the field on which the operation is to
- *   be performed. See field_info_field().
+ * @param \Drupal\field\FieldInterface $field
+ *   The field on which the operation is to be performed.
  * @param $entity_type
  *   The type of $entity; for example, 'node' or 'user'.
  * @param $entity
@@ -937,7 +937,7 @@ function field_has_data($field) {
  * @return
  *   TRUE if the operation is allowed; FALSE if the operation is denied.
  */
-function field_access($op, $field, $entity_type, $entity = NULL, $account = NULL) {
+function field_access($op, FieldInterface $field, $entity_type, $entity = NULL, $account = NULL) {
   global $user;
 
   if (!isset($account)) {
diff --git a/core/modules/field/lib/Drupal/field/FieldInstanceInterface.php b/core/modules/field/lib/Drupal/field/FieldInstanceInterface.php
index c6b8ad6..d2a0b85 100644
--- a/core/modules/field/lib/Drupal/field/FieldInstanceInterface.php
+++ b/core/modules/field/lib/Drupal/field/FieldInstanceInterface.php
@@ -8,11 +8,12 @@
 namespace Drupal\field;
 
 use Drupal\Core\Config\Entity\ConfigEntityInterface;
+use Drupal\Core\Entity\Field\FieldDefinitionInterface;
 
 /**
  * Provides an interface defining a field instance entity.
  */
-interface FieldInstanceInterface extends ConfigEntityInterface, \ArrayAccess, \Serializable {
+interface FieldInstanceInterface extends ConfigEntityInterface, FieldDefinitionInterface, \ArrayAccess, \Serializable {
 
   /**
    * Returns the field entity for this instance.
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/FieldInstance.php b/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/FieldInstance.php
index 66d8cbf..8507795 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/FieldInstance.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/FieldInstance.php
@@ -420,6 +420,78 @@ public function getField() {
   /**
    * {@inheritdoc}
    */
+  public function getName() {
+    return $this->field->id;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getType() {
+    return $this->field->type;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getSettings() {
+    return $this->settings + $this->field->settings;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getSetting($setting_name) {
+    $settings = $this->getSettings();
+    return isset($settings[$setting_name]) ? $settings[$setting_name] : NULL;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPropertyNames() {
+    $schema = $this->field->getSchema();
+    return array_keys($schema['columns']);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isTranslatable() {
+    return $this->field->translatable;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getLabel() {
+    return $this->label();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDescription() {
+    return $this->description;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCardinality() {
+    return $this->field->cardinality;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isRequired() {
+    return $this->required;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function allowBundleRename() {
     $this->bundle_rename_allowed = TRUE;
   }
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterBase.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterBase.php
index 6b316ae..99843e1 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterBase.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterBase.php
@@ -2,14 +2,15 @@
 
 /**
  * @file
- * Definition of Drupal\field\Plugin\Type\Formatter\FormatterBase.
+ * Contains \Drupal\field\Plugin\Type\Formatter\FormatterBase.
  */
 
 namespace Drupal\field\Plugin\Type\Formatter;
 
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\Field\FieldDefinitionInterface;
+use Drupal\field\FieldInstanceInterface;
 use Drupal\field\Plugin\PluginSettingsBase;
-use Drupal\field\Plugin\Core\Entity\FieldInstance;
 
 /**
  * Base class for 'Field formatter' plugin implementations.
@@ -19,16 +20,9 @@
   /**
    * The field definition.
    *
-   * @var array
-   */
-  protected $field;
-
-  /**
-   * The field instance definition.
-   *
-   * @var \Drupal\field\Plugin\Core\Entity\FieldInstance
+   * @var \Drupal\Core\Entity\Field\FieldDefinitionInterface
    */
-  protected $instance;
+  protected $fieldDefinition;
 
   /**
    * The formatter settings.
@@ -58,8 +52,8 @@
    *   The plugin_id for the formatter.
    * @param array $plugin_definition
    *   The plugin implementation definition.
-   * @param \Drupal\field\Plugin\Core\Entity\FieldInstance $instance
-   *   The field instance to which the formatter is associated.
+   * @param \Drupal\Core\Entity\Field\FieldDefinitionInterface $field_definition
+   *   The definition of the field to which the formatter is associated.
    * @param array $settings
    *   The formatter settings.
    * @param string $label
@@ -67,11 +61,10 @@
    * @param string $view_mode
    *   The view mode.
    */
-  public function __construct($plugin_id, array $plugin_definition, $instance, array $settings, $label, $view_mode) {
+  public function __construct($plugin_id, array $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode) {
     parent::__construct(array(), $plugin_id, $plugin_definition);
 
-    $this->instance = $instance;
-    $this->field = field_info_field($instance['field_name']);
+    $this->fieldDefinition = $field_definition;
     $this->settings = $settings;
     $this->label = $label;
     $this->viewMode = $view_mode;
@@ -81,9 +74,6 @@ public function __construct($plugin_id, array $plugin_definition, $instance, arr
    * {@inheritdoc}
    */
   public function view(EntityInterface $entity, $langcode, array $items) {
-    $field = $this->field;
-    $instance = $this->instance;
-
     $addition = array();
 
     $elements = $this->viewElements($entity, $langcode, $items);
@@ -91,14 +81,14 @@ public function view(EntityInterface $entity, $langcode, array $items) {
       $entity_type = $entity->entityType();
       $info = array(
         '#theme' => 'field',
-        '#title' => $instance['label'],
-        '#access' => field_access('view', $field, $entity->entityType(), $entity),
+        '#title' => $this->fieldDefinition->getLabel(),
+        '#access' => $this->checkFieldAccess('view', $entity),
         '#label_display' => $this->label,
         '#view_mode' => $this->viewMode,
         '#language' => $langcode,
-        '#field_name' => $field['field_name'],
-        '#field_type' => $field['type'],
-        '#field_translatable' => $field['translatable'],
+        '#field_name' => $this->fieldDefinition->getName(),
+        '#field_type' => $this->fieldDefinition->getType(),
+        '#field_translatable' => $this->fieldDefinition->isTranslatable(),
         '#entity_type' => $entity_type,
         '#bundle' => $entity->bundle(),
         '#object' => $entity,
@@ -106,7 +96,7 @@ public function view(EntityInterface $entity, $langcode, array $items) {
         '#formatter' => $this->getPluginId(),
       );
 
-      $addition[$field['field_name']] = array_merge($info, $elements);
+      $addition[$this->fieldDefinition->getName()] = array_merge($info, $elements);
     }
 
     return $addition;
@@ -131,4 +121,26 @@ public function settingsSummary() {
    */
   public function prepareView(array $entities, $langcode, array &$items) { }
 
+  /**
+   * Returns whether the currently logged in user has access to the field.
+   *
+   * @todo Remove this once Field API access is unified with entity field
+   *   access: http://drupal.org/node/1994140.
+   */
+  protected function checkFieldAccess($op, $entity) {
+    if ($this->fieldDefinition instanceof FieldInstanceInterface) {
+      $field = $this->fieldDefinition->getField();
+      return field_access($op, $field, $entity->entityType(), $entity);
+    }
+    else {
+      return FALSE;
+    }
+  }
+
+  /**
+   * Returns the value of a field setting.
+   */
+  protected function getFieldSetting($setting_name) {
+    return $this->fieldDefinition->getSetting($setting_name);
+  }
 }
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterFactory.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterFactory.php
index 0df5b97..1e41001 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterFactory.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterFactory.php
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Definition of Drupal\field\Plugin\Type\Formatter\FormatterFactory.
+ * Contains \Drupal\field\Plugin\Type\Formatter\FormatterFactory.
  */
 
 namespace Drupal\field\Plugin\Type\Formatter;
@@ -15,11 +15,11 @@
 class FormatterFactory extends DefaultFactory {
 
   /**
-   * Overrides Drupal\Component\Plugin\Factory\DefaultFactory::createInstance().
+   * {@inheritdoc}
    */
   public function createInstance($plugin_id, array $configuration) {
     $plugin_definition = $this->discovery->getDefinition($plugin_id);
     $plugin_class = static::getPluginClass($plugin_id, $plugin_definition);
-    return new $plugin_class($plugin_id, $plugin_definition, $configuration['instance'], $configuration['settings'], $configuration['label'], $configuration['view_mode']);
+    return new $plugin_class($plugin_id, $plugin_definition, $configuration['field_definition'], $configuration['settings'], $configuration['label'], $configuration['view_mode']);
   }
 }
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php
index 2260610..5f33353 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php
@@ -48,7 +48,7 @@ public function __construct(\Traversable $namespaces) {
    *
    * @param array $options
    *   An array with the following key/value pairs:
-   *   - instance: (FieldInstance) The field instance.
+   *   - field_definition: (FieldDefinitionInterface) The field definition.
    *   - view_mode: (string) The view mode.
    *   - prepare: (bool, optional) Whether default values should get merged in
    *     the 'configuration' array. Defaults to TRUE.
@@ -70,12 +70,12 @@ public function __construct(\Traversable $namespaces) {
    */
   public function getInstance(array $options) {
     $configuration = $options['configuration'];
-    $instance = $options['instance'];
-    $field = field_info_field($instance['field_name']);
+    $field_definition = $options['field_definition'];
+    $field_type = $field_definition->getType();
 
     // Fill in default configuration if needed.
     if (!isset($options['prepare']) || $options['prepare'] == TRUE) {
-      $configuration = $this->prepareConfiguration($field['type'], $configuration);
+      $configuration = $this->prepareConfiguration($field_type, $configuration);
     }
 
     $plugin_id = $configuration['type'];
@@ -84,14 +84,14 @@ public function getInstance(array $options) {
     // - $type_info doesn't exist (the widget type is unknown),
     // - the field type is not allowed for the widget.
     $definition = $this->getDefinition($configuration['type']);
-    if (!isset($definition['class']) || !in_array($field['type'], $definition['field_types'])) {
+    if (!isset($definition['class']) || !in_array($field_type, $definition['field_types'])) {
       // Grab the default widget for the field type.
-      $field_type_definition = field_info_field_types($field['type']);
+      $field_type_definition = field_info_field_types($field_type);
       $plugin_id = $field_type_definition['default_formatter'];
     }
 
     $configuration += array(
-      'instance' => $instance,
+      'field_definition' => $field_definition,
       'view_mode' => $options['view_mode'],
     );
     return $this->createInstance($plugin_id, $configuration);
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php
index 89c212a..6d7a2ff 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php
@@ -2,15 +2,16 @@
 
 /**
  * @file
- * Definition of Drupal\field\Plugin\Type\Widget\WidgetBase.
+ * Contains \Drupal\field\Plugin\Type\Widget\WidgetBase.
  */
 
 namespace Drupal\field\Plugin\Type\Widget;
 
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\Field\FieldDefinitionInterface;
+use Drupal\field\FieldInstanceInterface;
 use Drupal\field\Plugin\PluginSettingsBase;
-use Drupal\field\Plugin\Core\Entity\FieldInstance;
 
 /**
  * Base class for 'Field widget' plugin implementations.
@@ -20,16 +21,9 @@
   /**
    * The field definition.
    *
-   * @var array
-   */
-  protected $field;
-
-  /**
-   * The field instance definition.
-   *
-   * @var \Drupal\field\Plugin\Core\Entity\FieldInstance
+   * @var \Drupal\Core\Entity\Field\FieldDefinitionInterface
    */
-  protected $instance;
+  protected $fieldDefinition;
 
   /**
    * The widget settings.
@@ -45,26 +39,23 @@
    *   The plugin_id for the widget.
    * @param array $plugin_definition
    *   The plugin implementation definition.
-   * @param \Drupal\field\Plugin\Core\Entity\FieldInstance $instance
-   *   The field instance to which the widget is associated.
+   * @param \Drupal\Core\Entity\Field\FieldDefinitionInterface $field_definition
+   *   The definition of the field to which the widget is associated.
    * @param array $settings
    *   The widget settings.
    */
-  public function __construct($plugin_id, array $plugin_definition, FieldInstance $instance, array $settings) {
+  public function __construct($plugin_id, array $plugin_definition, array $field_definition, array $settings) {
     parent::__construct(array(), $plugin_id, $plugin_definition);
 
-    $this->instance = $instance;
-    $this->field = field_info_field($instance['field_name']);
+    $this->fieldDefinition = $field_definition;
     $this->settings = $settings;
   }
 
   /**
-   * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::form().
+   * {@inheritdoc}
    */
   public function form(EntityInterface $entity, $langcode, array $items, array &$form, array &$form_state, $get_delta = NULL) {
-    $field = $this->field;
-    $instance = $this->instance;
-    $field_name = $field['field_name'];
+    $field_name = $this->fieldDefinition->getName();
 
     $parents = $form['#parents'];
 
@@ -75,11 +66,10 @@ public function form(EntityInterface $entity, $langcode, array $items, array &$f
     // Store field information in $form_state.
     if (!field_form_get_state($parents, $field_name, $langcode, $form_state)) {
       $field_state = array(
-          'field' => $field,
-          'instance' => $instance,
-          'items_count' => count($items),
-          'array_parents' => array(),
-          'errors' => array(),
+        'field_definition' => $this->fieldDefinition,
+        'items_count' => count($items),
+        'array_parents' => array(),
+        'errors' => array(),
       );
       field_form_set_state($parents, $field_name, $langcode, $form_state, $field_state);
     }
@@ -94,8 +84,8 @@ public function form(EntityInterface $entity, $langcode, array $items, array &$f
     if (isset($get_delta) || $definition['multiple_values']) {
       $delta = isset($get_delta) ? $get_delta : 0;
       $element = array(
-        '#title' => check_plain($instance['label']),
-        '#description' => field_filter_xss(\Drupal::token()->replace($instance['description'])),
+        '#title' => check_plain($this->fieldDefinition->getLabel()),
+        '#description' => field_filter_xss(\Drupal::token()->replace($this->fieldDefinition->getDescription())),
       );
       $element = $this->formSingleElement($entity, $items, $delta, $langcode, $element, $form, $form_state);
 
@@ -125,7 +115,7 @@ public function form(EntityInterface $entity, $langcode, array $items, array &$f
       '#type' => 'container',
       '#attributes' => array(
         'class' => array(
-          'field-type-' . drupal_html_class($field['type']),
+          'field-type-' . drupal_html_class($this->fieldDefinition->getType()),
           'field-name-' . drupal_html_class($field_name),
           'field-widget-' . drupal_html_class($this->getPluginId()),
         ),
@@ -146,7 +136,7 @@ public function form(EntityInterface $entity, $langcode, array $items, array &$f
       // when $langcode is unknown.
       '#language' => $langcode,
       $langcode => $elements,
-      '#access' => field_access('edit', $field, $entity->entityType(), $entity),
+      '#access' => $this->checkFieldAccess('edit', $entity),
     );
 
     return $addition;
@@ -161,14 +151,12 @@ public function form(EntityInterface $entity, $langcode, array $items, array &$f
    * - table display and drag-n-drop value reordering
    */
   protected function formMultipleElements(EntityInterface $entity, array $items, $langcode, array &$form, array &$form_state) {
-    $field = $this->field;
-    $instance = $this->instance;
-    $field_name = $field['field_name'];
-
+    $field_name = $this->fieldDefinition->getName();
     $parents = $form['#parents'];
 
     // Determine the number of widgets to display.
-    switch ($field['cardinality']) {
+    $cardinality = $this->fieldDefinition->getCardinality();
+    switch ($cardinality) {
       case FIELD_CARDINALITY_UNLIMITED:
         $field_state = field_form_get_state($parents, $field_name, $langcode, $form_state);
         $max = $field_state['items_count'];
@@ -176,16 +164,16 @@ protected function formMultipleElements(EntityInterface $entity, array $items, $
         break;
 
       default:
-        $max = $field['cardinality'] - 1;
-        $is_multiple = ($field['cardinality'] > 1);
+        $max = $cardinality - 1;
+        $is_multiple = ($cardinality > 1);
         break;
     }
 
     $id_prefix = implode('-', array_merge($parents, array($field_name)));
     $wrapper_id = drupal_html_id($id_prefix . '-add-more-wrapper');
 
-    $title = check_plain($instance['label']);
-    $description = field_filter_xss(\Drupal::token()->replace($instance['description']));
+    $title = check_plain($this->fieldDefinition->getLabel());
+    $description = field_filter_xss(\Drupal::token()->replace($this->fieldDefinition->getDescription()));
 
     $elements = array();
 
@@ -221,9 +209,9 @@ protected function formMultipleElements(EntityInterface $entity, array $items, $
     if ($elements) {
       $elements += array(
         '#theme' => 'field_multiple_value_form',
-        '#field_name' => $field['field_name'],
-        '#cardinality' => $field['cardinality'],
-        '#required' => $instance['required'],
+        '#field_name' => $this->fieldDefinition->getName(),
+        '#cardinality' => $this->fieldDefinition->getCardinality(),
+        '#required' => $this->fieldDefinition->isRequired(),
         '#title' => $title,
         '#description' => $description,
         '#prefix' => '<div id="' . $wrapper_id . '">',
@@ -232,7 +220,7 @@ protected function formMultipleElements(EntityInterface $entity, array $items, $
       );
 
       // Add 'add more' button, if not working with a programmed form.
-      if ($field['cardinality'] == FIELD_CARDINALITY_UNLIMITED && empty($form_state['programmed'])) {
+      if ($this->fieldDefinition->getCardinality() == FIELD_CARDINALITY_UNLIMITED && empty($form_state['programmed'])) {
         $elements['add_more'] = array(
           '#type' => 'submit',
           '#name' => strtr($id_prefix, '-', '_') . '_add_more',
@@ -256,19 +244,15 @@ protected function formMultipleElements(EntityInterface $entity, array $items, $
    * Generates the form element for a single copy of the widget.
    */
   protected function formSingleElement(EntityInterface $entity, array $items, $delta, $langcode, array $element, array &$form, array &$form_state) {
-    $instance = $this->instance;
-    $field = $this->field;
-
     $element += array(
       '#entity_type' => $entity->entityType(),
       '#bundle' => $entity->bundle(),
       '#entity' => $entity,
-      '#field_name' => $field['field_name'],
+      '#field_name' => $this->fieldDefinition->getName(),
       '#language' => $langcode,
       '#field_parents' => $form['#parents'],
-      '#columns' => array_keys($field['columns']),
       // Only the first widget should be required.
-      '#required' => $delta == 0 && $instance['required'],
+      '#required' => $delta == 0 && $this->fieldDefinition->isRequired(),
       '#delta' => $delta,
       '#weight' => $delta,
     );
@@ -279,8 +263,9 @@ protected function formSingleElement(EntityInterface $entity, array $items, $del
       // Allow modules to alter the field widget form element.
       $context = array(
         'form' => $form,
-        'field' => $field,
-        'instance' => $instance,
+        'field_definition' => $this->fieldDefinition,
+        'entity_type' => $entity->entityType(),
+        'bundle' => $entity->bundle(),
         'langcode' => $langcode,
         'items' => $items,
         'delta' => $delta,
@@ -293,10 +278,10 @@ protected function formSingleElement(EntityInterface $entity, array $items, $del
   }
 
   /**
-   * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::extractFormValues().
+   * {@inheritdoc}
    */
   public function extractFormValues(EntityInterface $entity, $langcode, array &$items, array $form, array &$form_state) {
-    $field_name = $this->field['field_name'];
+    $field_name = $this->fieldDefinition->getName();
 
     // Extract the values from $form_state['values'].
     $path = array_merge($form['#parents'], array($field_name, $langcode));
@@ -331,7 +316,7 @@ public function extractFormValues(EntityInterface $entity, $langcode, array &$it
       $this->sortItems($items);
 
       // Remove empty values.
-      $items = _field_filter_items($this->field, $items);
+      $items = _field_filter_items($this->field_definition, $items);
 
       // Put delta mapping in $form_state, so that flagErrors() can use it.
       $field_state = field_form_get_state($form['#parents'], $field_name, $langcode, $form_state);
@@ -344,10 +329,10 @@ public function extractFormValues(EntityInterface $entity, $langcode, array &$it
   }
 
   /**
-   * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::flagErrors().
+   * {@inheritdoc}
    */
   public function flagErrors(EntityInterface $entity, $langcode, array $items, array $form, array &$form_state) {
-    $field_name = $this->field['field_name'];
+    $field_name = $this->fieldDefinition->getName();
 
     $field_state = field_form_get_state($form['#parents'], $field_name, $langcode, $form_state);
 
@@ -410,7 +395,8 @@ public function massageFormValues(array $values, array $form, array &$form_state
    *   The field values.
    */
   protected function sortItems(array &$items) {
-    $is_multiple = ($this->field['cardinality'] == FIELD_CARDINALITY_UNLIMITED) || ($this->field['cardinality'] > 1);
+    $cardinality = $this->fieldDefinition->getCardinality();
+    $is_multiple = ($cardinality == FIELD_CARDINALITY_UNLIMITED) || ($cardinality > 1);
     if ($is_multiple && isset($items[0]['_weight'])) {
       usort($items, function ($a, $b) {
         $a_weight = (is_array($a) ? $a['_weight'] : 0);
@@ -426,4 +412,26 @@ protected function sortItems(array &$items) {
     }
   }
 
+  /**
+   * Returns whether the currently logged in user has access to the field.
+   *
+   * @todo Remove this once Field API access is unified with entity field
+   *   access: http://drupal.org/node/1994140.
+   */
+  protected function checkFieldAccess($op, $entity) {
+    if ($this->fieldDefinition instanceof FieldInstanceInterface) {
+      $field = $this->fieldDefinition->getField();
+      return field_access($op, $field, $entity->entityType(), $entity);
+    }
+    else {
+      return FALSE;
+    }
+  }
+
+  /**
+   * Returns the value of a field setting.
+   */
+  protected function getFieldSetting($setting_name) {
+    return $this->fieldDefinition->getSetting($setting_name);
+  }
 }
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetFactory.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetFactory.php
index 9b14e85..4b7cb6b 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetFactory.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetFactory.php
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Definition of Drupal\field\Plugin\WidgetFactory.
+ * Contains \Drupal\field\Plugin\WidgetFactory.
  */
 
 namespace Drupal\field\Plugin\Type\Widget;
@@ -15,11 +15,11 @@
 class WidgetFactory extends DefaultFactory {
 
   /**
-   * Overrides Drupal\Component\Plugin\Factory\DefaultFactory::createInstance().
+   * {@inheritdoc}
    */
   public function createInstance($plugin_id, array $configuration) {
     $plugin_definition = $this->discovery->getDefinition($plugin_id);
     $plugin_class = static::getPluginClass($plugin_id, $plugin_definition);
-    return new $plugin_class($plugin_id, $plugin_definition, $configuration['instance'], $configuration['settings']);
+    return new $plugin_class($plugin_id, $plugin_definition, $configuration['field_definition'], $configuration['settings']);
   }
 }
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetInterface.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetInterface.php
index eb82844..ee83926 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetInterface.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetInterface.php
@@ -58,9 +58,9 @@ public function settingsForm(array $form, array &$form_state);
    * Therefore, the FAPI element callbacks (such as #process, #element_validate,
    * #value_callback...) used by the widget cannot use the field_info_field()
    * or field_info_instance() functions to retrieve the $field or $instance
-   * definitions they should operate on. The field_widget_field() and
-   * field_widget_instance() functions should be used instead to fetch the
-   * current working definitions from $form_state, where Field API stores them.
+   * definitions they should operate on. The field_widget_field_definition()
+   * should be used instead to fetch the current working definitions from
+   * $form_state, where Field API stores them.
    *
    * Alternatively, hook_field_widget_form() can extract the needed specific
    * properties from $field and $instance and set them as ad-hoc
@@ -86,7 +86,6 @@ public function settingsForm(array $form, array &$form_state);
    *       $form_state['values'], and is used to access processing information
    *       for the field through the field_form_get_state() and
    *       field_form_set_state() functions.
-   *   - #columns: A list of field storage columns of the field.
    *   - #title: The sanitized element label for the field instance, ready for
    *     output.
    *   - #description: The sanitized element description for the field instance,
@@ -107,8 +106,7 @@ public function settingsForm(array $form, array &$form_state);
    * @return array
    *   The form elements for a single widget for this field.
    *
-   * @see field_widget_field()
-   * @see field_widget_instance()
+   * @see field_widget_field_definition()
    * @see hook_field_widget_form_alter()
    * @see hook_field_widget_WIDGET_TYPE_form_alter()
    */
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetPluginManager.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetPluginManager.php
index bb85736..cfe613d 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetPluginManager.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetPluginManager.php
@@ -49,7 +49,7 @@ public function __construct(\Traversable $namespaces) {
    *
    * @param array $options
    *   An array with the following key/value pairs:
-   *   - instance: (FieldInstance) The field instance.
+   *   - field_definition: (FieldDefinitionInterface) The field definition.
    *   - form_mode: (string) The form mode.
    *   - prepare: (bool, optional) Whether default values should get merged in
    *     the 'configuration' array. Defaults to TRUE.
@@ -68,12 +68,12 @@ public function __construct(\Traversable $namespaces) {
    */
   public function getInstance(array $options) {
     $configuration = $options['configuration'];
-    $instance = $options['instance'];
-    $field = field_info_field($instance['field_name']);
+    $field_definition = $options['field_definition'];
+    $field_type = $field_definition->getType();
 
     // Fill in default configuration if needed.
     if (!isset($options['prepare']) || $options['prepare'] == TRUE) {
-      $configuration = $this->prepareConfiguration($field['type'], $configuration);
+      $configuration = $this->prepareConfiguration($field_type, $configuration);
     }
 
     $plugin_id = $configuration['type'];
@@ -82,14 +82,14 @@ public function getInstance(array $options) {
     // - $type_info doesn't exist (the widget type is unknown),
     // - the field type is not allowed for the widget.
     $definition = $this->getDefinition($configuration['type']);
-    if (!isset($definition['class']) || !in_array($field['type'], $definition['field_types'])) {
+    if (!isset($definition['class']) || !in_array($field_type, $definition['field_types'])) {
       // Grab the default widget for the field type.
-      $field_type_definition = field_info_field_types($field['type']);
+      $field_type_definition = field_info_field_types($field_type);
       $plugin_id = $field_type_definition['default_widget'];
     }
 
     $configuration += array(
-      'instance' => $instance,
+      'field_definition' => $field_definition,
     );
     return $this->createInstance($plugin_id, $configuration);
   }
diff --git a/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php b/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php
index 60b67e7..55ba148 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php
@@ -14,6 +14,7 @@
 use Drupal\views\Plugin\views\field\FieldPluginBase;
 use Drupal\Component\Annotation\PluginID;
 use Drupal\views\Views;
+use Drupal\field\Plugin\Core\Entity\FieldInstance;
 
 /**
  * A field that displays fieldapi fields.
@@ -397,7 +398,7 @@ public function buildOptionsForm(&$form, &$form_state) {
     $this->instance = $this->fakeFieldInstance($format, $settings);
 
     $options = array(
-      'instance' => $this->instance,
+      'field_definition' => $this->instance,
       'configuration' => array(
         'type' => $format,
         'settings' => $settings,
@@ -423,8 +424,8 @@ public function buildOptionsForm(&$form, &$form_state) {
    * @param array $formatter_settings
    *   An associative array of settings for the formatter.
    *
-   * @return array
-   *   An associative array of instance date for the fake field.
+   * @return \Drupal\field\Plugin\Core\Entity\FieldInstance
+   *   An Field instance object for the fake field.
    *
    * @see field_info_instance()
    */
@@ -434,7 +435,7 @@ function fakeFieldInstance($formatter, $formatter_settings) {
 
     $field_type = field_info_field_types($field['type']);
 
-    return array(
+    return new FieldInstance(array(
       // Build a fake entity type and bundle.
       'field_name' => $field_name,
       'entity_type' => 'views_fake',
@@ -448,7 +449,7 @@ function fakeFieldInstance($formatter, $formatter_settings) {
       'label' => $field_name,
       'description' => '',
       'deleted' => FALSE,
-    );
+    ));
   }
 
   /**
diff --git a/core/modules/field/tests/modules/field_test/field_test.field.inc b/core/modules/field/tests/modules/field_test/field_test.field.inc
index d2f4a94..734ef8d 100644
--- a/core/modules/field/tests/modules/field_test/field_test.field.inc
+++ b/core/modules/field/tests/modules/field_test/field_test.field.inc
@@ -7,6 +7,7 @@
 
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\field\FieldException;
+use Drupal\field\FieldInterface;
 
 /**
  * Implements hook_field_info().
@@ -197,7 +198,7 @@ function field_test_default_value(EntityInterface $entity, $field, $instance) {
 /**
  * Implements hook_field_access().
  */
-function field_test_field_access($op, $field, $entity_type, $entity, $account) {
+function field_test_field_access($op, FieldInterface $field, $entity_type, $entity, $account) {
   if ($field['field_name'] == "field_no_{$op}_access") {
     return FALSE;
   }
diff --git a/core/modules/field/tests/modules/field_test/field_test.module b/core/modules/field/tests/modules/field_test/field_test.module
index c2070f2..2648120 100644
--- a/core/modules/field/tests/modules/field_test/field_test.module
+++ b/core/modules/field/tests/modules/field_test/field_test.module
@@ -203,15 +203,16 @@ function field_test_field_attach_view_alter(&$output, $context) {
  * Implements hook_field_widget_form_alter().
  */
 function field_test_field_widget_form_alter(&$element, &$form_state, $context) {
-  $instance = $context['instance'];
-  $entity_form_display = entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default');
-  switch ($context['field']['field_name']) {
+  $field_name = $context['field_definition']['field_name'];
+  switch ($field_name) {
     case 'alter_test_text':
-      drupal_set_message('Field size: ' . $entity_form_display->getWidget($context['field']['field_name'])->getSetting('size'));
+      $instance = field_info_instance($context['entity_type'], $field_name, $context['bundle']);
+      drupal_set_message('Field size: ' . $instance->getWidget()->getSetting('size'));
       break;
 
     case 'alter_test_options':
-      drupal_set_message('Widget type: ' . $entity_form_display->getWidget($context['field']['field_name'])->getPluginId());
+      $instance = field_info_instance($context['entity_type'], $field_name, $context['bundle']);
+      drupal_set_message('Widget type: ' . $instance->getWidget()->getPluginId());
       break;
   }
   // Set a message if this is for the form displayed to set default value for
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php
index e6caf4e..965b558 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php
@@ -175,7 +175,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL,
       // Get the corresponding formatter object.
       if ($display_options && $display_options['type'] != 'hidden') {
         $formatter = drupal_container()->get('plugin.manager.field.formatter')->getInstance(array(
-          'instance' => $instance,
+          'field_definition' => $instance,
           'view_mode' => $this->mode,
           'configuration' => $display_options
         ));
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldInstanceEditForm.php b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldInstanceEditForm.php
index b37ddc3..3323b15 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldInstanceEditForm.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldInstanceEditForm.php
@@ -173,6 +173,7 @@ public function validateForm(array &$form, array &$form_state) {
     $field_name = $this->instance['field_name'];
     $entity = $form['#entity'];
     $entity_form_display = $form['#entity_form_display'];
+    $field = $this->instance->getField();
 
     if (isset($form['instance']['default_value_widget'])) {
       $element = $form['instance']['default_value_widget'];
@@ -181,9 +182,8 @@ public function validateForm(array &$form, array &$form_state) {
       $items = array();
       $entity_form_display->getWidget($this->instance->getField()->id)->extractFormValues($entity, Language::LANGCODE_NOT_SPECIFIED, $items, $element, $form_state);
 
-      // Grab the field definition from $form_state.
+      // Get the field state.
       $field_state = field_form_get_state($element['#parents'], $field_name, Language::LANGCODE_NOT_SPECIFIED, $form_state);
-      $field = $field_state['field'];
 
       // Validate the value.
       $errors = array();
diff --git a/core/modules/file/file.field.inc b/core/modules/file/file.field.inc
index 4e7253e..a5cceed 100644
--- a/core/modules/file/file.field.inc
+++ b/core/modules/file/file.field.inc
@@ -317,18 +317,18 @@ function file_field_displayed($item, $field) {
 /**
  * Retrieves the upload validators for a file field.
  *
- * @param $field
- *   A field array.
+ * @param array $field_settings
+ *   The field settings.
  *
  * @return
  *   An array suitable for passing to file_save_upload() or the file field
  *   element's '#upload_validators' property.
  */
-function file_field_widget_upload_validators($field, $instance) {
+function file_field_widget_upload_validators(array $field_settings) {
   // Cap the upload size according to the PHP limit.
   $max_filesize = parse_size(file_upload_max_size());
-  if (!empty($instance['settings']['max_filesize']) && parse_size($instance['settings']['max_filesize']) < $max_filesize) {
-    $max_filesize = parse_size($instance['settings']['max_filesize']);
+  if (!empty($field_settings['max_filesize']) && parse_size($field_settings['max_filesize']) < $max_filesize) {
+    $max_filesize = parse_size($field_settings['max_filesize']);
   }
 
   $validators = array();
@@ -337,20 +337,18 @@ function file_field_widget_upload_validators($field, $instance) {
   $validators['file_validate_size'] = array($max_filesize);
 
   // Add the extension check if necessary.
-  if (!empty($instance['settings']['file_extensions'])) {
-    $validators['file_validate_extensions'] = array($instance['settings']['file_extensions']);
+  if (!empty($field_settings['file_extensions'])) {
+    $validators['file_validate_extensions'] = array($field_settings['file_extensions']);
   }
 
   return $validators;
 }
 
 /**
- * Determines the URI for a file field instance.
+ * Determines the URI for a file field.
  *
- * @param $field
- *   A field array.
- * @param $instance
- *   A field instance array.
+ * @param array $field_settings
+ *   The field settings.
  * @param $data
  *   An array of token objects to pass to
  *   \Drupal\Core\Utility\Token::replace().
@@ -360,13 +358,13 @@ function file_field_widget_upload_validators($field, $instance) {
  *
  * @see \Drupal\Core\Utility\Token::replace()
  */
-function file_field_widget_uri($field, $instance, $data = array()) {
-  $destination = trim($instance['settings']['file_directory'], '/');
+function file_field_widget_uri(array $field_settings, $data = array()) {
+  $destination = trim($field_settings['file_directory'], '/');
 
   // Replace tokens.
   $destination = Drupal::token()->replace($destination, $data);
 
-  return $field['settings']['uri_scheme'] . '://' . $destination;
+  return $field_settings['uri_scheme'] . '://' . $destination;
 }
 
 /**
@@ -378,9 +376,9 @@ function file_field_widget_value($element, $input = FALSE, $form_state) {
   if ($input) {
     // Checkboxes lose their value when empty.
     // If the display field is present make sure its unchecked value is saved.
-    $field = field_widget_field($element, $form_state);
+    $field_definition = field_widget_field_definition($element, $form_state);
     if (empty($input['display'])) {
-      $input['display'] = $field['settings']['display_field'] ? 0 : 1;
+      $input['display'] = $field_definition['settings']['display_field'] ? 0 : 1;
     }
   }
 
@@ -449,17 +447,17 @@ function file_field_widget_process($element, &$form_state, $form) {
   $item = $element['#value'];
   $item['fids'] = $element['fids']['#value'];
 
-  $field = field_widget_field($element, $form_state);
-  $instance = field_widget_instance($element, $form_state);
+  $field_definition = field_widget_field_definition($element, $form_state);
+  $settings = $field_definition['settings'];
 
   $element['#theme'] = 'file_widget';
 
   // Add the display field if enabled.
-  if (!empty($field['settings']['display_field']) && $item['fids']) {
+  if (!empty($field_definition['settings']['display_field']) && $item['fids']) {
     $element['display'] = array(
       '#type' => empty($item['fids']) ? 'hidden' : 'checkbox',
       '#title' => t('Include file in display'),
-      '#value' => isset($item['display']) ? $item['display'] : $field['settings']['display_default'],
+      '#value' => isset($item['display']) ? $item['display'] : $field_definition['settings']['display_default'],
       '#attributes' => array('class' => array('file-display')),
     );
   }
@@ -471,7 +469,7 @@ function file_field_widget_process($element, &$form_state, $form) {
   }
 
   // Add the description field if enabled.
-  if (!empty($instance['settings']['description_field']) && $item['fids']) {
+  if (!empty($field_definition['settings']['description_field']) && $item['fids']) {
     $config = config('file.settings');
     $element['description'] = array(
       '#type' => $config->get('description.type'),
@@ -484,7 +482,7 @@ function file_field_widget_process($element, &$form_state, $form) {
 
   // Adjust the Ajax settings so that on upload and remove of any individual
   // file, the entire group of file fields is updated together.
-  if ($field['cardinality'] != 1) {
+  if ($field_definition['cardinality'] != 1) {
     $parents = array_slice($element['#array_parents'], 0, -1);
     $new_path = 'file/ajax/' . implode('/', $parents) . '/' . $form['form_build_id']['#value'];
     $field_element = NestedArray::getValue($form, $parents);
diff --git a/core/modules/file/lib/Drupal/file/Plugin/field/widget/FileWidget.php b/core/modules/file/lib/Drupal/file/Plugin/field/widget/FileWidget.php
index 4eebf6c..0064022 100644
--- a/core/modules/file/lib/Drupal/file/Plugin/field/widget/FileWidget.php
+++ b/core/modules/file/lib/Drupal/file/Plugin/field/widget/FileWidget.php
@@ -31,7 +31,7 @@
 class FileWidget extends WidgetBase {
 
   /**
-   * Implements \Drupal\field\Plugin\Type\Widget\WidgetInterface::settingsForm().
+   * {@inheritdoc}
    */
   public function settingsForm(array $form, array &$form_state) {
     $element['progress_indicator'] = array(
@@ -50,14 +50,12 @@ public function settingsForm(array $form, array &$form_state) {
   }
 
   /**
-   * Overrides \Drupal\field\Plugin\Type\Widget\WidgetBase::formMultipleElements().
+   * {@inheritdoc}
    *
    * Special handling for draggable multiple widgets and 'add more' button.
    */
   protected function formMultipleElements(EntityInterface $entity, array $items, $langcode, array &$form, array &$form_state) {
-    $field = $this->field;
-    $instance = $this->instance;
-    $field_name = $field['field_name'];
+    $field_name = $this->fieldDefinition->getName();
 
     $parents = $form['#parents'];
 
@@ -70,23 +68,24 @@ protected function formMultipleElements(EntityInterface $entity, array $items, $
     }
 
     // Determine the number of widgets to display.
-    switch ($field['cardinality']) {
+    $cardinality = $this->fieldDefinition->getCardinality();
+    switch ($cardinality) {
       case FIELD_CARDINALITY_UNLIMITED:
         $max = count($items);
         $is_multiple = TRUE;
         break;
 
       default:
-        $max = $field['cardinality'] - 1;
-        $is_multiple = ($field['cardinality'] > 1);
+        $max = $cardinality - 1;
+        $is_multiple = ($cardinality > 1);
         break;
     }
 
     $id_prefix = implode('-', array_merge($parents, array($field_name)));
     $wrapper_id = drupal_html_id($id_prefix . '-add-more-wrapper');
 
-    $title = check_plain($instance['label']);
-    $description = field_filter_xss($instance['description']);
+    $title = check_plain($this->fieldDefinition->getLabel());
+    $description = field_filter_xss($this->fieldDefinition->getDescription());
 
     $elements = array();
 
@@ -120,8 +119,8 @@ protected function formMultipleElements(EntityInterface $entity, array $items, $
       }
     }
 
-    $empty_single_allowed = ($this->field['cardinality'] == 1 && $delta == 0);
-    $empty_multiple_allowed = ($this->field['cardinality'] == FIELD_CARDINALITY_UNLIMITED || $delta < $this->field['cardinality']) && empty($form_state['programmed']);
+    $empty_single_allowed = ($cardinality == 1 && $delta == 0);
+    $empty_multiple_allowed = ($cardinality == FIELD_CARDINALITY_UNLIMITED || $delta < $cardinality) && empty($form_state['programmed']);
 
     // Add one more empty row for new uploads except when this is a programmed
     // multiple form as it is not necessary.
@@ -150,25 +149,25 @@ protected function formMultipleElements(EntityInterface $entity, array $items, $
       $elements['#description'] = $description;
       $elements['#field_name'] = $element['#field_name'];
       $elements['#language'] = $element['#language'];
-      $elements['#display_field'] = !empty($this->field['settings']['display_field']);
+      $elements['#display_field'] = (bool) $this->getFieldSetting('display_field');
 
       // Add some properties that will eventually be added to the file upload
       // field. These are added here so that they may be referenced easily
       // through a hook_form_alter().
       $elements['#file_upload_title'] = t('Add a new file');
-      $elements['#file_upload_description'] = theme('file_upload_help', array('description' => '', 'upload_validators' => $elements[0]['#upload_validators'], 'cardinality' => $this->field['cardinality']));
+      $elements['#file_upload_description'] = theme('file_upload_help', array('description' => '', 'upload_validators' => $elements[0]['#upload_validators'], 'cardinality' => $cardinality));
     }
 
     return $elements;
   }
 
   /**
-   * Implements \Drupal\field\Plugin\Type\Widget\WidgetInterface::formElement().
+   * {@inheritdoc}
    */
   public function formElement(array $items, $delta, array $element, $langcode, array &$form, array &$form_state) {
     $defaults = array(
       'fids' => array(),
-      'display' => !empty($this->field['settings']['display_default']),
+      'display' => (bool) $this->getFieldSetting('display_default'),
       'description' => '',
     );
 
@@ -177,8 +176,8 @@ public function formElement(array $items, $delta, array $element, $langcode, arr
     $element_info = element_info('managed_file');
     $element += array(
       '#type' => 'managed_file',
-      '#upload_location' => file_field_widget_uri($this->field, $this->instance),
-      '#upload_validators' => file_field_widget_upload_validators($this->field, $this->instance),
+      '#upload_location' => file_field_widget_uri($this->fieldDefinition->getSettings()),
+      '#upload_validators' => file_field_widget_upload_validators($this->fieldDefinition->getSettings()),
       '#value_callback' => 'file_field_widget_value',
       '#process' => array_merge($element_info['#process'], array('file_field_widget_process')),
       '#progress_indicator' => $this->getSetting('progress_indicator'),
@@ -197,7 +196,7 @@ public function formElement(array $items, $delta, array $element, $langcode, arr
 
     $default_fids = $element['#extended'] ? $element['#default_value']['fids'] : $element['#default_value'];
     if (empty($default_fids)) {
-      $cardinality = isset($this->field['cardinality']) ? $this->field['cardinality'] : 1;
+      $cardinality = $this->fieldDefinition->getCardinality();
       $element['#description'] = theme('file_upload_help', array('description' => $element['#description'], 'upload_validators' => $element['#upload_validators'], 'cardinality' => $cardinality));
       $element['#multiple'] = $cardinality != 1 ? TRUE : FALSE;
       if ($cardinality != 1 && $cardinality != -1) {
@@ -209,7 +208,7 @@ public function formElement(array $items, $delta, array $element, $langcode, arr
   }
 
   /**
-   * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::massageFormValues().
+   * {@inheritdoc}
    */
   public function massageFormValues(array $values, array $form, array &$form_state) {
     // Since file upload widget now supports uploads of more than one file at a
diff --git a/core/modules/image/image.field.inc b/core/modules/image/image.field.inc
index eed43df..1c41f8a 100644
--- a/core/modules/image/image.field.inc
+++ b/core/modules/image/image.field.inc
@@ -361,8 +361,8 @@ function image_field_widget_process($element, &$form_state, $form) {
   }
 
   // Get field settings.
-  $instance = field_widget_instance($element, $form_state);
-  $settings = $instance['settings'];
+  $field_definition = field_widget_field_definition($element, $form_state);
+  $settings = $field_definition['settings'];
 
   // Add the additional alt and title fields.
   $element['alt'] = array(
diff --git a/core/modules/image/lib/Drupal/image/Plugin/field/widget/ImageWidget.php b/core/modules/image/lib/Drupal/image/Plugin/field/widget/ImageWidget.php
index 8062ff6..1027d65 100644
--- a/core/modules/image/lib/Drupal/image/Plugin/field/widget/ImageWidget.php
+++ b/core/modules/image/lib/Drupal/image/Plugin/field/widget/ImageWidget.php
@@ -52,37 +52,38 @@ public function settingsForm(array $form, array &$form_state) {
   }
 
   /**
-   * Overrides \Drupal\file\Plugin\field\widget\FileWidget::formMultipleElements().
+   * {@inheritdoc}
    *
    * Special handling for draggable multiple widgets and 'add more' button.
    */
   protected function formMultipleElements(EntityInterface $entity, array $items, $langcode, array &$form, array &$form_state) {
     $elements = parent::formMultipleElements($entity, $items, $langcode, $form, $form_state);
 
-    if ($this->field['cardinality'] == 1) {
+    $cardinality = $this->fieldDefinition->getCardinality();
+    if ($cardinality == 1) {
       // If there's only one field, return it as delta 0.
       if (empty($elements[0]['#default_value']['fids'])) {
-        $elements[0]['#description'] = theme('file_upload_help', array('description' => $this->instance['description'], 'upload_validators' => $elements[0]['#upload_validators'], 'cardinality' => $this->field['cardinality']));
+        $elements[0]['#description'] = theme('file_upload_help', array('description' => $this->fieldDefinition->getDescription(), 'upload_validators' => $elements[0]['#upload_validators'], 'cardinality' => $cardinality));
       }
     }
     else {
-      $elements['#file_upload_description'] = theme('file_upload_help', array('upload_validators' => $elements[0]['#upload_validators'], 'cardinality' => $this->field['cardinality']));
+      $elements['#file_upload_description'] = theme('file_upload_help', array('upload_validators' => $elements[0]['#upload_validators'], 'cardinality' => $cardinality));
     }
 
     return $elements;
   }
 
   /**
-   * Overrides \Drupal\file\Plugin\field\widget\FileWidget::formElement().
+   * {@inheritdoc}
    */
   public function formElement(array $items, $delta, array $element, $langcode, array &$form, array &$form_state) {
     $element = parent::formElement($items, $delta, $element, $langcode, $form, $form_state);
 
-    $settings = $this->instance['settings'];
+    $field_settings = $this->fieldDefinition->getSettings();
 
     // Add upload resolution validation.
-    if ($settings['max_resolution'] || $settings['min_resolution']) {
-      $element['#upload_validators']['file_validate_image_resolution'] = array($settings['max_resolution'], $settings['min_resolution']);
+    if ($field_settings['max_resolution'] || $field_settings['min_resolution']) {
+      $element['#upload_validators']['file_validate_image_resolution'] = array($field_settings['max_resolution'], $field_settings['min_resolution']);
     }
 
     // If not using custom extension validation, ensure this is an image.
@@ -95,8 +96,8 @@ public function formElement(array $items, $delta, array $element, $langcode, arr
     $element['#process'][] = 'image_field_widget_process';
     // Add properties needed by image_field_widget_process().
     $element['#preview_image_style'] = $this->getSetting('preview_image_style');
-    $element['#title_field'] = $settings['title_field'];
-    $element['#alt_field'] = $settings['alt_field'];
+    $element['#title_field'] = $field_settings['title_field'];
+    $element['#alt_field'] = $field_settings['alt_field'];
 
     return $element;
   }
diff --git a/core/modules/link/lib/Drupal/link/Plugin/field/widget/LinkWidget.php b/core/modules/link/lib/Drupal/link/Plugin/field/widget/LinkWidget.php
index 0784cae..2a7638a 100644
--- a/core/modules/link/lib/Drupal/link/Plugin/field/widget/LinkWidget.php
+++ b/core/modules/link/lib/Drupal/link/Plugin/field/widget/LinkWidget.php
@@ -33,8 +33,6 @@ class LinkWidget extends WidgetBase {
    * {@inheritdoc}
    */
   public function formElement(array $items, $delta, array $element, $langcode, array &$form, array &$form_state) {
-    $instance = $this->instance;
-
     $element['url'] = array(
       '#type' => 'url',
       '#title' => t('URL'),
@@ -49,13 +47,13 @@ public function formElement(array $items, $delta, array $element, $langcode, arr
       '#placeholder' => $this->getSetting('placeholder_title'),
       '#default_value' => isset($items[$delta]['title']) ? $items[$delta]['title'] : NULL,
       '#maxlength' => 255,
-      '#access' => $instance['settings']['title'] != DRUPAL_DISABLED,
+      '#access' => $this->getFieldSetting('title') != DRUPAL_DISABLED,
     );
     // Post-process the title field to make it conditionally required if URL is
     // non-empty. Omit the validation on the field edit form, since the field
     // settings cannot be saved otherwise.
     $is_field_edit_form = ($element['#entity'] === NULL);
-    if (!$is_field_edit_form && $instance['settings']['title'] == DRUPAL_REQUIRED) {
+    if (!$is_field_edit_form && $this->getFieldSetting('title') == DRUPAL_REQUIRED) {
       $element['#element_validate'] = array(array($this, 'validateTitle'));
     }
 
@@ -70,7 +68,7 @@ public function formElement(array $items, $delta, array $element, $langcode, arr
 
     // If cardinality is 1, ensure a label is output for the field by wrapping it
     // in a details element.
-    if ($this->field['cardinality'] == 1) {
+    if ($this->fieldDefinition->getCardinality() == 1) {
       $element += array(
         '#type' => 'fieldset',
       );
diff --git a/core/modules/number/lib/Drupal/number/Plugin/field/widget/NumberWidget.php b/core/modules/number/lib/Drupal/number/Plugin/field/widget/NumberWidget.php
index 37c857f..26b9974 100644
--- a/core/modules/number/lib/Drupal/number/Plugin/field/widget/NumberWidget.php
+++ b/core/modules/number/lib/Drupal/number/Plugin/field/widget/NumberWidget.php
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Definition of Drupal\number\Plugin\field\widget\NumberWidget.
+ * Contains \Drupal\number\Plugin\field\widget\NumberWidget.
  */
 
 namespace Drupal\number\Plugin\field\widget;
@@ -31,7 +31,7 @@
 class NumberWidget extends WidgetBase {
 
   /**
-   * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::settingsForm().
+   * {@inheritdoc}
    */
   public function settingsForm(array $form, array &$form_state) {
     $element['placeholder'] = array(
@@ -44,12 +44,9 @@ public function settingsForm(array $form, array &$form_state) {
   }
 
   /**
-   * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::formElement().
+   * {@inheritdoc}
    */
   public function formElement(array $items, $delta, array $element, $langcode, array &$form, array &$form_state) {
-    $field = $this->field;
-    $instance = $this->instance;
-
     $value = isset($items[$delta]['value']) ? $items[$delta]['value'] : NULL;
 
     $element += array(
@@ -59,9 +56,9 @@ public function formElement(array $items, $delta, array $element, $langcode, arr
     );
 
     // Set the step for floating point and decimal numbers.
-    switch ($field['type']) {
+    switch ($this->fieldDefinition->getType()) {
       case 'number_decimal':
-        $element['#step'] = pow(0.1, $field['settings']['scale']);
+        $element['#step'] = pow(0.1, $this->getFieldSetting('scale'));
         break;
 
       case 'number_float':
@@ -70,20 +67,20 @@ public function formElement(array $items, $delta, array $element, $langcode, arr
     }
 
     // Set minimum and maximum.
-    if (is_numeric($instance['settings']['min'])) {
-      $element['#min'] = $instance['settings']['min'];
+    if (is_numeric($this->getFieldSetting('min'))) {
+      $element['#min'] = $this->getFieldSetting('min');
     }
-    if (is_numeric($instance['settings']['max'])) {
-      $element['#max'] = $instance['settings']['max'];
+    if (is_numeric($this->getFieldSetting('max'))) {
+      $element['#max'] = $this->getFieldSetting('max');
     }
 
     // Add prefix and suffix.
-    if (!empty($instance['settings']['prefix'])) {
-      $prefixes = explode('|', $instance['settings']['prefix']);
+    if ($this->getFieldSetting('prefix')) {
+      $prefixes = explode('|', $this->getFieldSetting('prefix'));
       $element['#field_prefix'] = field_filter_xss(array_pop($prefixes));
     }
-    if (!empty($instance['settings']['suffix'])) {
-      $suffixes = explode('|', $instance['settings']['suffix']);
+    if ($this->getFieldSetting('suffix')) {
+      $suffixes = explode('|', $this->getFieldSetting('suffix'));
       $element['#field_suffix'] = field_filter_xss(array_pop($suffixes));
     }
 
@@ -91,7 +88,7 @@ public function formElement(array $items, $delta, array $element, $langcode, arr
   }
 
   /**
-   * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::errorElement().
+   * {@inheritdoc}
    */
   public function errorElement(array $element, array $error, array $form, array &$form_state) {
     return $element['value'];
diff --git a/core/modules/options/lib/Drupal/options/Plugin/field/formatter/OptionsDefaultFormatter.php b/core/modules/options/lib/Drupal/options/Plugin/field/formatter/OptionsDefaultFormatter.php
index 01b4efb..3b9c57c 100644
--- a/core/modules/options/lib/Drupal/options/Plugin/field/formatter/OptionsDefaultFormatter.php
+++ b/core/modules/options/lib/Drupal/options/Plugin/field/formatter/OptionsDefaultFormatter.php
@@ -35,7 +35,7 @@ class OptionsDefaultFormatter extends FormatterBase {
   public function viewElements(EntityInterface $entity, $langcode, array $items) {
     $elements = array();
 
-    $allowed_values = options_allowed_values($this->field, $this->instance, $entity);
+    $allowed_values = options_allowed_values($this->fieldDefinition, $entity);
 
     foreach ($items as $delta => $item) {
       if (isset($allowed_values[$item['value']])) {
diff --git a/core/modules/options/lib/Drupal/options/Plugin/field/widget/OnOffWidget.php b/core/modules/options/lib/Drupal/options/Plugin/field/widget/OnOffWidget.php
index 7e6b4a5..13a69c1 100644
--- a/core/modules/options/lib/Drupal/options/Plugin/field/widget/OnOffWidget.php
+++ b/core/modules/options/lib/Drupal/options/Plugin/field/widget/OnOffWidget.php
@@ -57,7 +57,7 @@ public function formElement(array $items, $delta, array $element, $langcode, arr
 
     // Override the title from the incoming $element.
     if ($this->getSetting('display_label')) {
-      $element['#title'] = $this->instance['label'];
+      $element['#title'] = $this->fieldDefinition->getLabel();
     }
     else {
       $element['#title'] = isset($options[1]) ? $options[1] : '';
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 6986231..d2ef644 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
@@ -7,7 +7,7 @@
 
 namespace Drupal\options\Plugin\field\widget;
 
-use Drupal\field\Plugin\Core\Entity\FieldInstance;
+use Drupal\Core\Entity\Field\FieldDefinitionInterface;
 use Drupal\field\Plugin\Type\Widget\WidgetBase;
 
 /**
@@ -36,12 +36,10 @@
   /**
    * {@inheritdoc}
    */
-  public function __construct($plugin_id, array $plugin_definition, FieldInstance $instance, array $settings) {
-    parent::__construct($plugin_id, $plugin_definition, $instance, $settings);
-
-    // Reset internal pointer since we're dealing with objects now.
-    reset($this->field['columns']);
-    $this->column = key($this->field['columns']);
+  public function __construct($plugin_id, array $plugin_definition, FieldDefinitionInterface $field_definition, array $settings) {
+    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings);
+    $property_names = $this->fieldDefinition->getPropertyNames();
+    $this->column = $property_names[0];
   }
 
   /**
@@ -52,7 +50,8 @@ public function formElement(array $items, $delta, array $element, $langcode, arr
     // element.
     $this->entity = $element['#entity'];
     $this->required = $element['#required'];
-    $this->multiple = ($this->field['cardinality'] == FIELD_CARDINALITY_UNLIMITED) || ($this->field['cardinality'] > 1);
+    $cardinality = $this->fieldDefinition->getCardinality();
+    $this->multiple = ($cardinality == FIELD_CARDINALITY_UNLIMITED) || ($cardinality > 1);
     $this->has_value = isset($items[0][$this->column]);
 
     // Add our custom validator.
@@ -115,7 +114,9 @@ protected function getOptions() {
       $module_handler = \Drupal::moduleHandler();
 
       // Get the list of options from the field type module, and sanitize them.
-      $options = (array) $module_handler->invoke($this->field['module'], 'options_list', array($this->field, $this->instance, $this->entity));
+      $field_type_info = field_info_field_types($this->fieldDefinition->getType());
+      $module = $field_type_info['module'];
+      $options = (array) $module_handler->invoke($module, 'options_list', array($this->fieldDefinition, $this->entity));
 
       // Add an empty option if the widget needs one.
       if ($empty_option = $this->getEmptyOption()) {
@@ -133,8 +134,7 @@ protected function getOptions() {
       }
 
       $context = array(
-        'field' => $this->field,
-        'instance' => $this->instance,
+        'fieldDefinition' => $this->fieldDefinition,
         'entity' => $this->entity,
       );
       $module_handler->alter('options_list', $options, $context);
diff --git a/core/modules/options/options.api.php b/core/modules/options/options.api.php
index a026898..6d142eb 100644
--- a/core/modules/options/options.api.php
+++ b/core/modules/options/options.api.php
@@ -13,12 +13,8 @@
  * implement this hook to specify the list of options to display in the
  * widgets.
  *
- * @param $field
+ * @param \Drupal\Core\Entity\Field\FieldDefinitionInterface $field_definition
  *   The field definition.
- * @param $instance
- *   The instance definition. It is recommended to only use instance level
- *   properties to filter out values from a list defined by field level
- *   properties.
  * @param \Drupal\Core\Entity\EntityInterface $entity
  *   The entity object the field is attached to.
  *
@@ -31,7 +27,7 @@
  *   widget. The HTML tags defined in _field_filter_xss_allowed_tags() are
  *   allowed, other tags will be filtered.
  */
-function hook_options_list($field, $instance, $entity) {
+function hook_options_list(\Drupal\Core\Entity\Field\FieldDefinitionInterface $field_definition, \Drupal\Core\Entity\EntityInterface $entity) {
   // Sample structure.
   $options = array(
     0 => t('Zero'),
@@ -57,7 +53,7 @@ function hook_options_list($field, $instance, $entity) {
   // In actual implementations, the array of options will most probably depend
   // on properties of the field. Example from taxonomy.module:
   $options = array();
-  foreach ($field['settings']['allowed_values'] as $tree) {
+  foreach ($field_definition->getSetting('allowed_values') as $tree) {
     $terms = taxonomy_get_tree($tree['vid'], $tree['parent'], NULL, TRUE);
     if ($terms) {
       foreach ($terms as $term) {
@@ -81,10 +77,8 @@ function hook_options_list($field, $instance, $entity) {
  *
  * @param array $context
  *   An associative array containing:
- *   - field: The field definition (\Drupal\field\Plugin\Core\Entity\Field).
- *   - instance: The instance definition. It is recommended to only use instance
- *     level properties to filter out values from a list defined by field level
- *     properties (Drupal\field\Plugin\Core\Entity\FieldInstance).
+ *   - field_definition: The field definition
+ *     (\Drupal\Core\Entity\Field\FieldDefinitionInterface).
  *   - entity: The entity object the field is attached to
  *     (\Drupal\Core\Entity\EntityInterface).
  *
diff --git a/core/modules/options/options.module b/core/modules/options/options.module
index 0d8ec00..26896d1 100644
--- a/core/modules/options/options.module
+++ b/core/modules/options/options.module
@@ -7,6 +7,7 @@
 
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\Field\FieldDefinitionInterface;
 use Drupal\field\FieldUpdateForbiddenException;
 use Drupal\options\Plugin\field\widget\OptionsWidgetBase;
 
@@ -225,42 +226,41 @@ function options_field_update_field($field, $prior_field, $has_data) {
  * The strings are not safe for output. Keys and values of the array should be
  * sanitized through field_filter_xss() before being displayed.
  *
- * @param $field
+ * @param \Drupal\Core\Entity\Field\FieldDefinitionInterface $field_definition
  *   The field definition.
- * @param $instance
- *   (optional) A field instance array. Defaults to NULL.
  * @param \Drupal\Core\Entity\EntityInterface $entity
- *   (optional) The entity object. Defaults to NULL.
+ *   The entity object.
  *
  * @return
  *   The array of allowed values. Keys of the array are the raw stored values
  *   (number or text), values of the array are the display labels.
  */
-function options_allowed_values($field, $instance = NULL, EntityInterface $entity = NULL) {
+function options_allowed_values(FieldDefinitionInterface $field_definition, EntityInterface $entity = NULL) {
   $allowed_values = &drupal_static(__FUNCTION__, array());
 
-  if (!isset($allowed_values[$field['uuid']])) {
-    $function = $field['settings']['allowed_values_function'];
+  $cache_id = implode(':', array($entity->entityType(), $entity->bundle(), $field_definition->getName()));
+  if (!isset($allowed_values[$cache_id])) {
+    $function = $field_definition->getSetting('allowed_values_function');
     // If $cacheable is FALSE, then the allowed values are not statically
     // cached. See options_test_dynamic_values_callback() for an example of
     // generating dynamic and uncached values.
     $cacheable = TRUE;
     if (!empty($function)) {
-      $values = $function($field, $instance, $entity, $cacheable);
+      $values = $function($field_definition, $entity, $cacheable);
     }
     else {
-      $values = $field['settings']['allowed_values'];
+      $values = $field_definition->getSetting('allowed_values');
     }
 
     if ($cacheable) {
-      $allowed_values[$field['uuid']] = $values;
+      $allowed_values[$cache_id] = $values;
     }
     else {
       return $values;
     }
   }
 
-  return $allowed_values[$field['uuid']];
+  return $allowed_values[$cache_id];
 }
 
 /**
@@ -400,7 +400,7 @@ function _options_values_in_use($field, $values) {
  * - 'list_illegal_value': The value is not part of the list of allowed values.
  */
 function options_field_validate(EntityInterface $entity = NULL, $field, $instance, $langcode, $items, &$errors) {
-  $allowed_values = options_allowed_values($field, $instance, $entity);
+  $allowed_values = options_allowed_values($instance, $entity);
   foreach ($items as $delta => $item) {
     if (!empty($item['value'])) {
       if (!empty($allowed_values) && !isset($allowed_values[$item['value']])) {
@@ -426,7 +426,7 @@ function options_field_is_empty($item, $field) {
 /**
  * Implements hook_options_list().
  */
-function options_options_list($field, $instance, $entity) {
-  return options_allowed_values($field, $instance, $entity);
+function options_options_list(FieldDefinitionInterface $field_definition, EntityInterface $entity) {
+  return options_allowed_values($field_definition, $entity);
 }
 
diff --git a/core/modules/options/tests/options_test.module b/core/modules/options/tests/options_test.module
index 90f6bf1..a4c9c42 100644
--- a/core/modules/options/tests/options_test.module
+++ b/core/modules/options/tests/options_test.module
@@ -6,11 +6,12 @@
  */
 
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\Field\FieldDefinitionInterface;
 
 /**
  * Allowed values callback.
  */
-function options_test_allowed_values_callback($field, $instance, $entity) {
+function options_test_allowed_values_callback(FieldDefinitionInterface $field_definition, EntityInterface $entity) {
   $values = array(
     'Group 1' => array(
       0 => 'Zero',
@@ -27,7 +28,7 @@ function options_test_allowed_values_callback($field, $instance, $entity) {
 /**
  * An entity-bound allowed values callback.
  */
-function options_test_dynamic_values_callback($field, $instance, EntityInterface $entity, &$cacheable) {
+function options_test_dynamic_values_callback(FieldDefinitionInterface $field_definition, EntityInterface $entity, &$cacheable) {
   $cacheable = FALSE;
   // We need the values of the entity as keys.
   return drupal_map_assoc(array(
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/widget/TaxonomyAutocompleteWidget.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/widget/TaxonomyAutocompleteWidget.php
index 7ceb350..7a87963 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/widget/TaxonomyAutocompleteWidget.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/widget/TaxonomyAutocompleteWidget.php
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Definition of Drupal\taxonomy\Plugin\field\widget\TaxonomyAutocompleteWidget.
+ * Contains \Drupal\taxonomy\Plugin\field\widget\TaxonomyAutocompleteWidget.
  */
 
 namespace Drupal\taxonomy\Plugin\field\widget;
@@ -32,7 +32,7 @@
 class TaxonomyAutocompleteWidget extends WidgetBase {
 
   /**
-   * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::settingsForm().
+   * {@inheritdoc}
    */
   public function settingsForm(array $form, array &$form_state) {
     $element['placeholder'] = array(
@@ -45,11 +45,9 @@ public function settingsForm(array $form, array &$form_state) {
   }
 
   /**
-   * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::formElement().
+   * {@inheritdoc}
    */
   public function formElement(array $items, $delta, array $element, $langcode, array &$form, array &$form_state) {
-    $field = $this->field;
-
     $tags = array();
     foreach ($items as $item) {
       $tags[$item['tid']] = isset($item['taxonomy_term']) ? $item['taxonomy_term'] : taxonomy_term_load($item['tid']);
@@ -57,7 +55,7 @@ public function formElement(array $items, $delta, array $element, $langcode, arr
     $element += array(
       '#type' => 'textfield',
       '#default_value' => taxonomy_implode_tags($tags),
-      '#autocomplete_path' => $this->getSetting('autocomplete_path') . '/' . $field['field_name'],
+      '#autocomplete_path' => $this->getSetting('autocomplete_path') . '/' . $this->fieldDefinition->getName(),
       '#size' => $this->getSetting('size'),
       '#placeholder' => $this->getSetting('placeholder'),
       '#maxlength' => 1024,
@@ -68,16 +66,15 @@ public function formElement(array $items, $delta, array $element, $langcode, arr
   }
 
   /**
-   * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::massageFormValues()
+   * {@inheritdoc}
    */
   public function massageFormValues(array $values, array $form, array &$form_state) {
     // Autocomplete widgets do not send their tids in the form, so we must detect
     // them here and process them independently.
     $items = array();
-    $field = $this->field;
 
     // Collect candidate vocabularies.
-    foreach ($field['settings']['allowed_values'] as $tree) {
+    foreach ($this->getFieldSetting('allowed_values') as $tree) {
       if ($vocabulary = entity_load('taxonomy_vocabulary', $tree['vocabulary'])) {
         $vocabularies[$vocabulary->id()] = $vocabulary;
       }
diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module
index f1c2e01..bbd203e 100644
--- a/core/modules/taxonomy/taxonomy.module
+++ b/core/modules/taxonomy/taxonomy.module
@@ -929,9 +929,9 @@ function taxonomy_field_widget_info_alter(&$info) {
 /**
  * Implements hook_options_list().
  */
-function taxonomy_options_list($field, $instance, $entity) {
-  $function = !empty($field['settings']['options_list_callback']) ? $field['settings']['options_list_callback'] : 'taxonomy_allowed_values';
-  return $function($field, $instance, $entity);
+function taxonomy_options_list(array $field_definition, $entity) {
+  $function = !empty($field_definition['settings']['options_list_callback']) ? $field_definition['settings']['options_list_callback'] : 'taxonomy_allowed_values';
+  return $function($field_definition, $entity);
 }
 
 /**
@@ -1003,21 +1003,17 @@ function taxonomy_field_is_empty($item, $field) {
 /**
  * Returns the set of valid terms for a taxonomy field.
  *
- * @param $field
- *   The field definition.
- * @param $instance
- *   The instance definition. It is recommended to only use instance level
- *   properties to filter out values from a list defined by field level
- *   properties.
+ * @param array $field_definition
+ *   The field definition array.
  * @param \Drupal\Core\Entity\EntityInterface $entity
  *   The entity object the field is attached to.
  *
  * @return
  *   The array of valid terms for this field, keyed by term id.
  */
-function taxonomy_allowed_values($field, $instance, EntityInterface $entity) {
+function taxonomy_allowed_values(array $field_definition, EntityInterface $entity) {
   $options = array();
-  foreach ($field['settings']['allowed_values'] as $tree) {
+  foreach ($field_definition['settings']['allowed_values'] as $tree) {
     if ($vocabulary = taxonomy_vocabulary_load($tree['vocabulary'])) {
       if ($terms = taxonomy_get_tree($vocabulary->id(), $tree['parent'], NULL, TRUE)) {
         foreach ($terms as $term) {
diff --git a/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextDefaultFormatter.php b/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextDefaultFormatter.php
index 4a96cc3..0d76811 100644
--- a/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextDefaultFormatter.php
+++ b/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextDefaultFormatter.php
@@ -38,7 +38,7 @@ public function viewElements(EntityInterface $entity, $langcode, array $items) {
     $elements = array();
 
     foreach ($items as $delta => $item) {
-      $output = text_sanitize($this->instance['settings']['text_processing'], $langcode, $item, 'value');
+      $output = text_sanitize($this->getFieldSetting('text_processing'), $langcode, $item, 'value');
       $elements[$delta] = array('#markup' => $output);
     }
 
diff --git a/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextTrimmedFormatter.php b/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextTrimmedFormatter.php
index 4be366d..fa33b74 100644
--- a/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextTrimmedFormatter.php
+++ b/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextTrimmedFormatter.php
@@ -70,11 +70,11 @@ public function viewElements(EntityInterface $entity, $langcode, array $items) {
 
     foreach ($items as $delta => $item) {
       if ($this->getPluginId() == 'text_summary_or_trimmed' && !empty($item['summary'])) {
-        $output = text_sanitize($this->instance['settings']['text_processing'], $langcode, $item, 'summary');
+        $output = text_sanitize($this->getFieldSetting('text_processing'), $langcode, $item, 'summary');
       }
       else {
-        $output = text_sanitize($this->instance['settings']['text_processing'], $langcode, $item, 'value');
-        $output = text_summary($output, $this->instance['settings']['text_processing'] ? $item['format'] : NULL, $this->getSetting('trim_length'));
+        $output = text_sanitize($this->getFieldSetting('text_processing'), $langcode, $item, 'value');
+        $output = text_summary($output, $this->getFieldSetting('text_processing') ? $item['format'] : NULL, $this->getSetting('trim_length'));
       }
       $elements[$delta] = array('#markup' => $output);
     }
diff --git a/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextareaWidget.php b/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextareaWidget.php
index 496ea12..2fe37a0 100644
--- a/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextareaWidget.php
+++ b/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextareaWidget.php
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Definition of Drupal\text\Plugin\field\widget\TextareaWidget.
+ * Contains \Drupal\text\Plugin\field\widget\TextareaWidget.
  */
 
 namespace Drupal\text\Plugin\field\widget;
@@ -30,7 +30,7 @@
 class TextareaWidget extends WidgetBase {
 
   /**
-   * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::settingsForm().
+   * {@inheritdoc}
    */
   public function settingsForm(array $form, array &$form_state) {
     $element['rows'] = array(
@@ -50,7 +50,7 @@ public function settingsForm(array $form, array &$form_state) {
   }
 
   /**
-   * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::formElement().
+   * {@inheritdoc}
    */
   public function formElement(array $items, $delta, array $element, $langcode, array &$form, array &$form_state) {
     $main_widget = $element + array(
@@ -61,7 +61,7 @@ public function formElement(array $items, $delta, array $element, $langcode, arr
       '#attributes' => array('class' => array('text-full')),
     );
 
-    if ($this->instance['settings']['text_processing']) {
+    if ($this->getFieldSetting('text_processing')) {
       $element = $main_widget;
       $element['#type'] = 'text_format';
       $element['#format'] = isset($items[$delta]['format']) ? $items[$delta]['format'] : NULL;
diff --git a/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextareaWithSummaryWidget.php b/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextareaWithSummaryWidget.php
index b3a68ac..b98ce32 100644
--- a/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextareaWithSummaryWidget.php
+++ b/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextareaWithSummaryWidget.php
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Definition of Drupal\text\Plugin\field\widget\TextareaWithSummaryWidget.
+ * Contains \Drupal\text\Plugin\field\widget\TextareaWithSummaryWidget.
  */
 
 namespace Drupal\text\Plugin\field\widget;
@@ -30,12 +30,12 @@
 class TextareaWithSummaryWidget extends TextareaWidget {
 
   /**
-   * Overrides TextareaWidget::formElement().
+   * {@inheritdoc}
    */
   function formElement(array $items, $delta, array $element, $langcode, array &$form, array &$form_state) {
     $element = parent::formElement($items, $delta, $element, $langcode, $form, $form_state);
 
-    $display_summary = !empty($items[$delta]['summary']) || $this->instance['settings']['display_summary'];
+    $display_summary = !empty($items[$delta]['summary']) || $this->getFieldSetting('display_summary');
     $element['summary'] = array(
       '#type' => $display_summary ? 'textarea' : 'value',
       '#default_value' => isset($items[$delta]['summary']) ? $items[$delta]['summary'] : NULL,
@@ -55,7 +55,7 @@ function formElement(array $items, $delta, array $element, $langcode, array &$fo
   }
 
   /**
-   * Overrides TextareaWidget::errorElement().
+   * {@inheritdoc}
    */
   public function errorElement(array $element, array $error, array $form, array &$form_state) {
     switch ($error['error']) {
diff --git a/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextfieldWidget.php b/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextfieldWidget.php
index a6e26b7..7012c75 100644
--- a/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextfieldWidget.php
+++ b/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextfieldWidget.php
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Definition of Drupal\text\Plugin\field\widget\TextfieldWidget.
+ * Contains \Drupal\text\Plugin\field\widget\TextfieldWidget.
  */
 
 namespace Drupal\text\Plugin\field\widget;
@@ -30,7 +30,7 @@
 class TextfieldWidget extends WidgetBase {
 
   /**
-   * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::settingsForm().
+   * {@inheritdoc}
    */
   public function settingsForm(array $form, array &$form_state) {
     $element['size'] = array(
@@ -50,7 +50,7 @@ public function settingsForm(array $form, array &$form_state) {
   }
 
   /**
-   * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::formElement().
+   * {@inheritdoc}
    */
   public function formElement(array $items, $delta, array $element, $langcode, array &$form, array &$form_state) {
     $main_widget = $element + array(
@@ -58,11 +58,11 @@ public function formElement(array $items, $delta, array $element, $langcode, arr
       '#default_value' => isset($items[$delta]['value']) ? $items[$delta]['value'] : NULL,
       '#size' => $this->getSetting('size'),
       '#placeholder' => $this->getSetting('placeholder'),
-      '#maxlength' => $this->field['settings']['max_length'],
+      '#maxlength' => $this->getFieldSetting('max_length'),
       '#attributes' => array('class' => array('text-full')),
     );
 
-    if ($this->instance['settings']['text_processing']) {
+    if ($this->getFieldSetting('text_processing')) {
       $element = $main_widget;
       $element['#type'] = 'text_format';
       $element['#format'] = isset($items[$delta]['format']) ? $items[$delta]['format'] : NULL;
diff --git a/core/modules/views/lib/Drupal/views/Plugin/entity_reference/selection/ViewsSelection.php b/core/modules/views/lib/Drupal/views/Plugin/entity_reference/selection/ViewsSelection.php
index f872f7d..481c0b1 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/entity_reference/selection/ViewsSelection.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/entity_reference/selection/ViewsSelection.php
@@ -36,9 +36,8 @@ class ViewsSelection implements SelectionInterface {
   /**
    * Constructs a View selection handler.
    */
-  public function __construct($field, $instance = NULL, EntityInterface $entity = NULL) {
-    $this->field = $field;
-    $this->instance = $instance;
+  public function __construct(array $field_definition, EntityInterface $entity = NULL) {
+    $this->field_definition = $field_definition;
     $this->entity = $entity;
   }
 
@@ -117,13 +116,13 @@ public static function settingsForm(&$field, &$instance) {
    *   Return TRUE if the view was initialized, FALSE otherwise.
    */
   protected function initializeView($match = NULL, $match_operator = 'CONTAINS', $limit = 0, $ids = NULL) {
-    $view_name = $this->instance['settings']['handler_settings']['view']['view_name'];
-    $display_name = $this->instance['settings']['handler_settings']['view']['display_name'];
+    $view_name = $this->field_definition['settings']['handler_settings']['view']['view_name'];
+    $display_name = $this->field_definition['settings']['handler_settings']['view']['display_name'];
 
     // Check that the view is valid and the display still exists.
     $this->view = views_get_view($view_name);
     if (!$this->view || !$this->view->access($display_name)) {
-      drupal_set_message(t('The reference view %view_name used in the %field_name field cannot be found.', array('%view_name' => $view_name, '%field_name' => $this->instance['label'])), 'warning');
+      drupal_set_message(t('The reference view %view_name used in the %field_name field cannot be found.', array('%view_name' => $view_name, '%field_name' => $this->field_definition['label'])), 'warning');
       return FALSE;
     }
     $this->view->setDisplay($display_name);
@@ -143,8 +142,8 @@ protected function initializeView($match = NULL, $match_operator = 'CONTAINS', $
    * Implements \Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface::getReferencableEntities().
    */
   public function getReferencableEntities($match = NULL, $match_operator = 'CONTAINS', $limit = 0) {
-    $display_name = $this->instance['settings']['handler_settings']['view']['display_name'];
-    $arguments = $this->instance['settings']['handler_settings']['view']['arguments'];
+    $display_name = $this->field_definition['settings']['handler_settings']['view']['display_name'];
+    $arguments = $this->field_definition['settings']['handler_settings']['view']['arguments'];
     $result = array();
     if ($this->initializeView($match, $match_operator, $limit)) {
       // Get the results.
@@ -173,8 +172,8 @@ public function countReferencableEntities($match = NULL, $match_operator = 'CONT
    * Implements \Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface::validateReferencableEntities().
    */
   public function validateReferencableEntities(array $ids) {
-    $display_name = $this->instance['settings']['handler_settings']['view']['display_name'];
-    $arguments = $this->instance['settings']['handler_settings']['view']['arguments'];
+    $display_name = $this->field_definition['settings']['handler_settings']['view']['display_name'];
+    $arguments = $this->field_definition['settings']['handler_settings']['view']['arguments'];
     $result = array();
     if ($this->initializeView(NULL, 'CONTAINS', 0, $ids)) {
       // Get the results.
