diff --git a/core/includes/entity.api.php b/core/includes/entity.api.php
index 2219d40..3436129 100644
--- a/core/includes/entity.api.php
+++ b/core/includes/entity.api.php
@@ -326,7 +326,7 @@ function hook_entity_view(\Drupal\Core\Entity\EntityInterface $entity, \Drupal\e
   // Only do the extra work if the component is configured to be displayed.
   // This assumes a 'mymodule_addition' extra field has been defined for the
   // entity bundle in hook_field_extra_fields().
-  if ($display->getComponent('mymodule_addition')) {
+  if ($display->getComponent('extra_field', 'mymodule_addition')) {
     $entity->content['mymodule_addition'] = array(
       '#markup' => mymodule_addition($entity),
       '#theme' => 'mymodule_my_additional_field',
@@ -396,7 +396,7 @@ function hook_entity_prepare_view($entity_type, array $entities, array $displays
     // defined for the entity bundle in hook_field_extra_fields().
     $ids = array();
     foreach ($entities as $id => $entity) {
-      if ($displays[$entity->bundle()]->getComponent('mymodule_addition')) {
+      if ($displays[$entity->bundle()]->getComponent('extra_field', 'mymodule_addition')) {
         $ids[] = $id;
       }
     }
@@ -442,11 +442,9 @@ function hook_entity_view_mode_alter(&$view_mode, Drupal\Core\Entity\EntityInter
 function hook_entity_display_alter(\Drupal\entity\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->getComponents() as $name => $options) {
-      if (isset($options['label'])) {
-        $options['label'] = 'hidden';
-        $display->setComponent($name, $options);
-      }
+    foreach ($display->getComponents('field') as $name => $options) {
+      $options['label'] = 'hidden';
+      $display->setComponent('field', $name, $options);
     }
   }
 }
@@ -491,7 +489,7 @@ function hook_entity_prepare_form(\Drupal\Core\Entity\EntityInterface $entity, $
 function hook_entity_form_display_alter(\Drupal\entity\Plugin\Core\Entity\EntityFormDisplay $form_display, array $context) {
   // Hide the 'user_picture' field from the register form.
   if ($context['entity_type'] == 'user' && $context['form_mode'] == 'register') {
-    $form_display->setComponent('user_picture', array(
+    $form_display->setComponent('field', 'user_picture', array(
       'type' => 'hidden',
     ));
   }
diff --git a/core/includes/entity.inc b/core/includes/entity.inc
index ffe879a..71e1067 100644
--- a/core/includes/entity.inc
+++ b/core/includes/entity.inc
@@ -670,12 +670,12 @@ function entity_view_multiple(array $entities, $view_mode, $langcode = NULL) {
  *   hidden on article nodes in the 'default' display.
  * @code
  * entity_get_display('node', 'article', 'default')
- *   ->setComponent('body', array(
+ *   ->setComponent('field', 'body', array(
  *     'type' => 'text_summary_or_trimmed',
  *     'settings' => array('trim_length' => '200')
  *     'weight' => 1,
  *   ))
- *   ->removeComponent('field_image')
+ *   ->removeComponent('field', 'field_image')
  *   ->save();
  * @endcode
  *
@@ -765,11 +765,11 @@ function entity_get_render_display(EntityInterface $entity, $view_mode) {
  *  'default' form mode.
  * @code
  * entity_get_form_display('node', 'article', 'default')
- *   ->setComponent('body', array(
+ *   ->setComponent('field', 'body', array(
  *     'type' => 'text_textarea_with_summary',
  *     'weight' => 1,
  *   ))
- *   ->setComponent('field_image', array(
+ *   ->setComponent('field', 'field_image', array(
  *     'type' => 'hidden',
  *   ))
  *   ->save();
diff --git a/core/lib/Drupal/Core/Entity/EntityFormController.php b/core/lib/Drupal/Core/Entity/EntityFormController.php
index 9ad27f5..fdb63af 100644
--- a/core/lib/Drupal/Core/Entity/EntityFormController.php
+++ b/core/lib/Drupal/Core/Entity/EntityFormController.php
@@ -210,7 +210,7 @@ public function processForm($element, $form_state, $form) {
     // Hide extra fields.
     $extra_fields = field_info_extra_fields($this->entity->entityType(), $this->entity->bundle(), 'form');
     foreach ($extra_fields as $extra_field => $info) {
-      if (!$this->getFormDisplay($form_state)->getComponent($extra_field)) {
+      if (!$this->getFormDisplay($form_state)->getComponent('extra_field', $extra_field)) {
         $element[$extra_field]['#access'] = FALSE;
       }
     }
diff --git a/core/modules/block/custom_block/custom_block.module b/core/modules/block/custom_block/custom_block.module
index 0a3efde..3e5d926 100644
--- a/core/modules/block/custom_block/custom_block.module
+++ b/core/modules/block/custom_block/custom_block.module
@@ -198,14 +198,14 @@ function custom_block_add_body_field($block_type_id, $label = 'Block body') {
 
     // Assign widget settings for the 'default' form mode.
     entity_get_form_display('custom_block', $block_type_id, 'default')
-      ->setComponent('block_body', array(
+      ->setComponent('field', 'block_body', array(
         'type' => 'text_textarea_with_summary',
       ))
       ->save();
 
     // Assign display settings for 'default' view mode.
     entity_get_display('custom_block', $block_type_id, 'default')
-      ->setComponent('block_body', array(
+      ->setComponent('field', 'block_body', array(
         'label' => 'hidden',
         'type' => 'text_default',
       ))
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockFieldTest.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockFieldTest.php
index da5ac4f..6a89205 100644
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockFieldTest.php
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockFieldTest.php
@@ -80,12 +80,12 @@ public function testBlockFields() {
     ));
     $this->instance->save();
     entity_get_form_display('custom_block', 'link', 'default')
-      ->setComponent($this->field['field_name'], array(
+      ->setComponent('field', $this->field['field_name'], array(
         'type' => 'link_default',
       ))
       ->save();
     entity_get_display('custom_block', 'link', 'default')
-      ->setComponent($this->field['field_name'], array(
+      ->setComponent('field', $this->field['field_name'], array(
         'type' => 'link',
         'label' => 'hidden',
       ))
diff --git a/core/modules/comment/comment.api.php b/core/modules/comment/comment.api.php
index ec1707f..262eaf2 100644
--- a/core/modules/comment/comment.api.php
+++ b/core/modules/comment/comment.api.php
@@ -95,7 +95,7 @@ function hook_comment_view(\Drupal\comment\Plugin\Core\Entity\Comment $comment,
   // Only do the extra work if the component is configured to be displayed.
   // This assumes a 'mymodule_addition' extra field has been defined for the
   // node type in hook_field_extra_fields().
-  if ($display->getComponent('mymodule_addition')) {
+  if ($display->getComponent('extra_field', 'mymodule_addition')) {
     $comment->content['mymodule_addition'] = array(
       '#markup' => mymodule_addition($comment),
       '#theme' => 'mymodule_my_additional_field',
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index 951906f..067022f 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -346,14 +346,14 @@ function _comment_body_field_create($info) {
 
     // Assign widget settings for the 'default' form mode.
     entity_get_form_display('comment', 'comment_node_' . $info->type, 'default')
-      ->setComponent('comment_body', array(
+      ->setComponent('field', 'comment_body', array(
         'type' => 'text_textarea',
       ))
       ->save();
 
     // Assign display settings for the 'default' view mode.
     entity_get_display('comment', 'comment_node_' . $info->type, 'default')
-      ->setComponent('comment_body', array(
+      ->setComponent('field', 'comment_body', array(
         'label' => 'hidden',
         'type' => 'text_default',
         'weight' => 0,
diff --git a/core/modules/contact/lib/Drupal/contact/MessageRenderController.php b/core/modules/contact/lib/Drupal/contact/MessageRenderController.php
index f8aca5d..c052607 100644
--- a/core/modules/contact/lib/Drupal/contact/MessageRenderController.php
+++ b/core/modules/contact/lib/Drupal/contact/MessageRenderController.php
@@ -24,7 +24,7 @@ public function buildContent(array $entities, array $displays, $view_mode, $lang
     foreach ($entities as $entity) {
       // Add the message extra field, if enabled.
       $display = $displays[$entity->bundle()];
-      if ($entity->getMessage() && $display->getComponent('message')) {
+      if ($entity->getMessage() && $display->getComponent('extra_field', 'message')) {
         $entity->content['message'] = array(
           '#type' => 'item',
           '#title' => t('Message'),
diff --git a/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationTestBase.php b/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationTestBase.php
index b635c45..53d0e9b 100644
--- a/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationTestBase.php
+++ b/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationTestBase.php
@@ -174,7 +174,7 @@ protected function setupTestFields() {
       'label' => 'Test translatable text-field',
     ))->save();
     entity_get_form_display($this->entityType, $this->bundle, 'default')
-      ->setComponent($this->fieldName, array(
+      ->setComponent('field', $this->fieldName, array(
         'type' => 'text_textfield',
         'weight' => 0,
       ))
diff --git a/core/modules/datetime/lib/Drupal/datetime/Tests/DatetimeFieldTest.php b/core/modules/datetime/lib/Drupal/datetime/Tests/DatetimeFieldTest.php
index a0538d7..1ee3de6 100644
--- a/core/modules/datetime/lib/Drupal/datetime/Tests/DatetimeFieldTest.php
+++ b/core/modules/datetime/lib/Drupal/datetime/Tests/DatetimeFieldTest.php
@@ -73,7 +73,7 @@ function setUp() {
     $this->instance->save();
 
     entity_get_form_display($this->instance->entity_type, $this->instance->bundle, 'default')
-      ->setComponent($this->field->id(), array(
+      ->setComponent('field', $this->field->id(), array(
         'type' => 'datetime_default',
       ))
       ->save();
@@ -84,7 +84,7 @@ function setUp() {
       'settings' => array('format_type' => 'medium'),
     );
     entity_get_display($this->instance->entity_type, $this->instance->bundle, 'full')
-      ->setComponent($this->field->id(), $this->display_options)
+      ->setComponent('field', $this->field->id(), $this->display_options)
       ->save();
   }
 
@@ -131,7 +131,7 @@ function testDateField() {
         // Update the entity display settings.
         $this->display_options['settings'] = array($setting => $new_value);
         entity_get_display($this->instance->entity_type, $this->instance->bundle, 'full')
-          ->setComponent($field_name, $this->display_options)
+          ->setComponent('field', $field_name, $this->display_options)
           ->save();
 
         $this->renderTestEntity($id);
@@ -149,7 +149,7 @@ function testDateField() {
     // Verify that the plain formatter works.
     $this->display_options['type'] = 'datetime_plain';
     entity_get_display($this->instance->entity_type, $this->instance->bundle, 'full')
-      ->setComponent($field_name, $this->display_options)
+      ->setComponent('field', $field_name, $this->display_options)
       ->save();
     $expected = $date->format(DATETIME_DATE_STORAGE_FORMAT);
     $this->renderTestEntity($id);
@@ -200,7 +200,7 @@ function testDatetimeField() {
         // Update the entity display settings.
         $this->display_options['settings'] = array($setting => $new_value);
         entity_get_display($this->instance->entity_type, $this->instance->bundle, 'full')
-          ->setComponent($field_name, $this->display_options)
+          ->setComponent('field', $field_name, $this->display_options)
           ->save();
 
         $this->renderTestEntity($id);
@@ -218,7 +218,7 @@ function testDatetimeField() {
     // Verify that the plain formatter works.
     $this->display_options['type'] = 'datetime_plain';
     entity_get_display($this->instance->entity_type, $this->instance->bundle, 'full')
-      ->setComponent($field_name, $this->display_options)
+      ->setComponent('type', $field_name, $this->display_options)
       ->save();
     $expected = $date->format(DATETIME_DATETIME_STORAGE_FORMAT);
     $this->renderTestEntity($id);
@@ -236,7 +236,7 @@ function testDatelistWidget() {
 
     // Change the widget to a datelist widget.
     entity_get_form_display($this->instance->entity_type, $this->instance->bundle, 'default')
-      ->setComponent($field_name, array(
+      ->setComponent('field', $field_name, array(
         'type' => 'datetime_datelist',
         'settings' => array(
           'increment' => 1,
diff --git a/core/modules/edit/lib/Drupal/edit/MetadataGenerator.php b/core/modules/edit/lib/Drupal/edit/MetadataGenerator.php
index 97746e2..8a2bcb0 100644
--- a/core/modules/edit/lib/Drupal/edit/MetadataGenerator.php
+++ b/core/modules/edit/lib/Drupal/edit/MetadataGenerator.php
@@ -77,7 +77,7 @@ public function generateField(EntityInterface $entity, FieldInstance $instance,
     }
 
     // Early-return if no editor is available.
-    $formatter_id = entity_get_render_display($entity, $view_mode)->getRenderer($instance['field_name'])->getPluginId();
+    $formatter_id = entity_get_render_display($entity, $view_mode)->getRenderer('field', $instance['field_name'])->getPluginId();
     $items = $entity->getTranslation($langcode, FALSE)->get($field_name)->getValue();
     $editor_id = $this->editorSelector->getEditor($formatter_id, $instance, $items);
     if (!isset($editor_id)) {
diff --git a/core/modules/edit/lib/Drupal/edit/Tests/EditTestBase.php b/core/modules/edit/lib/Drupal/edit/Tests/EditTestBase.php
index 649f033..86d5086 100644
--- a/core/modules/edit/lib/Drupal/edit/Tests/EditTestBase.php
+++ b/core/modules/edit/lib/Drupal/edit/Tests/EditTestBase.php
@@ -74,7 +74,7 @@ function createFieldWithInstance($field_name, $type, $cardinality, $label, $inst
     $this->$instance->save();
 
     entity_get_form_display('entity_test', 'entity_test', 'default')
-      ->setComponent($field_name, array(
+      ->setComponent('field', $field_name, array(
         'type' => $widget_type,
         'label' => $label,
         'settings' => $widget_settings,
@@ -82,7 +82,7 @@ function createFieldWithInstance($field_name, $type, $cardinality, $label, $inst
       ->save();
 
     entity_get_display('entity_test', 'entity_test', 'default')
-      ->setComponent($field_name, array(
+      ->setComponent('field', $field_name, array(
         'label' => 'above',
         'type' => $formatter_type,
         'settings' => $formatter_settings
diff --git a/core/modules/edit/lib/Drupal/edit/Tests/EditorSelectionTest.php b/core/modules/edit/lib/Drupal/edit/Tests/EditorSelectionTest.php
index c1982c5..f365efe 100644
--- a/core/modules/edit/lib/Drupal/edit/Tests/EditorSelectionTest.php
+++ b/core/modules/edit/lib/Drupal/edit/Tests/EditorSelectionTest.php
@@ -49,7 +49,7 @@ function setUp() {
    * editor that Edit selects.
    */
   protected function getSelectedEditor($items, $field_name, $view_mode = 'default') {
-    $options = entity_get_display('entity_test', 'entity_test', $view_mode)->getComponent($field_name);
+    $options = entity_get_display('entity_test', 'entity_test', $view_mode)->getComponent('field', $field_name);
     $field_instance = field_info_instance('entity_test', $field_name, 'entity_test');
     return $this->editorSelector->getEditor($options['type'], $field_instance, $items);
   }
diff --git a/core/modules/editor/lib/Drupal/editor/Tests/EditIntegrationTest.php b/core/modules/editor/lib/Drupal/editor/Tests/EditIntegrationTest.php
index d2ec5e6..cfe688f 100644
--- a/core/modules/editor/lib/Drupal/editor/Tests/EditIntegrationTest.php
+++ b/core/modules/editor/lib/Drupal/editor/Tests/EditIntegrationTest.php
@@ -110,7 +110,7 @@ function setUp() {
    * editor that Edit selects.
    */
   protected function getSelectedEditor($items, $field_name, $view_mode = 'default') {
-    $options = entity_get_display('entity_test', 'entity_test', $view_mode)->getComponent($field_name);
+    $options = entity_get_display('entity_test', 'entity_test', $view_mode)->getComponent('field', $field_name);
     $field_instance = field_info_instance('entity_test', $field_name, 'entity_test');
     return $this->editorSelector->getEditor($options['type'], $field_instance, $items);
   }
diff --git a/core/modules/email/lib/Drupal/email/Tests/EmailFieldTest.php b/core/modules/email/lib/Drupal/email/Tests/EmailFieldTest.php
index 2d76d76..f4628a1 100644
--- a/core/modules/email/lib/Drupal/email/Tests/EmailFieldTest.php
+++ b/core/modules/email/lib/Drupal/email/Tests/EmailFieldTest.php
@@ -75,7 +75,7 @@ function testEmailField() {
 
     // Create a form display for the default form mode.
     entity_get_form_display('entity_test', 'entity_test', 'default')
-      ->setComponent($field_name, array(
+      ->setComponent('field', $field_name, array(
         'type' => 'email_default',
         'settings' => array(
           'placeholder' => 'example@example.com',
@@ -84,7 +84,7 @@ function testEmailField() {
       ->save();
     // Create a display for the full view mode.
     entity_get_display('entity_test', 'entity_test', 'full')
-      ->setComponent($field_name, array(
+      ->setComponent('field', $field_name, array(
         'type' => 'email_mailto',
       ))
       ->save();
diff --git a/core/modules/email/lib/Drupal/email/Tests/EmailItemTest.php b/core/modules/email/lib/Drupal/email/Tests/EmailItemTest.php
index 7e72163..58c84f3 100644
--- a/core/modules/email/lib/Drupal/email/Tests/EmailItemTest.php
+++ b/core/modules/email/lib/Drupal/email/Tests/EmailItemTest.php
@@ -47,7 +47,7 @@ public function setUp() {
 
     // Create a form display for the default form mode.
     entity_get_form_display('entity_test', 'entity_test', 'default')
-      ->setComponent('field_email', array(
+      ->setComponent('field', 'field_email', array(
         'type' => 'email_default',
       ))
       ->save();
diff --git a/core/modules/entity/entity.services.yml b/core/modules/entity/entity.services.yml
new file mode 100644
index 0000000..2ce7ef2
--- /dev/null
+++ b/core/modules/entity/entity.services.yml
@@ -0,0 +1,4 @@
+services:
+  plugin.manager.entity.display_component_handler:
+    class: Drupal\entity\Plugin\Type\DisplayComponentHandlerPluginManager
+    arguments: ['@container.namespaces', '@cache.cache', '@language_manager', '@module_handler']
diff --git a/core/modules/entity/lib/Drupal/entity/Annotation/DisplayComponent.php b/core/modules/entity/lib/Drupal/entity/Annotation/DisplayComponent.php
new file mode 100644
index 0000000..7c87043
--- /dev/null
+++ b/core/modules/entity/lib/Drupal/entity/Annotation/DisplayComponent.php
@@ -0,0 +1,26 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\entity\Annotation\DisplayComponent.
+ */
+
+namespace Drupal\entity\Annotation;
+
+use Drupal\Component\Annotation\Plugin;
+
+/**
+ * Defines a DisplayComponent annotation object.
+ *
+ * @Annotation
+ */
+class DisplayComponent extends Plugin {
+
+  /**
+   * The plugin ID.
+   *
+   * @var string
+   */
+  public $id;
+
+}
diff --git a/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php b/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php
index 99008e2..9360955 100644
--- a/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php
+++ b/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php
@@ -160,12 +160,15 @@ public function createCopy($mode) {
   /**
    * {@inheritdoc}
    */
-  public function getComponents() {
+  public function getComponents($type = '') {
     $result = array();
     foreach ($this->content as $name => $options) {
       if (!isset($options['visible']) || $options['visible'] == TRUE) {
         unset($options['visible']);
         $result[$name] = $options;
+        if (empty($type) || $options['handler_type'] == $type) {
+          $result[$name] = $this->getComponent($options['handler_type'], $name);
+        }
       }
     }
     return $result;
@@ -174,66 +177,42 @@ public function getComponents() {
   /**
    * {@inheritdoc}
    */
-  public function getComponent($name) {
-    // We always store 'extra fields', whether they are visible or hidden.
-    $extra_fields = field_info_extra_fields($this->targetEntityType, $this->bundle, $this->displayContext);
-    if (isset($extra_fields[$name])) {
-      // If we have explicit settings, return an array or NULL depending on
-      // visibility.
-      if (isset($this->content[$name])) {
-        if ($this->content[$name]['visible']) {
-          return array(
-            'weight' => $this->content[$name]['weight'],
-          );
-        }
-        else {
-          return NULL;
-        }
-      }
-
-      // If no explicit settings for the extra field, look at the default
-      // visibility in its definition.
-      $definition = $extra_fields[$name];
-      if (!isset($definition['visible']) || $definition['visible'] == TRUE) {
-        return array(
-          'weight' => $definition['weight']
-        );
-      }
-      else {
-        return NULL;
-      }
+  public function getComponent($type, $name) {
+    if (!isset($this->content[$name]) || $this->content[$name]['handler_type'] !== $type) {
+      return NULL;
     }
 
-    if (isset($this->content[$name])) {
-      return $this->content[$name];
+    $options = $this->content[$name];
+
+    if ($handler = $this->getComponentHandler($type)) {
+      $options = $handler->massageOut($name, $options);
     }
+
+    // The 'handler_type' entry is strictly internal.
+    unset($options['handler_type']);
+
+    return $options;
+
   }
 
   /**
    * {@inheritdoc}
    */
-  public function setComponent($name, array $options = array()) {
+  public function setComponent($type, $name, array $options = array()) {
     // If no weight specified, make sure the field sinks at the bottom.
     if (!isset($options['weight'])) {
       $max = $this->getHighestWeight();
       $options['weight'] = isset($max) ? $max + 1 : 0;
     }
 
-    if ($instance = field_info_instance($this->targetEntityType, $name, $this->bundle)) {
-      $field = field_info_field($instance['field_name']);
-      $options = $this->pluginManager->prepareConfiguration($field['type'], $options);
-
-      // Clear the persisted plugin, if any.
-      unset($this->plugins[$name]);
+    if ($handler = $this->getComponentHandler($type)) {
+      $options = $handler->massageIn($name, $options);
     }
 
-    // We always store 'extra fields', whether they are visible or hidden.
-    $extra_fields = field_info_extra_fields($this->targetEntityType, $this->bundle, $this->displayContext);
-    if (isset($extra_fields[$name])) {
-      $options['visible'] = TRUE;
-    }
+    $this->content[$name] = array('handler_type' => $type) + $options;
 
-    $this->content[$name] = $options;
+    // Clear the associated renderer object.
+    unset($this->renderers[$name]);
 
     return $this;
   }
@@ -241,22 +220,20 @@ public function setComponent($name, array $options = array()) {
   /**
    * {@inheritdoc}
    */
-  public function removeComponent($name) {
-    $extra_fields = field_info_extra_fields($this->targetEntityType, $this->bundle, $this->displayContext);
-    if (isset($extra_fields[$name])) {
-      // 'Extra fields' are exposed in hooks and can appear at any given time.
-      // Therefore we store extra fields that are explicitly being hidden, so
-      // that we can differenciate with those that are simply not configured
-      // yet.
-      $this->content[$name] = array(
-        'visible' => FALSE,
-      );
+  public function removeComponent($type, $name) {
+    if ($handler = $this->getComponentHandler($type)) {
+      $options = $handler->massageIn($name);
+    }
+    if (isset($options)) {
+      $this->content[$name] = array('handler_type' => $type) + $options;
     }
     else {
       unset($this->content[$name]);
-      unset($this->plugins[$name]);
     }
 
+    // Clear the associated renderer object.
+    unset($this->renderers[$name]);
+
     return $this;
   }
 
diff --git a/core/modules/entity/lib/Drupal/entity/EntityDisplayBaseInterface.php b/core/modules/entity/lib/Drupal/entity/EntityDisplayBaseInterface.php
index 06647e7..b6b8a86 100644
--- a/core/modules/entity/lib/Drupal/entity/EntityDisplayBaseInterface.php
+++ b/core/modules/entity/lib/Drupal/entity/EntityDisplayBaseInterface.php
@@ -31,14 +31,21 @@ public function createCopy($view_mode);
   /**
    * Gets the display options for all components.
    *
+   * @param string $type
+   *   The type of the component (i.e. the plugin id of its
+   *   display_component_handler).
+   *
    * @return array
    *   The array of display options, keyed by component name.
    */
-  public function getComponents();
+  public function getComponents($type = '');
 
   /**
    * Gets the display options set for a component.
    *
+   * @param string $type
+   *   The type of the component (i.e. the plugin id of its
+   *   display_component_handler).
    * @param string $name
    *   The name of the component.
    *
@@ -46,11 +53,14 @@ public function getComponents();
    *   The display options for the component, or NULL if the component is not
    *   displayed.
    */
-  public function getComponent($name);
+  public function getComponent($type, $name);
 
   /**
    * Sets the display options for a component.
    *
+   * @param string $type
+   *   The type of the component (i.e. the plugin id of its
+   *   display_component_handler).
    * @param string $name
    *   The name of the component.
    * @param array $options
@@ -59,18 +69,21 @@ public function getComponent($name);
    * @return \Drupal\entity\Plugin\Core\Entity\EntityDisplay
    *   The EntityDisplay object.
    */
-  public function setComponent($name, array $options = array());
+  public function setComponent($type, $name, array $options = array());
 
   /**
    * Sets a component to be hidden.
    *
+   * @param string $type
+   *   The type of the component (i.e. the plugin id of its
+   *   display_component_handler).
    * @param string $name
    *   The name of the component.
    *
    * @return \Drupal\entity\Plugin\Core\Entity\EntityDisplay
    *   The EntityDisplay object.
    */
-  public function removeComponent($name);
+  public function removeComponent($type, $name);
 
   /**
    * Returns the highest weight of the components in the display.
@@ -82,14 +95,17 @@ public function removeComponent($name);
   public function getHighestWeight();
 
   /**
-   * Returns the renderer plugin for a field (e.g. widget, formatter).
+   * Returns the object responsible for rendering the component.
    *
-   * @param string $field_name
-   *   The field name.
+   * @param string $type
+   *   The type of the component (i.e. the plugin id of its
+   *   display_component_handler).
+   * @param string $name
+   *   The component name.
    *
-   * @return \Drupal\field\Plugin\PluginSettingsInterface|null
-   *   A widget or formatter plugin or NULL if the field does not exist.
+   * @return
+   *   If the component is not hidden, the object to use for rendering it.
    */
-  public function getRenderer($field_name);
+  public function getRenderer($type, $name);
 
 }
diff --git a/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityDisplay.php b/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityDisplay.php
index 78963bc..39e9d22 100644
--- a/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityDisplay.php
+++ b/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityDisplay.php
@@ -33,41 +33,74 @@
 class EntityDisplay extends EntityDisplayBase implements EntityDisplayInterface {
 
   /**
+   * The renderer objects used for this display, keyed by component name.
+   */
+  protected $renderers = array();
+
+  /**
+   * The component handler plugin manager.
+   *
+   * @var \Drupal\entity\Plugin\Type\DisplayComponentHandlerPluginManager
+   */
+  protected $handlersManager;
+
+  /**
    * {@inheritdoc}
    */
   public function __construct(array $values, $entity_type) {
     $this->pluginManager = \Drupal::service('plugin.manager.field.formatter');
     $this->displayContext = 'display';
 
+    // Get the 'component handler' plugin manager.
+    $this->handlersManager = drupal_container()->get('plugin.manager.entity.display_component_handler');
+
     parent::__construct($values, $entity_type);
+
+    // Let the component handlers add missing components.
+    $handlers = $this->handlersManager->getDefinitions();
+    foreach (array_keys($handlers) as $type) {
+      $this->getComponentHandler($type)->prepareDisplayComponents($this->content);
+    }
+
   }
 
   /**
-   * {@inheritdoc}
+   * Returns the component handler plugin for a given component type.
+   *
+   * @param string $type
+   *   The component type.
+   *
+   * @return \Drupal\entity\Plugin\Type\DisplayComponentHandlerBase
+   *   @todo interface instead
+   *   The component handler plugin if it exists, NULL otherwise.
    */
-  public function getRenderer($field_name) {
-    if (isset($this->plugins[$field_name])) {
-      return $this->plugins[$field_name];
-    }
-
-    // Instantiate the formatter object from the stored display properties.
-    if ($configuration = $this->getComponent($field_name)) {
-      $instance = field_info_instance($this->targetEntityType, $field_name, $this->bundle);
-      $formatter = $this->pluginManager->getInstance(array(
-        'field_definition' => $instance,
+  public function getComponentHandler($type) {
+    $handler = $this->handlersManager->getInstance(array('type' => $type));
+    if ($handler) {
+      $handler->setContext(array(
+        'entity_type' => $this->targetEntityType,
+        'bundle' => $this->bundle,
         'view_mode' => $this->originalMode,
-        // No need to prepare, defaults have been merged in setComponent().
-        'prepare' => FALSE,
-        'configuration' => $configuration
+        'display_context' => $this->displayContext,
       ));
     }
-    else {
-      $formatter = NULL;
-    }
+    return $handler;
+  }
 
-    // Persist the formatter object.
-    $this->plugins[$field_name] = $formatter;
-    return $formatter;
+  /**
+   * {@inheritdoc}
+   */
+  public function getRenderer($type, $name) {
+    if (!isset($this->renderers[$name]) && !array_key_exists($name, $this->renderers)) {
+      $options = $this->getComponent($type, $name);
+      if ($handler = $this->getComponentHandler($type)) {
+        $this->renderers[$name] = $handler->getRenderer($name, $options);
+      }
+      else {
+        $this->renderers[$name] = NULL;
+      }
+    }
+    return $this->renderers[$name];
   }
 
 }
diff --git a/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityFormDisplay.php b/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityFormDisplay.php
index 9a3f0a6..3cea363 100644
--- a/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityFormDisplay.php
+++ b/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityFormDisplay.php
@@ -33,25 +33,59 @@
 class EntityFormDisplay extends EntityDisplayBase implements EntityFormDisplayInterface, \Serializable {
 
   /**
+   * The component handler plugin manager.
+   *
+   * @var \Drupal\entity\Plugin\Type\DisplayComponentHandlerPluginManager
+   */
+  protected $handlersManager;
+
+  /**
    * {@inheritdoc}
    */
   public function __construct(array $values, $entity_type) {
     $this->pluginManager = \Drupal::service('plugin.manager.field.widget');
     $this->displayContext = 'form';
 
+    // Get the 'component handler' plugin manager.
+    $this->handlersManager = drupal_container()->get('plugin.manager.entity.display_component_handler');
+
     parent::__construct($values, $entity_type);
+
+    // Let the component handlers add missing components.
+    $handlers = $this->handlersManager->getDefinitions();
+    foreach (array_keys($handlers) as $type) {
+      $this->getComponentHandler($type)->prepareDisplayComponents($this->content);
+    }
+
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getComponentHandler($type) {
+    // @todo this should  move to displayBase.
+    $handler = $this->handlersManager->getInstance(array('type' => $type));
+    if ($handler) {
+      $handler->setContext(array(
+        'entity_type' => $this->targetEntityType,
+        'bundle' => $this->bundle,
+        'view_mode' => $this->originalMode,
+        'display_context' => $this->displayContext,
+      ));
+    }
+    return $handler;
   }
 
   /**
    * {@inheritdoc}
    */
-  public function getRenderer($field_name) {
+  public function getRenderer($type, $field_name) {
     if (isset($this->plugins[$field_name])) {
       return $this->plugins[$field_name];
     }
 
     // Instantiate the widget object from the stored display properties.
-    if ($configuration = $this->getComponent($field_name)) {
+    if ($configuration = $this->getComponent('field', $field_name)) {
       $instance = field_info_instance($this->targetEntityType, $field_name, $this->bundle);
       $widget = $this->pluginManager->getInstance(array(
         'field_definition' => $instance,
diff --git a/core/modules/entity/lib/Drupal/entity/Plugin/DisplayComponent/ExtraFieldDisplayComponentHandler.php b/core/modules/entity/lib/Drupal/entity/Plugin/DisplayComponent/ExtraFieldDisplayComponentHandler.php
new file mode 100644
index 0000000..f1d7e89
--- /dev/null
+++ b/core/modules/entity/lib/Drupal/entity/Plugin/DisplayComponent/ExtraFieldDisplayComponentHandler.php
@@ -0,0 +1,77 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\entity\Plugin\DisplayComponent\ExtraFieldDisplayComponentHandler.
+ */
+
+namespace Drupal\entity\Plugin\DisplayComponent;
+
+use Drupal\entity\Annotation\DisplayComponent;
+use Drupal\entity\Plugin\Type\DisplayComponentHandlerBase;
+
+/**
+ * @todo
+ *
+ * @DisplayComponent(
+ *   id = "extra_field"
+ * )
+ */
+class ExtraFieldDisplayComponentHandler extends DisplayComponentHandlerBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function prepareDisplayComponents(array &$components) {
+    // Add extra fields that are not explicitely configured in the display.
+    $extra_fields = field_info_extra_fields($this->context['entity_type'], $this->context['bundle'], $this->context['display_context']);
+    foreach ($extra_fields as $name => $definition) {
+      if (!isset($components[$name])) {
+        if (!isset($definition['visible']) || $definition['visible'] == TRUE) {
+          $components[$name] = array(
+            'visible' => TRUE,
+            'weight' => $definition['weight'],
+          );
+        }
+        else {
+          $components[$name] = array(
+            'visible' => FALSE,
+          );
+        }
+
+        $components[$name]['handler_type'] = $this->pluginId;
+      }
+    }
+    // @todo : we could add a custom $display->hiddenExtraFields property on the display, and merge them back on save.
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function massageOut($name, array $options = NULL) {
+    // We always store 'extra fields', whether they are visible or hidden. Only
+    // return an options array for visible components.
+    if (!empty($options['visible'])) {
+      unset($options['visible']);
+      return $options;
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function massageIn($name, array $options = NULL) {
+    // 'Extra fields' are exposed in hooks and can appear at any given time.
+    // Therefore we store extra fields that are explicitly being hidden, so
+    // that we can differenciate with those that are simply not configured
+    // yet.
+    if (is_null($options)) {
+      $options['visible'] = FALSE;
+    }
+    else {
+      $options['visible'] = TRUE;
+    }
+    return $options;
+  }
+
+}
diff --git a/core/modules/entity/lib/Drupal/entity/Plugin/Type/DisplayComponentHandlerBase.php b/core/modules/entity/lib/Drupal/entity/Plugin/Type/DisplayComponentHandlerBase.php
new file mode 100644
index 0000000..b86c0ec
--- /dev/null
+++ b/core/modules/entity/lib/Drupal/entity/Plugin/Type/DisplayComponentHandlerBase.php
@@ -0,0 +1,38 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\entity\Plugin\Type\DisplayComponentHandlerBase.
+ */
+
+namespace Drupal\entity\Plugin\Type;
+
+use Drupal\Component\Plugin\PluginBase;
+
+// @todo interface
+abstract class DisplayComponentHandlerBase extends PluginBase {
+
+  /**
+   * The context in which the handler is being used.
+   *
+   * @var array
+   */
+  protected $context;
+
+  public function setContext(array $context) {
+    $this->context = $context;
+  }
+
+  public function prepareDisplayComponents(array &$components) { }
+
+  public function massageOut($name, array $options = NULL) {
+    return $options;
+  }
+
+  public function massageIn($name, array $options = NULL) {
+    return $options;
+  }
+
+  public function getRenderer($name, array $options = NULL) { }
+
+}
diff --git a/core/modules/entity/lib/Drupal/entity/Plugin/Type/DisplayComponentHandlerPluginManager.php b/core/modules/entity/lib/Drupal/entity/Plugin/Type/DisplayComponentHandlerPluginManager.php
new file mode 100644
index 0000000..1a8182b
--- /dev/null
+++ b/core/modules/entity/lib/Drupal/entity/Plugin/Type/DisplayComponentHandlerPluginManager.php
@@ -0,0 +1,68 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\entity\Plugin\Type\DisplayComponentHandlerPluginManager.
+ */
+
+namespace Drupal\entity\Plugin\Type;
+
+use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Language\LanguageManager;
+use Drupal\Core\Plugin\DefaultPluginManager;
+
+/**
+ * Plugin type manager for entity display component handlers.
+ *
+ * The handlers are typically shared for the whole request. getInstance() holds
+ * the instantiated plugins and only instantiates one of each type.
+ */
+class DisplayComponentHandlerPluginManager extends DefaultPluginManager {
+
+  /**
+   * The handlers that have already been instantiated by getInstance().
+   *
+   * @var array
+   */
+  protected $plugins = array();
+
+  /**
+   * Constructs a DisplayComponentHandlerPluginManager object.
+   *
+   * @param \Traversable $namespaces
+   *   An object that implements \Traversable which contains the root paths
+   *   keyed by the corresponding namespace to look for plugin implementations.
+   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
+   *   Cache backend instance to use.
+   * @param \Drupal\Core\Language\LanguageManager $language_manager
+   *   The language manager.
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler to invoke the alter hook with.
+   */
+  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler) {
+    // @todo Document the alter hook.
+    // @todo cache key / bin ?
+    $this->alterInfo($module_handler, 'display_component_handler_info');
+    $this->setCacheBackend($cache_backend, $language_manager, 'plugin_display_component_handler');
+
+    $annotation_namespaces = array(
+      'Drupal\entity\Annotation' => $namespaces['Drupal\entity'],
+    );
+    parent::__construct('DisplayComponent', $namespaces, $annotation_namespaces, 'Drupal\entity\Annotation\DisplayComponent');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getInstance(array $options) {
+    $plugin_id = $options['type'];
+
+    if (!isset($this->plugins[$plugin_id]) && !array_key_exists($plugin_id, $this->plugins)) {
+      $this->plugins[$plugin_id] = $this->discovery->getDefinition($plugin_id) ? $this->createInstance($plugin_id) : NULL;
+    }
+
+    return $this->plugins[$plugin_id];
+  }
+
+}
diff --git a/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayTest.php b/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayTest.php
index 4337abd..781a26e 100644
--- a/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayTest.php
+++ b/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayTest.php
@@ -45,34 +45,34 @@ public function testEntityDisplayCRUD() {
     // being assigned.
     $expected['component_1'] = array('weight' => 0);
     $expected['component_2'] = array('weight' => 1);
-    $display->setComponent('component_1');
-    $display->setComponent('component_2');
-    $this->assertEqual($display->getComponent('component_1'), $expected['component_1']);
-    $this->assertEqual($display->getComponent('component_2'), $expected['component_2']);
+    $display->setComponent('default', 'component_1');
+    $display->setComponent('default', 'component_2');
+    $this->assertEqual($display->getComponent('default', 'component_1'), $expected['component_1']);
+    $this->assertEqual($display->getComponent('default', 'component_2'), $expected['component_2']);
 
     // Check that arbitrary options are correctly stored.
     $expected['component_3'] = array('weight' => 10, 'foo' => 'bar');
-    $display->setComponent('component_3', $expected['component_3']);
-    $this->assertEqual($display->getComponent('component_3'), $expected['component_3']);
+    $display->setComponent('default', 'component_3', $expected['component_3']);
+    $this->assertEqual($display->getComponent('default', 'component_3'), $expected['component_3']);
 
     // Check that the display can be properly saved and read back.
     $display->save();
     $display = entity_load('entity_display', $display->id());
     foreach (array('component_1', 'component_2', 'component_3') as $name) {
-      $this->assertEqual($display->getComponent($name), $expected[$name]);
+      $this->assertEqual($display->getComponent('default', $name), $expected[$name]);
     }
 
     // Check that getComponents() returns options for all components.
-    $this->assertEqual($display->getComponents(), $expected);
+    $this->assertEqual($display->getComponents('default'), $expected);
 
     // Check that a component can be removed.
-    $display->removeComponent('component_3');
-    $this->assertNULL($display->getComponent('component_3'));
+    $display->removeComponent('default', 'component_3');
+    $this->assertNULL($display->getComponent('default', 'component_3'));
 
     // Check that the removal is correctly persisted.
     $display->save();
     $display = entity_load('entity_display', $display->id());
-    $this->assertNULL($display->getComponent('component_3'));
+    $this->assertNULL($display->getComponent('default', 'component_3'));
 
     // Check that CreateCopy() creates a new component that can be correclty
     // saved.
@@ -95,14 +95,14 @@ public function testEntityGetDisplay() {
     $this->assertTrue($display->isNew());
 
     // Add some components and save the display.
-    $display->setComponent('component_1', array('weight' => 10))
+    $display->setComponent('default', 'component_1', array('weight' => 10))
       ->save();
 
     // Check that entity_get_display() returns the correct object.
     $display = entity_get_display('entity_test', 'entity_test', 'default');
     $this->assertFalse($display->isNew());
     $this->assertEqual($display->id, 'entity_test.entity_test.default');
-    $this->assertEqual($display->getComponent('component_1'), array('weight' => 10));
+    $this->assertEqual($display->getComponent('default', 'component_1'), array('weight' => 10));
   }
 
   /**
@@ -111,20 +111,20 @@ public function testEntityGetDisplay() {
   public function testExtraFieldComponent() {
     $display = entity_create('entity_display', array(
       'targetEntityType' => 'entity_test',
-      'bundle' => 'entity_test',
+      'bundle' => 'bundle_with_extra_fields',
       'mode' => 'default',
     ));
 
     // Check that the default visibility taken into account for extra fields
     // unknown in the display.
-    $this->assertEqual($display->getComponent('display_extra_field'), array('weight' => 5));
-    $this->assertNull($display->getComponent('display_extra_field_hidden'));
+    $this->assertEqual($display->getComponent('extra_field', 'display_extra_field'), array('weight' => 5));
+    $this->assertNull($display->getComponent('extra_field', 'display_extra_field_hidden'));
 
     // Check that setting explicit options overrides the defaults.
-    $display->removeComponent('display_extra_field');
-    $display->setComponent('display_extra_field_hidden', array('weight' => 10));
-    $this->assertNull($display->getComponent('display_extra_field'));
-    $this->assertEqual($display->getComponent('display_extra_field_hidden'), array('weight' => 10));
+    $display->removeComponent('extra_field', 'display_extra_field');
+    $display->setComponent('extra_field', 'display_extra_field_hidden', array('weight' => 10));
+    $this->assertNull($display->getComponent('extra_field', 'display_extra_field'));
+    $this->assertEqual($display->getComponent('extra_field', 'display_extra_field_hidden'), array('weight' => 10));
   }
 
   /**
@@ -154,7 +154,7 @@ public function testFieldComponent() {
     $instance->save();
 
     // Check that providing no options results in default values being used.
-    $display->setComponent($field_name);
+    $display->setComponent('field', $field_name);
     $field_type_info = field_info_field_types($field->type);
     $default_formatter = $field_type_info['default_formatter'];
     $default_settings = field_info_formatter_settings($default_formatter);
@@ -164,10 +164,10 @@ public function testFieldComponent() {
       'type' => $default_formatter,
       'settings' => $default_settings,
     );
-    $this->assertEqual($display->getComponent($field_name), $expected);
+    $this->assertEqual($display->getComponent('field', $field_name), $expected);
 
-    // Check that the getFormatter() method returns the correct formatter plugin.
-    $formatter = $display->getRenderer($field_name);
+    // Check that the getRenderer() method returns the correct formatter plugin.
+    $formatter = $display->getRenderer('field', $field_name);
     $this->assertEqual($formatter->getPluginId(), $default_formatter);
     $this->assertEqual($formatter->getSettings(), $default_settings);
 
@@ -175,26 +175,26 @@ public function testFieldComponent() {
     // arbitrary property and reading it back.
     $random_value = $this->randomString();
     $formatter->randomValue = $random_value;
-    $formatter = $display->getRenderer($field_name);
+    $formatter = $display->getRenderer('field', $field_name);
     $this->assertEqual($formatter->randomValue, $random_value);
 
     // Check that changing the definition creates a new formatter.
-    $display->setComponent($field_name, array(
+    $display->setComponent('field', $field_name, array(
       'type' => 'field_test_multiple',
     ));
-    $formatter = $display->getRenderer($field_name);
+    $formatter = $display->getRenderer('field', $field_name);
     $this->assertEqual($formatter->getPluginId(), 'field_test_multiple');
     $this->assertFalse(isset($formatter->randomValue));
 
     // Check that specifying an unknown formatter (e.g. case of a disabled
     // module) gets stored as is in the display, but results in the default
     // formatter being used.
-    $display->setComponent($field_name, array(
+    $display->setComponent('field', $field_name, array(
       'type' => 'unknown_formatter',
     ));
-    $options = $display->getComponent($field_name);
+    $options = $display->getComponent('field', $field_name);
     $this->assertEqual($options['type'], 'unknown_formatter');
-    $formatter = $display->getRenderer($field_name);
+    $formatter = $display->getRenderer('field', $field_name);
     $this->assertEqual($formatter->getPluginId(), $default_formatter);
   }
 
@@ -252,14 +252,14 @@ public function testDeleteFieldInstance() {
       'targetEntityType' => 'entity_test',
       'bundle' => 'entity_test',
       'viewMode' => 'default',
-    ))->setComponent($field_name)->save();
+    ))->setComponent('field', $field_name)->save();
 
     // Delete the instance.
     $instance->delete();
 
     // Check that the component has been removed from the entity display.
     $display = entity_get_display('entity_test', 'entity_test', 'default');
-    $this->assertFalse($display->getComponent($field_name));
+    $this->assertFalse($display->getComponent('field', $field_name));
   }
 
 }
diff --git a/core/modules/entity/lib/Drupal/entity/Tests/EntityFormDisplayTest.php b/core/modules/entity/lib/Drupal/entity/Tests/EntityFormDisplayTest.php
index a74c966..3c781a6 100644
--- a/core/modules/entity/lib/Drupal/entity/Tests/EntityFormDisplayTest.php
+++ b/core/modules/entity/lib/Drupal/entity/Tests/EntityFormDisplayTest.php
@@ -39,14 +39,14 @@ public function testEntityGetFromDisplay() {
     $this->assertTrue($form_display->isNew());
 
     // Add some components and save the display.
-    $form_display->setComponent('component_1', array('weight' => 10))
+    $form_display->setComponent('default', 'component_1', array('weight' => 10))
       ->save();
 
     // Check that entity_get_form_display() returns the correct object.
     $form_display = entity_get_form_display('entity_test', 'entity_test', 'default');
     $this->assertFalse($form_display->isNew());
     $this->assertEqual($form_display->id, 'entity_test.entity_test.default');
-    $this->assertEqual($form_display->getComponent('component_1'), array('weight' => 10));
+    $this->assertEqual($form_display->getComponent('default', 'component_1'), array('weight' => 10));
   }
 
   /**
@@ -76,7 +76,7 @@ public function testFieldComponent() {
     $instance->save();
 
     // Check that providing no options results in default values being used.
-    $form_display->setComponent($field_name);
+    $form_display->setComponent('field', $field_name);
     $field_type_info = field_info_field_types($field->type);
     $default_widget = $field_type_info['default_widget'];
     $default_settings = field_info_widget_settings($default_widget);
@@ -85,7 +85,7 @@ public function testFieldComponent() {
       'type' => $default_widget,
       'settings' => $default_settings,
     );
-    $this->assertEqual($form_display->getComponent($field_name), $expected);
+    $this->assertEqual($form_display->getComponent('field', $field_name), $expected);
 
     // Check that the getWidget() method returns the correct widget plugin.
     $widget = $form_display->getRenderer($field_name);
@@ -100,7 +100,7 @@ public function testFieldComponent() {
     $this->assertEqual($widget->randomValue, $random_value);
 
     // Check that changing the definition creates a new widget.
-    $form_display->setComponent($field_name, array(
+    $form_display->setComponent('field', $field_name, array(
       'type' => 'field_test_multiple',
     ));
     $widget = $form_display->getRenderer($field_name);
@@ -110,10 +110,10 @@ public function testFieldComponent() {
     // Check that specifying an unknown widget (e.g. case of a disabled module)
     // gets stored as is in the display, but results in the default widget being
     // used.
-    $form_display->setComponent($field_name, array(
+    $form_display->setComponent('field', $field_name, array(
       'type' => 'unknown_widget',
     ));
-    $options = $form_display->getComponent($field_name);
+    $options = $form_display->getComponent('field', $field_name);
     $this->assertEqual($options['type'], 'unknown_widget');
     $widget = $form_display->getRenderer($field_name);
     $this->assertEqual($widget->getPluginId(), $default_widget);
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/EntityReferenceAutocomplete.php b/core/modules/entity_reference/lib/Drupal/entity_reference/EntityReferenceAutocomplete.php
index f1e9178..1c37d1f 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/EntityReferenceAutocomplete.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/EntityReferenceAutocomplete.php
@@ -75,7 +75,7 @@ public function getMatches($field, $instance, $entity_type, $entity_id = '', $pr
 
     if (isset($string)) {
       // Get an array of matching entities.
-      $widget = entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')->getComponent($instance['field_name']);
+      $widget = entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')->getComponent('field', $instance['field_name']);
       $match_operator = !empty($widget['settings']['match_operator']) ? $widget['settings']['match_operator'] : 'CONTAINS';
       $entity_labels = $handler->getReferenceableEntities($string, $match_operator, 10);
 
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutoCreateTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutoCreateTest.php
index f5f74d0..58941b1 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutoCreateTest.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutoCreateTest.php
@@ -65,10 +65,10 @@ function setUp() {
     ))->save();
 
     entity_get_display('node', $referencing->type, 'default')
-      ->setComponent('test_field')
+      ->setComponent('field', 'test_field')
       ->save();
     entity_get_form_display('node', $referencing->type, 'default')
-      ->setComponent('test_field', array(
+      ->setComponent('field', 'test_field', array(
         'type' => 'entity_reference_autocomplete',
       ))
       ->save();
diff --git a/core/modules/field/field.attach.inc b/core/modules/field/field.attach.inc
index 5ed17ff..a950b8e 100644
--- a/core/modules/field/field.attach.inc
+++ b/core/modules/field/field.attach.inc
@@ -402,7 +402,7 @@ function _field_invoke_get_instances($entity_type, $bundle, $options) {
  */
 function _field_invoke_widget_target($form_display) {
   return function ($instance) use ($form_display) {
-    return $form_display->getRenderer($instance['field_name']);
+    return $form_display->getRenderer('field', $instance['field_name']);
   };
 }
 
@@ -1048,7 +1048,7 @@ function field_attach_prepare_view($entity_type, array $entities, array $display
   // the entity display.
   $target_function = function ($instance) use ($displays) {
     if (isset($displays[$instance['bundle']])) {
-      return $displays[$instance['bundle']]->getRenderer($instance['field_name']);
+      return $displays[$instance['bundle']]->getRenderer('field', $instance['field_name']);
     }
   };
   $null = NULL;
@@ -1093,7 +1093,7 @@ function field_attach_view(EntityInterface $entity, EntityDisplay $display, $lan
   // For each instance, call the view() method on the formatter object handed
   // by the entity display.
   $target_function = function ($instance) use ($display) {
-    return $display->getRenderer($instance['field_name']);
+    return $display->getRenderer('field', $instance['field_name']);
   };
   $null = NULL;
   $output = field_invoke_method('view', $target_function, $entity, $null, $null, $options);
diff --git a/core/modules/field/field.info.inc b/core/modules/field/field.info.inc
index b6b2a95..70ad748 100644
--- a/core/modules/field/field.info.inc
+++ b/core/modules/field/field.info.inc
@@ -129,7 +129,7 @@ function _field_info_collate_types_reset() {
  */
 function field_behaviors_widget($op, $instance) {
   $info = array();
-  if ($component = entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')->getComponent($instance['field_name'])) {
+  if ($component = entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')->getComponent('field', $instance['field_name'])) {
     $info = field_info_widget_types($component['type']);
   }
   return isset($info[$op]) ? $info[$op] : FIELD_BEHAVIOR_DEFAULT;
diff --git a/core/modules/field/field.install b/core/modules/field/field.install
index b425169..fdfaf7b 100644
--- a/core/modules/field/field.install
+++ b/core/modules/field/field.install
@@ -127,6 +127,7 @@ function field_update_8002() {
     // Migrate 'widget' settings.
     if (isset($data['widget'])) {
       $widget_options = $data['widget'];
+      $widget_options['handler_type'] = 'field';
       // Determine name and create initial entry in the $form_displays array.
       $form_display_id = $record->entity_type . '.' . $record->bundle . '.default';
       if (!isset($form_displays[$form_display_id])) {
@@ -135,6 +136,7 @@ function field_update_8002() {
 
       // We do not need the 'module' key anymore.
       unset($widget_options['module']);
+      $display_options['handler_type'] = 'field';
       $form_displays[$form_display_id]->set("content.$record->field_name", $widget_options);
     }
 
@@ -205,7 +207,10 @@ function field_update_8002() {
             }
 
             // Set options in the display.
-            $new_options = array('visible' => $display_options['visible']);
+            $new_options = array(
+              'handler_type' => 'extra_field',
+              'visible' => $display_options['visible']
+            );
             // The display object only stores the weight for 'visible' extra
             // fields.
             if ($display_options['visible']) {
diff --git a/core/modules/field/field.module b/core/modules/field/field.module
index ce9c5fa..8f08c4e 100644
--- a/core/modules/field/field.module
+++ b/core/modules/field/field.module
@@ -748,7 +748,7 @@ function field_view_value(EntityInterface $entity, $field_name, $item, $display
  *     - 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
+ *     - formatter: (string) The formatter to use. Defaults to the
  *       'default_formatter' for the field type. The default formatter will also
  *       be used if the requested formatter is not available.
  *     - settings: (array) Settings specific to the formatter. Defaults to the
@@ -780,7 +780,7 @@ function field_view_field(EntityInterface $entity, $field_name, $display_options
   // Get the formatter object.
   if (is_string($display_options)) {
     $view_mode = $display_options;
-    $formatter = entity_get_render_display($entity, $view_mode)->getRenderer($field_name);
+    $formatter = entity_get_render_display($entity, $view_mode)->getRenderer('field', $field_name);
   }
   else {
     $view_mode = '_custom';
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/FieldInstance.php b/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/FieldInstance.php
index 5f7e435..3160f0f 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/FieldInstance.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/FieldInstance.php
@@ -464,7 +464,7 @@ public function delete($field_cleanup = TRUE) {
 
       // Remove the instance from the entity form displays.
       if ($form_display = entity_load('entity_form_display', $this->entity_type . '.' . $this->bundle . '.default')) {
-        $form_display->removeComponent($this->field->id())->save();
+        $form_display->removeComponent('field', $this->field->id())->save();
       }
 
       // Remove the instance from the entity displays.
@@ -474,7 +474,7 @@ public function delete($field_cleanup = TRUE) {
         $ids[] = $this->entity_type . '.' . $this->bundle . '.' . $view_mode;
       }
       foreach (entity_load_multiple('entity_display', $ids) as $display) {
-        $display->removeComponent($this->field->id())->save();
+        $display->removeComponent('field', $this->field->id())->save();
       }
 
       // Delete the field itself if we just deleted its last instance.
diff --git a/core/modules/field/lib/Drupal/field/Plugin/DisplayComponent/FieldDisplayComponentHandler.php b/core/modules/field/lib/Drupal/field/Plugin/DisplayComponent/FieldDisplayComponentHandler.php
new file mode 100644
index 0000000..96d4a46
--- /dev/null
+++ b/core/modules/field/lib/Drupal/field/Plugin/DisplayComponent/FieldDisplayComponentHandler.php
@@ -0,0 +1,49 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\field\Plugin\DisplayComponent\FieldDisplayComponentHandler.
+ */
+
+namespace Drupal\field\Plugin\DisplayComponent;
+
+use Drupal\entity\Annotation\DisplayComponent;
+use Drupal\entity\Plugin\Type\DisplayComponentHandlerBase;
+
+/**
+ * @todo
+ *
+ * @DisplayComponent(
+ *   id = "field"
+ * )
+ */
+class FieldDisplayComponentHandler extends DisplayComponentHandlerBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function massageIn($name, array $options = NULL) {
+    if ($options !== NULL) {
+      // @todo do we need to check the field exists on the bundle ?
+      // Do we need a more general check by the handler that the $name is a valid component ?
+      $field = field_info_field($name);
+      return drupal_container()->get('plugin.manager.field.formatter')->prepareConfiguration($field['type'], $options);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getRenderer($name, array $options = NULL) {
+    if ($options) {
+      return drupal_container()->get('plugin.manager.field.formatter')->getInstance(array(
+        'field_definition' => field_info_instance($this->context['entity_type'], $name, $this->context['bundle']),
+        'view_mode' => $this->context['view_mode'],
+        'configuration' => $options,
+        // No need to prepare, defaults have been merged when the options were written in the display.
+        'prepare' => FALSE,
+      ));
+    }
+  }
+
+}
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php
index 39deee9..29385d4 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php
@@ -64,7 +64,7 @@ public function createInstance($plugin_id, array $configuration) {
    *     - 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
+   *     - formatter: (string) The formatter to use. Defaults to the
    *       'default_formatter' for the field type, The default formatter will
    *       also be used if the requested formatter is not available.
    *     - settings: (array) Settings specific to the formatter. Each setting
@@ -88,7 +88,7 @@ public function getInstance(array $options) {
     // Switch back to default formatter if either:
     // - $type_info doesn't exist (the widget type is unknown),
     // - the field type is not allowed for the widget.
-    $definition = $this->getDefinition($configuration['type']);
+    $definition = $this->getDefinition($plugin_id);
     if (!isset($definition['class']) || !in_array($field_type, $definition['field_types'])) {
       // Grab the default widget for the field type.
       $field_type_definition = field_info_field_types($field_type);
diff --git a/core/modules/field/lib/Drupal/field/Tests/DisplayApiTest.php b/core/modules/field/lib/Drupal/field/Tests/DisplayApiTest.php
index 70195d3..a6c7552 100644
--- a/core/modules/field/lib/Drupal/field/Tests/DisplayApiTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/DisplayApiTest.php
@@ -100,11 +100,11 @@ function setUp() {
     entity_create('field_instance', $instance)->save();
     // Create a display for the default view mode.
     entity_get_display($instance['entity_type'], $instance['bundle'], 'default')
-      ->setComponent($this->field_name, $this->display_options['default'])
+      ->setComponent('field', $this->field_name, $this->display_options['default'])
       ->save();
     // Create a display for the teaser view mode.
     entity_get_display($instance['entity_type'], $instance['bundle'], 'teaser')
-      ->setComponent($this->field_name, $this->display_options['teaser'])
+      ->setComponent('field', $this->field_name, $this->display_options['teaser'])
       ->save();
 
     // Create an entity with values.
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldAccessTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldAccessTest.php
index 58fb767..b4c487f 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldAccessTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldAccessTest.php
@@ -66,7 +66,7 @@ function setUp() {
     // Assign display properties for the 'default' and 'teaser' view modes.
     foreach (array('default', 'teaser') as $view_mode) {
       entity_get_display('node', $content_type, $view_mode)
-        ->setComponent($field['field_name'])
+        ->setComponent('field', $field['field_name'])
         ->save();
     }
 
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php
index 4739d5f..f224e86 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php
@@ -71,7 +71,7 @@ function testFieldAttachView() {
         'test_formatter_setting' => $formatter_setting,
       ),
     );
-    $display->setComponent($this->field['field_name'], $display_options);
+    $display->setComponent('field', $this->field['field_name'], $display_options);
 
     $formatter_setting_2 = $this->randomName();
     $display_options_2 = array(
@@ -81,7 +81,7 @@ function testFieldAttachView() {
         'test_formatter_setting' => $formatter_setting_2,
       ),
     );
-    $display->setComponent($this->field_2['field_name'], $display_options_2);
+    $display->setComponent('field', $this->field_2['field_name'], $display_options_2);
 
     // View all fields.
     field_attach_prepare_view($entity_type, array($entity->id() => $entity), $displays);
@@ -102,7 +102,7 @@ function testFieldAttachView() {
     // Label hidden.
     $entity = clone($entity_init);
     $display_options['label'] = 'hidden';
-    $display->setComponent($this->field['field_name'], $display_options);
+    $display->setComponent('field', $this->field['field_name'], $display_options);
     field_attach_prepare_view($entity_type, array($entity->id() => $entity), $displays);
     $entity->content = field_attach_view($entity, $display);
     $output = drupal_render($entity->content);
@@ -124,7 +124,7 @@ function testFieldAttachView() {
     // Multiple formatter.
     $entity = clone($entity_init);
     $formatter_setting = $this->randomName();
-    $display->setComponent($this->field['field_name'], array(
+    $display->setComponent('field', $this->field['field_name'], array(
       'label' => 'above',
       'type' => 'field_test_multiple',
       'settings' => array(
@@ -144,7 +144,7 @@ function testFieldAttachView() {
     // Test a formatter that uses hook_field_formatter_prepare_view().
     $entity = clone($entity_init);
     $formatter_setting = $this->randomName();
-    $display->setComponent($this->field['field_name'], array(
+    $display->setComponent('field', $this->field['field_name'], array(
       'label' => 'above',
       'type' => 'field_test_with_prepare_view',
       'settings' => array(
@@ -196,7 +196,7 @@ function testFieldAttachPrepareViewMultiple() {
     $this->instance2->save();
 
     $display_2 = entity_get_display('entity_test', 'test_bundle_2', 'full')
-      ->setComponent($this->field['field_name'], array(
+      ->setComponent('field', $this->field['field_name'], array(
         'type' => 'field_test_with_prepare_view',
         'settings' => array(
           'test_formatter_setting_additional' => $formatter_setting,
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldUnitTestBase.php b/core/modules/field/lib/Drupal/field/Tests/FieldUnitTestBase.php
index 4580e7b..683b0bd 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldUnitTestBase.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldUnitTestBase.php
@@ -82,7 +82,7 @@ function createFieldWithInstance($suffix = '', $entity_type = 'entity_test', $bu
     $this->$instance->save();
 
     entity_get_form_display($entity_type, $bundle, 'default')
-      ->setComponent($this->$field_name, array(
+      ->setComponent('field', $this->$field_name, array(
         'type' => 'test_field_widget',
         'settings' => array(
           'test_widget_setting' => $this->randomName(),
diff --git a/core/modules/field/lib/Drupal/field/Tests/FormTest.php b/core/modules/field/lib/Drupal/field/Tests/FormTest.php
index b7c600e..30a73ec 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FormTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FormTest.php
@@ -84,7 +84,7 @@ function testFieldFormSingle() {
     entity_create('field_entity', $field)->save();
     entity_create('field_instance', $this->instance)->save();
     entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
-      ->setComponent($field_name)
+      ->setComponent('field', $field_name)
       ->save();
     $langcode = Language::LANGCODE_NOT_SPECIFIED;
 
@@ -169,7 +169,7 @@ function testFieldFormDefaultValue() {
     entity_create('field_entity', $field)->save();
     entity_create('field_instance', $this->instance)->save();
     entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
-      ->setComponent($field_name)
+      ->setComponent('field', $field_name)
       ->save();
     $langcode = Language::LANGCODE_NOT_SPECIFIED;
 
@@ -200,7 +200,7 @@ function testFieldFormSingleRequired() {
     entity_create('field_entity', $field)->save();
     entity_create('field_instance', $this->instance)->save();
     entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
-      ->setComponent($field_name)
+      ->setComponent('field', $field_name)
       ->save();
     $langcode = Language::LANGCODE_NOT_SPECIFIED;
 
@@ -249,7 +249,7 @@ function testFieldFormUnlimited() {
     entity_create('field_entity', $field)->save();
     entity_create('field_instance', $this->instance)->save();
     entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
-      ->setComponent($field_name)
+      ->setComponent('field', $field_name)
       ->save();
     $langcode = Language::LANGCODE_NOT_SPECIFIED;
 
@@ -336,7 +336,7 @@ function testFieldFormMultivalueWithRequiredRadio() {
     entity_create('field_entity', $field)->save();
     entity_create('field_instance', $this->instance)->save();
     entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
-      ->setComponent($field_name)
+      ->setComponent('field', $field_name)
       ->save();
     $langcode = Language::LANGCODE_NOT_SPECIFIED;
 
@@ -356,7 +356,7 @@ function testFieldFormMultivalueWithRequiredRadio() {
     );
     entity_create('field_instance', $instance)->save();
     entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')
-      ->setComponent($instance['field_name'], array(
+      ->setComponent('field', $instance['field_name'], array(
         'type' => 'options_buttons',
       ))
       ->save();
@@ -383,7 +383,7 @@ function testFieldFormJSAddMore() {
     entity_create('field_entity', $field)->save();
     entity_create('field_instance', $this->instance)->save();
     entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
-      ->setComponent($field_name)
+      ->setComponent('field', $field_name)
       ->save();
     $langcode = Language::LANGCODE_NOT_SPECIFIED;
 
@@ -445,7 +445,7 @@ function testFieldFormMultipleWidget() {
     entity_create('field_entity', $field)->save();
     entity_create('field_instance', $this->instance)->save();
     entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
-      ->setComponent($field_name, array(
+      ->setComponent('field', $field_name, array(
         'type' => 'test_field_widget_multiple',
       ))
       ->save();
@@ -496,7 +496,7 @@ function testFieldFormAccess() {
     entity_create('field_entity', $field)->save();
     entity_create('field_instance', $instance)->save();
     entity_get_form_display($entity_type, $entity_type, 'default')
-      ->setComponent($field_name)
+      ->setComponent('field', $field_name)
       ->save();
 
     // Create a field with no edit access - see field_test_field_access().
@@ -514,7 +514,7 @@ function testFieldFormAccess() {
     entity_create('field_entity', $field_no_access)->save();
     entity_create('field_instance', $instance_no_access)->save();
     entity_get_form_display($instance_no_access['entity_type'], $instance_no_access['bundle'], 'default')
-      ->setComponent($field_name_no_access)
+      ->setComponent('field', $field_name_no_access)
       ->save();
 
     $langcode = Language::LANGCODE_NOT_SPECIFIED;
@@ -586,7 +586,7 @@ function testFieldFormHiddenWidget() {
     $this->instance = entity_create('field_instance', $this->instance);
     $this->instance->save();
     entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
-      ->setComponent($this->instance['field_name'], array(
+      ->setComponent('field', $this->instance['field_name'], array(
         'type' => 'hidden',
       ))
       ->save();
@@ -610,7 +610,7 @@ function testFieldFormHiddenWidget() {
     $this->instance['default_value'] = NULL;
     $this->instance->save();
     entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
-      ->setComponent($this->instance['field_name'], array(
+      ->setComponent('field', $this->instance['field_name'], array(
         'type' => 'test_field_widget',
       ))
       ->save();
@@ -630,7 +630,7 @@ function testFieldFormHiddenWidget() {
 
     // Update the form display and switch to the Hidden widget again.
     entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
-      ->setComponent($this->instance['field_name'], array(
+      ->setComponent('field', $this->instance['field_name'], array(
         'type' => 'hidden',
       ))
       ->save();
diff --git a/core/modules/field/lib/Drupal/field/Tests/NestedFormTest.php b/core/modules/field/lib/Drupal/field/Tests/NestedFormTest.php
index 3d180f6..f17cd2d 100644
--- a/core/modules/field/lib/Drupal/field/Tests/NestedFormTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/NestedFormTest.php
@@ -59,13 +59,13 @@ function testNestedFieldForm() {
     $this->instance['label'] = 'Single field';
     entity_create('field_instance', $this->instance)->save();
     entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
-      ->setComponent($this->instance['field_name'])
+      ->setComponent('field', $this->instance['field_name'])
       ->save();
     $this->instance['field_name'] = 'field_unlimited';
     $this->instance['label'] = 'Unlimited field';
     entity_create('field_instance', $this->instance)->save();
     entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
-      ->setComponent($this->instance['field_name'])
+      ->setComponent('field', $this->instance['field_name'])
       ->save();
 
     // Create two entities.
diff --git a/core/modules/field/lib/Drupal/field/Tests/TranslationWebTest.php b/core/modules/field/lib/Drupal/field/Tests/TranslationWebTest.php
index 8fdf064..6dd7fb6 100644
--- a/core/modules/field/lib/Drupal/field/Tests/TranslationWebTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/TranslationWebTest.php
@@ -82,7 +82,7 @@ function setUp() {
     $this->instance = field_read_instance($this->entity_type, $this->field_name, $this->entity_type);
 
     entity_get_form_display($this->entity_type, $this->entity_type, 'default')
-      ->setComponent($this->field_name)
+      ->setComponent('field', $this->field_name)
       ->save();
 
     for ($i = 0; $i < 3; ++$i) {
diff --git a/core/modules/field/lib/Drupal/field/Tests/Views/FieldUITest.php b/core/modules/field/lib/Drupal/field/Tests/Views/FieldUITest.php
index 5c9b253..0ede906 100644
--- a/core/modules/field/lib/Drupal/field/Tests/Views/FieldUITest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/Views/FieldUITest.php
@@ -50,7 +50,7 @@ public function testHandlerUI() {
     $this->drupalGet($url);
 
     // Tests the available formatter options.
-    $result = $this->xpath('//select[@id=:id]/option', array(':id' => 'edit-options-type'));
+    $result = $this->xpath('//select[@id=:id]/option', array(':id' => 'edit-options-formatter'));
     $options = array_map(function($item) {
       return (string) $item->attributes()->value[0];
     }, $result);
@@ -58,10 +58,10 @@ public function testHandlerUI() {
     sort($options, SORT_STRING);
     $this->assertEqual($options, array('text_default', 'text_plain', 'text_trimmed'), 'The text formatters for a simple text field appear as expected.');
 
-    $this->drupalPost(NULL, array('options[type]' => 'text_trimmed'), t('Apply'));
+    $this->drupalPost(NULL, array('options[formatter]' => 'text_trimmed'), t('Apply'));
 
     $this->drupalGet($url);
-    $this->assertOptionSelected('edit-options-type', 'text_trimmed');
+    $this->assertOptionSelected('edit-options-formatter', 'text_trimmed');
 
     $random_number = rand(100, 400);
     $this->drupalPost(NULL, array('options[settings][trim_length]' => $random_number), t('Apply'));
diff --git a/core/modules/field/tests/modules/field_test/field_test.module b/core/modules/field/tests/modules/field_test/field_test.module
index 800f4d4..06fdf55 100644
--- a/core/modules/field/tests/modules/field_test/field_test.module
+++ b/core/modules/field/tests/modules/field_test/field_test.module
@@ -218,7 +218,7 @@ function field_test_field_formatter_settings_form_alter(&$element, &$form_state,
   $element['field_test_formatter_settings_form_alter'] = array(
     '#type' => 'textfield',
     '#title' => t('Formatter settings form alter'),
-    '#default_value' => $context['formatter']->getSetting('field_test_formatter_settings_form_alter'),
+    '#default_value' => $context['type']->getSetting('field_test_formatter_settings_form_alter'),
   );
 }
 
diff --git a/core/modules/field_ui/field_ui.api.php b/core/modules/field_ui/field_ui.api.php
index 176993d..b6cd8d6 100644
--- a/core/modules/field_ui/field_ui.api.php
+++ b/core/modules/field_ui/field_ui.api.php
@@ -30,11 +30,11 @@
 function hook_field_formatter_settings_form_alter(&$element, &$form_state, $context) {
   // Add a 'mysetting' checkbox to the settings form for 'foo_formatter'
   // field formatters.
-  if ($context['formatter']->getPluginId() == 'foo_formatter') {
+  if ($context['type']->getPluginId() == 'foo_formatter') {
     $element['mysetting'] = array(
       '#type' => 'checkbox',
       '#title' => t('My setting'),
-      '#default_value' => $context['formatter']->getSetting('mysetting'),
+      '#default_value' => $context['type']->getSetting('mysetting'),
     );
   }
 }
@@ -62,7 +62,7 @@ function hook_field_widget_settings_form_alter(&$element, &$form_state, $context
     $element['mysetting'] = array(
       '#type' => 'checkbox',
       '#title' => t('My setting'),
-      '#default_value' => $context['formatter']->getSetting('mysetting'),
+      '#default_value' => $context['type']->getSetting('mysetting'),
     );
   }
 }
@@ -84,10 +84,8 @@ function hook_field_widget_settings_form_alter(&$element, &$form_state, $context
 function hook_field_formatter_settings_summary_alter(&$summary, $context) {
   // Append a message to the summary when an instance of foo_formatter has
   // mysetting set to TRUE for the current view mode.
-  if ($context['formatter']->getPluginId() == 'foo_formatter') {
-    if ($context['formatter']->getSetting('mysetting')) {
-      $summary[] = t('My setting enabled.');
-    }
+  if ($context['type']->getPluginId() == 'foo_formatter') {
+    $summary[] = t('My setting enabled.');
   }
 }
 
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 841c056..20126ed 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php
@@ -38,9 +38,9 @@ public function getFormID() {
   /**
    * {@inheritdoc}
    */
-  protected function buildFieldRow($field_id, FieldInstanceInterface $instance, EntityDisplayBaseInterface $entity_display, array $form, array &$form_state) {
-    $field_row = parent::buildFieldRow($field_id, $instance, $entity_display, $form, $form_state);
-    $display_options = $entity_display->getComponent($field_id);
+  protected function buildFieldRow($type, $field_id, FieldInstanceInterface $instance, EntityDisplayBaseInterface $entity_display, array $form, array &$form_state) {
+    $field_row = parent::buildFieldRow($type, $field_id, $instance, $entity_display, $form, $form_state);
+    $display_options = $entity_display->getComponent('field', $field_id);
 
     // Insert the label column.
     $label = array(
@@ -69,8 +69,8 @@ protected function buildFieldRow($field_id, FieldInstanceInterface $instance, En
   /**
    * {@inheritdoc}
    */
-  protected function buildExtraFieldRow($field_id, $extra_field, $entity_display) {
-    $extra_field_row = parent::buildExtraFieldRow($field_id, $extra_field, $entity_display);
+  protected function buildExtraFieldRow($type, $field_id, $extra_field, $entity_display) {
+    $extra_field_row = parent::buildExtraFieldRow($type, $field_id, $extra_field, $entity_display);
 
     // Insert an empty placeholder for the label column.
     $label = array(
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverviewBase.php b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverviewBase.php
index 5a45c21..1ba34ba 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverviewBase.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverviewBase.php
@@ -112,12 +112,12 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL,
 
     // Field rows.
     foreach ($instances as $field_id => $instance) {
-      $table[$field_id] = $this->buildFieldRow($field_id, $instance, $entity_display, $form, $form_state);
+      $table[$field_id] = $this->buildFieldRow('field', $field_id, $instance, $entity_display, $form, $form_state);
     }
 
     // Non-field elements.
     foreach ($extra_fields as $field_id => $extra_field) {
-      $table[$field_id] = $this->buildExtraFieldRow($field_id, $extra_field, $entity_display);
+      $table[$field_id] = $this->buildExtraFieldRow('extra_field', $field_id, $extra_field, $entity_display);
     }
 
     $form['fields'] = $table;
@@ -189,6 +189,8 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL,
   /**
    * Builds the table row structure for a single field.
    *
+   * @param string $type
+   *   The component type.
    * @param string $field_id
    *   The field ID.
    * @param \Drupal\field\FieldInstanceInterface $instance
@@ -203,9 +205,9 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL,
    * @return array
    *   A table row array.
    */
-  protected function buildFieldRow($field_id, FieldInstanceInterface $instance, EntityDisplayBaseInterface $entity_display, array $form, array &$form_state) {
+  protected function buildFieldRow($type, $field_id, FieldInstanceInterface $instance, EntityDisplayBaseInterface $entity_display, array $form, array &$form_state) {
     $field = $instance->getField();
-    $display_options = $entity_display->getComponent($field_id);
+    $display_options = $entity_display->getComponent($type, $field_id);
 
     $field_row = array(
       '#attributes' => array('class' => array('draggable', 'tabledrag-leaf')),
@@ -373,8 +375,8 @@ protected function buildFieldRow($field_id, FieldInstanceInterface $instance, En
    * @return array
    *   A table row array.
    */
-  protected function buildExtraFieldRow($field_id, $extra_field, $entity_display) {
-    $display_options = $entity_display->getComponent($field_id);
+  protected function buildExtraFieldRow($type, $field_id, $extra_field, $entity_display) {
+    $display_options = $entity_display->getComponent($type, $field_id);
 
     $extra_field_row = array(
       '#attributes' => array('class' => array('draggable', 'tabledrag-leaf')),
@@ -440,7 +442,7 @@ public function submitForm(array &$form, array &$form_state) {
       $values = $form_values['fields'][$field_name];
 
       if ($values['type'] == 'hidden') {
-        $display->removeComponent($field_name);
+        $display->removeComponent('field', $field_name);
       }
       else {
         // Get plugin settings. They lie either directly in submitted form
@@ -453,7 +455,7 @@ public function submitForm(array &$form, array &$form_state) {
         elseif (isset($form_state['plugin_settings'][$field_name])) {
           $settings = $form_state['plugin_settings'][$field_name];
         }
-        elseif ($current_options = $display->getComponent($field_name)) {
+        elseif ($current_options = $display->getComponent('field', $field_name)) {
           $settings = $current_options['settings'];
         }
 
@@ -473,17 +475,17 @@ public function submitForm(array &$form, array &$form_state) {
           $component_values['label'] = $values['label'];
         }
 
-        $display->setComponent($field_name, $component_values);
+        $display->setComponent('field', $field_name, $component_values);
       }
     }
 
     // Collect data for 'extra' fields.
     foreach ($form['#extra'] as $name) {
       if ($form_values['fields'][$name]['type'] == 'hidden') {
-        $display->removeComponent($name);
+        $display->removeComponent('extra_field', $name);
       }
       else {
-        $display->setComponent($name, array(
+        $display->setComponent('extra_field', $name, array(
           'weight' => $form_values['fields'][$name]['weight'],
         ));
       }
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 8e7e770..a443286 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php
@@ -357,14 +357,14 @@ public function submitForm(array &$form, array &$form_state) {
         // default widget and settings). It stays hidden for other form modes
         // until it is explicitly configured.
         entity_get_form_display($this->entity_type, $this->bundle, 'default')
-          ->setComponent($field['field_name'])
+          ->setComponent('field', $field['field_name'])
           ->save();
 
         // Make sure the field is displayed in the 'default' view mode (using
         // default formatter and settings). It stays hidden for other view
         // modes until it is explicitly configured.
         entity_get_display($this->entity_type, $this->bundle, 'default')
-          ->setComponent($field['field_name'])
+          ->setComponent('field', $field['field_name'])
           ->save();
 
         // Always show the field settings step, as the cardinality needs to be
@@ -403,14 +403,14 @@ public function submitForm(array &$form, array &$form_state) {
           // default widget and settings). It stays hidden for other form modes
           // until it is explicitly configured.
           entity_get_form_display($this->entity_type, $this->bundle, 'default')
-            ->setComponent($field['field_name'])
+            ->setComponent('field', $field['field_name'])
             ->save();
 
           // Make sure the field is displayed in the 'default' view mode (using
           // default formatter and settings). It stays hidden for other view
           // modes until it is explicitly configured.
           entity_get_display($this->entity_type, $this->bundle, 'default')
-            ->setComponent($field['field_name'])
+            ->setComponent('field', $field['field_name'])
             ->save();
 
           $destinations[] = $this->adminPath . '/fields/' . $new_instance->id();
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldInstanceEditForm.php b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldInstanceEditForm.php
index 26264ac..2adf906 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldInstanceEditForm.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldInstanceEditForm.php
@@ -136,7 +136,7 @@ public function validateForm(array &$form, array &$form_state) {
 
       // Extract the 'default value'.
       $items = array();
-      $entity_form_display->getRenderer($this->instance->getField()->id)->extractFormValues($entity, Language::LANGCODE_NOT_SPECIFIED, $items, $element, $form_state);
+      $entity_form_display->getRenderer('field', $this->instance->getField()->id)->extractFormValues($entity, Language::LANGCODE_NOT_SPECIFIED, $items, $element, $form_state);
 
       // @todo Simplify when all entity types are converted to EntityNG.
       if ($entity instanceof EntityNG) {
@@ -178,7 +178,7 @@ public function submitForm(array &$form, array &$form_state) {
 
       // Extract field values.
       $items = array();
-      $entity_form_display->getRenderer($this->instance->getField()->id)->extractFormValues($entity, Language::LANGCODE_NOT_SPECIFIED, $items, $element, $form_state);
+      $entity_form_display->getRenderer('field', $this->instance->getField()->id)->extractFormValues($entity, Language::LANGCODE_NOT_SPECIFIED, $items, $element, $form_state);
 
       $this->instance['default_value'] = $items ? $items : NULL;
     }
@@ -250,7 +250,7 @@ protected function getDefaultValueWidget($field, array &$form, &$form_state) {
     if (!empty($this->instance['default_value'])) {
       $items = (array) $this->instance['default_value'];
     }
-    $element += $entity_form_display->getRenderer($this->instance->getField()->id)->form($entity, Language::LANGCODE_NOT_SPECIFIED, $items, $element, $form_state);
+    $element += $entity_form_display->getRenderer('field', $this->instance->getField()->id)->form($entity, Language::LANGCODE_NOT_SPECIFIED, $items, $element, $form_state);
 
     return $element;
   }
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/FormDisplayOverview.php b/core/modules/field_ui/lib/Drupal/field_ui/FormDisplayOverview.php
index d2ab86a..6237682 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/FormDisplayOverview.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/FormDisplayOverview.php
@@ -38,8 +38,8 @@ public function getFormID() {
   /**
    * {@inheritdoc}
    */
-  protected function buildFieldRow($field_id, FieldInstanceInterface $instance, EntityDisplayBaseInterface $entity_display, array $form, array &$form_state) {
-    $field_row = parent::buildFieldRow($field_id, $instance, $entity_display, $form, $form_state);
+  protected function buildFieldRow($type, $field_id, FieldInstanceInterface $instance, EntityDisplayBaseInterface $entity_display, array $form, array &$form_state) {
+    $field_row = parent::buildFieldRow($type, $field_id, $instance, $entity_display, $form, $form_state);
 
     // Update the (invisible) title of the 'plugin' column.
     $field_row['plugin']['#title'] = t('Formatter for @title', array('@title' => $instance['label']));
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 a5d8790..732106b 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
@@ -45,7 +45,7 @@ function testFormatterUI() {
 
     // Clear the test-side cache and get the saved field instance.
     $display = entity_get_display('node', $this->type, 'default');
-    $display_options = $display->getComponent('field_test');
+    $display_options = $display->getComponent('field', 'field_test');
     $format = $display_options['type'];
     $default_settings = field_info_formatter_settings($format);
     $setting_name = key($default_settings);
@@ -70,7 +70,7 @@ function testFormatterUI() {
     // Submit the form and check that the display is updated.
     $this->drupalPost(NULL, array(), t('Save'));
     $display = entity_get_display('node', $this->type, 'default');
-    $display_options = $display->getComponent('field_test');
+    $display_options = $display->getComponent('field', 'field_test');
     $current_format = $display_options['type'];
     $current_setting_value = $display_options['settings'][$setting_name];
     $this->assertEqual($current_format, $format, 'The formatter was updated.');
@@ -111,7 +111,7 @@ public function testWidgetUI() {
 
     // Clear the test-side cache and get the saved field instance.
     $display = entity_get_form_display('node', $this->type, 'default');
-    $display_options = $display->getComponent('field_test');
+    $display_options = $display->getComponent('field', 'field_test');
     $widget_type = $display_options['type'];
     $default_settings = field_info_widget_settings($widget_type);
     $setting_name = key($default_settings);
@@ -136,7 +136,7 @@ public function testWidgetUI() {
     // Submit the form and check that the display is updated.
     $this->drupalPost(NULL, array(), t('Save'));
     $display = entity_get_form_display('node', $this->type, 'default');
-    $display_options = $display->getComponent('field_test');
+    $display_options = $display->getComponent('field', 'field_test');
     $current_widget = $display_options['type'];
     $current_setting_value = $display_options['settings'][$setting_name];
     $this->assertEqual($current_widget, $widget_type, 'The widget was updated.');
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php
index cd7037f..2f97313 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php
@@ -56,7 +56,7 @@ function setUp() {
     entity_create('field_instance', $instance)->save();
 
     entity_get_form_display('node', 'article', 'default')
-      ->setComponent('field_' . $vocabulary->id())
+      ->setComponent('field', 'field_' . $vocabulary->id())
       ->save();
   }
 
@@ -287,7 +287,7 @@ function testDefaultValue() {
     $instance->save();
 
     entity_get_form_display('node', $this->type, 'default')
-      ->setComponent($field_name)
+      ->setComponent('field', $field_name)
       ->save();
 
     $langcode = Language::LANGCODE_NOT_SPECIFIED;
@@ -324,7 +324,7 @@ function testDefaultValue() {
 
     // Change the widget to TestFieldWidgetNoDefault.
     entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')
-      ->setComponent($field_name, array(
+      ->setComponent('field', $field_name, array(
         'type' => 'test_field_widget_no_default',
       ))
       ->save();
@@ -398,7 +398,7 @@ function testLockedField() {
       'bundle' => $this->type,
     ))->save();
     entity_get_form_display('node', $this->type, 'default')
-      ->setComponent($field->id, array(
+      ->setComponent('field', $field->id, array(
         'type' => 'test_field_widget',
       ))
       ->save();
@@ -434,7 +434,7 @@ function testHiddenFields() {
     );
     entity_create('field_instance', $instance)->save();
     entity_get_form_display('node', $this->type, 'default')
-      ->setComponent($field_name)
+      ->setComponent('field', $field_name)
       ->save();
     $this->assertTrue(field_read_instance('node', $field_name, $this->type), format_string('An instance of the field %field was created programmatically.', array('%field' => $field_name)));
 
@@ -521,7 +521,7 @@ function testHelpDescriptions() {
       'bundle' => 'article',
     ))->save();
 
-    entity_get_form_display('node', 'article', 'default')->setComponent('field_image')->save();
+    entity_get_form_display('node', 'article', 'default')->setComponent('field', 'field_image')->save();
 
     $edit = array(
       'instance[description]' => '<strong>Test with an upload field.',
diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldDisplayTest.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldDisplayTest.php
index 29ba4ef..b3af5ad 100644
--- a/core/modules/file/lib/Drupal/file/Tests/FileFieldDisplayTest.php
+++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldDisplayTest.php
@@ -46,7 +46,7 @@ function testNodeDisplay() {
     $file_formatters = array('file_table', 'file_url_plain', 'hidden', 'file_default');
     foreach ($file_formatters as $formatter) {
       $edit = array(
-        "fields[$field_name][type]" => $formatter,
+        "fields[$field_name][formatter]" => $formatter,
       );
       $this->drupalPost("admin/structure/types/manage/$type_name/display", $edit, t('Save'));
       $this->drupalGet('node/' . $node->nid);
diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldRSSContentTest.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldRSSContentTest.php
index e241dea..4bcbb95 100644
--- a/core/modules/file/lib/Drupal/file/Tests/FileFieldRSSContentTest.php
+++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldRSSContentTest.php
@@ -54,7 +54,7 @@ function testFileFieldRSSContent() {
 
     // Change the format to 'RSS enclosure'.
     $this->drupalGet("admin/structure/types/manage/$type_name/display/rss");
-    $edit = array("fields[$field_name][type]" => 'file_rss_enclosure');
+    $edit = array("fields[$field_name][formatter]" => 'file_rss_enclosure');
     $this->drupalPost(NULL, $edit, t('Save'));
 
     // Create a new node with a file field set. Promote to frontpage
diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php
index 965c44d..01e7ca5 100644
--- a/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php
+++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php
@@ -110,7 +110,7 @@ function attachFileField($name, $entity_type, $bundle, $instance_settings = arra
     entity_create('field_instance', $instance)->save();
 
     entity_get_form_display($entity_type, $bundle, 'default')
-      ->setComponent($name, array(
+      ->setComponent('field', $name, array(
         'type' => 'file_generic',
         'settings' => $widget_settings,
       ))
@@ -127,7 +127,7 @@ function updateFileField($name, $type_name, $instance_settings = array(), $widge
     $instance->save();
 
     entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')
-      ->setComponent($instance['field_name'], array(
+      ->setComponent('field', $instance['field_name'], array(
         'settings' => $widget_settings,
       ))
       ->save();
diff --git a/core/modules/forum/forum.install b/core/modules/forum/forum.install
index d44da5c..b266161 100644
--- a/core/modules/forum/forum.install
+++ b/core/modules/forum/forum.install
@@ -86,20 +86,20 @@ function forum_enable() {
 
     // Assign form display settings for the 'default' form mode.
     entity_get_form_display('node', 'forum', 'default')
-      ->setComponent('taxonomy_forums', array(
+      ->setComponent('field', 'taxonomy_forums', array(
         'type' => 'options_select',
       ))
       ->save();
 
     // Assign display settings for the 'default' and 'teaser' view modes.
     entity_get_display('node', 'forum', 'default')
-      ->setComponent('taxonomy_forums', array(
+      ->setComponent('field', 'taxonomy_forums', array(
         'type' => 'taxonomy_term_reference_link',
         'weight' => 10,
       ))
       ->save();
     entity_get_display('node', 'forum', 'teaser')
-      ->setComponent('taxonomy_forums', array(
+      ->setComponent('field', 'taxonomy_forums', array(
         'type' => 'taxonomy_term_reference_link',
         'weight' => 10,
       ))
diff --git a/core/modules/image/lib/Drupal/image/Plugin/Core/Entity/ImageStyle.php b/core/modules/image/lib/Drupal/image/Plugin/Core/Entity/ImageStyle.php
index 2e99768..4c57f50 100644
--- a/core/modules/image/lib/Drupal/image/Plugin/Core/Entity/ImageStyle.php
+++ b/core/modules/image/lib/Drupal/image/Plugin/Core/Entity/ImageStyle.php
@@ -125,22 +125,22 @@ protected static function replaceImageStyle(ImageStyle $style) {
           $view_modes = array('default') + array_keys($view_modes);
           foreach ($view_modes as $view_mode) {
             $display = entity_get_display($instance['entity_type'], $instance['bundle'], $view_mode);
-            $display_options = $display->getComponent($instance['field_name']);
+            $display_options = $display->getComponent('field', $instance['field_name']);
 
             // Check if the formatter involves an image style.
             if ($display_options && $display_options['type'] == 'image' && $display_options['settings']['image_style'] == $style->getOriginalID()) {
               // Update display information for any instance using the image
               // style that was just deleted.
               $display_options['settings']['image_style'] = $style->id();
-              $display->setComponent($instance['field_name'], $display_options)
+              $display->setComponent('field', $instance['field_name'], $display_options)
                 ->save();
             }
           }
           $entity_form_display = entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default');
-          $widget_configuration = $entity_form_display->getComponent($instance['field_name']);
+          $widget_configuration = $entity_form_display->getComponent('field', $instance['field_name']);
           if ($widget_configuration['settings']['preview_image_style'] == $style->getOriginalID()) {
             $widget_options['settings']['preview_image_style'] = $style->id();
-            $entity_form_display->setComponent($instance['field_name'], $widget_options)
+            $entity_form_display->setComponent('field', $instance['field_name'], $widget_options)
               ->save();
           }
         }
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageAdminStylesTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageAdminStylesTest.php
index 973a8ef..9e5ed5c 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageAdminStylesTest.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageAdminStylesTest.php
@@ -260,7 +260,7 @@ function testStyleReplacement() {
     $field_name = strtolower($this->randomName(10));
     $this->createImageField($field_name, 'article');
     entity_get_display('node', 'article', 'default')
-      ->setComponent($field_name, array(
+      ->setComponent('field', $field_name, array(
         'type' => 'image',
         'settings' => array('image_style' => $style_name),
       ))
@@ -349,7 +349,7 @@ function testConfigImport() {
     $field_name = strtolower($this->randomName(10));
     $this->createImageField($field_name, 'article');
     entity_get_display('node', 'article', 'default')
-      ->setComponent($field_name, array(
+      ->setComponent('field', $field_name, array(
         'type' => 'image',
         'settings' => array('image_style' => $style_name),
       ))
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php
index 164cbad..9768e0c 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php
@@ -67,12 +67,12 @@ function testDefaultImages() {
     ));
     $instance2->save();
 
-    $widget_settings = entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')->getComponent($field['field_name']);
+    $widget_settings = entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')->getComponent('field', $field['field_name']);
     entity_get_form_display('node', 'page', 'default')
-      ->setComponent($field->id(), $widget_settings)
+      ->setComponent('field', $field->id(), $widget_settings)
       ->save();
     entity_get_display('node', 'page', 'default')
-      ->setComponent($field->id())
+      ->setComponent('field', $field->id())
       ->save();
 
     // Confirm the defaults are present on the article field settings form.
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
index c0f0cfd..baa4552 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
@@ -73,7 +73,7 @@ function _testImageFieldFormatters($scheme) {
       'settings' => array('image_link' => 'file'),
     );
     $display = entity_get_display('node', $node->type, 'default');
-    $display->setComponent($field_name, $display_options)
+    $display->setComponent('field', $field_name, $display_options)
       ->save();
 
     $default_output = l(theme('image', $image_info), file_create_url($image_uri), array('html' => TRUE));
@@ -98,7 +98,7 @@ function _testImageFieldFormatters($scheme) {
 
     // Test the image linked to content formatter.
     $display_options['settings']['image_link'] = 'content';
-    $display->setComponent($field_name, $display_options)
+    $display->setComponent('field', $field_name, $display_options)
       ->save();
     $default_output = l(theme('image', $image_info), 'node/' . $nid, array('html' => TRUE, 'attributes' => array('class' => 'active')));
     $this->drupalGet('node/' . $nid);
@@ -107,7 +107,7 @@ function _testImageFieldFormatters($scheme) {
     // Test the image style 'thumbnail' formatter.
     $display_options['settings']['image_link'] = '';
     $display_options['settings']['image_style'] = 'thumbnail';
-    $display->setComponent($field_name, $display_options)
+    $display->setComponent('field', $field_name, $display_options)
       ->save();
 
     // Ensure the derivative image is generated so we do not have to deal with
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php
index 3b9be9f..f28a534 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php
@@ -92,14 +92,14 @@ function createImageField($name, $type_name, $field_settings = array(), $instanc
     $field_instance->save();
 
     entity_get_form_display('node', $type_name, 'default')
-      ->setComponent($field['field_name'], array(
+      ->setComponent('field', $field['field_name'], array(
         'type' => 'image_image',
         'settings' => $widget_settings,
       ))
       ->save();
 
     entity_get_display('node', $type_name, 'default')
-      ->setComponent($field['field_name'])
+      ->setComponent('field', $field['field_name'])
       ->save();
 
     return $field_instance;
diff --git a/core/modules/link/lib/Drupal/link/Tests/LinkFieldTest.php b/core/modules/link/lib/Drupal/link/Tests/LinkFieldTest.php
index b4033ff..c6b7530 100644
--- a/core/modules/link/lib/Drupal/link/Tests/LinkFieldTest.php
+++ b/core/modules/link/lib/Drupal/link/Tests/LinkFieldTest.php
@@ -81,7 +81,7 @@ function testURLValidation() {
       ),
     ))->save();
     entity_get_form_display('entity_test', 'entity_test', 'default')
-      ->setComponent($field_name, array(
+      ->setComponent('field', $field_name, array(
         'type' => 'link_default',
         'settings' => array(
           'placeholder_url' => 'http://example.com',
@@ -89,7 +89,7 @@ function testURLValidation() {
       ))
       ->save();
     entity_get_display('entity_test', 'entity_test', 'full')
-      ->setComponent($field_name, array(
+      ->setComponent('field', $field_name, array(
         'type' => 'link',
       ))
       ->save();
@@ -157,7 +157,7 @@ function testLinkTitle() {
     ));
     $this->instance->save();
     entity_get_form_display('entity_test', 'entity_test', 'default')
-      ->setComponent($field_name, array(
+      ->setComponent('field', $field_name, array(
         'type' => 'link_default',
         'settings' => array(
           'placeholder_url' => 'http://example.com',
@@ -166,7 +166,7 @@ function testLinkTitle() {
       ))
       ->save();
     entity_get_display('entity_test', 'entity_test', 'full')
-      ->setComponent($field_name, array(
+      ->setComponent('field', $field_name, array(
         'type' => 'link',
         'label' => 'hidden',
       ))
@@ -276,7 +276,7 @@ function testLinkFormatter() {
       ),
     ))->save();
     entity_get_form_display('entity_test', 'entity_test', 'default')
-      ->setComponent($field_name, array(
+      ->setComponent('field', $field_name, array(
         'type' => 'link_default',
       ))
       ->save();
@@ -285,7 +285,7 @@ function testLinkFormatter() {
       'label' => 'hidden',
     );
     entity_get_display('entity_test', 'entity_test', 'full')
-      ->setComponent($field_name, $display_options)
+      ->setComponent('field', $field_name, $display_options)
       ->save();
 
     $langcode = Language::LANGCODE_NOT_SPECIFIED;
@@ -343,7 +343,7 @@ function testLinkFormatter() {
           $display_options['settings'] = $new_value;
         }
         entity_get_display('entity_test', 'entity_test', 'full')
-          ->setComponent($field_name, $display_options)
+          ->setComponent('field', $field_name, $display_options)
           ->save();
 
         $this->renderTestEntity($id);
@@ -422,12 +422,12 @@ function testLinkSeparateFormatter() {
       'label' => 'hidden',
     );
     entity_get_form_display('entity_test', 'entity_test', 'default')
-      ->setComponent($field_name, array(
+      ->setComponent('field', $field_name, array(
         'type' => 'link_default',
       ))
       ->save();
     entity_get_display('entity_test', 'entity_test', 'full')
-      ->setComponent($field_name, $display_options)
+      ->setComponent('field', $field_name, $display_options)
       ->save();
 
     $langcode = Language::LANGCODE_NOT_SPECIFIED;
@@ -465,7 +465,7 @@ function testLinkSeparateFormatter() {
         // Update the field formatter settings.
         $display_options['settings'] = array($setting => $new_value);
         entity_get_display('entity_test', 'entity_test', 'full')
-          ->setComponent($this->field['field_name'], $display_options)
+          ->setComponent('field', $this->field['field_name'], $display_options)
           ->save();
 
         $this->renderTestEntity($id);
diff --git a/core/modules/node/lib/Drupal/node/NodeRenderController.php b/core/modules/node/lib/Drupal/node/NodeRenderController.php
index a58a96f..aef85e6 100644
--- a/core/modules/node/lib/Drupal/node/NodeRenderController.php
+++ b/core/modules/node/lib/Drupal/node/NodeRenderController.php
@@ -65,7 +65,7 @@ public function buildContent(array $entities, array $displays, $view_mode, $lang
       );
 
       // Add Language field text element to node render array.
-      if ($display->getComponent('language')) {
+      if ($display->getComponent('extra_field', 'language')) {
         $entity->content['language'] = array(
           '#type' => 'item',
           '#title' => t('Language'),
diff --git a/core/modules/node/lib/Drupal/node/Plugin/views/wizard/Node.php b/core/modules/node/lib/Drupal/node/Plugin/views/wizard/Node.php
index db8b858..3908b70 100644
--- a/core/modules/node/lib/Drupal/node/Plugin/views/wizard/Node.php
+++ b/core/modules/node/lib/Drupal/node/Plugin/views/wizard/Node.php
@@ -278,7 +278,7 @@ protected function buildFilters(&$form, &$form_state) {
     $tag_fields = array();
     foreach ($bundles as $bundle) {
       foreach (field_info_instances($this->entity_type, $bundle) as $instance) {
-        $widget = entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')->getComponent($instance['field_name']);
+        $widget = entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')->getComponent('field', $instance['field_name']);
         // We define "tag-like" taxonomy fields as ones that use the
         // "Autocomplete term widget (tagging)" widget.
         if ($widget['type'] == 'taxonomy_autocomplete') {
diff --git a/core/modules/node/lib/Drupal/node/Tests/MultiStepNodeFormBasicOptionsTest.php b/core/modules/node/lib/Drupal/node/Tests/MultiStepNodeFormBasicOptionsTest.php
index 65e3aec..993a8cc 100644
--- a/core/modules/node/lib/Drupal/node/Tests/MultiStepNodeFormBasicOptionsTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/MultiStepNodeFormBasicOptionsTest.php
@@ -57,7 +57,7 @@ function testMultiStepNodeFormBasicOptions() {
       ),
     ))->save();
     entity_get_form_display('node', 'page', 'default')
-      ->setComponent($this->field_name, array(
+      ->setComponent('field', $this->field_name, array(
         'type' => 'text_textfield',
       ))
       ->save();
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeAccessFieldTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeAccessFieldTest.php
index e1a33aa..2080e5d 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeAccessFieldTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeAccessFieldTest.php
@@ -71,10 +71,10 @@ public function setUp() {
       'bundle' => 'page',
     ))->save();
     entity_get_display('node', 'page', 'default')
-      ->setComponent($this->field_name)
+      ->setComponent('field', $this->field_name)
       ->save();
     entity_get_form_display('node', 'page', 'default')
-      ->setComponent($this->field_name)
+      ->setComponent('field', $this->field_name)
       ->save();
   }
 
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeTypeInitialLanguageTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeTypeInitialLanguageTest.php
index 1a0b7ed..bfa5b07 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeTypeInitialLanguageTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeTypeInitialLanguageTest.php
@@ -86,7 +86,7 @@ function testNodeTypeInitialLanguageDefaults() {
     $language_display = $this->xpath('//*[@id="language"]');
     $this->assert(!empty($language_display), 'Language field is visible on manage display tab.');
     // Tests if the language field is hidden by default.
-    $this->assertOptionSelected('edit-fields-language-type', 'hidden', 'Language is hidden by default on manage display tab.');
+    $this->assertOptionSelected('edit-fields-language-visibility', 'hidden', 'Language is hidden by default on manage display tab.');
 
     // Changes the inital language settings.
     $edit = array(
@@ -121,11 +121,11 @@ function testLanguageFieldVisibility() {
 
     // Changes Language field visibility to true and check if it is saved.
     $edit = array(
-      'fields[language][type]' => 'visible',
+      'fields[language][visibility]' => 'visible',
     );
     $this->drupalPost('admin/structure/types/manage/article/display', $edit, t('Save'));
     $this->drupalGet('admin/structure/types/manage/article/display');
-    $this->assertOptionSelected('edit-fields-language-type', 'visible', 'Language field has been set to visible.');
+    $this->assertOptionSelected('edit-fields-language-visibility', 'visible', 'Language field has been set to visible.');
 
     // Loads node page and check if Language field is shown.
     $this->drupalGet('node/' . $node->nid);
diff --git a/core/modules/node/lib/Drupal/node/Tests/PagePreviewTest.php b/core/modules/node/lib/Drupal/node/Tests/PagePreviewTest.php
index b485545..ea4f154 100644
--- a/core/modules/node/lib/Drupal/node/Tests/PagePreviewTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/PagePreviewTest.php
@@ -87,19 +87,19 @@ function setUp() {
     ))->save();
 
     entity_get_form_display('node', 'page', 'default')
-      ->setComponent($this->field_name, array(
+      ->setComponent('field', $this->field_name, array(
         'type' => 'taxonomy_autocomplete',
       ))
       ->save();
 
     // Show on default display and teaser.
     entity_get_display('node', 'page', 'default')
-      ->setComponent($this->field_name, array(
+      ->setComponent('field', $this->field_name, array(
         'type' => 'taxonomy_term_reference_link',
       ))
       ->save();
     entity_get_display('node', 'page', 'teaser')
-      ->setComponent($this->field_name, array(
+      ->setComponent('field', $this->field_name, array(
         'type' => 'taxonomy_term_reference_link',
       ))
       ->save();
diff --git a/core/modules/node/lib/Drupal/node/Tests/SummaryLengthTest.php b/core/modules/node/lib/Drupal/node/Tests/SummaryLengthTest.php
index e627c6e..87416c9 100644
--- a/core/modules/node/lib/Drupal/node/Tests/SummaryLengthTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/SummaryLengthTest.php
@@ -48,9 +48,9 @@ function testSummaryLength() {
 
     // Change the teaser length for "Basic page" content type.
     $display = entity_get_display('node', $node->type, 'teaser');
-    $display_options = $display->getComponent('body');
+    $display_options = $display->getComponent('field', 'body');
     $display_options['settings']['trim_length'] = 200;
-    $display->setComponent('body', $display_options)
+    $display->setComponent('field', 'body', $display_options)
       ->save();
 
     // Render the node as a teaser again and check that the summary is now only
diff --git a/core/modules/node/node.api.php b/core/modules/node/node.api.php
index 51abca3..e495e02 100644
--- a/core/modules/node/node.api.php
+++ b/core/modules/node/node.api.php
@@ -806,7 +806,7 @@ function hook_node_view(\Drupal\Core\Entity\EntityInterface $node, \Drupal\entit
   // Only do the extra work if the component is configured to be displayed.
   // This assumes a 'mymodule_addition' extra field has been defined for the
   // node type in hook_field_extra_fields().
-  if ($display->getComponent('mymodule_addition')) {
+  if ($display->getComponent('extra_field', 'mymodule_addition')) {
     $node->content['mymodule_addition'] = array(
       '#markup' => mymodule_addition($node),
       '#theme' => 'mymodule_my_additional_field',
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 9d9d48f..04473c0 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -195,11 +195,9 @@ function node_entity_bundle_info() {
 function node_entity_display_alter(EntityDisplay $display, $context) {
   // Hide field labels in search index.
   if ($context['entity_type'] == 'node' && $context['view_mode'] == 'search_index') {
-    foreach ($display->getComponents() as $name => $options) {
-      if (isset($options['label'])) {
-        $options['label'] = 'hidden';
-        $display->setComponent($name, $options);
-      }
+    foreach ($display->getComponents('field') as $name => $options) {
+      $options['label'] = 'hidden';
+      $display->setComponent('field', $name, $options);
     }
   }
 }
@@ -417,20 +415,20 @@ function node_add_body_field(NodeTypeInterface $type, $label = 'Body') {
 
     // Assign widget settings for the 'default' form mode.
     entity_get_form_display('node', $type->type, 'default')
-      ->setComponent($field->id(), array(
+      ->setComponent('field', $field->id(), array(
         'type' => 'text_textarea_with_summary',
       ))
       ->save();
 
     // Assign display settings for the 'default' and 'teaser' view modes.
     entity_get_display('node', $type->type, 'default')
-      ->setComponent($field->id(), array(
+      ->setComponent('field', $field->id(), array(
         'label' => 'hidden',
         'type' => 'text_default',
       ))
       ->save();
     entity_get_display('node', $type->type, 'teaser')
-      ->setComponent($field->id(), array(
+      ->setComponent('field', $field->id(), array(
         'label' => 'hidden',
         'type' => 'text_summary_or_trimmed',
       ))
diff --git a/core/modules/node/node.tokens.inc b/core/modules/node/node.tokens.inc
index 241b83b..8f0d3a2 100644
--- a/core/modules/node/node.tokens.inc
+++ b/core/modules/node/node.tokens.inc
@@ -154,7 +154,7 @@ function node_tokens($type, $tokens, array $data = array(), array $options = arr
 
                 // Get the 'trim_length' size used for the 'teaser' mode, if
                 // present, or use the default trim_length size.
-                $display_options = entity_get_display('node', $node->type, 'teaser')->getComponent('body');
+                $display_options = entity_get_display('node', $node->type, 'teaser')->getComponent('field', 'body');
                 if (isset($display_options['settings']['trim_length'])) {
                   $length = $display_options['settings']['trim_length'];
                 }
diff --git a/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php b/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php
index 8bea406..b0e731f 100644
--- a/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php
+++ b/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php
@@ -78,7 +78,7 @@ function testNumberDecimalField() {
     ))->save();
 
     entity_get_form_display('entity_test', 'entity_test', 'default')
-      ->setComponent($this->field->id(), array(
+      ->setComponent('field', $this->field->id(), array(
         'type' => 'number',
         'settings' => array(
           'placeholder' => '0.00'
@@ -86,7 +86,7 @@ function testNumberDecimalField() {
       ))
       ->save();
     entity_get_display('entity_test', 'entity_test', 'default')
-      ->setComponent($this->field->id(), array(
+      ->setComponent('field', $this->field->id(), array(
         'type' => 'number_decimal',
       ))
       ->save();
diff --git a/core/modules/options/lib/Drupal/options/Tests/OptionsDynamicValuesTest.php b/core/modules/options/lib/Drupal/options/Tests/OptionsDynamicValuesTest.php
index c270e4a..654830f 100644
--- a/core/modules/options/lib/Drupal/options/Tests/OptionsDynamicValuesTest.php
+++ b/core/modules/options/lib/Drupal/options/Tests/OptionsDynamicValuesTest.php
@@ -47,7 +47,7 @@ function setUp() {
       'required' => TRUE,
     ))->save();
     entity_get_form_display('entity_test_rev', 'entity_test_rev', 'default')
-      ->setComponent($this->field_name, array(
+      ->setComponent('field', $this->field_name, array(
         'type' => 'options_select',
       ))
       ->save();
diff --git a/core/modules/options/lib/Drupal/options/Tests/OptionsFieldTest.php b/core/modules/options/lib/Drupal/options/Tests/OptionsFieldTest.php
index 218e413..7c1f685 100644
--- a/core/modules/options/lib/Drupal/options/Tests/OptionsFieldTest.php
+++ b/core/modules/options/lib/Drupal/options/Tests/OptionsFieldTest.php
@@ -88,7 +88,7 @@ function testUpdateAllowedValues() {
       'bundle' => 'entity_test',
     ))->save();
     entity_get_form_display('entity_test', 'entity_test', 'default')
-      ->setComponent($this->fieldName, array(
+      ->setComponent('field', $this->fieldName, array(
         'type' => 'options_buttons',
       ))
       ->save();
diff --git a/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUITest.php b/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUITest.php
index d34f178..d7e2d4b 100644
--- a/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUITest.php
+++ b/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUITest.php
@@ -268,7 +268,7 @@ protected function createOptionsField($type) {
       'bundle' => $this->type,
     ))->save();
 
-    entity_get_form_display('node', $this->type, 'default')->setComponent($this->field_name)->save();
+    entity_get_form_display('node', $this->type, 'default')->setComponent('field', $this->field_name)->save();
 
     $this->admin_path = 'admin/structure/types/manage/' . $this->type . '/fields/node.' . $this->type . '.' . $this->field_name . '/field';
   }
@@ -328,7 +328,7 @@ function testNodeDisplay() {
     $file_formatters = array('list_default', 'list_key');
     foreach ($file_formatters as $formatter) {
       $edit = array(
-        "fields[$this->field_name][type]" => $formatter,
+        "fields[$this->field_name][formatter]" => $formatter,
       );
       $this->drupalPost('admin/structure/types/manage/' . $this->type_name . '/display', $edit, t('Save'));
       $this->drupalGet('node/' . $node->nid);
diff --git a/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUnitTestBase.php b/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUnitTestBase.php
index 748ee6e..b3d9867 100644
--- a/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUnitTestBase.php
+++ b/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUnitTestBase.php
@@ -77,7 +77,7 @@ public function setUp() {
     $this->instance->save();
 
     entity_get_form_display('entity_test', 'entity_test', 'default')
-      ->setComponent($this->fieldName, array(
+      ->setComponent('field', $this->fieldName, array(
         'type' => 'options_buttons',
       ))
       ->save();
diff --git a/core/modules/options/lib/Drupal/options/Tests/OptionsWidgetsTest.php b/core/modules/options/lib/Drupal/options/Tests/OptionsWidgetsTest.php
index dbc1876..4163033 100644
--- a/core/modules/options/lib/Drupal/options/Tests/OptionsWidgetsTest.php
+++ b/core/modules/options/lib/Drupal/options/Tests/OptionsWidgetsTest.php
@@ -114,7 +114,7 @@ function testRadioButtons() {
     ));
     $instance->save();
     entity_get_form_display('entity_test', 'entity_test', 'default')
-      ->setComponent($this->card_1->id(), array(
+      ->setComponent('field', $this->card_1->id(), array(
         'type' => 'options_buttons',
       ))
       ->save();
@@ -173,7 +173,7 @@ function testCheckBoxes() {
     ));
     $instance->save();
     entity_get_form_display('entity_test', 'entity_test', 'default')
-      ->setComponent($this->card_2->id(), array(
+      ->setComponent('field', $this->card_2->id(), array(
         'type' => 'options_buttons',
       ))
       ->save();
@@ -266,7 +266,7 @@ function testSelectListSingle() {
     ));
     $instance->save();
     entity_get_form_display('entity_test', 'entity_test', 'default')
-      ->setComponent($this->card_1->id(), array(
+      ->setComponent('field', $this->card_1->id(), array(
         'type' => 'options_select',
       ))
       ->save();
@@ -367,7 +367,7 @@ function testSelectListMultiple() {
     ));
     $instance->save();
     entity_get_form_display('entity_test', 'entity_test', 'default')
-      ->setComponent($this->card_2->id(), array(
+      ->setComponent('field', $this->card_2->id(), array(
         'type' => 'options_select',
       ))
       ->save();
@@ -488,7 +488,7 @@ function testOnOffCheckbox() {
       'bundle' => 'entity_test',
     ))->save();
     entity_get_form_display('entity_test', 'entity_test', 'default')
-      ->setComponent($this->bool->id(), array(
+      ->setComponent('field', $this->bool->id(), array(
         'type' => 'options_onoff',
       ))
       ->save();
@@ -544,7 +544,7 @@ function testOnOffCheckbox() {
     ))->save();
 
     entity_get_form_display('node', 'page', 'default')
-      ->setComponent($this->bool['field_name'], array(
+      ->setComponent('field', $this->bool['field_name'], array(
         'type' => 'options_onoff',
       ))
       ->save();
diff --git a/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php b/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php
index b79ad21..70562da 100644
--- a/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php
+++ b/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php
@@ -135,11 +135,10 @@ public function _testPictureFieldFormatters($scheme) {
     // Use the picture formatter linked to file formatter.
     $display_options = array(
       'type' => 'picture',
-      'module' => 'picture',
       'settings' => array('image_link' => 'file'),
     );
     $display = entity_get_display('node', 'article', 'default');
-    $display->setComponent($field_name, $display_options)
+    $display->setComponent('field', $field_name, $display_options)
       ->save();
 
     $default_output = l(theme('image', $image_info), file_create_url($image_uri), array('html' => TRUE));
@@ -164,7 +163,7 @@ public function _testPictureFieldFormatters($scheme) {
 
     // Use the picture formatter with a picture mapping.
     $display_options['settings']['picture_mapping'] = 'mapping_one';
-    $display->setComponent($field_name, $display_options)
+    $display->setComponent('field', $field_name, $display_options)
       ->save();
 
     // Output should contain all image styles and all breakpoints.
@@ -179,7 +178,7 @@ public function _testPictureFieldFormatters($scheme) {
     // Test the fallback image style.
     $display_options['settings']['image_link'] = '';
     $display_options['settings']['fallback_image_style'] = 'large';
-    $display->setComponent($field_name, $display_options)
+    $display->setComponent('field', $field_name, $display_options)
       ->save();
 
     $this->drupalGet(image_style_url('large', $image_uri));
diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/FileFieldAttributesTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/FileFieldAttributesTest.php
index 11176dc..1d7593f 100644
--- a/core/modules/rdf/lib/Drupal/rdf/Tests/FileFieldAttributesTest.php
+++ b/core/modules/rdf/lib/Drupal/rdf/Tests/FileFieldAttributesTest.php
@@ -60,7 +60,7 @@ public function setUp() {
 
     // Set the teaser display to show this field.
     entity_get_display('node', 'article', 'teaser')
-      ->setComponent($this->fieldName, array('type' => 'file_default'))
+      ->setComponent('field', $this->fieldName, array('type' => 'file_default'))
       ->save();
 
     // Set the RDF mapping for the new field.
diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/ImageFieldAttributesTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/ImageFieldAttributesTest.php
index 338ddfb..2e082ce 100644
--- a/core/modules/rdf/lib/Drupal/rdf/Tests/ImageFieldAttributesTest.php
+++ b/core/modules/rdf/lib/Drupal/rdf/Tests/ImageFieldAttributesTest.php
@@ -86,7 +86,7 @@ function testNodeTeaser() {
       'settings' => array('image_style' => 'medium', 'image_link' => 'content'),
     );
     $display = entity_get_display('node', 'article', 'teaser');
-    $display->setComponent($this->fieldName, $display_options)
+    $display->setComponent('field', $this->fieldName, $display_options)
       ->save();
 
     // Render the teaser.
diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/TaxonomyTermFieldAttributesTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/TaxonomyTermFieldAttributesTest.php
index 78c91ca..6fddf3f 100644
--- a/core/modules/rdf/lib/Drupal/rdf/Tests/TaxonomyTermFieldAttributesTest.php
+++ b/core/modules/rdf/lib/Drupal/rdf/Tests/TaxonomyTermFieldAttributesTest.php
@@ -79,7 +79,7 @@ public function setUp() {
   function testNodeTeaser() {
     // Set the teaser display to show this field.
     entity_get_display('node', 'article', 'teaser')
-      ->setComponent($this->fieldName, array('type' => 'taxonomy_term_reference_link'))
+      ->setComponent('field', $this->fieldName, array('type' => 'taxonomy_term_reference_link'))
       ->save();
 
     // Create a term in each vocabulary.
@@ -172,10 +172,10 @@ protected function createTaxonomyTermReferenceField($field_name, $vocabulary) {
       'bundle' => 'article',
     ))->save();
     entity_get_form_display('node', 'article', 'default')
-      ->setComponent($field_name, array('type' => 'options_select'))
+      ->setComponent('field', $field_name, array('type' => 'options_select'))
       ->save();
     entity_get_display('node', 'article', 'full')
-      ->setComponent($field_name, array('type' => 'taxonomy_term_reference_link'))
+      ->setComponent('field', $field_name, array('type' => 'taxonomy_term_reference_link'))
       ->save();
   }
 
diff --git a/core/modules/system/lib/Drupal/system/Tests/Ajax/MultiFormTest.php b/core/modules/system/lib/Drupal/system/Tests/Ajax/MultiFormTest.php
index f15f382..e12b7ab 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Ajax/MultiFormTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Ajax/MultiFormTest.php
@@ -45,7 +45,7 @@ function setUp() {
       'bundle' => 'page',
     ))->save();
     entity_get_form_display('node', 'page', 'default')
-      ->setComponent($field_name, array('type' => 'text_default'))
+      ->setComponent('field', $field_name, array('type' => 'text_default'))
       ->save();
 
     // Login a user who can create 'page' nodes.
diff --git a/core/modules/system/lib/Drupal/system/Tests/Form/ArbitraryRebuildTest.php b/core/modules/system/lib/Drupal/system/Tests/Form/ArbitraryRebuildTest.php
index cc6546a..af0e247 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Form/ArbitraryRebuildTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Form/ArbitraryRebuildTest.php
@@ -46,7 +46,7 @@ function setUp() {
       'label' => 'Test a multiple valued field',
     ))->save();
     entity_get_form_display('user', 'user', 'register')
-      ->setComponent('test_multiple', array(
+      ->setComponent('field', 'test_multiple', array(
         'type' => 'text_textfield',
         'weight' => 0,
       ))
diff --git a/core/modules/system/lib/Drupal/system/Tests/Form/RebuildTest.php b/core/modules/system/lib/Drupal/system/Tests/Form/RebuildTest.php
index c580e88..0aefab9 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Form/RebuildTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Form/RebuildTest.php
@@ -84,7 +84,7 @@ function testPreserveFormActionAfterAJAX() {
     );
     entity_create('field_instance', $instance)->save();
     entity_get_form_display('node', 'page', 'default')
-      ->setComponent($field_name, array('type' => 'text_test'))
+      ->setComponent('field', $field_name, array('type' => 'text_test'))
       ->save();
 
     // Log in a user who can create 'page' nodes.
diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php
index 79abf93..e267d5b 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php
@@ -46,12 +46,14 @@ public function testEntityDisplayUpgrade() {
     // Check that the 'body' field is configured as expected.
     $expected = array(
       'default' => array(
+        'handler_type' => 'field',
         'label' => 'hidden',
         'type' => 'text_default',
         'weight' => 0,
         'settings' => array(),
       ),
       'teaser' => array(
+        'handler_type' => 'field',
         'label' => 'hidden',
         'type' => 'text_summary_or_trimmed',
         'weight' => 0,
@@ -70,10 +72,12 @@ public function testEntityDisplayUpgrade() {
     // Check that the 'language' extra field is configured as expected.
     $expected = array(
       'default' => array(
+        'handler_type' => 'extra_field',
         'weight' => -1,
         'visible' => 1,
       ),
       'teaser' => array(
+        'handler_type' => 'extra_field',
         'visible' => 0,
       ),
     );
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 dd9bcf9..d1d076f 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/UserPictureUpgradePathTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/UserPictureUpgradePathTest.php
@@ -60,12 +60,12 @@ public function testUserPictureUpgrade() {
     $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.');
 
-    $display_options = entity_get_display('user', 'user', 'default')->getComponent('user_picture');
+    $display_options = entity_get_display('user', 'user', 'default')->getComponent('field', 'user_picture');
     $this->assertEqual($display_options['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');
-    $this->assertFieldByName('fields[member_for][type]', 'hidden');
+    $this->assertFieldByName('fields[member_for][visibility]', 'hidden');
 
     // Check the user picture and file usage record.
     $user = user_load(1);
diff --git a/core/modules/system/tests/modules/entity_test/entity_test.install b/core/modules/system/tests/modules/entity_test/entity_test.install
index d6f1b34..4b85257 100644
--- a/core/modules/system/tests/modules/entity_test/entity_test.install
+++ b/core/modules/system/tests/modules/entity_test/entity_test.install
@@ -32,7 +32,7 @@ function entity_test_install() {
     ))->save();
 
     entity_get_form_display($entity_type, $entity_type, 'default')
-      ->setComponent('field_test_text', array('type' => 'text_text'))
+      ->setComponent('field', 'field_test_text', array('type' => 'text_text'))
       ->save();
   }
 }
diff --git a/core/modules/system/tests/modules/entity_test/entity_test.module b/core/modules/system/tests/modules/entity_test/entity_test.module
index 55d0dac..922621f 100644
--- a/core/modules/system/tests/modules/entity_test/entity_test.module
+++ b/core/modules/system/tests/modules/entity_test/entity_test.module
@@ -160,7 +160,7 @@ function entity_test_entity_view_mode_info_alter(&$view_modes) {
  * Implements hook_field_extra_fields().
  */
 function entity_test_field_extra_fields() {
-  $extra['entity_test']['entity_test'] = array(
+  $extra['entity_test']['bundle_with_extra_fields'] = array(
     'display' => array(
       // Note: those extra fields do not currently display anything, they are
       // just used in \Drupal\entity\Tests\EntityDisplayTest to test the
@@ -396,9 +396,9 @@ function entity_test_entity_field_access_alter(array &$grants, array $context) {
 function entity_test_entity_form_display_alter(EntityFormDisplay $form_display, $context) {
   // Make the field_test_text field 42 characters for entity_test_mul.
   if ($context['entity_type'] == 'entity_test') {
-    if ($component_options = $form_display->getComponent('field_test_text')) {
+    if ($component_options = $form_display->getComponent('field', 'field_test_text')) {
       $component_options['settings']['size'] = 42;
-      $form_display->setComponent('field_test_text', $component_options);
+      $form_display->setComponent('field', 'field_test_text', $component_options);
     }
   }
 }
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/TermRenderController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/TermRenderController.php
index e7f8882..fd3e1fb 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/TermRenderController.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/TermRenderController.php
@@ -25,7 +25,7 @@ public function buildContent(array $entities, array $displays, $view_mode, $lang
     foreach ($entities as $entity) {
       // Add the description if enabled.
       $display = $displays[$entity->bundle()];
-      if (!empty($entity->description->value) && $display->getComponent('description')) {
+      if (!empty($entity->description->value) && $display->getComponent('extra_field', 'description')) {
         $entity->content['description'] = array(
           '#markup' => check_markup($entity->description->value, $entity->format->value, '', TRUE),
           '#prefix' => '<div class="taxonomy-term-description">',
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php
index c9b8078..2bec37c 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php
@@ -57,12 +57,12 @@ function setUp() {
       'entity_type' => 'node',
     ))->save();
     entity_get_form_display('node', 'article', 'default')
-      ->setComponent($this->field_name, array(
+      ->setComponent('field', $this->field_name, array(
         'type' => 'options_select',
       ))
       ->save();
     entity_get_display('node', 'article', 'default')
-      ->setComponent($this->field_name, array(
+      ->setComponent('field', $this->field_name, array(
         'type' => 'taxonomy_term_reference_link',
       ))
       ->save();
@@ -87,7 +87,7 @@ function testTaxonomyRss() {
     // Change the format to 'RSS category'.
     $this->drupalGet("admin/structure/types/manage/article/display/rss");
     $edit = array(
-      "fields[taxonomy_" . $this->vocabulary->id() . "][type]" => 'taxonomy_term_reference_rss_category',
+      'fields[taxonomy_' . $this->vocabulary->id() . '][formatter]' => 'taxonomy_term_reference_rss_category',
     );
     $this->drupalPost(NULL, $edit, t('Save'));
 
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php
index c19ce9d..5fb01a5 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php
@@ -65,12 +65,12 @@ function setUp() {
       'bundle' => 'entity_test',
     ))->save();
     entity_get_form_display('entity_test', 'entity_test', 'default')
-      ->setComponent($this->field_name, array(
+      ->setComponent('field', $this->field_name, array(
         'type' => 'options_select',
       ))
       ->save();
     entity_get_display('entity_test', 'entity_test', 'full')
-      ->setComponent($this->field_name, array(
+      ->setComponent('field', $this->field_name, array(
         'type' => 'taxonomy_term_reference_link',
       ))
       ->save();
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php
index e893001..2e5a2e4 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php
@@ -64,12 +64,12 @@ function setUp() {
       'bundle' => 'entity_test',
     ))->save();
     entity_get_form_display('entity_test', 'entity_test', 'default')
-      ->setComponent($this->field_name, array(
+      ->setComponent('field', $this->field_name, array(
         'type' => 'options_select',
       ))
       ->save();
     entity_get_display('entity_test', 'entity_test', 'full')
-      ->setComponent($this->field_name, array(
+      ->setComponent('field', $this->field_name, array(
         'type' => 'taxonomy_term_reference_link',
       ))
       ->save();
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php
index 8fa30c3..71dae7a 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php
@@ -52,12 +52,12 @@ function setUp() {
       'entity_type' => 'node',
     ))->save();
     entity_get_form_display('node', 'article', 'default')
-      ->setComponent($this->field_name_1, array(
+      ->setComponent('field', $this->field_name_1, array(
         'type' => 'options_select',
       ))
       ->save();
     entity_get_display('node', 'article', 'default')
-      ->setComponent($this->field_name_1, array(
+      ->setComponent('field', $this->field_name_1, array(
         'type' => 'taxonomy_term_reference_link',
       ))
       ->save();
@@ -82,12 +82,12 @@ function setUp() {
       'entity_type' => 'node',
     ))->save();
     entity_get_form_display('node', 'article', 'default')
-      ->setComponent($this->field_name_2, array(
+      ->setComponent('field', $this->field_name_2, array(
         'type' => 'options_select',
       ))
       ->save();
     entity_get_display('node', 'article', 'default')
-      ->setComponent($this->field_name_2, array(
+      ->setComponent('field', $this->field_name_2, array(
         'type' => 'taxonomy_term_reference_link',
       ))
       ->save();
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
index 9dbf118..4d58803 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
@@ -50,12 +50,12 @@ function setUp() {
     ));
     $this->instance->save();
     entity_get_form_display('node', 'article', 'default')
-      ->setComponent('taxonomy_' . $this->vocabulary->id(), array(
+      ->setComponent('field', 'taxonomy_' . $this->vocabulary->id(), array(
         'type' => 'options_select',
       ))
       ->save();
     entity_get_display('node', 'article', 'default')
-      ->setComponent($this->instance['field_name'], array(
+      ->setComponent('field', $this->instance['field_name'], array(
         'type' => 'taxonomy_term_reference_link',
       ))
       ->save();
@@ -147,7 +147,7 @@ function testNodeTermCreationAndDeletion() {
     // Enable tags in the vocabulary.
     $instance = $this->instance;
     entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')
-      ->setComponent($instance['field_name'], array(
+      ->setComponent('field', $instance['field_name'], array(
         'type' => 'taxonomy_autocomplete',
         'settings' => array(
           'placeholder' => 'Start typing here.',
@@ -517,7 +517,7 @@ function testReSavingTags() {
     // Enable tags in the vocabulary.
     $instance = $this->instance;
     entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')
-      ->setComponent($instance['field_name'], array(
+      ->setComponent('field', $instance['field_name'], array(
         'type' => 'taxonomy_autocomplete',
       ))
       ->save();
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php
index 622eae7..dadf360 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php
@@ -49,12 +49,12 @@ function setUp() {
       'entity_type' => 'node',
     ))->save();
     entity_get_form_display('node', 'article', 'default')
-      ->setComponent($this->field_name, array(
+      ->setComponent('field', $this->field_name, array(
         'type' => 'options_select',
       ))
       ->save();
     entity_get_display('node', 'article', 'default')
-      ->setComponent($this->field_name, array(
+      ->setComponent('field', $this->field_name, array(
         'type' => 'taxonomy_term_reference_link',
       ))
       ->save();
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/Views/TaxonomyTestBase.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/Views/TaxonomyTestBase.php
index e7c7031..6188c7c 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/Views/TaxonomyTestBase.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/Views/TaxonomyTestBase.php
@@ -99,20 +99,20 @@ protected function mockStandardInstall() {
     ))->save();
 
     entity_get_form_display('node', 'article', 'default')
-      ->setComponent($this->field_name, array(
+      ->setComponent('field', $this->field_name, array(
         'type' => 'taxonomy_autocomplete',
         'weight' => -4,
       ))
       ->save();
 
     entity_get_display('node', 'article', 'default')
-      ->setComponent($this->field_name, array(
+      ->setComponent('field', $this->field_name, array(
         'type' => 'taxonomy_term_reference_link',
         'weight' => 10,
       ))
       ->save();
     entity_get_display('node', 'article', 'teaser')
-      ->setComponent($this->field_name, array(
+      ->setComponent('field', $this->field_name, array(
         'type' => 'taxonomy_term_reference_link',
         'weight' => 10,
       ))
diff --git a/core/modules/taxonomy/taxonomy.api.php b/core/modules/taxonomy/taxonomy.api.php
index ca3af07..0b39230 100644
--- a/core/modules/taxonomy/taxonomy.api.php
+++ b/core/modules/taxonomy/taxonomy.api.php
@@ -264,7 +264,7 @@ function hook_taxonomy_term_view(\Drupal\taxonomy\Plugin\Core\Entity\Term $term,
   // Only do the extra work if the component is configured to be displayed.
   // This assumes a 'mymodule_addition' extra field has been defined for the
   // vocabulary in hook_field_extra_fields().
-  if ($display->getComponent('mymodule_addition')) {
+  if ($display->getComponent('extra_field', 'mymodule_addition')) {
     $term->content['mymodule_addition'] = array(
       '#markup' => mymodule_addition($term),
       '#theme' => 'mymodule_my_additional_field',
diff --git a/core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneFieldTest.php b/core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneFieldTest.php
index 6158f07..f63cb8b 100644
--- a/core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneFieldTest.php
+++ b/core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneFieldTest.php
@@ -65,7 +65,7 @@ function testTelephoneField() {
     ))->save();
 
     entity_get_form_display('node', 'article', 'default')
-      ->setComponent('field_telephone', array(
+      ->setComponent('field', 'field_telephone', array(
         'type' => 'telephone_default',
         'settings' => array(
           'placeholder' => '123-456-7890',
@@ -74,7 +74,7 @@ function testTelephoneField() {
       ->save();
 
     entity_get_display('node', 'article', 'default')
-      ->setComponent('field_telephone', array(
+      ->setComponent('field', 'field_telephone', array(
         'type' => 'telephone_link',
         'weight' => 1,
       ))
diff --git a/core/modules/text/lib/Drupal/text/Tests/Formatter/TextPlainUnitTest.php b/core/modules/text/lib/Drupal/text/Tests/Formatter/TextPlainUnitTest.php
index 0a2b900..8593519 100644
--- a/core/modules/text/lib/Drupal/text/Tests/Formatter/TextPlainUnitTest.php
+++ b/core/modules/text/lib/Drupal/text/Tests/Formatter/TextPlainUnitTest.php
@@ -85,7 +85,7 @@ function setUp() {
 
     $this->view_mode = 'default';
     $this->display = entity_get_display($this->entity_type, $this->bundle, $this->view_mode)
-      ->setComponent($this->field_name, array(
+      ->setComponent('field', $this->field_name, array(
         'type' => $this->formatter_type,
         'settings' => $this->formatter_settings,
       ));
diff --git a/core/modules/text/lib/Drupal/text/Tests/TextFieldTest.php b/core/modules/text/lib/Drupal/text/Tests/TextFieldTest.php
index c349d6d..b98bd65 100644
--- a/core/modules/text/lib/Drupal/text/Tests/TextFieldTest.php
+++ b/core/modules/text/lib/Drupal/text/Tests/TextFieldTest.php
@@ -107,7 +107,7 @@ function _testTextfieldWidgets($field_type, $widget_type) {
       ),
     ))->save();
     entity_get_form_display('entity_test', 'entity_test', 'default')
-      ->setComponent($this->field_name, array(
+      ->setComponent('field', $this->field_name, array(
         'type' => $widget_type,
         'settings' => array(
           'placeholder' => 'A placeholder on ' . $widget_type,
@@ -115,7 +115,7 @@ function _testTextfieldWidgets($field_type, $widget_type) {
       ))
       ->save();
     entity_get_display('entity_test', 'entity_test', 'full')
-      ->setComponent($this->field_name)
+      ->setComponent('field', $this->field_name)
       ->save();
 
     $langcode = Language::LANGCODE_NOT_SPECIFIED;
@@ -175,12 +175,12 @@ function _testTextfieldWidgetsFormatted($field_type, $widget_type) {
       ),
     ))->save();
     entity_get_form_display('entity_test', 'entity_test', 'default')
-      ->setComponent($this->field_name, array(
+      ->setComponent('field', $this->field_name, array(
         'type' => $widget_type,
       ))
       ->save();
     entity_get_display('entity_test', 'entity_test', 'full')
-      ->setComponent($this->field_name)
+      ->setComponent('field', $this->field_name)
       ->save();
 
     $langcode = Language::LANGCODE_NOT_SPECIFIED;
diff --git a/core/modules/user/lib/Drupal/user/Tests/UserRegistrationTest.php b/core/modules/user/lib/Drupal/user/Tests/UserRegistrationTest.php
index 32dc5cc..12f7442 100644
--- a/core/modules/user/lib/Drupal/user/Tests/UserRegistrationTest.php
+++ b/core/modules/user/lib/Drupal/user/Tests/UserRegistrationTest.php
@@ -210,7 +210,7 @@ function testRegistrationWithUserFields() {
     ));
     $instance->save();
     entity_get_form_display('user', 'user', 'default')
-      ->setComponent('test_user_field', array('type' => 'test_field_widget'))
+      ->setComponent('field', 'test_user_field', array('type' => 'test_field_widget'))
       ->save();
 
     // Check that the field does not appear on the registration form.
@@ -219,7 +219,7 @@ function testRegistrationWithUserFields() {
 
     // Have the field appear on the registration form.
     entity_get_form_display('user', 'user', 'register')
-      ->setComponent('test_user_field', array('type' => 'test_field_widget'))
+      ->setComponent('field', 'test_user_field', array('type' => 'test_field_widget'))
       ->save();
 
     $this->drupalGet('user/register');
diff --git a/core/modules/user/user.api.php b/core/modules/user/user.api.php
index 2f337d9..8681358 100644
--- a/core/modules/user/user.api.php
+++ b/core/modules/user/user.api.php
@@ -329,7 +329,7 @@ function hook_user_view(\Drupal\user\UserInterface $account, \Drupal\entity\Plug
   // Only do the extra work if the component is configured to be displayed.
   // This assumes a 'mymodule_addition' extra field has been defined for the
   // user entity type in hook_field_extra_fields().
-  if ($display->getComponent('mymodule_addition')) {
+  if ($display->getComponent('extra_field', 'mymodule_addition')) {
     $account->content['mymodule_addition'] = array(
       '#markup' => mymodule_addition($account),
       '#theme' => 'mymodule_my_additional_field',
diff --git a/core/modules/user/user.install b/core/modules/user/user.install
index 37dc770..e686e66 100644
--- a/core/modules/user/user.install
+++ b/core/modules/user/user.install
@@ -303,7 +303,7 @@ function user_install_picture_field() {
 
   // Assign form display settings for the 'default' view mode.
   entity_get_form_display('user', 'user', 'default')
-    ->setComponent('user_picture', array(
+    ->setComponent('field', 'user_picture', array(
       'type' => 'image_image',
       'settings' => array(
         'progress_indicator' => 'throbber',
@@ -315,7 +315,7 @@ function user_install_picture_field() {
 
   // Assign display settings for the 'default' and 'compact' view modes.
   entity_get_display('user', 'user', 'default')
-    ->setComponent('user_picture', array(
+    ->setComponent('field', 'user_picture', array(
       'label' => 'hidden',
       'type' => 'image',
       'settings' => array(
@@ -325,7 +325,7 @@ function user_install_picture_field() {
     ))
     ->save();
   entity_get_display('user', 'user', 'compact')
-    ->setComponent('user_picture', array(
+    ->setComponent('field', 'user_picture', array(
       'label' => 'hidden',
       'type' => 'image',
       'settings' => array(
@@ -334,7 +334,7 @@ function user_install_picture_field() {
       ),
     ))
     // Additionally, hide 'summary' pseudo-field from compact view mode..
-    ->removeComponent('member_for')
+    ->removeComponent('extra_field', 'member_for')
     ->save();
 }
 
@@ -700,6 +700,7 @@ function user_update_8011() {
   // Assign form settings for the 'default' form mode.
   $form_display = _update_8000_entity_get_form_display('user', 'user', 'default');
   $form_display->set('content.user_picture', array(
+      'handler_type' => 'field',
       'type' => $widget,
       'settings' => array(
         'progress_indicator' => 'throbber',
@@ -712,6 +713,7 @@ function user_update_8011() {
   // Assign display settings for the 'default' and 'compact' view modes.
   $display = _update_8000_entity_get_display('user', 'user', 'default');
   $display->set('content.user_picture', array(
+      'handler_type' => 'field',
       'label' => 'hidden',
       'type' => $formatter,
       'settings' => array(
@@ -724,6 +726,7 @@ function user_update_8011() {
 
   $display = _update_8000_entity_get_display('user', 'user', 'compact');
   $display->set('content.user_picture', array(
+      'handler_type' => 'field',
       'label' => 'hidden',
       'type' => $formatter,
       'settings' => array(
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 911f00b..489b618 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -601,7 +601,7 @@ function user_search_execute($keys = NULL, $conditions = NULL) {
  * Implements hook_user_view().
  */
 function user_user_view(UserInterface $account, EntityDisplay $display) {
-  if ($display->getComponent('member_for')) {
+  if ($display->getComponent('extra_field', 'member_for')) {
     $account->content['member_for'] = array(
       '#type' => 'item',
       '#title' => t('Member for'),
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 2f870d8..1d83ca6 100644
--- a/core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php
@@ -80,19 +80,19 @@ function setUp() {
     entity_create('field_instance', $this->tag_instance)->save();
 
     entity_get_form_display('node', $this->node_type_with_tags->type, 'default')
-      ->setComponent('field_views_testing_tags', array(
+      ->setComponent('field', 'field_views_testing_tags', array(
         'type' => 'taxonomy_autocomplete',
       ))
       ->save();
 
-    entity_get_display('node', $this->node_type_with_tags->type, 'default')
-      ->setComponent('field_views_testing_tags', array(
+    entity_get_display('field', 'node', $this->node_type_with_tags->type, 'default')
+      ->setComponent('field', 'field_views_testing_tags', array(
         'type' => 'taxonomy_term_reference_link',
         'weight' => 10,
       ))
       ->save();
-    entity_get_display('node', $this->node_type_with_tags->type, 'teaser')
-      ->setComponent('field_views_testing_tags', array(
+    entity_get_display('field', 'node', $this->node_type_with_tags->type, 'teaser')
+      ->setComponent('field', 'field_views_testing_tags', array(
         'type' => 'taxonomy_term_reference_link',
         'weight' => 10,
       ))
@@ -191,7 +191,7 @@ function testTaggedWithByNodeType() {
     $instance['bundle'] = $this->node_type_without_tags->type;
     entity_create('field_instance', $instance)->save();
     entity_get_form_display('node', $this->node_type_without_tags->type, 'default')
-      ->setComponent('field_views_testing_tags', array(
+      ->setComponent('field', 'field_views_testing_tags', array(
         'type' => 'taxonomy_autocomplete',
       ))
       ->save();
diff --git a/core/profiles/standard/config/entity.display.node.article.default.yml b/core/profiles/standard/config/entity.display.node.article.default.yml
index 330de2d..3746dbf 100644
--- a/core/profiles/standard/config/entity.display.node.article.default.yml
+++ b/core/profiles/standard/config/entity.display.node.article.default.yml
@@ -4,16 +4,19 @@ bundle: article
 mode: default
 content:
   body:
+    handler_type: field
     label: hidden
     type: text_default
     weight: '0'
     settings: {  }
   field_tags:
+    handler_type: field
     type: taxonomy_term_reference_link
     weight: '10'
     label: above
     settings: {  }
   field_image:
+    handler_type: field
     label: hidden
     type: image
     settings:
diff --git a/core/profiles/standard/config/entity.display.node.article.teaser.yml b/core/profiles/standard/config/entity.display.node.article.teaser.yml
index 44add7e..b6ef1ed 100644
--- a/core/profiles/standard/config/entity.display.node.article.teaser.yml
+++ b/core/profiles/standard/config/entity.display.node.article.teaser.yml
@@ -4,17 +4,20 @@ bundle: article
 mode: teaser
 content:
   body:
+    handler_type: field
     label: hidden
     type: text_summary_or_trimmed
     weight: '0'
     settings:
       trim_length: '600'
   field_tags:
+    handler_type: field
     type: taxonomy_term_reference_link
     weight: '10'
     label: above
     settings: {  }
   field_image:
+    handler_type: field
     label: hidden
     type: image
     settings:
diff --git a/core/profiles/standard/config/entity.form_display.node.article.default.yml b/core/profiles/standard/config/entity.form_display.node.article.default.yml
index dcd242e..7aeda44 100644
--- a/core/profiles/standard/config/entity.form_display.node.article.default.yml
+++ b/core/profiles/standard/config/entity.form_display.node.article.default.yml
@@ -4,6 +4,7 @@ bundle: article
 mode: default
 content:
   body:
+    handler_type: field
     type: text_textarea_with_summary
     weight: '0'
     settings:
@@ -11,6 +12,7 @@ content:
       summary_rows: '3'
       placeholder: ''
   field_tags:
+    handler_type: field
     type: taxonomy_autocomplete
     weight: '-4'
     settings:
@@ -18,6 +20,7 @@ content:
       autocomplete_path: taxonomy/autocomplete
       placeholder: ''
   field_image:
+    handler_type: field
     type: image_image
     settings:
       progress_indicator: throbber
