diff --git a/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/Field.php b/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/Field.php
index e7e9bd5..544acdd 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/Field.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/Field.php
@@ -262,122 +262,169 @@ public function getExportProperties() {
   }
 
   /**
-   * {@inheritdoc}
+   * Overrides \Drupal\Core\Entity\Entity::save().
+   *
+   * @return
+   *   Either SAVED_NEW or SAVED_UPDATED, depending on the operation performed.
+   *
+   * @throws \Drupal\field\FieldException
+   *   If the field definition is invalid.
+   *
+   * @throws \Drupal\Core\Entity\EntityStorageException
+   *   In case of failures at the configuration storage level.
    */
   public function save() {
-    $module_handler = \Drupal::moduleHandler();
-    $storage_controller = \Drupal::entityManager()->getStorageController($this->entityType);
-
     // Clear the derived data about the field.
     unset($this->schema, $this->storageDetails);
 
     if ($this->isNew()) {
-      // Field name cannot be longer than Field::ID_MAX_LENGTH characters. We
-      // use drupal_strlen() because the DB layer assumes that column widths
-      // are given in characters rather than bytes.
-      if (drupal_strlen($this->id) > static::ID_MAX_LENGTH) {
-        throw new FieldException(format_string(
-          'Attempt to create a field with an ID longer than @max characters: %id', array(
-            '@max' => static::ID_MAX_LENGTH,
-            '%id' => $this->id,
-          )
-        ));
-      }
+      return $this->saveNew();
+    }
+    else {
+      return $this->saveUpdated();
+    }
+  }
 
