diff --git a/core/includes/entity.api.php b/core/includes/entity.api.php
index 656f088..7b18aa8 100644
--- a/core/includes/entity.api.php
+++ b/core/includes/entity.api.php
@@ -366,7 +366,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',
@@ -436,7 +436,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;
       }
     }
@@ -482,11 +482,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($name, $options);
     }
   }
 }
diff --git a/core/includes/entity.inc b/core/includes/entity.inc
index 41e8add..7e854f0 100644
--- a/core/includes/entity.inc
+++ b/core/includes/entity.inc
@@ -632,12 +632,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(
- *     'type' => 'text_summary_or_trimmed',
+ *   ->setComponent('field', 'body', array(
+ *     'formatter' => 'text_summary_or_trimmed',
  *     'settings' => array('trim_length' => '200')
  *     'weight' => 1,
  *   ))
- *   ->removeComponent('field_image')
+ *   ->removeComponent('field', 'field_image')
  *   ->save();
  * @endcode
  *
diff --git a/core/modules/comment/comment.api.php b/core/modules/comment/comment.api.php
index 793d9ad..0f567dc 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 6d0d003..221eb18 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -376,9 +376,9 @@ function _comment_body_field_create($info) {
     );
     field_create_instance($instance);
     entity_get_display('comment', 'comment_node_' . $info->type, 'default')
-      ->setComponent('comment_body', array(
+      ->setComponent('field', 'comment_body', array(
         'label' => 'hidden',
-        'type' => 'text_default',
+        'formatter' => 'text_default',
         'weight' => 0,
       ))
       ->save();
diff --git a/core/modules/contact/lib/Drupal/contact/MessageRenderController.php b/core/modules/contact/lib/Drupal/contact/MessageRenderController.php
index b3a8a31..eb51b2c 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 (!empty($entity->message) && $display->getComponent('message')) {
+      if (!empty($entity->message) && $display->getComponent('extra_field', 'message')) {
         $entity->content['message'] = array(
           '#type' => 'item',
           '#title' => t('Message'),
diff --git a/core/modules/edit/lib/Drupal/edit/MetadataGenerator.php b/core/modules/edit/lib/Drupal/edit/MetadataGenerator.php
index b613442..188d7c8 100644
--- a/core/modules/edit/lib/Drupal/edit/MetadataGenerator.php
+++ b/core/modules/edit/lib/Drupal/edit/MetadataGenerator.php
@@ -68,7 +68,7 @@ public function generate(EntityInterface $entity, FieldInstance $instance, $lang
     }
 
     // Early-return if no editor is available.
-    $formatter_id = entity_get_render_display($entity, $view_mode)->getFormatter($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 d3737bb..f1b2cda 100644
--- a/core/modules/edit/lib/Drupal/edit/Tests/EditTestBase.php
+++ b/core/modules/edit/lib/Drupal/edit/Tests/EditTestBase.php
@@ -79,10 +79,10 @@ function createFieldWithInstance($field_name, $type, $cardinality, $label, $inst
     field_create_instance($this->$instance);
 
     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
+        'settings' => $formatter_settings,
+        'formatter' => $formatter_type,
       ))
       ->save();
   }
diff --git a/core/modules/edit/lib/Drupal/edit/Tests/EditorSelectionTest.php b/core/modules/edit/lib/Drupal/edit/Tests/EditorSelectionTest.php
index 26ec6c0..89101b7 100644
--- a/core/modules/edit/lib/Drupal/edit/Tests/EditorSelectionTest.php
+++ b/core/modules/edit/lib/Drupal/edit/Tests/EditorSelectionTest.php
@@ -49,9 +49,9 @@ 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);
+    return $this->editorSelector->getEditor($options['formatter'], $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 c719c97..093edfd 100644
--- a/core/modules/email/lib/Drupal/email/Tests/EmailFieldTest.php
+++ b/core/modules/email/lib/Drupal/email/Tests/EmailFieldTest.php
@@ -64,8 +64,8 @@ function testEmailField() {
     field_create_instance($this->instance);
     // Create a display for the full view mode.
     entity_get_display('test_entity', 'test_bundle', 'full')
-      ->setComponent($this->field['field_name'], array(
-        'type' => 'email_mailto',
+      ->setComponent('field', $this->field['field_name'], array(
+        'formatter' => 'email_mailto',
       ))
       ->save();
 
diff --git a/core/modules/entity/entity.services.yml b/core/modules/entity/entity.services.yml
new file mode 100644
index 0000000..44ab004
--- /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']
diff --git a/core/modules/entity/lib/Drupal/entity/EntityDisplayInterface.php b/core/modules/entity/lib/Drupal/entity/EntityDisplayInterface.php
index 0c1fa6c..ed43eea 100644
--- a/core/modules/entity/lib/Drupal/entity/EntityDisplayInterface.php
+++ b/core/modules/entity/lib/Drupal/entity/EntityDisplayInterface.php
@@ -31,14 +31,21 @@ public function createCopy($view_mode);
   /**
    * Gets the display options for all components.
    *
+   * @param string $type
+   *   (Optional) A component type.
+   *
    * @return array
-   *   The array of display options, keyed by component name.
+   *   The array of display options for all components of type $type, keyed by
+   *   component name.
    */
   public function getComponents();
 
   /**
    * 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,15 +95,17 @@ public function removeComponent($name);
   public function getHighestWeight();
 
   /**
-   * Returns the Formatter plugin for a field.
+   * 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\Type\Formatter\FormatterInterface
-   *   If the field is not hidden, the Formatter plugin to use for rendering
-   *   it.
+   * @return
+   *   If the component is not hidden, the object to use for rendering it.
    */
-  public function getFormatter($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 461a240..3a1e2f4 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
@@ -83,11 +83,18 @@ class EntityDisplay extends ConfigEntityBase implements EntityDisplayInterface {
   public $originalViewMode;
 
   /**
-   * The formatter objects used for this display, keyed by field name.
+   * The renderer objects used for this display, keyed by component name.
    *
    * @var array
    */
-  protected $formatters = array();
+  protected $renderers = array();
+
+  /**
+   * The component handler plugin manager.
+   *
+   * @var \Drupal\entity\Plugin\Type\DisplayComponentHandlerPluginManager
+   */
+  protected $handlersManager;
 
   /**
    * Overrides \Drupal\Core\Config\Entity\ConfigEntityBase::__construct().
@@ -103,6 +110,15 @@ public function __construct(array $values, $entity_type) {
     parent::__construct($values, $entity_type);
 
     $this->originalViewMode = $this->viewMode;
+
+    // Get the 'component handler' plugin manager.
+    $this->handlersManager = drupal_container()->get('plugin.manager.entity.display_component_handler');
+
+    // Let the component handlers add missing components.
+    $handlers = $this->handlersManager->getDefinitions();
+    foreach (array_keys($handlers) as $type) {
+      $this->getComponentHandler($type)->prepareDisplayComponents($this->content);
+    }
   }
 
   /**
@@ -152,14 +168,38 @@ public function createCopy($view_mode) {
   }
 
   /**
+   * 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 getComponentHandler($type) {
+    $handler = $this->handlersManager->getInstance(array('type' => $type));
+    if ($handler) {
+      $handler->setContext(array(
+        'entity_type' => $this->targetEntityType,
+        'bundle' => $this->bundle,
+        'view_mode' => $this->originalViewMode,
+      ));
+    }
+    return $handler;
+  }
+
+  /**
    * {@inheritdoc}
    */
-  public function getComponents() {
+  public function getComponents($type = NULL) {
     $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;
@@ -168,66 +208,41 @@ 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, 'display');
-    if (isset($extra_fields[$name])) {
-      // If we have explicit settings, return an array or NULL depending on
-      // visibility.
-      if (isset($this->content[$name])) {
-        if ($this->content[$name]['visible']) {
-          return array(
-            'weight' => $this->content[$name]['weight'],
-          );
-        }
-        else {
-          return NULL;
-        }
-      }
-
-      // If no explicit settings for the extra field, look at the default
-      // visibility in its definition.
-      $definition = $extra_fields[$name];
-      if (!isset($definition['visible']) || $definition['visible'] == TRUE) {
-        return array(
-          'weight' => $definition['weight']
-        );
-      }
-      else {
-        return NULL;
-      }
+  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 = drupal_container()->get('plugin.manager.field.formatter')->prepareConfiguration($field['type'], $options);
-
-      // Clear the persisted formatter, if any.
-      unset($this->formatters[$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, 'display');
-    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;
   }
@@ -235,28 +250,42 @@ public function setComponent($name, array $options = array()) {
   /**
    * {@inheritdoc}
    */
-  public function removeComponent($name) {
-    $extra_fields = field_info_extra_fields($this->targetEntityType, $this->bundle, 'display');
-    if (isset($extra_fields[$name])) {
-      // 'Extra fields' are exposed in hooks and can appear at any given time.
-      // Therefore we store extra fields that are explicitly being hidden, so
-      // that we can differenciate with those that are simply not configured
-      // yet.
-      $this->content[$name] = array(
-        'visible' => FALSE,
-      );
+  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->formatters[$name]);
     }
 
+    // Clear the associated renderer object.
+    unset($this->renderers[$name]);
+
     return $this;
   }
 
   /**
    * {@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];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function getHighestWeight() {
     $weights = array();
 
@@ -273,32 +302,4 @@ public function getHighestWeight() {
     return $weights ? max($weights) : NULL;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormatter($field_name) {
-    if (isset($this->formatters[$field_name])) {
-      return $this->formatters[$field_name];
-    }
-
-    // Instantiate the formatter object from the stored display properties.
-    if ($configuration = $this->getComponent($field_name)) {
-      $instance = field_info_instance($this->targetEntityType, $field_name, $this->bundle);
-      $formatter = drupal_container()->get('plugin.manager.field.formatter')->getInstance(array(
-        'instance' => $instance,
-        'view_mode' => $this->originalViewMode,
-        // No need to prepare, defaults have been merged in setComponent().
-        'prepare' => FALSE,
-        'configuration' => $configuration
-      ));
-    }
-    else {
-      $formatter = NULL;
-    }
-
-    // Persist the formatter object.
-    $this->formatters[$field_name] = $formatter;
-    return $formatter;
-  }
-
 }
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..7431086
--- /dev/null
+++ b/core/modules/entity/lib/Drupal/entity/Plugin/Type/DisplayComponentHandlerBase.php
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\entity\Plugin\Type\DisplayComponentHandlerBase.
+ */
+
+namespace Drupal\entity\Plugin\Type;
+
+use Drupal\Component\Plugin\PluginBase;
+use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
+
+
+// @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..de99ec7
--- /dev/null
+++ b/core/modules/entity/lib/Drupal/entity/Plugin/Type/DisplayComponentHandlerPluginManager.php
@@ -0,0 +1,63 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\entity\Plugin\Type\DisplayComponentHandlerPluginManager.
+ */
+
+namespace Drupal\entity\Plugin\Type;
+
+use Drupal\Component\Plugin\PluginManagerBase;
+use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
+use Drupal\Core\Plugin\Discovery\AlterDecorator;
+use Drupal\Core\Plugin\Discovery\CacheDecorator;
+use Drupal\Component\Plugin\Factory\DefaultFactory;
+
+/**
+ * Plugin type manager for entity display component handlers.
+ *
+ * The handlers are typically shared for the whole request. getInstance() holds
+ * the instanciated plugins and only instanciates one of each type.
+ */
+class DisplayComponentHandlerPluginManager extends PluginManagerBase {
+
+  /**
+   * The handlers that have already been instanciated 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,
+   */
+  public function __construct(\Traversable $namespaces) {
+    // @todo document the aletr hook.
+    // @todo cache key / bin ?
+    $this->discovery = new AnnotatedClassDiscovery('display_component_handler', $namespaces);
+    $this->discovery = new AlterDecorator($this->discovery, 'display_component_handler_info');
+    $this->discovery = new CacheDecorator($this->discovery, 'plugin_display_component_handler');
+
+    $this->factory = new DefaultFactory($this->discovery);
+  }
+
+  /**
+   * Overrides PluginManagerBase::getInstance().
+   *
+   * The display component handlers are shared for the whole request.
+   */
+  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/Plugin/entity/display_component_handler/ExtraFieldDisplayComponentHandler.php b/core/modules/entity/lib/Drupal/entity/Plugin/entity/display_component_handler/ExtraFieldDisplayComponentHandler.php
new file mode 100644
index 0000000..01ebb01
--- /dev/null
+++ b/core/modules/entity/lib/Drupal/entity/Plugin/entity/display_component_handler/ExtraFieldDisplayComponentHandler.php
@@ -0,0 +1,68 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\entity\Plugin\entity\display_component_handler\ExtraFieldDisplayComponentHandler.
+ */
+
+namespace Drupal\entity\Plugin\entity\display_component_handler;
+
+use Drupal\Core\Annotation\Plugin;
+use Drupal\entity\Plugin\Type\DisplayComponentHandlerBase;
+
+/**
+ * @todo
+ *
+ * @Plugin(
+ *   id = "extra_field",
+ *   module = "entity"
+ * )
+ */
+class ExtraFieldDisplayComponentHandler extends DisplayComponentHandlerBase {
+
+  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'], 'display');
+    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->plugin_id;
+      }
+    }
+    // @todo : we could add a custom $display->hiddenExtraFields property on the display, and merge them back on save.
+  }
+
+  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;
+    }
+  }
+
+  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/Tests/EntityDisplayTest.php b/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayTest.php
index cd513f4..c27331c 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',
       'viewMode' => 'default',
     ));
 
-    // Check that the default visibility taken into account for extra fields
+    // Check that the default visibility is 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));
   }
 
   /**
@@ -153,20 +153,20 @@ public function testFieldComponent() {
     field_create_instance($instance);
 
     // Check that providing no options results in default values being used.
-    $display->setComponent($field['field_name']);
+    $display->setComponent('field', $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);
     $expected = array(
       'weight' => 0,
       'label' => 'above',
-      'type' => $default_formatter,
+      'formatter' => $default_formatter,
       'settings' => $default_settings,
     );
-    $this->assertEqual($display->getComponent($field['field_name']), $expected);
+    $this->assertEqual($display->getComponent('field', $field['field_name']), $expected);
 
     // Check that the getFormatter() method returns the correct formatter plugin.
-    $formatter = $display->getFormatter($field['field_name']);
+    $formatter = $display->getRenderer('field', $field['field_name']);
     $this->assertEqual($formatter->getPluginId(), $default_formatter);
     $this->assertEqual($formatter->getSettings(), $default_settings);
 
@@ -174,26 +174,26 @@ public function testFieldComponent() {
     // arbitrary property and reading it back.
     $random_value = $this->randomString();
     $formatter->randomValue = $random_value;
-    $formatter = $display->getFormatter($field['field_name']);
+    $formatter = $display->getRenderer('field', $field['field_name']);
     $this->assertEqual($formatter->randomValue, $random_value );
 
     // Check that changing the definition creates a new formatter.
-    $display->setComponent($field['field_name'], array(
-      'type' => 'field_test_multiple',
+    $display->setComponent('field', $field['field_name'], array(
+      'formatter' => 'field_test_multiple',
     ));
-    $formatter = $display->getFormatter($field['field_name']);
+    $formatter = $display->getRenderer('field', $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['field_name'], array(
-      'type' => 'unknown_formatter',
+    $display->setComponent('field', $field['field_name'], array(
+      'formatter' => 'unknown_formatter',
     ));
-    $options = $display->getComponent($field['field_name']);
-    $this->assertEqual($options['type'], 'unknown_formatter');
-    $formatter = $display->getFormatter($field['field_name']);
+    $options = $display->getComponent('field', $field['field_name']);
+    $this->assertEqual($options['formatter'], 'unknown_formatter');
+    $formatter = $display->getRenderer('field', $field['field_name']);
     $this->assertEqual($formatter->getPluginId(), $default_formatter);
   }
 
diff --git a/core/modules/field/field.attach.inc b/core/modules/field/field.attach.inc
index e61f659..599d6c2 100644
--- a/core/modules/field/field.attach.inc
+++ b/core/modules/field/field.attach.inc
@@ -1393,7 +1393,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']]->getFormatter($instance['field_name']);
+      return $displays[$instance['bundle']]->getRenderer('field', $instance['field_name']);
     }
   };
   field_invoke_method_multiple('prepareView', $target_function, $prepare, $null, $null, $options);
@@ -1456,7 +1456,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->getFormatter($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.install b/core/modules/field/field.install
index dcf2b38..b75b874 100644
--- a/core/modules/field/field.install
+++ b/core/modules/field/field.install
@@ -280,9 +280,13 @@ function field_update_8002() {
 
       // The display object does not store hidden fields.
       if ($display_options['type'] != 'hidden') {
-        // We do not need the 'module' key anymore.
-        unset($display_options['module']);
-        $displays[$display_id]->set("content.$record->field_name", $display_options);
+        $displays[$display_id]->set("content.$record->field_name", array(
+          'handler_type' => 'field',
+          'weight' => $display_options['weight'],
+          'label' => $display_options['label'],
+          'formatter' => $display_options['type'],
+          'settings' => $display_options['settings'],
+        ));
       }
     }
 
@@ -315,7 +319,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 13fb22c..8f432bd 100644
--- a/core/modules/field/field.module
+++ b/core/modules/field/field.module
@@ -783,7 +783,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, specified in hook_field_info().
  *       The default formatter will also be used if the requested formatter is
  *       not available.
@@ -815,7 +815,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)->getFormatter($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/Type/Formatter/FormatterPluginManager.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php
index 2260610..4515691 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
@@ -58,7 +58,7 @@ public function __construct(\Traversable $namespaces) {
    *     - 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, specified in
    *       hook_field_info(). The default formatter will also be used if the
    *       requested formatter is not available.
@@ -78,12 +78,12 @@ public function getInstance(array $options) {
       $configuration = $this->prepareConfiguration($field['type'], $configuration);
     }
 
-    $plugin_id = $configuration['type'];
+    $plugin_id = $configuration['formatter'];
 
     // 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']);
@@ -115,12 +115,12 @@ public function prepareConfiguration($field_type, array $configuration) {
       'settings' => array(),
     );
     // If no formatter is specified, use the default formatter.
-    if (!isset($configuration['type'])) {
+    if (!isset($configuration['formatter'])) {
       $field_type = field_info_field_types($field_type);
-      $configuration['type'] = $field_type['default_formatter'];
+      $configuration['formatter'] = $field_type['default_formatter'];
     }
     // Fill in default settings values for the formatter.
-    $configuration['settings'] += field_info_formatter_settings($configuration['type']);
+    $configuration['settings'] += field_info_formatter_settings($configuration['formatter']);
 
     return $configuration;
   }
diff --git a/core/modules/field/lib/Drupal/field/Plugin/entity/display_component_handler/FieldDisplayComponentHandler.php b/core/modules/field/lib/Drupal/field/Plugin/entity/display_component_handler/FieldDisplayComponentHandler.php
new file mode 100644
index 0000000..fee0f4d
--- /dev/null
+++ b/core/modules/field/lib/Drupal/field/Plugin/entity/display_component_handler/FieldDisplayComponentHandler.php
@@ -0,0 +1,44 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\field\Plugin\entity\display_component_handler\FieldDisplayComponentHandler.
+ */
+
+namespace Drupal\field\Plugin\entity\display_component_handler;;
+
+use Drupal\Core\Annotation\Plugin;
+use Drupal\entity\Plugin\Type\DisplayComponentHandlerBase;
+
+/**
+ * @todo
+ *
+ * @Plugin(
+ *   id = "field",
+ *   module = "field"
+ * )
+ */
+class FieldDisplayComponentHandler extends DisplayComponentHandlerBase {
+
+  public function massageIn($name, array $options = NULL) {
+    if (!is_null($options)) {
+      // @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);
+    }
+  }
+
+  public function getRenderer($name, array $options = NULL) {
+    if ($options) {
+      return drupal_container()->get('plugin.manager.field.formatter')->getInstance(array(
+        'instance' => 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/views/field/Field.php b/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php
index e9517c0..e3c3833 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php
@@ -275,7 +275,7 @@ protected function defineOptions() {
     $options['click_sort_column'] = array(
       'default' => $default_column,
     );
-    $options['type'] = array(
+    $options['formatter'] = array(
       'default' => $field_type['default_formatter'],
     );
     $options['settings'] = array(
@@ -355,11 +355,11 @@ public function buildOptionsForm(&$form, &$form_state) {
       );
     }
 
-    $form['type'] = array(
+    $form['formatter'] = array(
       '#type' => 'select',
       '#title' => t('Formatter'),
       '#options' => $formatters,
-      '#default_value' => $this->options['type'],
+      '#default_value' => $this->options['formatter'],
       '#ajax' => array(
         'path' => views_ui_build_form_url($form_state),
       ),
@@ -381,7 +381,7 @@ public function buildOptionsForm(&$form, &$form_state) {
     }
 
     // Get the currently selected formatter.
-    $format = $this->options['type'];
+    $format = $this->options['formatter'];
 
     $settings = $this->options['settings'] + field_info_formatter_settings($format);
 
@@ -391,7 +391,7 @@ public function buildOptionsForm(&$form, &$form_state) {
     $options = array(
       'instance' => $this->instance,
       'configuration' => array(
-        'type' => $format,
+        'formatter' => $format,
         'settings' => $settings,
         'label' => '',
         'weight' => 0,
@@ -442,7 +442,7 @@ function fakeFieldInstance($formatter, $formatter_settings) {
       // Build a dummy display mode.
       'display' => array(
         '_custom' => array(
-          'type' => $formatter,
+          'formatter' => $formatter,
           'settings' => $formatter_settings,
         ),
       ),
@@ -658,7 +658,7 @@ function get_items($values) {
     }
 
     $display = array(
-      'type' => $this->options['type'],
+      'formatter' => $this->options['formatter'],
       'settings' => $this->options['settings'],
       'label' => 'hidden',
       // Pass the View object in the display so that fields can act on it.
diff --git a/core/modules/field/lib/Drupal/field/Tests/DisplayApiTest.php b/core/modules/field/lib/Drupal/field/Tests/DisplayApiTest.php
index 39d9594..547e9f3 100644
--- a/core/modules/field/lib/Drupal/field/Tests/DisplayApiTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/DisplayApiTest.php
@@ -39,13 +39,13 @@ function setUp() {
 
     $this->display_options = array(
       'default' => array(
-        'type' => 'field_test_default',
+        'formatter' => 'field_test_default',
         'settings' => array(
           'test_formatter_setting' => $this->randomName(),
         ),
       ),
       'teaser' => array(
-        'type' => 'field_test_default',
+        'formatter' => 'field_test_default',
         'settings' => array(
           'test_formatter_setting' => $this->randomName(),
         ),
@@ -56,11 +56,11 @@ function setUp() {
     field_create_instance($this->instance);
     // Create a display for the default view mode.
     entity_get_display($this->instance['entity_type'], $this->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($this->instance['entity_type'], $this->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.
@@ -88,7 +88,7 @@ function testFieldViewField() {
     // Check that explicit display settings are used.
     $display = array(
       'label' => 'hidden',
-      'type' => 'field_test_multiple',
+      'formatter' => 'field_test_multiple',
       'settings' => array(
         'test_formatter_setting_multiple' => $this->randomName(),
         'alter' => TRUE,
@@ -109,7 +109,7 @@ function testFieldViewField() {
     // Check the prepare_view steps are invoked.
     $display = array(
       'label' => 'hidden',
-      'type' => 'field_test_with_prepare_view',
+      'formatter' => 'field_test_with_prepare_view',
       'settings' => array(
         'test_formatter_setting_additional' => $this->randomName(),
       ),
@@ -161,13 +161,12 @@ function testFieldViewValue() {
 
     // Check that explicit display settings are used.
     $display = array(
-      'type' => 'field_test_multiple',
+      'formatter' => 'field_test_multiple',
       'settings' => array(
         'test_formatter_setting_multiple' => $this->randomName(),
       ),
     );
     $setting = $display['settings']['test_formatter_setting_multiple'];
-    $array = array();
     foreach ($this->values as $delta => $value) {
       $item = $this->entity->{$this->field_name}[LANGUAGE_NOT_SPECIFIED][$delta];
       $output = field_view_value($this->entity, $this->field_name, $item, $display);
@@ -177,13 +176,12 @@ function testFieldViewValue() {
 
     // Check that prepare_view steps are invoked.
     $display = array(
-      'type' => 'field_test_with_prepare_view',
+      'formatter' => 'field_test_with_prepare_view',
       'settings' => array(
         'test_formatter_setting_additional' => $this->randomName(),
       ),
     );
     $setting = $display['settings']['test_formatter_setting_additional'];
-    $array = array();
     foreach ($this->values as $delta => $value) {
       $item = $this->entity->{$this->field_name}[LANGUAGE_NOT_SPECIFIED][$delta];
       $output = field_view_value($this->entity, $this->field_name, $item, $display);
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldAccessTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldAccessTest.php
index 86f1f34..c6e28d0 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldAccessTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldAccessTest.php
@@ -55,7 +55,7 @@ function setUp() {
     // Assign display properties for the 'default' and 'teaser' view modes.
     foreach (array('default', 'teaser') as $view_mode) {
       entity_get_display('node', $this->content_type, $view_mode)
-        ->setComponent($this->field['field_name'])
+        ->setComponent('field', $this->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 1ec87cf..d1d8b4d 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php
@@ -51,22 +51,22 @@ function testFieldAttachView() {
     $formatter_setting = $this->randomName();
     $display_options = array(
       'label' => 'above',
-      'type' => 'field_test_default',
+      'formatter' => 'field_test_default',
       'settings' => array(
         '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(
       'label' => 'above',
-      'type' => 'field_test_default',
+      'formatter' => 'field_test_default',
       'settings' => array(
         '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->ftid => $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->ftid => $entity), $displays);
     $entity->content = field_attach_view($entity, $display);
     $output = drupal_render($entity->content);
@@ -111,7 +111,7 @@ function testFieldAttachView() {
 
     // Field hidden.
     $entity = clone($entity_init);
-    $display->removeComponent($this->field['field_name']);
+    $display->removeComponent('field', $this->field['field_name']);
     field_attach_prepare_view($entity_type, array($entity->ftid => $entity), $displays);
     $entity->content = field_attach_view($entity, $display);
     $output = drupal_render($entity->content);
@@ -124,9 +124,9 @@ 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',
+      'formatter' => 'field_test_multiple',
       'settings' => array(
         'test_formatter_setting_multiple' => $formatter_setting,
       ),
@@ -144,9 +144,9 @@ 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',
+      'formatter' => 'field_test_with_prepare_view',
       'settings' => array(
         'test_formatter_setting_additional' => $formatter_setting,
       ),
@@ -185,7 +185,7 @@ function testFieldAttachPrepareViewMultiple() {
 
     // Set the instance to be hidden.
     $display = entity_get_display('test_entity', 'test_bundle', 'full')
-      ->removeComponent($this->field['field_name']);
+      ->removeComponent('field', $this->field['field_name']);
 
     // Set up a second instance on another bundle, with a formatter that uses
     // hook_field_formatter_prepare_view().
@@ -196,8 +196,8 @@ function testFieldAttachPrepareViewMultiple() {
     field_create_instance($this->instance2);
 
     $display_2 = entity_get_display('test_entity', 'test_bundle_2', 'full')
-      ->setComponent($this->field['field_name'], array(
-        'type' => 'field_test_with_prepare_view',
+      ->setComponent('field', $this->field['field_name'], array(
+        'formatter' => 'field_test_with_prepare_view',
         'settings' => array(
           'test_formatter_setting_additional' => $formatter_setting,
         ),
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..46be374 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'));
@@ -72,7 +72,7 @@ public function testHandlerUI() {
     $this->drupalPost('admin/structure/views/view/test_view_fieldapi', array(), t('Save'));
     $view = views_get_view('test_view_fieldapi');
     $view->initHandlers();
-    $this->assertEqual($view->field['field_name_0']->options['type'], 'text_trimmed');
+    $this->assertEqual($view->field['field_name_0']->options['formatter'], 'text_trimmed');
     $this->assertEqual($view->field['field_name_0']->options['settings']['trim_length'], $random_number);
   }
 
diff --git a/core/modules/field/lib/Drupal/field/Tests/Views/HandlerFieldFieldTest.php b/core/modules/field/lib/Drupal/field/Tests/Views/HandlerFieldFieldTest.php
index 6d1975e..6aef9aa 100644
--- a/core/modules/field/lib/Drupal/field/Tests/Views/HandlerFieldFieldTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/Views/HandlerFieldFieldTest.php
@@ -116,7 +116,7 @@ public function _testSimpleFieldRender() {
   public function _testFormatterSimpleFieldRender() {
     $view = views_get_view('test_view_fieldapi');
     $this->prepareView($view);
-    $view->displayHandlers->get('default')->options['fields'][$this->fields[0]['field_name']]['type'] = 'text_trimmed';
+    $view->displayHandlers->get('default')->options['fields'][$this->fields[0]['field_name']]['formatter'] = 'text_trimmed';
     $view->displayHandlers->get('default')->options['fields'][$this->fields[0]['field_name']]['settings'] = array(
       'trim_length' => 3,
     );
diff --git a/core/modules/field_ui/field_ui.admin.inc b/core/modules/field_ui/field_ui.admin.inc
index e419063..7306b4c 100644
--- a/core/modules/field_ui/field_ui.admin.inc
+++ b/core/modules/field_ui/field_ui.admin.inc
@@ -124,8 +124,9 @@ function field_ui_field_overview_row_region($row) {
 function field_ui_display_overview_row_region($row) {
   switch ($row['#row_type']) {
     case 'field':
+      return ($row['format']['formatter']['#value'] == 'hidden' ? 'hidden' : 'content');
     case 'extra_field':
-      return ($row['format']['type']['#value'] == 'hidden' ? 'hidden' : 'content');
+      return ($row['format']['visibility']['#value'] == 'hidden' ? 'hidden' : 'content');
   }
 }
 
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 cf4f6de..fa26f13 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php
@@ -102,7 +102,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL,
     // Field rows.
     foreach ($instances as $name => $instance) {
       $field = field_info_field($name);
-      $display_options = $entity_display->getComponent($name);
+      $display_options = $entity_display->getComponent('field', $name);
 
       $table[$name] = array(
         '#attributes' => array('class' => array('draggable', 'tabledrag-leaf')),
@@ -151,13 +151,13 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL,
       $formatter_options = field_ui_formatter_options($field['type']);
       $formatter_options['hidden'] = '<' . t('Hidden') . '>';
       $table[$name]['format'] = array(
-        'type' => array(
+        'formatter' => array(
           '#type' => 'select',
           '#title' => t('Formatter for @title', array('@title' => $instance['label'])),
           '#title_display' => 'invisible',
           '#options' => $formatter_options,
-          '#default_value' => $display_options ? $display_options['type'] : 'hidden',
-          '#parents' => array('fields', $name, 'type'),
+          '#default_value' => $display_options ? $display_options['formatter'] : 'hidden',
+          '#parents' => array('fields', $name, 'formatter'),
           '#attributes' => array('class' => array('field-formatter-type')),
         ),
         'settings_edit_form' => array(),
@@ -165,15 +165,15 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL,
 
       // Check the currently selected formatter, and merge persisted values for
       // formatter settings.
-      if (isset($form_state['values']['fields'][$name]['type'])) {
-        $display_options['type'] = $form_state['values']['fields'][$name]['type'];
+      if (isset($form_state['values']['fields'][$name]['formatter'])) {
+        $display_options['formatter'] = $form_state['values']['fields'][$name]['formatter'];
       }
       if (isset($form_state['formatter_settings'][$name])) {
         $display_options['settings'] = $form_state['formatter_settings'][$name];
       }
 
       // Get the corresponding formatter object.
-      if ($display_options && $display_options['type'] != 'hidden') {
+      if ($display_options && $display_options['formatter'] != 'hidden') {
         $formatter = drupal_container()->get('plugin.manager.field.formatter')->getInstance(array(
           'instance' => $instance,
           'view_mode' => $this->view_mode,
@@ -239,7 +239,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL,
                   '#op' => 'cancel',
                   // Do not check errors for the 'Cancel' button, but make sure we
                   // get the value of the 'formatter type' select.
-                  '#limit_validation_errors' => array(array('fields', $name, 'type')),
+                  '#limit_validation_errors' => array(array('fields', $name, 'formatter')),
                 ),
               ),
             );
@@ -278,7 +278,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL,
               '#op' => 'edit',
               // Do not check errors for the 'Edit' button, but make sure we get
               // the value of the 'formatter type' select.
-              '#limit_validation_errors' => array(array('fields', $name, 'type')),
+              '#limit_validation_errors' => array(array('fields', $name, 'formatter')),
               '#prefix' => '<div class="field-formatter-settings-edit-wrapper">',
               '#suffix' => '</div>',
             );
@@ -289,7 +289,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL,
 
     // Non-field elements.
     foreach ($extra_fields as $name => $extra_field) {
-      $display_options = $entity_display->getComponent($name);
+      $display_options = $entity_display->getComponent('extra_field', $name);
 
       $table[$name] = array(
         '#attributes' => array('class' => array('draggable', 'tabledrag-leaf')),
@@ -327,13 +327,13 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL,
           '#markup' => '&nbsp;',
         ),
         'format' => array(
-          'type' => array(
+          'visibility' => array(
             '#type' => 'select',
             '#title' => t('Visibility for @title', array('@title' => $extra_field['label'])),
             '#title_display' => 'invisible',
             '#options' => $extra_visibility_options,
             '#default_value' => $display_options ? 'visible' : 'hidden',
-            '#parents' => array('fields', $name, 'type'),
+            '#parents' => array('fields', $name, 'visibility'),
             '#attributes' => array('class' => array('field-formatter-type')),
           ),
         ),
@@ -422,8 +422,8 @@ public function submitForm(array &$form, array &$form_state) {
       // values.
       $values = $form_values['fields'][$field_name];
 
-      if ($values['type'] == 'hidden') {
-        $display->removeComponent($field_name);
+      if ($values['formatter'] == 'hidden') {
+        $display->removeComponent('field', $field_name);
       }
       else {
         // Get formatter settings. They lie either directly in submitted form
@@ -436,17 +436,17 @@ public function submitForm(array &$form, array &$form_state) {
         elseif (isset($form_state['formatter_settings'][$field_name])) {
           $settings = $form_state['formatter_settings'][$field_name];
         }
-        elseif ($current_options = $display->getComponent($field_name)) {
+        elseif ($current_options = $display->getComponent('field', $field_name)) {
           $settings = $current_options['settings'];
         }
 
         // Only save settings actually used by the selected formatter.
-        $default_settings = field_info_formatter_settings($values['type']);
+        $default_settings = field_info_formatter_settings($values['formatter']);
         $settings = array_intersect_key($settings, $default_settings);
 
-        $display->setComponent($field_name, array(
+        $display->setComponent('field', $field_name, array(
           'label' => $values['label'],
-          'type' => $values['type'],
+          'formatter' => $values['formatter'],
           'weight' => $values['weight'],
           'settings' => $settings,
         ));
@@ -455,11 +455,11 @@ public function submitForm(array &$form, array &$form_state) {
 
     // Collect data for 'extra' fields.
     foreach ($form['#extra'] as $name) {
-      if ($form_values['fields'][$name]['type'] == 'hidden') {
-        $display->removeComponent($name);
+      if ($form_values['fields'][$name]['visibility'] == 'hidden') {
+        $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 f02e2eb..dc97ac1 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php
@@ -571,7 +571,7 @@ public function submitForm(array &$form, array &$form_state) {
         // 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
@@ -614,7 +614,7 @@ public function submitForm(array &$form, array &$form_state) {
           // 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/Tests/ManageDisplayTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php
index 51dc8b1..7a79ac8 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,8 +45,8 @@ 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');
-    $format = $display_options['type'];
+    $display_options = $display->getComponent('field', 'field_test');
+    $format = $display_options['formatter'];
     $default_settings = field_info_formatter_settings($format);
     $setting_name = key($default_settings);
     $setting_value = $display_options['settings'][$setting_name];
@@ -54,24 +54,24 @@ function testFormatterUI() {
     // Display the "Manage display" screen and check that the expected formatter is
     // selected.
     $this->drupalGet($manage_display);
-    $this->assertFieldByName('fields[field_test][type]', $format, 'The expected formatter is selected.');
+    $this->assertFieldByName('fields[field_test][formatter]', $format, 'The expected formatter is selected.');
     $this->assertText("$setting_name: $setting_value", 'The expected summary is displayed.');
 
     // Change the formatter and check that the summary is updated.
-    $edit = array('fields[field_test][type]' => 'field_test_multiple', 'refresh_rows' => 'field_test');
+    $edit = array('fields[field_test][formatter]' => 'field_test_multiple', 'refresh_rows' => 'field_test');
     $this->drupalPostAJAX(NULL, $edit, array('op' => t('Refresh')));
     $format = 'field_test_multiple';
     $default_settings = field_info_formatter_settings($format);
     $setting_name = key($default_settings);
     $setting_value = $default_settings[$setting_name];
-    $this->assertFieldByName('fields[field_test][type]', $format, 'The expected formatter is selected.');
+    $this->assertFieldByName('fields[field_test][formatter]', $format, 'The expected formatter is selected.');
     $this->assertText("$setting_name: $setting_value", 'The expected summary is displayed.');
 
     // 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');
-    $current_format = $display_options['type'];
+    $display_options = $display->getComponent('field', 'field_test');
+    $current_format = $display_options['formatter'];
     $current_setting_value = $display_options['settings'][$setting_name];
     $this->assertEqual($current_format, $format, 'The formatter was updated.');
     $this->assertEqual($current_setting_value, $setting_value, 'The setting was updated.');
@@ -130,7 +130,7 @@ function testViewModeCustom() {
     // Change fomatter for 'default' mode, check that the field is displayed
     // accordingly in 'rss' mode.
     $edit = array(
-      'fields[field_test][type]' => 'field_test_with_prepare_view',
+      'fields[field_test][formatter]' => 'field_test_with_prepare_view',
     );
     $this->drupalPost('admin/structure/types/manage/' . $this->type . '/display', $edit, t('Save'));
     $this->assertNodeViewText($node, 'rss', $output['field_test_with_prepare_view'], "The field is displayed as expected in view modes that use 'default' settings.");
@@ -145,7 +145,7 @@ function testViewModeCustom() {
     // Set the field to 'hidden' in the view mode, check that the field is
     // hidden.
     $edit = array(
-      'fields[field_test][type]' => 'hidden',
+      'fields[field_test][formatter]' => 'hidden',
     );
     $this->drupalPost('admin/structure/types/manage/' . $this->type . '/display/rss', $edit, t('Save'));
     $this->assertNodeViewNoText($node, 'rss', $value, "The field is hidden in 'rss' mode.");
@@ -185,7 +185,7 @@ function testNonInitializedFields() {
     // Check that the field appears as 'hidden' on the 'Manage display' page
     // for the 'teaser' mode.
     $this->drupalGet('admin/structure/types/manage/' . $this->type . '/display/teaser');
-    $this->assertFieldByName('fields[field_test][type]', 'hidden', 'The field is displayed as \'hidden \'.');
+    $this->assertFieldByName('fields[field_test][formatter]', 'hidden', 'The field is displayed as \'hidden \'.');
   }
 
   /**
diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldDisplayTest.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldDisplayTest.php
index d50ecb6..8f91593 100644
--- a/core/modules/file/lib/Drupal/file/Tests/FileFieldDisplayTest.php
+++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldDisplayTest.php
@@ -44,7 +44,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 a66fd8d..3476446 100644
--- a/core/modules/file/lib/Drupal/file/Tests/FileFieldRSSContentTest.php
+++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldRSSContentTest.php
@@ -52,7 +52,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/forum/forum.install b/core/modules/forum/forum.install
index 6855a6d..488ee01 100644
--- a/core/modules/forum/forum.install
+++ b/core/modules/forum/forum.install
@@ -92,14 +92,14 @@ function forum_enable() {
 
     // Assign display settings for the 'default' and 'teaser' view modes.
     entity_get_display('node', 'forum', 'default')
-      ->setComponent('taxonomy_forums', array(
-        'type' => 'taxonomy_term_reference_link',
+      ->setComponent('field', 'taxonomy_forums', array(
+        'formatter' => 'taxonomy_term_reference_link',
         'weight' => 10,
       ))
       ->save();
     entity_get_display('node', 'forum', 'teaser')
-      ->setComponent('taxonomy_forums', array(
-        'type' => 'taxonomy_term_reference_link',
+      ->setComponent('field', 'taxonomy_forums', array(
+        'formatter' => 'taxonomy_term_reference_link',
         'weight' => 10,
       ))
       ->save();
diff --git a/core/modules/image/lib/Drupal/image/ImageStyleStorageController.php b/core/modules/image/lib/Drupal/image/ImageStyleStorageController.php
index 4bbbbde..a1f8e2d 100644
--- a/core/modules/image/lib/Drupal/image/ImageStyleStorageController.php
+++ b/core/modules/image/lib/Drupal/image/ImageStyleStorageController.php
@@ -81,14 +81,14 @@ protected 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()) {
+            if ($display_options && $display_options['formatter'] == '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();
             }
           }
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageAdminStylesTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageAdminStylesTest.php
index 4cb1dca..d83fd6d 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageAdminStylesTest.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageAdminStylesTest.php
@@ -258,8 +258,8 @@ function testStyleReplacement() {
     $field_name = strtolower($this->randomName(10));
     $this->createImageField($field_name, 'article');
     entity_get_display('node', 'article', 'default')
-      ->setComponent($field_name, array(
-        'type' => 'image',
+      ->setComponent('field', $field_name, array(
+        'formatter' => 'image',
         'settings' => array('image_style' => $style_name),
       ))
       ->save();
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php
index 7767dc4..eedb2d4 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php
@@ -70,7 +70,7 @@ function testDefaultImages() {
     field_create_instance($instance2);
     $instance2 = field_info_instance('node', $field_name, 'page');
     entity_get_display('node', 'page', 'default')
-      ->setComponent($field['field_name'])
+      ->setComponent('field', $field['field_name'])
       ->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 c30c686..2f14ac0 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
@@ -67,11 +67,11 @@ function _testImageFieldFormatters($scheme) {
 
     // Test the image linked to file formatter.
     $display_options = array(
-      'type' => 'image',
+      'formatter' => 'image',
       '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));
@@ -96,7 +96,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);
@@ -105,7 +105,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 5a4e20e..b8f9340 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php
@@ -96,7 +96,7 @@ function createImageField($name, $type_name, $field_settings = array(), $instanc
     $field_instance = field_create_instance($instance);
 
     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 f28bcc2..32e39a3 100644
--- a/core/modules/link/lib/Drupal/link/Tests/LinkFieldTest.php
+++ b/core/modules/link/lib/Drupal/link/Tests/LinkFieldTest.php
@@ -65,8 +65,8 @@ function testURLValidation() {
     );
     field_create_instance($this->instance);
     entity_get_display('test_entity', 'test_bundle', 'full')
-      ->setComponent($this->field['field_name'], array(
-        'type' => 'link',
+      ->setComponent('field', $this->field['field_name'], array(
+        'formatter' => 'link',
       ))
       ->save();
 
@@ -135,8 +135,8 @@ function testLinkTitle() {
     );
     field_create_instance($this->instance);
     entity_get_display('test_entity', 'test_bundle', 'full')
-      ->setComponent($this->field['field_name'], array(
-        'type' => 'link',
+      ->setComponent('field', $this->field['field_name'], array(
+        'formatter' => 'link',
         'label' => 'hidden',
       ))
       ->save();
@@ -242,13 +242,13 @@ function testLinkFormatter() {
         'type' => 'link_default',
       ),
     );
+    field_create_instance($this->instance);
     $display_options = array(
-      'type' => 'link',
+      'formatter' => 'link',
       'label' => 'hidden',
     );
-    field_create_instance($this->instance);
     entity_get_display('test_entity', 'test_bundle', 'full')
-      ->setComponent($this->field['field_name'], $display_options)
+      ->setComponent('field', $this->field['field_name'], $display_options)
       ->save();
 
     $langcode = LANGUAGE_NOT_SPECIFIED;
@@ -304,7 +304,7 @@ function testLinkFormatter() {
           $display_options['settings'] = $new_value;
         }
         entity_get_display('test_entity', 'test_bundle', 'full')
-          ->setComponent($this->field['field_name'], $display_options)
+          ->setComponent('field', $this->field['field_name'], $display_options)
           ->save();
 
         $this->renderTestEntity($id);
@@ -380,13 +380,13 @@ function testLinkSeparateFormatter() {
         'type' => 'link_default',
       ),
     );
+    field_create_instance($this->instance);
     $display_options = array(
-      'type' => 'link_separate',
+      'formatter' => 'link_separate',
       'label' => 'hidden',
     );
-    field_create_instance($this->instance);
     entity_get_display('test_entity', 'test_bundle', 'full')
-      ->setComponent($this->field['field_name'], $display_options)
+      ->setComponent('field', $this->field['field_name'], $display_options)
       ->save();
 
     $langcode = LANGUAGE_NOT_SPECIFIED;
@@ -422,7 +422,7 @@ function testLinkSeparateFormatter() {
         // Update the field formatter settings.
         $display_options['settings'] = array($setting => $new_value);
         entity_get_display('test_entity', 'test_bundle', '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 6a6608a..5e31fbf 100644
--- a/core/modules/node/lib/Drupal/node/NodeRenderController.php
+++ b/core/modules/node/lib/Drupal/node/NodeRenderController.php
@@ -71,7 +71,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/Tests/NodeAccessFieldTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeAccessFieldTest.php
index 452ed93..d5f7999 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeAccessFieldTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeAccessFieldTest.php
@@ -46,7 +46,7 @@ public function setUp() {
     );
     $this->instance = field_create_instance($instance);
     entity_get_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 2643981..e81dc5a 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeTypeInitialLanguageTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeTypeInitialLanguageTest.php
@@ -83,7 +83,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(
@@ -118,11 +118,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/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 78a3139..40b03fa 100644
--- a/core/modules/node/node.api.php
+++ b/core/modules/node/node.api.php
@@ -880,7 +880,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',
@@ -1352,7 +1352,7 @@ function hook_view(\Drupal\Core\Entity\EntityInterface $node, \Drupal\entity\Plu
   // 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 7ba5d23..8feeaca 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -227,11 +227,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);
     }
   }
 }
@@ -579,15 +577,15 @@ function node_add_body_field($type, $label = 'Body') {
 
     // Assign display settings for the 'default' and 'teaser' view modes.
     entity_get_display('node', $type->type, 'default')
-      ->setComponent($field['field_name'], array(
+      ->setComponent('field', $field['field_name'], array(
         'label' => 'hidden',
-        'type' => 'text_default',
+        'formatter' => 'text_default',
       ))
       ->save();
     entity_get_display('node', $type->type, 'teaser')
-      ->setComponent($field['field_name'], array(
+      ->setComponent('field', $field['field_name'], array(
         'label' => 'hidden',
-        'type' => 'text_summary_or_trimmed',
+        'formatter' => 'text_summary_or_trimmed',
       ))
       ->save();
   }
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 aa6c06e..0f6f3ea 100644
--- a/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php
+++ b/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php
@@ -66,7 +66,7 @@ function testNumberDecimalField() {
     );
     field_create_instance($this->instance);
     entity_get_display('test_entity', 'test_bundle', 'default')
-      ->setComponent($this->field['field_name'])
+      ->setComponent('field', $this->field['field_name'])
       ->save();
 
     // Display creation form.
@@ -151,11 +151,11 @@ function testNumberIntegerField() {
     // check that the settings summary does not generate warnings.
     $this->drupalGet("admin/structure/types/manage/$type/display");
     $edit = array(
-      "fields[field_$field_name][type]" => 'number_integer',
+      "fields[field_$field_name][formatter]" => 'number_integer',
     );
     $this->drupalPost(NULL, $edit, t('Save'));
     $edit = array(
-      "fields[field_$field_name][type]" => 'number_unformatted',
+      "fields[field_$field_name][formatter]" => 'number_unformatted',
     );
     $this->drupalPost(NULL, $edit, t('Save'));
   }
diff --git a/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php b/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php
index c8cd4cb..0e7d07d 100644
--- a/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php
+++ b/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php
@@ -133,12 +133,11 @@ public function _testPictureFieldFormatters($scheme) {
 
     // Use the picture formatter linked to file formatter.
     $display_options = array(
-      'type' => 'picture',
-      'module' => 'picture',
+      'formatter' => '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));
@@ -163,7 +162,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.
@@ -178,7 +177,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/RdfaMarkupTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/RdfaMarkupTest.php
index 6f99dae..982ba29 100644
--- a/core/modules/rdf/lib/Drupal/rdf/Tests/RdfaMarkupTest.php
+++ b/core/modules/rdf/lib/Drupal/rdf/Tests/RdfaMarkupTest.php
@@ -118,8 +118,8 @@ function testAttributesInMarkupFile() {
     );
     field_create_instance($instance);
     entity_get_display('node', $bundle_name, 'teaser')
-      ->setComponent($field_name, array(
-        'type' => 'file_default',
+      ->setComponent('field', $field_name, array(
+        'formatter' => 'file_default',
       ))
       ->save();
 
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 0936aa5..5908365 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php
@@ -52,14 +52,16 @@ public function testEntityDisplayUpgrade() {
     // Check that the 'body' field is configured as expected.
     $expected = array(
       'default' => array(
+        'handler_type' => 'field',
         'label' => 'hidden',
-        'type' => 'text_default',
+        'formatter' => 'text_default',
         'weight' => 0,
         'settings' => array(),
       ),
       'teaser' => array(
+        'handler_type' => 'field',
         'label' => 'hidden',
-        'type' => 'text_summary_or_trimmed',
+        'formatter' => 'text_summary_or_trimmed',
         'weight' => 0,
         'settings' => array(
           'trim_length' => 600,
@@ -76,10 +78,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 cb68737..b9ff450 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/UserPictureUpgradePathTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/UserPictureUpgradePathTest.php
@@ -58,12 +58,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.module b/core/modules/system/tests/modules/entity_test/entity_test.module
index 673ab67..8a38e98 100644
--- a/core/modules/system/tests/modules/entity_test/entity_test.module
+++ b/core/modules/system/tests/modules/entity_test/entity_test.module
@@ -136,7 +136,7 @@ function entity_test_entity_bundle_info_alter(&$bundles) {
  * 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
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/TermRenderController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/TermRenderController.php
index 4b6c60f..0f187f5 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 ca775e9..e29a7cc 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php
@@ -59,8 +59,8 @@ function setUp() {
     );
     field_create_instance($this->instance);
     entity_get_display('node', 'article', 'default')
-      ->setComponent('taxonomy_' . $this->vocabulary->id(), array(
-        'type' => 'taxonomy_term_reference_link',
+      ->setComponent('field', 'taxonomy_' . $this->vocabulary->id(), array(
+        'formatter' => 'taxonomy_term_reference_link',
       ))
       ->save();
   }
@@ -84,7 +84,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 f84f02a..e0910fc 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php
@@ -69,8 +69,8 @@ function setUp() {
     );
     field_create_instance($this->instance);
     entity_get_display('test_entity', 'test_bundle', 'full')
-      ->setComponent($this->field_name, array(
-        'type' => 'taxonomy_term_reference_link',
+      ->setComponent('field', $this->field_name, array(
+        'formatter' => '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 83051fa..8db7c86 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php
@@ -64,8 +64,8 @@ function setUp() {
     );
     field_create_instance($this->instance);
     entity_get_display('test_entity', 'test_bundle', 'full')
-      ->setComponent($this->field_name, array(
-        'type' => 'taxonomy_term_reference_link',
+      ->setComponent('field', $this->field_name, array(
+        'formatter' => '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 022a1fa..4d405b8 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php
@@ -55,8 +55,8 @@ function setUp() {
     );
     field_create_instance($this->instance_1);
     entity_get_display('node', 'article', 'default')
-      ->setComponent($this->field_name_1, array(
-        'type' => 'taxonomy_term_reference_link',
+      ->setComponent('field', $this->field_name_1, array(
+        'formatter' => 'taxonomy_term_reference_link',
       ))
       ->save();
 
@@ -85,8 +85,8 @@ function setUp() {
     );
     field_create_instance($this->instance_2);
     entity_get_display('node', 'article', 'default')
-      ->setComponent($this->field_name_2, array(
-        'type' => 'taxonomy_term_reference_link',
+      ->setComponent('field', $this->field_name_2, array(
+        'formatter' => '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 b9b1108..52aa44c 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
@@ -51,8 +51,8 @@ function setUp() {
     );
     field_create_instance($this->instance);
     entity_get_display('node', 'article', 'default')
-      ->setComponent($this->instance['field_name'], array(
-        'type' => 'taxonomy_term_reference_link',
+      ->setComponent('field', $this->instance['field_name'], array(
+        'formatter' => 'taxonomy_term_reference_link',
       ))
       ->save();
   }
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php
index 0a45dd2..9bc0f4d 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php
@@ -52,8 +52,8 @@ function setUp() {
     );
     field_create_instance($this->instance);
     entity_get_display('node', 'article', 'default')
-      ->setComponent('taxonomy_' . $this->vocabulary->id(), array(
-        'type' => 'taxonomy_term_reference_link',
+      ->setComponent('field', 'taxonomy_' . $this->vocabulary->id(), array(
+        'formatter' => '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 6de1b17..618bc7c 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/Views/TaxonomyTestBase.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/Views/TaxonomyTestBase.php
@@ -108,14 +108,14 @@ protected function mockStandardInstall() {
     field_create_instance($instance);
 
     entity_get_display('node', 'article', 'default')
-      ->setComponent($instance['field_name'], array(
-        'type' => 'taxonomy_term_reference_link',
+      ->setComponent('field', $instance['field_name'], array(
+        'formatter' => 'taxonomy_term_reference_link',
         'weight' => 10,
       ))
       ->save();
     entity_get_display('node', 'article', 'teaser')
-      ->setComponent($instance['field_name'], array(
-        'type' => 'taxonomy_term_reference_link',
+      ->setComponent('field', $instance['field_name'], array(
+        'formatter' => 'taxonomy_term_reference_link',
         'weight' => 10,
       ))
       ->save();
diff --git a/core/modules/taxonomy/taxonomy.api.php b/core/modules/taxonomy/taxonomy.api.php
index 24fcc01..61094b2 100644
--- a/core/modules/taxonomy/taxonomy.api.php
+++ b/core/modules/taxonomy/taxonomy.api.php
@@ -269,7 +269,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 1bec98f..1934316 100644
--- a/core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneFieldTest.php
+++ b/core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneFieldTest.php
@@ -74,8 +74,8 @@ function testTelephoneField() {
     field_create_instance($instance);
 
     entity_get_display('node', 'article', 'default')
-      ->setComponent('field_telephone', array(
-        'type' => 'telephone_link',
+      ->setComponent('field', 'field_telephone', array(
+        'formatter' => 'telephone_link',
         'weight' => 1,
       ))
       ->save();
diff --git a/core/modules/text/lib/Drupal/text/Tests/TextFieldTest.php b/core/modules/text/lib/Drupal/text/Tests/TextFieldTest.php
index f8c585b..9506b9c 100644
--- a/core/modules/text/lib/Drupal/text/Tests/TextFieldTest.php
+++ b/core/modules/text/lib/Drupal/text/Tests/TextFieldTest.php
@@ -68,7 +68,7 @@ function testTextFieldValidation() {
     );
     field_create_instance($this->instance);
     entity_get_display('test_entity', 'test_bundle', 'default')
-      ->setComponent($this->field['field_name'])
+      ->setComponent('field', $this->field['field_name'])
       ->save();
 
     // Test valid and invalid values with field_attach_validate().
@@ -120,7 +120,7 @@ function _testTextfieldWidgets($field_type, $widget_type) {
     );
     field_create_instance($this->instance);
     entity_get_display('test_entity', 'test_bundle', 'full')
-      ->setComponent($this->field_name)
+      ->setComponent('field', $this->field_name)
       ->save();
 
     $langcode = LANGUAGE_NOT_SPECIFIED;
@@ -180,7 +180,7 @@ function _testTextfieldWidgetsFormatted($field_type, $widget_type) {
     );
     field_create_instance($this->instance);
     entity_get_display('test_entity', 'test_bundle', 'full')
-      ->setComponent($this->field_name)
+      ->setComponent('field', $this->field_name)
       ->save();
 
     $langcode = LANGUAGE_NOT_SPECIFIED;
diff --git a/core/modules/user/user.api.php b/core/modules/user/user.api.php
index 652c5b5..4201a70 100644
--- a/core/modules/user/user.api.php
+++ b/core/modules/user/user.api.php
@@ -363,7 +363,7 @@ function hook_user_view(\Drupal\user\Plugin\Core\Entity\User $account, \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
   // 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 dca417c..b5de19a 100644
--- a/core/modules/user/user.install
+++ b/core/modules/user/user.install
@@ -349,9 +349,9 @@ 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',
+      'formatter' => 'image',
       'settings' => array(
         'image_style' => 'thumbnail',
         'image_link' => 'content',
@@ -359,16 +359,16 @@ 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',
+      'formatter' => 'image',
       'settings' => array(
         'image_style' => 'thumbnail',
         'image_link' => 'content',
       ),
     ))
     // Additionally, hide 'summary' pseudo-field from compact view mode..
-    ->removeComponent('member_for')
+    ->removeComponent('extra_field', 'member_for')
     ->save();
 }
 
@@ -756,8 +756,9 @@ function user_update_8011() {
 
   $display = _update_8000_entity_get_display('user', 'user', 'default');
   $display->set('content.user_picture', array(
+      'handler_type' => 'field',
       'label' => 'hidden',
-      'type' => $formatter,
+      'formatter' => $formatter,
       'settings' => array(
         'image_style' => 'thumbnail',
         'image_link' => 'content',
@@ -769,8 +770,9 @@ 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,
+      'formatter' => $formatter,
       'settings' => array(
         'image_style' => update_variable_get('user_picture_style', ''),
         'image_link' => 'content',
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index ed3078c..7617020 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -616,7 +616,7 @@ function user_search_execute($keys = NULL, $conditions = NULL) {
  * Implements hook_user_view().
  */
 function user_user_view(User $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/DefaultViewsTest.php b/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php
index c6e44fe..90528e6 100644
--- a/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php
@@ -83,8 +83,8 @@ protected function setUp() {
     );
     field_create_instance($this->instance);
     entity_get_display('node', 'page', 'full')
-      ->setComponent($this->field_name, array(
-        'type' => 'taxonomy_term_reference_link',
+      ->setComponent('field', $this->field_name, array(
+        'formatter' => 'taxonomy_term_reference_link',
       ))
       ->save();
 
diff --git a/core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php b/core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php
index 7c150dc..62cba00 100644
--- a/core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php
@@ -81,14 +81,14 @@ function setUp() {
     field_create_instance($this->tag_instance);
 
     entity_get_display('node', $this->node_type_with_tags->type, 'default')
-      ->setComponent('field_views_testing_tags', array(
-        'type' => 'taxonomy_term_reference_link',
+      ->setComponent('field', 'field_views_testing_tags', array(
+        'formatter' => 'taxonomy_term_reference_link',
         'weight' => 10,
       ))
       ->save();
     entity_get_display('node', $this->node_type_with_tags->type, 'teaser')
-      ->setComponent('field_views_testing_tags', array(
-        'type' => 'taxonomy_term_reference_link',
+      ->setComponent('field', 'field_views_testing_tags', array(
+        'formatter' => 'taxonomy_term_reference_link',
         'weight' => 10,
       ))
       ->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 7cd3ae0..9ae9d63 100644
--- a/core/profiles/standard/config/entity.display.node.article.default.yml
+++ b/core/profiles/standard/config/entity.display.node.article.default.yml
@@ -4,18 +4,21 @@ bundle: article
 viewMode: default
 content:
   body:
+    handler_type: field
     label: hidden
-    type: text_default
+    formatter: text_default
     weight: '0'
     settings: {  }
   field_tags:
-    type: taxonomy_term_reference_link
+    handler_type: field
+    formatter: taxonomy_term_reference_link
     weight: '10'
     label: above
     settings: {  }
   field_image:
+    handler_type: field
     label: hidden
-    type: image
+    formatter: image
     settings:
       image_style: large
       image_link: ''
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 ae65eb4..b61878a 100644
--- a/core/profiles/standard/config/entity.display.node.article.teaser.yml
+++ b/core/profiles/standard/config/entity.display.node.article.teaser.yml
@@ -4,19 +4,22 @@ bundle: article
 viewMode: teaser
 content:
   body:
+    handler_type: field
     label: hidden
-    type: text_summary_or_trimmed
+    formatter: text_summary_or_trimmed
     weight: '0'
     settings:
       trim_length: '600'
   field_tags:
-    type: taxonomy_term_reference_link
+    handler_type: field
+    formatter: taxonomy_term_reference_link
     weight: '10'
     label: above
     settings: {  }
   field_image:
+    handler_type: field
     label: hidden
-    type: image
+    formatter: image
     settings:
       image_style: medium
       image_link: content
