diff --git a/core/lib/Drupal/Core/Field/ConfigEntityReferenceItemBase.php b/core/lib/Drupal/Core/Field/ConfigEntityReferenceItemBase.php
deleted file mode 100644
index 4d8fbf904be1568cfb427a5b46d81b01bfe27f22..0000000000000000000000000000000000000000
--- a/core/lib/Drupal/Core/Field/ConfigEntityReferenceItemBase.php
+++ /dev/null
@@ -1,63 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Field\ConfigEntityReferenceItemBase.
- */
-
-namespace Drupal\Core\Field;
-
-use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
-
-/**
- * A common base class for configurable entity reference fields.
- *
- * Extends the Core 'entity_reference' entity field item with common methods
- * used in general configurable entity reference field.
- */
-class ConfigEntityReferenceItemBase extends EntityReferenceItem {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isEmpty() {
-    // Avoid loading the entity by first checking the 'target_id'.
-    $target_id = $this->target_id;
-    if (!empty($target_id)) {
-      return FALSE;
-    }
-    // Allow auto-create entities.
-    if (empty($target_id) && ($entity = $this->get('entity')->getValue()) && $entity->isNew()) {
-      return FALSE;
-    }
-    return TRUE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getValue() {
-    $values = parent::getValue();
-
-    // If there is an unsaved entity, return it as part of the field item values
-    // to ensure idempotency of getValue() / setValue().
-    if (empty($this->target_id) && !empty($this->entity)) {
-      $values['entity'] = $this->entity;
-    }
-    return $values;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function preSave() {
-    $entity = $this->get('entity')->getValue();
-    $target_id = $this->get('target_id')->getValue();
-
-    if (!$target_id && !empty($entity) && $entity->isNew()) {
-      $entity->save();
-      $this->set('target_id', $entity->id());
-    }
-  }
-
-}
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php
index 3a776e295db0f4e73318e257a38f8b66fe2db9c6..31a7d8eae1c2bbe238d45d20e9842839778e35ce 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php
@@ -166,6 +166,20 @@ public function setValue($values, $notify = TRUE) {
     }
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getValue($include_computed = FALSE) {
+    $values = parent::getValue($include_computed);
+
+    // If there is an unsaved entity, return it as part of the field item values
+    // to ensure idempotency of getValue() / setValue().
+    if ($this->hasUnsavedEntity()) {
+      $values['entity'] = $this->entity;
+    }
+    return $values;
+  }
+
   /**
    * {@inheritdoc}
    */
@@ -187,4 +201,44 @@ public function getMainPropertyName() {
     return 'target_id';
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function isEmpty() {
+    // Avoid loading the entity by first checking the 'target_id'.
+    $target_id = $this->target_id;
+    if ($target_id !== NULL) {
+      return FALSE;
+    }
+    // Allow auto-create entities.
+    if ($this->hasUnsavedEntity()) {
+      return FALSE;
+    }
+    return TRUE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function preSave() {
+    if ($this->hasUnsavedEntity()) {
+      $this->entity->save();
+      $this->target_id = $this->entity->id();
+    }
+  }
+
+  /**
+   * Determines whether the item holds an unsaved entity.
+   *
+   * This is notably used for "autocreate" widgets, and more generally to
+   * support referencing freshly created entities (they will get saved
+   * automatically as the hosting entity gets saved).
+   *
+   * @return bool
+   *   TRUE if the item holds an unsaved entity.
+   */
+  public function hasUnsavedEntity() {
+    return $this->target_id === NULL && ($entity = $this->entity) && $entity->isNew();
+  }
+
 }
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/ConfigurableEntityReferenceItem.php b/core/modules/entity_reference/lib/Drupal/entity_reference/ConfigurableEntityReferenceItem.php
index 73cee86ed7b0576f19c0fc220c1a564f3c5a1c18..c350955b2c1d41d5af798ab3ac295a54128463f1 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/ConfigurableEntityReferenceItem.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/ConfigurableEntityReferenceItem.php
@@ -8,12 +8,12 @@
 namespace Drupal\entity_reference;
 
 use Drupal\Component\Utility\String;
+use Drupal\Core\Field\ConfigFieldItemInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\TypedData\AllowedValuesInterface;
 use Drupal\Core\TypedData\DataDefinition;
-use Drupal\Core\Field\FieldDefinitionInterface;
-use Drupal\Core\Field\ConfigEntityReferenceItemBase;
-use Drupal\Core\Field\ConfigFieldItemInterface;
 use Drupal\Core\Validation\Plugin\Validation\Constraint\AllowedValuesConstraint;
 
 /**
@@ -26,9 +26,8 @@
  *  - target_type: The entity type to reference.
  *
  * @see entity_reference_field_info_alter().
- *
  */
-class ConfigurableEntityReferenceItem extends ConfigEntityReferenceItemBase implements ConfigFieldItemInterface, AllowedValuesInterface {
+class ConfigurableEntityReferenceItem extends EntityReferenceItem implements ConfigFieldItemInterface, AllowedValuesInterface {
 
   /**
    * {@inheritdoc}
@@ -48,7 +47,7 @@ public function getPossibleOptions(AccountInterface $account = NULL) {
    * {@inheritdoc}
    */
   public function getSettableValues(AccountInterface $account = NULL) {
-    // Flatten options firstly, because Settable Options may contain group
+    // Flatten options first, because "settable options" may contain group
     // arrays.
     $flatten_options = \Drupal::formBuilder()->flattenOptions($this->getSettableOptions($account));
     return array_keys($flatten_options);
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldWidget/AutocompleteTagsWidget.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldWidget/AutocompleteTagsWidget.php
index 9c41b2ae9738c6893e5b4c9458a040b83cf51719..2367fa10e25cbc0662ce2bb88e2a94de39074f19 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldWidget/AutocompleteTagsWidget.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldWidget/AutocompleteTagsWidget.php
@@ -7,8 +7,6 @@
 
 namespace Drupal\entity_reference\Plugin\Field\FieldWidget;
 
-use Drupal\entity_reference\Plugin\Field\FieldWidget\AutocompleteWidgetBase;
-
 /**
  * Plugin implementation of the 'entity_reference autocomplete-tags' widget.
  *
@@ -64,9 +62,10 @@ public function elementValidate($element, &$form_state, $form) {
           $value[] = array('target_id' => $match);
         }
         elseif ($auto_create && (count($this->getSelectionHandlerSetting('target_bundles')) == 1 || count($bundles) == 1)) {
-          // Auto-create item. see entity_reference_field_presave().
+          // Auto-create item. See
+          // \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem::presave().
           $value[] = array(
-            'target_id' => 0,
+            'target_id' => NULL,
             'entity' => $this->createNewEntity($input, $element['#autocreate_uid']),
           );
         }
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldWidget/AutocompleteWidget.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldWidget/AutocompleteWidget.php
index f0719fec3797adba5dc98f110116dc30815cb411..0898d685de0c54eeb9e53506adc43307283fb629 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldWidget/AutocompleteWidget.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldWidget/AutocompleteWidget.php
@@ -8,7 +8,6 @@
 namespace Drupal\entity_reference\Plugin\Field\FieldWidget;
 
 use Drupal\Core\Field\FieldItemListInterface;
-use Drupal\entity_reference\Plugin\Field\FieldWidget\AutocompleteWidgetBase;
 
 /**
  * Plugin implementation of the 'entity_reference autocomplete' widget.
@@ -54,7 +53,7 @@ public function elementValidate($element, &$form_state, $form) {
     $auto_create = $this->getSelectionHandlerSetting('auto_create');
 
     // If a value was entered into the autocomplete.
-    $value = '';
+    $value = NULL;
     if (!empty($element['#value'])) {
       // Take "label (entity id)', match the id from parenthesis.
       // @todo: Lookup the entity type's ID data type and use it here.
@@ -73,9 +72,10 @@ public function elementValidate($element, &$form_state, $form) {
       }
 
       if (!$value && $auto_create && (count($this->getSelectionHandlerSetting('target_bundles')) == 1)) {
-        // Auto-create item. see entity_reference_field_presave().
+        // Auto-create item. See
+        // \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem::presave().
         $value = array(
-          'target_id' => 0,
+          'target_id' => NULL,
           'entity' => $this->createNewEntity($element['#value'], $element['#autocreate_uid']),
           // Keep the weight property.
           '_weight' => $element['#weight'],
diff --git a/core/modules/file/lib/Drupal/file/Plugin/Field/FieldType/FileItem.php b/core/modules/file/lib/Drupal/file/Plugin/Field/FieldType/FileItem.php
index 9bb9dd0296e7e54b964f3df341b6e8d656aa3c73..886be529608d274bf6fac29dc265ccd1e7e08c1e 100644
--- a/core/modules/file/lib/Drupal/file/Plugin/Field/FieldType/FileItem.php
+++ b/core/modules/file/lib/Drupal/file/Plugin/Field/FieldType/FileItem.php
@@ -196,13 +196,6 @@ public function instanceSettingsForm(array $form, array &$form_state) {
     return $element;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function isEmpty() {
-    return empty($this->target_id);
-  }
-
   /**
    * Form API callback
    *
diff --git a/core/modules/image/image.module b/core/modules/image/image.module
index 1f5d8a504e93ae331bcd64ad8444f4c64fce931a..e5f52ed15817204d4f7b27b0b304cde381a2cb71 100644
--- a/core/modules/image/image.module
+++ b/core/modules/image/image.module
@@ -421,7 +421,7 @@ function image_filter_keyword($value, $current_pixels, $new_pixels) {
  *
  * Transforms default image of image field from array into single value at save.
  */
-function image_entity_presave(EntityInterface $entity, $type) {
+function image_entity_presave(EntityInterface $entity) {
   $field = FALSE;
   if ($entity instanceof FieldInstance) {
     $field = $entity->getField();
diff --git a/core/modules/image/lib/Drupal/image/Plugin/Field/FieldType/ImageItem.php b/core/modules/image/lib/Drupal/image/Plugin/Field/FieldType/ImageItem.php
index be20c66536d3b0c37e3262c958e6ea90c84e97d3..849cec8eb3872ab1c585e35c63b443ac9f6235a7 100644
--- a/core/modules/image/lib/Drupal/image/Plugin/Field/FieldType/ImageItem.php
+++ b/core/modules/image/lib/Drupal/image/Plugin/Field/FieldType/ImageItem.php
@@ -284,6 +284,8 @@ public function instanceSettingsForm(array $form, array &$form_state) {
    * {@inheritdoc}
    */
   public function preSave() {
+    parent::preSave();
+
     $width = $this->width;
     $height = $this->height;
 
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldFormatter/TaxonomyFormatterBase.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldFormatter/TaxonomyFormatterBase.php
index b99024ac110bd50bd606c5f6c83bcbcbaa394a7c..29beaf5b5072d9307c97285364175ee3aa2e9210 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldFormatter/TaxonomyFormatterBase.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldFormatter/TaxonomyFormatterBase.php
@@ -48,7 +48,7 @@ public function prepareView(array $entities_items) {
             $item->entity = $terms[$item->target_id];
           }
           // Terms to be created are not in $terms, but are still legitimate.
-          elseif ($item->target_id === NULL && isset($item->entity)) {
+          elseif ($item->hasUnsavedEntity()) {
             // Leave the item in place.
           }
           // Otherwise, unset the instance value, since the term does not exist.
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldType/TaxonomyTermReferenceItem.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldType/TaxonomyTermReferenceItem.php
index 98660eb45e56ab3708e80454a731ce6449ea1ba3..e183e05f601807e59b69179340839b88eaaf0f67 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldType/TaxonomyTermReferenceItem.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldType/TaxonomyTermReferenceItem.php
@@ -7,9 +7,9 @@
 
 namespace Drupal\taxonomy\Plugin\Field\FieldType;
 
-use Drupal\Core\Field\ConfigEntityReferenceItemBase;
 use Drupal\Core\Field\ConfigFieldItemInterface;
 use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\TypedData\AllowedValuesInterface;
 
@@ -35,7 +35,7 @@
  *   list_class = "\Drupal\taxonomy\Plugin\Field\FieldType\TaxonomyTermReferenceFieldItemList"
  * )
  */
-class TaxonomyTermReferenceItem extends ConfigEntityReferenceItemBase implements ConfigFieldItemInterface, AllowedValuesInterface {
+class TaxonomyTermReferenceItem extends EntityReferenceItem implements ConfigFieldItemInterface, AllowedValuesInterface {
 
   /**
    * {@inheritdoc}