-      // Ensure the field name is unique (we do not care about deleted fields).
-      if ($prior_field = current($storage_controller->load(array($this->id)))) {
-        $message = $prior_field->active ?
-          'Attempt to create field name %id which already exists and is active.' :
-          'Attempt to create field name %id which already exists, although it is inactive.';
-        throw new FieldException(format_string($message, array('%id' => $this->id)));
-      }
+  /**
+   * Saves a new field definition.
+   *
+   * @return
+   *   SAVED_NEW if the definition was saved.
+   *
+   * @throws \Drupal\field\FieldException
+   *   If the field definition is invalid.
+   *
+   * @throws \Drupal\Core\Entity\EntityStorageException
+   *   In case of failures at the configuration storage level.
+   */
+  protected function saveNew() {
+    $module_handler = \Drupal::moduleHandler();
+    $entity_manager = \Drupal::entityManager();
+    $storage_controller = $entity_manager->getStorageController($this->entityType);
+
+    // Field name cannot be longer than Field::ID_MAX_LENGTH characters. We
+    // use drupal_strlen() because the DB layer assumes that column widths
+    // are given in characters rather than bytes.
+    if (drupal_strlen($this->id) > static::ID_MAX_LENGTH) {
+      throw new FieldException(format_string(
+        'Attempt to create a field with an ID longer than @max characters: %id', array(
+          '@max' => static::ID_MAX_LENGTH,
+          '%id' => $this->id,
+        )
+      ));
+    }
 
-      // Disallow reserved field names. This can't prevent all field name
-      // collisions with existing entity properties, but some is better than
-      // none.
-      foreach (\Drupal::entityManager()->getDefinitions() as $type => $info) {
-        if (in_array($this->id, $info['entity_keys'])) {
-          throw new FieldException(format_string('Attempt to create field %id which is reserved by entity type %type.', array('%id' => $this->id, '%type' => $type)));
-        }
-      }
+    // Ensure the field name is unique (we do not care about deleted fields).
+    if ($prior_field = current($storage_controller->load(array($this->id)))) {
+      $message = $prior_field->active ?
+        'Attempt to create field name %id which already exists and is active.' :
+        'Attempt to create field name %id which already exists, although it is inactive.';
+      throw new FieldException(format_string($message, array('%id' => $this->id)));
+    }
 
-      // Check that the field type is known.
-      $field_type = field_info_field_types($this->type);
-      if (!$field_type) {
-        throw new FieldException(format_string('Attempt to create a field of unknown type %type.', array('%type' => $this->type)));
+    // Disallow reserved field names. This can't prevent all field name
+    // collisions with existing entity properties, but some is better than
+    // none.
+    foreach ($entity_manager->getDefinitions() as $type => $info) {
+      if (in_array($this->id, $info['entity_keys'])) {
+        throw new FieldException(format_string('Attempt to create field %id which is reserved by entity type %type.', array('%id' => $this->id, '%type' => $type)));
       }
-      $this->module = $field_type['module'];
-      $this->active = TRUE;
-
-      // Make sure all settings are present, so that a complete field
-      // definition is passed to the various hooks and written to config.
-      $this->settings += $field_type['settings'];
-
-      // Provide default storage.
-      $this->storage += array(
-        'type' => config('field.settings')->get('default_storage'),
-        'settings' => array(),
-      );
-      // Check that the storage type is known.
-      $storage_type = field_info_storage_types($this->storage['type']);
-      if (!$storage_type) {
-        throw new FieldException(format_string('Attempt to create a field with unknown storage type %type.', array('%type' => $this->storage['type'])));
-      }
-      $this->storage['module'] = $storage_type['module'];
-      $this->storage['active'] = TRUE;
-      // Provide default storage settings.
-      $this->storage['settings'] += $storage_type['settings'];
+    }
 
-      // Invoke the storage backend's hook_field_storage_create_field().
-      $module_handler->invoke($this->storage['module'], 'field_storage_create_field', array($this));
+    // Check that the field type is known.
+    $field_type = field_info_field_types($this->type);
+    if (!$field_type) {
+      throw new FieldException(format_string('Attempt to create a field of unknown type %type.', array('%type' => $this->type)));
+    }
+    $this->module = $field_type['module'];
+    $this->active = TRUE;
 
-      $hook = 'field_create_field';
-      $hook_args = array($this);
+    // Make sure all settings are present, so that a complete field
+    // definition is passed to the various hooks and written to config.
+    $this->settings += $field_type['settings'];
+
+    // Provide default storage.
+    $this->storage += array(
+      'type' => variable_get('field_storage_default', 'field_sql_storage'),
+      'settings' => array(),
+    );
+    // Check that the storage type is known.
+    $storage_type = field_info_storage_types($this->storage['type']);
+    if (!$storage_type) {
+      throw new FieldException(format_string('Attempt to create a field with unknown storage type %type.', array('%type' => $this->storage['type'])));
     }
-    // Otherwise, the field is being updated.
-    else {
-      $original = $storage_controller->loadUnchanged($this->id());
+    $this->storage['module'] = $storage_type['module'];
+    $this->storage['active'] = TRUE;
+    // Provide default storage settings.
+    $this->storage['settings'] += $storage_type['settings'];
 
-      // Some updates are always disallowed.
-      if ($this->type != $original->type) {
-        throw new FieldException("Cannot change an existing field's type.");
-      }
-      if ($this->entity_types != $original->entity_types) {
-        throw new FieldException("Cannot change an existing field's entity_types property.");
-      }
-      if ($this->storage['type'] != $original->storage['type']) {
-        throw new FieldException("Cannot change an existing field's storage type.");
-      }
+    // Invoke the storage backend's hook_field_storage_create_field().
+    $module_handler->invoke($this->storage['module'], 'field_storage_create_field', array($this));
 
-      // Make sure all settings are present, so that a complete field
-      // definition is saved. This allows calling code to perform partial
-      // updates on a field object.
-      $this->settings += $original->settings;
+    // Save the configuration.
+    $result = parent::save();
+    field_cache_clear();
 
-      $has_data = field_has_data($this);
+    // Invoke hook_field_create_field() after the cache is cleared for API
+    // consistency.
+    $module_handler->invokeAll('field_create_field', array($this));
 
-      // See if any module forbids the update by throwing an exception. This
-      // invokes hook_field_update_forbid().
-      $module_handler->invokeAll('field_update_forbid', array($this, $original, $has_data));
+    return $result;
+  }
 
-      // Tell the storage engine to update the field by invoking the
-      // hook_field_storage_update_field(). The storage engine can reject the
-      // definition update as invalid by raising an exception, which stops
-      // execution before the definition is written to config.
-      $module_handler->invoke($this->storage['module'], 'field_storage_update_field', array($this, $original, $has_data));
+  /**
+   * Saves an updated field definition.
+   *
+   * @return
+   *   SAVED_UPDATED if the definition was saved.
+   *
+   * @throws \Drupal\field\FieldException
+   *   If the field definition is invalid.
+   *
+   * @throws \Drupal\Core\Entity\EntityStorageException
+   *   In case of failures at the configuration storage level.
+   */
+  protected function saveUpdated() {
+    $module_handler = \Drupal::moduleHandler();
+    $storage_controller = \Drupal::entityManager()->getStorageController($this->entityType);
+
+    $original = $storage_controller->loadUnchanged($this->id());
 
-      $hook = 'field_update_field';
-      $hook_args = array($this, $original, $has_data);
+    // Some updates are always disallowed.
+    if ($this->type != $original->type) {
+      throw new FieldException("Cannot change an existing field's type.");
     }
+    if ($this->entity_types != $original->entity_types) {
+      throw new FieldException("Cannot change an existing field's entity_types property.");
+    }
+    if ($this->storage['type'] != $original->storage['type']) {
+      throw new FieldException("Cannot change an existing field's storage type.");
+    }
+
+    // Make sure all settings are present, so that a complete field
+    // definition is saved. This allows calling code to perform partial
+    // updates on a field object.
+    $this->settings += $original->settings;
+
+    $has_data = field_has_data($this);
+
+    // See if any module forbids the update by throwing an exception. This
+    // invokes hook_field_update_forbid().
+    $module_handler->invokeAll('field_update_forbid', array($this, $original, $has_data));
+
+    // Tell the storage engine to update the field by invoking the
+    // hook_field_storage_update_field(). The storage engine can reject the
+    // definition update as invalid by raising an exception, which stops
+    // execution before the definition is written to config.
+    $module_handler->invoke($this->storage['module'], 'field_storage_update_field', array($this, $original, $has_data));
 
     // Save the configuration.
     $result = parent::save();
     field_cache_clear();
 
-    // Invoke external hooks after the cache is cleared for API consistency.
-    // This invokes either hook_field_create_field() or
-    // hook_field_update_field() depending on whether the field is new.
-    $module_handler->invokeAll($hook, $hook_args);
+    // Invoke hook_field_update_field() after the cache is cleared for API
+    // consistency.
+    $module_handler->invokeAll('field_update_field', array($this, $original, $has_data));
 
     return $result;
   }
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/FieldInstance.php b/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/FieldInstance.php
index 53132ec..e12bc57 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/FieldInstance.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/FieldInstance.php
@@ -317,51 +317,121 @@ public function getExportProperties() {
   }
 
   /**
-   * {@inheritdoc}
+   * Overrides \Drupal\Core\Entity\Entity::save().
+   *
+   * @return
+   *   Either SAVED_NEW or SAVED_UPDATED, depending on the operation performed.
+   *
+   * @throws \Drupal\field\FieldException
+   *   If the field instance definition is invalid.
+   *
+   * @throws \Drupal\Core\Entity\EntityStorageException
+   *   In case of failures at the configuration storage level.
    */
   public function save() {
-    $module_handler = \Drupal::moduleHandler();
-    $entity_manager = \Drupal::entityManager();
-    $instance_controller = $entity_manager->getStorageController($this->entityType);
-
     if ($this->isNew()) {
-      // Check that the field can be attached to this entity type.
-      if (!empty($this->field->entity_types) && !in_array($this->entity_type, $this->field->entity_types)) {
-        throw new FieldException(format_string('Attempt to create an instance of field @field_id on forbidden entity type @entity_type.', array('@field_id' => $this->field->id, '@entity_type' => $this->entity_type)));
-      }
+      return $this->saveNew();
+    }
+    else {
+      return $this->saveUpdated();
+    }
+  }
 
-      // Assign the ID.
-      $this->id = $this->id();
+  /**
+   * Saves a new field instance definition.
+   *
+   * @return
+   *   SAVED_NEW if the definition was saved.
+   *
+   * @throws \Drupal\field\FieldException
+   *   If the field instance definition is invalid.
+   *
+   * @throws \Drupal\Core\Entity\EntityStorageException
+   *   In case of failures at the configuration storage level.
+   */
+  protected function saveNew() {
+    $module_handler = \Drupal::moduleHandler();
+    $instance_controller = \Drupal::entityManager()->getStorageController($this->entityType);
 
-      // Ensure the field instance is unique within the bundle.
-      if ($prior_instance = current($instance_controller->load(array($this->id)))) {
-        throw new FieldException(format_string('Attempt to create an instance of field @field_id on bundle @bundle that already has an instance of that field.', array('@field_id' => $this->field->id, '@bundle' => $this->bundle)));
-      }
+    // Check that the field can be attached to this entity type.
+    if (!empty($this->field->entity_types) && !in_array($this->entity_type, $this->field->entity_types)) {
+      throw new FieldException(format_string('Attempt to create an instance of field @field_id on forbidden entity type @entity_type.', array('@field_id' => $this->field->id, '@entity_type' => $this->entity_type)));
+    }
+
+    // Assign the ID.
+    $this->id = $this->id();
 
-      $hook = 'field_create_instance';
-      $hook_args = array($this);
+    // Ensure the field instance is unique within the bundle.
+    if ($prior_instance = current($instance_controller->load(array($this->id)))) {
+      throw new FieldException(format_string('Attempt to create an instance of field @field_id on bundle @bundle that already has an instance of that field.', array('@field_id' => $this->field->id, '@bundle' => $this->bundle)));
     }
-    // Otherwise, the field instance is being updated.
-    else {
-      $original = \Drupal::service('plugin.manager.entity')
-        ->getStorageController($this->entityType)
-        ->loadUnchanged($this->getOriginalID());
 
-      // Some updates are always disallowed.
-      if ($this->entity_type != $original->entity_type) {
-        throw new FieldException("Cannot change an existing instance's entity_type.");
-      }
-      if ($this->bundle != $original->bundle && empty($this->bundle_rename_allowed)) {
-        throw new FieldException("Cannot change an existing instance's bundle.");
-      }
-      if ($this->field_uuid != $original->field_uuid) {
-        throw new FieldException("Cannot change an existing instance's field.");
-      }
+    // Set the field UUID.
+    $this->field_uuid = $this->field->uuid;
+
+    // Ensure default values are present.
+    $this->prepareSave();
+
+    // Save the configuration.
+    $result = parent::save();
+    field_cache_clear();
+
+    // Invoke hook_field_create_instance() after the cache is cleared for API
+    // consistency.
+    $module_handler->invokeAll('field_create_instance', array($this));
+
+    return $result;
+  }
+
+  /**
+   * Saves an updated field instance definition.
+   *
+   * @return
+   *   SAVED_UPDATED if the definition was saved.
+   *
+   * @throws \Drupal\field\FieldException
+   *   If the field instance definition is invalid.
+   *
+   * @throws \Drupal\Core\Entity\EntityStorageException
+   *   In case of failures at the configuration storage level.
+   */
+  protected function saveUpdated() {
+    $module_handler = \Drupal::moduleHandler();
+    $instance_controller = \Drupal::entityManager()->getStorageController($this->entityType);
+
+    $original = $instance_controller->loadUnchanged($this->getOriginalID());
 
-      $hook = 'field_update_instance';
-      $hook_args = array($this, $original);
+    // Some updates are always disallowed.
+    if ($this->entity_type != $original->entity_type) {
+      throw new FieldException("Cannot change an existing instance's entity_type.");
+    }
+    if ($this->bundle != $original->bundle && empty($this->bundle_rename_allowed)) {
+      throw new FieldException("Cannot change an existing instance's bundle.");
+    }
+    if ($this->field_uuid != $original->field_uuid) {
+      throw new FieldException("Cannot change an existing instance's field.");
     }
 
+    // Ensure default values are present.
+    $this->prepareSave();
+
+    // Save the configuration.
+    $result = parent::save();
+    field_cache_clear();
+
+    // Invoke hook_field_update_instance() after the cache is cleared for API
+    // consistency.
+    $module_handler->invokeAll('field_update_instance', array($this, $original));
+
+    return $result;
+  }
+
+  /**
+   * Prepares the instance definition for saving.
+   */
+  protected function prepareSave() {
+    $widget_manager = \Drupal::service('plugin.manager.field.widget');
+
     $field_type_info = field_info_field_types($this->field->type);
 
     // Set the default instance settings.
@@ -373,7 +443,7 @@ public function save() {
       'settings' => array(),
     );
     // Get the widget module and settings from the widget type.
-    if ($widget_type_info = \Drupal::service('plugin.manager.field.widget')->getDefinition($this->widget['type'])) {
+    if ($widget_type_info = $widget_manager->getDefinition($this->widget['type'])) {
       $this->widget['module'] = $widget_type_info['module'];
       $this->widget['settings'] += $widget_type_info['settings'];
     }
@@ -382,17 +452,6 @@ public function save() {
       $max_weight = field_info_max_weight($this->entity_type, $this->bundle, 'form');
       $this->widget['weight'] = isset($max_weight) ? $max_weight + 1 : 0;
     }
-
-    // Save the configuration.
-    $result = parent::save();
-    field_cache_clear();
-
-    // Invoke external hooks after the cache is cleared for API consistency.
-    // This invokes hook_field_create_instance() or hook_field_update_instance()
-    // depending on whether the field is new.
-    $module_handler->invokeAll($hook, $hook_args);
-
-    return $result;
   }
 
   /**
