diff --git a/core/includes/entity.api.php b/core/includes/entity.api.php
index c12e4db..4d634ed 100644
--- a/core/includes/entity.api.php
+++ b/core/includes/entity.api.php
@@ -279,6 +279,28 @@ function hook_entity_view_mode_alter(&$view_mode, Drupal\Core\Entity\EntityInter
 }
 
 /**
+ * Alters the settings used for displaying an entity.
+ *
+ * @param \Drupal\field\Plugin\Core\Entity\EntityDisplay $display
+ *   The entity_display object that will be used to display the entity 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'.
+ *   - view_mode: The view mode, e.g. 'full', 'teaser'...
+ */
+function hook_entity_display_alter(Drupal\field\Plugin\Core\Entity\EntityDisplay $display, array $context) {
+  // Leave field labels out of the search index.
+  if ($context['entity_type'] == 'node' && $context['view_mode'] == 'search_index') {
+    foreach ($display->content as $name => &$properties) {
+      if (isset($properties['label'])) {
+        $properties['label'] = 'hidden';
+      }
+    }
+  }
+}
+
+/**
  * Define custom entity properties.
  *
  * @param string $entity_type
diff --git a/core/includes/entity.inc b/core/includes/entity.inc
index a866864..0e5b3ab 100644
--- a/core/includes/entity.inc
+++ b/core/includes/entity.inc
@@ -563,6 +563,71 @@ function entity_view_multiple(array $entities, $view_mode, $langcode = NULL) {
   return entity_render_controller(reset($entities)->entityType())->viewMultiple($entities, $view_mode, $langcode);
 }
 
+
+/**
+ * Returns an entity_display object for the view mode.
+ *
+ * The function reads the object from the current configuration, or returns a
+ * new object if the display is not configured yet.
+ *
+ * @param string $entity_type
+ *   Machine readable name of the content entity.
+ * @param string $bundle
+ *   Machine readable name of the content entity bundle.
+ * @param string $view_mode
+ *   Machine readable name of the content entity view_mode.
+ *
+ * @return Drupal\field\Plugin\Core\Entity\EntityDisplay
+ */
+function entity_get_display($entity_type, $bundle, $view_mode) {
+  // Try loading the display from configuration.
+  if ($display = entity_load('entity_display', $entity_type . '.' . $bundle . '.' . $view_mode)) {
+    return $display;
+  }
+
+  // If not found, create a fresh display object.
+  $display = entity_create('entity_display', array(
+    'targetEntityType' => $entity_type,
+    'bundle' => $bundle,
+    'viewMode' => $view_mode,
+  ));
+  // Initialize default visibility for extra fields.
+  // @todo Cannot work here - see http://drupal.org/node/1848858
+  $extra_fields = field_info_extra_fields($entity_type, $bundle, 'display');
+  foreach ($extra_fields as $field_name => $extra_field) {
+    $display_properties = isset($extra_field['display'][$view_mode]) ? $extra_field['display'][$view_mode]: NULL;
+    if (!isset($display_properties['visible']) || $display_properties['visible'] == TRUE) {
+      $display->setContent($field_name, array(
+        'weight' => $display_properties['weight']
+      ));
+    }
+  }
+  return $display;
+}
+
+/**
+ * Adjusts weights and visibility of components in displayed entities.
+ *
+ * This is used as a #pre_render callback.
+ */
+function _entity_view_pre_render($elements) {
+  $display = $elements['#entity_display'];
+
+  $extra_fields = field_info_extra_fields($display->targetEntityType, $display->bundle, 'display');
+  foreach (array_keys($extra_fields) as $name) {
+    if (isset($elements[$name]) && (!isset($elements[$name]['#access']) || $elements[$name]['#access'])) {
+      if ($properties = $display->getContent($name, FALSE)) {
+        $elements[$name]['#weight'] = $properties['weight'];
+      }
+      else {
+        $elements[$name]['#access'] = FALSE;
+      }
+    }
+  }
+
+  return $elements;
+}
+
 /**
  * Returns the entity query object for this entity type.
  *
diff --git a/core/lib/Drupal/Core/Entity/EntityRenderController.php b/core/lib/Drupal/Core/Entity/EntityRenderController.php
index 2cd0578..dfda261 100644
--- a/core/lib/Drupal/Core/Entity/EntityRenderController.php
+++ b/core/lib/Drupal/Core/Entity/EntityRenderController.php
@@ -30,37 +30,67 @@ public function buildContent(array $entities = array(), $view_mode = 'full', $la
     // Allow modules to change the view mode.
     $context = array('langcode' => $langcode);
 
-    $prepare = array();
-    foreach ($entities as $key => $entity) {
+    $view_modes = array();
+    $displays = array();
+
+    foreach ($entities as $entity) {
       // Remove previously built content, if exists.
       $entity->content = array();
 
       drupal_alter('entity_view_mode', $view_mode, $entity, $context);
       $entity->content['#view_mode'] = $view_mode;
-      $prepare[$view_mode][$key] = $entity;
+      $view_modes[$view_mode][$entity->id()] = $entity;
+
+      $bundle = $entity->bundle();
+
+      // Load the corresponding display settings if not stored yet.
+      if (!isset($displays[$view_mode][$bundle])) {
+        // If the view mode is not configured to use dedicated settings,
+        // rendering is done using 'default'.
+        $actual_mode = field_get_actual_view_mode($this->entityType, $bundle, $view_mode);
+
+        // Get the display object for this bundle and view mode.
+        $display = entity_get_display($this->entityType, $bundle, $actual_mode);
+        $display->originalViewMode = $view_mode;
+
+        // Let modules alter the display.
+        $display_context = array(
+          'entity_type' => $this->entityType,
+          'bundle' => $bundle,
+          'view_mode' => $view_mode,
+        );
+        drupal_alter('entity_display', $display, $display_context);
+
+        $displays[$view_mode][$bundle] = $display;
+      }
+
+      // Assigning weights to 'extra fields' is done in a pre_render callback.
+      $entity->content['#pre_render'] = array('_entity_view_pre_render');
+      $entity->content['#entity_display'] = $displays[$view_mode][$bundle];
     }
 
     // Prepare and build field content, grouped by view mode.
-    foreach ($prepare as $view_mode => $prepare_entities) {
-      $call = array();
+    foreach ($view_modes as $view_mode => $view_mode_entities) {
+      $call_prepare = array();
       // To ensure hooks are only run once per entity, check for an
       // entity_view_prepared flag and only process items without it.
-      foreach ($prepare_entities as $entity) {
+      foreach ($view_mode_entities as $entity) {
         if (empty($entity->entity_view_prepared)) {
           // Add this entity to the items to be prepared.
-          $call[$entity->id()] = $entity;
+          $call_prepare[$entity->id()] = $entity;
 
           // Mark this item as prepared.
           $entity->entity_view_prepared = TRUE;
         }
       }
 
-      if (!empty($call)) {
-        field_attach_prepare_view($this->entityType, $call, $view_mode, $langcode);
-        module_invoke_all('entity_prepare_view', $call, $this->entityType);
+      if (!empty($call_prepare)) {
+        field_attach_prepare_view($this->entityType, $call_prepare, $displays[$view_mode], $langcode);
+        module_invoke_all('entity_prepare_view', $call_prepare, $this->entityType);
       }
-      foreach ($entities as $entity) {
-        $entity->content += field_attach_view($this->entityType, $entity, $view_mode, $langcode);
+
+      foreach ($view_mode_entities as $entity) {
+        $entity->content += field_attach_view($this->entityType, $entity, $displays[$view_mode][$entity->bundle()], $langcode);
       }
     }
   }
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index ab757a9..4d47b9f 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -376,15 +376,15 @@ function _comment_body_field_create($info) {
       'bundle' => 'comment_node_' . $info->type,
       'settings' => array('text_processing' => 1),
       'required' => TRUE,
-      'display' => array(
-        'default' => array(
-          'label' => 'hidden',
-          'type' => 'text_default',
-          'weight' => 0,
-        ),
-      ),
     );
     field_create_instance($instance);
+    $display = entity_get_display('comment', 'comment_node_' . $info->type, 'default');
+    $display->setContent('comment_body', array(
+      'label' => 'hidden',
+      'type' => 'text_default',
+      'weight' => 0,
+    ));
+    $display->save();
   }
 }
 
diff --git a/core/modules/field/field.api.php b/core/modules/field/field.api.php
index 22a9ed7..3aa0cb4 100644
--- a/core/modules/field/field.api.php
+++ b/core/modules/field/field.api.php
@@ -1942,94 +1942,6 @@ function hook_field_info_max_weight($entity_type, $bundle, $context) {
 }
 
 /**
- * Alters the display settings of a field before it is displayed.
- *
- * Note that instead of hook_field_display_alter(), which is called for all
- * fields on all entity types, hook_field_display_ENTITY_TYPE_alter() may be
- * used to alter display settings for fields on a specific entity type only.
- *
- * This hook is called once per field per displayed entity. If the result of the
- * hook involves reading from the database, it is highly recommended to
- * statically cache the information.
- *
- * @param array $display_properties
- *   The display settings that will be used to display the field values, as
- *   found in the 'display' key of $instance definitions.
- * @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 being rendered.
- *   - instance: The instance being rendered.
- *   - view_mode: The view mode, e.g. 'full', 'teaser'...
- *
- * @see hook_field_display_ENTITY_TYPE_alter()
- */
-function hook_field_display_alter(array &$display_properties, array $context) {
-  // Leave field labels out of the search index.
-  // Note: The check against $context['entity_type'] == 'node' could be avoided
-  // by using hook_field_display_node_alter() instead of
-  // hook_field_display_alter(), resulting in less function calls when
-  // rendering non-node entities.
-  if ($context['entity_type'] == 'node' && $context['view_mode'] == 'search_index') {
-    $display_properties['label'] = 'hidden';
-  }
-}
-
-/**
- * Alters the display settings of a field before it is displayed.
- *
- * Modules can implement hook_field_display_ENTITY_TYPE_alter() to alter display
- * settings for fields on a specific entity type, rather than implementing
- * hook_field_display_alter().
- *
- * This hook is called once per field per displayed entity. If the result of the
- * hook involves reading from the database, it is highly recommended to
- * statically cache the information.
- *
- * @param array $display_properties
- *   The display settings that will be used to display the field values, as
- *   found in the 'display' key of $instance definitions.
- * @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 being rendered.
- *   - instance: The instance being rendered.
- *   - view_mode: The view mode, e.g. 'full', 'teaser'...
- *
- * @see hook_field_display_alter()
- */
-function hook_field_display_ENTITY_TYPE_alter(array &$display_properties, array $context) {
-  // Leave field labels out of the search index.
-  if ($context['view_mode'] == 'search_index') {
-    $display_properties['label'] = 'hidden';
-  }
-}
-
-/**
- * Alters the display settings of pseudo-fields before an entity is displayed.
- *
- * This hook is called once per displayed entity. If the result of the hook
- * involves reading from the database, it is highly recommended to statically
- * cache the information.
- *
- * @param $displays
- *   An array of display settings for the pseudo-fields in the entity, keyed by
- *   pseudo-field names.
- * @param $context
- *   An associative array containing:
- *   - entity_type: The entity type; e.g., 'node' or 'user'.
- *   - bundle: The bundle name.
- *   - view_mode: The view mode, e.g. 'full', 'teaser'...
- */
-function hook_field_extra_fields_display_alter(&$displays, $context) {
-  if ($context['entity_type'] == 'taxonomy_term' && $context['view_mode'] == 'full') {
-    $displays['description']['visible'] = FALSE;
-  }
-}
-
-/**
  * Alters the widget properties of a field instance on a given entity type
  * before it gets displayed.
  *
diff --git a/core/modules/field/field.attach.inc b/core/modules/field/field.attach.inc
index 29ebd3b..3edda35 100644
--- a/core/modules/field/field.attach.inc
+++ b/core/modules/field/field.attach.inc
@@ -7,6 +7,7 @@
 
 use Drupal\field\FieldValidationException;
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\field\Plugin\Core\Entity\EntityDisplay;
 
 /**
  * @defgroup field_storage Field Storage API
@@ -719,18 +720,26 @@ function _field_invoke_widget_target() {
  *
  * Used to invoke methods on an instance's formatter.
  *
- * @param mixed $display
- *   Can be either:
- *   - The name of a view mode.
- *   - An array of display properties, as found in
- *     $instance['display'][$view_mode].
+ * @param \Drupal\field\Plugin\Core\Entity\EntityDisplay $display
+ *   The display object for the entity.
  *
  * @return callable $target_function
  *   A 'target function' for field_invoke_method().
  */
