diff --git modules/field/field.api.php modules/field/field.api.php
index 35243dc..152db03 100644
--- modules/field/field.api.php
+++ modules/field/field.api.php
@@ -2178,6 +2178,46 @@ function hook_field_extra_fields_display_alter(&$displays, $context) {
     $displays['description']['visibility'] = FALSE;
   }
 }
+
+/**
+ * Alters bundle settings before they are saved.
+ *
+ * @param $settings
+ *   Settings that are about to be saved. See field_bundle_settings() for the
+ *   structure of this array.
+ * @param $context
+ *   An associative array containing:
+ *   - entity_type: The entity type; e.g. 'node' or 'user'.
+ *   - bundle: The bundle name.
+ */
+function hook_field_bundle_settings_alter($settings, $context) {
+  $entity_type = $context['entity_type'];
+  $bundle = $context['bundle'];
+  // When the 'search index' view mode gets set to use custom display settings,
+  // initialize it with the display settings for the 'default' view mode, so
+  // that the way content is indexed does not change until the display settings
+  // are properly adjusted.
+  if ($entity_type == 'node') {
+    $view_mode_settings = field_view_mode_settings($entity_type, $bundle);
+
+    if (!empty($settings['view_modes']['search_index']['custom_settings']) && empty($view_mode_settings['search_index']['custom_settings'])) {
+      // Update display settings for field instances.
+      $instances = field_read_instances(array('entity_type' => $entity_type, 'bundle' => $bundle));
+      foreach ($instances as $instance) {
+        $instance['display']['search_index'] = $instance['display']['default'];
+        field_update_instance($instance);
+      }
+
+      // Update display settings for 'extra fields'.
+      foreach (array_keys($settings['extra_fields']['display']) as $name) {
+        if (!isset($settings['extra_fields']['display'][$name]['search_index'])) {
+          $settings['extra_fields']['display'][$name]['search_index'] = $settings['extra_fields']['display'][$name]['default'];
+        }
+      }
+    }
+  }
+}
+
 /**
  * @} End of "ingroup field_storage"
  */
