diff --git a/core/includes/entity.api.php b/core/includes/entity.api.php
index 65725b660b06c13436566a786dc1cfdf4370460d..148f11dd8cb11097b043f195f99cbb125ee883bc 100644
--- a/core/includes/entity.api.php
+++ b/core/includes/entity.api.php
@@ -451,6 +451,27 @@ function hook_entity_display_alter(\Drupal\entity\Plugin\Core\Entity\EntityDispl
   }
 }
 
+/**
+ * Alters the settings used for displaying an entity form.
+ *
+ * @param \Drupal\entity\Plugin\Core\Entity\EntityFormDisplay $form_display
+ *   The entity_form_display object that will be used to display the entity form
+ *   components.
+ * @param array $context
+ *   An associative array containing:
+ *   - entity_type: The entity type, e.g., 'node' or 'user'.
+ *   - bundle: The bundle, e.g., 'page' or 'article'.
+ *   - form_mode: The form mode, e.g. 'default', 'profile', 'register'...
+ */
+function hook_entity_form_display_alter(\Drupal\entity\Plugin\Core\Entity\EntityFormDisplay $form_display, array $context) {
+  // Hide the 'user_picture' field from the register form.
+  if ($context['entity_type'] == 'user' && $context['form_mode'] == 'register') {
+    $form_display->setComponent('user_picture', array(
+      'type' => 'hidden',
+    ));
+  }
+}
+
 /**
  * Define custom entity properties.
  *
diff --git a/core/includes/entity.inc b/core/includes/entity.inc
index 53d8bcf6983af1af1040801f0b54d476e0b91994..444634b3500d827ea292067bb19b76d5fa3c3143 100644
--- a/core/includes/entity.inc
+++ b/core/includes/entity.inc
@@ -662,7 +662,7 @@ function entity_get_display($entity_type, $bundle, $view_mode) {
     $display = entity_create('entity_display', array(
       'targetEntityType' => $entity_type,
       'bundle' => $bundle,
-      'viewMode' => $view_mode,
+      'mode' => $view_mode,
     ));
   }
 
@@ -691,7 +691,7 @@ function entity_get_display($entity_type, $bundle, $view_mode) {
  * @return \Drupal\entity\Plugin\Core\Entity\EntityDisplay
  *   The display object that should be used to render the entity.
  *
- * @see entity_get_render_display().
+ * @see entity_get_display().
  */
 function entity_get_render_display(EntityInterface $entity, $view_mode) {
   $entity_type = $entity->entityType();
@@ -704,11 +704,98 @@ function entity_get_render_display(EntityInterface $entity, $view_mode) {
   $render_view_mode = !empty($view_mode_settings[$view_mode]['status']) ? $view_mode : 'default';
 
   $display = entity_get_display($entity_type, $bundle, $render_view_mode);
-  $display->originalViewMode = $view_mode;
+  $display->originalMode = $view_mode;
 
   return $display;
 }
 
+/**
+ * Returns the entity_form_display object associated to a bundle and form mode.
+ *
+ * The function reads the entity_form_display object from the current
+ * configuration, or returns a ready-to-use empty one if configuration entry
+ * exists yet for this bundle and form mode. This streamlines manipulation of
+ * EntityFormDisplay objects by always returning a consistent object that
+ * reflects the current state of the configuration.
+ *
+ * Example usage:
+ * - Set the 'body' field to be displayed with the 'text_textarea_with_summary'
+ *   widget and the 'field_image' field to be hidden on article nodes in the
+ *  'default' form mode.
+ * @code
+ * entity_get_form_display('node', 'article', 'default')
+ *   ->setComponent('body', array(
+ *     'type' => 'text_textarea_with_summary',
+ *     'weight' => 1,
+ *   ))
+ *   ->setComponent('field_image', array(
+ *     'type' => 'hidden',
+ *   ))
+ *   ->save();
+ * @endcode
+ *
+ * @param string $entity_type
+ *   The entity type.
+ * @param string $bundle
+ *   The bundle.
+ * @param string $form_mode
+ *   The form mode.
+ *
+ * @return \Drupal\entity\Plugin\Core\Entity\EntityFormDisplay
+ *   The EntityFormDisplay object associated to the form mode.
+ */
+function entity_get_form_display($entity_type, $bundle, $form_mode) {
+  // Try loading the entity from configuration.
+  $entity_form_display = entity_load('entity_form_display', $entity_type . '.' . $bundle . '.' . $form_mode);
+
+  // If not found, create a fresh entity object. We do not preemptively create
+  // new EntityFormDisplay configuration entries for each existing entity type
+  // and bundle whenever a new form mode becomes available. Instead,
+  // configuration entries are only created when a EntityFormDisplay object is
+  // explicitly configured and saved.
+  if (!$entity_form_display) {
+    $entity_form_display = entity_create('entity_form_display', array(
+      'targetEntityType' => $entity_type,
+      'bundle' => $bundle,
+      'mode' => $form_mode,
+    ));
+  }
+
+  return $entity_form_display;
+}
+
+/**
+ * Returns the entity_form_display object used to render an entity form.
+ *
+ * This function should only be used internally when rendering an entity form.
+ * When assigning suggested form display options for a component in a given form
+ * mode, entity_get_form_display() should be used instead, in order to avoid
+ * inadvertently modifying the output of other form modes that might happen to
+ * use the 'default' form display too. Those options will then be effectively
+ * applied only if the form mode is configured to use them.
+ *
+ * @param \Drupal\Core\Entity\EntityInterface $entity
+ *   The entity for which the form is being rendered.
+ * @param string $form_mode
+ *   The form mode being rendered.
+ *
+ * @return \Drupal\entity\Plugin\Core\Entity\EntityFormDisplay
+ *   The form display object that should be used to render the entity form.
+ *
+ * @see entity_get_form_display().
+ */
+function entity_get_render_form_display(EntityInterface $entity, $form_mode) {
+  $entity_type = $entity->entityType();
+  $bundle = $entity->bundle();
+
+  // @todo Form modes don't have custom settings yet, so just return the display
+  // for the form mode that was requested.
+  $form_display = entity_get_form_display($entity_type, $bundle, $form_mode);
+  $form_display->originalMode = $form_mode;
+
+  return $form_display;
+}
+
 /**
  * Generic access callback for entity pages.
  *
diff --git a/core/lib/Drupal/Core/Entity/EntityFormController.php b/core/lib/Drupal/Core/Entity/EntityFormController.php
index 98d4a3d6fafe07d277379239914437f04e43ba75..53f1de3e7939a4349f43590ada6f11349ff02651 100644
--- a/core/lib/Drupal/Core/Entity/EntityFormController.php
+++ b/core/lib/Drupal/Core/Entity/EntityFormController.php
@@ -7,6 +7,8 @@
 
 namespace Drupal\Core\Entity;
 
+use Drupal\entity\EntityFormDisplayInterface;
+
 /**
  * Base class for entity form controllers.
  */
@@ -117,6 +119,20 @@ protected function init(array &$form_state) {
     // module-provided form handlers there.
     $form_state['controller'] = $this;
     $this->prepareEntity();
+
+    // @todo Allow the usage of different form modes by exposing a hook and the
+    // UI for them.
+    $form_display = entity_get_render_form_display($this->entity, 'default');
+
+    // Let modules alter the form display.
+    $form_display_context = array(
+      'entity_type' => $this->entity->entityType(),
+      'bundle' => $this->entity->bundle(),
+      'form_mode' => 'default',
+    );
+    \Drupal::moduleHandler()->alter('entity_form_display', $form_display, $form_display_context);
+
+    $this->setFormDisplay($form_display, $form_state);
   }
 
   /**
@@ -132,6 +148,14 @@ public function form(array $form, array &$form_state) {
     if (!empty($info['fieldable'])) {
       field_attach_form($entity, $form, $form_state, $this->getFormLangcode($form_state));
     }
+
+    // Assign the weights configured in the form display.
+    foreach ($this->getFormDisplay($form_state)->getComponents() as $name => $options) {
+      if (isset($form[$name])) {
+        $form[$name]['#weight'] = $options['weight'];
+      }
+    }
+
     if (!isset($form['langcode'])) {
       // If the form did not specify otherwise, default to keeping the existing
       // language of the entity or defaulting to the site default language for
@@ -393,6 +417,21 @@ protected function prepareEntity() {
     // @todo Perform common prepare operations and add a hook.
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormDisplay(array $form_state) {
+    return isset($form_state['form_display']) ? $form_state['form_display'] : NULL;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setFormDisplay(EntityFormDisplayInterface $form_display, array &$form_state) {
+    $form_state['form_display'] = $form_display;
+    return $this;
+  }
+
   /**
    * Implements \Drupal\Core\Entity\EntityFormControllerInterface::getOperation().
    */
diff --git a/core/lib/Drupal/Core/Entity/EntityFormControllerInterface.php b/core/lib/Drupal/Core/Entity/EntityFormControllerInterface.php
index 289df868ebd46a4d27aea15041445107f25925e2..d52363c6c569ff22ce2f85fb3a81cda5e75acc84 100644
--- a/core/lib/Drupal/Core/Entity/EntityFormControllerInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityFormControllerInterface.php
@@ -8,6 +8,7 @@
 namespace Drupal\Core\Entity;
 
 use Drupal\Core\Form\BaseFormIdInterface;
+use Drupal\entity\EntityFormDisplayInterface;
 
 /**
  * Defines a common interface for entity form controller classes.
@@ -44,6 +45,30 @@ public function isDefaultFormLangcode(array $form_state);
    */
   public function getOperation();
 
+  /**
+   * Returns the form display.
+   *
+   * @param array $form_state
+   *   An associative array containing the current state of the form.
+   *
+   * @return \Drupal\entity\EntityFormDisplayInterface
+   *   The current form display.
+   */
+  public function getFormDisplay(array $form_state);
+
+  /**
+   * Sets the form display.
+   *
+   * Sets the form display which will be used for populating form element
+   * defaults.
+   *
+   * @param \Drupal\entity\EntityFormDisplayInterface $form_display
+   *   The form display that the current form operates with.
+   * @param array $form_state
+   *   An associative array containing the current state of the form.
+   */
+  public function setFormDisplay(EntityFormDisplayInterface $form_display, array &$form_state);
+
   /**
    * Returns the form entity.
    *
diff --git a/core/lib/Drupal/Core/Entity/EntityFormControllerNG.php b/core/lib/Drupal/Core/Entity/EntityFormControllerNG.php
index e886e1da01f93281ba441960e0480809ddb39a6f..40ef05699fc803a9e9b3d7261bae2b9d5119ba02 100644
--- a/core/lib/Drupal/Core/Entity/EntityFormControllerNG.php
+++ b/core/lib/Drupal/Core/Entity/EntityFormControllerNG.php
@@ -30,6 +30,14 @@ public function form(array $form, array &$form_state) {
     if (!empty($info['fieldable'])) {
       field_attach_form($entity, $form, $form_state, $this->getFormLangcode($form_state));
     }
+
+    // Assign the weights configured in the form display.
+    foreach ($this->getFormDisplay($form_state)->getComponents() as $name => $options) {
+      if (isset($form[$name])) {
+        $form[$name]['#weight'] = $options['weight'];
+      }
+    }
+
     return $form;
   }
 
diff --git a/core/modules/block/block.install b/core/modules/block/block.install
index 01c57795967b954842041283197009d7a1210eb4..bb9806e255c39254f0efa27f16f76297d7b339b6 100644
--- a/core/modules/block/block.install
+++ b/core/modules/block/block.install
@@ -259,11 +259,19 @@ function block_update_8008() {
       'entity_type' => 'custom_block',
       'bundle' => 'basic',
       'label' => 'Block body',
-      'widget' => array('type' => 'text_textarea_with_summary'),
       'settings' => array('display_summary' => FALSE),
     );
     _update_7000_field_create_instance($body_field, $instance);
 
+    module_load_install('entity');
+    // Assign form settings for the 'default' form mode.
+    $form_display = _update_8000_entity_get_form_display('custom_block', 'basic', 'default');
+    $form_display->set('content.user_picture', array(
+        'type' => 'text_textarea_with_summary',
+      ))
+      ->save();
+    update_config_manifest_add('entity.form_display', array($form_display->get('id')));
+
     // Initialize state for future calls.
     $sandbox['last'] = 0;
     $sandbox['count'] = 0;
diff --git a/core/modules/block/custom_block/custom_block.module b/core/modules/block/custom_block/custom_block.module
index 99738b39af4c95f8650481236d13702a492082fa..b8785dee4fda92ac79967a29ee97b2950779241d 100644
--- a/core/modules/block/custom_block/custom_block.module
+++ b/core/modules/block/custom_block/custom_block.module
@@ -214,11 +214,17 @@ function custom_block_add_body_field($block_type_id, $label = 'Block body') {
       'entity_type' => 'custom_block',
       'bundle' => $block_type_id,
       'label' => $label,
-      'widget' => array('type' => 'text_textarea_with_summary'),
       'settings' => array('display_summary' => FALSE),
     );
     $instance = field_create_instance($instance);
 
+    // Assign widget settings for the 'default' form mode.
+    entity_get_form_display('custom_block', $block_type_id, 'default')
+      ->setComponent('block_body', array(
+        'type' => 'text_textarea_with_summary',
+      ))
+      ->save();
+
     // Assign display settings for 'default' view mode.
     entity_get_display('custom_block', $block_type_id, 'default')
       ->setComponent('block_body', array(
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockFieldTest.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockFieldTest.php
index ab9a9382383fe81c646e580a850e19016216753b..909dd128afbd5250ce4c6f20377084aa2a11598e 100644
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockFieldTest.php
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockFieldTest.php
@@ -77,17 +77,18 @@ public function testBlockFields() {
       'settings' => array(
         'title' => DRUPAL_OPTIONAL,
       ),
-      'widget' => array(
-        'type' => 'link_default',
-      ),
-    );
-    $display_options = array(
-      'type' => 'link',
-      'label' => 'hidden',
     );
     field_create_instance($this->instance);
+    entity_get_form_display('custom_block', 'link', 'default')
+      ->setComponent($this->field['field_name'], array(
+        'type' => 'link_default',
+      ))
+      ->save();
     entity_get_display('custom_block', 'link', 'default')
-      ->setComponent($this->field['field_name'], $display_options)
+      ->setComponent($this->field['field_name'], array(
+        'type' => 'link',
+        'label' => 'hidden',
+      ))
       ->save();
 
     // Create a block.
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index 717a25b25d59a3e9b3d2fad65b74059afb60c84a..0c2cd55a1c40a0998a289dc2ecc6059170af205c 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -365,6 +365,15 @@ function _comment_body_field_create($info) {
       'required' => TRUE,
     );
     field_create_instance($instance);
+
+    // Assign widget settings for the 'default' form mode.
+    entity_get_form_display('comment', 'comment_node_' . $info->type, 'default')
+      ->setComponent('comment_body', array(
+        'type' => 'text_textarea',
+      ))
+      ->save();
+
+    // Assign display settings for the 'default' view mode.
     entity_get_display('comment', 'comment_node_' . $info->type, 'default')
       ->setComponent('comment_body', array(
         'label' => 'hidden',
diff --git a/core/modules/datetime/datetime.module b/core/modules/datetime/datetime.module
index 79905f8ae5fc261cb0013213036a81f2a66c34cc..b545c36b5138bde978e18fe596ae3d3f37587b59 100644
--- a/core/modules/datetime/datetime.module
+++ b/core/modules/datetime/datetime.module
@@ -134,9 +134,7 @@ function datetime_field_settings_form($field, $instance, $has_data) {
  * Implements hook_field_instance_settings_form().
  */
 function datetime_field_instance_settings_form($field, $instance) {
-  $widget = $instance['widget'];
   $settings = $instance['settings'];
-  $widget_settings = $instance['widget']['settings'];
 
   $form['default_value'] = array(
     '#type' => 'select',
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 366a4c43bd8edd9177487377f5a666f4a8571d6e..f0d60fe7fa223872501b1b3776c028caddcca77d 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
@@ -36,23 +36,12 @@
 class DateTimeDatelistWidget extends WidgetBase {
 
   /**
-   * Constructs a DateTimeDatelist Widget object.
-   *
-   * @param array $plugin_id
-   *   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 array $settings
-   *   The widget settings.
-   * @param int $weight
-   *   The widget weight.
+   * {@inheritdoc}
    */
-  public function __construct($plugin_id, array $plugin_definition, FieldInstance $instance, array $settings, $weight) {
+  public function __construct($plugin_id, array $plugin_definition, FieldInstance $instance, 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, $weight);
+    parent::__construct($plugin_id, $plugin_definition, $instance, $settings);
   }
 
   /**
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 d51bac431be284f437227268ee4ba69ba110ca46..f0c45c04ad2ed3625df53f811afadd440d1c7782 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
@@ -30,23 +30,12 @@
 class DateTimeDefaultWidget extends WidgetBase {
 
   /**
-   * Constructs a DateTimeDefault Widget object.
-   *
-   * @param array $plugin_id
-   *   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 array $settings
-   *   The widget settings.
-   * @param int $weight
-   *   The widget weight.
+   * {@inheritdoc}
    */
-  public function __construct($plugin_id, array $plugin_definition, FieldInstance $instance, array $settings, $weight) {
+  public function __construct($plugin_id, array $plugin_definition, FieldInstance $instance, 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, $weight);
+    parent::__construct($plugin_id, $plugin_definition, $instance, $settings);
   }
 
   /**
diff --git a/core/modules/datetime/lib/Drupal/datetime/Tests/DatetimeFieldTest.php b/core/modules/datetime/lib/Drupal/datetime/Tests/DatetimeFieldTest.php
index bb3bddfd0aa9ecef9be10b62e3b43a367ef360c3..ac3f4a32d4456ad7fd1c030bf2e15434a0629b7a 100644
--- a/core/modules/datetime/lib/Drupal/datetime/Tests/DatetimeFieldTest.php
+++ b/core/modules/datetime/lib/Drupal/datetime/Tests/DatetimeFieldTest.php
@@ -57,14 +57,17 @@ function setUp() {
       'field_name' => $this->field['field_name'],
       'entity_type' => 'test_entity',
       'bundle' => 'test_bundle',
-      'widget' => array(
-        'type' => 'datetime_default',
-      ),
       'settings' => array(
         'default_value' => 'blank',
       ),
     ));
 
+    entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
+      ->setComponent($this->field['field_name'], array(
+        'type' => 'datetime_default',
+      ))
+      ->save();
+
     $this->display_options = array(
       'type' => 'datetime_default',
       'label' => 'hidden',
@@ -217,17 +220,16 @@ function testDatelistWidget() {
     field_update_field($this->field);
 
     // Change the widget to a datelist widget.
-    $increment = 1;
-    $date_order = 'YMD';
-    $time_type = '12';
-
-    $this->instance['widget']['type'] = 'datetime_datelist';
-    $this->instance['widget']['settings'] = array(
-      'increment' => $increment,
-      'date_order' => $date_order,
-      'time_type' => $time_type,
-    );
-    field_update_instance($this->instance);
+    entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
+      ->setComponent($this->instance['field_name'], array(
+        'type' => 'datetime_datelist',
+        'settings' => array(
+          'increment' => 1,
+          'date_order' => 'YMD',
+          'time_type' => '12',
+        ),
+      ))
+      ->save();
     field_cache_clear();
 
     // Display creation form.
diff --git a/core/modules/edit/lib/Drupal/edit/Form/EditFieldForm.php b/core/modules/edit/lib/Drupal/edit/Form/EditFieldForm.php
index 3a0da13975342db790668dbd0dc056d62a3d2266..c075b4c79b09e50f35b7aabad0bea294a1b30797 100644
--- a/core/modules/edit/lib/Drupal/edit/Form/EditFieldForm.php
+++ b/core/modules/edit/lib/Drupal/edit/Form/EditFieldForm.php
@@ -59,6 +59,20 @@ protected function init(array &$form_state, EntityInterface $entity, $field_name
 
     $form_state['entity'] = $entity;
     $form_state['field_name'] = $field_name;
+
+    // @todo Allow the usage of different form modes by exposing a hook and the
+    // UI for them.
+    $form_display = entity_get_render_form_display($entity, 'default');
+
+    // Let modules alter the form display.
+    $form_display_context = array(
+      'entity_type' => $entity->entityType(),
+      'bundle' => $entity->bundle(),
+      'form_mode' => 'default',
+    );
+    \Drupal::moduleHandler()->alter('entity_form_display', $form_display, $form_display_context);
+
+    $form_state['form_display'] = $form_display;
   }
 
   /**
diff --git a/core/modules/edit/lib/Drupal/edit/Tests/EditTestBase.php b/core/modules/edit/lib/Drupal/edit/Tests/EditTestBase.php
index d3737bb5a9f6dabcebb6a968586283f60179affb..30aec3fd530afe31903c91e9b94e9b9548ad1c38 100644
--- a/core/modules/edit/lib/Drupal/edit/Tests/EditTestBase.php
+++ b/core/modules/edit/lib/Drupal/edit/Tests/EditTestBase.php
@@ -70,13 +70,16 @@ function createFieldWithInstance($field_name, $type, $cardinality, $label, $inst
       'description' => $label,
       'weight' => mt_rand(0, 127),
       'settings' => $instance_settings,
-      'widget' => array(
+    );
+    field_create_instance($this->$instance);
+
+    entity_get_form_display('entity_test', 'entity_test', 'default')
+      ->setComponent($field_name, array(
         'type' => $widget_type,
         'label' => $label,
         'settings' => $widget_settings,
-      ),
-    );
-    field_create_instance($this->$instance);
+      ))
+      ->save();
 
     entity_get_display('entity_test', 'entity_test', 'default')
       ->setComponent($field_name, array(
diff --git a/core/modules/email/lib/Drupal/email/Tests/EmailFieldTest.php b/core/modules/email/lib/Drupal/email/Tests/EmailFieldTest.php
index c719c9792a54c373a13d8016ff9a2814a56ace70..dbb2bed71465daa8dd904f46e5bf7a1550439adc 100644
--- a/core/modules/email/lib/Drupal/email/Tests/EmailFieldTest.php
+++ b/core/modules/email/lib/Drupal/email/Tests/EmailFieldTest.php
@@ -54,14 +54,18 @@ function testEmailField() {
       'field_name' => $this->field['field_name'],
       'entity_type' => 'test_entity',
       'bundle' => 'test_bundle',
-      'widget' => array(
+    );
+    field_create_instance($this->instance);
+
+    // Create a form display for the default form mode.
+    entity_get_form_display('test_entity', 'test_bundle', 'default')
+      ->setComponent($this->field['field_name'], array(
         'type' => 'email_default',
         'settings' => array(
           'placeholder' => 'example@example.com',
         ),
-      ),
-    );
-    field_create_instance($this->instance);
+      ))
+      ->save();
     // Create a display for the full view mode.
     entity_get_display('test_entity', 'test_bundle', 'full')
       ->setComponent($this->field['field_name'], array(
diff --git a/core/modules/email/lib/Drupal/email/Tests/EmailItemTest.php b/core/modules/email/lib/Drupal/email/Tests/EmailItemTest.php
index def99f1ba52f036423bc91f9e355742f5bc1e060..1555b8d7b20cd6b0d1f66460f31edf990eb88005 100644
--- a/core/modules/email/lib/Drupal/email/Tests/EmailItemTest.php
+++ b/core/modules/email/lib/Drupal/email/Tests/EmailItemTest.php
@@ -44,11 +44,15 @@ public function setUp() {
       'entity_type' => 'entity_test',
       'field_name' => 'field_email',
       'bundle' => 'entity_test',
-      'widget' => array(
-        'type' => 'email_default',
-      ),
     );
     field_create_instance($this->instance);
+
+    // Create a form display for the default form mode.
+    entity_get_form_display('entity_test', 'entity_test', 'default')
+      ->setComponent('field_email', array(
+        'type' => 'email_default',
+      ))
+      ->save();
   }
 
   /**
diff --git a/core/modules/entity/entity.install b/core/modules/entity/entity.install
index 2e1efd751ba8e679d33e35bb776954e8625721f7..af2aba14dd120d6d7a9416ae588b60492643c6ac 100644
--- a/core/modules/entity/entity.install
+++ b/core/modules/entity/entity.install
@@ -37,7 +37,46 @@ function _update_8000_entity_get_display($entity_type, $bundle, $view_mode) {
     'uuid' => $uuid->generate(),
     'targetEntityType' => $entity_type,
     'bundle' => $bundle,
-    'viewMode' => $view_mode,
+    'mode' => $view_mode,
+    'content' => array(),
+  );
+  foreach ($properties as $key => $value) {
+    $config->set($key, $value);
+  }
+  return $config;
+}
+
+/**
+ * Returns the raw configuration object for an EntityFormDisplay entity.
+ *
+ * The function returns the existing configuration entry if it exists, or
+ * creates a fresh structure.
+ *
+ * @param string $entity_type
+ *   The entity type.
+ * @param string $bundle
+ *   The bundle name.
+ * @param string $form_mode
+ *   The form mode.
+ *
+ * @return \Drupal\Core\Config\Config
+ *   The configuration object.
+ */
+function _update_8000_entity_get_form_display($entity_type, $bundle, $form_mode) {
+  $id = $entity_type . '.' . $bundle . '.' . $form_mode;
+  $config = config("entity.form_display.$id");
+  if ($config->get()) {
+    return $config;
+  }
+
+  // Initialize a fresh structure.
+  $uuid = new Uuid();
+  $properties = array(
+    'id' => $id,
+    'uuid' => $uuid->generate(),
+    'targetEntityType' => $entity_type,
+    'bundle' => $bundle,
+    'mode' => $form_mode,
     'content' => array(),
   );
   foreach ($properties as $key => $value) {
diff --git a/core/modules/entity/entity.module b/core/modules/entity/entity.module
index 8fca68347ec16fa74109801f8f950e0d4d527b5e..7a9c8a84e19a7e50a94324ffde52ccb9d5508e9a 100644
--- a/core/modules/entity/entity.module
+++ b/core/modules/entity/entity.module
@@ -14,20 +14,33 @@
  * Implements hook_entity_bundle_rename().
  */
 function entity_entity_bundle_rename($entity_type, $bundle_old, $bundle_new) {
-  $entity_info = entity_get_info('entity_display');
-
   // Rename entity displays.
+  $entity_info = entity_get_info('entity_display');
   if ($bundle_old !== $bundle_new) {
     $ids = config_get_storage_names_with_prefix('entity.display.' . $entity_type . '.' . $bundle_old);
     foreach ($ids as $id) {
       $id = ConfigStorageController::getIDFromConfigName($id, $entity_info['config_prefix']);
       $display = entity_load('entity_display', $id);
-      $new_id = $entity_type . '.' . $bundle_new . '.' . $display->viewMode;
+      $new_id = $entity_type . '.' . $bundle_new . '.' . $display->mode;
       $display->id = $new_id;
       $display->bundle = $bundle_new;
       $display->save();
     }
   }
+
+  // Rename entity form displays.
+  $entity_info = entity_get_info('entity_form_display');
+  if ($bundle_old !== $bundle_new) {
+    $ids = config_get_storage_names_with_prefix('entity.form_display.' . $entity_type . '.' . $bundle_old);
+    foreach ($ids as $id) {
+      $id = ConfigStorageController::getIDFromConfigName($id, $entity_info['config_prefix']);
+      $form_display = entity_load('entity_form_display', $id);
+      $new_id = $entity_type . '.' . $bundle_new . '.' . $form_display->mode;
+      $form_display->id = $new_id;
+      $form_display->bundle = $bundle_new;
+      $form_display->save();
+    }
+  }
 }
 
 /**
@@ -42,4 +55,11 @@ function entity_entity_bundle_delete($entity_type, $bundle) {
     $id = ConfigStorageController::getIDFromConfigName($id, $entity_info['config_prefix']);
   }
   entity_delete_multiple('entity_display', $ids);
+
+  // Remove entity form displays of the deleted bundle.
+  $ids = config_get_storage_names_with_prefix('entity.form_display.' . $entity_type . '.' . $bundle);
+  foreach ($ids as &$id) {
+    $id = ConfigStorageController::getIDFromConfigName($id, $entity_info['config_prefix']);
+  }
+  entity_delete_multiple('entity_form_display', $ids);
 }
diff --git a/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php b/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php
new file mode 100644
index 0000000000000000000000000000000000000000..0a7ff40b8e4a6a908bb7afd659dbae00112c6295
--- /dev/null
+++ b/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php
@@ -0,0 +1,282 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\entity\EntityDisplayBase.
+ */
+
+namespace Drupal\entity;
+
+use Drupal\Core\Config\Entity\ConfigEntityBase;
+
+/**
+ * Base class for config entity types that store configuration for entity forms
+ * and displays.
+ */
+abstract class EntityDisplayBase extends ConfigEntityBase implements EntityDisplayBaseInterface {
+
+  /**
+   * Unique ID for the config entity.
+   *
+   * @var string
+   */
+  public $id;
+
+  /**
+   * Unique UUID for the config entity.
+   *
+   * @var string
+   */
+  public $uuid;
+
+  /**
+   * Entity type to be displayed.
+   *
+   * @var string
+   */
+  public $targetEntityType;
+
+  /**
+   * Bundle to be displayed.
+   *
+   * @var string
+   */
+  public $bundle;
+
+  /**
+   * View or form mode to be displayed.
+   *
+   * @var string
+   */
+  public $mode;
+
+  /**
+   * List of component display options, keyed by component name.
+   *
+   * @var array
+   */
+  protected $content = array();
+
+  /**
+   * The original view or form mode that was requested (case of view/form modes
+   * being configured to fall back to the 'default' display).
+   *
+   * @var string
+   */
+  public $originalMode;
+
+  /**
+   * The plugin objects used for this display, keyed by field name.
+   *
+   * @var array
+   */
+  protected $plugins = array();
+
+  /**
+   * Context in which this entity will be used (e.g. 'display', 'form').
+   *
+   * @var string
+   */
+  protected $displayContext;
+
+  /**
+   * The plugin manager used by this entity type.
+   *
+   * @var \Drupal\Component\Plugin\PluginManagerBase
+   */
+  protected $pluginManager;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function __construct(array $values, $entity_type) {
+    // @todo See http://drupal.org/node/1825044#comment-6847792: contact.module
+    // currently produces invalid entities with a NULL bundle in some cases.
+    // Add the validity checks back when http://drupal.org/node/1856556 is
+    // fixed.
+    // if (!isset($values['targetEntityType']) || !isset($values['bundle']) || !isset($values['mode'])) {
+    //   throw new \InvalidArgumentException('Missing required properties for an EntityDisplay entity.');
+    // }
+
+    // A plugin manager and a context type needs to be set by extending classes.
+    if (!isset($this->pluginManager)) {
+      throw new \RuntimeException('Missing plugin manager.');
+    }
+    if (!isset($this->displayContext)) {
+      throw new \RuntimeException('Missing display context type.');
+    }
+
+    parent::__construct($values, $entity_type);
+
+    $this->originalMode = $this->mode;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function id() {
+    return $this->targetEntityType . '.' . $this->bundle . '.' . $this->mode;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function save() {
+    // Build an ID if none is set.
+    if (empty($this->id)) {
+      $this->id = $this->id();
+    }
+    return parent::save();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getExportProperties() {
+    $names = array(
+      'id',
+      'uuid',
+      'targetEntityType',
+      'bundle',
+      'mode',
+      'content',
+    );
+    $properties = array();
+    foreach ($names as $name) {
+      $properties[$name] = $this->get($name);
+    }
+    return $properties;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function createCopy($mode) {
+    $display = $this->createDuplicate();
+    $display->mode = $display->originalMode = $mode;
+    return $display;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getComponents() {
+    $result = array();
+    foreach ($this->content as $name => $options) {
+      if (!isset($options['visible']) || $options['visible'] === TRUE) {
+        unset($options['visible']);
+        $result[$name] = $options;
+      }
+    }
+    return $result;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getComponent($name) {
+    // We always store 'extra fields', whether they are visible or hidden.
+    $extra_fields = field_info_extra_fields($this->targetEntityType, $this->bundle, $this->displayContext);
+    if (isset($extra_fields[$name])) {
+      // If we have explicit settings, return an array or NULL depending on
+      // visibility.
+      if (isset($this->content[$name])) {
+        if ($this->content[$name]['visible']) {
+          return array(
+            'weight' => $this->content[$name]['weight'],
+          );
+        }
+        else {
+          return NULL;
+        }
+      }
+
+      // If no explicit settings for the extra field, look at the default
+      // visibility in its definition.
+      $definition = $extra_fields[$name];
+      if (!isset($definition['visible']) || $definition['visible'] == TRUE) {
+        return array(
+          'weight' => $definition['weight']
+        );
+      }
+      else {
+        return NULL;
+      }
+    }
+
+    if (isset($this->content[$name])) {
+      return $this->content[$name];
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setComponent($name, array $options = array()) {
+    // If no weight specified, make sure the field sinks at the bottom.
+    if (!isset($options['weight'])) {
+      $max = $this->getHighestWeight();
+      $options['weight'] = isset($max) ? $max + 1 : 0;
+    }
+
+    if ($instance = field_info_instance($this->targetEntityType, $name, $this->bundle)) {
+      $field = field_info_field($instance['field_name']);
+      $options = $this->pluginManager->prepareConfiguration($field['type'], $options);
+
+      // Clear the persisted plugin, if any.
+      unset($this->plugins[$name]);
+    }
+
+    // We always store 'extra fields', whether they are visible or hidden.
+    $extra_fields = field_info_extra_fields($this->targetEntityType, $this->bundle, $this->displayContext);
+    if (isset($extra_fields[$name])) {
+      $options['visible'] = TRUE;
+    }
+
+    $this->content[$name] = $options;
+
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function removeComponent($name) {
+    $extra_fields = field_info_extra_fields($this->targetEntityType, $this->bundle, $this->displayContext);
+    if (isset($extra_fields[$name])) {
+      // 'Extra fields' are exposed in hooks and can appear at any given time.
+      // Therefore we store extra fields that are explicitly being hidden, so
+      // that we can differenciate with those that are simply not configured
+      // yet.
+      $this->content[$name] = array(
+        'visible' => FALSE,
+      );
+    }
+    else {
+      unset($this->content[$name]);
+      unset($this->plugins[$name]);
+    }
+
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getHighestWeight() {
+    $weights = array();
+
+    // Collect weights for the components in the display.
+    foreach ($this->content as $options) {
+      if (isset($options['weight'])) {
+        $weights[] = $options['weight'];
+      }
+    }
+
+    // Let other modules feedback about their own additions.
+    $weights = array_merge($weights, module_invoke_all('field_info_max_weight', $this->targetEntityType, $this->bundle, $this->displayContext, $this->mode));
+
+    return $weights ? max($weights) : NULL;
+  }
+
+}
diff --git a/core/modules/entity/lib/Drupal/entity/EntityDisplayBaseInterface.php b/core/modules/entity/lib/Drupal/entity/EntityDisplayBaseInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..42a68c079c98f07b6060de7dcb18c1ce1854ef53
--- /dev/null
+++ b/core/modules/entity/lib/Drupal/entity/EntityDisplayBaseInterface.php
@@ -0,0 +1,84 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\entity\Plugin\Core\Entity\EntityDisplayBaseInterface.
+ */
+
+namespace Drupal\entity;
+
+use Drupal\Core\Config\Entity\ConfigEntityInterface;
+
+/**
+ * Provides an interface defining an entity display entity.
+ */
+interface EntityDisplayBaseInterface extends ConfigEntityInterface {
+
+  /**
+   * Creates a duplicate of the EntityDisplay object on a different view mode.
+   *
+   * The new object necessarily has the same $targetEntityType and $bundle
+   * properties than the original one.
+   *
+   * @param $view_mode
+   *   The view mode for the new object.
+   *
+   * @return \Drupal\entity\Plugin\Core\Entity\EntityDisplay
+   *   The new object.
+   */
+  public function createCopy($view_mode);
+
+  /**
+   * Gets the display options for all components.
+   *
+   * @return array
+   *   The array of display options, keyed by component name.
+   */
+  public function getComponents();
+
+  /**
+   * Gets the display options set for a component.
+   *
+   * @param string $name
+   *   The name of the component.
+   *
+   * @return array|null
+   *   The display options for the component, or NULL if the component is not
+   *   displayed.
+   */
+  public function getComponent($name);
+
+  /**
+   * Sets the display options for a component.
+   *
+   * @param string $name
+   *   The name of the component.
+   * @param array $options
+   *   The display options.
+   *
+   * @return \Drupal\entity\Plugin\Core\Entity\EntityDisplay
+   *   The EntityDisplay object.
+   */
+  public function setComponent($name, array $options = array());
+
+  /**
+   * Sets a component to be hidden.
+   *
+   * @param string $name
+   *   The name of the component.
+   *
+   * @return \Drupal\entity\Plugin\Core\Entity\EntityDisplay
+   *   The EntityDisplay object.
+   */
+  public function removeComponent($name);
+
+  /**
+   * Returns the highest weight of the components in the display.
+   *
+   * @return int|null
+   *   The highest weight of the components in the display, or NULL if the
+   *   display is empty.
+   */
+  public function getHighestWeight();
+
+}
diff --git a/core/modules/entity/lib/Drupal/entity/EntityDisplayInterface.php b/core/modules/entity/lib/Drupal/entity/EntityDisplayInterface.php
index 0c1fa6c02fd9986f5b03d1a0d4b4501ccdfc6029..ef8a7cb6ed347beeff403e02e390a040d3ea40cd 100644
--- a/core/modules/entity/lib/Drupal/entity/EntityDisplayInterface.php
+++ b/core/modules/entity/lib/Drupal/entity/EntityDisplayInterface.php
@@ -2,84 +2,17 @@
 
 /**
  * @file
- * Contains \Drupal\entity\Plugin\Core\Entity\EntityDisplayInterface.
+ * Contains \Drupal\entity\EntityDisplayInterface.
  */
 
 namespace Drupal\entity;
 
-use Drupal\Core\Config\Entity\ConfigEntityInterface;
+use Drupal\entity\EntityDisplayBaseInterface;
 
 /**
  * Provides an interface defining an entity display entity.
  */
-interface EntityDisplayInterface extends ConfigEntityInterface {
-
-  /**
-   * Creates a duplicate of the EntityDisplay object on a different view mode.
-   *
-   * The new object necessarily has the same $targetEntityType and $bundle
-   * properties than the original one.
-   *
-   * @param $view_mode
-   *   The view mode for the new object.
-   *
-   * @return \Drupal\entity\Plugin\Core\Entity\EntityDisplay
-   *   The new object.
-   */
-  public function createCopy($view_mode);
-
-  /**
-   * Gets the display options for all components.
-   *
-   * @return array
-   *   The array of display options, keyed by component name.
-   */
-  public function getComponents();
-
-  /**
-   * Gets the display options set for a component.
-   *
-   * @param string $name
-   *   The name of the component.
-   *
-   * @return array|null
-   *   The display options for the component, or NULL if the component is not
-   *   displayed.
-   */
-  public function getComponent($name);
-
-  /**
-   * Sets the display options for a component.
-   *
-   * @param string $name
-   *   The name of the component.
-   * @param array $options
-   *   The display options.
-   *
-   * @return \Drupal\entity\Plugin\Core\Entity\EntityDisplay
-   *   The EntityDisplay object.
-   */
-  public function setComponent($name, array $options = array());
-
-  /**
-   * Sets a component to be hidden.
-   *
-   * @param string $name
-   *   The name of the component.
-   *
-   * @return \Drupal\entity\Plugin\Core\Entity\EntityDisplay
-   *   The EntityDisplay object.
-   */
-  public function removeComponent($name);
-
-  /**
-   * Returns the highest weight of the components in the display.
-   *
-   * @return int|null
-   *   The highest weight of the components in the display, or NULL if the
-   *   display is empty.
-   */
-  public function getHighestWeight();
+interface EntityDisplayInterface extends EntityDisplayBaseInterface {
 
   /**
    * Returns the Formatter plugin for a field.
diff --git a/core/modules/entity/lib/Drupal/entity/EntityFormDisplayInterface.php b/core/modules/entity/lib/Drupal/entity/EntityFormDisplayInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..dce1f683934cdf5b66e08f47be28803f95c1795a
--- /dev/null
+++ b/core/modules/entity/lib/Drupal/entity/EntityFormDisplayInterface.php
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\entity\EntityFormDisplayInterface.
+ */
+
+namespace Drupal\entity;
+
+use Drupal\entity\EntityDisplayBaseInterface;
+
+/**
+ * Provides an interface defining an entity display entity.
+ */
+interface EntityFormDisplayInterface extends EntityDisplayBaseInterface {
+
+  /**
+   * Returns the Widget plugin for a field.
+   *
+   * @param string $field_name
+   *   The field name.
+   *
+   * @return \Drupal\field\Plugin\Type\Widget\WidgetInterface|null
+   *   A Widget plugin or NULL if the field does not exist.
+   */
+  public function getWidget($field_name);
+
+}
diff --git a/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityDisplay.php b/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityDisplay.php
index 461a240ed60eb0331f27a85a83aced68a3b4bd65..6f4f20e04d452c91d31ae2ad5faa4a4e32510be6 100644
--- a/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityDisplay.php
+++ b/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityDisplay.php
@@ -7,14 +7,14 @@
 
 namespace Drupal\entity\Plugin\Core\Entity;
 
-use Drupal\Core\Config\Entity\ConfigEntityBase;
 use Drupal\Core\Entity\Annotation\EntityType;
 use Drupal\Core\Annotation\Translation;
+use Drupal\entity\EntityDisplayBase;
 use Drupal\entity\EntityDisplayInterface;
 
 /**
  * Configuration entity that contains display options for all components of a
- * rendered entity in a given view mode..
+ * rendered entity in a given view mode.
  *
  * @EntityType(
  *   id = "entity_display",
@@ -30,263 +30,32 @@
  *   }
  * )
  */
-class EntityDisplay extends ConfigEntityBase implements EntityDisplayInterface {
-
-  /**
-   * Unique ID for the config entity.
-   *
-   * @var string
-   */
-  public $id;
-
-  /**
-   * Unique UUID for the config entity.
-   *
-   * @var string
-   */
-  public $uuid;
-
-  /**
-   * Entity type to be displayed.
-   *
-   * @var string
-   */
-  public $targetEntityType;
-
-  /**
-   * Bundle to be displayed.
-   *
-   * @var string
-   */
-  public $bundle;
-
-  /**
-   * View mode to be displayed.
-   *
-   * @var string
-   */
-  public $viewMode;
-
-  /**
-   * List of component display options, keyed by component name.
-   *
-   * @var array
-   */
-  protected $content = array();
-
-  /**
-   * The original view mode that was requested (case of view modes being
-   * configured to fall back to the 'default' display).
-   *
-   * @var string
-   */
-  public $originalViewMode;
-
-  /**
-   * The formatter objects used for this display, keyed by field name.
-   *
-   * @var array
-   */
-  protected $formatters = array();
-
-  /**
-   * Overrides \Drupal\Core\Config\Entity\ConfigEntityBase::__construct().
-   */
-  public function __construct(array $values, $entity_type) {
-    // @todo See http://drupal.org/node/1825044#comment-6847792: contact.module
-    // currently produces invalid entities with a NULL bundle in some cases.
-    // Add the validity checks back when http://drupal.org/node/1856556 is
-    // fixed.
-    // if (!isset($values['targetEntityType']) || !isset($values['bundle']) || !isset($values['viewMode'])) {
-    //   throw new \InvalidArgumentException('Missing required properties for an EntiyDisplay entity.');
-    // }
-    parent::__construct($values, $entity_type);
-
-    $this->originalViewMode = $this->viewMode;
-  }
-
-  /**
-   * Overrides \Drupal\Core\Entity\Entity::id().
-   */
-  public function id() {
-    return $this->targetEntityType . '.' . $this->bundle . '.' . $this->viewMode;
-  }
-
-  /**
-   * Overrides \Drupal\config\ConfigEntityBase::save().
-   */
-  public function save() {
-    // Build an ID if none is set.
-    if (empty($this->id)) {
-      $this->id = $this->id();
-    }
-    return parent::save();
-  }
-
-  /**
-   * Overrides \Drupal\config\ConfigEntityBase::getExportProperties();
-   */
-  public function getExportProperties() {
-    $names = array(
-      'id',
-      'uuid',
-      'targetEntityType',
-      'bundle',
-      'viewMode',
-      'content',
-    );
-    $properties = array();
-    foreach ($names as $name) {
-      $properties[$name] = $this->get($name);
-    }
-    return $properties;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function createCopy($view_mode) {
-    $display = $this->createDuplicate();
-    $display->viewMode = $display->originalViewMode = $view_mode;
-    return $display;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getComponents() {
-    $result = array();
-    foreach ($this->content as $name => $options) {
-      if (!isset($options['visible']) || $options['visible'] === TRUE) {
-        unset($options['visible']);
-        $result[$name] = $options;
-      }
-    }
-    return $result;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getComponent($name) {
-    // We always store 'extra fields', whether they are visible or hidden.
-    $extra_fields = field_info_extra_fields($this->targetEntityType, $this->bundle, 'display');
-    if (isset($extra_fields[$name])) {
-      // If we have explicit settings, return an array or NULL depending on
-      // visibility.
-      if (isset($this->content[$name])) {
-        if ($this->content[$name]['visible']) {
-          return array(
-            'weight' => $this->content[$name]['weight'],
-          );
-        }
-        else {
-          return NULL;
-        }
-      }
-
-      // If no explicit settings for the extra field, look at the default
-      // visibility in its definition.
-      $definition = $extra_fields[$name];
-      if (!isset($definition['visible']) || $definition['visible'] == TRUE) {
-        return array(
-          'weight' => $definition['weight']
-        );
-      }
-      else {
-        return NULL;
-      }
-    }
-
-    if (isset($this->content[$name])) {
-      return $this->content[$name];
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setComponent($name, array $options = array()) {
-    // If no weight specified, make sure the field sinks at the bottom.
-    if (!isset($options['weight'])) {
-      $max = $this->getHighestWeight();
-      $options['weight'] = isset($max) ? $max + 1 : 0;
-    }
-
-    if ($instance = field_info_instance($this->targetEntityType, $name, $this->bundle)) {
-      $field = field_info_field($instance['field_name']);
-      $options = drupal_container()->get('plugin.manager.field.formatter')->prepareConfiguration($field['type'], $options);
-
-      // Clear the persisted formatter, if any.
-      unset($this->formatters[$name]);
-    }
-
-    // We always store 'extra fields', whether they are visible or hidden.
-    $extra_fields = field_info_extra_fields($this->targetEntityType, $this->bundle, 'display');
-    if (isset($extra_fields[$name])) {
-      $options['visible'] = TRUE;
-    }
-
-    $this->content[$name] = $options;
-
-    return $this;
-  }
+class EntityDisplay extends EntityDisplayBase implements EntityDisplayInterface {
 
   /**
    * {@inheritdoc}
    */
-  public function removeComponent($name) {
-    $extra_fields = field_info_extra_fields($this->targetEntityType, $this->bundle, 'display');
-    if (isset($extra_fields[$name])) {
-      // 'Extra fields' are exposed in hooks and can appear at any given time.
-      // Therefore we store extra fields that are explicitly being hidden, so
-      // that we can differenciate with those that are simply not configured
-      // yet.
-      $this->content[$name] = array(
-        'visible' => FALSE,
-      );
-    }
-    else {
-      unset($this->content[$name]);
-      unset($this->formatters[$name]);
-    }
-
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getHighestWeight() {
-    $weights = array();
-
-    // Collect weights for the components in the display.
-    foreach ($this->content as $options) {
-      if (isset($options['weight'])) {
-        $weights[] = $options['weight'];
-      }
-    }
-
-    // Let other modules feedback about their own additions.
-    $weights = array_merge($weights, module_invoke_all('field_info_max_weight', $this->targetEntityType, $this->bundle, $this->viewMode));
+  public function __construct(array $values, $entity_type) {
+    $this->pluginManager = \Drupal::service('plugin.manager.field.formatter');
+    $this->displayContext = 'display';
 
-    return $weights ? max($weights) : NULL;
+    parent::__construct($values, $entity_type);
   }
 
   /**
    * {@inheritdoc}
    */
   public function getFormatter($field_name) {
-    if (isset($this->formatters[$field_name])) {
-      return $this->formatters[$field_name];
+    if (isset($this->plugins[$field_name])) {
+      return $this->plugins[$field_name];
     }
 
     // Instantiate the formatter object from the stored display properties.
     if ($configuration = $this->getComponent($field_name)) {
       $instance = field_info_instance($this->targetEntityType, $field_name, $this->bundle);
-      $formatter = drupal_container()->get('plugin.manager.field.formatter')->getInstance(array(
+      $formatter = $this->pluginManager->getInstance(array(
         'instance' => $instance,
-        'view_mode' => $this->originalViewMode,
+        'view_mode' => $this->originalMode,
         // No need to prepare, defaults have been merged in setComponent().
         'prepare' => FALSE,
         'configuration' => $configuration
@@ -297,7 +66,7 @@ public function getFormatter($field_name) {
     }
 
     // Persist the formatter object.
-    $this->formatters[$field_name] = $formatter;
+    $this->plugins[$field_name] = $formatter;
     return $formatter;
   }
 
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
new file mode 100644
index 0000000000000000000000000000000000000000..9f6425bfabc35e0ec7cf62a04671b126f65ca42d
--- /dev/null
+++ b/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityFormDisplay.php
@@ -0,0 +1,92 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\entity\Plugin\Core\Entity\EntityFormDisplay.
+ */
+
+namespace Drupal\entity\Plugin\Core\Entity;
+
+use Drupal\Core\Entity\Annotation\EntityType;
+use Drupal\Core\Annotation\Translation;
+use Drupal\entity\EntityDisplayBase;
+use Drupal\entity\EntityFormDisplayInterface;
+
+/**
+ * Configuration entity that contains widget options for all components of a
+ * entity form in a given form mode.
+ *
+ * @EntityType(
+ *   id = "entity_form_display",
+ *   label = @Translation("Entity form display"),
+ *   module = "entity",
+ *   controllers = {
+ *     "storage" = "Drupal\Core\Config\Entity\ConfigStorageController"
+ *   },
+ *   config_prefix = "entity.form_display",
+ *   entity_keys = {
+ *     "id" = "id",
+ *     "uuid" = "uuid"
+ *   }
+ * )
+ */
+class EntityFormDisplay extends EntityDisplayBase implements EntityFormDisplayInterface, \Serializable {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function __construct(array $values, $entity_type) {
+    $this->pluginManager = \Drupal::service('plugin.manager.field.widget');
+    $this->displayContext = 'form';
+
+    parent::__construct($values, $entity_type);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getWidget($field_name) {
+    if (isset($this->plugins[$field_name])) {
+      return $this->plugins[$field_name];
+    }
+
+    // Instantiate the widget object from the stored display properties.
+    if ($configuration = $this->getComponent($field_name)) {
+      $instance = field_info_instance($this->targetEntityType, $field_name, $this->bundle);
+      $widget = $this->pluginManager->getInstance(array(
+        'instance' => $instance,
+        'form_mode' => $this->originalMode,
+        // No need to prepare, defaults have been merged in setComponent().
+        'prepare' => FALSE,
+        'configuration' => $configuration
+      ));
+    }
+    else {
+      $widget = NULL;
+    }
+
+    // Persist the widget object.
+    $this->plugins[$field_name] = $widget;
+    return $widget;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function serialize() {
+    // Only store the definition, not external objects or derived data.
+    $data = $this->getExportProperties() + array('entityType' => $this->entityType());
+    return serialize($data);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function unserialize($serialized) {
+    $data = unserialize($serialized);
+    $entity_type = $data['entityType'];
+    unset($data['entityType']);
+    $this->__construct($data, $entity_type);
+  }
+
+}
diff --git a/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayTest.php b/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayTest.php
index cd513f455174efaea24c60ee0971834a2c1629d9..051fb76f87e0066592de17dfcae1947d72ca57ae 100644
--- a/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayTest.php
+++ b/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayTest.php
@@ -36,7 +36,7 @@ public function testEntityDisplayCRUD() {
     $display = entity_create('entity_display', array(
       'targetEntityType' => 'entity_test',
       'bundle' => 'entity_test',
-      'viewMode' => 'default',
+      'mode' => 'default',
     ));
 
     $expected = array();
@@ -81,7 +81,7 @@ public function testEntityDisplayCRUD() {
     $new_display = entity_load('entity_display', $new_display->id());
     $this->assertEqual($new_display->targetEntityType, $display->targetEntityType);
     $this->assertEqual($new_display->bundle, $display->bundle);
-    $this->assertEqual($new_display->viewMode, 'other_view_mode');
+    $this->assertEqual($new_display->mode, 'other_view_mode');
     $this->assertEqual($new_display->getComponents(), $display->getComponents());
   }
 
@@ -112,7 +112,7 @@ public function testExtraFieldComponent() {
     $display = entity_create('entity_display', array(
       'targetEntityType' => 'entity_test',
       'bundle' => 'entity_test',
-      'viewMode' => 'default',
+      'mode' => 'default',
     ));
 
     // Check that the default visibility taken into account for extra fields
@@ -136,7 +136,7 @@ public function testFieldComponent() {
     $display = entity_create('entity_display', array(
       'targetEntityType' => 'entity_test',
       'bundle' => 'entity_test',
-      'viewMode' => 'default',
+      'mode' => 'default',
     ));
 
     // Create a field and an instance.
@@ -175,7 +175,7 @@ public function testFieldComponent() {
     $random_value = $this->randomString();
     $formatter->randomValue = $random_value;
     $formatter = $display->getFormatter($field['field_name']);
-    $this->assertEqual($formatter->randomValue, $random_value );
+    $this->assertEqual($formatter->randomValue, $random_value);
 
     // Check that changing the definition creates a new formatter.
     $display->setComponent($field['field_name'], array(
diff --git a/core/modules/entity/lib/Drupal/entity/Tests/EntityFormDisplayTest.php b/core/modules/entity/lib/Drupal/entity/Tests/EntityFormDisplayTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b92cfbff36abe8b74a8b659e2de0a0ece116c82d
--- /dev/null
+++ b/core/modules/entity/lib/Drupal/entity/Tests/EntityFormDisplayTest.php
@@ -0,0 +1,121 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\entity\Tests\EntityFormDisplayTest.
+ */
+
+namespace Drupal\entity\Tests;
+
+use Drupal\simpletest\DrupalUnitTestBase;
+
+/**
+ * Tests the EntityDisplay configuration entities.
+ */
+class EntityFormDisplayTest extends DrupalUnitTestBase {
+
+  public static $modules = array('entity', 'field', 'entity_test');
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Entity form display configuration entities',
+      'description' => 'Tests the entity form display configuration entities.',
+      'group' => 'Entity API',
+    );
+  }
+
+  protected function setUp() {
+    parent::setUp();
+    $this->installConfig(array('field'));
+  }
+
+  /**
+   * Tests entity_get_form_display().
+   */
+  public function testEntityGetFromDisplay() {
+    // Check that entity_get_form_display() returns a fresh object when no
+    // configuration entry exists.
+    $form_display = entity_get_form_display('entity_test', 'entity_test', 'default');
+    $this->assertTrue($form_display->isNew());
+
+    // Add some components and save the display.
+    $form_display->setComponent('component_1', array('weight' => 10))
+      ->save();
+
+    // Check that entity_get_form_display() returns the correct object.
+    $form_display = entity_get_form_display('entity_test', 'entity_test', 'default');
+    $this->assertFalse($form_display->isNew());
+    $this->assertEqual($form_display->id, 'entity_test.entity_test.default');
+    $this->assertEqual($form_display->getComponent('component_1'), array('weight' => 10));
+  }
+
+  /**
+   * Tests the behavior of a field component within an EntityFormDisplay object.
+   */
+  public function testFieldComponent() {
+    $this->enableModules(array('field_sql_storage', 'field_test'));
+
+    $form_display = entity_create('entity_form_display', array(
+      'targetEntityType' => 'entity_test',
+      'bundle' => 'entity_test',
+      'mode' => 'default',
+    ));
+
+    // Create a field and an instance.
+    $field = array(
+      'field_name' => 'test_field',
+      'type' => 'test_field'
+    );
+    field_create_field($field);
+    $instance = array(
+      'field_name' => $field['field_name'],
+      'entity_type' => 'entity_test',
+      'bundle' => 'entity_test',
+    );
+    field_create_instance($instance);
+
+    // Check that providing no options results in default values being used.
+    $form_display->setComponent($field['field_name']);
+    $field_type_info = field_info_field_types($field['type']);
+    $default_widget = $field_type_info['default_widget'];
+    $default_settings = field_info_widget_settings($default_widget);
+    $expected = array(
+      'weight' => 0,
+      'type' => $default_widget,
+      'settings' => $default_settings,
+    );
+    $this->assertEqual($form_display->getComponent($field['field_name']), $expected);
+
+    // Check that the getWidget() method returns the correct widget plugin.
+    $widget = $form_display->getWidget($field['field_name']);
+    $this->assertEqual($widget->getPluginId(), $default_widget);
+    $this->assertEqual($widget->getSettings(), $default_settings);
+
+    // Check that the widget is statically persisted, by assigning an
+    // arbitrary property and reading it back.
+    $random_value = $this->randomString();
+    $widget->randomValue = $random_value;
+    $widget = $form_display->getWidget($field['field_name']);
+    $this->assertEqual($widget->randomValue, $random_value);
+
+    // Check that changing the definition creates a new widget.
+    $form_display->setComponent($field['field_name'], array(
+      'type' => 'field_test_multiple',
+    ));
+    $widget = $form_display->getWidget($field['field_name']);
+    $this->assertEqual($widget->getPluginId(), 'test_field_widget');
+    $this->assertFalse(isset($widget->randomValue));
+
+    // Check that specifying an unknown widget (e.g. case of a disabled module)
+    // gets stored as is in the display, but results in the default widget being
+    // used.
+    $form_display->setComponent($field['field_name'], array(
+      'type' => 'unknown_widget',
+    ));
+    $options = $form_display->getComponent($field['field_name']);
+    $this->assertEqual($options['type'], 'unknown_widget');
+    $widget = $form_display->getWidget($field['field_name']);
+    $this->assertEqual($widget->getPluginId(), $default_widget);
+  }
+
+}
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 b3fe3a0a4b02370450df7ae34dd9158bd31caf63..6168bea72e374d89c17244aebdc877151142e0ca 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/EntityReferenceAutocomplete.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/EntityReferenceAutocomplete.php
@@ -75,7 +75,8 @@ public function getMatches($field, $instance, $entity_type, $entity_id = '', $pr
 
     if (isset($string)) {
       // Get an array of matching entities.
-      $match_operator = !empty($instance['widget']['settings']['match_operator']) ? $instance['widget']['settings']['match_operator'] : 'CONTAINS';
+      $widget = entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')->getComponent($instance['field_name']);
+      $match_operator = !empty($widget['settings']['match_operator']) ? $widget['settings']['match_operator'] : 'CONTAINS';
       $entity_labels = $handler->getReferencableEntities($string, $match_operator, 10);
 
       // Loop through the entities and convert them into autocomplete output.
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutoCreateTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutoCreateTest.php
index 99ebe159b2dc502bac24c889d03efa75deba0483..ace6f5daf5db6b20f23d7e7630574793e99a33d4 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutoCreateTest.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutoCreateTest.php
@@ -66,6 +66,12 @@ function setUp() {
     );
 
     field_create_instance($instance);
+
+    entity_get_form_display('node', $referencing->type, 'default')
+      ->setComponent('test_field', array(
+        'type' => 'entity_reference_autocomplete',
+      ))
+      ->save();
   }
 
   /**
diff --git a/core/modules/field/field.api.php b/core/modules/field/field.api.php
index 33f2581aba74b30f060af272c33a750633fff27b..b159f59579d4679d62a3de703f45b22f65b17658 100644
--- a/core/modules/field/field.api.php
+++ b/core/modules/field/field.api.php
@@ -21,10 +21,9 @@
  * in a #pre_render callback added by field_attach_form() and
  * field_attach_view().
  *
- * @see _field_extra_fields_pre_render()
  * @see hook_field_extra_fields_alter()
  *
- * @return
+ * @return array
  *   A nested array of 'pseudo-field' elements. Each list is nested within the
  *   following keys: entity type, bundle name, context (either 'form' or
  *   'display'). The keys are the name of the elements as appearing in the
@@ -33,8 +32,8 @@
  *   - label: The human readable name of the element.
  *   - description: A short description of the element contents.
  *   - weight: The default weight of the element.
- *   - visible: The default visibility of the element. Only for 'display'
- *     context.
+ *   - visible: (optional) The default visibility of the element.  Only for
+ *    'display' context. Defaults to TRUE.
  *   - edit: (optional) String containing markup (normally a link) used as the
  *     element's 'edit' operation in the administration interface. Only for
  *     'form' context.
@@ -783,38 +782,6 @@ function hook_field_widget_WIDGET_TYPE_form_alter(&$element, &$form_state, $cont
   $element['#autocomplete_path'] = 'mymodule/autocomplete_path';
 }
 
-/**
- * Alters the widget properties of a field instance before it gets displayed.
- *
- * Note that instead of hook_field_widget_properties_alter(), which is called
- * for all fields on all entity types,
- * hook_field_widget_properties_ENTITY_TYPE_alter() may be used to alter widget
- * properties for fields on a specific entity type only.
- *
- * This hook is called once per field per added or edit entity. If the result
- * of the hook involves reading from the database, it is highly recommended to
- * statically cache the information.
- *
- * @param array $widget_properties
- *   The instance's widget properties.
- * @param array $context
- *   An associative array containing:
- *   - entity_type: The entity type, e.g., 'node' or 'user'.
- *   - bundle: The bundle, e.g., 'page' or 'article'.
- *   - field: The field that the widget belongs to.
- *   - instance: The instance of the field.
- *
- * @see hook_field_widget_properties_ENTITY_TYPE_alter()
- */
-function hook_field_widget_properties_alter(array &$widget_properties, array $context) {
-  // Change a widget's type according to the time of day.
-  $field = $context['field'];
-  if ($context['entity_type'] == 'node' && $field['field_name'] == 'field_foo') {
-    $time = date('H');
-    $widget_properties['type'] = $time < 12 ? 'widget_am' : 'widget_pm';
-  }
-}
-
 /**
  * @} End of "defgroup field_widget".
  */
@@ -1819,59 +1786,30 @@ function hook_field_storage_pre_update(\Drupal\Core\Entity\EntityInterface $enti
  * Field API takes care of fields and 'extra_fields'. This hook is intended for
  * third-party modules adding other entity components (e.g. field_group).
  *
- * @param $entity_type
+ * @param string $entity_type
  *   The type of entity; e.g. 'node' or 'user'.
- * @param $bundle
+ * @param string $bundle
  *   The bundle name.
- * @param $context
- *   The context for which the maximum weight is requested. Either 'form', or
- *   the name of a view mode.
- * @return
+ * @param string $context
+ *   The context for which the maximum weight is requested. Either 'form' or
+ *   'display'.
+ * @param string $context_mode
+ *   The view or form mode name.
+ *
+ * @return int
  *   The maximum weight of the entity's components, or NULL if no components
  *   were found.
  */
-function hook_field_info_max_weight($entity_type, $bundle, $context) {
+function hook_field_info_max_weight($entity_type, $bundle, $context, $context_mode) {
   $weights = array();
 
-  foreach (my_module_entity_additions($entity_type, $bundle, $context) as $addition) {
+  foreach (my_module_entity_additions($entity_type, $bundle, $context, $context_mode) as $addition) {
     $weights[] = $addition['weight'];
   }
 
   return $weights ? max($weights) : NULL;
 }
 
-/**
- * Alters the widget properties of a field instance on a given entity type
- * before it gets displayed.
- *
- * Modules can implement hook_field_widget_properties_ENTITY_TYPE_alter() to
- * alter the widget properties for fields on a specific entity type, rather than
- * implementing hook_field_widget_properties_alter().
- *
- * This hook is called once per field per displayed widget entity. If the result
- * of the hook involves reading from the database, it is highly recommended to
- * statically cache the information.
- *
- * @param array $widget_properties
- *   The instance's widget properties.
- * @param array $context
- *   An associative array containing:
- *   - entity_type: The entity type, e.g., 'node' or 'user'.
- *   - bundle: The bundle, e.g., 'page' or 'article'.
- *   - field: The field that the widget belongs to.
- *   - instance: The instance of the field.
- *
- * @see hook_field_widget_properties_alter()
- */
-function hook_field_widget_properties_ENTITY_TYPE_alter(array &$widget_properties, array $context) {
-  // Change a widget's type according to the time of day.
-  $field = $context['field'];
-  if ($field['field_name'] == 'field_foo') {
-    $time = date('H');
-    $widget_properties['type'] = $time < 12 ? 'widget_am' : 'widget_pm';
-  }
-}
-
 /**
  * @} End of "addtogroup field_storage".
  */
diff --git a/core/modules/field/field.attach.inc b/core/modules/field/field.attach.inc
index e61f6596a3a56ec062427a67e849a6295cf5095b..baa7ff47909c0a455f7a7e47e02d67b4f59635b0 100644
--- a/core/modules/field/field.attach.inc
+++ b/core/modules/field/field.attach.inc
@@ -8,6 +8,7 @@
 use Drupal\field\FieldValidationException;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\entity\Plugin\Core\Entity\EntityDisplay;
+use Drupal\entity\Plugin\Core\Entity\EntityFormDisplay;
 
 /**
  * @defgroup field_storage Field Storage API
@@ -705,12 +706,15 @@ function _field_invoke_get_instances($entity_type, $bundle, $options) {
  *
  * Used to invoke methods on an instance's widget.
  *
+ * @param \Drupal\entity\Plugin\Core\Entity\EntityFormDisplay $form_display
+ *   An EntityFormDisplay object.
+ *
  * @return callable $target_function
  *   A 'target function' for field_invoke_method().
  */
-function _field_invoke_widget_target() {
-  return function ($instance) {
-    return $instance->getWidget();
+function _field_invoke_widget_target($form_display) {
+  return function ($instance) use ($form_display) {
+    return $form_display->getWidget($instance['field_name']);
   };
 }
 
@@ -828,12 +832,13 @@ function field_attach_form(EntityInterface $entity, &$form, &$form_state, $langc
   // Set #parents to 'top-level' by default.
   $form += array('#parents' => array());
 
+  // Get the entity_form_display object for this form.
+  $form_display = $form_state['form_display'];
+
   // If no language is provided use the default site language.
   $options['langcode'] = field_valid_language($langcode);
-  $form += (array) field_invoke_method('form', _field_invoke_widget_target(), $entity, $form, $form_state, $options);
+  $form += (array) field_invoke_method('form', _field_invoke_widget_target($form_display), $entity, $form, $form_state, $options);
 
-  // Add custom weight handling.
-  $form['#pre_render'][] = '_field_extra_fields_pre_render';
   $form['#entity_type'] = $entity->entityType();
   $form['#bundle'] = $entity->bundle();
 
@@ -1106,7 +1111,8 @@ function field_attach_form_validate(EntityInterface $entity, $form, &$form_state
         field_form_set_state($form['#parents'], $field_name, $langcode, $form_state, $field_state);
       }
     }
-    field_invoke_method('flagErrors', _field_invoke_widget_target(), $entity, $form, $form_state, $options);
+    $form_display = $form_state['form_display'];
+    field_invoke_method('flagErrors', _field_invoke_widget_target($form_display), $entity, $form, $form_state, $options);
   }
 }
 
@@ -1133,7 +1139,8 @@ function field_attach_extract_form_values(EntityInterface $entity, $form, &$form
   $entity = $entity->getBCEntity();
 
   // Extract field values from submitted values.
-  field_invoke_method('extractFormValues', _field_invoke_widget_target(), $entity, $form, $form_state, $options);
+  $form_display = $form_state['form_display'];
+  field_invoke_method('extractFormValues', _field_invoke_widget_target($form_display), $entity, $form, $form_state, $options);
 
   // Let other modules act on submitting the entity.
   // Avoid module_invoke_all() to let $form_state be taken by reference.
@@ -1464,7 +1471,7 @@ function field_attach_view(EntityInterface $entity, EntityDisplay $display, $lan
   $entity = $entity->getNGEntity();
 
   // Let other modules alter the renderable array.
-  $view_mode = $display->originalViewMode;
+  $view_mode = $display->originalMode;
   $context = array(
     'entity' => $entity,
     'view_mode' => $view_mode,
diff --git a/core/modules/field/field.info.inc b/core/modules/field/field.info.inc
index 38edcdbe2032cacf5ae9f1865c005edb574155be..d4b439e8d1bf617bee168a1b12842677b1b37e29 100644
--- a/core/modules/field/field.info.inc
+++ b/core/modules/field/field.info.inc
@@ -130,20 +130,23 @@ function _field_info_collate_types_reset() {
 /**
  * Determines the behavior of a widget with respect to an operation.
  *
- * @param $op
- *   The name of the operation. Currently supported: 'default value', 'multiple
- *   values'.
- * @param $instance
+ * @param string $op
+ *   The name of the operation. Currently supported: 'default_value',
+ *   'multiple_values'.
+ * @param array $instance
  *   The field instance array.
  *
- * @return
+ * @return int
  *   One of these values:
  *   - FIELD_BEHAVIOR_NONE: Do nothing for this operation.
  *   - FIELD_BEHAVIOR_CUSTOM: Use the widget's callback function.
  *   - FIELD_BEHAVIOR_DEFAULT: Use field.module default behavior.
  */
 function field_behaviors_widget($op, $instance) {
-  $info = field_info_widget_types($instance['widget']['type']);
+  $info = array();
+  if ($component = entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')->getComponent($instance['field_name'])) {
+    $info = field_info_widget_types($component['type']);
+  }
   return isset($info[$op]) ? $info[$op] : FIELD_BEHAVIOR_DEFAULT;
 }
 
@@ -477,40 +480,6 @@ function field_info_extra_fields($entity_type, $bundle, $context) {
   return isset($info[$context]) ? $info[$context] : array();
 }
 
-/**
- * Returns the maximum weight of all the components in a form entity.
- *
- * This includes fields, 'extra_fields', and other components added by
- * third-party modules (e.g. field_group).
- *
- * @param $entity_type
- *   The type of entity; e.g. 'node' or 'user'.
- * @param $bundle
- *   The bundle name.
- *
- * @return
- *   The maximum weight of the entity's components, or NULL if no components
- *   were found.
- */
-function field_info_max_weight($entity_type, $bundle) {
-  $weights = array();
-
-  // Collect weights for fields.
-  foreach (field_info_instances($entity_type, $bundle) as $instance) {
-    $weights[] = $instance['widget']['weight'];
-  }
-  // Collect weights for extra fields.
-  foreach (field_info_extra_fields($entity_type, $bundle, 'form') as $extra) {
-    $weights[] = $extra['weight'];
-  }
-
-  // Let other modules feedback about their own additions.
-  $weights = array_merge($weights, module_invoke_all('field_info_max_weight', $entity_type, $bundle, 'form'));
-  $max_weight = $weights ? max($weights) : NULL;
-
-  return $max_weight;
-}
-
 /**
  * Returns a field type's default settings.
  *
diff --git a/core/modules/field/field.install b/core/modules/field/field.install
index dcf2b388ebb93af25624cd7a6e4817cf4bafaed0..dc20e251ee442f236332f4a4a9c9e6de448fe12b 100644
--- a/core/modules/field/field.install
+++ b/core/modules/field/field.install
@@ -250,12 +250,12 @@ function field_update_8001() {
 }
 
 /**
- * Migrate all instance display settings to configuration.
+ * Migrate all instance widget and display settings to configuration.
  *
  * @ingroup config_upgrade
  */
 function field_update_8002() {
-  $displays = array();
+  $form_displays = $displays = array();
   module_load_install('entity');
 
   $query = db_select('field_config_instance', 'fc')->fields('fc');
@@ -266,28 +266,46 @@ function field_update_8002() {
 
     // Skip field instances that were created directly with the new API earlier
     // in the upgrade path.
-    if (!isset($data['display'])) {
+    if (!isset($data['widget']) && !isset($data['display'])) {
       continue;
     }
 
-    foreach ($data['display'] as $view_mode => $display_options) {
-      // Determine name and create initial entry in the $displays array if it
-      // does not exist yet.
-      $display_id = $record->entity_type . '.' . $record->bundle . '.' . $view_mode;
-      if (!isset($displays[$display_id])) {
-        $displays[$display_id] = _update_8000_entity_get_display($record->entity_type, $record->bundle, $view_mode);
+    // Migrate 'widget' settings.
+    if (isset($data['widget'])) {
+      $widget_options = $data['widget'];
+      // Determine name and create initial entry in the $form_displays array.
+      $form_display_id = $record->entity_type . '.' . $record->bundle . '.default';
+      if (!isset($form_displays[$form_display_id])) {
+        $form_displays[$form_display_id] = _update_8000_entity_get_form_display($record->entity_type, $record->bundle, 'default');
       }
 
-      // The display object does not store hidden fields.
-      if ($display_options['type'] != 'hidden') {
-        // We do not need the 'module' key anymore.
-        unset($display_options['module']);
-        $displays[$display_id]->set("content.$record->field_name", $display_options);
+      // We do not need the 'module' key anymore.
+      unset($widget_options['module']);
+      $form_displays[$form_display_id]->set("content.$record->field_name", $widget_options);
+    }
+
+    // Migrate 'display' settings.
+    if (isset($data['display'])) {
+      foreach ($data['display'] as $view_mode => $display_options) {
+        // Determine name and create initial entry in the $displays array if it
+        // does not exist yet.
+        $display_id = $record->entity_type . '.' . $record->bundle . '.' . $view_mode;
+        if (!isset($displays[$display_id])) {
+          $displays[$display_id] = _update_8000_entity_get_display($record->entity_type, $record->bundle, $view_mode);
+        }
+
+        // The display object does not store hidden fields.
+        if ($display_options['type'] != 'hidden') {
+          // We do not need the 'module' key anymore.
+          unset($display_options['module']);
+          $displays[$display_id]->set("content.$record->field_name", $display_options);
+        }
       }
     }
 
-    // Remove the 'display' key and save the record back into the table.
-    unset($data['display']);
+    // Remove the 'widget' and 'display' keys and save the record back into the
+    // table.
+    unset($data['display'], $data['widget']);
     db_update('field_config_instance')
       ->condition('id', $record->id)
       ->fields(array(
@@ -302,8 +320,26 @@ function field_update_8002() {
   $variables = array_map('unserialize', db_query("SELECT name, value FROM {variable} WHERE name LIKE '%field_bundle_settings_%'")->fetchAllKeyed());
   foreach ($variables as $variable_name => $variable_value) {
     if (preg_match('/field_bundle_settings_(.*)__(.*)/', $variable_name, $matches)) {
+      $variable_needs_update = FALSE;
       $entity_type = $matches[1];
       $bundle = $matches[2];
+
+      if (isset($variable_value['extra_fields']['form'])) {
+        foreach ($variable_value['extra_fields']['form'] as $field_name => $field_settings) {
+          // Determine name and create initial entry in the $form_displays
+          // array if it does not exist yet.
+          $form_display_id = $entity_type . '.' . $bundle . '.default';
+          if (!isset($form_displays[$form_display_id])) {
+            $form_displays[$form_display_id] = _update_8000_entity_get_form_display($entity_type, $bundle, 'default');
+          }
+          $form_displays[$form_display_id]->set("content.$field_name", $field_settings);
+        }
+
+        // Remove the old entry.
+        unset($variable_value['extra_fields']['form']);
+        $variable_needs_update = TRUE;
+      }
+
       if (isset($variable_value['extra_fields']['display'])) {
         foreach ($variable_value['extra_fields']['display'] as $field_name => $field_settings) {
           foreach ($field_settings as $view_mode => $display_options) {
@@ -322,16 +358,26 @@ function field_update_8002() {
               $new_options['weight'] = $display_options['weight'];
             }
             $displays[$display_id]->set("content.$field_name", $new_options);
-
-            // Remove the old entry.
-            unset($variable_value['extra_fields']['display']);
-            variable_set($variable_name, $variable_value);
           }
         }
+
+        // Remove the old entry.
+        unset($variable_value['extra_fields']['display']);
+        $variable_needs_update = TRUE;
+      }
+
+      if ($variable_needs_update) {
+        variable_set($variable_name, $variable_value);
       }
     }
   }
 
+  // Save the form displays to configuration.
+  foreach ($form_displays as $config) {
+    $config->save();
+  }
+  update_config_manifest_add('entity.form_display', array_keys($form_displays));
+
   // Save the displays to configuration.
   foreach ($displays as $config) {
     $config->save();
@@ -437,7 +483,6 @@ function field_update_8003() {
       'default_value' => isset($record['data']['default_value']) ? $record['data']['default_value'] : array(),
       'default_value_function' => isset($record['data']['default_value_function']) ? $record['data']['default_value_function'] : '',
       'settings' => $record['data']['settings'],
-      'widget' => $record['data']['widget'],
       'status' => 1,
       'langcode' => 'und',
     );
diff --git a/core/modules/field/field.module b/core/modules/field/field.module
index 2cb7679b6004e2b16ef7638b5ad84f5f43fc61de..bf0ac5699add0bf7a184fd21d70b83d99ca21603 100644
--- a/core/modules/field/field.module
+++ b/core/modules/field/field.module
@@ -603,10 +603,6 @@ function field_bundle_settings($entity_type, $bundle, $settings = NULL) {
     $settings = variable_get('field_bundle_settings_' . $entity_type . '__' . $bundle, array());
     $settings += array(
       'view_modes' => array(),
-      'extra_fields' => array(),
-    );
-    $settings['extra_fields'] += array(
-      'form' => array(),
     );
 
     return $settings;
@@ -648,23 +644,6 @@ function field_view_mode_settings($entity_type, $bundle) {
   return $cache[$entity_type][$bundle];
 }
 
-/**
- * Pre-render callback: Adjusts weights and visibility of non-field elements.
- */
-function _field_extra_fields_pre_render($elements) {
-  $entity_type = $elements['#entity_type'];
-  $bundle = $elements['#bundle'];
-
-  $extra_fields = field_info_extra_fields($entity_type, $bundle, 'form');
-  foreach ($extra_fields as $name => $settings) {
-    if (isset($elements[$name])) {
-      $elements[$name]['#weight'] = $settings['weight'];
-    }
-  }
-
-  return $elements;
-}
-
 /**
  * Clears the field info and field data caches.
  */
diff --git a/core/modules/field/lib/Drupal/field/FieldInstanceInterface.php b/core/modules/field/lib/Drupal/field/FieldInstanceInterface.php
index 438bd0082909e416104909b9aaee0e61f360c918..c6b8ad60ff089bf945496fe3a99b64336f8880f2 100644
--- a/core/modules/field/lib/Drupal/field/FieldInstanceInterface.php
+++ b/core/modules/field/lib/Drupal/field/FieldInstanceInterface.php
@@ -22,14 +22,6 @@ interface FieldInstanceInterface extends ConfigEntityInterface, \ArrayAccess, \S
    */
   public function getField();
 
-  /**
-   * Returns the Widget plugin for the instance.
-   *
-   * @return Drupal\field\Plugin\Type\Widget\WidgetInterface
-   *   The Widget plugin to be used for the instance.
-   */
-  public function getWidget();
-
   /**
    * Allows a bundle to be renamed.
    *
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 53132ec0b1efdc9d3330cee0b2554d01bdc4e6b9..66d8cbf2fdd329c0fbef478cc4357018f143f4e1 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
@@ -171,24 +171,6 @@ class FieldInstance extends ConfigEntityBase implements FieldInstanceInterface {
    */
   public $default_value_function = '';
 
-  /**
-   * The widget definition.
-   *
-   * An array of key/value pairs identifying the Form API input widget for
-   * the field when used by this bundle.
-   *   - type: (string) The plugin ID of the widget, such as text_textfield.
-   *   - settings: (array) A sub-array of key/value pairs of settings. The keys
-   *     and default values are defined by the widget plugin in the 'settings'
-   *     entry of its "plugin definition" (typycally plugin class annotations).
-   *   - weight: (float) The weight of the widget relative to the other
-   *     elements in entity edit forms.
-   *   - module: (string, read-only) The name of the module that provides the
-   *     widget plugin.
-   *
-   * @var array
-   */
-  public $widget = array();
-
   /**
    * Flag indicating whether the instance is deleted.
    *
@@ -211,13 +193,6 @@ class FieldInstance extends ConfigEntityBase implements FieldInstanceInterface {
    */
   protected $field;
 
-  /**
-   * The widget plugin used for this instance.
-   *
-   * @var \Drupal\field\Plugin\Type\Widget\WidgetInterface
-   */
-  protected $widgetPlugin;
-
   /**
    * Flag indicating whether the bundle name can be renamed or not.
    *
@@ -302,7 +277,6 @@ public function getExportProperties() {
       'default_value',
       'default_value_function',
       'settings',
-      'widget',
     );
     $properties = array();
     foreach ($names as $name) {
@@ -367,22 +341,6 @@ public function save() {
     // Set the default instance settings.
     $this->settings += $field_type_info['instance_settings'];
 
-    // Set the default widget and settings.
-    $this->widget += array(
-      'type' => $field_type_info['default_widget'],
-      'settings' => array(),
-    );
-    // Get the widget module and settings from the widget type.
-    if ($widget_type_info = \Drupal::service('plugin.manager.field.widget')->getDefinition($this->widget['type'])) {
-      $this->widget['module'] = $widget_type_info['module'];
-      $this->widget['settings'] += $widget_type_info['settings'];
-    }
-    // If no weight is specified, make sure the field sinks to the bottom.
-    if (!isset($this->widget['weight'])) {
-      $max_weight = field_info_max_weight($this->entity_type, $this->bundle, 'form');
-      $this->widget['weight'] = isset($max_weight) ? $max_weight + 1 : 0;
-    }
-
     // Save the configuration.
     $result = parent::save();
     field_cache_clear();
@@ -430,6 +388,11 @@ public function delete($field_cleanup = TRUE) {
       // hook_field_delete_instance().
       $module_handler->invokeAll('field_delete_instance', array($this));
 
+      // Remove the instance from the entity form displays.
+      if ($form_display = entity_load('entity_form_display', $this->entity_type . '.' . $this->bundle . '.default')) {
+        $form_display->removeComponent($this->field->id())->save();
+      }
+
       // Remove the instance from the entity displays.
       $ids = array();
       $view_modes = array('default' => array()) + entity_get_view_modes($this->entity_type);
@@ -454,36 +417,6 @@ public function getField() {
     return $this->field;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function getWidget() {
-    if (empty($this->widgetPlugin)) {
-      $widget_properties = $this->widget;
-
-      // Let modules alter the widget properties.
-      $context = array(
-        'entity_type' => $this->entity_type,
-        'bundle' => $this->bundle,
-        'field' => $this->field,
-        'instance' => $this,
-      );
-      // Invoke hook_field_widget_properties_alter() and
-      // hook_field_widget_properties_ENTITY_TYPE_alter().
-      drupal_alter(array('field_widget_properties', 'field_widget_properties_' . $this->entity_type), $widget_properties, $context);
-
-      $options = array(
-        'instance' => $this,
-        'type' => $widget_properties['type'],
-        'settings' => $widget_properties['settings'],
-        'weight' => $widget_properties['weight'],
-      );
-      $this->widgetPlugin = \Drupal::service('plugin.manager.field.widget')->getInstance($options);
-    }
-
-    return $this->widgetPlugin;
-  }
-
   /**
    * {@inheritdoc}
    */
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 64c83a2d303691bdbba86ee04a5ffd34cf66c076..89c212a57ba4bbe69d4e1c0f59fde0ae832dee34 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
@@ -38,13 +38,6 @@ abstract class WidgetBase extends PluginSettingsBase implements WidgetInterface
    */
   protected $settings;
 
-  /**
-   * The widget weight.
-   *
-   * @var int
-   */
-  protected $weight;
-
   /**
    * Constructs a WidgetBase object.
    *
@@ -56,16 +49,13 @@ abstract class WidgetBase extends PluginSettingsBase implements WidgetInterface
    *   The field instance to which the widget is associated.
    * @param array $settings
    *   The widget settings.
-   * @param int $weight
-   *   The widget weight.
    */
-  public function __construct($plugin_id, array $plugin_definition, FieldInstance $instance, array $settings, $weight) {
+  public function __construct($plugin_id, array $plugin_definition, FieldInstance $instance, array $settings) {
     parent::__construct(array(), $plugin_id, $plugin_definition);
 
     $this->instance = $instance;
     $this->field = field_info_field($instance['field_name']);
     $this->settings = $settings;
-    $this->weight = $weight;
   }
 
   /**
@@ -140,7 +130,6 @@ public function form(EntityInterface $entity, $langcode, array $items, array &$f
           'field-widget-' . drupal_html_class($this->getPluginId()),
         ),
       ),
-      '#weight' => $this->weight,
     );
 
     // Populate the 'array_parents' information in $form_state['field'] after
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 392ef5eb26cf01d209d71a81562ce1765ad4f558..9b14e85eb4ddac1932c5163acc9d7b3da300388e 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
@@ -20,6 +20,6 @@ class WidgetFactory extends DefaultFactory {
   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['weight']);
+    return new $plugin_class($plugin_id, $plugin_definition, $configuration['instance'], $configuration['settings']);
   }
 }
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 c8ea1f9c3b683e5bfb51510759dfa0883782ffd5..bb857368a79a7922bea855a98dc9ea32102e885a 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
@@ -45,30 +45,79 @@ public function __construct(\Traversable $namespaces) {
   }
 
   /**
-   * Overrides Drupal\Component\Plugin\PluginManagerBase::getInstance().
+   * Overrides PluginManagerBase::getInstance().
+   *
+   * @param array $options
+   *   An array with the following key/value pairs:
+   *   - instance: (FieldInstance) The field instance.
+   *   - form_mode: (string) The form mode.
+   *   - prepare: (bool, optional) Whether default values should get merged in
+   *     the 'configuration' array. Defaults to TRUE.
+   *   - configuration: (array) the configuration for the widget. The
+   *     following key value pairs are allowed, and are all optional if
+   *     'prepare' is TRUE:
+   *     - type: (string) The widget to use. Defaults to the
+   *       'default_widget' for the field type, specified in
+   *       hook_field_info(). The default widget will also be used if the
+   *       requested widget is not available.
+   *     - settings: (array) Settings specific to the widget. Each setting
+   *       defaults to the default value specified in the widget definition.
+   *
+   * @return \Drupal\field\Plugin\Type\Widget\WidgetInterface
+   *   A Widget object.
    */
   public function getInstance(array $options) {
+    $configuration = $options['configuration'];
     $instance = $options['instance'];
-    $type = $options['type'];
-
-    $definition = $this->getDefinition($type);
     $field = field_info_field($instance['field_name']);
 
+    // Fill in default configuration if needed.
+    if (!isset($options['prepare']) || $options['prepare'] == TRUE) {
+      $configuration = $this->prepareConfiguration($field['type'], $configuration);
+    }
+
+    $plugin_id = $configuration['type'];
+
     // Switch back to default widget if either:
     // - $type_info doesn't exist (the widget type is unknown),
     // - the field type is not allowed for the widget.
+    $definition = $this->getDefinition($configuration['type']);
     if (!isset($definition['class']) || !in_array($field['type'], $definition['field_types'])) {
       // Grab the default widget for the field type.
       $field_type_definition = field_info_field_types($field['type']);
-      $type = $field_type_definition['default_widget'];
+      $plugin_id = $field_type_definition['default_widget'];
     }
 
-    $configuration = array(
+    $configuration += array(
       'instance' => $instance,
-      'settings' => $options['settings'],
-      'weight' => $options['weight'],
     );
-    return $this->createInstance($type, $configuration);
+    return $this->createInstance($plugin_id, $configuration);
   }
 
+  /**
+   * Merges default values for widget configuration.
+   *
+   * @param string $field_type
+   *   The field type.
+   * @param array $configuration
+   *   An array of widget configuration.
+   *
+   * @return array
+   *   The display properties with defaults added.
+   */
+  public function prepareConfiguration($field_type, array $configuration) {
+    // Fill in defaults for missing properties.
+    $configuration += array(
+      'settings' => array(),
+    );
+    // If no widget is specified, use the default widget.
+    if (!isset($configuration['type'])) {
+      $field_type = field_info_field_types($field_type);
+      $configuration['type'] = $field_type['default_widget'];
+    }
+    // Fill in default settings values for the widget.
+    $configuration['settings'] += field_info_widget_settings($configuration['type']);
+
+    return $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 e9517c05d90456b5d46b573d50d9508b5ea54255..7e7de463319bd0e06ce55f82236e181baca0bdde 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
@@ -432,20 +432,8 @@ function fakeFieldInstance($formatter, $formatter_settings) {
       'entity_type' => 'views_fake',
       'bundle' => 'views_fake',
 
-      // Use the default field settings for settings and widget.
+      // Use the default field settings.
       'settings' => field_info_instance_settings($field['type']),
-      'widget' => array(
-        'type' => $field_type['default_widget'],
-        'settings' => array(),
-      ),
-
-      // Build a dummy display mode.
-      'display' => array(
-        '_custom' => array(
-          'type' => $formatter,
-          'settings' => $formatter_settings,
-        ),
-      ),
 
       // Set the other fields to their default values.
       'required' => FALSE,
diff --git a/core/modules/field/lib/Drupal/field/Tests/BulkDeleteTest.php b/core/modules/field/lib/Drupal/field/Tests/BulkDeleteTest.php
index ca414bca952b1c65f3c1a8348ba30e4cbfd28e16..7ff4ff90ce27ab7628199e0a09d5a23b2753307d 100644
--- a/core/modules/field/lib/Drupal/field/Tests/BulkDeleteTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/BulkDeleteTest.php
@@ -117,9 +117,6 @@ function setUp() {
           'field_name' => $field['field_name'],
           'entity_type' => $this->entity_type,
           'bundle' => $bundle,
-          'widget' => array(
-            'type' => 'test_field_widget',
-          )
         );
         $this->instances[] = field_create_instance($instance);
       }
diff --git a/core/modules/field/lib/Drupal/field/Tests/CrudTest.php b/core/modules/field/lib/Drupal/field/Tests/CrudTest.php
index 125ed971647c8db0c1d4572ecf403686e0c4b46b..8f9bdf9361d416ed1bf583ba2bf9a505c71d6050 100644
--- a/core/modules/field/lib/Drupal/field/Tests/CrudTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/CrudTest.php
@@ -283,9 +283,6 @@ function testDeleteField() {
       'field_name' => $this->field['field_name'],
       'entity_type' => 'test_entity',
       'bundle' => 'test_bundle',
-      'widget' => array(
-        'type' => 'test_field_widget',
-      ),
     );
     field_create_instance($this->instance_definition);
     $this->another_instance_definition = $this->instance_definition;
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldAccessTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldAccessTest.php
index 86f1f3409ed14b305ee185316c03b3af155a13e7..b63d48d8d25d49dac6548c4bedd24579667a0693 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldAccessTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldAccessTest.php
@@ -46,9 +46,6 @@ function setUp() {
       'field_name' => $this->field['field_name'],
       'entity_type' => 'node',
       'bundle' => $this->content_type,
-      'widget' => array(
-        'type' => 'text_textfield',
-      ),
     );
     field_create_instance($this->instance);
 
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php
index 1ec87cfc3134d6c909e9e8b685d6501f3b5abaa7..4bc03be8a3cb6f4f01033455e946f07286152c69 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php
@@ -437,6 +437,7 @@ function testFieldAttachForm() {
     // When generating form for all fields.
     $form = array();
     $form_state = form_state_defaults();
+    $form_state['form_display'] = entity_get_form_display($entity_type, $this->instance['bundle'], 'default');
     field_attach_form($entity, $form, $form_state);
 
     $this->assertEqual($form[$this->field_name][$langcode]['#title'], $this->instance['label'], "First field's form title is {$this->instance['label']}");
@@ -454,6 +455,7 @@ function testFieldAttachForm() {
     $options = array('field_name' => $this->field_name_2);
     $form = array();
     $form_state = form_state_defaults();
+    $form_state['form_display'] = entity_get_form_display($entity_type, $this->instance['bundle'], 'default');
     field_attach_form($entity, $form, $form_state, NULL, $options);
 
     $this->assertFalse(isset($form[$this->field_name]), 'The first field does not exist in the form');
@@ -477,6 +479,7 @@ function testFieldAttachExtractFormValues() {
     // Build the form for all fields.
     $form = array();
     $form_state = form_state_defaults();
+    $form_state['form_display'] = entity_get_form_display($entity_type, $this->instance['bundle'], 'default');
     field_attach_form($entity_init, $form, $form_state);
 
     // Simulate incoming values.
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldAttachStorageTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldAttachStorageTest.php
index 38499c8b47331e611f036ce29813d81f11fb2204..b9e87c72f1d2385f05ca471dca9a1f98e2186006 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldAttachStorageTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldAttachStorageTest.php
@@ -495,11 +495,7 @@ function testEntityDeleteBundle() {
       'label' => $this->randomName() . '_label',
       'description' => $this->randomName() . '_description',
       'weight' => mt_rand(0, 127),
-      // test_field has no instance settings
-      'widget' => array(
-        'type' => 'test_field_widget',
-        'settings' => array(
-          'size' => mt_rand(0, 255))));
+    );
     field_create_instance($instance);
 
     // Save an entity with data for both fields
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php
index 122d14c4ea0d16c54aa6c0b665ad643756dc2c7c..dd093d5833237c6d36dfd4f5d5ae560ff9c01866 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php
@@ -79,11 +79,7 @@ function testFieldInfo() {
       'label' => $this->randomName(),
       'description' => $this->randomName(),
       'weight' => mt_rand(0, 127),
-      // test_field has no instance settings
-      'widget' => array(
-        'type' => 'test_field_widget',
-        'settings' => array(
-          'test_setting' => 999)));
+    );
     field_create_instance($instance);
 
     $info = entity_get_info('test_entity');
@@ -181,12 +177,6 @@ function testInstancePrepare() {
     // Check that all expected instance settings are in place.
     $field_type = field_info_field_types($field_definition['type']);
     $this->assertEqual($instance['settings'], $field_type['instance_settings'] , 'All expected instance settings are present.');
-
-    // Check that the default widget is used and expected settings are in place.
-    $widget = $instance->getWidget();
-    $this->assertIdentical($widget->getPluginId(), $field_type['default_widget'], 'Unavailable widget replaced with default widget.');
-    $widget_type = $widget->getDefinition();
-    $this->assertIdentical($widget->getSettings(), $widget_type['settings'] , 'All expected widget settings are present.');
   }
 
   /**
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php
index 2455a31db075d900fa42d8310c0cb5fa71e27f74..5f9578a51ce3ec26ad2c3cec1a239a20fb1dfa5c 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php
@@ -55,17 +55,14 @@ function testCreateFieldInstance() {
     $config = \Drupal::config('field.instance.' . $instance->id())->get();
 
     $field_type = field_info_field_types($this->field['type']);
-    $widget_type = field_info_widget_types($field_type['default_widget']);
 
     // Check that default values are set.
     $this->assertEqual($config['required'], FALSE, 'Required defaults to false.');
     $this->assertIdentical($config['label'], $this->instance_definition['field_name'], 'Label defaults to field name.');
     $this->assertIdentical($config['description'], '', 'Description defaults to empty string.');
-    $this->assertIdentical($config['widget']['type'], $field_type['default_widget'], 'Default widget has been written.');
 
     // Check that default settings are set.
     $this->assertEqual($config['settings'], $field_type['instance_settings'] , 'Default instance settings have been written.');
-    $this->assertIdentical($config['widget']['settings'], $widget_type['settings'] , 'Default widget settings have been written.');
 
     // Guarantee that the field/bundle combination is unique.
     try {
@@ -147,26 +144,12 @@ function testUpdateFieldInstance() {
     $instance['label'] = $this->randomName();
     $instance['description'] = $this->randomName();
     $instance['settings']['test_instance_setting'] = $this->randomName();
-    $instance['widget']['settings']['test_widget_setting'] =$this->randomName();
-    $instance['widget']['weight']++;
     field_update_instance($instance);
 
     $instance_new = field_read_instance('test_entity', $this->instance_definition['field_name'], $this->instance_definition['bundle']);
     $this->assertEqual($instance['required'], $instance_new['required'], '"required" change is saved');
     $this->assertEqual($instance['label'], $instance_new['label'], '"label" change is saved');
     $this->assertEqual($instance['description'], $instance_new['description'], '"description" change is saved');
-    $this->assertEqual($instance['widget']['settings']['test_widget_setting'], $instance_new['widget']['settings']['test_widget_setting'], 'Widget setting change is saved');
-    $this->assertEqual($instance['widget']['weight'], $instance_new['widget']['weight'], 'Widget weight change is saved');
-
-    // Check that changing the widget type updates the default settings.
-    $instance = field_read_instance('test_entity', $this->instance_definition['field_name'], $this->instance_definition['bundle']);
-    $instance['widget']['type'] = 'test_field_widget_multiple';
-    field_update_instance($instance);
-
-    $instance_new = field_read_instance('test_entity', $this->instance_definition['field_name'], $this->instance_definition['bundle']);
-    $this->assertEqual($instance['widget']['type'], $instance_new['widget']['type'] , 'Widget type change is saved.');
-    $settings = field_info_widget_settings($instance_new['widget']['type']);
-    $this->assertIdentical($settings, array_intersect_key($instance_new['widget']['settings'], $settings) , 'Widget type change updates default settings.');
 
     // TODO: test failures.
   }
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldUnitTestBase.php b/core/modules/field/lib/Drupal/field/Tests/FieldUnitTestBase.php
index 23f5269ff6b3967bd4fff37d4d6c142879ffee7a..ed3c151fd355931e2d39849c7dcd70f0600557b3 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldUnitTestBase.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldUnitTestBase.php
@@ -69,15 +69,17 @@ function createFieldWithInstance($suffix = '') {
       'settings' => array(
         'test_instance_setting' => $this->randomName(),
       ),
-      'widget' => array(
+    );
+    field_create_instance($this->$instance);
+
+    entity_get_form_display('test_entity', 'test_bundle', 'default')
+      ->setComponent($this->$field_name, array(
         'type' => 'test_field_widget',
-        'label' => 'Test Field',
         'settings' => array(
           'test_widget_setting' => $this->randomName(),
         )
-      )
-    );
-    field_create_instance($this->$instance);
+      ))
+      ->save();
   }
 
   /**
diff --git a/core/modules/field/lib/Drupal/field/Tests/FormTest.php b/core/modules/field/lib/Drupal/field/Tests/FormTest.php
index b0a830dc4cb722e00e881c2a9f3b8afedd7ee1a2..3d2aac3b5514c29a98b4cdce481917cb8da635db 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FormTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FormTest.php
@@ -43,13 +43,6 @@ function setUp() {
       'settings' => array(
         'test_instance_setting' => $this->randomName(),
       ),
-      'widget' => array(
-        'type' => 'test_field_widget',
-        'label' => 'Test Field',
-        'settings' => array(
-          'test_widget_setting' => $this->randomName(),
-        )
-      )
     );
   }
 
@@ -59,6 +52,9 @@ function testFieldFormSingle() {
     $this->instance['field_name'] = $this->field_name;
     field_create_field($this->field);
     field_create_instance($this->instance);
+    entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
+      ->setComponent($this->field_name)
+      ->save();
     $langcode = LANGUAGE_NOT_SPECIFIED;
 
     // Display creation form.
@@ -125,6 +121,9 @@ function testFieldFormDefaultValue() {
     $this->instance['default_value'] = array(array('value' => $default));
     field_create_field($this->field);
     field_create_instance($this->instance);
+    entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
+      ->setComponent($this->field_name)
+      ->save();
     $langcode = LANGUAGE_NOT_SPECIFIED;
 
     // Display creation form.
@@ -149,6 +148,9 @@ function testFieldFormSingleRequired() {
     $this->instance['required'] = TRUE;
     field_create_field($this->field);
     field_create_instance($this->instance);
+    entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
+      ->setComponent($this->field_name)
+      ->save();
     $langcode = LANGUAGE_NOT_SPECIFIED;
 
     // Submit with missing required value.
@@ -187,6 +189,9 @@ function testFieldFormUnlimited() {
     $this->instance['field_name'] = $this->field_name;
     field_create_field($this->field);
     field_create_instance($this->instance);
+    entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
+      ->setComponent($this->field_name)
+      ->save();
     $langcode = LANGUAGE_NOT_SPECIFIED;
 
     // Display creation form -> 1 widget.
@@ -267,6 +272,9 @@ function testFieldFormMultivalueWithRequiredRadio() {
     $this->instance['field_name'] = $this->field_name;
     field_create_field($this->field);
     field_create_instance($this->instance);
+    entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
+      ->setComponent($this->field_name)
+      ->save();
     $langcode = LANGUAGE_NOT_SPECIFIED;
 
     // Add a required radio field.
@@ -282,11 +290,13 @@ function testFieldFormMultivalueWithRequiredRadio() {
       'entity_type' => 'test_entity',
       'bundle' => 'test_bundle',
       'required' => TRUE,
-      'widget' => array(
-        'type' => 'options_buttons',
-      ),
     );
     field_create_instance($instance);
+    entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')
+      ->setComponent($instance['field_name'], array(
+        'type' => 'options_buttons',
+      ))
+      ->save();
 
     // Display creation form.
     $this->drupalGet('test-entity/add/test_bundle');
@@ -309,6 +319,9 @@ function testFieldFormJSAddMore() {
     $this->instance['field_name'] = $this->field_name;
     field_create_field($this->field);
     field_create_instance($this->instance);
+    entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
+      ->setComponent($this->field_name)
+      ->save();
     $langcode = LANGUAGE_NOT_SPECIFIED;
 
     // Display creation form -> 1 widget.
@@ -366,9 +379,13 @@ function testFieldFormMultipleWidget() {
     $this->field = $this->field_multiple;
     $this->field_name = $this->field['field_name'];
     $this->instance['field_name'] = $this->field_name;
-    $this->instance['widget']['type'] = 'test_field_widget_multiple';
     field_create_field($this->field);
     field_create_instance($this->instance);
+    entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
+      ->setComponent($this->field_name, array(
+        'type' => 'test_field_widget_multiple',
+      ))
+      ->save();
     $langcode = LANGUAGE_NOT_SPECIFIED;
 
     // Display creation form.
@@ -408,6 +425,9 @@ function testFieldFormAccess() {
     $instance['field_name'] = $field_name;
     field_create_field($field);
     field_create_instance($instance);
+    entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
+      ->setComponent($field_name)
+      ->save();
 
     // Create a field with no edit access - see field_test_field_access().
     $field_no_access = array(
@@ -423,6 +443,9 @@ function testFieldFormAccess() {
     );
     field_create_field($field_no_access);
     field_create_instance($instance_no_access);
+    entity_get_form_display($instance_no_access['entity_type'], $instance_no_access['bundle'], 'default')
+      ->setComponent($field_name_no_access)
+      ->save();
 
     $langcode = LANGUAGE_NOT_SPECIFIED;
 
@@ -433,6 +456,7 @@ function testFieldFormAccess() {
 
     $form = array();
     $form_state = form_state_defaults();
+    $form_state['form_display'] = entity_get_form_display($entity_type, $this->instance['bundle'], 'default');
     field_attach_form($entity, $form, $form_state);
 
     $this->assertEqual($form[$field_name_no_access][$langcode][0]['value']['#entity_type'], $entity_type, 'The correct entity type is set in the field structure.');
@@ -479,9 +503,15 @@ function testNestedFieldForm() {
     $this->instance['field_name'] = 'field_single';
     $this->instance['label'] = 'Single field';
     field_create_instance($this->instance);
+    entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
+      ->setComponent($this->instance['field_name'])
+      ->save();
     $this->instance['field_name'] = 'field_unlimited';
     $this->instance['label'] = 'Unlimited field';
     field_create_instance($this->instance);
+    entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
+      ->setComponent($this->instance['field_name'])
+      ->save();
 
     // Create two entities.
     $entity_1 = field_test_create_entity(1, 1);
@@ -585,10 +615,14 @@ function testFieldFormHiddenWidget() {
     $this->field = $this->field_single;
     $this->field_name = $this->field['field_name'];
     $this->instance['field_name'] = $this->field_name;
-    $this->instance['widget']['type'] = 'hidden';
     $this->instance['default_value'] = array(0 => array('value' => 99));
     field_create_field($this->field);
     field_create_instance($this->instance);
+    entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
+      ->setComponent($this->instance['field_name'], array(
+        'type' => 'hidden',
+      ))
+      ->save();
     $langcode = LANGUAGE_NOT_SPECIFIED;
 
     // Display the entity creation form.
@@ -607,8 +641,12 @@ function testFieldFormHiddenWidget() {
     // Update the instance to remove the default value and switch to the
     // default widget.
     $this->instance['default_value'] = NULL;
-    $this->instance['widget']['type'] = 'test_field_widget';
     field_update_instance($this->instance);
+    entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
+      ->setComponent($this->instance['field_name'], array(
+        'type' => 'test_field_widget',
+      ))
+      ->save();
 
     // Display edit form.
     $this->drupalGet('test-entity/manage/' . $id . '/edit');
@@ -623,9 +661,12 @@ function testFieldFormHiddenWidget() {
     $entity = field_test_entity_test_load($id);
     $this->assertEqual($entity->{$this->field_name}[$langcode][0]['value'], $value, 'Field value was updated');
 
-    // Update the instance and switch to the Hidden widget again.
-    $this->instance['widget']['type'] = 'hidden';
-    field_update_instance($this->instance);
+    // Update the form display and switch to the Hidden widget again.
+    entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
+      ->setComponent($this->instance['field_name'], array(
+        'type' => 'hidden',
+      ))
+      ->save();
 
     // Create a new revision.
     $edit = array('revision' => TRUE);
diff --git a/core/modules/field/lib/Drupal/field/Tests/ShapeItemTest.php b/core/modules/field/lib/Drupal/field/Tests/ShapeItemTest.php
index 26282564eb3a4f1c138348f6eb013e985693db33..4e92d7e681d6c29a070b0f92102db72f530c9398 100644
--- a/core/modules/field/lib/Drupal/field/Tests/ShapeItemTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/ShapeItemTest.php
@@ -43,9 +43,6 @@ public function setUp() {
       'entity_type' => 'entity_test',
       'field_name' => 'field_shape',
       'bundle' => 'entity_test',
-      'widget' => array(
-        'type' => 'test_field_widget',
-      ),
     );
     field_create_instance($this->instance);
   }
diff --git a/core/modules/field/lib/Drupal/field/Tests/TestItemTest.php b/core/modules/field/lib/Drupal/field/Tests/TestItemTest.php
index 198be2af44c6c8c60f7fa94fd62809b1ed0b0c24..c8ff8fa3e69875727730dbc08f58fc4779052544 100644
--- a/core/modules/field/lib/Drupal/field/Tests/TestItemTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/TestItemTest.php
@@ -43,9 +43,6 @@ public function setUp() {
       'entity_type' => 'entity_test',
       'field_name' => 'field_test',
       'bundle' => 'entity_test',
-      'widget' => array(
-        'type' => 'test_field_widget',
-      ),
     );
     field_create_instance($this->instance);
   }
diff --git a/core/modules/field/lib/Drupal/field/Tests/TranslationWebTest.php b/core/modules/field/lib/Drupal/field/Tests/TranslationWebTest.php
index 40447f139828400239535fa0667e6031aea7285d..a32cc81f533e713a2a6819f43562b066f8c29447 100644
--- a/core/modules/field/lib/Drupal/field/Tests/TranslationWebTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/TranslationWebTest.php
@@ -53,6 +53,10 @@ function setUp() {
     field_create_instance($instance);
     $this->instance = field_read_instance('test_entity', $this->field_name, 'test_bundle');
 
+    entity_get_form_display($this->entity_type, 'test_bundle', 'default')
+      ->setComponent($this->field_name)
+      ->save();
+
     for ($i = 0; $i < 3; ++$i) {
       $language = new Language(array(
         'langcode' => 'l' . $i,
diff --git a/core/modules/field/tests/modules/field_test/field_test.entity.inc b/core/modules/field/tests/modules/field_test/field_test.entity.inc
index 32f20b34c1bd417e63a2fa73b1322b605b70bbbc..817986f851e71e5ea5864ab6a2e3b4fffccc4007 100644
--- a/core/modules/field/tests/modules/field_test/field_test.entity.inc
+++ b/core/modules/field/tests/modules/field_test/field_test.entity.inc
@@ -227,6 +227,7 @@ function field_test_entity_nested_form($form, &$form_state, $entity_1, $entity_2
       '#value' => $entity_1->$key,
     );
   }
+  $form_state['form_display'] = entity_get_form_display($entity_1->entityType(), $entity_1->bundle(), 'default');
   field_attach_form($entity_1, $form, $form_state);
 
   // Second entity.
@@ -243,6 +244,7 @@ function field_test_entity_nested_form($form, &$form_state, $entity_1, $entity_2
       '#value' => $entity_2->$key,
     );
   }
+  $form_state['form_display'] = entity_get_form_display($entity_1->entityType(), $entity_1->bundle(), 'default');
   field_attach_form($entity_2, $form['entity_2'], $form_state);
 
   $form['save'] = array(
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 33623bf3d419173f52ea27d80a950d5f00dc7442..2e62f7774acac1a685a5385583179a6fb909adf8 100644
--- a/core/modules/field/tests/modules/field_test/field_test.module
+++ b/core/modules/field/tests/modules/field_test/field_test.module
@@ -199,37 +199,19 @@ function field_test_field_attach_view_alter(&$output, $context) {
   }
 }
 
-/**
- * Implements hook_field_widget_properties_alter().
- */
-function field_test_field_widget_properties_alter(&$widget, $context) {
-  // Make the alter_test_text field 42 characters for nodes and comments.
-  if (in_array($context['entity_type'], array('node', 'comment')) && ($context['field']['field_name'] == 'alter_test_text')) {
-    $widget['settings']['size'] = 42;
-  }
-}
-
-/**
- * Implements hook_field_widget_properties_ENTITY_TYPE_alter().
- */
-function field_test_field_widget_properties_user_alter(&$widget, $context) {
-  // Always use buttons for the alter_test_options field on user forms.
-  if ($context['field']['field_name'] == 'alter_test_options') {
-    $widget['type'] = 'options_buttons';
-  }
-}
-
 /**
  * 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']) {
     case 'alter_test_text':
-      drupal_set_message('Field size: ' . $context['instance']->getWidget()->getSetting('size'));
+      drupal_set_message('Field size: ' . $entity_form_display->getWidget($context['field']['field_name'])->getSetting('size'));
       break;
 
     case 'alter_test_options':
-      drupal_set_message('Widget type: ' . $context['instance']->getWidget()->getPluginId());
+      drupal_set_message('Widget type: ' . $entity_form_display->getWidget($context['field']['field_name'])->getPluginId());
       break;
   }
   // Set a message if this is for the form displayed to set default value for
diff --git a/core/modules/field/tests/modules/field_test_config/config/field.instance.test_entity.test_bundle.field_test_import.yml b/core/modules/field/tests/modules/field_test_config/config/field.instance.test_entity.test_bundle.field_test_import.yml
index 4817a77b56787a307ec4a1b068d7624b2b7d277a..a179a5537d702207209f0b565e2993095ddd90c1 100644
--- a/core/modules/field/tests/modules/field_test_config/config/field.instance.test_entity.test_bundle.field_test_import.yml
+++ b/core/modules/field/tests/modules/field_test_config/config/field.instance.test_entity.test_bundle.field_test_import.yml
@@ -11,10 +11,4 @@ default_value_function: ''
 settings:
   text_processing: '0'
   user_register_form: false
-widget:
-  weight: '-2'
-  type: text_textfield
-  module: text
-  settings:
-    size: '60'
 field_type: text
diff --git a/core/modules/field/tests/modules/field_test_config/staging/field.instance.test_entity.test_bundle.field_test_import_staging.yml b/core/modules/field/tests/modules/field_test_config/staging/field.instance.test_entity.test_bundle.field_test_import_staging.yml
index 2e4229d8437ef6dd4ba0466a6632a34b84a81bb8..f751ad5e6b520d9c4b4c9fbd8db96367186cf40f 100644
--- a/core/modules/field/tests/modules/field_test_config/staging/field.instance.test_entity.test_bundle.field_test_import_staging.yml
+++ b/core/modules/field/tests/modules/field_test_config/staging/field.instance.test_entity.test_bundle.field_test_import_staging.yml
@@ -12,10 +12,4 @@ default_value_function: ''
 settings:
   text_processing: '0'
   user_register_form: '0'
-widget:
-  type: text_textfield
-  weight: '-3'
-  settings:
-    size: '60'
-  module: text
 field_type: text
diff --git a/core/modules/field_ui/field_ui.admin.inc b/core/modules/field_ui/field_ui.admin.inc
index e419063ef39f5fa2473a7a3e596fad3db4ad29a8..3ee1eaa33908c4d19aecc2d026fccf2138fe8e59 100644
--- a/core/modules/field_ui/field_ui.admin.inc
+++ b/core/modules/field_ui/field_ui.admin.inc
@@ -417,12 +417,13 @@ function field_ui_existing_field_options($entity_type, $bundle) {
             && !field_info_instance($entity_type, $field['field_name'], $bundle)
             && (empty($field['entity_types']) || in_array($entity_type, $field['entity_types']))
             && empty($field_types[$field['type']]['no_ui'])) {
+            $widget = entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')->getComponent($instance['field_name']);
             $info[$instance['field_name']] = array(
               'type' => $field['type'],
               'type_label' => $field_types[$field['type']]['label'],
               'field' => $field['field_name'],
               'label' => $instance['label'],
-              'widget_type' => $instance['widget']['type'],
+              'widget_type' => $widget['type'],
             );
           }
         }
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 c1a490d6f1932857fbc8b0129e3c222fee6675cd..e6caf4e1227deae16cad28d8e68d6c09262389a2 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php
@@ -44,12 +44,12 @@ public function getFormID() {
   public function buildForm(array $form, array &$form_state, $entity_type = NULL, $bundle = NULL, $view_mode = NULL) {
     parent::buildForm($form, $form_state, $entity_type, $bundle);
 
-    $this->view_mode = (isset($view_mode) ? $view_mode : 'default');
+    $this->mode = (isset($view_mode) ? $view_mode : 'default');
     // Gather type information.
     $instances = field_info_instances($this->entity_type, $this->bundle);
     $field_types = field_info_field_types();
     $extra_fields = field_info_extra_fields($this->entity_type, $this->bundle, 'display');
-    $entity_display = entity_get_display($this->entity_type, $this->bundle, $this->view_mode);
+    $entity_display = entity_get_display($this->entity_type, $this->bundle, $this->mode);
 
     $form_state += array(
       'formatter_settings_edit' => NULL,
@@ -58,7 +58,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL,
     $form += array(
       '#entity_type' => $this->entity_type,
       '#bundle' => $this->bundle,
-      '#view_mode' => $this->view_mode,
+      '#view_mode' => $this->mode,
       '#fields' => array_keys($instances),
       '#extra' => array_keys($extra_fields),
     );
@@ -176,7 +176,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL,
       if ($display_options && $display_options['type'] != 'hidden') {
         $formatter = drupal_container()->get('plugin.manager.field.formatter')->getInstance(array(
           'instance' => $instance,
-          'view_mode' => $this->view_mode,
+          'view_mode' => $this->mode,
           'configuration' => $display_options
         ));
       }
@@ -209,7 +209,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL,
             'formatter' => $formatter,
             'field' => $field,
             'instance' => $instance,
-            'view_mode' => $this->view_mode,
+            'view_mode' => $this->mode,
             'form' => $form,
           );
           drupal_alter('field_formatter_settings_form', $settings_form, $form_state, $context);
@@ -261,7 +261,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL,
             'formatter' => $formatter,
             'field' => $field,
             'instance' => $instance,
-            'view_mode' => $this->view_mode,
+            'view_mode' => $this->mode,
           );
           drupal_alter('field_formatter_settings_summary', $summary, $context);
 
@@ -345,7 +345,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL,
     $form['fields'] = $table;
 
     // Custom display settings.
-    if ($this->view_mode == 'default') {
+    if ($this->mode == 'default') {
       $view_modes = entity_get_view_modes($this->entity_type);
       // Only show the settings if there is more than one view mode.
       if (count($view_modes) > 1) {
@@ -414,7 +414,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL,
    */
   public function submitForm(array &$form, array &$form_state) {
     $form_values = $form_state['values'];
-    $display = entity_get_display($this->entity_type, $this->bundle, $this->view_mode);
+    $display = entity_get_display($this->entity_type, $this->bundle, $this->mode);
 
     // Collect data for 'regular' fields.
     foreach ($form['#fields'] as $field_name) {
@@ -469,7 +469,7 @@ public function submitForm(array &$form, array &$form_state) {
     $display->save();
 
     // Handle the 'view modes' checkboxes if present.
-    if ($this->view_mode == 'default' && !empty($form_values['view_modes_custom'])) {
+    if ($this->mode == 'default' && !empty($form_values['view_modes_custom'])) {
       $entity_info = entity_get_info($this->entity_type);
       $view_modes = entity_get_view_modes($this->entity_type);
       $bundle_settings = field_bundle_settings($this->entity_type, $this->bundle);
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php b/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php
index f02e2eba45250a7d36593dd5d04c86bdf836a752..ac53e2e3e1c673cf206d13c14ffe445c37ce9e37 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php
@@ -42,10 +42,10 @@ public function getFormID() {
   /**
    * Implements \Drupal\Core\Form\FormInterface::buildForm().
    */
-  public function buildForm(array $form, array &$form_state, $entity_type = NULL, $bundle = NULL) {
+  public function buildForm(array $form, array &$form_state, $entity_type = NULL, $bundle = NULL, $form_mode = NULL) {
     parent::buildForm($form, $form_state, $entity_type, $bundle);
 
-    $this->view_mode = 'form';
+    $this->mode = (isset($form_mode) ? $form_mode : 'default');
     // When displaying the form, make sure the list of fields is up-to-date.
     if (empty($form_state['post'])) {
       field_info_cache_clear();
@@ -56,6 +56,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL,
     $field_types = field_info_field_types();
     $widget_types = field_info_widget_types();
     $extra_fields = field_info_extra_fields($this->entity_type, $this->bundle, 'form');
+    $entity_form_display = entity_get_form_display($this->entity_type, $this->bundle, $this->mode);
 
     $form += array(
       '#entity_type' => $this->entity_type,
@@ -87,6 +88,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL,
     // Fields.
     foreach ($instances as $name => $instance) {
       $field = field_info_field($instance['field_name']);
+      $widget_configuration = $entity_form_display->getComponent($instance['field_name']);
       $admin_field_path = $this->adminPath . '/fields/' . $instance->id();
       $table[$name] = array(
         '#attributes' => array('class' => array('draggable', 'tabledrag-leaf')),
@@ -99,7 +101,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL,
           '#type' => 'textfield',
           '#title' => t('Weight for @title', array('@title' => $instance['label'])),
           '#title_display' => 'invisible',
-          '#default_value' => $instance['widget']['weight'],
+          '#default_value' => $widget_configuration ? $widget_configuration['weight'] : '0',
           '#size' => 3,
           '#attributes' => array('class' => array('field-weight')),
          ),
@@ -130,7 +132,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL,
         ),
         'widget_type' => array(
           '#type' => 'link',
-          '#title' => $widget_types[$instance['widget']['type']]['label'],
+          '#title' => $widget_configuration ? $widget_types[$widget_configuration['type']]['label'] : $widget_types['hiden']['label'],
           '#href' => $admin_field_path . '/widget-type',
           '#options' => array('attributes' => array('title' => t('Change widget type.'))),
         ),
@@ -205,7 +207,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL,
     }
 
     // Additional row: add new field.
-    $max_weight = field_info_max_weight($this->entity_type, $this->bundle, 'form');
+    $max_weight = $entity_form_display->getHighestWeight();
     $field_type_options = field_ui_field_type_options();
     $widget_type_options = field_ui_widget_type_options(NULL, TRUE);
     if ($field_type_options && $widget_type_options) {
@@ -521,27 +523,29 @@ protected function validateAddExisting(array $form, array &$form_state) {
    */
   public function submitForm(array &$form, array &$form_state) {
     $form_values = $form_state['values']['fields'];
+    $entity_form_display = entity_get_form_display($this->entity_type, $this->bundle, $this->mode);
 
-    $bundle_settings = field_bundle_settings($this->entity_type, $this->bundle);
+    // Collect data for 'regular' fields.
+    foreach ($form['#fields'] as $field_name) {
+      $options = $entity_form_display->getComponent($field_name);
+      $options['weight'] = $form_values[$field_name]['weight'];
 
-    // Update field weights.
-    foreach ($form_values as $key => $values) {
-      if (in_array($key, $form['#fields'])) {
-        $instance = field_read_instance($this->entity_type, $key, $this->bundle);
-        $instance['widget']['weight'] = $values['weight'];
-        field_update_instance($instance);
-      }
-      elseif (in_array($key, $form['#extra'])) {
-        $bundle_settings['extra_fields']['form'][$key]['weight'] = $values['weight'];
-      }
+      $entity_form_display->setComponent($field_name, $options);
+    }
+
+    // Collect data for 'extra' fields.
+    foreach ($form['#extra'] as $field_name) {
+      $entity_form_display->setComponent($field_name, array(
+        'weight' => $form_values[$field_name]['weight'],
+      ));
     }
 
-    field_bundle_settings($this->entity_type, $this->bundle, $bundle_settings);
+    // Save the form display.
+    $entity_form_display->save();
 
     $destinations = array();
 
     // Create new field.
-    $field = array();
     if (!empty($form_values['_add_new_field']['field_name'])) {
       $values = $form_values['_add_new_field'];
 
@@ -555,10 +559,6 @@ public function submitForm(array &$form, array &$form_state) {
         'entity_type' => $this->entity_type,
         'bundle' => $this->bundle,
         'label' => $values['label'],
-        'widget' => array(
-          'type' => $values['widget_type'],
-          'weight' => $values['weight'],
-        ),
       );
 
       // Create the field and instance.
@@ -567,6 +567,15 @@ public function submitForm(array &$form, array &$form_state) {
         $new_instance = $this->entityManager->getStorageController('field_instance')->create($instance);
         $new_instance->save();
 
+        // Make sure the field is displayed in the 'default' form mode (using
+        // the configured widget and default settings).
+        entity_get_form_display($this->entity_type, $this->bundle, 'default')
+          ->setComponent($field['field_name'], array(
+            'type' => $values['widget_type'],
+            'weight' => $values['weight'],
+          ))
+          ->save();
+
         // Make sure the field is displayed in the 'default' view mode (using
         // default formatter and settings). It stays hidden for other view
         // modes until it is explicitly configured.
@@ -582,7 +591,7 @@ public function submitForm(array &$form, array &$form_state) {
         // Store new field information for any additional submit handlers.
         $form_state['fields_added']['_add_new_field'] = $field['field_name'];
       }
-      catch (Exception $e) {
+      catch (\Exception $e) {
         drupal_set_message(t('There was a problem creating field %label: !message', array('%label' => $instance['label'], '!message' => $e->getMessage())), 'error');
       }
     }
@@ -600,16 +609,21 @@ public function submitForm(array &$form, array &$form_state) {
           'entity_type' => $this->entity_type,
           'bundle' => $this->bundle,
           'label' => $values['label'],
-          'widget' => array(
-            'type' => $values['widget_type'],
-            'weight' => $values['weight'],
-          ),
         );
 
         try {
           $new_instance = $this->entityManager->getStorageController('field_instance')->create($instance);
           $new_instance->save();
 
+          // Make sure the field is displayed in the 'default' form mode (using
+          // the configured widget and default settings).
+          entity_get_form_display($this->entity_type, $this->bundle, 'default')
+            ->setComponent($field['field_name'], array(
+              'type' => $values['widget_type'],
+              'weight' => $values['weight'],
+            ))
+            ->save();
+
           // Make sure the field is displayed in the 'default' view mode (using
           // default formatter and settings). It stays hidden for other view
           // modes until it is explicitly configured.
@@ -621,7 +635,7 @@ public function submitForm(array &$form, array &$form_state) {
           // Store new field information for any additional submit handlers.
           $form_state['fields_added']['_add_existing_field'] = $instance['field_name'];
         }
-        catch (Exception $e) {
+        catch (\Exception $e) {
           drupal_set_message(t('There was a problem creating field instance %label: @message.', array('%label' => $instance['label'], '@message' => $e->getMessage())), 'error');
         }
       }
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 48037011bf2a9c383c1651d37de87fc6db90e35b..d8788a75a8a6eb96c2b5951e9904ca6ef03f37b2 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
@@ -67,6 +67,7 @@ public function buildForm(array $form, array &$form_state, FieldInstance $field_
     $bundle = $this->instance['bundle'];
     $entity_type = $this->instance['entity_type'];
     $field = $this->instance->getField();
+    $entity_form_display = entity_get_form_display($entity_type, $bundle, 'default');
     $bundles = entity_get_bundles();
 
     drupal_set_title(t('%instance settings for %bundle', array(
@@ -75,6 +76,7 @@ public function buildForm(array $form, array &$form_state, FieldInstance $field_
     )), PASS_THROUGH);
 
     $form['#field'] = $field;
+    $form['#entity_form_display'] = $entity_form_display;
     // Create an arbitrary entity object (used by the 'default value' widget).
     $ids = (object) array('entity_type' => $this->instance['entity_type'], 'bundle' => $this->instance['bundle'], 'entity_id' => NULL);
     $form['#entity'] = _field_create_entity_from_ids($ids);
@@ -87,8 +89,6 @@ public function buildForm(array $form, array &$form_state, FieldInstance $field_
       return $form;
     }
 
-    $widget_type = $this->widgetManager->getDefinition($this->instance['widget']['type']);
-
     // Create a form structure for the instance values.
     $form['instance'] = array(
       '#tree' => TRUE,
@@ -107,10 +107,6 @@ public function buildForm(array $form, array &$form_state, FieldInstance $field_
       '#type' => 'value',
       '#value' => $bundle,
     );
-    $form['instance']['widget']['weight'] = array(
-      '#type' => 'value',
-      '#value' => !empty($this->instance['widget']['weight']) ? $this->instance['widget']['weight'] : 0,
-    );
 
     // Build the configurable instance values.
     $form['instance']['label'] = array(
@@ -137,12 +133,6 @@ public function buildForm(array $form, array &$form_state, FieldInstance $field_
       '#weight' => -5,
     );
 
-    // Build the widget component of the instance.
-    $form['instance']['widget']['type'] = array(
-      '#type' => 'value',
-      '#value' => $this->instance['widget']['type'],
-    );
-
     // Add additional field instance settings from the field module.
     $additions = \Drupal::moduleHandler()->invoke($field['module'], 'field_instance_settings_form', array($field, $this->instance, $form_state));
     if (is_array($additions)) {
@@ -151,7 +141,7 @@ public function buildForm(array $form, array &$form_state, FieldInstance $field_
     }
 
     // Add widget settings for the widget type.
-    $additions = $this->instance->getWidget()->settingsForm($form, $form_state);
+    $additions = $entity_form_display->getWidget($this->instance->getField()->id)->settingsForm($form, $form_state);
     $form['instance']['widget']['settings'] = $additions ?: array('#type' => 'value', '#value' => array());
     $form['instance']['widget']['#weight'] = 20;
 
@@ -181,13 +171,14 @@ public function validateForm(array &$form, array &$form_state) {
     // value' gets validated using the instance settings being submitted.
     $field_name = $this->instance['field_name'];
     $entity = $form['#entity'];
+    $entity_form_display = $form['#entity_form_display'];
 
     if (isset($form['instance']['default_value_widget'])) {
       $element = $form['instance']['default_value_widget'];
 
       // Extract the 'default value'.
       $items = array();
-      $this->instance->getWidget()->extractFormValues($entity, LANGUAGE_NOT_SPECIFIED, $items, $element, $form_state);
+      $entity_form_display->getWidget($this->instance->getField()->id)->extractFormValues($entity, LANGUAGE_NOT_SPECIFIED, $items, $element, $form_state);
 
       // Grab the field definition from $form_state.
       $field_state = field_form_get_state($element['#parents'], $field_name, LANGUAGE_NOT_SPECIFIED, $form_state);
@@ -207,7 +198,7 @@ public function validateForm(array &$form, array &$form_state) {
         field_form_set_state($element['#parents'], $field_name, LANGUAGE_NOT_SPECIFIED, $form_state, $field_state);
 
         // Assign reported errors to the correct form element.
-        $this->instance->getWidget()->flagErrors($entity, LANGUAGE_NOT_SPECIFIED, $items, $element, $form_state);
+        $entity_form_display->getWidget($this->instance->getField()->id)->flagErrors($entity, LANGUAGE_NOT_SPECIFIED, $items, $element, $form_state);
       }
     }
   }
@@ -217,8 +208,8 @@ public function validateForm(array &$form, array &$form_state) {
    */
   public function submitForm(array &$form, array &$form_state) {
     form_load_include($form_state, 'inc', 'field_ui', 'field_ui.admin');
-    $field = $form['#field'];
     $entity = $form['#entity'];
+    $entity_form_display = $form['#entity_form_display'];
 
     // Handle the default value.
     if (isset($form['instance']['default_value_widget'])) {
@@ -226,11 +217,17 @@ public function submitForm(array &$form, array &$form_state) {
 
       // Extract field values.
       $items = array();
-      $this->instance->getWidget()->extractFormValues($entity, LANGUAGE_NOT_SPECIFIED, $items, $element, $form_state);
+      $entity_form_display->getWidget($this->instance->getField()->id)->extractFormValues($entity, LANGUAGE_NOT_SPECIFIED, $items, $element, $form_state);
 
       $this->instance['default_value'] = $items ? $items : NULL;
     }
 
+    // Handle widget settings.
+    $options = $entity_form_display->getComponent($this->instance->getField()->id);
+    $options['settings'] = $form_state['values']['instance']['widget']['settings'];
+    $entity_form_display->setComponent($this->instance->getField()->id, $options)->save();
+    unset($form_state['values']['instance']['widget']);
+
     // Merge incoming values into the instance.
     foreach ($form_state['values']['instance'] as $key => $value) {
       $this->instance[$key] = $value;
@@ -262,8 +259,8 @@ public function delete(array &$form, array &$form_state) {
    * Builds the default value widget for a given field instance.
    */
   protected function getDefaultValueWidget($field, array &$form, &$form_state) {
-    $field_name = $field['field_name'];
     $entity = $form['#entity'];
+    $entity_form_display = $form['#entity_form_display'];
 
     $element = array(
       '#type' => 'details',
@@ -300,7 +297,7 @@ protected function getDefaultValueWidget($field, array &$form, &$form_state) {
     if (!empty($this->instance['default_value'])) {
       $items = (array) $this->instance['default_value'];
     }
-    $element += $this->instance->getWidget()->form($entity, LANGUAGE_NOT_SPECIFIED, $items, $element, $form_state);
+    $element += $entity_form_display->getWidget($this->instance->getField()->id)->form($entity, LANGUAGE_NOT_SPECIFIED, $items, $element, $form_state);
 
     return $element;
   }
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldWidgetTypeForm.php b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldWidgetTypeForm.php
index b28083a87bd09ee0676cdabc1eff9c1b57c00a24..5558bc64b78195d67f94b73c310a690aad10b961 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldWidgetTypeForm.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldWidgetTypeForm.php
@@ -70,6 +70,7 @@ public function buildForm(array $form, array &$form_state, FieldInstance $field_
     $entity_type = $this->instance['entity_type'];
     $field_name = $this->instance['field_name'];
 
+    $entity_form_display = entity_get_form_display($entity_type, $bundle, 'default');
     $field = $this->instance->getField();
     $bundles = entity_get_bundles();
     $bundle_label = $bundles[$entity_type][$bundle]['label'];
@@ -78,6 +79,7 @@ public function buildForm(array $form, array &$form_state, FieldInstance $field_
       '#bundle' => $bundle,
       '#entity_type' => $entity_type,
       '#field_name' => $field_name,
+      '#instance' => $this->instance,
     );
 
     $form['widget_type'] = array(
@@ -85,7 +87,7 @@ public function buildForm(array $form, array &$form_state, FieldInstance $field_
       '#title' => t('Widget type'),
       '#required' => TRUE,
       '#options' => field_ui_widget_type_options($field['type']),
-      '#default_value' => $this->instance->getWidget()->getPluginId(),
+      '#default_value' => $entity_form_display->getWidget($field_name)->getPluginId(),
       '#description' => t('The type of form element you would like to present to the user when creating this field in the %type type.', array('%type' => $bundle_label)),
     );
 
@@ -109,19 +111,15 @@ public function submitForm(array &$form, array &$form_state) {
     $bundle = $form['#bundle'];
     $entity_type = $form['#entity_type'];
     $field_name = $form['#field_name'];
+    $instance = $form['#instance'];
 
-    // Retrieve the stored instance settings to merge with the incoming values.
-    $instance = field_read_instance($entity_type, $field_name, $bundle);
-
-    // Set the right module information.
-    $widget_type = $this->widgetManager->getDefinition($form_values['widget_type']);
-    $widget_module = $widget_type['module'];
-
-    $instance['widget']['type'] = $form_values['widget_type'];
-    $instance['widget']['module'] = $widget_module;
+    $entity_form_display = entity_get_form_display($entity_type, $bundle, 'default')
+      ->setComponent($field_name, array(
+        'type' => $form_values['widget_type'],
+      ));
 
     try {
-      $instance->save();
+      $entity_form_display->save();
       drupal_set_message(t('Changed the widget for field %label.', array('%label' => $instance['label'])));
 
       if ($instance['required'] && empty($instance['default_value']) && empty($instance['default_value_function']) && $instance['widget']['type'] == 'field_hidden') {
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/OverviewBase.php b/core/modules/field_ui/lib/Drupal/field_ui/OverviewBase.php
index a8cd8912fa968dcfc8412bfa10c4c8d4190dc71b..20f6c09c1902874e19cd435c2cf044103f91f1dd 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/OverviewBase.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/OverviewBase.php
@@ -32,11 +32,11 @@ abstract class OverviewBase implements FormInterface, ControllerInterface {
   protected $bundle = '';
 
   /**
-   * The entity view mode.
+   * The entity view or form mode.
    *
    * @var string
    */
-  protected $view_mode = '';
+  protected $mode = '';
 
   /**
    * The admin path of the overview page.
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/AlterTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/AlterTest.php
deleted file mode 100644
index 1c688fbf7bc98edb3029f274606c94c6afd1607c..0000000000000000000000000000000000000000
--- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/AlterTest.php
+++ /dev/null
@@ -1,112 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\field_ui\Tests\AlterTest.
- */
-
-namespace Drupal\field_ui\Tests;
-
-use Drupal\simpletest\WebTestBase;
-
-/**
- * Tests custom widget hooks and callbacks on the field administration pages.
- */
-class AlterTest extends WebTestBase {
-
-  /**
-   * Modules to enable.
-   *
-   * @var array
-   */
-  public static $modules = array('field_ui', 'field_test', 'text', 'options');
-
-  public static function getInfo() {
-    return array(
-      'name' => 'Widget customization',
-      'description' => 'Test custom field widget hooks and callbacks on field administration pages.',
-      'group' => 'Field UI',
-    );
-  }
-
-  function setUp() {
-    parent::setUp();
-
-    // Create Article node type.
-    $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page'));
-    $this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article'));
-
-    // Create test user.
-    $admin_user = $this->drupalCreateUser(array('access content', 'administer content types', 'administer node fields', 'administer users', 'administer user fields'));
-    $this->drupalLogin($admin_user);
-  }
-
-  /**
-   * Tests hook_field_widget_properties_alter() on the default field widget.
-   *
-   * @see field_test_field_widget_properties_alter()
-   * @see field_test_field_widget_properties_user_alter()
-   * @see field_test_field_widget_form_alter()
-   */
-  function testDefaultWidgetPropertiesAlter() {
-    // Create the alter_test_text field and an instance on article nodes.
-    field_create_field(array(
-      'field_name' => 'alter_test_text',
-      'type' => 'text',
-    ));
-    $instance = array(
-      'field_name' => 'alter_test_text',
-      'entity_type' => 'node',
-      'bundle' => 'article',
-      'widget' => array(
-        'type' => 'text_textfield',
-        'size' => 60,
-      ),
-    );
-    field_create_instance($instance);
-
-    // Test that field_test_field_widget_properties_alter() sets the size to
-    // 42 and that field_test_field_widget_form_alter() reports the correct
-    // size when the form is displayed.
-    $this->drupalGet('admin/structure/types/manage/article/fields/node.article.alter_test_text');
-    $this->assertText('Field size: 42', 'Altered field size is found in hook_field_widget_form_alter().');
-    // Test that hook_field_widget_form_alter() registers this is the default
-    // value form and sets a message.
-    $this->assertText('From hook_field_widget_form_alter(): Default form is true.', 'Default value form detected in hook_field_widget_form_alter().');
-
-    // Create the alter_test_options field.
-    field_create_field(array(
-      'field_name' => 'alter_test_options',
-      'type' => 'list_text'
-    ));
-    // Create instances on users and page nodes.
-    $instance = array(
-      'field_name' => 'alter_test_options',
-      'entity_type' => 'user',
-      'bundle' => 'user',
-      'widget' => array(
-        'type' => 'options_select',
-      )
-    );
-    field_create_instance($instance);
-    $instance = array(
-      'field_name' => 'alter_test_options',
-      'entity_type' => 'node',
-      'bundle' => 'page',
-      'widget' => array(
-        'type' => 'options_select',
-      )
-    );
-    field_create_instance($instance);
-
-    // Test that field_test_field_widget_properties_user_alter() replaces
-    // the widget and that field_test_field_widget_form_alter() reports the
-    // correct widget name when the form is displayed.
-    $this->drupalGet('admin/config/people/accounts/fields/user.user.alter_test_options');
-    $this->assertText('Widget type: options_buttons', 'Widget type is altered for users in hook_field_widget_form_alter().');
-
-    // Test that the widget is not altered on page nodes.
-    $this->drupalGet('admin/structure/types/manage/page/fields/node.page.alter_test_options');
-    $this->assertText('Widget type: options_select', 'Widget type is not altered for pages in hook_field_widget_form_alter().');
-  }
-}
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php
index 9b60409a7d5333b05a43293f9cea7c0e2a85b9cf..582e47847fc317eee60724ff643cbcdd3c35f70b 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php
@@ -52,6 +52,10 @@ function setUp() {
       'bundle' => 'article',
     );
     field_create_instance($instance);
+
+    entity_get_form_display('node', 'article', 'default')
+      ->setComponent('field_' . $vocabulary->id())
+      ->save();
   }
 
   /**
@@ -232,7 +236,10 @@ function assertFieldSettings($bundle, $field_name, $string = 'dummy test string'
     // Assert instance and widget settings.
     $instance = field_info_instance($entity_type, $field_name, $bundle);
     $this->assertTrue($instance['settings']['test_instance_setting'] == $string, 'Field instance settings were found.');
-    $this->assertTrue($instance['widget']['settings']['test_widget_setting'] == $string, 'Field widget settings were found.');
+
+    // Assert widget settings.
+    $widget_configuration = entity_get_form_display($entity_type, $bundle, 'default')->getComponent($field_name);
+    $this->assertTrue($widget_configuration['settings']['test_widget_setting'] == $string, 'Field widget settings were found.');
   }
 
   /**
@@ -253,6 +260,10 @@ function testDefaultValue() {
     );
     $instance = field_create_instance($instance);
 
+    entity_get_form_display('node', $this->type, 'default')
+      ->setComponent($field_name)
+      ->save();
+
     $langcode = LANGUAGE_NOT_SPECIFIED;
     $admin_path = 'admin/structure/types/manage/' . $this->type . '/fields/' . $instance->id();
     $element_id = "edit-$field_name-$langcode-0-value";
@@ -269,6 +280,7 @@ function testDefaultValue() {
     $edit = array($element_name => '1');
     $this->drupalPost($admin_path, $edit, t('Save settings'));
     $this->assertText("Saved $field_name configuration", 'The form was successfully submitted.');
+    field_info_cache_clear();
     $instance = field_info_instance('node', $field_name, $this->type);
     $this->assertEqual($instance['default_value'], array(array('value' => 1)), 'The default value was correctly saved.');
 
@@ -285,8 +297,11 @@ function testDefaultValue() {
     $this->assertEqual($instance['default_value'], NULL, 'The default value was correctly saved.');
 
     // Change the widget to TestFieldWidgetNoDefault.
-    $instance['widget']['type'] = 'test_field_widget_no_default';
-    field_update_instance($instance);
+    entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')
+      ->setComponent($field_name, array(
+        'type' => 'test_field_widget_no_default',
+      ))
+      ->save();
 
     $this->drupalGet($admin_path);
     $this->assertNoFieldById($element_id, '', t('No default value was possible for widget that disables default value.'));
@@ -355,10 +370,12 @@ function testLockedField() {
       'field_uuid' => $field->uuid,
       'entity_type' => 'node',
       'bundle' => $this->type,
-      'widget' => array(
-        'type' => 'test_field_widget',
-      )
     ))->save();
+    entity_get_form_display('node', $this->type, 'default')
+      ->setComponent($field->id, array(
+        'type' => 'test_field_widget',
+      ))
+      ->save();
 
     // Check that the links for edit and delete are not present.
     $this->drupalGet('admin/structure/types/manage/' . $this->type . '/fields');
@@ -388,9 +405,11 @@ function testHiddenFields() {
       'bundle' => $this->type,
       'entity_type' => 'node',
       'label' => t('Hidden field'),
-      'widget' => array('type' => 'test_field_widget'),
     );
     field_create_instance($instance);
+    entity_get_form_display('node', $this->type, 'default')
+      ->setComponent($field_name)
+      ->save();
     $this->assertTrue(field_read_instance('node', $field_name, $this->type), format_string('An instance of the field %field was created programmatically.', array('%field' => $field_name)));
 
     // Check that the newly added instance appears on the 'Manage Fields'
@@ -446,8 +465,8 @@ function testWidgetChange() {
 
     // Check that the field_tags field currently uses the 'options_select'
     // widget.
-    $instance = field_info_instance('node', 'field_tags', 'article');
-    $this->assertEqual($instance['widget']['type'], 'options_select');
+    $entity_form_display = entity_get_form_display('node', 'article', 'default')->getComponent('field_tags');
+    $this->assertEqual($entity_form_display['type'], 'options_select');
 
     // Check that the "Manage fields" page shows the correct widget type.
     $this->drupalGet($url_fields);
@@ -471,8 +490,8 @@ function testWidgetChange() {
 
     // Check that the field uses the newly set widget.
     field_cache_clear();
-    $instance = field_info_instance('node', 'field_tags', 'article');
-    $this->assertEqual($instance['widget']['type'], 'options_buttons');
+    $widget_configuration = entity_get_form_display('node', 'article', 'default')->getComponent('field_tags');
+    $this->assertEqual($widget_configuration['type'], 'options_buttons');
 
     // Go to the 'Widget type' form and check that the correct widget is
     // selected.
diff --git a/core/modules/file/file.field.inc b/core/modules/file/file.field.inc
index de03e50d776a3e3db2d23e973af5d36b53bd6268..59d068bf68565b0b4a466788c11167935f62d65e 100644
--- a/core/modules/file/file.field.inc
+++ b/core/modules/file/file.field.inc
@@ -451,7 +451,6 @@ function file_field_widget_process($element, &$form_state, $form) {
 
   $field = field_widget_field($element, $form_state);
   $instance = field_widget_instance($element, $form_state);
-  $settings = $instance['widget']['settings'];
 
   $element['#theme'] = 'file_widget';
 
diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php
index 8cff7311d7beee3a683378e9421a7361a322f98e..ac2f428030d08695189ec590d0936d68e263ff13 100644
--- a/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php
+++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php
@@ -102,14 +102,16 @@ function attachFileField($name, $entity_type, $bundle, $instance_settings = arra
       'bundle' => $bundle,
       'required' => !empty($instance_settings['required']),
       'settings' => array(),
-      'widget' => array(
-        'type' => 'file_generic',
-        'settings' => array(),
-      ),
     );
     $instance['settings'] = array_merge($instance['settings'], $instance_settings);
-    $instance['widget']['settings'] = array_merge($instance['widget']['settings'], $widget_settings);
     field_create_instance($instance);
+
+    entity_get_form_display($entity_type, $bundle, 'default')
+      ->setComponent($name, array(
+        'type' => 'file_generic',
+        'settings' => $widget_settings,
+      ))
+      ->save();
   }
 
   /**
@@ -118,9 +120,14 @@ function attachFileField($name, $entity_type, $bundle, $instance_settings = arra
   function updateFileField($name, $type_name, $instance_settings = array(), $widget_settings = array()) {
     $instance = field_info_instance('node', $name, $type_name);
     $instance['settings'] = array_merge($instance['settings'], $instance_settings);
-    $instance['widget']['settings'] = array_merge($instance['widget']['settings'], $widget_settings);
 
     field_update_instance($instance);
+
+    entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')
+      ->setComponent($instance['field_name'], array(
+        'settings' => $widget_settings,
+      ))
+      ->save();
   }
 
   /**
diff --git a/core/modules/forum/forum.install b/core/modules/forum/forum.install
index 6855a6d98035652f9b486858a7ab473ec1a1e511..a6641a2dd2ea0c2312908410c87e8922d4e678d7 100644
--- a/core/modules/forum/forum.install
+++ b/core/modules/forum/forum.install
@@ -84,12 +84,16 @@ function forum_enable() {
       'label' => $vocabulary->name,
       'bundle' => 'forum',
       'required' => TRUE,
-      'widget' => array(
-        'type' => 'options_select',
-      ),
     );
     field_create_instance($instance);
 
+    // Assign form display settings for the 'default' form mode.
+    entity_get_form_display('node', 'forum', 'default')
+      ->setComponent('taxonomy_forums', array(
+        'type' => 'options_select',
+      ))
+      ->save();
+
     // Assign display settings for the 'default' and 'teaser' view modes.
     entity_get_display('node', 'forum', 'default')
       ->setComponent('taxonomy_forums', array(
diff --git a/core/modules/hal/lib/Drupal/hal/Tests/NormalizerTestBase.php b/core/modules/hal/lib/Drupal/hal/Tests/NormalizerTestBase.php
index b40bffadcf9659883a3c9942b59376b9e95f346f..2d73a24eb480a490be8dd2134baea1a4836add3f 100644
--- a/core/modules/hal/lib/Drupal/hal/Tests/NormalizerTestBase.php
+++ b/core/modules/hal/lib/Drupal/hal/Tests/NormalizerTestBase.php
@@ -30,7 +30,7 @@ abstract class NormalizerTestBase extends DrupalUnitTestBase {
    *
    * @var array
    */
-  public static $modules = array('entity_test', 'entity_reference', 'field', 'field_sql_storage', 'hal', 'language', 'rest', 'serialization', 'system', 'text', 'user');
+  public static $modules = array('entity', 'entity_test', 'entity_reference', 'field', 'field_sql_storage', 'hal', 'language', 'rest', 'serialization', 'system', 'text', 'user');
 
   /**
    * The mock serializer.
diff --git a/core/modules/image/lib/Drupal/image/ImageStyleStorageController.php b/core/modules/image/lib/Drupal/image/ImageStyleStorageController.php
index 4bbbbde67a213a89b00c1df033ae024045b54041..97766b520b27ef97eccf7d46f9b0b58aab578b70 100644
--- a/core/modules/image/lib/Drupal/image/ImageStyleStorageController.php
+++ b/core/modules/image/lib/Drupal/image/ImageStyleStorageController.php
@@ -76,7 +76,7 @@ protected function replaceImageStyle(ImageStyle $style) {
       $instances = field_read_instances();
       // Loop through all fields searching for image fields.
       foreach ($instances as $instance) {
-        if ($instance['widget']['module'] == 'image') {
+        if ($instance->getField()->type == 'image') {
           $view_modes = entity_get_view_modes($instance['entity_type']);
           $view_modes = array('default') + array_keys($view_modes);
           foreach ($view_modes as $view_mode) {
@@ -92,9 +92,12 @@ protected function replaceImageStyle(ImageStyle $style) {
                 ->save();
             }
           }
-          if ($instance['widget']['settings']['preview_image_style'] == $style->getOriginalID()) {
-            $instance['widget']['settings']['preview_image_style'] = $style->id();
-            field_update_instance($instance);
+          $entity_form_display = entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default');
+          $widget_configuration = $entity_form_display->getComponent($instance['field_name']);
+          if ($widget_configuration['settings']['preview_image_style'] == $style->getOriginalID()) {
+            $widget_options['settings']['preview_image_style'] = $style->id();
+            $entity_form_display->setComponent($instance['field_name'], $widget_options)
+              ->save();
           }
         }
       }
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php
index 7767dc42eaf51084398530739333e7634a156f94..40e380d4bbcf805e97bcc01c55551f38101691c4 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php
@@ -65,10 +65,14 @@ function testDefaultImages() {
       'settings' => array(
         'default_image' => array($default_images['instance2']->fid),
       ),
-      'widget' => $instance['widget'],
     );
     field_create_instance($instance2);
     $instance2 = field_info_instance('node', $field_name, 'page');
+
+    $widget_settings = entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')->getComponent($field['field_name']);
+    entity_get_form_display('node', 'page', 'default')
+      ->setComponent($field['field_name'], $widget_settings)
+      ->save();
     entity_get_display('node', 'page', 'default')
       ->setComponent($field['field_name'])
       ->save();
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php
index 5a4e20e89d82cff31b4a7fc41d1f0f3c9651ab69..508c9bcab27a372d7a68d81b9e20499747c04b1e 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php
@@ -85,16 +85,17 @@ function createImageField($name, $type_name, $field_settings = array(), $instanc
       'required' => !empty($instance_settings['required']),
       'description' => !empty($instance_settings['description']) ? $instance_settings['description'] : '',
       'settings' => array(),
-      'widget' => array(
-        'type' => 'image_image',
-        'settings' => array(),
-      ),
     );
     $instance['settings'] = array_merge($instance['settings'], $instance_settings);
-    $instance['widget']['settings'] = array_merge($instance['widget']['settings'], $widget_settings);
-
     $field_instance = field_create_instance($instance);
 
+    entity_get_form_display('node', $type_name, 'default')
+      ->setComponent($field['field_name'], array(
+        'type' => 'image_image',
+        'settings' => $widget_settings,
+      ))
+      ->save();
+
     entity_get_display('node', $type_name, 'default')
       ->setComponent($field['field_name'])
       ->save();
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageItemTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageItemTest.php
index 7f863cfdea5f0c04f150dd4a46b3904a55349d77..709073da51daef2c94021e55bcc8df6716e79b36 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageItemTest.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageItemTest.php
@@ -53,9 +53,6 @@ public function setUp() {
       'entity_type' => 'entity_test',
       'field_name' => 'image_test',
       'bundle' => 'entity_test',
-      'widget' => array(
-        'type' => 'image_image',
-      ),
     );
     field_create_instance($instance);
     file_unmanaged_copy(DRUPAL_ROOT . '/core/misc/druplicon.png', 'public://example.jpg');
diff --git a/core/modules/link/lib/Drupal/link/Tests/LinkFieldTest.php b/core/modules/link/lib/Drupal/link/Tests/LinkFieldTest.php
index f28bcc2df551831978022ad72e296b5e7a71f66e..0a6dc0b153a61b54963ab18e15d4d0ccc2e32481 100644
--- a/core/modules/link/lib/Drupal/link/Tests/LinkFieldTest.php
+++ b/core/modules/link/lib/Drupal/link/Tests/LinkFieldTest.php
@@ -56,14 +56,16 @@ function testURLValidation() {
       'settings' => array(
         'title' => DRUPAL_DISABLED,
       ),
-      'widget' => array(
+    );
+    field_create_instance($this->instance);
+    entity_get_form_display('test_entity', 'test_bundle', 'default')
+      ->setComponent($this->field['field_name'], array(
         'type' => 'link_default',
         'settings' => array(
           'placeholder_url' => 'http://example.com',
         ),
-      ),
-    );
-    field_create_instance($this->instance);
+      ))
+      ->save();
     entity_get_display('test_entity', 'test_bundle', 'full')
       ->setComponent($this->field['field_name'], array(
         'type' => 'link',
@@ -125,15 +127,17 @@ function testLinkTitle() {
       'settings' => array(
         'title' => DRUPAL_OPTIONAL,
       ),
-      'widget' => array(
+    );
+    field_create_instance($this->instance);
+    entity_get_form_display('test_entity', 'test_bundle', 'default')
+      ->setComponent($this->field['field_name'], array(
         'type' => 'link_default',
         'settings' => array(
           'placeholder_url' => 'http://example.com',
           'placeholder_title' => 'Enter a title for this link',
         ),
-      ),
-    );
-    field_create_instance($this->instance);
+      ))
+      ->save();
     entity_get_display('test_entity', 'test_bundle', 'full')
       ->setComponent($this->field['field_name'], array(
         'type' => 'link',
@@ -238,15 +242,17 @@ function testLinkFormatter() {
       'settings' => array(
         'title' => DRUPAL_OPTIONAL,
       ),
-      'widget' => array(
-        'type' => 'link_default',
-      ),
     );
     $display_options = array(
       'type' => 'link',
       'label' => 'hidden',
     );
     field_create_instance($this->instance);
+    entity_get_form_display('test_entity', 'test_bundle', 'default')
+      ->setComponent($this->field['field_name'], array(
+        'type' => 'link_default',
+      ))
+      ->save();
     entity_get_display('test_entity', 'test_bundle', 'full')
       ->setComponent($this->field['field_name'], $display_options)
       ->save();
@@ -376,15 +382,17 @@ function testLinkSeparateFormatter() {
       'settings' => array(
         'title' => DRUPAL_OPTIONAL,
       ),
-      'widget' => array(
-        'type' => 'link_default',
-      ),
     );
     $display_options = array(
       'type' => 'link_separate',
       'label' => 'hidden',
     );
     field_create_instance($this->instance);
+    entity_get_form_display('test_entity', 'test_bundle', 'default')
+      ->setComponent($this->field['field_name'], array(
+        'type' => 'link_default',
+      ))
+      ->save();
     entity_get_display('test_entity', 'test_bundle', 'full')
       ->setComponent($this->field['field_name'], $display_options)
       ->save();
diff --git a/core/modules/link/lib/Drupal/link/Tests/LinkItemTest.php b/core/modules/link/lib/Drupal/link/Tests/LinkItemTest.php
index e59e403320087d03615101d9d59a4fce9b314b4f..eb40cbc0659db225b321d8585e7113bb647ddfa5 100644
--- a/core/modules/link/lib/Drupal/link/Tests/LinkItemTest.php
+++ b/core/modules/link/lib/Drupal/link/Tests/LinkItemTest.php
@@ -44,9 +44,6 @@ public function setUp() {
       'entity_type' => 'entity_test',
       'field_name' => 'field_test',
       'bundle' => 'entity_test',
-      'widget' => array(
-        'type' => 'link_default',
-      ),
     );
     field_create_instance($this->instance);
   }
diff --git a/core/modules/node/lib/Drupal/node/Plugin/views/wizard/Node.php b/core/modules/node/lib/Drupal/node/Plugin/views/wizard/Node.php
index 4f868f73a22d922593d8968291b5e5ba17e983b9..644fbcf5dc2ce5d02e7a37624820272bdaf5f131 100644
--- a/core/modules/node/lib/Drupal/node/Plugin/views/wizard/Node.php
+++ b/core/modules/node/lib/Drupal/node/Plugin/views/wizard/Node.php
@@ -278,9 +278,10 @@ protected function build_filters(&$form, &$form_state) {
     $tag_fields = array();
     foreach ($bundles as $bundle) {
       foreach (field_info_instances($this->entity_type, $bundle) as $instance) {
+        $widget = entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')->getComponent($instance['field_name']);
         // We define "tag-like" taxonomy fields as ones that use the
         // "Autocomplete term widget (tagging)" widget.
-        if ($instance['widget']['type'] == 'taxonomy_autocomplete') {
+        if ($widget['type'] == 'taxonomy_autocomplete') {
           $tag_fields[] = $instance['field_name'];
         }
       }
diff --git a/core/modules/node/lib/Drupal/node/Tests/MultiStepNodeFormBasicOptionsTest.php b/core/modules/node/lib/Drupal/node/Tests/MultiStepNodeFormBasicOptionsTest.php
index 7ee1e8578c601f10f64741903c7fa5d962d70c9b..465a49225f2157e32952429ede9db730c69f1dfa 100644
--- a/core/modules/node/lib/Drupal/node/Tests/MultiStepNodeFormBasicOptionsTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/MultiStepNodeFormBasicOptionsTest.php
@@ -54,16 +54,14 @@ function testMultiStepNodeFormBasicOptions() {
       'settings' => array(
         'text_processing' => TRUE,
       ),
-      'widget' => array(
-        'type' => 'text_textfield',
-      ),
-      'display' => array(
-        'full' => array(
-          'type' => 'text_default',
-        ),
-      ),
     );
     field_create_instance($this->instance);
+    entity_get_form_display('node', 'page', 'default')
+      ->setComponent($this->field_name, array(
+        'type' => 'text_textfield',
+      ))
+      ->save();
+
     $langcode = LANGUAGE_NOT_SPECIFIED;
 
     $edit = array(
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeAccessFieldTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeAccessFieldTest.php
index 452ed93de71d2af469b3e9c6b8962bccfe2b5c05..9c9c52ed68dffe7dcaaf4735e3a7bf56c32ffcd9 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeAccessFieldTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeAccessFieldTest.php
@@ -48,6 +48,9 @@ public function setUp() {
     entity_get_display('node', 'page', 'default')
       ->setComponent($this->field_name)
       ->save();
+    entity_get_form_display('node', 'page', 'default')
+      ->setComponent($this->field_name)
+      ->save();
   }
 
   /**
diff --git a/core/modules/node/lib/Drupal/node/Tests/PagePreviewTest.php b/core/modules/node/lib/Drupal/node/Tests/PagePreviewTest.php
index ed93b253f90ad5a435d5495c75093ec16fee3580..81456a3c7eb804c0d629315ac45578df15f04ffa 100644
--- a/core/modules/node/lib/Drupal/node/Tests/PagePreviewTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/PagePreviewTest.php
@@ -77,22 +77,25 @@ function setUp() {
       'field_name' => $this->field_name,
       'entity_type' => 'node',
       'bundle' => 'page',
-      'widget' => array(
-        'type' => 'taxonomy_autocomplete',
-      ),
-      // Hide on full display but render on teaser.
-      'display' => array(
-        'default' => array(
-          'type' => 'hidden',
-        ),
-        'teaser' => array(
-          'type' => 'taxonomy_term_reference_link',
-        ),
-      ),
     );
     field_create_instance($this->instance);
+
+    entity_get_form_display('node', 'page', 'default')
+      ->setComponent($this->field['field_name'], array(
+        'type' => 'taxonomy_autocomplete',
+      ))
+      ->save();
+
+    // Show on default display and teaser.
     entity_get_display('node', 'page', 'default')
-      ->setComponent($this->field_name)
+      ->setComponent($this->field['field_name'], array(
+        'type' => 'taxonomy_term_reference_link',
+      ))
+      ->save();
+    entity_get_display('node', 'page', 'teaser')
+      ->setComponent($this->field['field_name'], array(
+        'type' => 'taxonomy_term_reference_link',
+      ))
       ->save();
   }
 
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index ae25bb197e0d695c0af048f74de2803b95c5144e..5c934df6aebd8077ec7e77e0572324989222b7fb 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -545,11 +545,17 @@ function node_add_body_field($type, $label = 'Body') {
       'entity_type' => 'node',
       'bundle' => $type->type,
       'label' => $label,
-      'widget' => array('type' => 'text_textarea_with_summary'),
       'settings' => array('display_summary' => TRUE),
     );
     $instance = field_create_instance($instance);
 
+    // Assign widget settings for the 'default' form mode.
+    entity_get_form_display('node', $type->type, 'default')
+      ->setComponent($field['field_name'], array(
+        'type' => 'text_textarea_with_summary',
+      ))
+      ->save();
+
     // Assign display settings for the 'default' and 'teaser' view modes.
     entity_get_display('node', $type->type, 'default')
       ->setComponent($field['field_name'], array(
diff --git a/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php b/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php
index aa6c06e18a50a42a3c6e70f2abe3f4b6f867b269..d0b98ac086d1ef3e97333eb764e6b4b9524d3f46 100644
--- a/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php
+++ b/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php
@@ -57,16 +57,21 @@ function testNumberDecimalField() {
       'field_name' => $this->field['field_name'],
       'entity_type' => 'test_entity',
       'bundle' => 'test_bundle',
-      'widget' => array(
+    );
+    field_create_instance($this->instance);
+
+    entity_get_form_display('test_entity', 'test_bundle', 'default')
+      ->setComponent($this->field['field_name'], array(
         'type' => 'number',
         'settings' => array(
           'placeholder' => '0.00'
         ),
-      ),
-    );
-    field_create_instance($this->instance);
+      ))
+      ->save();
     entity_get_display('test_entity', 'test_bundle', 'default')
-      ->setComponent($this->field['field_name'])
+      ->setComponent($this->field['field_name'], array(
+        'type' => 'number_decimal',
+      ))
       ->save();
 
     // Display creation form.
diff --git a/core/modules/number/lib/Drupal/number/Tests/NumberItemTest.php b/core/modules/number/lib/Drupal/number/Tests/NumberItemTest.php
index a0fc77849fef16ae6add7cc4c7df7279fd9df9c7..fa7e0fa3faaa10b1e86a0ed1e9cbffca6860c2cd 100644
--- a/core/modules/number/lib/Drupal/number/Tests/NumberItemTest.php
+++ b/core/modules/number/lib/Drupal/number/Tests/NumberItemTest.php
@@ -45,9 +45,6 @@ public function setUp() {
         'entity_type' => 'entity_test',
         'field_name' => 'field_' . $type,
         'bundle' => 'entity_test',
-        'widget' => array(
-          'type' => 'number',
-        ),
       );
       field_create_instance($this->instance[$type]);
     }
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 5e0e3bfad36a66b07630908e94d198d72691ee91..6986231e426212968d5a7c8bfa1307bf31029ee9 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
@@ -36,8 +36,8 @@ abstract class OptionsWidgetBase extends WidgetBase {
   /**
    * {@inheritdoc}
    */
-  public function __construct($plugin_id, array $plugin_definition, FieldInstance $instance, array $settings, $weight) {
-    parent::__construct($plugin_id, $plugin_definition, $instance, $settings, $weight);
+  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']);
diff --git a/core/modules/options/lib/Drupal/options/Tests/OptionsDynamicValuesTest.php b/core/modules/options/lib/Drupal/options/Tests/OptionsDynamicValuesTest.php
index 4065b7d03b9718076cab969ab954069147ad54f8..4e97dbec3de63f6f680d351733d0d0f5bdbc5599 100644
--- a/core/modules/options/lib/Drupal/options/Tests/OptionsDynamicValuesTest.php
+++ b/core/modules/options/lib/Drupal/options/Tests/OptionsDynamicValuesTest.php
@@ -40,11 +40,14 @@ function setUp() {
       'entity_type' => 'test_entity',
       'bundle' => 'test_bundle',
       'required' => TRUE,
-      'widget' => array(
-        'type' => 'options_select',
-      ),
     );
     $this->instance = field_create_instance($this->instance);
+    entity_get_form_display('test_entity', 'test_bundle', 'default')
+      ->setComponent($this->field_name, array(
+        'type' => 'options_select',
+      ))
+      ->save();
+
     $this->test = array(
       'id' => mt_rand(1, 10),
       // Make sure this does not equal the ID so that
diff --git a/core/modules/options/lib/Drupal/options/Tests/OptionsFieldTest.php b/core/modules/options/lib/Drupal/options/Tests/OptionsFieldTest.php
index 13d0fbaeaea70b8ad08fff6161751a6ee24ffd20..efd8d5c63c672a0d03818c07de776aff1449d2ad 100644
--- a/core/modules/options/lib/Drupal/options/Tests/OptionsFieldTest.php
+++ b/core/modules/options/lib/Drupal/options/Tests/OptionsFieldTest.php
@@ -86,11 +86,13 @@ function testUpdateAllowedValues() {
       'field_name' => $this->fieldName,
       'entity_type' => 'entity_test',
       'bundle' => 'entity_test',
-      'widget' => array(
-        'type' => 'options_buttons',
-      ),
     );
     field_create_instance($this->instance);
+    entity_get_form_display('entity_test', 'entity_test', 'default')
+      ->setComponent($this->fieldName, array(
+        'type' => 'options_buttons',
+      ))
+      ->save();
     $entity = entity_create('entity_test', array());
     $form = entity_get_form($entity);
     $this->assertTrue(!empty($form[$this->fieldName][$langcode][1]), 'Option 1 exists');
diff --git a/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUITest.php b/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUITest.php
index e2314582032ea6e15c8f669b16f5f19d918c1875..3d54c817503d0b78efb2bf1fb460783c4c3e4345 100644
--- a/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUITest.php
+++ b/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUITest.php
@@ -223,6 +223,10 @@ function testOptionsAllowedValuesBoolean() {
     );
     $this->drupalPost($this->admin_path, $edit, t('Save field settings'));
     $this->assertRaw(t('Updated field %label field settings.', array('%label' => $this->field_name)));
+
+    // Clear field cache.
+    field_info_cache_clear();
+
     // Test the allowed_values on the field settings form.
     $this->drupalGet($this->admin_path);
     $this->assertFieldByName('on', $on, t("The 'On' value is stored correctly."));
@@ -266,6 +270,8 @@ protected function createOptionsField($type) {
     );
     field_create_instance($instance);
 
+    entity_get_form_display('node', $this->type, 'default')->setComponent($this->field_name)->save();
+
     $this->admin_path = 'admin/structure/types/manage/' . $this->type . '/fields/node.' . $this->type . '.' . $this->field_name . '/field';
   }
 
diff --git a/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUnitTestBase.php b/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUnitTestBase.php
index e2d4ad7af5b189277a8cfbb93b0240f32bae0f36..748ee6e4a20ab41baf662bbfb1cca30a305a28da 100644
--- a/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUnitTestBase.php
+++ b/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUnitTestBase.php
@@ -72,12 +72,15 @@ public function setUp() {
       'field_name' => $this->fieldName,
       'entity_type' => 'entity_test',
       'bundle' => 'entity_test',
-      'widget' => array(
-        'type' => 'options_buttons',
-      ),
     );
     $this->instance = entity_create('field_instance', $instance);
     $this->instance->save();
+
+    entity_get_form_display('entity_test', 'entity_test', 'default')
+      ->setComponent($this->fieldName, array(
+        'type' => 'options_buttons',
+      ))
+      ->save();
   }
 
 }
diff --git a/core/modules/options/lib/Drupal/options/Tests/OptionsWidgetsTest.php b/core/modules/options/lib/Drupal/options/Tests/OptionsWidgetsTest.php
index 4dfd302a3401ed21836d7131b3f15dc0ae03a05e..cbb3c7ff7756e5d506e4ac213b1ce0486d906af7 100644
--- a/core/modules/options/lib/Drupal/options/Tests/OptionsWidgetsTest.php
+++ b/core/modules/options/lib/Drupal/options/Tests/OptionsWidgetsTest.php
@@ -81,11 +81,14 @@ function testRadioButtons() {
       'field_name' => $this->card_1['field_name'],
       'entity_type' => 'test_entity',
       'bundle' => 'test_bundle',
-      'widget' => array(
-        'type' => 'options_buttons',
-      ),
     );
     $instance = field_create_instance($instance);
+    entity_get_form_display('test_entity', 'test_bundle', 'default')
+      ->setComponent($this->card_1['field_name'], array(
+        'type' => 'options_buttons',
+      ))
+      ->save();
+
     $langcode = LANGUAGE_NOT_SPECIFIED;
 
     // Create an entity.
@@ -135,11 +138,14 @@ function testCheckBoxes() {
       'field_name' => $this->card_2['field_name'],
       'entity_type' => 'test_entity',
       'bundle' => 'test_bundle',
-      'widget' => array(
-        'type' => 'options_buttons',
-      ),
     );
     $instance = field_create_instance($instance);
+    entity_get_form_display('test_entity', 'test_bundle', 'default')
+      ->setComponent($this->card_2['field_name'], array(
+        'type' => 'options_buttons',
+      ))
+      ->save();
+
     $langcode = LANGUAGE_NOT_SPECIFIED;
 
     // Create an entity.
@@ -223,11 +229,14 @@ function testSelectListSingle() {
       'entity_type' => 'test_entity',
       'bundle' => 'test_bundle',
       'required' => TRUE,
-      'widget' => array(
-        'type' => 'options_select',
-      ),
     );
     $instance = field_create_instance($instance);
+    entity_get_form_display('test_entity', 'test_bundle', 'default')
+      ->setComponent($this->card_1['field_name'], array(
+        'type' => 'options_select',
+      ))
+      ->save();
+
     $langcode = LANGUAGE_NOT_SPECIFIED;
 
     // Create an entity.
@@ -319,11 +328,14 @@ function testSelectListMultiple() {
       'field_name' => $this->card_2['field_name'],
       'entity_type' => 'test_entity',
       'bundle' => 'test_bundle',
-      'widget' => array(
-        'type' => 'options_select',
-      ),
     );
     $instance = field_create_instance($instance);
+    entity_get_form_display('test_entity', 'test_bundle', 'default')
+      ->setComponent($this->card_2['field_name'], array(
+        'type' => 'options_select',
+      ))
+      ->save();
+
     $langcode = LANGUAGE_NOT_SPECIFIED;
 
     // Create an entity.
@@ -436,11 +448,14 @@ function testOnOffCheckbox() {
       'field_name' => $this->bool['field_name'],
       'entity_type' => 'test_entity',
       'bundle' => 'test_bundle',
-      'widget' => array(
-        'type' => 'options_onoff',
-      ),
     );
     $instance = field_create_instance($instance);
+    entity_get_form_display('test_entity', 'test_bundle', 'default')
+      ->setComponent($this->bool['field_name'], array(
+        'type' => 'options_onoff',
+      ))
+      ->save();
+
     $langcode = LANGUAGE_NOT_SPECIFIED;
 
     // Create an entity.
@@ -487,13 +502,15 @@ function testOnOffCheckbox() {
       'field_name' => $this->bool['field_name'],
       'entity_type' => 'node',
       'bundle' => 'page',
-      'widget' => array(
-        'type' => 'options_onoff',
-        'module' => 'options',
-      ),
     );
     field_create_instance($instance);
 
+    entity_get_form_display('node', 'page', 'default')
+      ->setComponent($this->bool['field_name'], array(
+        'type' => 'options_onoff',
+      ))
+      ->save();
+
     // Go to the edit page and check if the default settings works as expected
     $fieldEditUrl = 'admin/structure/types/manage/page/fields/node.page.bool';
     $this->drupalGet($fieldEditUrl);
diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/RdfaMarkupTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/RdfaMarkupTest.php
index 6f99dae9082967331242eba99a3c6b53a001ad56..5d917a4f54885c860caab206bbb785c7aec12232 100644
--- a/core/modules/rdf/lib/Drupal/rdf/Tests/RdfaMarkupTest.php
+++ b/core/modules/rdf/lib/Drupal/rdf/Tests/RdfaMarkupTest.php
@@ -117,6 +117,12 @@ function testAttributesInMarkupFile() {
       'bundle' => $bundle_name,
     );
     field_create_instance($instance);
+
+    entity_get_form_display('node', $bundle_name, 'default')
+      ->setComponent($field_name, array(
+        'type' => 'file_generic',
+      ))
+      ->save();
     entity_get_display('node', $bundle_name, 'teaser')
       ->setComponent($field_name, array(
         'type' => 'file_default',
diff --git a/core/modules/simpletest/lib/Drupal/simpletest/Tests/DrupalUnitTestBaseTest.php b/core/modules/simpletest/lib/Drupal/simpletest/Tests/DrupalUnitTestBaseTest.php
index 2379193eaef8876e6dee4b33391aa9a65daa9eea..242bcd6089a5345cd46875b96099e93d8549dc23 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/Tests/DrupalUnitTestBaseTest.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/Tests/DrupalUnitTestBaseTest.php
@@ -229,7 +229,7 @@ function testEnableModulesFixedList() {
     $display = entity_create('entity_display', array(
       'targetEntityType' => 'entity_test',
       'bundle' => 'entity_test',
-      'viewMode' => 'default',
+      'mode' => 'default',
     ));
     $field = array(
       'field_name' => 'test_field',
diff --git a/core/modules/system/lib/Drupal/system/Tests/Ajax/MultiFormTest.php b/core/modules/system/lib/Drupal/system/Tests/Ajax/MultiFormTest.php
index c9e7b6dd962719c1bc7bc5d433571f8c21bbc985..d3ba0b71b4b7ebb58df02de365aa252e8a3aa0f9 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Ajax/MultiFormTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Ajax/MultiFormTest.php
@@ -46,6 +46,9 @@ function setUp() {
       'bundle' => 'page',
     );
     field_create_instance($instance);
+    entity_get_form_display('node', 'page', 'default')
+      ->setComponent($field_name, array('type' => 'text_default'))
+      ->save();
 
     // Login a user who can create 'page' nodes.
     $this->web_user = $this->drupalCreateUser(array('create page content'));
diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFormTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFormTest.php
index fbbd131c113de5da6c99b83bbb1e284a1a4070b6..78ce17d7cf2b1bccc505f645e7179ed191b6c010 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFormTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFormTest.php
@@ -45,6 +45,17 @@ function testFormCRUD() {
     }
   }
 
+  /**
+   * Tests hook_entity_form_display_alter().
+   *
+   * @see entity_test_entity_form_display_alter()
+   */
+  function testEntityFormDisplayAlter() {
+    $this->drupalGet('entity_test/add');
+    $altered_field = $this->xpath('//input[@name="field_test_text[und][0][value]" and @size="42"]');
+    $this->assertTrue(count($altered_field) === 1, 'The altered field has the correct size value.');
+  }
+
   /**
    * Executes the form CRUD tests for the given entity type.
    *
diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUnitTestBase.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUnitTestBase.php
index 41918d3b27109eda38941306555b2299c363a730..4da3b21bf9df2997f409b9b6b3b6c794f3a20dc4 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUnitTestBase.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUnitTestBase.php
@@ -19,7 +19,7 @@ abstract class EntityUnitTestBase extends DrupalUnitTestBase {
    *
    * @var array
    */
-  public static $modules = array('user', 'system', 'field', 'text', 'field_sql_storage', 'entity_test');
+  public static $modules = array('entity', 'user', 'system', 'field', 'text', 'field_sql_storage', 'entity_test');
 
   public function setUp() {
     parent::setUp();
diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/FieldAccessTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/FieldAccessTest.php
index a460b6f70482722f3e1fbd52ad3a9a4252b6ff98..b00bfeaa7f2a49ed0b0dba35bde2261636c13ef1 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Entity/FieldAccessTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Entity/FieldAccessTest.php
@@ -19,7 +19,7 @@ class FieldAccessTest extends DrupalUnitTestBase {
    *
    * @var array
    */
-  public static $modules = array('entity_test', 'field', 'field_sql_storage', 'system', 'text', 'user');
+  public static $modules = array('entity', 'entity_test', 'field', 'field_sql_storage', 'system', 'text', 'user');
 
   /**
    * Holds the currently active global user ID that initiated the test run.
diff --git a/core/modules/system/lib/Drupal/system/Tests/Form/ArbitraryRebuildTest.php b/core/modules/system/lib/Drupal/system/Tests/Form/ArbitraryRebuildTest.php
index 1604063bfe13e8dde14989243d604c17fa6fd264..f049ac88b1eddf51c7c42c2ee2cf21cc126b52c9 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Form/ArbitraryRebuildTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Form/ArbitraryRebuildTest.php
@@ -42,16 +42,21 @@ function setUp() {
     field_create_field($field);
 
     $instance = array(
-      'entity_type' => 'node',
+      'entity_type' => 'user',
       'field_name' => 'test_multiple',
-      'bundle' => 'page',
+      'bundle' => 'user',
       'label' => 'Test a multiple valued field',
-      'widget' => array(
-        'type' => 'text_textfield',
-        'weight' => 0,
+      'settings' => array(
+        'user_register_form' => TRUE,
       ),
     );
     field_create_instance($instance);
+    entity_get_form_display('user', 'user', 'default')
+      ->setComponent('test_multiple', array(
+        'type' => 'text_textfield',
+        'weight' => 0,
+      ))
+      ->save();
   }
 
   /**
diff --git a/core/modules/system/lib/Drupal/system/Tests/Form/RebuildTest.php b/core/modules/system/lib/Drupal/system/Tests/Form/RebuildTest.php
index 3c0c0c55b0c62d651e7ffc3fef87dcac8dd15927..8e9f6495a7f9c7091d1a519ed85c5ee71436ec1f 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Form/RebuildTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Form/RebuildTest.php
@@ -83,6 +83,9 @@ function testPreserveFormActionAfterAJAX() {
       'bundle' => 'page',
     );
     field_create_instance($instance);
+    entity_get_form_display('node', 'page', 'default')
+      ->setComponent($field_name, array('type' => 'text_test'))
+      ->save();
 
     // Log in a user who can create 'page' nodes.
     $this->web_user = $this->drupalCreateUser(array('create page content'));
diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php
index 0936aa5c7a57e53cb737e02b941e9ee8ab689eff..621f1144d1f353ae420c8e560f2e09f3fecb6ebd 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php
@@ -87,6 +87,45 @@ public function testEntityDisplayUpgrade() {
     $this->assertEqual($displays['teaser']['content']['language'], $expected['teaser']);
   }
 
+  /**
+   * Tests upgrade of entity form displays.
+   */
+  public function testEntityFormDisplayUpgrade() {
+    $this->assertTrue($this->performUpgrade(), 'The upgrade was completed successfully.');
+
+    // Check that the configuration entries were created.
+    $form_display = config('entity.form_display.node.article.default')->get();
+    $this->assertTrue(!empty($form_display));
+
+    // Check that manifest entries for the 'article' node type were correctly
+    // created.
+    $manifest = config('manifest.entity.form_display');
+    $data = $manifest->get();
+    $this->assertEqual($data['node.article.default'], array('name' => 'entity.form_display.node.article.default'));
+
+    // Check that the 'body' field is configured as expected.
+    $expected = array(
+      'type' => 'text_textarea_with_summary',
+      'weight' => -4,
+      'settings' => array(
+        'rows' => '20',
+        'summary_rows' => '5',
+      ),
+    );
+    $this->assertEqual($form_display['content']['body'], $expected);
+
+    // Check that the display key in the instance data was removed.
+    $body_instance = field_info_instance('node', 'body', 'article');
+    $this->assertTrue(!isset($body_instance['widget']));
+
+    // Check that the 'title' extra field is configured as expected.
+    $expected = array(
+      'weight' => -5,
+      'visible' => 1,
+    );
+    $this->assertEqual($form_display['content']['title'], $expected);
+  }
+
   /**
    * Tests migration of field and instance definitions to config.
    */
@@ -150,15 +189,6 @@ function testFieldUpgradeToConfig() {
           'text_processing' => 1,
           'user_register_form' => FALSE,
         ),
-        'widget' => array(
-          'type' => 'text_textarea_with_summary',
-          'module' => 'text',
-          'settings' => array(
-            'rows' => 20,
-            'summary_rows' => 5,
-          ),
-          'weight' => -4,
-        ),
         'status' => 1,
         'langcode' => 'und',
       ));
diff --git a/core/modules/system/tests/modules/entity_test/entity_test.install b/core/modules/system/tests/modules/entity_test/entity_test.install
index 3465e8c756536d67b1aae95c7619c59214c29151..f7b8726de2316cb07cefcc0c5ebb0a8ee2494fdf 100644
--- a/core/modules/system/tests/modules/entity_test/entity_test.install
+++ b/core/modules/system/tests/modules/entity_test/entity_test.install
@@ -30,12 +30,12 @@ function entity_test_install() {
       'field_name' => 'field_test_text',
       'bundle' => $entity_type,
       'label' => 'Test text-field',
-      'widget' => array(
-        'type' => 'text_textfield',
-        'weight' => 0,
-      ),
     );
     field_create_instance($instance);
+
+    entity_get_form_display($entity_type, $entity_type, 'default')
+      ->setComponent('field_test_text', array('type' => 'text_text'))
+      ->save();
   }
 }
 
diff --git a/core/modules/system/tests/modules/entity_test/entity_test.module b/core/modules/system/tests/modules/entity_test/entity_test.module
index 07707382adb02acde827bdf571712807eef61b26..e8c1d9b97027355a49d6233d156abbb389134326 100644
--- a/core/modules/system/tests/modules/entity_test/entity_test.module
+++ b/core/modules/system/tests/modules/entity_test/entity_test.module
@@ -6,6 +6,7 @@
  */
 
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\entity\Plugin\Core\Entity\EntityFormDisplay;
 
 /**
  * Filter that limits test entity list to revisable ones.
@@ -365,3 +366,16 @@ function entity_test_entity_field_access_alter(array &$grants, array $context) {
     $grants[':default'] = FALSE;
   }
 }
+
+/**
+ * Implements hook_entity_form_display_alter().
+ */
+function entity_test_entity_form_display_alter(EntityFormDisplay $form_display, $context) {
+  // Make the field_test_text field 42 characters for entity_test_mul.
+  if ($context['entity_type'] == 'entity_test') {
+    if ($component_options = $form_display->getComponent('field_test_text')) {
+      $component_options['settings']['size'] = 42;
+      $form_display->setComponent('field_test_text', $component_options);
+    }
+  }
+}
diff --git a/core/modules/system/tests/upgrade/drupal-7.field.database.php b/core/modules/system/tests/upgrade/drupal-7.field.database.php
index 48950aac6387e87f4f003ddbb91f6237c98bbefe..74f69fbaaf6cb1246f56b8de921c5d8a3cb0c0b8 100644
--- a/core/modules/system/tests/upgrade/drupal-7.field.database.php
+++ b/core/modules/system/tests/upgrade/drupal-7.field.database.php
@@ -28,7 +28,12 @@
     ),
   ),
   'extra_fields' => array(
-    'form' => array(),
+    'form' => array(
+      'title' => array(
+        'weight' => -5,
+        'visible' => 1,
+      ),
+    ),
     'display' => array(
       'language' => array(
         'default' => array(
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php
index ca775e9b31acabae23a58682ffea685a8daff236..d4be486705747307f488349d4673a6da5f1ac5f4 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php
@@ -53,11 +53,13 @@ function setUp() {
       'field_name' => 'taxonomy_' . $this->vocabulary->id(),
       'bundle' => 'article',
       'entity_type' => 'node',
-      'widget' => array(
-        'type' => 'options_select',
-      ),
     );
     field_create_instance($this->instance);
+    entity_get_form_display('node', 'article', 'default')
+      ->setComponent($field['field_name'], array(
+        'type' => 'options_select',
+      ))
+      ->save();
     entity_get_display('node', 'article', 'default')
       ->setComponent('taxonomy_' . $this->vocabulary->id(), array(
         'type' => 'taxonomy_term_reference_link',
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TaxonomyTermReferenceItemTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TaxonomyTermReferenceItemTest.php
index abb5893e830afab7b30bf326a4eda894a958a3f7..77b9b1c7229745bcfe518dfb3b485612f991cecb 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TaxonomyTermReferenceItemTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TaxonomyTermReferenceItemTest.php
@@ -60,9 +60,6 @@ public function setUp() {
       'entity_type' => 'entity_test',
       'field_name' => 'field_test_taxonomy',
       'bundle' => 'entity_test',
-      'widget' => array(
-        'type' => 'options_select',
-      ),
     );
     field_create_instance($instance);
     $this->term = entity_create('taxonomy_term', array(
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php
index f84f02af48a99c95bdd06adce2aac540983c9d90..627f7625a5e8e0c737ae49d989125d786893a4dd 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php
@@ -63,11 +63,13 @@ function setUp() {
       'field_name' => $this->field_name,
       'entity_type' => 'test_entity',
       'bundle' => 'test_bundle',
-      'widget' => array(
-        'type' => 'options_select',
-      ),
     );
     field_create_instance($this->instance);
+    entity_get_form_display('test_entity', 'test_bundle', 'default')
+      ->setComponent($this->field_name, array(
+        'type' => 'options_select',
+      ))
+      ->save();
     entity_get_display('test_entity', 'test_bundle', 'full')
       ->setComponent($this->field_name, array(
         'type' => 'taxonomy_term_reference_link',
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php
index 83051fa8a57109e460244f2b9c0860b12538c904..27184d8ab7647d5e20c8871161ffd05a38f3dbd7 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php
@@ -58,11 +58,13 @@ function setUp() {
       'field_name' => $this->field_name,
       'entity_type' => 'test_entity',
       'bundle' => 'test_bundle',
-      'widget' => array(
-        'type' => 'options_select',
-      ),
     );
     field_create_instance($this->instance);
+    entity_get_form_display('test_entity', 'test_bundle', 'default')
+      ->setComponent($this->field_name, array(
+        'type' => 'options_select',
+      ))
+      ->save();
     entity_get_display('test_entity', 'test_bundle', 'full')
       ->setComponent($this->field_name, array(
         'type' => 'taxonomy_term_reference_link',
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php
index 022a1fabc427dfef578184708264fd85fe3e27bb..4c2202c1561f5ad6dab4dcd8223ed30cbdc812be 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php
@@ -49,11 +49,13 @@ function setUp() {
       'field_name' => $this->field_name_1,
       'bundle' => 'article',
       'entity_type' => 'node',
-      'widget' => array(
-        'type' => 'options_select',
-      ),
     );
     field_create_instance($this->instance_1);
+    entity_get_form_display('node', 'article', 'default')
+      ->setComponent($this->field_name_1, array(
+        'type' => 'options_select',
+      ))
+      ->save();
     entity_get_display('node', 'article', 'default')
       ->setComponent($this->field_name_1, array(
         'type' => 'taxonomy_term_reference_link',
@@ -79,11 +81,13 @@ function setUp() {
       'field_name' => $this->field_name_2,
       'bundle' => 'article',
       'entity_type' => 'node',
-      'widget' => array(
-        'type' => 'options_select',
-      ),
     );
     field_create_instance($this->instance_2);
+    entity_get_form_display('node', 'article', 'default')
+      ->setComponent($this->field_name_2, array(
+        'type' => 'options_select',
+      ))
+      ->save();
     entity_get_display('node', 'article', 'default')
       ->setComponent($this->field_name_2, array(
         'type' => 'taxonomy_term_reference_link',
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
index b9b110875a21d29c5690bf1a7878bbd1934d9115..f9fb10b65a6d69900521e01a408f878e941e28f2 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
@@ -45,11 +45,13 @@ function setUp() {
       'field_name' => 'taxonomy_' . $this->vocabulary->id(),
       'bundle' => 'article',
       'entity_type' => 'node',
-      'widget' => array(
-        'type' => 'options_select',
-      ),
     );
     field_create_instance($this->instance);
+    entity_get_form_display('node', 'article', 'default')
+      ->setComponent('taxonomy_' . $this->vocabulary->id(), array(
+        'type' => 'options_select',
+      ))
+      ->save();
     entity_get_display('node', 'article', 'default')
       ->setComponent($this->instance['field_name'], array(
         'type' => 'taxonomy_term_reference_link',
@@ -142,13 +144,14 @@ function testTaxonomyNode() {
   function testNodeTermCreationAndDeletion() {
     // Enable tags in the vocabulary.
     $instance = $this->instance;
-    $instance['widget'] = array(
-      'type' => 'taxonomy_autocomplete',
-      'settings' => array(
-        'placeholder' => 'Start typing here.',
-      ),
-    );
-    field_update_instance($instance);
+    entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')
+      ->setComponent($instance['field_name'], array(
+        'type' => 'taxonomy_autocomplete',
+        'settings' => array(
+          'placeholder' => 'Start typing here.',
+        ),
+      ))
+      ->save();
     $terms = array(
       'term1' => $this->randomName(),
       'term2' => $this->randomName(),
@@ -506,8 +509,11 @@ function testTaxonomyGetTermByName() {
   function testReSavingTags() {
     // Enable tags in the vocabulary.
     $instance = $this->instance;
-    $instance['widget'] = array('type' => 'taxonomy_autocomplete');
-    field_update_instance($instance);
+    entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')
+      ->setComponent($instance['field_name'], array(
+        'type' => 'taxonomy_autocomplete',
+      ))
+      ->save();
 
     // Create a term and a node using it.
     $term = $this->createTerm($this->vocabulary);
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php
index 0a45dd269deb8e4eedaff29567343394f6c69e4f..2d3657e9465b92c22383d90f8b3ef907a4d7a2fe 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php
@@ -46,11 +46,13 @@ function setUp() {
       'field_name' => 'taxonomy_' . $this->vocabulary->id(),
       'bundle' => 'article',
       'entity_type' => 'node',
-      'widget' => array(
-        'type' => 'options_select',
-      ),
     );
     field_create_instance($this->instance);
+    entity_get_form_display('node', 'article', 'default')
+      ->setComponent('taxonomy_' . $this->vocabulary->id(), array(
+        'type' => 'options_select',
+      ))
+      ->save();
     entity_get_display('node', 'article', 'default')
       ->setComponent('taxonomy_' . $this->vocabulary->id(), array(
         'type' => 'taxonomy_term_reference_link',
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/Views/TaxonomyTestBase.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/Views/TaxonomyTestBase.php
index 6de1b17169a7ab191046f1e8ec6e4fae4e780261..e71cf9738a761c18ce0bb43d5925ed4470e68027 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/Views/TaxonomyTestBase.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/Views/TaxonomyTestBase.php
@@ -100,13 +100,16 @@ protected function mockStandardInstall() {
       'entity_type' => 'node',
       'label' => 'Tags',
       'bundle' => 'article',
-      'widget' => array(
-        'type' => 'taxonomy_autocomplete',
-        'weight' => -4,
-      ),
     );
     field_create_instance($instance);
 
+    entity_get_form_display('node', 'article', 'default')
+      ->setComponent($instance['field_name'], array(
+        'type' => 'taxonomy_autocomplete',
+        'weight' => -4,
+      ))
+      ->save();
+
     entity_get_display('node', 'article', 'default')
       ->setComponent($instance['field_name'], array(
         'type' => 'taxonomy_term_reference_link',
diff --git a/core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneFieldTest.php b/core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneFieldTest.php
index 1bec98fc6ef8ff5f0c8c7ad5cdcb23e5713619fc..0d5aa473900bfc398ed9b4772bfd0b77de352f79 100644
--- a/core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneFieldTest.php
+++ b/core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneFieldTest.php
@@ -64,14 +64,17 @@ function testTelephoneField() {
       'label' => 'Telephone Number',
       'entity_type' => 'node',
       'bundle' => 'article',
-      'widget' => array(
+    );
+    field_create_instance($instance);
+
+    entity_get_form_display('node', 'article', 'default')
+      ->setComponent('field_telephone', array(
         'type' => 'telephone_default',
         'settings' => array(
           'placeholder' => '123-456-7890',
         ),
-      ),
-    );
-    field_create_instance($instance);
+      ))
+      ->save();
 
     entity_get_display('node', 'article', 'default')
       ->setComponent('field_telephone', array(
diff --git a/core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneItemTest.php b/core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneItemTest.php
index 35012b3fb2e7ff2ee0abe1c38ddce8446ddde9c3..d809161d8e3cbaa3c02b941dfb08d689286deab4 100644
--- a/core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneItemTest.php
+++ b/core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneItemTest.php
@@ -44,9 +44,6 @@ public function setUp() {
       'entity_type' => 'entity_test',
       'field_name' => 'field_test',
       'bundle' => 'entity_test',
-      'widget' => array(
-        'type' => 'telephone_default',
-      ),
     );
     field_create_instance($this->instance);
   }
diff --git a/core/modules/text/lib/Drupal/text/Tests/Formatter/TextPlainUnitTest.php b/core/modules/text/lib/Drupal/text/Tests/Formatter/TextPlainUnitTest.php
index 9530fd8d0e1730c6876bc8121e9dfa6909f4d895..052cfe35916e2f4a8c34ced044154512ecd4ba84 100644
--- a/core/modules/text/lib/Drupal/text/Tests/Formatter/TextPlainUnitTest.php
+++ b/core/modules/text/lib/Drupal/text/Tests/Formatter/TextPlainUnitTest.php
@@ -62,9 +62,6 @@ function setUp() {
       'text_processing' => FALSE,
     );
 
-    $this->widget_type = 'text_textarea';
-    $this->widget_settings = array();
-
     $this->formatter_type = 'text_plain';
     $this->formatter_settings = array();
 
@@ -81,10 +78,6 @@ function setUp() {
       'field_name' => $this->field_name,
       'label' => $this->randomName(),
       'settings' => $this->instance_settings,
-      'widget' => array(
-        'type' => $this->widget_type,
-        'settings' => $this->widget_settings,
-      ),
     );
     $this->instance = field_create_instance($this->instance);
 
diff --git a/core/modules/text/lib/Drupal/text/Tests/TextFieldTest.php b/core/modules/text/lib/Drupal/text/Tests/TextFieldTest.php
index f8c585b86b889d63229a0ba8ba24ade6b958b325..e12553f4e3ed4c71cf084c4f90b0ff022a3cd604 100644
--- a/core/modules/text/lib/Drupal/text/Tests/TextFieldTest.php
+++ b/core/modules/text/lib/Drupal/text/Tests/TextFieldTest.php
@@ -62,14 +62,8 @@ function testTextFieldValidation() {
       'field_name' => $this->field['field_name'],
       'entity_type' => 'test_entity',
       'bundle' => 'test_bundle',
-      'widget' => array(
-        'type' => 'text_textfield',
-      ),
     );
     field_create_instance($this->instance);
-    entity_get_display('test_entity', 'test_bundle', 'default')
-      ->setComponent($this->field['field_name'])
-      ->save();
 
     // Test valid and invalid values with field_attach_validate().
     $entity = field_test_create_entity();
@@ -111,14 +105,16 @@ function _testTextfieldWidgets($field_type, $widget_type) {
       'settings' => array(
         'text_processing' => TRUE,
       ),
-      'widget' => array(
+    );
+    field_create_instance($this->instance);
+    entity_get_form_display('test_entity', 'test_bundle', 'default')
+      ->setComponent($this->field_name, array(
         'type' => $widget_type,
         'settings' => array(
           'placeholder' => 'A placeholder on ' . $widget_type,
         ),
-      ),
-    );
-    field_create_instance($this->instance);
+      ))
+      ->save();
     entity_get_display('test_entity', 'test_bundle', 'full')
       ->setComponent($this->field_name)
       ->save();
@@ -174,11 +170,13 @@ function _testTextfieldWidgetsFormatted($field_type, $widget_type) {
       'settings' => array(
         'text_processing' => TRUE,
       ),
-      'widget' => array(
-        'type' => $widget_type,
-      ),
     );
     field_create_instance($this->instance);
+    entity_get_form_display('test_entity', 'test_bundle', 'default')
+      ->setComponent($this->field_name, array(
+        'type' => $widget_type,
+      ))
+      ->save();
     entity_get_display('test_entity', 'test_bundle', 'full')
       ->setComponent($this->field_name)
       ->save();
diff --git a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationSyncImageTest.php b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationSyncImageTest.php
index 61f93cf809e67f73db7a7ed9fa6abac5a83442c1..aa9c626d50d4abc4e40cb120fe42fd88cae2c13a 100644
--- a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationSyncImageTest.php
+++ b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationSyncImageTest.php
@@ -69,10 +69,6 @@ protected function setupTestFields() {
       'field_name' => $this->fieldName,
       'bundle' => $this->entityType,
       'label' => 'Test translatable image field',
-      'widget' => array(
-        'type' => 'image_image',
-        'weight' => 0,
-      ),
       'settings' => array(
         'translation_sync' => array(
           'file' => FALSE,
diff --git a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationTestBase.php b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationTestBase.php
index 13e1f59d104bbaf3343faa15fa6fd98dd14d9fc0..870321fc753c19615ac3b45bc61d2d764108a407 100644
--- a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationTestBase.php
+++ b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationTestBase.php
@@ -170,12 +170,14 @@ protected function setupTestFields() {
       'field_name' => $this->fieldName,
       'bundle' => $this->bundle,
       'label' => 'Test translatable text-field',
-      'widget' => array(
-        'type' => 'text_textfield',
-        'weight' => 0,
-      ),
     );
     field_create_instance($instance);
+    entity_get_form_display($this->entityType, $this->bundle, 'default')
+      ->setComponent($this->fieldName, array(
+        'type' => 'text_textfield',
+        'weight' => 0,
+      ))
+      ->save();
   }
 
   /**
diff --git a/core/modules/user/lib/Drupal/user/Tests/UserRegistrationTest.php b/core/modules/user/lib/Drupal/user/Tests/UserRegistrationTest.php
index 38ca376339d1e2950457557900be0820ddc4fe84..db649b0ac6185c2d38777021e74fbb1f32ed51f0 100644
--- a/core/modules/user/lib/Drupal/user/Tests/UserRegistrationTest.php
+++ b/core/modules/user/lib/Drupal/user/Tests/UserRegistrationTest.php
@@ -209,6 +209,9 @@ function testRegistrationWithUserFields() {
       'settings' => array('user_register_form' => FALSE),
     );
     field_create_instance($instance);
+    entity_get_form_display('user', 'user', 'default')
+      ->setComponent('test_user_field', array('type' => 'test_field_widget'))
+      ->save();
 
     // Check that the field does not appear on the registration form.
     $this->drupalGet('user/register');
diff --git a/core/modules/user/user.install b/core/modules/user/user.install
index dca417c3ccdf9cf947cb212fc35fe4d6d273eab9..4f2295869fe7b041c2e7aa0fd7cba097f35d70ad 100644
--- a/core/modules/user/user.install
+++ b/core/modules/user/user.install
@@ -335,17 +335,20 @@ function user_install_picture_field() {
       'min_resolution' => '',
       'default_image' => 0,
     ),
-    'widget' => array(
-      'module' => 'image',
+  );
+  field_create_instance($instance);
+
+  // Assign form display settings for the 'default' view mode.
+  entity_get_form_display('user', 'user', 'default')
+    ->setComponent('user_picture', array(
       'type' => 'image_image',
       'settings' => array(
         'progress_indicator' => 'throbber',
         'preview_image_style' => 'thumbnail',
       ),
       'weight' => -1,
-    ),
-  );
-  field_create_instance($instance);
+    ))
+    ->save();
 
   // Assign display settings for the 'default' and 'compact' view modes.
   entity_get_display('user', 'user', 'default')
@@ -731,29 +734,32 @@ function user_update_8011() {
       'min_resolution' => '',
       'default_image' => !empty($default_image_fid) ? $default_image_fid : 0,
     ),
-    'widget' => array(
-      'module' => 'image',
-      'type' => 'image_image',
+  );
+  _update_7000_field_create_instance($field, $instance);
+
+  module_load_install('entity');
+  if (update_variable_get('user_pictures', 0)) {
+    $formatter = 'image';
+    $widget = 'image_image';
+  }
+  else {
+    $formatter = $widget = 'hidden';
+  }
+
+  // Assign form settings for the 'default' form mode.
+  $form_display = _update_8000_entity_get_form_display('user', 'user', 'default');
+  $form_display->set('content.user_picture', array(
+      'type' => $widget,
       'settings' => array(
         'progress_indicator' => 'throbber',
         'preview_image_style' => 'thumbnail',
       ),
       'weight' => -1,
-    ),
-  );
-  _update_7000_field_create_instance($field, $instance);
-
-  // Assign display settings for the 'default' and 'compact' view modes. In D7,
-  // user pictures did not require Image module to work. Image module only
-  // allowed usage of an image style to format user pictures in the output.
-  // The 'user_pictures' variable had a global effect on the presence of the
-  // user picture functionality before. The new user picture image field is
-  // created regardless of that global setting, which means the field appears
-  // on the user account form after migration, even if user pictures were
-  // disabled previously. The picture is only hidden in the output.
-  $formatter = update_variable_get('user_pictures', 0) ? 'image' : 'hidden';
-  module_load_install('entity');
+    ))
+    ->save();
+  update_config_manifest_add('entity.form_display', array($form_display->get('id')));
 
+  // Assign display settings for the 'default' and 'compact' view modes.
   $display = _update_8000_entity_get_display('user', 'user', 'default');
   $display->set('content.user_picture', array(
       'label' => 'hidden',
diff --git a/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php b/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php
index c6e44fe74c35e1e8e21a2ec4f1bcaebf274588e4..d6d72260b29e65422ba747c418eb0ac11067f54e 100644
--- a/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php
@@ -77,16 +77,8 @@ protected function setUp() {
       'field_name' => $this->field_name,
       'entity_type' => 'node',
       'bundle' => 'page',
-      'widget' => array(
-        'type' => 'options_select',
-      ),
     );
     field_create_instance($this->instance);
-    entity_get_display('node', 'page', 'full')
-      ->setComponent($this->field_name, array(
-        'type' => 'taxonomy_term_reference_link',
-      ))
-      ->save();
 
     // Create a time in the past for the archive.
     $time = time() - 3600;
diff --git a/core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php b/core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php
index 7c150dc0d432ed30a93280366b7f0aeb736eb196..f1a06a374bcb56bf37dde2fd6e824c232032cf03 100644
--- a/core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php
@@ -74,12 +74,15 @@ function setUp() {
       'field_name' => 'field_views_testing_tags',
       'entity_type' => 'node',
       'bundle' => $this->node_type_with_tags->type,
-      'widget' => array(
-        'type' => 'taxonomy_autocomplete',
-      ),
     );
     field_create_instance($this->tag_instance);
 
+    entity_get_form_display('node', $this->node_type_with_tags->type, 'default')
+      ->setComponent('field_views_testing_tags', array(
+        'type' => 'taxonomy_autocomplete',
+      ))
+      ->save();
+
     entity_get_display('node', $this->node_type_with_tags->type, 'default')
       ->setComponent('field_views_testing_tags', array(
         'type' => 'taxonomy_term_reference_link',
@@ -185,6 +188,12 @@ function testTaggedWithByNodeType() {
     $instance = $this->tag_instance;
     $instance['bundle'] = $this->node_type_without_tags->type;
     field_create_instance($instance);
+    entity_get_form_display('node', $this->node_type_without_tags->type, 'default')
+      ->setComponent('field_views_testing_tags', array(
+        'type' => 'taxonomy_autocomplete',
+      ))
+      ->save();
+
     $view['show[type]'] = $this->node_type_with_tags->type;
     $this->drupalPost('admin/structure/views/add', $view, t('Update "of type" choice'));
     $this->assertFieldByXpath($tags_xpath);
diff --git a/core/profiles/standard/config/entity.display.node.article.default.yml b/core/profiles/standard/config/entity.display.node.article.default.yml
index 7cd3ae0cad6937d9c17dbfe6007609c01fcb3518..330de2d84e2fab0e2dd4ffe4db8c342a617691e3 100644
--- a/core/profiles/standard/config/entity.display.node.article.default.yml
+++ b/core/profiles/standard/config/entity.display.node.article.default.yml
@@ -1,7 +1,7 @@
 id: node.article.default
 targetEntityType: node
 bundle: article
-viewMode: default
+mode: default
 content:
   body:
     label: hidden
diff --git a/core/profiles/standard/config/entity.display.node.article.teaser.yml b/core/profiles/standard/config/entity.display.node.article.teaser.yml
index ae65eb4ddab459eafcdff298f5294100a13f1f34..44add7e5862c610d9e905eee494baca5dad60bb6 100644
--- a/core/profiles/standard/config/entity.display.node.article.teaser.yml
+++ b/core/profiles/standard/config/entity.display.node.article.teaser.yml
@@ -1,7 +1,7 @@
 id: node.article.teaser
 targetEntityType: node
 bundle: article
-viewMode: teaser
+mode: teaser
 content:
   body:
     label: hidden
diff --git a/core/profiles/standard/config/entity.form_display.node.article.default.yml b/core/profiles/standard/config/entity.form_display.node.article.default.yml
new file mode 100644
index 0000000000000000000000000000000000000000..dcd242e9bb5a8406607aeedb22ae6db7dd2ede23
--- /dev/null
+++ b/core/profiles/standard/config/entity.form_display.node.article.default.yml
@@ -0,0 +1,25 @@
+id: node.article.default
+targetEntityType: node
+bundle: article
+mode: default
+content:
+  body:
+    type: text_textarea_with_summary
+    weight: '0'
+    settings:
+      rows: '9'
+      summary_rows: '3'
+      placeholder: ''
+  field_tags:
+    type: taxonomy_autocomplete
+    weight: '-4'
+    settings:
+      size: '60'
+      autocomplete_path: taxonomy/autocomplete
+      placeholder: ''
+  field_image:
+    type: image_image
+    settings:
+      progress_indicator: throbber
+      preview_image_style: thumbnail
+    weight: '-1'
diff --git a/core/profiles/standard/config/field.instance.node.article.field_image.yml b/core/profiles/standard/config/field.instance.node.article.field_image.yml
index 3412036692cc90b6e3d0023d54d221533be87ad6..98bd0e34fabefc59d08bb5d07f279b9747c9c3c6 100644
--- a/core/profiles/standard/config/field.instance.node.article.field_image.yml
+++ b/core/profiles/standard/config/field.instance.node.article.field_image.yml
@@ -19,12 +19,5 @@ settings:
   title_field_required: 0
   default_image: 0
   user_register_form: false
-widget:
-  type: image_image
-  settings:
-    progress_indicator: throbber
-    preview_image_style: thumbnail
-  weight: -1
-  module: image
 status: 1
 langcode: und
diff --git a/core/profiles/standard/config/field.instance.node.article.field_tags.yml b/core/profiles/standard/config/field.instance.node.article.field_tags.yml
index bbca2986e0dc9ebf5770d7f25d720068157e6b9d..bb51b394ef14b1287025ea93f10e5c7909bd223e 100644
--- a/core/profiles/standard/config/field.instance.node.article.field_tags.yml
+++ b/core/profiles/standard/config/field.instance.node.article.field_tags.yml
@@ -9,13 +9,5 @@ default_value: {  }
 default_value_function: ''
 settings:
   user_register_form: false
-widget:
-  type: taxonomy_autocomplete
-  weight: -4
-  settings:
-    size: '60'
-    autocomplete_path: taxonomy/autocomplete
-    placeholder: ''
-  module: taxonomy
 status: 1
 langcode: und