-function _field_invoke_formatter_target($display) {
+function _field_invoke_formatter_target(EntityDisplay $display) {
   return function ($instance) use ($display) {
-    return $instance->getFormatter($display);
+    return $display->getFormatter($instance['field_name']);
+  };
+}
+
+/**
+ * @todo UGLY !
+ */
+function _field_invoke_formatter_multiple_target(array $displays) {
+  return function ($instance) use ($displays) {
+    if (isset($displays[$instance['bundle']])) {
+      return $displays[$instance['bundle']]->getFormatter($instance['field_name']);
+    }
   };
 }
 
@@ -1361,10 +1370,10 @@ function field_attach_delete_revision($entity_type, $entity) {
  *
  * @param $entity_type
  *   The type of entities in $entities; e.g. 'node' or 'user'.
- * @param $entities
+ * @param array $entities
  *   An array of entities, keyed by entity ID.
- * @param $view_mode
- *   View mode, e.g. 'full', 'teaser'...
+ * @param array $displays
+ *   An array of entity display objects, keyed by bundle name.
  * @param $langcode
  *   (Optional) The language the field values are to be shown in. If no language
  *   is provided the current language is used.
@@ -1372,7 +1381,7 @@ function field_attach_delete_revision($entity_type, $entity) {
  *   An associative array of additional options. See field_invoke_method() for
  *   details.
  */
-function field_attach_prepare_view($entity_type, $entities, $view_mode, $langcode = NULL, array $options = array()) {
+function field_attach_prepare_view($entity_type, array $entities, array $displays, $langcode = NULL, array $options = array()) {
   $options['langcode'] = array();
 
   // To ensure hooks are only run once per entity, only process items without
@@ -1397,7 +1406,7 @@ function field_attach_prepare_view($entity_type, $entities, $view_mode, $langcod
   // First let the field types do their preparation.
   _field_invoke_multiple('prepare_view', $entity_type, $prepare, $null, $null, $options);
   // Then let the formatters do their own specific massaging.
-  field_invoke_method_multiple('prepareView', _field_invoke_formatter_target($view_mode), $prepare, $view_mode, $null, $options);
+  field_invoke_method_multiple('prepareView', _field_invoke_formatter_multiple_target($displays), $prepare, $null, $null, $options);
 }
 
 /**
@@ -1437,32 +1446,29 @@ function field_attach_prepare_view($entity_type, $entities, $view_mode, $langcod
  *   The type of $entity; e.g. 'node' or 'user'.
  * @param Drupal\Core\Entity\EntityInterface $entity
  *   The entity with fields to render.
- * @param $view_mode
- *   View mode, e.g. 'full', 'teaser'...
+ * @param \Drupal\field\Plugin\Core\Entity\EntityDisplay $display
+ *   The entity display object.
  * @param $langcode
  *   The language the field values are to be shown in. If no language is
  *   provided the current language is used.
  * @param array $options
  *   An associative array of additional options. See field_invoke_method() for
  *   details.
- * @return
+
+ * @return array
  *   A renderable array for the field values.
  */
-function field_attach_view($entity_type, EntityInterface $entity, $view_mode, $langcode = NULL, array $options = array()) {
+function field_attach_view($entity_type, EntityInterface $entity, EntityDisplay $display, $langcode = NULL, array $options = array()) {
   // Determine the actual language code to display for each field, given the
   // language codes available in the field data.
   $options['langcode'] = field_language($entity_type, $entity, NULL, $langcode);
 
   // Invoke field_default_view().
   $null = NULL;
-  $output = field_invoke_method('view', _field_invoke_formatter_target($view_mode), $entity, $view_mode, $null, $options);
-
-  // Add custom weight handling.
-  $output['#pre_render'][] = '_field_extra_fields_pre_render';
-  $output['#entity_type'] = $entity_type;
-  $output['#bundle'] = $entity->bundle();
+  $output = field_invoke_method('view', _field_invoke_formatter_target($display), $entity, $null, $null, $options);
 
   // Let other modules alter the renderable array.
+  $view_mode = $display->originalViewMode;
   $context = array(
     'entity_type' => $entity_type,
     'entity' => $entity,
diff --git a/core/modules/field/field.crud.inc b/core/modules/field/field.crud.inc
index ac66c77..a62ad2e 100644
--- a/core/modules/field/field.crud.inc
+++ b/core/modules/field/field.crud.inc
@@ -588,7 +588,6 @@ function _field_write_instance(&$instance, $update = FALSE) {
   // Set defaults.
   $instance += array(
     'settings' => array(),
-    'display' => array(),
     'widget' => array(),
     'required' => FALSE,
     'label' => $instance['field_name'],
@@ -615,30 +614,6 @@ function _field_write_instance(&$instance, $update = FALSE) {
   $instance['widget']['module'] = $widget_type['module'];
   $instance['widget']['settings'] += field_info_widget_settings($instance['widget']['type']);
 
-  // Make sure there are at least display settings for the 'default' view mode,
-  // and fill in defaults for each view mode specified in the definition.
-  $instance['display'] += array(
-    'default' => array(),
-  );
-  foreach ($instance['display'] as $view_mode => $display) {
-    $display += array(
-      'label' => 'above',
-      'type' => isset($field_type['default_formatter']) ? $field_type['default_formatter'] : 'hidden',
-      'settings' => array(),
-    );
-    if ($display['type'] != 'hidden') {
-      $formatter_type = field_info_formatter_types($display['type']);
-      $display['module'] = $formatter_type['module'];
-      $display['settings'] += field_info_formatter_settings($display['type']);
-    }
-    // If no weight specified, make sure the field sinks at the bottom.
-    if (!isset($display['weight'])) {
-      $max_weight = field_info_max_weight($instance['entity_type'], $instance['bundle'], $view_mode);
-      $display['weight'] = isset($max_weight) ? $max_weight + 1 : 0;
-    }
-    $instance['display'][$view_mode] = $display;
-  }
-
   // The serialized 'data' column contains everything from $instance that does
   // not have its own column and is not automatically populated when the
   // instance is read.
diff --git a/core/modules/field/field.info.inc b/core/modules/field/field.info.inc
index 5fab889..688d611 100644
--- a/core/modules/field/field.info.inc
+++ b/core/modules/field/field.info.inc
@@ -522,7 +522,7 @@ function field_info_extra_fields($entity_type, $bundle, $context) {
 }
 
 /**
- * Returns the maximum weight of all the components in an entity.
+ * 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).
@@ -531,33 +531,25 @@ function field_info_extra_fields($entity_type, $bundle, $context) {
  *   The type of entity; e.g. 'node' or 'user'.
  * @param $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
  *   The maximum weight of the entity's components, or NULL if no components
  *   were found.
  */
-function field_info_max_weight($entity_type, $bundle, $context) {
+function field_info_max_weight($entity_type, $bundle) {
   $weights = array();
 
   // Collect weights for fields.
   foreach (field_info_instances($entity_type, $bundle) as $instance) {
-    if ($context == 'form') {
-      $weights[] = $instance['widget']['weight'];
-    }
-    elseif (isset($instance['display'][$context]['weight'])) {
-      $weights[] = $instance['display'][$context]['weight'];
-    }
+    $weights[] = $instance['widget']['weight'];
   }
   // Collect weights for extra fields.
-  foreach (field_info_extra_fields($entity_type, $bundle, $context) as $extra) {
+  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, $context));
+  $weights = array_merge($weights, module_invoke_all('field_info_max_weight', $entity_type, $bundle, 'form'));
   $max_weight = $weights ? max($weights) : NULL;
 
   return $max_weight;
diff --git a/core/modules/field/field.install b/core/modules/field/field.install
index b88faa8..ce6bfa0 100644
--- a/core/modules/field/field.install
+++ b/core/modules/field/field.install
@@ -357,15 +357,6 @@ function _update_7000_field_create_instance($field, &$instance) {
     'deleted' => 0,
   );
 
-  // Merge in display defaults.
-  if (isset($instance['display'])) {
-    foreach ($instance['display'] as &$display) {
-      $display += array(
-        'weight' => 0,
-      );
-    }
-  }
-
   // The serialized 'data' column contains everything from $instance that does
   // not have its own column and is not automatically populated when the
   // instance is read.
@@ -403,6 +394,66 @@ function field_update_8001() {
 }
 
 /**
+ * Migrate all instance display settings to configuration.
+ *
+ * @ingroup config_upgrade
+ */
+function field_update_8002() {
+  $displays = array();
+
+  $query = db_select('field_config_instance', 'fc')->fields('fc');
+  foreach ($query->execute() as $record) {
+
+    // Unserialize the data array and start investigating the display key
+    // which holds the configuration of this instance for all view modes.
+    $data = unserialize($record->data);
+
+    // @todo Somehow, user picture field has no display key,
+    // check with user picture field upgrade path.
+    if (!isset($data['display'])) {
+      continue;
+    }
+
+    foreach ($data['display'] as $view_mode => $configuration) {
+
+      // Determine name and create initial entry in the $displays array if
+      // it does not exist yet.
+      $name = 'field.entity_display.' . $record->entity_type . '.' . $record->bundle . '.' . $view_mode;
+      if (!isset($displays[$name])) {
+        $displays[$name] = array(
+          'id' => $record->entity_type . '.' . $record->bundle . '.' . $view_mode,
+          'targetEntityType' => $record->entity_type,
+          'bundle' => $record->bundle,
+          'viewMode' => $view_mode,
+          'content' => array(),
+        );
+      }
+
+      // Add field configuration of this view mode to the content key
+      // of the display, but only if the formatter type is not set to hidden.
+      // We do not store hidden fields on the new display object.
+      if ($configuration['type'] != 'hidden') {
+        $displays[$name]['content'][$record->field_name] = $configuration;
+      }
+    }
+
+    // Remove the display key from the configuration and save the instance
+    // back into the table.
+    unset($data['display']);
+    db_update('field_config_instance')
+      ->condition('id', $record->id)
+      ->fields(array(
+        'data' => serialize($data),
+      ))
+      ->execute();
+  }
+
+  foreach ($displays as $name => $configuration) {
+    config($name)->setData($configuration)->save();
+  }
+}
+
+/**
  * @} End of "addtogroup updates-7.x-to-8.x".
  * The next series of updates should start at 9000.
  */
diff --git a/core/modules/field/field.module b/core/modules/field/field.module
index 686e3f5..a010c56 100644
--- a/core/modules/field/field.module
+++ b/core/modules/field/field.module
@@ -682,7 +682,6 @@ function field_bundle_settings($entity_type, $bundle, $settings = NULL) {
     );
     $settings['extra_fields'] += array(
       'form' => array(),
-      'display' => array(),
     );
 
     return $settings;
@@ -725,6 +724,29 @@ function field_view_mode_settings($entity_type, $bundle) {
 }
 
 /**
+ * Returns the actual view mode to use for a bundle.
+ *
+ * Depending on the current configuration of the bundle for this view mode, the
+ * function returns either:
+ * - the value of the incoming $view_mode parameter,
+ * - or 'default'.
+ *
+ * @param string $entity_type
+ *   The type of $entity; e.g., 'node' or 'user'.
+ * @param string $bundle
+ *   The bundle name.
+ * @param string $view_mode
+ *   The view mode.
+ *
+ * @return string
+ *   The actual view mode to use for this entity type and bundle.
+ */
+function field_get_actual_view_mode($entity_type, $bundle, $view_mode) {
+  $view_mode_settings = field_view_mode_settings($entity_type, $bundle);
+  return (!empty($view_mode_settings[$view_mode]['custom_settings']) ? $view_mode : 'default');
+}
+
+/**
  * Returns the display settings to use for pseudo-fields in a given view mode.
  *
  * @param $entity_type
@@ -738,25 +760,16 @@ function field_view_mode_settings($entity_type, $bundle) {
  *   The display settings to be used when viewing the bundle's pseudo-fields.
  */
 function field_extra_fields_get_display($entity_type, $bundle, $view_mode) {
-  // Check whether the view mode uses custom display settings or the 'default'
-  // mode.
-  $view_mode_settings = field_view_mode_settings($entity_type, $bundle);
-  $actual_mode = (!empty($view_mode_settings[$view_mode]['custom_settings'])) ? $view_mode : 'default';
+
+  $actual_mode = field_get_actual_view_mode($entity_type, $bundle, $view_mode);
+  $entity_display = entity_get_display($entity_type, $bundle, $actual_mode);
   $extra_fields = field_info_extra_fields($entity_type, $bundle, 'display');
 
   $displays = array();
   foreach ($extra_fields as $name => $value) {
-    $displays[$name] = $extra_fields[$name]['display'][$actual_mode];
+    $displays[$name] = $entity_display->getContent($name);
   }
 
-  // Let modules alter the display settings.
-  $context = array(
-    'entity_type' => $entity_type,
-    'bundle' => $bundle,
-    'view_mode' => $view_mode,
-  );
-  drupal_alter('field_extra_fields_display', $displays, $context);
-
   return $displays;
 }
 
@@ -767,23 +780,10 @@ function _field_extra_fields_pre_render($elements) {
   $entity_type = $elements['#entity_type'];
   $bundle = $elements['#bundle'];
 
-  if (isset($elements['#type']) && $elements['#type'] == 'form') {
-    $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'];
-      }
-    }
-  }
-  elseif (isset($elements['#view_mode'])) {
-    $view_mode = $elements['#view_mode'];
-    $extra_fields = field_extra_fields_get_display($entity_type, $bundle, $view_mode);
-    foreach ($extra_fields as $name => $settings) {
-      if (isset($elements[$name])) {
-        $elements[$name]['#weight'] = $settings['weight'];
-        // Visibility: make sure we do not accidentally show a hidden element.
-        $elements[$name]['#access'] = isset($elements[$name]['#access']) ? ($elements[$name]['#access'] && $settings['visible']) : $settings['visible'];
-      }
+  $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'];
     }
   }
 
@@ -902,15 +902,16 @@ function field_view_value($entity_type, $entity, $field_name, $item, $display =
  *   key and the field data to display.
  * @param $field_name
  *   The name of the field to display.
- * @param $display
+ * @param $display_properties
  *   Can be either:
  *   - The name of a view mode. The field will be displayed according to the
  *     display settings specified for this view mode in the $instance
  *     definition for the field in the entity's bundle. If no display settings
  *     are found for the view mode, the settings for the 'default' view mode
  *     will be used.
- *   - An array of display settings, as found in the 'display' entry of
- *     $instance definitions. The following key/value pairs are allowed:
+ *   - An array of display settings, as accepted by
+ *     \Drupal\field\FieldInstance::getFormatter(). The following key/value
+ *     pairs are allowed:
  *     - label: (string) Position of the label. The default 'field' theme
  *       implementation supports the values 'inline', 'above' and 'hidden'.
  *       Defaults to 'above'.
@@ -933,51 +934,64 @@ function field_view_value($entity_type, $entity, $field_name, $item, $display =
  *
  * @see field_view_value()
  */
-function field_view_field($entity_type, $entity, $field_name, $display = array(), $langcode = NULL) {
+function field_view_field($entity_type, $entity, $field_name, $display_properties = array(), $langcode = NULL) {
   $output = array();
+  $bundle = $entity->bundle();
 
-  if ($instance = field_info_instance($entity_type, $field_name, $entity->bundle())) {
-    if (is_array($display) && empty($display['type'])) {
-      $field = field_info_field($instance['field_name']);
-      $field_type_info = field_info_field_types($field['type']);
-      $display['type'] = $field_type_info['default_formatter'];
-    }
-    if ($formatter = $instance->getFormatter($display)) {
-      $display_langcode = field_language($entity_type, $entity, $field_name, $langcode);
-      $items = $entity->{$field_name}[$display_langcode];
-
-      // Invoke prepare_view steps if needed.
-      if (empty($entity->_field_view_prepared)) {
-        $id = $entity->id();
-
-        // First let the field types do their preparation.
-        // @todo invoke hook_field_prepare_view() directly ?
-        $options = array('field_name' => $field_name, 'langcode' => $display_langcode);
-        $null = NULL;
-        _field_invoke_multiple('prepare_view', $entity_type, array($id => $entity), $display, $null, $options);
-
-        // Then let the formatters do their own specific massaging.
-        $items_multi = array($id => $entity->{$field_name}[$display_langcode]);
-        $formatter->prepareView(array($id => $entity), $display_langcode, $items_multi);
-        $items = $items_multi[$id];
-      }
+  // Return nothing if the field doesn't exist.
+  $instance = field_info_instance($entity_type, $field_name, $bundle);
+  if (!$instance) {
+    return $output;
+  }
+
+  // Get the formatter object.
+  if (is_string($display_properties)) {
+    $view_mode = $display_properties;
+    // If the view mode is not configured to use dedicated settings,
+    // rendering is done using 'default'.
+    $actual_mode = field_get_actual_view_mode($entity_type, $entity->bundle(), $view_mode);
+    $formatter = entity_get_display($entity_type, $bundle, $actual_mode)->getFormatter($field_name);
+  }
+  else {
+    $view_mode = '_custom';
+    $formatter = $instance->getFormatter($display_properties, $view_mode);
+  }
 
-      // Build the renderable array.
-      $result = $formatter->view($entity, $display_langcode, $items);
+  if ($formatter) {
+    $display_langcode = field_language($entity_type, $entity, $field_name, $langcode);
+    $items = $entity->{$field_name}[$display_langcode];
 
-      // Invoke hook_field_attach_view_alter() to let other modules alter the
-      // renderable array, as in a full field_attach_view() execution.
-      $context = array(
-        'entity_type' => $entity_type,
-        'entity' => $entity,
-        'view_mode' => '_custom',
-        'display' => $display,
-      );
-      drupal_alter('field_attach_view', $result, $context);
+    // Invoke prepare_view steps if needed.
+    if (empty($entity->_field_view_prepared)) {
+      $id = $entity->id();
 
-      if (isset($result[$field_name])) {
-        $output = $result[$field_name];
-      }
+      // First let the field types do their preparation.
+      $options = array('field_name' => $field_name, 'langcode' => $display_langcode);
+      $null = NULL;
+      _field_invoke_multiple('prepare_view', $entity_type, array($id => $entity), $null, $null, $options);
+
+      // Then let the formatter do its own specific massaging.
+      $items_multi = array($id => $entity->{$field_name}[$display_langcode]);
+      $formatter->prepareView(array($id => $entity), $display_langcode, $items_multi);
+      $items = $items_multi[$id];
+    }
+
+    // Build the renderable array.
+    $result = $formatter->view($entity, $display_langcode, $items);
+
+    // Invoke hook_field_attach_view_alter() to let other modules alter the
+    // renderable array, as in a full field_attach_view() execution.
+    $context = array(
+      'entity_type' => $entity_type,
+      'entity' => $entity,
+      'view_mode' => $view_mode,
+      // @todo see http://drupal.org/node/990148
+      'display' => $display_properties,
+    );
+    drupal_alter('field_attach_view', $result, $context);
+
+    if (isset($result[$field_name])) {
+      $output = $result[$field_name];
     }
   }
 
diff --git a/core/modules/field/lib/Drupal/field/EntityDisplayStorageController.php b/core/modules/field/lib/Drupal/field/EntityDisplayStorageController.php
new file mode 100644
index 0000000..3a0ac84
--- /dev/null
+++ b/core/modules/field/lib/Drupal/field/EntityDisplayStorageController.php
@@ -0,0 +1,37 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\field\EntityDisplayStorageController.
+ */
+
+namespace Drupal\field;
+
+use Drupal\Core\Config\Entity\ConfigStorageController;
+use Drupal\Core\Entity\EntityInterface;
+
+/**
+ * Defines the storage controller class for EntityDisplay  entities.
+ */
+class EntityDisplayStorageController extends ConfigStorageController {
+
+  /**
+   * Overrides \Drupal\config\ConfigStorageController::getProperties();
+   */
+  protected function getProperties(EntityInterface $entity) {
+    $names = array(
+      'id',
+      'uuid',
+      'targetEntityType',
+      'bundle',
+      'viewMode',
+      'content',
+    );
+    $properties = array();
+    foreach ($names as $name) {
+      $properties[$name] = $entity->get($name);
+    }
+    return $properties;
+  }
+
+}
diff --git a/core/modules/field/lib/Drupal/field/FieldInfo.php b/core/modules/field/lib/Drupal/field/FieldInfo.php
index 65aa26c..2f33c89 100644
--- a/core/modules/field/lib/Drupal/field/FieldInfo.php
+++ b/core/modules/field/lib/Drupal/field/FieldInfo.php
@@ -543,25 +543,7 @@ public function prepareExtraFields($extra_fields, $entity_type, $bundle) {
     }
 
     // Extra fields in displayed entities.
-    $data = $extra_fields['display'];
-    foreach ($extra_fields['display'] as $name => $field_data) {
-      $settings = isset($bundle_settings['extra_fields']['display'][$name]) ? $bundle_settings['extra_fields']['display'][$name] : array();
-      $view_modes = array_merge(array('default'), array_keys($entity_type_info['view_modes']));
-      foreach ($view_modes as $view_mode) {
-        if (isset($settings[$view_mode])) {
-          $field_data['display'][$view_mode] = $settings[$view_mode];
-        }
-        else {
-          $field_data['display'][$view_mode] = array(
-            'weight' => $field_data['weight'],
-            'visible' => isset($field_data['visible']) ? $field_data['visible'] : TRUE,
-          );
-        }
-      }
-      unset($field_data['weight']);
-      unset($field_data['visible']);
-      $result['display'][$name] = $field_data;
-    }
+    $result['display'] = $extra_fields['display'];
 
     return $result;
   }
diff --git a/core/modules/field/lib/Drupal/field/FieldInstance.php b/core/modules/field/lib/Drupal/field/FieldInstance.php
index a1e7a4f..ee89aa8 100644
--- a/core/modules/field/lib/Drupal/field/FieldInstance.php
+++ b/core/modules/field/lib/Drupal/field/FieldInstance.php
@@ -27,13 +27,6 @@ class FieldInstance implements \ArrayAccess {
   protected $widget;
 
   /**
-   * The formatter objects used for this instance, keyed by view mode.
-   *
-   * @var array
-   */
-  protected $formatters;
-
-  /**
    * Constructs a FieldInstance object.
    *
    * @param array $definition
@@ -75,85 +68,73 @@ public function getWidget() {
   }
 
   /**
-   * Returns a Formatter plugin for the instance.
+   * Merges default values for an array of display properties.
+   *
+   * @todo Not sure what is the best place for this yet.
+   * In FormatterPluginManager ?
    *
-   * @param mixed $display_properties
-   *   Can be either:
-   *   - The name of a view mode.
-   *   - An array of display properties, as found in the 'display' entry of
-   *     $instance definitions.
+   * @param array $properties
+   *   An array of display properties.
    *
-   * @return Drupal\field\Plugin\Type\Formatter\FormatterInterface|null
-   *   The Formatter plugin to be used for the instance, or NULL if the field
-   *   is hidden.
+   * @return array
+   *   The display properties with defaults added.
    */
-  public function getFormatter($display_properties) {
-    if (is_string($display_properties)) {
-      // A view mode was provided. Switch to 'default' if the view mode is not
-      // configured to use dedicated settings.
-      $view_mode = $display_properties;
-      $view_mode_settings = field_view_mode_settings($this->definition['entity_type'], $this->definition['bundle']);
-      $actual_mode = (!empty($view_mode_settings[$view_mode]['custom_settings']) ? $view_mode : 'default');
-
-      if (isset($this->formatters[$actual_mode])) {
-        return $this->formatters[$actual_mode];
-      }
-
-      // Switch to 'hidden' if the instance has no properties for the view
-      // mode.
-      if (isset($this->definition['display'][$actual_mode])) {
-        $display_properties = $this->definition['display'][$actual_mode];
-      }
-      else {
-        $display_properties = array(
-          'type' => 'hidden',
-          'settings' => array(),
-          'label' => 'above',
-          'weight' => 0,
-        );
-      }
-
-      // Let modules alter the widget properties.
-      $context = array(
-        'entity_type' => $this->definition['entity_type'],
-        'bundle' => $this->definition['bundle'],
-        'field' => field_info_field($this->definition['field_name']),
-        'instance' => $this,
-        'view_mode' => $view_mode,
-      );
-      drupal_alter(array('field_display', 'field_display_' . $this->definition['entity_type']), $display_properties, $context);
-    }
-    else {
-      // Arbitrary display settings. Make sure defaults are present.
-      $display_properties += array(
-        'settings' => array(),
-        'label' => 'above',
-        'weight' => 0,
-      );
-      $view_mode = '_custom_display';
+  public function prepareDisplayProperties($properties) {
+    // Fill in defaults for missing properties.
+    $properties += array(
+      'label' => 'above',
+      'settings' => array(),
+      'weight' => 0,
+    );
+      // If no formatter is specified, use the default formatter.
+    if (!isset($properties['type'])) {
+      $field = field_info_field($this->definition['field_name']);
+      $field_type = field_info_field_types($field['type']);
+      $properties['type'] = $field_type['default_formatter'];
     }
+    // Fill in default settings values for the formatter.
+    $properties['settings'] += field_info_formatter_settings($properties['type']);
 
-    if (!empty($display_properties['type']) && $display_properties['type'] != 'hidden') {
-      $options = array(
-        'instance' => $this,
-        'type' => $display_properties['type'],
-        'settings' => $display_properties['settings'],
-        'label' => $display_properties['label'],
-        'weight' => $display_properties['weight'],
-        'view_mode' => $view_mode,
-      );
-      $formatter = drupal_container()->get('plugin.manager.field.formatter')->getInstance($options);
-    }
-    else {
-      $formatter = NULL;
-    }
+    return $properties;
+  }
 
-    // Persist the object if we were not passed custom display settings.
-    if (isset($actual_mode)) {
-      $this->formatters[$actual_mode] = $formatter;
+  /**
+   * @param $properties
+   *   An array of display properties. The following key/value pairs are
+   *   allowed:
+   *   - label: (string) Position of the label. The default 'field' theme
+   *     implementation supports the values 'inline', 'above' and 'hidden'.
+   *     Defaults to 'above'.
+   *   - type: (string) The formatter to use. Defaults to the
+   *     'default_formatter' for the field type, specified in hook_field_info().
+   *     The default formatter will also be used if the requested formatter is
+   *     not available.
+   *   - settings: (array) Settings specific to the formatter. Defaults to the
+   *     formatter's default settings, specified in hook_field_formatter_info().
+   *   - weight: (float) The weight to assign to the renderable element.
+   *     Defaults to 0.
+   * @param $view_mode
+   *   The view_mode.
+   * @param bool $prepare
+   *   (optional) Whether to merges default values in the incoming $properties.
+   *
+   * @return \Drupal\field\Plugin\Type\Formatter\FormatterInterface|null
+   *   The Formatter plugin, or NULL if the field is hidden.
+   */
+  public function getFormatter($properties, $view_mode, $prepare = TRUE) {
+    if ($prepare) {
+      $properties = $this->prepareDisplayProperties($properties);
     }
 
-    return $formatter;
+    $options = array(
+      'instance' => $this,
+      'type' => $properties['type'],
+      'settings' => $properties['settings'],
+      'label' => $properties['label'],
+      'weight' => $properties['weight'],
+      'view_mode' => $view_mode,
+    );
+    return drupal_container()->get('plugin.manager.field.formatter')->getInstance($options);
   }
 
   /**
@@ -185,9 +166,6 @@ public function offsetSet($offset, $value) {
     if ($offset == 'widget') {
       unset($this->widget);
     }
-    if ($offset == 'display') {
-      unset($this->formatters);
-    }
   }
 
   /**
@@ -201,9 +179,6 @@ public function offsetUnset($offset) {
     if ($offset == 'widget') {
       unset($this->widget);
     }
-    if ($offset == 'display') {
-      unset($this->formatters);
-    }
   }
 
   /**
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/EntityDisplay.php b/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/EntityDisplay.php
new file mode 100644
index 0000000..bde24c7
--- /dev/null
+++ b/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/EntityDisplay.php
@@ -0,0 +1,215 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\field\Plugin\Core\Entity\EntityDisplay.
+ */
+
+namespace Drupal\field\Plugin\Core\Entity;
+
+use Drupal\Core\Config\Entity\ConfigEntityBase;
+use Drupal\Core\Annotation\Plugin;
+use Drupal\Core\Annotation\Translation;
+
+/**
+ * Configuration encapsulator that provides all the data needed by block-driven
+ * controllers to render an entity.
+ *
+ * @Plugin(
+ *   id = "entity_display",
+ *   label = @Translation("Entity display"),
+ *   module = "field",
+ *   controller_class = "Drupal\field\EntityDisplayStorageController",
+ *   config_prefix = "field.entity_display",
+ *   entity_keys = {
+ *     "id" = "id"
+ *   }
+ * )
+ */
+class EntityDisplay extends ConfigEntityBase {
+
+  /**
+   * 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;
+
+  /**
+   * Contains all field display configuration
+   *
+   * @var array
+   */
+  public $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 Exception if no targetEntityType, bundle, viewMode
+    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;
+  }
+
+  /**
+   * Sets the display settings of a field.
+   *
+   * @param string $field_name
+   *   The field name to save settings for.
+   * @param array $settings
+   *   The settings for the field.
+   */
+  public function setContent($field_name, array $properties = array()) {
+    // If no weight specified, assign highest weight to make sure the field
+    // sinks at the bottom.
+    if (!isset($properties['weight'])) {
+      $weights = array();
+      // Collect weights for fields.
+      foreach ($this->content as $item) {
+        $weights[] = $item['weight'];
+      }
+      // Let other modules feedback about their own additions.
+      // @todo If "other components" (e.g field_groups) can live in the
+      // $entity_display, then this is not needed anymore.
+      $weights = array_merge($weights, module_invoke_all('field_info_max_weight', $this->targetEntityType, $this->bundle, $this->viewMode));
+      $properties['weight'] = $weights ? max($weights) + 1 : 0;
+    }
+
+    if ($instance = field_info_instance($this->targetEntityType, $field_name, $this->bundle)) {
+      $properties = $instance->prepareDisplayProperties($properties);
+
+      // Clear the persisted formatter, if any.
+      unset($this->formatters[$field_name]);
+    }
+
+    $this->content[$field_name] = $properties;
+  }
+
+  /**
+   * Gets the display settings of a field.
+   *
+   * @param string $field_name
+   *   The field name to get settings for.
+   * @param bool $add_default
+   *   Add default settings or not.
+   *
+   * @return array
+   *   The settings for the field.
+   */
+  public function getContent($field_name) {
+    if (isset($this->content[$field_name])) {
+      return $this->content[$field_name];
+    }
+  }
+
+  /**
+   * Removes the display settings from a field.
+   *
+   * @param string $field_name
+   *   The field name to delete.
+   */
+  public function deleteContent($field_name) {
+    unset($this->content[$field_name]);
+    unset($this->formatters[$field_name]);
+  }
+
+  /**
+   * Clears all content fields for the display object.
+   */
+  public function clearContent() {
+    $this->content = array();
+    $this->formatters = array();
+  }
+
+  /**
+   * 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();
+  }
+
+  /**
+   * Returns the Formatter plugin for a field.
+   *
+   * @param string $field_name
+   *   The field name.
+   *
+   * @return \Drupal\field\Plugin\Type\Formatter\FormatterInterface
+   *   If the field is not hidden, the Formatter plugin to use for rendering
+   *   it.
+   */
+  public function getFormatter($field_name) {
+    if (isset($this->formatters[$field_name])) {
+      return $this->formatters[$field_name];
+    }
+
+    // Instanciate the formatter object from the stored display properties.
+    if ($display_properties = $this->getContent($field_name)) {
+      $instance = field_info_instance($this->targetEntityType, $field_name, $this->bundle);
+      $formatter = $instance->getFormatter($display_properties, $this->originalViewMode, FALSE);
+    }
+    else {
+      $formatter = NULL;
+    }
+
+    // Persist the formatter object.
+    $this->formatters[$field_name] = $formatter;
+    return $formatter;
+  }
+
+}
diff --git a/core/modules/field/lib/Drupal/field/Tests/DisplayApiTest.php b/core/modules/field/lib/Drupal/field/Tests/DisplayApiTest.php
index 1c8f166..5db54c5 100644
--- a/core/modules/field/lib/Drupal/field/Tests/DisplayApiTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/DisplayApiTest.php
@@ -42,23 +42,33 @@ function setUp() {
       'entity_type' => 'test_entity',
       'bundle' => 'test_bundle',
       'label' => $this->label,
-      'display' => array(
-        'default' => array(
-          'type' => 'field_test_default',
-          'settings' => array(
-            'test_formatter_setting' => $this->randomName(),
-          ),
+    );
+
+    $this->display_settings = array(
+      'default' => array(
+        'type' => 'field_test_default',
+        'settings' => array(
+          'test_formatter_setting' => $this->randomName(),
         ),
-        'teaser' => array(
-          'type' => 'field_test_default',
-          'settings' => array(
-            'test_formatter_setting' => $this->randomName(),
-          ),
+      ),
+      'teaser' => array(
+        'type' => 'field_test_default',
+        'settings' => array(
+          'test_formatter_setting' => $this->randomName(),
         ),
       ),
     );
+
     field_create_field($this->field);
     field_create_instance($this->instance);
+    // Create a display for the default view mode.
+    $display = entity_get_display($this->instance['entity_type'], $this->instance['bundle'], 'default');
+    $display->setContent($this->field_name, $this->display_settings['default']);
+    $display->save();
+    // Create a display for the teaser view mode.
+    $display = entity_get_display($this->instance['entity_type'], $this->instance['bundle'], 'teaser');
+    $display->setContent($this->field_name, $this->display_settings['teaser']);
+    $display->save();
 
     // Create an entity with values.
     $this->values = $this->_generateTestFieldValues($this->cardinality);
@@ -120,11 +130,11 @@ function testFieldViewField() {
       $this->assertText($setting . '|' . $value['value'] . '|' . ($value['value'] + 1), format_string('Value @delta was displayed with expected setting.', array('@delta' => $delta)));
     }
 
-    // View mode: check that display settings specified in the instance are
-    // used.
+    // View mode: check that display settings specified in the display object
+    // are used.
     $output = field_view_field('test_entity', $this->entity, $this->field_name, 'teaser');
     $this->drupalSetContent(drupal_render($output));
-    $setting = $this->instance['display']['teaser']['settings']['test_formatter_setting'];
+    $setting = $this->display_settings['teaser']['settings']['test_formatter_setting'];
     $this->assertText($this->label, 'Label was displayed.');
     foreach ($this->values as $delta => $value) {
       $this->assertText($setting . '|' . $value['value'], format_string('Value @delta was displayed with expected setting.', array('@delta' => $delta)));
@@ -134,7 +144,7 @@ function testFieldViewField() {
     // are used.
     $output = field_view_field('test_entity', $this->entity, $this->field_name, 'unknown_view_mode');
     $this->drupalSetContent(drupal_render($output));
-    $setting = $this->instance['display']['default']['settings']['test_formatter_setting'];
+    $setting = $this->display_settings['default']['settings']['test_formatter_setting'];
     $this->assertText($this->label, 'Label was displayed.');
     foreach ($this->values as $delta => $value) {
       $this->assertText($setting . '|' . $value['value'], format_string('Value @delta was displayed with expected setting.', array('@delta' => $delta)));
@@ -189,7 +199,7 @@ function testFieldViewValue() {
 
     // View mode: check that display settings specified in the instance are
     // used.
-    $setting = $this->instance['display']['teaser']['settings']['test_formatter_setting'];
+    $setting = $this->display_settings['teaser']['settings']['test_formatter_setting'];
     foreach ($this->values as $delta => $value) {
       $item = $this->entity->{$this->field_name}[LANGUAGE_NOT_SPECIFIED][$delta];
       $output = field_view_value('test_entity', $this->entity, $this->field_name, $item, 'teaser');
@@ -199,7 +209,7 @@ function testFieldViewValue() {
 
     // Unknown view mode: check that display settings for 'default' view mode
     // are used.
-    $setting = $this->instance['display']['default']['settings']['test_formatter_setting'];
+    $setting = $this->display_settings['default']['settings']['test_formatter_setting'];
     foreach ($this->values as $delta => $value) {
       $item = $this->entity->{$this->field_name}[LANGUAGE_NOT_SPECIFIED][$delta];
       $output = field_view_value('test_entity', $this->entity, $this->field_name, $item, 'unknown_view_mode');
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldAccessTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldAccessTest.php
index 7f87887..22c4202 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldAccessTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldAccessTest.php
@@ -49,14 +49,16 @@ function setUp() {
       'widget' => array(
         'type' => 'text_textfield',
       ),
-      'display' => array(
-        'default' => array(
-          'type' => 'text_default',
-        ),
-      ),
     );
     field_create_instance($this->instance);
 
+    // Assign display properties for the 'default' and 'teaser' view modes.
+    foreach (array('default', 'teaser') as $view_mode) {
+      $display = entity_get_display('node', $this->content_type, $view_mode);
+      $display->setContent($this->field['field_name']);
+      $display->save();
+    }
+
     // Create test node.
     $this->test_view_field_value = 'This is some text';
     $settings = array();
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php
index f971099..bb638d5 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php
@@ -40,31 +40,32 @@ function testFieldAttachView() {
 
     // Simple formatter, label displayed.
     $entity = clone($entity_init);
+    $display = entity_get_display($entity_type, $entity->bundle(), 'full');
+    $displays = array($entity->bundle() => $display);
+
     $formatter_setting = $this->randomName();
-    $this->instance['display'] = array(
-      'full' => array(
-        'label' => 'above',
-        'type' => 'field_test_default',
-        'settings' => array(
-          'test_formatter_setting' => $formatter_setting,
-        )
+    $display_settings = array(
+      'label' => 'above',
+      'type' => 'field_test_default',
+      'settings' => array(
+        'test_formatter_setting' => $formatter_setting,
       ),
     );
-    field_update_instance($this->instance);
+    $display->setContent($this->field['field_name'], $display_settings);
+
     $formatter_setting_2 = $this->randomName();
-    $this->instance_2['display'] = array(
-      'full' => array(
-        'label' => 'above',
-        'type' => 'field_test_default',
-        'settings' => array(
-          'test_formatter_setting' => $formatter_setting_2,
-        )
+    $display_settings_2 = array(
+      'label' => 'above',
+      'type' => 'field_test_default',
+      'settings' => array(
+        'test_formatter_setting' => $formatter_setting_2,
       ),
     );
-    field_update_instance($this->instance_2);
+    $display->setContent($this->field_2['field_name'], $display_settings_2);
+
     // View all fields.
-    field_attach_prepare_view($entity_type, array($entity->ftid => $entity), 'full');
-    $entity->content = field_attach_view($entity_type, $entity, 'full');
+    field_attach_prepare_view($entity_type, array($entity->ftid => $entity), $displays);
+    $entity->content = field_attach_view($entity_type, $entity, $display);
     $output = drupal_render($entity->content);
     $this->content = $output;
     $this->assertRaw($this->instance['label'], "First field's label is displayed.");
@@ -78,8 +79,8 @@ function testFieldAttachView() {
       $this->assertRaw("$formatter_setting_2|{$value['value']}", "Value $delta is displayed, formatter settings are applied.");
     }
     // View single field (the second field).
-    field_attach_prepare_view($entity_type, array($entity->ftid => $entity), 'full', $langcode, $options);
-    $entity->content = field_attach_view($entity_type, $entity, 'full', $langcode, $options);
+    field_attach_prepare_view($entity_type, array($entity->ftid => $entity), $displays, $langcode, $options);
+    $entity->content = field_attach_view($entity_type, $entity, $display, $langcode, $options);
     $output = drupal_render($entity->content);
     $this->content = $output;
     $this->assertNoRaw($this->instance['label'], "First field's label is not displayed.");
@@ -95,25 +96,19 @@ function testFieldAttachView() {
 
     // Label hidden.
     $entity = clone($entity_init);
-    $this->instance['display']['full']['label'] = 'hidden';
-    field_update_instance($this->instance);
-    field_attach_prepare_view($entity_type, array($entity->ftid => $entity), 'full');
-    $entity->content = field_attach_view($entity_type, $entity, 'full');
+    $display_settings['label'] = 'hidden';
+    $display->setContent($this->field['field_name'], $display_settings);
+    field_attach_prepare_view($entity_type, array($entity->ftid => $entity), $displays);
+    $entity->content = field_attach_view($entity_type, $entity, $display);
     $output = drupal_render($entity->content);
     $this->content = $output;
     $this->assertNoRaw($this->instance['label'], "Hidden label: label is not displayed.");
 
     // Field hidden.
     $entity = clone($entity_init);
-    $this->instance['display'] = array(
-      'full' => array(
-        'label' => 'above',
-        'type' => 'hidden',
-      ),
-    );
-    field_update_instance($this->instance);
-    field_attach_prepare_view($entity_type, array($entity->ftid => $entity), 'full');
-    $entity->content = field_attach_view($entity_type, $entity, 'full');
+    $display->deleteContent($this->field['field_name']);
+    field_attach_prepare_view($entity_type, array($entity->ftid => $entity), $displays);
+    $entity->content = field_attach_view($entity_type, $entity, $display);
     $output = drupal_render($entity->content);
     $this->content = $output;
     $this->assertNoRaw($this->instance['label'], "Hidden field: label is not displayed.");
@@ -124,45 +119,40 @@ function testFieldAttachView() {
     // Multiple formatter.
     $entity = clone($entity_init);
     $formatter_setting = $this->randomName();
-    $this->instance['display'] = array(
-      'full' => array(
-        'label' => 'above',
-        'type' => 'field_test_multiple',
-        'settings' => array(
-          'test_formatter_setting_multiple' => $formatter_setting,
-        )
+    $display_settings = array(
+      'label' => 'above',
+      'type' => 'field_test_multiple',
+      'settings' => array(
+        'test_formatter_setting_multiple' => $formatter_setting,
       ),
     );
-    field_update_instance($this->instance);
-    field_attach_prepare_view($entity_type, array($entity->ftid => $entity), 'full');
-    $entity->content = field_attach_view($entity_type, $entity, 'full');
+    $display->setContent($this->field['field_name'], $display_settings);
+    field_attach_prepare_view($entity_type, array($entity->ftid => $entity), $displays);
+    $entity->content = field_attach_view($entity_type, $entity, $display);
     $output = drupal_render($entity->content);
-    $display = $formatter_setting;
+    $expected_output = $formatter_setting;
     foreach ($values as $delta => $value) {
-      $display .= "|$delta:{$value['value']}";
+      $expected_output .= "|$delta:{$value['value']}";
     }
     $this->content = $output;
-    $this->assertRaw($display, "Multiple formatter: all values are displayed, formatter settings are applied.");
+    $this->assertRaw($expected_output, "Multiple formatter: all values are displayed, formatter settings are applied.");
 
     // Test a formatter that uses hook_field_formatter_prepare_view().
     $entity = clone($entity_init);
     $formatter_setting = $this->randomName();
-    $this->instance['display'] = array(
-      'full' => array(
-        'label' => 'above',
-        'type' => 'field_test_with_prepare_view',
-        'settings' => array(
-          'test_formatter_setting_additional' => $formatter_setting,
-        )
+    $display_settings = array(
+      'label' => 'above',
+      'type' => 'field_test_with_prepare_view',
+      'settings' => array(
+        'test_formatter_setting_additional' => $formatter_setting,
       ),
     );
-    field_update_instance($this->instance);
-    field_attach_prepare_view($entity_type, array($entity->ftid => $entity), 'full');
-    $entity->content = field_attach_view($entity_type, $entity, 'full');
+    $display->setContent($this->field['field_name'], $display_settings);
+    field_attach_prepare_view($entity_type, array($entity->ftid => $entity), $displays);
+    $entity->content = field_attach_view($entity_type, $entity, $display);
     $output = drupal_render($entity->content);
     $this->content = $output;
     foreach ($values as $delta => $value) {
-      $this->content = $output;
       $expected = $formatter_setting . '|' . $value['value'] . '|' . ($value['value'] + 1);
       $this->assertRaw($expected, "Value $delta is displayed, formatter settings are applied.");
     }
@@ -190,9 +180,9 @@ function testFieldAttachPrepareViewMultiple() {
     $entity_type = 'test_entity';
     $langcode = LANGUAGE_NOT_SPECIFIED;
 
+    $display = entity_get_display('test_entity', 'test_bundle', 'full');
     // Set the instance to be hidden.
-    $this->instance['display']['full']['type'] = 'hidden';
-    field_update_instance($this->instance);
+    $display->deleteContent($this->field['field_name']);
 
     // Set up a second instance on another bundle, with a formatter that uses
     // hook_field_formatter_prepare_view().
@@ -200,13 +190,17 @@ function testFieldAttachPrepareViewMultiple() {
     $formatter_setting = $this->randomName();
     $this->instance2 = $this->instance;
     $this->instance2['bundle'] = 'test_bundle_2';
-    $this->instance2['display']['full'] = array(
+    field_create_instance($this->instance2);
+
+    $display_2 = entity_get_display('test_entity', 'test_bundle_2', 'full');
+    $display_2->setContent($this->field['field_name'], array(
       'type' => 'field_test_with_prepare_view',
       'settings' => array(
         'test_formatter_setting_additional' => $formatter_setting,
-      )
-    );
-    field_create_instance($this->instance2);
+      ),
+    ));
+
+    $displays = array('test_bundle' => $display, 'test_bundle_2' => $display_2);
 
     // Create one entity in each bundle.
     $entity1_init = field_test_create_entity(1, 1, 'test_bundle');
@@ -220,14 +214,16 @@ function testFieldAttachPrepareViewMultiple() {
     // Run prepare_view, and check that the entities come out as expected.
     $entity1 = clone($entity1_init);
     $entity2 = clone($entity2_init);
-    field_attach_prepare_view($entity_type, array($entity1->ftid => $entity1, $entity2->ftid => $entity2), 'full');
+    $entities = array($entity1->ftid => $entity1, $entity2->ftid => $entity2);
+    field_attach_prepare_view($entity_type, $entities, $displays);
     $this->assertFalse(isset($entity1->{$this->field_name}[$langcode][0]['additional_formatter_value']), 'Entity 1 did not run through the prepare_view hook.');
     $this->assertTrue(isset($entity2->{$this->field_name}[$langcode][0]['additional_formatter_value']), 'Entity 2 ran through the prepare_view hook.');
 
     // Same thing, reversed order.
     $entity1 = clone($entity1_init);
     $entity2 = clone($entity2_init);
-    field_attach_prepare_view($entity_type, array($entity2->ftid => $entity2, $entity1->ftid => $entity1), 'full');
+    $entities = array($entity1->ftid => $entity1, $entity2->ftid => $entity2);
+    field_attach_prepare_view($entity_type, $entities, $displays);
     $this->assertFalse(isset($entity1->{$this->field_name}[$langcode][0]['additional_formatter_value']), 'Entity 1 did not run through the prepare_view hook.');
     $this->assertTrue(isset($entity2->{$this->field_name}[$langcode][0]['additional_formatter_value']), 'Entity 2 ran through the prepare_view hook.');
   }
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php
index cfc1718..07a9846 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php
@@ -175,8 +175,8 @@ function testInstancePrepare() {
     $data['settings'] = array();
     $data['widget']['settings'] = 'unavailable_widget';
     $data['widget']['settings'] = array();
-    $data['display']['default']['type'] = 'unavailable_formatter';
-    $data['display']['default']['settings'] = array();
+    //$data['display']['default']['type'] = 'unavailable_formatter';
+    //$data['display']['default']['settings'] = array();
     db_update('field_config_instance')
       ->fields(array('data' => serialize($data)))
       ->condition('field_name', $instance_definition['field_name'])
@@ -199,10 +199,10 @@ function testInstancePrepare() {
     $this->assertIdentical($widget->getSettings(), $widget_type['settings'] , 'All expected widget settings are present.');
 
     // Check that display settings are set for the 'default' mode.
-    $formatter = $instance->getFormatter('default');
-    $this->assertIdentical($formatter->getPluginId(), $field_type['default_formatter'], "Formatter is set for the 'default' view mode");
-    $formatter_type = $formatter->getDefinition();
-    $this->assertIdentical($formatter->getSettings(), $formatter_type['settings'] , "Formatter settings are set for the 'default' view mode");
+    //$formatter = $instance->getFormatter('default');
+    //$this->assertIdentical($formatter->getPluginId(), $field_type['default_formatter'], "Formatter is set for the 'default' view mode");
+    //$formatter_type = $formatter->getDefinition();
+    //$this->assertIdentical($formatter->getSettings(), $formatter_type['settings'] , "Formatter settings are set for the 'default' view mode");
 
   }
 
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php
index 84cee72..b83e2f3 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php
@@ -72,13 +72,13 @@ function testCreateFieldInstance() {
     $this->assertIdentical($record['data']['label'], $this->instance_definition['field_name'], 'Label defaults to field name.');
     $this->assertIdentical($record['data']['description'], '', 'Description defaults to empty string.');
     $this->assertIdentical($record['data']['widget']['type'], $field_type['default_widget'], 'Default widget has been written.');
-    $this->assertTrue(isset($record['data']['display']['default']), 'Display for "full" view_mode has been written.');
-    $this->assertIdentical($record['data']['display']['default']['type'], $field_type['default_formatter'], 'Default formatter for "full" view_mode has been written.');
+    //$this->assertTrue(isset($record['data']['display']['default']), 'Display for "full" view_mode has been written.');
+    //$this->assertIdentical($record['data']['display']['default']['type'], $field_type['default_formatter'], 'Default formatter for "full" view_mode has been written.');
 
     // Check that default settings are set.
     $this->assertIdentical($record['data']['settings'], $field_type['instance_settings'] , 'Default instance settings have been written.');
     $this->assertIdentical($record['data']['widget']['settings'], $widget_type['settings'] , 'Default widget settings have been written.');
-    $this->assertIdentical($record['data']['display']['default']['settings'], $formatter_type['settings'], 'Default formatter settings for "full" view_mode have been written.');
+    //$this->assertIdentical($record['data']['display']['default']['settings'], $formatter_type['settings'], 'Default formatter settings for "full" view_mode have been written.');
 
     // Guarantee that the field/bundle combination is unique.
     try {
@@ -161,8 +161,8 @@ function testUpdateFieldInstance() {
     $instance['settings']['test_instance_setting'] = $this->randomName();
     $instance['widget']['settings']['test_widget_setting'] =$this->randomName();
     $instance['widget']['weight']++;
-    $instance['display']['default']['settings']['test_formatter_setting'] = $this->randomName();
-    $instance['display']['default']['weight']++;
+    //$instance['display']['default']['settings']['test_formatter_setting'] = $this->randomName();
+    //$instance['display']['default']['weight']++;
     field_update_instance($instance);
 
     $instance_new = field_read_instance('test_entity', $this->instance_definition['field_name'], $this->instance_definition['bundle']);
@@ -171,35 +171,35 @@ function testUpdateFieldInstance() {
     $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');
-    $this->assertEqual($instance['display']['default']['settings']['test_formatter_setting'], $instance_new['display']['default']['settings']['test_formatter_setting'], 'Formatter setting change is saved');
-    $this->assertEqual($instance['display']['default']['weight'], $instance_new['display']['default']['weight'], 'Widget weight change is saved');
+    //$this->assertEqual($instance['display']['default']['settings']['test_formatter_setting'], $instance_new['display']['default']['settings']['test_formatter_setting'], 'Formatter setting change is saved');
+    //$this->assertEqual($instance['display']['default']['weight'], $instance_new['display']['default']['weight'], 'Widget weight change is saved');
 
     // Check that changing widget and formatter types 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';
-    $instance['display']['default']['type'] = 'field_test_multiple';
+    //$instance['display']['default']['type'] = 'field_test_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.');
-    $this->assertEqual($instance['display']['default']['type'], $instance_new['display']['default']['type'] , 'Formatter type change is saved.');
-    $info = field_info_formatter_types($instance_new['display']['default']['type']);
-    $settings = $info['settings'];
-    $this->assertIdentical($settings, array_intersect_key($instance_new['display']['default']['settings'], $settings) , 'Changing formatter type updates default settings.');
+    //$this->assertEqual($instance['display']['default']['type'], $instance_new['display']['default']['type'] , 'Formatter type change is saved.');
+    //$info = field_info_formatter_types($instance_new['display']['default']['type']);
+    //$settings = $info['settings'];
+    //$this->assertIdentical($settings, array_intersect_key($instance_new['display']['default']['settings'], $settings) , 'Changing formatter type updates default settings.');
 
     // Check that adding a new view mode is saved and gets default settings.
-    $instance = field_read_instance('test_entity', $this->instance_definition['field_name'], $this->instance_definition['bundle']);
-    $instance['display']['teaser'] = array();
-    field_update_instance($instance);
-
-    $instance_new = field_read_instance('test_entity', $this->instance_definition['field_name'], $this->instance_definition['bundle']);
-    $this->assertTrue(isset($instance_new['display']['teaser']), 'Display for the new view_mode has been written.');
-    $this->assertIdentical($instance_new['display']['teaser']['type'], $field_type['default_formatter'], 'Default formatter for the new view_mode has been written.');
-    $info = field_info_formatter_types($instance_new['display']['teaser']['type']);
-    $settings = $info['settings'];
-    $this->assertIdentical($settings, $instance_new['display']['teaser']['settings'] , 'Default formatter settings for the new view_mode have been written.');
+    //$instance = field_read_instance('test_entity', $this->instance_definition['field_name'], $this->instance_definition['bundle']);
+    //$instance['display']['teaser'] = array();
+    //field_update_instance($instance);
+
+    //$instance_new = field_read_instance('test_entity', $this->instance_definition['field_name'], $this->instance_definition['bundle']);
+    //$this->assertTrue(isset($instance_new['display']['teaser']), 'Display for the new view_mode has been written.');
+    //$this->assertIdentical($instance_new['display']['teaser']['type'], $field_type['default_formatter'], 'Default formatter for the new view_mode has been written.');
+    //$info = field_info_formatter_types($instance_new['display']['teaser']['type']);
+    //$settings = $info['settings'];
+    //$this->assertIdentical($settings, $instance_new['display']['teaser']['settings'] , 'Default formatter settings for the new view_mode have been written.');
 
     // TODO: test failures.
   }
diff --git a/core/modules/field/modules/email/lib/Drupal/email/Tests/EmailFieldTest.php b/core/modules/field/modules/email/lib/Drupal/email/Tests/EmailFieldTest.php
index c88f563..c512637 100644
--- a/core/modules/field/modules/email/lib/Drupal/email/Tests/EmailFieldTest.php
+++ b/core/modules/field/modules/email/lib/Drupal/email/Tests/EmailFieldTest.php
@@ -60,13 +60,14 @@ function testEmailField() {
           'placeholder' => 'example@example.com',
         ),
       ),
-      'display' => array(
-        'full' => array(
-          'type' => 'email_mailto',
-        ),
-      ),
     );
     field_create_instance($this->instance);
+    // Create a display for the full view mode.
+    $display = entity_get_display('test_entity', 'test_bundle', 'full');
+    $display->setContent($this->field['field_name'], array(
+      'type' => 'email_mailto',
+    ));
+    $display->save();
 
     // Display creation form.
     $this->drupalGet('test-entity/add/test_bundle');
@@ -87,7 +88,8 @@ function testEmailField() {
 
     // Verify that a mailto link is displayed.
     $entity = field_test_entity_test_load($id);
-    $entity->content = field_attach_view('test_entity', $entity, 'full');
+    $display = entity_get_display($entity->entityType(), $entity->bundle(), 'full');
+    $entity->content = field_attach_view('test_entity', $entity, $display);
     $this->drupalSetContent(drupal_render($entity->content));
     $this->assertLinkByHref('mailto:test@example.com');
   }
diff --git a/core/modules/field/modules/link/lib/Drupal/link/Tests/LinkFieldTest.php b/core/modules/field/modules/link/lib/Drupal/link/Tests/LinkFieldTest.php
index a3366d2..3bba223 100644
--- a/core/modules/field/modules/link/lib/Drupal/link/Tests/LinkFieldTest.php
+++ b/core/modules/field/modules/link/lib/Drupal/link/Tests/LinkFieldTest.php
@@ -62,13 +62,14 @@ function testURLValidation() {
           'placeholder_url' => 'http://example.com',
         ),
       ),
-      'display' => array(
-        'full' => array(
-          'type' => 'link',
-        ),
-      ),
     );
     field_create_instance($this->instance);
+    $display = entity_get_display('test_entity', 'test_bundle', 'full');
+    $display->setContent($this->field['field_name'], array(
+      'type' => 'link',
+    ));
+    $display->save();
+
     $langcode = LANGUAGE_NOT_SPECIFIED;
 
     // Display creation form.
@@ -130,14 +131,15 @@ function testLinkTitle() {
           'placeholder_title' => 'Enter a title for this link',
         ),
       ),
-      'display' => array(
-        'full' => array(
-          'type' => 'link',
-          'label' => 'hidden',
-        ),
-      ),
     );
     field_create_instance($this->instance);
+    $display = entity_get_display('test_entity', 'test_bundle', 'full');
+    $display->setContent($this->field['field_name'], array(
+      'type' => 'link',
+      'label' => 'hidden',
+    ));
+    $display->save();
+
     $langcode = LANGUAGE_NOT_SPECIFIED;
 
     // Verify that the title field works according to the field setting.
@@ -235,14 +237,18 @@ function testLinkFormatter() {
       'widget' => array(
         'type' => 'link_default',
       ),
-      'display' => array(
-        'full' => array(
-          'type' => 'link',
-          'label' => 'hidden',
-        ),
+    );
+    $display_settings = array(
+      'full' => array(
+        'type' => 'link',
+        'label' => 'hidden',
       ),
     );
     field_create_instance($this->instance);
+    $display = entity_get_display('test_entity', 'test_bundle', 'full');
+    $display->setContent($this->field['field_name'], $display_settings['full']);
+    $display->save();
+
     $langcode = LANGUAGE_NOT_SPECIFIED;
 
     // Create an entity with two link field values:
@@ -288,12 +294,14 @@ function testLinkFormatter() {
       foreach ($values as $new_value) {
         // Update the field formatter settings.
         if (!is_array($new_value)) {
-          $this->instance['display']['full']['settings'] = array($setting => $new_value);
+          $display_settings['full']['settings'] = array($setting => $new_value);
         }
         else {
-          $this->instance['display']['full']['settings'] = $new_value;
+          $display_settings['full']['settings'] = $new_value;
         }
-        field_update_instance($this->instance);
+        $display = entity_get_display('test_entity', 'test_bundle', 'full');
+        $display->setContent($this->field['field_name'], $display_settings['full']);
+        $display->save();
 
         $this->renderTestEntity($id);
         switch ($setting) {
@@ -367,14 +375,18 @@ function testLinkSeparateFormatter() {
       'widget' => array(
         'type' => 'link_default',
       ),
-      'display' => array(
-        'full' => array(
-          'type' => 'link_separate',
-          'label' => 'hidden',
-        ),
+    );
+    $display_settings = array(
+      'full' => array(
+        'type' => 'link_separate',
+        'label' => 'hidden',
       ),
     );
     field_create_instance($this->instance);
+    $display = entity_get_display('test_entity', 'test_bundle', 'full');
+    $display->setContent($this->field['field_name'], $display_settings['full']);
+    $display->save();
+
     $langcode = LANGUAGE_NOT_SPECIFIED;
 
     // Create an entity with two link field values:
@@ -406,8 +418,10 @@ function testLinkSeparateFormatter() {
     foreach ($options as $setting => $values) {
       foreach ($values as $new_value) {
         // Update the field formatter settings.
-        $this->instance['display']['full']['settings'] = array($setting => $new_value);
-        field_update_instance($this->instance);
+        $display_settings['full']['settings'] = array($setting => $new_value);
+        $display = entity_get_display('test_entity', 'test_bundle', 'full');
+        $display->setContent($this->field['field_name'], $display_settings['full']);
+        $display->save();
 
         $this->renderTestEntity($id);
         switch ($setting) {
@@ -461,8 +475,9 @@ protected function renderTestEntity($id, $view_mode = 'full', $reset = TRUE) {
       entity_get_controller('test_entity')->resetCache(array($id));
     }
     $entity = field_test_entity_test_load($id);
-    field_attach_prepare_view('test_entity', array($entity->id() => $entity), $view_mode);
-    $entity->content = field_attach_view('test_entity', $entity, $view_mode);
+    $display = entity_get_display($entity->entityType(), $entity->bundle(), $view_mode);
+    field_attach_prepare_view('test_entity', array($entity->id() => $entity), array($entity->bundle() => $display));
+    $entity->content = field_attach_view('test_entity', $entity, $display);
 
     $output = drupal_render($entity->content);
     $this->drupalSetContent($output);
diff --git a/core/modules/field/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php b/core/modules/field/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php
index 7588942..626b47f 100644
--- a/core/modules/field/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php
+++ b/core/modules/field/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php
@@ -70,6 +70,14 @@ function testNumberDecimalField() {
       ),
     );
     field_create_instance($this->instance);
+    $display_settings = array(
+      'default' => array(
+        'type' => 'number_decimal',
+      ),
+    );
+    $display = entity_get_display('test_entity', 'test_bundle', 'default');
+    $display->setContent($this->field['field_name'], $display_settings['default']);
+    $display->save();
 
     // Display creation form.
     $this->drupalGet('test-entity/add/test_bundle');
diff --git a/core/modules/field/modules/options/lib/Drupal/options/Tests/OptionsWidgetsTest.php b/core/modules/field/modules/options/lib/Drupal/options/Tests/OptionsWidgetsTest.php
index d61eebb..6804b6a 100644
--- a/core/modules/field/modules/options/lib/Drupal/options/Tests/OptionsWidgetsTest.php
+++ b/core/modules/field/modules/options/lib/Drupal/options/Tests/OptionsWidgetsTest.php
@@ -489,9 +489,9 @@ function testOnOffCheckbox() {
       'entity_type' => 'node',
       'bundle' => 'page',
       'widget' => array(
-            'type' => 'options_onoff',
-            'module' => 'options',
-        ),
+        'type' => 'options_onoff',
+        'module' => 'options',
+      ),
     );
     field_create_instance($instance);
 
diff --git a/core/modules/field/modules/text/lib/Drupal/text/Tests/TextFieldTest.php b/core/modules/field/modules/text/lib/Drupal/text/Tests/TextFieldTest.php
index 8efc516..4621108 100644
--- a/core/modules/field/modules/text/lib/Drupal/text/Tests/TextFieldTest.php
+++ b/core/modules/field/modules/text/lib/Drupal/text/Tests/TextFieldTest.php
@@ -65,13 +65,17 @@ function testTextFieldValidation() {
       'widget' => array(
         'type' => 'text_textfield',
       ),
-      'display' => array(
-        'default' => array(
-          'type' => 'text_default',
-        ),
-      ),
     );
     field_create_instance($this->instance);
+    $display_settings = array(
+      'default' => array(
+        'type' => 'text_default',
+      ),
+    );
+    $display = entity_get_display('test_entity', 'test_bundle', 'default');
+    $display->setContent($this->field['field_name'], $display_settings['default']);
+    $display->save();
+
     // Test valid and invalid values with field_attach_validate().
     $entity = field_test_create_entity();
     $langcode = LANGUAGE_NOT_SPECIFIED;
@@ -118,13 +122,16 @@ function _testTextfieldWidgets($field_type, $widget_type) {
           'placeholder' => 'A placeholder on ' . $widget_type,
         ),
       ),
-      'display' => array(
-        'full' => array(
-          'type' => 'text_default',
-        ),
-      ),
     );
     field_create_instance($this->instance);
+    $display_settings = array(
+      'full' => array(
+        'type' => 'text_default',
+      ),
+    );
+    $display = entity_get_display('test_entity', 'test_bundle', 'full');
+    $display->setContent($this->field_name, $display_settings['full']);
+    $display->save();
     $langcode = LANGUAGE_NOT_SPECIFIED;
 
     // Display creation form.
@@ -145,7 +152,8 @@ function _testTextfieldWidgets($field_type, $widget_type) {
 
     // Display the entity.
     $entity = field_test_entity_test_load($id);
-    $entity->content = field_attach_view($entity_type, $entity, 'full');
+    $display = entity_get_display($entity->entityType(), $entity->bundle(), 'full');
+    $entity->content = field_attach_view($entity_type, $entity, $display);
     $this->content = drupal_render($entity->content);
     $this->assertText($value, 'Filtered tags are not displayed');
   }
@@ -178,13 +186,17 @@ function _testTextfieldWidgetsFormatted($field_type, $widget_type) {
       'widget' => array(
         'type' => $widget_type,
       ),
-      'display' => array(
-        'full' => array(
-          'type' => 'text_default',
-        ),
-      ),
     );
     field_create_instance($this->instance);
+    $display_settings = array(
+      'full' => array(
+        'type' => 'text_default',
+      ),
+    );
+    $display = entity_get_display('test_entity', 'test_bundle', 'full');
+    $display->setContent($this->field_name, $display_settings['full']);
+    $display->save();
+
     $langcode = LANGUAGE_NOT_SPECIFIED;
 
     // Disable all text formats besides the plain text fallback format.
@@ -214,7 +226,8 @@ function _testTextfieldWidgetsFormatted($field_type, $widget_type) {
 
     // Display the entity.
     $entity = field_test_entity_test_load($id);
-    $entity->content = field_attach_view($entity_type, $entity, 'full');
+    $display = entity_get_display($entity->entityType(), $entity->bundle(), 'full');
+    $entity->content = field_attach_view($entity_type, $entity, $display);
     $this->content = drupal_render($entity->content);
     $this->assertNoRaw($value, 'HTML tags are not displayed.');
     $this->assertRaw(check_plain($value), 'Escaped HTML is displayed correctly.');
@@ -254,7 +267,8 @@ function _testTextfieldWidgetsFormatted($field_type, $widget_type) {
     // Display the entity.
     entity_get_controller('test_entity')->resetCache(array($id));
     $entity = field_test_entity_test_load($id);
-    $entity->content = field_attach_view($entity_type, $entity, 'full');
+    $display = entity_get_display($entity->entityType(), $entity->bundle(), 'full');
+    $entity->content = field_attach_view($entity_type, $entity, $display);
     $this->content = drupal_render($entity->content);
     $this->assertRaw($value, 'Value is displayed unfiltered');
   }
diff --git a/core/modules/field_ui/field_ui.admin.inc b/core/modules/field_ui/field_ui.admin.inc
index d919eed..490c0c5 100644
--- a/core/modules/field_ui/field_ui.admin.inc
+++ b/core/modules/field_ui/field_ui.admin.inc
@@ -374,51 +374,6 @@ function field_ui_display_overview($entity_type, $bundle, $view_mode) {
 }
 
 /**
- * Populates display settings for a new view mode from the default view mode.
- *
- * When an administrator decides to use custom display settings for a view mode,
- * that view mode needs to be initialized with the display settings for the
- * 'default' view mode, which it was previously using. This helper function
- * adds the new custom display settings to this bundle's instances, and saves
- * them. It also modifies the passed-in $settings array, which the caller can
- * then save using field_bundle_settings().
- *
- * @param $entity_type
- *   The bundle's entity type.
- * @param $bundle
- *   The bundle whose view mode is being customized.
- * @param $view_mode
- *   The view mode that the administrator has set to use custom settings.
- * @param $settings
- *   An associative array of bundle settings, as expected by
- *   field_bundle_settings().
- *
- * @see Drupal\field_ui\DisplayOverview::submit().
- * @see field_bundle_settings()
- */
-function _field_ui_add_default_view_mode_settings($entity_type, $bundle, $view_mode, &$settings) {
-  // Update display settings for field instances.
-  $instances = field_read_instances(array('entity_type' => $entity_type, 'bundle' => $bundle));
-  foreach ($instances as $instance) {
-    // If this field instance has display settings defined for this view mode,
-    // respect those settings.
-    if (!isset($instance['display'][$view_mode])) {
-      // The instance doesn't specify anything for this view mode, so use the
-      // default display settings.
-      $instance['display'][$view_mode] = $instance['display']['default'];
-      field_update_instance($instance);
-    }
-  }
-
-  // Update display settings for 'extra fields'.
-  foreach (array_keys($settings['extra_fields']['display']) as $name) {
-    if (!isset($settings['extra_fields']['display'][$name][$view_mode])) {
-      $settings['extra_fields']['display'][$name][$view_mode] = $settings['extra_fields']['display'][$name]['default'];
-    }
-  }
-}
-
-/**
  * Returns an array of field_type options.
  */
 function field_ui_field_type_options() {
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 6117de9..6e2e0fd 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php
@@ -49,6 +49,7 @@ public function form(array $form, array &$form_state) {
     $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);
 
     $form_state += array(
       'formatter_settings_edit' => NULL,
@@ -94,24 +95,14 @@ public function form(array $form, array &$form_state) {
       'hidden' => t('<Hidden>'),
     );
     $extra_visibility_options = array(
-      'content' => t('Visible'),
+      'visible' => t('Visible'),
       'hidden' => t('Hidden'),
     );
 
     // Field rows.
     foreach ($instances as $name => $instance) {
-      $field = field_info_field($instance['field_name']);
-
-      if (isset($instance['display'][$this->view_mode])) {
-        $display = $instance['display'][$this->view_mode];
-      }
-      else {
-        $display = array(
-          'type' => 'hidden',
-          'label' => 'above',
-          'weight' => 0,
-        );
-      }
+      $field = field_info_field($name);
+      $display_settings = $entity_display->getContent($name);
 
       $table[$name] = array(
         '#attributes' => array('class' => array('draggable', 'tabledrag-leaf')),
@@ -128,7 +119,7 @@ public function form(array $form, array &$form_state) {
           '#type' => 'textfield',
           '#title' => t('Weight for @title', array('@title' => $instance['label'])),
           '#title_display' => 'invisible',
-          '#default_value' => $display['weight'],
+          '#default_value' => $display_settings ? $display_settings['weight'] : '0',
           '#size' => 3,
           '#attributes' => array('class' => array('field-weight')),
         ),
@@ -153,7 +144,7 @@ public function form(array $form, array &$form_state) {
           '#title' => t('Label display for @title', array('@title' => $instance['label'])),
           '#title_display' => 'invisible',
           '#options' => $field_label_options,
-          '#default_value' => $display['label'],
+          '#default_value' => $display_settings ? $display_settings['label'] : 'above',
         ),
       );
 
@@ -165,7 +156,7 @@ public function form(array $form, array &$form_state) {
           '#title' => t('Formatter for @title', array('@title' => $instance['label'])),
           '#title_display' => 'invisible',
           '#options' => $formatter_options,
-          '#default_value' => $display['type'],
+          '#default_value' => $display_settings ? $display_settings['type'] : 'hidden',
           '#parents' => array('fields', $name, 'type'),
           '#attributes' => array('class' => array('field-formatter-type')),
         ),
@@ -175,12 +166,19 @@ public function form(array $form, array &$form_state) {
       // Check the currently selected formatter, and merge persisted values for
       // formatter settings.
       if (isset($form_state['values']['fields'][$name]['type'])) {
-        $display['type'] = $form_state['values']['fields'][$name]['type'];
+        $display_settings['type'] = $form_state['values']['fields'][$name]['type'];
       }
       if (isset($form_state['formatter_settings'][$name])) {
-        $display['settings'] = $form_state['formatter_settings'][$name];
+        $display_settings['settings'] = $form_state['formatter_settings'][$name];
+      }
+
+      // Get the corresponding formatter object.
+      if ($display_settings && $display_settings['type'] != 'hidden') {
+        $formatter = $instance->getFormatter($display_settings, $this->view_mode);
+      }
+      else {
+        $formatter = NULL;
       }
-      $formatter = $instance->getFormatter($display);
 
       // Base button element for the various formatter settings actions.
       $base_button = array(
@@ -287,7 +285,8 @@ public function form(array $form, array &$form_state) {
 
     // Non-field elements.
     foreach ($extra_fields as $name => $extra_field) {
-      $display = $extra_field['display'][$this->view_mode];
+      $display_settings = $entity_display->getContent($name);
+
       $table[$name] = array(
         '#attributes' => array('class' => array('draggable', 'tabledrag-leaf')),
         '#row_type' => 'extra_field',
@@ -300,7 +299,7 @@ public function form(array $form, array &$form_state) {
           '#type' => 'textfield',
           '#title' => t('Weight for @title', array('@title' => $extra_field['label'])),
           '#title_display' => 'invisible',
-          '#default_value' => $display['weight'],
+          '#default_value' => $display_settings ? $display_settings['weight'] : 0,
           '#size' => 3,
           '#attributes' => array('class' => array('field-weight')),
         ),
@@ -329,7 +328,7 @@ public function form(array $form, array &$form_state) {
             '#title' => t('Visibility for @title', array('@title' => $extra_field['label'])),
             '#title_display' => 'invisible',
             '#options' => $extra_visibility_options,
-            '#default_value' => $display['visible'] ? 'content' : 'hidden',
+            '#default_value' => $display_settings ? 'content' : 'hidden',
             '#parents' => array('fields', $name, 'type'),
             '#attributes' => array('class' => array('field-formatter-type')),
           ),
@@ -418,73 +417,84 @@ public function form(array $form, array &$form_state) {
    */
   public function submit(array $form, array &$form_state) {
     $form_values = $form_state['values'];
+    $entity_display = entity_get_display($this->entity_type, $this->bundle, $this->view_mode);
 
-    // Save data for 'regular' fields.
+    $display_content = $entity_display->content;
+    $entity_display->clearContent();
+
+    // Collect data for 'regular' fields.
     foreach ($form['#fields'] as $field_name) {
       // Retrieve the stored instance settings to merge with the incoming
       // values.
-      $instance = field_read_instance($this->entity_type, $field_name, $this->bundle);
       $values = $form_values['fields'][$field_name];
-      // Get formatter settings. They lie either directly in submitted form
-      // values (if the whole form was submitted while some formatter
-      // settings were being edited), or have been persisted in
-      // $form_state.
-      $settings = array();
-      if (isset($values['settings_edit_form']['settings'])) {
-        $settings = $values['settings_edit_form']['settings'];
-      }
-      elseif (isset($form_state['formatter_settings'][$field_name])) {
-        $settings = $form_state['formatter_settings'][$field_name];
-      }
-      elseif (isset($instance['display'][$this->view_mode]['settings'])) {
-        $settings = $instance['display'][$this->view_mode]['settings'];
-      }
 
-      // Only save settings actually used by the selected formatter.
-      $default_settings = field_info_formatter_settings($values['type']);
-      $settings = array_intersect_key($settings, $default_settings);
+      if ($values['type'] !== 'hidden') {
+        // Get formatter settings. They lie either directly in submitted form
+        // values (if the whole form was submitted while some formatter
+        // settings were being edited), or have been persisted in $form_state.
+        $settings = array();
+        if (isset($values['settings_edit_form']['settings'])) {
+          $settings = $values['settings_edit_form']['settings'];
+        }
+        elseif (isset($form_state['formatter_settings'][$field_name])) {
+          $settings = $form_state['formatter_settings'][$field_name];
+        }
+        elseif (isset($display_content[$field_name])) {
+          $settings = $display_content[$field_name]['settings'];
+        }
+
+        // Only save settings actually used by the selected formatter.
+        $default_settings = field_info_formatter_settings($values['type']);
+        $settings = array_intersect_key($settings, $default_settings);
 
-      $instance['display'][$this->view_mode] = array(
-        'label' => $values['label'],
-        'type' => $values['type'],
-        'weight' => $values['weight'],
-        'settings' => $settings,
-      );
-      field_update_instance($instance);
+        $entity_display->setContent($field_name, array(
+          'label' => $values['label'],
+          'type' => $values['type'],
+          'weight' => $values['weight'],
+          'settings' => $settings,
+        ));
+      }
     }
 
-    // Get current bundle settings.
-    $bundle_settings = field_bundle_settings($this->entity_type, $this->bundle);
-
-    // Save data for 'extra' fields.
+    // Collect data for 'extra' fields.
     foreach ($form['#extra'] as $name) {
-      $bundle_settings['extra_fields']['display'][$name][$this->view_mode] = array(
-        'weight' => $form_values['fields'][$name]['weight'],
-        'visible' => $form_values['fields'][$name]['type'] == 'content',
-      );
+      if ($form_values['fields'][$name]['type'] !== 'hidden') {
+        $entity_display->setContent($name, array(
+          'weight' => $form_values['fields'][$name]['weight'],
+        ));
+      }
     }
 
-    // Save view modes data.
+    // Save the display.
+    $entity_display->save();
+
+    // Handle the 'view modes' checkboxes if present.
     if ($this->view_mode == 'default' && !empty($form_values['view_modes_custom'])) {
       $entity_info = entity_get_info($this->entity_type);
+      $bundle_settings = field_bundle_settings($this->entity_type, $this->bundle);
+      $view_mode_settings = field_view_mode_settings($this->entity_type, $this->bundle);
+
       foreach ($form_values['view_modes_custom'] as $view_mode_name => $value) {
-        // Display a message for each view mode newly configured to use custom
-        // settings.
-        $view_mode_settings = field_view_mode_settings($this->entity_type, $this->bundle);
         if (!empty($value) && empty($view_mode_settings[$view_mode_name]['custom_settings'])) {
+          // If no display exists for the newly enabled view mode, initialize
+          // it with those from the 'default' view mode, which were used so
+          // far.
+          $display = entity_get_display($this->entity_type, $this->bundle, $view_mode_name);
+          if ($display->isNew()) {
+            $display->content = entity_get_display($this->entity_type, $this->bundle, 'default')->content;
+            $display->save();
+          }
+
           $view_mode_label = $entity_info['view_modes'][$view_mode_name]['label'];
           $path = field_ui_bundle_admin_path($this->entity_type, $this->bundle) . "/display/$view_mode_name";
           drupal_set_message(t('The %view_mode mode now uses custom display settings. You might want to <a href="@url">configure them</a>.', array('%view_mode' => $view_mode_label, '@url' => url($path))));
-          // Initialize the newly customized view mode with the display settings
-          // from the default view mode.
-          _field_ui_add_default_view_mode_settings($this->entity_type, $this->bundle, $view_mode_name, $bundle_settings);
         }
         $bundle_settings['view_modes'][$view_mode_name]['custom_settings'] = !empty($value);
       }
-    }
 
-    // Save updated bundle settings.
-    field_bundle_settings($this->entity_type, $this->bundle, $bundle_settings);
+      // Save updated bundle settings.
+      field_bundle_settings($this->entity_type, $this->bundle, $bundle_settings);
+    }
 
     drupal_set_message(t('Your settings have been saved.'));
   }
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 177e3fd..0bcac74 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php
@@ -586,6 +586,13 @@ public function submit(array $form, array &$form_state) {
         field_create_field($field);
         field_create_instance($instance);
 
+        // 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.
+        $display = entity_get_display($this->entity_type, $this->bundle, 'default');
+        $display->setContent($field['field_name']);
+        $display->save();
+
         $destinations[] = $this->adminPath. '/fields/' . $field['field_name'] . '/field-settings';
         $destinations[] = $this->adminPath . '/fields/' . $field['field_name'];
 
@@ -618,6 +625,14 @@ public function submit(array $form, array &$form_state) {
 
         try {
           field_create_instance($instance);
+
+          // 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.
+          $display = entity_get_display($this->entity_type, $this->bundle, 'default');
+          $display->setContent($field['field_name']);
+          $display->save();
+
           $destinations[] = $this->adminPath . '/fields/' . $instance['field_name'] . '/edit';
           // Store new field information for any additional submit handlers.
           $form_state['fields_added']['_add_existing_field'] = $instance['field_name'];
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php
index 8396c7f..d4cec87 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php
@@ -44,12 +44,12 @@ function testFormatterUI() {
     $this->fieldUIAddNewField($manage_fields, $edit);
 
     // Clear the test-side cache and get the saved field instance.
-    field_info_cache_clear();
-    $instance = field_info_instance('node', 'field_test', $this->type);
-    $format = $instance['display']['default']['type'];
+    $display = entity_get_display('node', $this->type, 'default');
+    $display_settings = $display->getContent('field_test');
+    $format = $display_settings['type'];
     $default_settings = field_info_formatter_settings($format);
     $setting_name = key($default_settings);
-    $setting_value = $instance['display']['default']['settings'][$setting_name];
+    $setting_value = $display_settings['settings'][$setting_name];
 
     // Display the "Manage display" screen and check that the expected formatter is
     // selected.
@@ -67,12 +67,12 @@ function testFormatterUI() {
     $this->assertFieldByName('fields[field_test][type]', $format, 'The expected formatter is selected.');
     $this->assertText("$setting_name: $setting_value", 'The expected summary is displayed.');
 
-    // Submit the form and check that the instance is updated.
+    // Submit the form and check that the display is updated.
     $this->drupalPost(NULL, array(), t('Save'));
-    field_info_cache_clear();
-    $instance = field_info_instance('node', 'field_test', $this->type);
-    $current_format = $instance['display']['default']['type'];
-    $current_setting_value = $instance['display']['default']['settings'][$setting_name];
+    $display = entity_get_display('node', $this->type, 'default');
+    $display_settings = $display->getContent('field_test');
+    $current_format = $display_settings['type'];
+    $current_setting_value = $display_settings['settings'][$setting_name];
     $this->assertEqual($current_format, $format, 'The formatter was updated.');
     $this->assertEqual($current_setting_value, $setting_value, 'The setting was updated.');
 
diff --git a/core/modules/forum/forum.install b/core/modules/forum/forum.install
index 56f8402..473e917 100644
--- a/core/modules/forum/forum.install
+++ b/core/modules/forum/forum.install
@@ -90,18 +90,22 @@ function forum_enable() {
       'widget' => array(
         'type' => 'options_select',
       ),
-      'display' => array(
-        'default' => array(
-          'type' => 'taxonomy_term_reference_link',
-          'weight' => 10,
-        ),
-        'teaser' => array(
-          'type' => 'taxonomy_term_reference_link',
-          'weight' => 10,
-        ),
-      ),
     );
     field_create_instance($instance);
+
+    // Assign display settings for the 'default' and 'teaser' view modes.
+    $display = entity_get_display('node', 'forum', 'default');
+    $display->setContent('taxonomy_forums', array(
+      'type' => 'taxonomy_term_reference_link',
+      'weight' => 10,
+    ));
+    $display->save();
+    $display = entity_get_display('node', 'forum', 'teaser');
+    $display->setContent('taxonomy_forums', array(
+      'type' => 'taxonomy_term_reference_link',
+      'weight' => 10,
+    ));
+    $display->save();
   }
 
   // Ensure the forum node type is available.
diff --git a/core/modules/image/image.module b/core/modules/image/image.module
index 221e07c..54022c5 100644
--- a/core/modules/image/image.module
+++ b/core/modules/image/image.module
@@ -334,21 +334,23 @@ function image_image_style_save($style) {
     // Loop through all fields searching for image fields.
     foreach ($instances as $instance) {
       if ($instance['widget']['module'] == 'image') {
-        $instance_changed = FALSE;
-        foreach ($instance['display'] as $view_mode => $display) {
+        $entity_info = entity_get_info($instance['entity_type']);
+        $view_modes = array('default') + array_keys($entity_info['view_modes']);
+        foreach ($view_modes as $view_mode) {
+          $display = entity_get_display($instance['entity_type'], $instance['bundle'], $view_mode);
+          $display_properties = $display->getContent($instance['field_name']);
+
           // Check if the formatter involves an image style.
-          if ($display['type'] == 'image' && $display['settings']['image_style'] == $style->getOriginalID()) {
+          if ($display_properties && $display_properties['type'] == 'image' && $display_properties['settings']['image_style'] == $style->getOriginalID()) {
             // Update display information for any instance using the image
             // style that was just deleted.
-            $instance['display'][$view_mode]['settings']['image_style'] = $style->id();
-            $instance_changed = TRUE;
+            $display_properties['settings']['image_style'] = $style->id();
+            $display->setContent($instance['field_name'], $display_properties);
+            $display->save();
           }
         }
         if ($instance['widget']['settings']['preview_image_style'] == $style->getOriginalID()) {
           $instance['widget']['settings']['preview_image_style'] = $style->id();
-          $instance_changed = TRUE;
-        }
-        if ($instance_changed) {
           field_update_instance($instance);
         }
       }
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageAdminStylesTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageAdminStylesTest.php
index 958610d..0fd137f 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageAdminStylesTest.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageAdminStylesTest.php
@@ -253,10 +253,12 @@ function testStyleReplacement() {
     // Create an image field that uses the new style.
     $field_name = strtolower($this->randomName(10));
     $this->createImageField($field_name, 'article');
-    $instance = field_info_instance('node', $field_name, 'article');
-    $instance['display']['default']['type'] = 'image';
-    $instance['display']['default']['settings']['image_style'] = $style_name;
-    field_update_instance($instance);
+    $display = entity_get_display('node', 'article', 'default');
+    $display->setContent($field_name, array(
+      'type' => 'image',
+      'settings' => array('image_style' => $style_name),
+    ));
+    $display->save();
 
     // Create a new node with an image attached.
     $test_image = current($this->drupalGetTestFiles('image'));
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php
index f7670fe..dbfa5a9 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php
@@ -69,7 +69,9 @@ function testDefaultImages() {
     );
     field_create_instance($instance2);
     $instance2 = field_info_instance('node', $field_name, 'page');
-
+    $display = entity_get_display('node', 'page', 'default');
+    $display->setContent($field['field_name']);
+    $display->save();
 
     // Confirm the defaults are present on the article field admin form.
     $this->drupalGet("admin/structure/types/manage/article/fields/$field_name");
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
index c07acf6..5d513cb 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
@@ -49,6 +49,7 @@ function testImageFieldFormattersPrivate() {
   function _testImageFieldFormatters($scheme) {
     $field_name = strtolower($this->randomName());
     $this->createImageField($field_name, 'article', array('uri_scheme' => $scheme));
+
     // Create a new node with an image attached.
     $test_image = current($this->drupalGetTestFiles('image'));
     $nid = $this->uploadNodeImage($test_image, $field_name, 'article');
@@ -65,10 +66,16 @@ function _testImageFieldFormatters($scheme) {
     $this->assertRaw($default_output, 'Default formatter displaying correctly on full node view.');
 
     // Test the image linked to file formatter.
-    $instance = field_info_instance('node', $field_name, 'article');
-    $instance['display']['default']['type'] = 'image';
-    $instance['display']['default']['settings']['image_link'] = 'file';
-    field_update_instance($instance);
+    $display_properties = array(
+      'default' => array(
+        'type' => 'image',
+        'settings' => array('image_link' => 'file'),
+      ),
+    );
+    $display = entity_get_display('node', $node->type, 'default');
+    $display->setContent($field_name, $display_properties['default']);
+    $display->save();
+
     $default_output = l(theme('image', $image_info), file_create_url($image_uri), array('html' => TRUE));
     $this->drupalGet('node/' . $nid);
     $this->assertRaw($default_output, 'Image linked to file formatter displaying correctly on full node view.');
@@ -91,16 +98,19 @@ function _testImageFieldFormatters($scheme) {
     }
 
     // Test the image linked to content formatter.
-    $instance['display']['default']['settings']['image_link'] = 'content';
-    field_update_instance($instance);
+    $display_properties['default']['settings']['image_link'] = 'content';
+    $display->setContent($field_name, $display_properties['default']);
+    $display->save();
     $default_output = l(theme('image', $image_info), 'node/' . $nid, array('html' => TRUE, 'attributes' => array('class' => 'active')));
     $this->drupalGet('node/' . $nid);
     $this->assertRaw($default_output, 'Image linked to content formatter displaying correctly on full node view.');
 
     // Test the image style 'thumbnail' formatter.
-    $instance['display']['default']['settings']['image_link'] = '';
-    $instance['display']['default']['settings']['image_style'] = 'thumbnail';
-    field_update_instance($instance);
+    $display_properties['default']['settings']['image_link'] = '';
+    $display_properties['default']['settings']['image_style'] = 'thumbnail';
+    $display->setContent($field_name, $display_properties['default']);
+    $display->save();
+
     // Ensure the derivative image is generated so we do not have to deal with
     // image style callback paths.
     $this->drupalGet(image_style_url('thumbnail', $image_uri));
@@ -264,6 +274,9 @@ function testImageFieldDefaultImage() {
       'files[field_settings_default_image]' => drupal_realpath($images[1]->uri),
     );
     $this->drupalPost('admin/structure/types/manage/article/fields/' . $private_field_name, $edit, t('Save settings'));
+    // Clear field info cache so the new default image is detected.
+    field_info_cache_clear();
+
     $private_field = field_info_field($private_field_name);
     $image = file_load($private_field['settings']['default_image']);
     $this->assertEqual('private', file_uri_scheme($image->uri), 'Default image uses private:// scheme.');
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php
index fc964ac..9db05b2 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php
@@ -93,7 +93,15 @@ function createImageField($name, $type_name, $field_settings = array(), $instanc
     );
     $instance['settings'] = array_merge($instance['settings'], $instance_settings);
     $instance['widget']['settings'] = array_merge($instance['widget']['settings'], $widget_settings);
-    return field_create_instance($instance);
+
+    $field_instance = field_create_instance($instance);
+
+    $display = entity_get_display('node', $type_name, 'default');
+    $display->setContent($field['field_name']);
+    $display->save();
+
+    return $field_instance;
+
   }
 
   /**
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeAccessFieldTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeAccessFieldTest.php
index 8dd2ab6..91833c6 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeAccessFieldTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeAccessFieldTest.php
@@ -45,6 +45,9 @@ public function setUp() {
       'bundle' => 'page',
     );
     $this->instance = field_create_instance($instance);
+    $display = entity_get_display('node', 'page', 'default');
+    $display->setContent($this->field_name);
+    $display->save();
   }
 
   /**
diff --git a/core/modules/node/lib/Drupal/node/Tests/SummaryLengthTest.php b/core/modules/node/lib/Drupal/node/Tests/SummaryLengthTest.php
index 4276146..e407853 100644
--- a/core/modules/node/lib/Drupal/node/Tests/SummaryLengthTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/SummaryLengthTest.php
@@ -46,9 +46,11 @@ function testSummaryLength() {
     $this->assertRaw($expected);
 
     // Change the teaser length for "Basic page" content type.
-    $instance = field_info_instance('node', 'body', $node->type);
-    $instance['display']['teaser']['settings']['trim_length'] = 200;
-    field_update_instance($instance);
+    $display = entity_get_display('node', $node->type, 'teaser');
+    $display_properties = $display->getContent('body');
+    $display_properties['settings']['trim_length'] = 200;
+    $display->setContent('body', $display_properties);
+    $display->save();
 
     // Render the node as a teaser again and check that the summary is now only
     // 200 characters in length and so does not include 'What is a Drupalism?'.
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index ea2b4ce..f4ae7ce 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -19,6 +19,7 @@
 use Drupal\node\Plugin\Core\Entity\Node;
 use Drupal\file\Plugin\Core\Entity\File;
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\field\Plugin\Core\Entity\EntityDisplay;
 
 /**
  * Denotes that the node is not published.
@@ -212,12 +213,16 @@ function node_entity_info(&$info) {
 }
 
 /**
- * Implements hook_field_display_ENTITY_TYPE_alter().
+ * Implements hook_entity_display_alter().
  */
-function node_field_display_node_alter(&$display, $context) {
+function node_entity_display_alter(EntityDisplay $display, $context) {
   // Hide field labels in search index.
-  if ($context['view_mode'] == 'search_index') {
-    $display['label'] = 'hidden';
+  if ($context['entity_type'] == 'node' && $context['view_mode'] == 'search_index') {
+    foreach ($display->content as $name => &$properties) {
+      if (isset($properties['label'])) {
+        $properties['label'] = 'hidden';
+      }
+    }
   }
 }
 
@@ -559,19 +564,24 @@ function node_add_body_field($type, $label = 'Body') {
       'label' => $label,
       'widget' => array('type' => 'text_textarea_with_summary'),
       'settings' => array('display_summary' => TRUE),
-      'display' => array(
-        'default' => array(
-          'label' => 'hidden',
-          'type' => 'text_default',
-        ),
-        'teaser' => array(
-          'label' => 'hidden',
-          'type' => 'text_summary_or_trimmed',
-        ),
-      ),
     );
     $instance = field_create_instance($instance);
+
+    // Assign display settings for the 'default' and 'teaser' view modes.
+    $display = entity_get_display('node', $type->type, 'default');
+    $display->setContent($field['field_name'], array(
+      'label' => 'hidden',
+      'type' => 'text_default',
+    ));
+    $display->save();
+    $display = entity_get_display('node', $type->type, 'teaser');
+    $display->setContent($field['field_name'], array(
+      'label' => 'hidden',
+      'type' => 'text_summary_or_trimmed',
+    ));
+    $display->save();
   }
+
   return $instance;
 }
 
diff --git a/core/modules/node/node.pages.inc b/core/modules/node/node.pages.inc
index 0a18ec1..c8101ab 100644
--- a/core/modules/node/node.pages.inc
+++ b/core/modules/node/node.pages.inc
@@ -144,8 +144,6 @@ function node_preview(Node $node) {
     }
 
     $node->changed = REQUEST_TIME;
-    $nodes = array($node->nid => $node);
-    field_attach_prepare_view('node', $nodes, 'full');
 
     // Display a preview of the node.
     if (!form_get_errors()) {
diff --git a/core/modules/node/node.tokens.inc b/core/modules/node/node.tokens.inc
index 2d783c9..9bba099 100644
--- a/core/modules/node/node.tokens.inc
+++ b/core/modules/node/node.tokens.inc
@@ -149,7 +149,19 @@ function node_tokens($type, $tokens, array $data = array(), array $options = arr
               // A summary was requested.
               if ($name == 'summary') {
                 // Generate an optionally trimmed summary of the body field.
-                $output = text_summary($output, $instance['settings']['text_processing'] ? $items[0]['format'] : NULL, $instance['display']['teaser']['settings']['trim_length']);
+                
+                // Get the 'trim_length' size used for the 'teaser' mode, if present, or
+                // use the default trim_length size.
+                $display_properties = entity_get_display('node', $node->type, 'teaser')->getContent('body');
+                if (isset($display_properties['settings']['trim_length'])) {
+                  $length = $display_properties['settings']['trim_length'];
+                }
+                else {
+                  $settings = field_info_formatter_settings('text_summary_or_trimmed');
+                  $length = $settings['trim_length'];
+                }
+
+                $output = text_summary($output, $instance['settings']['text_processing'] ? $items[0]['format'] : NULL, $length);
               }
             }
             $replacements[$original] = $output;
diff --git a/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php b/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php
index 69b0231..f583fe2 100644
--- a/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php
+++ b/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php
@@ -120,11 +120,6 @@ public function _testPictureFieldFormatters($scheme) {
     $nid = $this->uploadNodeImage($test_image, $field_name, 'article');
     $node = node_load($nid, TRUE);
 
-    // Use the picture formatter.
-    $instance = field_info_instance('node', $field_name, 'article');
-    $instance['display']['default']['type'] = 'picture';
-    $instance['display']['default']['module'] = 'picture';
-
     // Test that the default formatter is being used.
     $image_uri = file_load($node->{$field_name}[LANGUAGE_NOT_SPECIFIED][0]['fid'])->uri;
     $image_info = array(
@@ -136,11 +131,17 @@ public function _testPictureFieldFormatters($scheme) {
     $this->assertRaw($default_output, 'Default formatter displaying correctly on full node view.');
 
     // Use the picture formatter linked to file formatter.
-    $instance = field_info_instance('node', $field_name, 'article');
-    $instance['display']['default']['type'] = 'picture';
-    $instance['display']['default']['module'] = 'picture';
-    $instance['display']['default']['settings']['image_link'] = 'file';
-    field_update_instance($instance);
+    $display_properties = array(
+      'default' => array(
+        'type' => 'picture',
+        'module' => 'picture',
+        'settings' => array('image_link' => 'file'),
+      ),
+    );
+    $display = entity_get_display('node', 'article', 'default');
+    $display->setContent($field_name, $display_properties['default']);
+    $display->save();
+
     $default_output = l(theme('image', $image_info), file_create_url($image_uri), array('html' => TRUE));
     $this->drupalGet('node/' . $nid);
     $this->assertRaw($default_output, 'Image linked to file formatter displaying correctly on full node view.');
@@ -163,8 +164,10 @@ public function _testPictureFieldFormatters($scheme) {
     }
 
     // Use the picture formatter with a picture mapping.
-    $instance['display']['default']['settings']['picture_mapping'] = 'mapping_one';
-    field_update_instance($instance);
+    $display_properties['default']['settings']['picture_mapping'] = 'mapping_one';
+    $display->setContent($field_name, $display_properties['default']);
+    $display->save();
+
     // Output should contain all image styles and all breakpoints.
     $this->drupalGet('node/' . $nid);
     $this->assertRaw('/styles/thumbnail/');
@@ -175,9 +178,10 @@ public function _testPictureFieldFormatters($scheme) {
     $this->assertRaw('media="(min-width: 600px)"');
 
     // Test the fallback image style.
-    $instance['display']['default']['settings']['image_link'] = '';
-    $instance['display']['default']['settings']['fallback_image_style'] = 'large';
-    field_update_instance($instance);
+    $display_properties['default']['settings']['image_link'] = '';
+    $display_properties['default']['settings']['fallback_image_style'] = 'large';
+    $display->setContent($field_name, $display_properties['default']);
+    $display->save();
 
     $this->drupalGet(image_style_url('large', $image_uri));
     $image_info['uri'] = $image_uri;
diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/RdfaMarkupTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/RdfaMarkupTest.php
index db24097..ef3cd55 100644
--- a/core/modules/rdf/lib/Drupal/rdf/Tests/RdfaMarkupTest.php
+++ b/core/modules/rdf/lib/Drupal/rdf/Tests/RdfaMarkupTest.php
@@ -115,13 +115,13 @@ function testAttributesInMarkupFile() {
       'field_name' => $field_name,
       'entity_type' => 'node',
       'bundle' => $bundle_name,
-      'display' => array(
-        'teaser' => array(
-          'type' => 'file_default',
-        ),
-      ),
     );
     field_create_instance($instance);
+    $display = entity_get_display('node', $bundle_name, 'teaser');
+    $display->setContent($field_name, array(
+      'type' => 'file_default',
+    ));
+    $display->save();
 
     // Set the RDF mapping for the new field.
     $rdf_mapping = rdf_mapping_load('node', $bundle_name);
diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php
new file mode 100644
index 0000000..ba3b772
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php
@@ -0,0 +1,45 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\system\Tests\Upgrade\FieldUpgradePathTest.
+ */
+
+namespace Drupal\system\Tests\Upgrade;
+
+/**
+ * Tests upgrade of system variables.
+ */
+class FieldUpgradePathTest extends UpgradePathTestBase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Field upgrade test',
+      'description' => 'Tests upgrade of Field API.',
+      'group' => 'Upgrade path',
+    );
+  }
+
+  public function setUp() {
+    $this->databaseDumpFiles = array(
+      drupal_get_path('module', 'system') . '/tests/upgrade/drupal-7.bare.standard_all.database.php.gz',
+    );
+    parent::setUp();
+  }
+
+  /**
+   * Tests upgrade of entity displays.
+   */
+  public function testEntityDisplayUpgrade() {
+    $this->assertTrue($this->performUpgrade(), 'The upgrade was completed successfully.');
+
+    // Verify that entity display config was created.
+    // entity_get_display() creates a display if the the one we ask does not
+    // exist, so use entity_load() instead.
+    $this->assertTrue(entity_load('entity_display', 'node.article.default'));
+    $this->assertTrue(entity_load('entity_display', 'node.article.teaser'));
+
+    // Verify that display key in the instance data was removed.
+    $body_instance = field_info_instance('node', 'body', 'article');
+    $this->assertTrue(!isset($body_instance['display']));
+  }
+}
diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/UserPictureUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/UserPictureUpgradePathTest.php
index d86f7cd..8b257c7 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/UserPictureUpgradePathTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/UserPictureUpgradePathTest.php
@@ -57,7 +57,9 @@ public function testUserPictureUpgrade() {
     $this->assertEqual($instance['settings']['max_filesize'], '700 KB', 'User picture maximum filesize has been migrated.');
     $this->assertEqual($instance['description'], 'These are user picture guidelines.', 'User picture guidelines are now the user picture field description.');
     $this->assertEqual($instance['settings']['file_directory'], 'user_pictures_dir', 'User picture directory path has been migrated.');
-    $this->assertEqual($instance['display']['default']['settings']['image_style'], 'thumbnail', 'User picture image style setting has been migrated.');
+
+    $properties = entity_get_display('user', 'user', 'default')->getContent('user_picture');
+    $this->assertEqual($properties['settings']['image_style'], 'thumbnail', 'User picture image style setting has been migrated.');
 
     // Verify compact view mode default settings.
     $this->drupalGet('admin/config/people/accounts/display/compact');
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/TermRenderController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/TermRenderController.php
index c22f6e3..56cc036 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/TermRenderController.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/TermRenderController.php
@@ -25,11 +25,11 @@ public function buildContent(array $entities = array(), $view_mode = 'full', $la
       // Add the description if enabled.
       $bundle = $entity->bundle();
       $entity_view_mode = $entity->content['#view_mode'];
-      $fields = field_extra_fields_get_display($this->entityType, $bundle, $entity_view_mode);
-      if (!empty($entity->description) && isset($fields['description']) && $fields['description']['visible']) {
+      $display = field_extra_fields_get_display($this->entityType, $bundle, $entity_view_mode);
+      if (!empty($entity->description) && !empty($display['description'])) {
         $entity->content['description'] = array(
           '#markup' => check_markup($entity->description, $entity->format, '', TRUE),
-          '#weight' => $fields['description']['weight'],
+          '#weight' => $display['description']['weight'],
           '#prefix' => '<div class="taxonomy-term-description">',
           '#suffix' => '</div>',
         );
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php
index e87d931..4a98d45 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php
@@ -56,13 +56,13 @@ function setUp() {
       'widget' => array(
         'type' => 'options_select',
       ),
-      'display' => array(
-        'default' => array(
-          'type' => 'taxonomy_term_reference_link',
-        ),
-      ),
     );
     field_create_instance($this->instance);
+    $display = entity_get_display('node', 'article', 'default');
+    $display->setContent('taxonomy_' . $this->vocabulary->machine_name, array(
+      'type' => 'taxonomy_term_reference_link',
+    ));
+    $display->save();
   }
 
   /**
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php
index 37cbf4e..de77491 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php
@@ -66,13 +66,13 @@ function setUp() {
       'widget' => array(
         'type' => 'options_select',
       ),
-      'display' => array(
-        'full' => array(
-          'type' => 'taxonomy_term_reference_link',
-        ),
-      ),
     );
     field_create_instance($this->instance);
+    $display = entity_get_display('test_entity', 'test_bundle', 'full');
+    $display->setContent($this->field_name, array(
+      'type' => 'taxonomy_term_reference_link',
+    ));
+    $display->save();
   }
 
   /**
@@ -98,8 +98,9 @@ function testTaxonomyTermFieldMultipleVocabularies() {
     // Render the entity.
     $entity = field_test_entity_test_load($id);
     $entities = array($id => $entity);
-    field_attach_prepare_view('test_entity', $entities, 'full');
-    $entity->content = field_attach_view('test_entity', $entity, 'full');
+    $display = entity_get_display($entity->entityType(), $entity->bundle(), 'full');
+    field_attach_prepare_view('test_entity', $entities, array($entity->bundle() => $display));
+    $entity->content = field_attach_view('test_entity', $entity, $display);
     $this->content = drupal_render($entity->content);
     $this->assertText($term1->name, 'Term 1 name is displayed.');
     $this->assertText($term2->name, 'Term 2 name is displayed.');
@@ -110,8 +111,9 @@ function testTaxonomyTermFieldMultipleVocabularies() {
     // Re-render the content.
     $entity = field_test_entity_test_load($id);
     $entities = array($id => $entity);
-    field_attach_prepare_view('test_entity', $entities, 'full');
-    $entity->content = field_attach_view('test_entity', $entity, 'full');
+    $display = entity_get_display($entity->entityType(), $entity->bundle(), 'full');
+    field_attach_prepare_view('test_entity', $entities, array($entity->bundle() => $display));
+    $entity->content = field_attach_view('test_entity', $entity, $display);
     $this->plainTextContent = FALSE;
     $this->content = drupal_render($entity->content);
 
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php
index 34065e1..6a900cd 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php
@@ -61,13 +61,13 @@ function setUp() {
       'widget' => array(
         'type' => 'options_select',
       ),
-      'display' => array(
-        'full' => array(
-          'type' => 'taxonomy_term_reference_link',
-        ),
-      ),
     );
     field_create_instance($this->instance);
+    $display = entity_get_display('test_entity', 'test_bundle', 'full');
+    $display->setContent($this->field_name, array(
+      'type' => 'taxonomy_term_reference_link',
+    ));
+    $display->save();
   }
 
   /**
@@ -123,8 +123,9 @@ function testTaxonomyTermFieldWidgets() {
     // Display the object.
     $entity = field_test_entity_test_load($id);
     $entities = array($id => $entity);
-    field_attach_prepare_view('test_entity', $entities, 'full');
-    $entity->content = field_attach_view('test_entity', $entity, 'full');
+    $display = entity_get_display($entity->entityType(), $entity->bundle(), 'full');
+    field_attach_prepare_view('test_entity', $entities, array($entity->bundle() => $display));
+    $entity->content = field_attach_view('test_entity', $entity, $display);
     $this->content = drupal_render($entity->content);
     $this->assertText($term->label(), 'Term label is displayed.');
 
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php
index 31d01c5..efabbdb 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php
@@ -52,13 +52,13 @@ function setUp() {
       'widget' => array(
         'type' => 'options_select',
       ),
-      'display' => array(
-        'default' => array(
-          'type' => 'taxonomy_term_reference_link',
-        ),
-      ),
     );
     field_create_instance($this->instance_1);
+    $display = entity_get_display('node', 'article', 'default');
+    $display->setContent($this->field_name_1, array(
+      'type' => 'taxonomy_term_reference_link',
+    ));
+    $display->save();
 
     $this->field_name_2 = drupal_strtolower($this->randomName());
     $this->field_2 = array(
@@ -82,13 +82,13 @@ function setUp() {
       'widget' => array(
         'type' => 'options_select',
       ),
-      'display' => array(
-        'default' => array(
-          'type' => 'taxonomy_term_reference_link',
-        ),
-      ),
     );
     field_create_instance($this->instance_2);
+    $display = entity_get_display('node', 'article', 'default');
+    $display->setContent($this->field_name_2, array(
+      'type' => 'taxonomy_term_reference_link',
+    ));
+    $display->save();
   }
 
   /**
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
index 4abbf62..1d4d963 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
@@ -48,13 +48,13 @@ function setUp() {
       'widget' => array(
         'type' => 'options_select',
       ),
-      'display' => array(
-        'default' => array(
-          'type' => 'taxonomy_term_reference_link',
-        ),
-      ),
     );
     field_create_instance($this->instance);
+    $display = entity_get_display('node', 'article', 'default');
+    $display->setContent($this->instance['field_name'], array(
+      'type' => 'taxonomy_term_reference_link',
+    ));
+    $display->save();
   }
 
   /**
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php
index e273c1b..6460cee 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php
@@ -49,13 +49,13 @@ function setUp() {
       'widget' => array(
         'type' => 'options_select',
       ),
-      'display' => array(
-        'default' => array(
-          'type' => 'taxonomy_term_reference_link',
-        ),
-      ),
     );
     field_create_instance($this->instance);
+    $display = entity_get_display('node', 'article', 'default');
+    $display->setContent('taxonomy_' . $this->vocabulary->machine_name, array(
+      'type' => 'taxonomy_term_reference_link',
+    ));
+    $display->save();
   }
 
   /**
diff --git a/core/modules/user/lib/Drupal/user/Tests/UserPictureTest.php b/core/modules/user/lib/Drupal/user/Tests/UserPictureTest.php
index 26545d8..8d31aee 100644
--- a/core/modules/user/lib/Drupal/user/Tests/UserPictureTest.php
+++ b/core/modules/user/lib/Drupal/user/Tests/UserPictureTest.php
@@ -48,12 +48,9 @@ function setUp() {
     _user_install_picture_field();
 
     // Remove 'summary' pseudo-field from compact view mode on the User entity.
-    $bundle_settings = field_bundle_settings('user', 'user');
-    $bundle_settings['extra_fields']['display']['member_for']['compact'] = array(
-      'visible' => FALSE,
-      'weight' => 10,
-    );
-    field_bundle_settings('user', 'user', $bundle_settings);
+    $display = entity_get_display('user', 'user', 'compact');
+    $display->deleteContent('member_for');
+    $display->save();
   }
 
   /**
diff --git a/core/modules/user/user.install b/core/modules/user/user.install
index bb86002..82ab816 100644
--- a/core/modules/user/user.install
+++ b/core/modules/user/user.install
@@ -1026,19 +1026,30 @@ function _user_install_picture_field(array $settings = array()) {
       ),
       'weight' => -1,
     ),
-    'display' => array(
-      'default' => array(
-        'label' => 'hidden',
-        'type' => $settings['formatter'],
-        'settings' => array('image_style' => 'thumbnail', 'image_link' => 'content'),
-      ),
-      'compact' => array(
-        'label' => 'hidden',
-        'type' => $settings['formatter'],
-        'settings' => array('image_style' => $settings['image_style'], 'image_link' => 'content'),
-      ),
-    ),
   );
   _update_7000_field_create_instance($field, $instance);
+
+  // Assign display settings for the 'default' and 'compact' view modes.
+  $display = entity_get_display('user', 'user', 'default');
+  $display->setContent('user_picture', array(
+    'label' => 'hidden',
+    'type' => $settings['formatter'],
+    'settings' => array(
+      'image_style' => 'thumbnail',
+      'image_link' => 'content',
+    ),
+  ));
+  $display->save();
+  $display = entity_get_display('user', 'user', 'compact');
+  $display->setContent('user_picture', array(
+    'label' => 'hidden',
+    'type' => $settings['formatter'],
+    'settings' => array(
+      'image_style' => $settings['image_style'],
+      'image_link' => 'content',
+    ),
+  ));
+  $display->save();
+
   return $field;
 }
diff --git a/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php b/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php
index 7e37452..f4b856d 100644
--- a/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php
@@ -77,13 +77,13 @@ protected function setUp() {
       'widget' => array(
         'type' => 'options_select',
       ),
-      'display' => array(
-        'full' => array(
-          'type' => 'taxonomy_term_reference_link',
-        ),
-      ),
     );
     field_create_instance($this->instance);
+    $display = entity_get_display('node', 'page', 'full');
+    $display->setContent($this->field_name, array(
+      'type' => 'taxonomy_term_reference_link',
+    ));
+    $display->save();
 
     // Create a time in the past for the archive.
     $time = time() - 3600;
diff --git a/core/modules/views/lib/Drupal/views/Tests/Taxonomy/TaxonomyTestBase.php b/core/modules/views/lib/Drupal/views/Tests/Taxonomy/TaxonomyTestBase.php
index 9c2835a..6c881af 100644
--- a/core/modules/views/lib/Drupal/views/Tests/Taxonomy/TaxonomyTestBase.php
+++ b/core/modules/views/lib/Drupal/views/Tests/Taxonomy/TaxonomyTestBase.php
@@ -101,18 +101,25 @@ protected function mockStandardInstall() {
         'type' => 'taxonomy_autocomplete',
         'weight' => -4,
       ),
-      'display' => array(
-        'default' => array(
-          'type' => 'taxonomy_term_reference_link',
-          'weight' => 10,
-        ),
-        'teaser' => array(
-          'type' => 'taxonomy_term_reference_link',
-          'weight' => 10,
-        ),
-      ),
     );
     field_create_instance($instance);
+
+    $display_properties = array(
+      'default' => array(
+        'type' => 'taxonomy_term_reference_link',
+        'weight' => 10,
+      ),
+      'teaser' => array(
+        'type' => 'taxonomy_term_reference_link',
+        'weight' => 10,
+      ),
+    );
+    $display = entity_get_display('node', 'article', 'default');
+    $display->setContent($instance['field_name'], $display_properties['default']);
+    $display->save();
+    $display = entity_get_display('node', 'article', 'teaser');
+    $display->setContent($instance['field_name'], $display_properties['teaser']);
+    $display->save();
   }
 
   /**
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 cf3d19e..105f9c9 100644
--- a/core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php
@@ -77,18 +77,26 @@ function setUp() {
       'widget' => array(
         'type' => 'taxonomy_autocomplete',
       ),
-      'display' => array(
-        'default' => array(
-          'type' => 'taxonomy_term_reference_link',
-          'weight' => 10,
-        ),
-        'teaser' => array(
-          'type' => 'taxonomy_term_reference_link',
-          'weight' => 10,
-        ),
-      ),
     );
     field_create_instance($this->tag_instance);
+
+    $display_properties = array(
+      'default' => array(
+        'type' => 'taxonomy_term_reference_link',
+        'weight' => 10,
+      ),
+      'teaser' => array(
+        'type' => 'taxonomy_term_reference_link',
+        'weight' => 10,
+      ),
+    );
+    $display = entity_get_display('node', $this->node_type_with_tags->type, 'default');
+    $display->setContent('field_views_testing_tags', $display_properties['default']);
+    $display->save();
+
+    $display = entity_get_display('node', $this->node_type_with_tags->type, 'teaser');
+    $display->setContent('field_views_testing_tags', $display_properties['teaser']);
+    $display->save();
   }
 
   /**
diff --git a/core/profiles/standard/standard.install b/core/profiles/standard/standard.install
index 071bf31..94358ac 100644
--- a/core/profiles/standard/standard.install
+++ b/core/profiles/standard/standard.install
@@ -295,19 +295,22 @@ function standard_install() {
       'type' => 'taxonomy_autocomplete',
       'weight' => -4,
     ),
-    'display' => array(
-      'default' => array(
-        'type' => 'taxonomy_term_reference_link',
-        'weight' => 10,
-      ),
-      'teaser' => array(
-        'type' => 'taxonomy_term_reference_link',
-        'weight' => 10,
-      ),
-    ),
   );
   field_create_instance($instance);
 
+  // Assign display settings for the 'default' and 'teaser' view modes.
+  $display = entity_get_display('node', 'article', 'default');
+  $display->setContent($instance['field_name'], array(
+    'type' => 'taxonomy_term_reference_link',
+    'weight' => 10,
+  ));
+  $display->save();
+  $display = entity_get_display('node', 'article', 'teaser');
+  $display->setContent($instance['field_name'], array(
+    'type' => 'taxonomy_term_reference_link',
+    'weight' => 10,
+  ));
+  $display->save();
 
   // Create an image field named "Image", enabled for the 'article' content type.
   // Many of the following values will be defaulted, they're included here as an illustrative examples.
@@ -359,34 +362,34 @@ function standard_install() {
       ),
       'weight' => -1,
     ),
-
-    'display' => array(
-      'default' => array(
-        'label' => 'hidden',
-        'type' => 'image',
-        'settings' => array('image_style' => 'large', 'image_link' => ''),
-        'weight' => -1,
-      ),
-      'teaser' => array(
-        'label' => 'hidden',
-        'type' => 'image',
-        'settings' => array('image_style' => 'medium', 'image_link' => 'content'),
-        'weight' => -1,
-      ),
-    ),
   );
   field_create_instance($instance);
 
+  // Assign display settings for the 'default' and 'teaser' view modes.
+  $display = entity_get_display('node', 'article', 'default');
+  $display->setContent($instance['field_name'], array(
+    'label' => 'hidden',
+    'type' => 'image',
+    'settings' => array('image_style' => 'large', 'image_link' => ''),
+    'weight' => -1,
+  ));
+  $display->save();
+  $display = entity_get_display('node', 'article', 'teaser');
+  $display->setContent($instance['field_name'], array(
+    'label' => 'hidden',
+    'type' => 'image',
+    'settings' => array('image_style' => 'medium', 'image_link' => 'content'),
+    'weight' => -1,
+  ));
+  $display->save();
+
   // Create user picture field.
   module_load_install('user');
   _user_install_picture_field();
   // Remove 'summary' pseudo-field from compact view mode on the User entity.
-  $bundle_settings = field_bundle_settings('user', 'user');
-  $bundle_settings['extra_fields']['display']['member_for']['compact'] = array(
-    'visible' => FALSE,
-    'weight' => 10,
-  );
-  field_bundle_settings('user', 'user', $bundle_settings);
+  $display = entity_get_display('user', 'user', 'compact');
+  $display->deleteContent('member_for');
+  $display->save();
 
   // Enable default permissions for system roles.
   $filtered_html_permission = filter_permission_name($filtered_html_format);
diff --git a/core/update.php b/core/update.php
index 8563657..fcad34e 100644
--- a/core/update.php
+++ b/core/update.php
@@ -477,6 +477,8 @@ function update_check_requirements($skip_warnings = FALSE) {
   ->addArgument(new Reference('router.dumper'))
   ->addArgument(new Reference('lock'))
   ->addArgument(new Reference('dispatcher'));
+$container->register('plugin.manager.field.widget', 'Drupal\field\Plugin\Type\Widget\WidgetPluginManager');
+$container->register('plugin.manager.field.formatter', 'Drupal\field\Plugin\Type\Formatter\FormatterPluginManager');
 
 // Turn error reporting back on. From now on, only fatal errors (which are
 // not passed through the error handler) will cause a message to be printed.