diff --git modules/field/field.info.inc modules/field/field.info.inc
index a484eec..06b27c9 100644
--- modules/field/field.info.inc
+++ modules/field/field.info.inc
@@ -24,6 +24,8 @@
  * are affected.
  */
 function field_info_cache_clear() {
+  drupal_static_reset('field_view_mode_settings');
+
   // @todo: Remove this when field_attach_*_bundle() bundle management
   // functions are moved to the entity API.
   entity_info_cache_clear();
@@ -273,7 +275,7 @@ function _field_info_prepare_field($field) {
  * Prepares an instance definition for the current run-time context.
  *
  * Since the instance was last saved or updated, a number of things might have
- * changed: widgets or formatters disabled, new settings expected, new build
+ * changed: widgets or formatters disabled, new settings expected, new view
  * modes added...
  *
  * @param $instance
@@ -301,16 +303,21 @@ function _field_info_prepare_instance($instance, $field) {
     $instance['display'][$view_mode] = _field_info_prepare_instance_display($field, $display);
   }
 
-  // Fallback to 'hidden' for unspecified view modes.
+  // Fallback to 'hidden' for view modes configured to use custom display
+  // settings, and for which the instance has no explicit settings.
   $entity_info = entity_get_info($instance['entity_type']);
-  foreach ($entity_info['view modes'] as $view_mode => $info) {
-    if (!isset($instance['display'][$view_mode])) {
-      $instance['display'][$view_mode] = array(
-        'type' => 'hidden',
-        'label' => 'above',
-        'settings' => array(),
-        'weight' => 0,
-      );
+  $view_modes = array_merge(array('default'), array_keys($entity_info['view modes']));;
+  $view_mode_settings = field_view_mode_settings($instance['entity_type'], $instance['bundle']);
+  foreach ($view_modes as $view_mode) {
+    if ($view_mode == 'default' || !empty($view_mode_settings[$view_mode]['custom_settings'])) {
+      if (!isset($instance['display'][$view_mode])) {
+        $instance['display'][$view_mode] = array(
+          'type' => 'hidden',
+          'label' => 'above',
+          'settings' => array(),
+          'weight' => 0,
+        );
+      }
     }
   }
 
diff --git modules/field/field.module modules/field/field.module
index c623be9..1e1d49a 100644
--- modules/field/field.module
+++ modules/field/field.module
@@ -369,7 +369,7 @@ function _field_sort_items_value_helper($a, $b) {
  *       'extra_field_2' => ...
  *     ),
  *   ),
- * ),
+ * );
  * @endcode
  *
  * @param $entity_type
@@ -386,9 +386,15 @@ function field_bundle_settings($entity_type, $bundle, $settings = NULL) {
   $stored_settings = variable_get('field_bundle_settings', array());
 
   if (isset($settings)) {
+    // Let modules alter the display settings.
+    $context = array(
+      'entity_type' => $entity_type,
+      'bundle' => $bundle,
+    );
+    drupal_alter('field_bundle_settings', $settings, $context);
     $stored_settings[$entity_type][$bundle] = $settings;
+
     variable_set('field_bundle_settings', $stored_settings);
-    drupal_static_reset('field_view_mode_settings');
     field_info_cache_clear();
   }
   else {
@@ -397,6 +403,10 @@ function field_bundle_settings($entity_type, $bundle, $settings = NULL) {
       'view_modes' => array(),
       'extra_fields' => array(),
     );
+    $settings['extra_fields'] += array(
+      'form' => array(),
+      'display' => array(),
+    );
 
     return $settings;
   }
diff --git modules/field_ui/field_ui.admin.inc modules/field_ui/field_ui.admin.inc
index fb336d5..714e419 100644
--- modules/field_ui/field_ui.admin.inc
+++ modules/field_ui/field_ui.admin.inc
@@ -1231,19 +1231,23 @@ function field_ui_display_overview_form_submit($form, &$form_state) {
 
   // Save data for 'regular' fields.
   foreach ($form['#fields'] as $field_name) {
-    $instance = field_info_instance($entity_type, $field_name, $bundle);
+    // Retrieve the stored instance settings to merge with the incoming values.
+    $instance = field_read_instance($entity_type, $field_name, $bundle);
     $values = $form_values['fields'][$field_name];
     // Get formatter settings. They lie either directly in submitted form
     // values (if the whole form was submitted while some formatter
     // settings were being edited), or have been persisted in
     // $form_state.
-    $settings = $instance['display'][$view_mode]['settings'];
+    $settings = array();
     if (isset($values['settings_edit_form']['settings'])) {
       $settings = $values['settings_edit_form']['settings'];
     }
     elseif (isset($form_state['formatter_settings'][$field_name])) {
       $settings = $form_state['formatter_settings'][$field_name];
     }
+    elseif (isset($instance['display'][$view_mode]['settings'])) {
+      $settings = $instance['display'][$view_mode]['settings'];
+    }
 
     // Only save settings actually used by the selected formatter.
     $default_settings = field_info_formatter_settings($values['type']);
@@ -1275,10 +1279,14 @@ function field_ui_display_overview_form_submit($form, &$form_state) {
     foreach ($form_values['view_modes_custom'] as $view_mode_name => $value) {
       // Display a message for each view mode newly configured to use custom
       // settings.
-      if (!empty($value) && empty($bundle_settings['view_modes'][$view_mode_name]['custom_settings'])) {
+      $view_mode_settings = field_view_mode_settings($entity_type, $bundle);
+      if (!empty($value) && empty($view_mode_settings[$view_mode_name]['custom_settings'])) {
         $view_mode_label = $entity_info['view modes'][$view_mode_name]['label'];
         $path = _field_ui_bundle_admin_path($entity_type, $bundle) . "/display/$view_mode_name";
         drupal_set_message(t('The %view_mode mode now uses custom display settings. You might want to <a href="@url">configure them</a>.', array('%view_mode' => $view_mode_label, '@url' => url($path))));
+        // Initialize the newly customized view mode with the display settings
+        // from the default view mode.
+        _field_ui_add_default_view_mode_settings($entity_type, $bundle, $view_mode_name, $bundle_settings);
       }
       $bundle_settings['view_modes'][$view_mode_name]['custom_settings'] = !empty($value);
     }
@@ -1291,6 +1299,50 @@ function field_ui_display_overview_form_submit($form, &$form_state) {
 }
 
 /**
+ * Helper function for field_ui_display_overview_form_submit().
+ *
+ * When an administrator decides to use custom display settings for a view mode,
+ * that view mode needs to be initialized with the display settings for the
+ * 'default' view mode, which it was previously using. This helper function
+ * adds the new custom display settings to this bundle's instances, and saves
+ * them. It also modifies the passed-in $settings array, which the caller can
+ * then save using field_bundle_settings().
+ *
+ * @see field_bundle_settings()
+ *
+ * @param $entity_type
+ *   The bundle's entity type.
+ * @param $bundle
+ *   The bundle whose view mode is being customized.
+ * @param $view_mode
+ *   The view mode that the administrator has set to use custom settings.
+ * @param $settings
+ *   An associative array of bundle settings, as expected by
+ *   field_bundle_settings().
+ */
+function _field_ui_add_default_view_mode_settings($entity_type, $bundle, $view_mode, &$settings) {
+  // Update display settings for field instances.
+  $instances = field_read_instances(array('entity_type' => $entity_type, 'bundle' => $bundle));
+  foreach ($instances as $instance) {
+    // If this field instance has display settings defined for this view mode,
+    // respect those settings.
+    if (!isset($instance['display'][$view_mode])) {
+      // The instance doesn't specify anything for this view mode, so use the
+      // default display settings.
+      $instance['display'][$view_mode] = $instance['display']['default'];
+      field_update_instance($instance);
+    }
+  }
+
+  // Update display settings for 'extra fields'.
+  foreach (array_keys($settings['extra_fields']['display']) as $name) {
+    if (!isset($settings['extra_fields']['display'][$name][$view_mode])) {
+      $settings['extra_fields']['display'][$name][$view_mode] = $settings['extra_fields']['display'][$name]['default'];
+    }
+  }
+}
+
+/**
  * Return an array of field_type options.
  */
 function field_ui_field_type_options() {
@@ -1501,17 +1553,24 @@ function field_ui_field_settings_form_submit($form, &$form_state) {
  * Menu callback; select a widget for the field.
  */
 function field_ui_widget_type_form($form, &$form_state, $instance) {
+  drupal_set_title($instance['label']);
+
   $bundle = $instance['bundle'];
   $entity_type = $instance['entity_type'];
-  $field = field_info_field($instance['field_name']);
-
-  drupal_set_title($instance['label']);
+  $field_name = $instance['field_name'];
 
+  $field = field_info_field($field_name);
   $field_type = field_info_field_types($field['type']);
   $widget_type = field_info_widget_types($instance['widget']['type']);
   $bundles = field_info_bundles();
   $bundle_label = $bundles[$entity_type][$bundle]['label'];
 
+  $form = array(
+    '#bundle' => $bundle,
+    '#entity_type' => $entity_type,
+    '#field_name' => $field_name,
+  );
+
   $form['basic'] = array(
     '#type' => 'fieldset',
     '#title' => t('Change widget'),
@@ -1525,7 +1584,6 @@ function field_ui_widget_type_form($form, &$form_state, $instance) {
     '#description' => t('The type of form element you would like to present to the user when creating this field in the %type type.', array('%type' => $bundle_label)),
   );
 
-  $form['#instance'] = $instance;
   $form['actions'] = array('#type' => 'actions');
   $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Continue'));
 
@@ -1540,9 +1598,12 @@ function field_ui_widget_type_form($form, &$form_state, $instance) {
  */
 function field_ui_widget_type_form_submit($form, &$form_state) {
   $form_values = $form_state['values'];
-  $instance = $form['#instance'];
-  $bundle = $instance['bundle'];
-  $entity_type = $instance['entity_type'];
+  $bundle = $form['#bundle'];
+  $entity_type = $form['#entity_type'];
+  $field_name = $form['#field_name'];
+
+  // Retrieve the stored instance settings to merge with the incoming values.
+  $instance = field_read_instance($entity_type, $field_name, $bundle);
 
   // Set the right module information.
   $widget_type = field_info_widget_types($form_values['widget_type']);
@@ -1550,6 +1611,7 @@ function field_ui_widget_type_form_submit($form, &$form_state) {
 
   $instance['widget']['type'] = $form_values['widget_type'];
   $instance['widget']['module'] = $widget_module;
+
   try {
     field_update_instance($instance);
     drupal_set_message(t('Changed the widget for field %label.', array('%label' => $instance['label'])));
@@ -1876,8 +1938,8 @@ function field_ui_field_edit_form_submit($form, &$form_state) {
   field_default_submit(NULL, NULL, $field, $instance, LANGUAGE_NONE, $items, $form, $form_state);
   $instance['default_value'] = $items ? $items : NULL;
 
-  // Update the instance settings.
-  $instance_source = field_info_instance($instance['entity_type'], $instance['field_name'], $instance['bundle']);
+  // Retrieve the stored instance settings to merge with the incoming values.
+  $instance_source = field_read_instance($instance['entity_type'], $instance['field_name'], $instance['bundle']);
   $instance = array_merge($instance_source, $instance);
   field_update_instance($instance);
 
diff --git modules/field_ui/field_ui.test modules/field_ui/field_ui.test
index 715fce4..7b2282b 100644
--- modules/field_ui/field_ui.test
+++ modules/field_ui/field_ui.test
@@ -7,19 +7,13 @@
  */
 
 /**
- * Field UI tests.
+ * Helper class for Field UI test classes.
  */
 class FieldUITestCase extends DrupalWebTestCase {
-    public static function getInfo() {
-    return array(
-      'name' => 'Field UI tests',
-      'description' => 'Test the field UI functionality.',
-      'group' => 'Field UI',
-    );
-  }
 
-  function setUp() {
-    parent::setUp('field_test');
+  function setUp($modules = array()) {
+    array_unshift($modules, 'field_test');
+    parent::setUp($modules);
 
     // Create test user.
     $admin_user = $this->drupalCreateUser(array('access content', 'administer content types', 'administer taxonomy'));
@@ -31,6 +25,119 @@ class FieldUITestCase extends DrupalWebTestCase {
     $this->type = $type->type;
     // Store a valid URL name, with hyphens instead of underscores.
     $this->hyphen_type = str_replace('_', '-', $this->type);
+  }
+
+  /**
+   * Create a new field through the Field UI.
+   *
+   * @param $bundle_path
+   *   Path of the 'Manage fields' page for the bundle.
+   * @param $initial_edit
+   *   $edit parameter for drupalPost() on the first step ('Manage fields'
+   *   screen).
+   * @param $field_edit
+   *   $edit parameter for drupalPost() on the first step ('Field settings'
+   *   form).
+   * @param $instance_edit
+   *   $edit parameter for drupalPost() on the second step ('Instance settings'
+   *   form).
+   */
+  function fieldUIAddNewField($bundle_path, $initial_edit, $field_edit = array(), $instance_edit = array()) {
+    // Use 'test_field' field type by default.
+    $initial_edit += array(
+      'fields[_add_new_field][type]' => 'test_field',
+      'fields[_add_new_field][widget_type]' => 'test_field_widget',
+    );
+    $label = $initial_edit['fields[_add_new_field][label]'];
+    $field_name = $initial_edit['fields[_add_new_field][field_name]'];
+
+    // First step : 'Add new field' on the 'Manage fields' page.
+    $this->drupalPost("$bundle_path/fields",  $initial_edit, t('Save'));
+    $this->assertRaw(t('These settings apply to the %label field everywhere it is used.', array('%label' => $label)), t('Field settings page was displayed.'));
+
+    // Second step : 'Field settings' form.
+    $this->drupalPost(NULL, $field_edit, t('Save field settings'));
+    $this->assertRaw(t('Updated field %label field settings.', array('%label' => $label)), t('Redirected to instance and widget settings page.'));
+
+    // Third step : 'Instance settings' form.
+    $this->drupalPost(NULL, $instance_edit, t('Save settings'));
+    $this->assertRaw(t('Saved %label configuration.', array('%label' => $label)), t('Redirected to "Manage fields" page.'));
+
+    // Check that the field appears in the overview form.
+    $this->assertFieldByXPath('//table[@id="field-overview"]//td[1]', $label, t('Field was created and appears in the overview page.'));
+  }
+
+  /**
+   * Add an existing field through the Field UI.
+   *
+   * @param $bundle_path
+   *   Path of the 'Manage fields' page for the bundle.
+   * @param $initial_edit
+   *   $edit parameter for drupalPost() on the first step ('Manage fields'
+   *   screen).
+   * @param $instance_edit
+   *   $edit parameter for drupalPost() on the second step ('Instance settings'
+   *   form).
+   */
+  function fieldUIAddExistingField($bundle_path, $initial_edit, $instance_edit = array()) {
+    // Use 'test_field_widget' by default.
+    $initial_edit += array(
+      'fields[_add_existing_field][widget_type]' => 'test_field_widget',
+    );
+    $label = $initial_edit['fields[_add_existing_field][label]'];
+    $field_name = $initial_edit['fields[_add_existing_field][field_name]'];
+
+    // First step : 'Add existing field' on the 'Manage fields' page.
+    $this->drupalPost("$bundle_path/fields", $initial_edit, t('Save'));
+
+    // Second step : 'Instance settings' form.
+    $this->drupalPost(NULL, $instance_edit, t('Save settings'));
+    $this->assertRaw(t('Saved %label configuration.', array('%label' => $label)), t('Redirected to "Manage fields" page.'));
+
+    // Check that the field appears in the overview form.
+    $this->assertFieldByXPath('//table[@id="field-overview"]//td[1]', $label, t('Field was created and appears in the overview page.'));
+  }
+
+  /**
+   * Delete a field instance through the Field UI.
+   *
+   * @param $bundle_path
+   *   Path of the 'Manage fields' page for the bundle.
+   * @param $field_name
+   *   The name of the field.
+   * @param $label
+   *   The label of the field.
+   * @param $bundle_label
+   *   The label of the bundle.
+   */
+  function fieldUIDeleteField($bundle_path, $field_name, $label, $bundle_label) {
+    // Display confirmation form.
+    $this->drupalGet("$bundle_path/fields/$field_name/delete");
+    $this->assertRaw(t('Are you sure you want to delete the field %label', array('%label' => $label)), t('Delete confirmation was found.'));
+
+    // Submit confirmation form.
+    $this->drupalPost(NULL, array(), t('Delete'));
+    $this->assertRaw(t('The field %label has been deleted from the %type content type.', array('%label' => $label, '%type' => $bundle_label)), t('Delete message was found.'));
+
+    // Check that the field doesn not appear in the overview form
+    $this->assertNoFieldByXPath('//table[@id="field-overview"]//span[@class="label-field"]', $label, t('Field does not appear in the overview page.'));
+  }
+}
+
+/**
+ * Field UI tests for the 'Manage fields' screen.
+ */
+class FieldUIManageFieldsTestCase extends FieldUITestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Manage fields',
+      'description' => 'Test the Field UI "Manage fields" screen.',
+      'group' => 'Field UI',
+    );
+  }
+
+  function setUp() {
+    parent::setUp();
 
     // Create random field name.
     $this->field_label = $this->randomName(8);
@@ -298,103 +405,177 @@ class FieldUITestCase extends DrupalWebTestCase {
     $this->drupalGet($bundle_path);
     $this->assertFalse($this->xpath('//select[@id="edit-add-existing-field-field-name"]//option[@value=:field_name]', array(':field_name' => $field_name)), t("The 'add existing field' select respects field types 'no_ui' property."));
   }
+}
 
-  /**
-   * Create a new field through the Field UI.
-   *
-   * @param $bundle_path
-   *   Path of the 'Manage fields' page for the bundle.
-   * @param $initial_edit
-   *   $edit parameter for drupalPost() on the first step ('Manage fields'
-   *   screen).
-   * @param $field_edit
-   *   $edit parameter for drupalPost() on the first step ('Field settings'
-   *   form).
-   * @param $instance_edit
-   *   $edit parameter for drupalPost() on the second step ('Instance settings'
-   *   form).
-   */
-  function fieldUIAddNewField($bundle_path, $initial_edit, $field_edit = array(), $instance_edit = array()) {
-    // Use 'test_field' field type by default.
-    $initial_edit += array(
-      'fields[_add_new_field][type]' => 'test_field',
-      'fields[_add_new_field][widget_type]' => 'test_field_widget',
+/**
+ * Field UI tests for the 'Manage display' screens.
+ */
+class FieldUIManageDisplayTestCase extends FieldUITestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Manage display',
+      'description' => 'Test the Field UI "Manage display" screens.',
+      'group' => 'Field UI',
     );
-    $label = $initial_edit['fields[_add_new_field][label]'];
-    $field_name = $initial_edit['fields[_add_new_field][field_name]'];
+  }
 
-    // First step : 'Add new field' on the 'Manage fields' page.
-    $this->drupalPost("$bundle_path/fields",  $initial_edit, t('Save'));
-    $this->assertRaw(t('These settings apply to the %label field everywhere it is used.', array('%label' => $label)), t('Field settings page was displayed.'));
+  function setUp() {
+    parent::setUp(array('search'));
+  }
 
-    // Second step : 'Field settings' form.
-    $this->drupalPost(NULL, $field_edit, t('Save field settings'));
-    $this->assertRaw(t('Updated field %label field settings.', array('%label' => $label)), t('Redirected to instance and widget settings page.'));
+  /**
+   * Test switching view modes to use custom or 'default' settings'.
+   */
+  function testViewModeCustom() {
+    // Create a field, and a node with some data for the field.
+    $edit = array(
+      'fields[_add_new_field][label]' => 'Test field',
+      'fields[_add_new_field][field_name]' => 'field_test',
+    );
+    $this->fieldUIAddNewField('admin/structure/types/manage/' . $this->hyphen_type, $edit);
+    $value = rand(1, 100);
+    $settings = array(
+      'type' => $this->type,
+      'field_test' => array(LANGUAGE_NONE => array(array('value' => $value))),
+    );
+    $node = $this->drupalCreateNode($settings);
 
-    // Assert the field settings are correct.
-    $this->assertFieldSettings($this->type, $this->field_name);
+    // Gather expected output values with the various formatters.
+    $formatters = field_info_formatter_types();
+    $output = array(
+      'field_test_default' => $formatters['field_test_default']['settings']['test_formatter_setting'] . '|' . $value,
+      'field_test_with_prepare_view' => $formatters['field_test_with_prepare_view']['settings']['test_formatter_setting_additional'] . '|' . $value. '|' . ($value + 1),
+    );
 
-    // Third step : 'Instance settings' form.
-    $this->drupalPost(NULL, $instance_edit, t('Save settings'));
-    $this->assertRaw(t('Saved %label configuration.', array('%label' => $label)), t('Redirected to "Manage fields" page.'));
+    // Check that the field is displayed with the default formatter in 'rss'
+    // mode (uses 'default'), and hidden in 'teaser' mode (uses custom settings).
+    $this->assertNodeViewText($node, 'rss', $output['field_test_default'], t("The field is displayed as expected in view modes that use 'default' settings."));
+    $this->assertNodeViewNoText($node, 'teaser', $value, t("The field is hidden in view modes that use custom settings."));
 
-    // Check that the field appears in the overview form.
-    $this->assertFieldByXPath('//table[@id="field-overview"]//td[1]', $label, t('Field was created and appears in the overview page.'));
+    // 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',
+    );
+    $this->drupalPost('admin/structure/types/manage/' . $this->hyphen_type . '/display', $edit, t('Save'));
+    $this->assertNodeViewText($node, 'rss', $output['field_test_with_prepare_view'], t("The field is displayed as expected in view modes that use 'default' settings."));
+
+    foreach (array('rss', 'search_index') as $view_mode) {
+      // Specialize the view mode, check that the field is displayed the same.
+      $edit = array(
+        "view_modes_custom[$view_mode]" => TRUE,
+      );
+      $this->drupalPost('admin/structure/types/manage/' . $this->hyphen_type . '/display', $edit, t('Save'));
+      $this->assertNodeViewText($node, $view_mode, $output['field_test_with_prepare_view'], t("The field is displayed as expected in newly specialized '@view_mode' mode.", array('@view_mode' => $view_mode)));
+
+      // Set the field to 'hidden' in the view mode, check that the field is
+      // hidden.
+      $edit = array(
+        'fields[field_test][type]' => 'hidden',
+      );
+      $this->drupalPost('admin/structure/types/manage/' . $this->hyphen_type . '/display/' . $view_mode, $edit, t('Save'));
+      $this->assertNodeViewNoText($node, $view_mode, $value, t("The field is hidden in '@view_mode' mode.", array('@view_mode' => $view_mode)));
+
+      // Set the view mode back to 'default', check that the field is displayed
+      // accordingly.
+      $edit = array(
+        "view_modes_custom[$view_mode]" => FALSE,
+      );
+      $this->drupalPost('admin/structure/types/manage/' . $this->hyphen_type . '/display', $edit, t('Save'));
+      $this->assertNodeViewText($node, $view_mode, $output['field_test_with_prepare_view'], t("The field is displayed as expected in view modes that use 'default' settings."));
+
+      // Specialize the view mode again..
+      $edit = array(
+        "view_modes_custom[$view_mode]" => TRUE,
+      );
+      $this->drupalPost('admin/structure/types/manage/' . $this->hyphen_type . '/display', $edit, t('Save'));
+      if ($view_mode == 'rss') {
+        // Check that the previous settings for the view mode have been kept.
+        $this->assertNodeViewNoText($node, $view_mode, $value, t("The previous settings are kept when '@view_mode' mode is specialized again.", array('@view_mode' => $view_mode)));
+      }
+      else {
+        // Special case: the 'search_index' mode should be fully reinitiliazed
+        // from 'default' each time it gets specialized.
+        $this->assertNodeViewText($node, $view_mode, $output['field_test_with_prepare_view'], t("The '@view_mode' mode fully reinitiallized when it is specialized again.", array('@view_mode' => $view_mode)));
+      }
+    }
   }
 
   /**
-   * Add an existing field through the Field UI.
+   * Pass if the text is found in the rendered node in a given view mode.
    *
-   * @param $bundle_path
-   *   Path of the 'Manage fields' page for the bundle.
-   * @param $initial_edit
-   *   $edit parameter for drupalPost() on the first step ('Manage fields'
-   *   screen).
-   * @param $instance_edit
-   *   $edit parameter for drupalPost() on the second step ('Instance settings'
-   *   form).
+   * @param $node
+   *   The node.
+   * @param $view_mode
+   *   The view mode in which the node should be displayed.
+   * @param $text
+   *   Plain text to look for.
+   * @param $message
+   *   Message to display
+   *
+   * @return
+   *   TRUE on pass, FALSE on fail.
    */
-  function fieldUIAddExistingField($bundle_path, $initial_edit, $instance_edit = array()) {
-    // Use 'test_field_widget' by default.
-    $initial_edit += array(
-      'fields[_add_existing_field][widget_type]' => 'test_field_widget',
-    );
-    $label = $initial_edit['fields[_add_existing_field][label]'];
-    $field_name = $initial_edit['fields[_add_existing_field][field_name]'];
-
-    // First step : 'Add existing field' on the 'Manage fields' page.
-    $this->drupalPost("$bundle_path/fields", $initial_edit, t('Save'));
-
-    // Second step : 'Instance settings' form.
-    $this->drupalPost(NULL, $instance_edit, t('Save settings'));
-    $this->assertRaw(t('Saved %label configuration.', array('%label' => $label)), t('Redirected to "Manage fields" page.'));
+  function assertNodeViewText($node, $view_mode, $text, $message) {
+    return $this->assertNodeViewTextHelper($node, $view_mode, $text, $message, FALSE);
+  }
 
-    // Check that the field appears in the overview form.
-    $this->assertFieldByXPath('//table[@id="field-overview"]//td[1]', $label, t('Field was created and appears in the overview page.'));
+  /**
+   * Pass if the text is node found in the rendered node in a given view mode.
+   *
+   * @param $node
+   *   The node.
+   * @param $view_mode
+   *   The view mode in which the node should be displayed.
+   * @param $text
+   *   Plain text to look for.
+   * @param $message
+   *   Message to display
+   * @return
+   *   TRUE on pass, FALSE on fail.
+   */
+  function assertNodeViewNoText($node, $view_mode, $text, $message) {
+    return $this->assertNodeViewTextHelper($node, $view_mode, $text, $message, TRUE);
   }
 
   /**
-   * Delete a field instance through the Field UI.
+   * Helper for assertNodeViewText and assertNodeViewNoText.
    *
-   * @param $bundle_path
-   *   Path of the 'Manage fields' page for the bundle.
-   * @param $field_name
-   *   The name of the field.
-   * @param $label
-   *   The label of the field.
-   * @param $bundle_label
-   *   The label of the bundle.
+   * @param $node
+   *   The node.
+   * @param $view_mode
+   *   The view mode in which the node should be displayed.
+   * @param $text
+   *   Plain text to look for.
+   * @param $message
+   *   Message to display
+   * @param $not_exists
+   *   TRUE if this text should not exist, FALSE if it should.
+   *
+   * @return
+   *   TRUE on pass, FALSE on fail.
    */
-  function fieldUIDeleteField($bundle_path, $field_name, $label, $bundle_label) {
-    // Display confirmation form.
-    $this->drupalGet("$bundle_path/fields/$field_name/delete");
-    $this->assertRaw(t('Are you sure you want to delete the field %label', array('%label' => $label)), t('Delete confirmation was found.'));
+  function assertNodeViewTextHelper($node, $view_mode, $text, $message, $not_exists) {
+    // Make sure caches on the tester side are refreshed after changes
+    // submitted on the tested side.
+    field_info_cache_clear();
 
-    // Submit confirmation form.
-    $this->drupalPost(NULL, array(), t('Delete'));
-    $this->assertRaw(t('The field %label has been deleted from the %type content type.', array('%label' => $label, '%type' => $bundle_label)), t('Delete message was found.'));
+    // Save current content so that we can restore it when we're done.
+    $old_content = $this->drupalGetContent();
 
-    // Check that the field doesn not appear in the overview form
-    $this->assertNoFieldByXPath('//table[@id="field-overview"]//span[@class="label-field"]', $label, t('Field does not appear in the overview page.'));
+    // Render a cloned node, so that we do not alter the original.
+    $clone = clone $node;
+    $output = drupal_render(node_view($clone, $view_mode));
+    $this->verbose(t('Rendered node - view mode: @view_mode', array('@view_mode' => $view_mode)) . '<hr />'. $output);
+
+    // Assign content so that DrupalWebTestCase functions can be used.
+    $this->drupalSetContent($output);
+    $method = ($not_exists ? 'assertNoText' : 'assertText');
+    $return = $this->{$method}((string) $text, $message);
+
+    // Restore previous content.
+    $this->drupalSetContent($old_content);
+
+    return $return;
   }
 }
diff --git modules/node/node.module modules/node/node.module
index b12b91b..19cf8f1 100644
--- modules/node/node.module
+++ modules/node/node.module
@@ -243,6 +243,37 @@ function node_field_display_node_alter(&$display, $context) {
 }
 
 /**
+ * Implements hook_field_bundle_settings_alter().
+ */
+function node_field_bundle_settings_alter(&$settings, $context) {
+  $entity_type = $context['entity_type'];
+  $bundle = $context['bundle'];
+  // When the 'search index' view mode gets set to use custom display settings,
+  // initialize it with the display settings for the 'default' view mode, so
+  // that the way content is indexed does not change until the display settings
+  // are properly adjusted.
+  if ($entity_type == 'node') {
+    $view_mode_settings = field_view_mode_settings($entity_type, $bundle);
+
+    if (!empty($settings['view_modes']['search_index']['custom_settings']) && empty($view_mode_settings['search_index']['custom_settings'])) {
+      // Update display settings for field instances.
+      $instances = field_read_instances(array('entity_type' => $entity_type, 'bundle' => $bundle));
+      foreach ($instances as $instance) {
+        $instance['display']['search_index'] = $instance['display']['default'];
+        field_update_instance($instance);
+      }
+
+      // Update display settings for 'extra fields'.
+      foreach (array_keys($settings['extra_fields']['display']) as $name) {
+        if (!isset($settings['extra_fields']['display'][$name]['search_index'])) {
+          $settings['extra_fields']['display'][$name]['search_index'] = $settings['extra_fields']['display'][$name]['default'];
+        }
+      }
+    }
+  }
+}
+
+/**
  * Entity uri callback.
  */
 function node_uri($node) {
