diff --git a/src/Plugin/Field/FieldType/DynamicEntityReferenceItem.php b/src/Plugin/Field/FieldType/DynamicEntityReferenceItem.php
index ae014e8..487cf5b 100644
--- a/src/Plugin/Field/FieldType/DynamicEntityReferenceItem.php
+++ b/src/Plugin/Field/FieldType/DynamicEntityReferenceItem.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * @file
  * Contains \Drupal\dynamic_entity_reference\Plugin\Field\FieldType\DynamicEntityReferenceItem.
@@ -39,16 +40,14 @@ class DynamicEntityReferenceItem extends ConfigurableEntityReferenceItem {
     return array(
       'exclude_entity_types' => TRUE,
       'entity_type_ids' => array(),
-    ) + parent::defaultStorageSettings();
+    );
   }
 
   /**
    * {@inheritdoc}
    */
   public static function defaultFieldSettings() {
-    return array(
-      'handler' => 'default',
-    ) + parent::defaultFieldSettings();
+    return array();
   }
 
   /**
@@ -126,7 +125,6 @@ class DynamicEntityReferenceItem extends ConfigurableEntityReferenceItem {
 
   /**
    * {@inheritdoc}
-   * @todo update
    */
   public function storageSettingsForm(array &$form, FormStateInterface $form_state, $has_data) {
     // @todo inject this.
@@ -155,7 +153,26 @@ class DynamicEntityReferenceItem extends ConfigurableEntityReferenceItem {
    * {@inheritdoc}
    */
   public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
-    return array();
+
+    $settings_form = array();
+    $field = $form_state->get('field');
+    $settings = $this->getSettings();
+    $entity_type_ids = $this->getAllEntityTypeIds($settings);
+    foreach (array_keys($entity_type_ids) as $entity_type_id) {
+      $settings += array(
+        $entity_type_id => array(
+          'handler' => 'default',
+          'handler_settings' => array(),
+        ),
+      );
+      // We put the dummy value here so selection plugins can work.
+      $field->settings['target_type'] = $entity_type_id;
+      $field->settings['handler'] = $settings[$entity_type_id]['handler'];
+      $field->settings['handler_settings'] = $settings[$entity_type_id]['handler_settings'];
+      $settings_form[$entity_type_id] = parent::fieldSettingsForm($form, $form_state);
+      $settings_form[$entity_type_id]['handler']['#title'] = t('Reference type for @entity_type_id', array('@entity_type_id' => $entity_type_ids[$entity_type_id]));
+    }
+    return $settings_form;
   }
 
   /**
@@ -165,11 +182,18 @@ class DynamicEntityReferenceItem extends ConfigurableEntityReferenceItem {
    *   The form where the settings form is being included in.
    * @param \Drupal\Core\Form\FormStateInterface $form_state
    *   The form state of the (entire) configuration form.
-   * @todo update
    */
   public static function fieldSettingsFormValidate(array $form, FormStateInterface $form_state) {
     if ($form_state->hasValue('field')) {
-      $form_state->unsetValue(array('field', 'settings', 'handler_submit'));
+      $settings = $form_state->getValue(array('field', 'settings'));
+      foreach (array_keys($settings) as $entity_typ_id) {
+        $form_state->unsetValue(array(
+          'field',
+          'settings',
+          $entity_typ_id,
+          'handler_submit',
+        ));
+      }
       $form_state->get('field')->settings = $form_state->getValue(array('field', 'settings'));
     }
   }
@@ -200,4 +224,40 @@ class DynamicEntityReferenceItem extends ConfigurableEntityReferenceItem {
     return $this->values;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function preSave() {
+    if ($this->hasUnsavedEntity()) {
+      $this->entity->save();
+    }
+    // Handle the case where an unsaved entity was directly set using the public
+    // 'entity' property and then saved before this entity. In this case
+    // ::hasUnsavedEntity() will return FALSE but $this->target_id and
+    // $this->target_type will still be empty.
+    if (empty($this->target_id) && $this->entity) {
+      $this->target_type = $this->entity->getEntityTypeId();
+      $this->target_id = $this->entity->id();
+    }
+  }
+
+  /**
+   * Helper function to get all the entity type ids that can be referenced.
+   *
+   * @return string[]
+   *   All the entity type ids that can be referenced.
+   */
+  protected static function getAllEntityTypeIds($settings) {
+    $labels = \Drupal::entityManager()->getEntityTypeLabels(TRUE);
+    $options = $labels['Content'];
+
+    if ($settings['exclude_entity_types']) {
+      $entity_type_ids = array_diff_key($options, $settings['entity_type_ids'] ?: array());
+    }
+    else {
+      $entity_type_ids = array_intersect_key($options, $settings['entity_type_ids'] ?: array());
+    }
+    return $entity_type_ids;
+  }
+
 }
diff --git a/src/Plugin/Field/FieldWidget/DynamicEntityReferenceWidget.php b/src/Plugin/Field/FieldWidget/DynamicEntityReferenceWidget.php
index 13d5f04..6a3567e 100644
--- a/src/Plugin/Field/FieldWidget/DynamicEntityReferenceWidget.php
+++ b/src/Plugin/Field/FieldWidget/DynamicEntityReferenceWidget.php
@@ -98,8 +98,10 @@ class DynamicEntityReferenceWidget extends AutocompleteWidget {
    * Checks whether a content entity is referenced.
    *
    * @param string $target_type
-   *   The value target entity type
+   *   The value target entity type.
+   *
    * @return bool
+   *   TRUE if a content entity is referenced.
    */
   protected function isContentReferenced($target_type = NULL) {
     $target_type_info = \Drupal::entityManager()->getDefinition($target_type);
@@ -115,10 +117,17 @@ class DynamicEntityReferenceWidget extends AutocompleteWidget {
     if (!empty($element['#value'])) {
       // If this is the default value of the field.
       if ($form_state->hasValue('default_value_input')) {
-        $values = $form_state->getValue(array('default_value_input', $element['#field_name'], $element['#delta']));
+        $values = $form_state->getValue(array(
+          'default_value_input',
+          $element['#field_name'],
+          $element['#delta'],
+        ));
       }
       else {
-        $values = $form_state->getValue(array($element['#field_name'], $element['#delta']));
+        $values = $form_state->getValue(array(
+          $element['#field_name'],
+          $element['#delta'],
+        ));
       }
       // Take "label (entity id)', match the id from parenthesis.
       if ($this->isContentReferenced($values['target_type']) && preg_match("/.+\((\d+)\)/", $element['#value'], $matches)) {
@@ -127,10 +136,27 @@ class DynamicEntityReferenceWidget extends AutocompleteWidget {
       elseif (preg_match("/.+\(([\w.]+)\)/", $element['#value'], $matches)) {
         $value = $matches[1];
       }
-      if (!$value) {
+      $auto_create = $this->getHandlerSetting('auto_create', $values['target_type']);
+      if ($value === NULL) {
         // Try to get a match from the input string when the user didn't use the
         // autocomplete but filled in a value manually.
-        $value = $this->validateAutocompleteInput($values['target_type'], $element['#value'], $element, $form_state, $form);
+        $this->fakeFieldSettings($values['target_type']);
+        /** @var \Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface $handler */
+        $handler = \Drupal::service('plugin.manager.entity_reference.selection')->getSelectionHandler($this->fieldDefinition);
+        $value = $handler->validateAutocompleteInput($element['#value'], $element, $form_state, $form, !$auto_create);
+      }
+      if (!$value && $auto_create && (count($this->getHandlerSetting('target_bundles', $values['target_type'])) == 1)) {
+        // Auto-create item. See
+        // \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem::presave().
+        $value = array(
+          'target_id' => NULL,
+          'entity' => $this->createNewEntity($element['#value'], $element['#autocreate_uid']),
+          // Keep the weight property.
+          '_weight' => $element['#weight'],
+        );
+        // Change the element['#parents'], so in form_set_value() we
+        // populate the correct key.
+        array_pop($element['#parents']);
       }
 
     }
@@ -138,55 +164,32 @@ class DynamicEntityReferenceWidget extends AutocompleteWidget {
   }
 
   /**
-   * {@inheritdoc}
+   * Sets the fake field settings values.
+   *
+   * @param string $entity_type_id
+   *   The id of the entity type.
    */
-  public function validateAutocompleteInput($target_type, $input, &$element, FormStateInterface $form_state, $form) {
-    // @todo Make this a service.
-    $controller = new DynamicEntityReferenceController(\Drupal::service('entity.query'));
-    $bundled_entities = $controller->getReferenceableEntities($target_type, $input, '=', 6);
-    $params = array(
-      '%value' => $input,
-      '@value' => $input,
-    );
-    $entities = array();
-    foreach ($bundled_entities as $entities_list) {
-      $entities += $entities_list;
-    }
-    if (empty($entities)) {
-      // Error if there are no entities available for a required field.
-      $form_state->setError($element, t('There are no entities matching "%value".', $params));
-    }
-    elseif (count($entities) > 5) {
-      $params['@id'] = key($entities);
-      // Error if there are more than 5 matching entities.
-      $form_state->setError($element, t('Many entities are called %value. Specify the one you want by appending the id in parentheses, like "@value (@id)".', $params));
-    }
-    elseif (count($entities) > 1) {
-      // More helpful error if there are only a few matching entities.
-      $multiples = array();
-      foreach ($entities as $id => $name) {
-        $multiples[] = $name . ' (' . $id . ')';
-      }
-      $params['@id'] = $id;
-      $params['%multiple'] = implode('", "', $multiples);
-      $form_state->setError($element, t('Multiple entities match this reference; "%multiple". Specify the one you want by appending the id in parentheses, like "@value (@id)".', $params));
-    }
-    else {
-      // Take the one and only matching entity.
-      return key($entities);
-    }
+  protected function fakeFieldSettings($entity_type_id) {
+    $settings = $this->getFieldSettings();
+    $this->fieldDefinition->settings['target_type'] = $entity_type_id;
+    $this->fieldDefinition->settings['handler'] = $settings[$entity_type_id]['handler'];
+    $this->fieldDefinition->settings['handler_settings'] = $settings[$entity_type_id]['handler_settings'];
   }
 
   /**
-   * {@inheritdoc}
+   * Returns the value of a setting for the entity reference selection handler.
+   *
+   * @param string $setting_name
+   *   The setting name.
+   * @param string $entity_type_id
+   *   The id of the entity type.
+   *
+   * @return mixed
+   *   The setting value.
    */
-  protected function getEntityType(FieldItemListInterface $items, $delta) {
-    // The autocomplete widget outputs one entity label per form element.
-    if (isset($items[$delta])) {
-      return $items[$delta]->target_type;
-    }
-
-    return FALSE;
+  protected function getHandlerSetting($setting_name, $entity_type_id) {
+    $settings = $this->getFieldSettings();
+    return isset($settings[$entity_type_id]['handler_settings'][$setting_name]) ? $settings[$entity_type_id]['handler_settings'][$setting_name] : NULL;
   }
 
 }
