diff --git a/core/modules/field/src/Entity/FieldStorageConfig.php b/core/modules/field/src/Entity/FieldStorageConfig.php
index 9ae0fc4..911b866 100644
--- a/core/modules/field/src/Entity/FieldStorageConfig.php
+++ b/core/modules/field/src/Entity/FieldStorageConfig.php
@@ -179,7 +179,7 @@ class FieldStorageConfig extends ConfigEntityBase implements FieldStorageConfigI
    *
    * @var bool
    */
-  public $deleted = FALSE;
+  protected $deleted = FALSE;
 
   /**
    * The field schema.
@@ -238,7 +238,7 @@ public function __construct(array $values, $entity_type = 'field_storage_config'
    * {@inheritdoc}
    */
   public function id() {
-    return $this->entity_type . '.' . $this->field_name;
+    return $this->getTargetEntityTypeId() . '.' . $this->getName();
   }
 
   /**
@@ -288,30 +288,36 @@ protected function preSaveNew(EntityStorageInterface $storage) {
     // Field name cannot be longer than FieldStorageConfig::NAME_MAX_LENGTH characters.
     // We use Unicode::strlen() because the DB layer assumes that column widths
     // are given in characters rather than bytes.
-    if (Unicode::strlen($this->field_name) > static::NAME_MAX_LENGTH) {
+    if (Unicode::strlen($this->getName()) > static::NAME_MAX_LENGTH) {
       throw new FieldException(String::format(
         'Attempt to create a field storage with an name longer than @max characters: %name', array(
           '@max' => static::NAME_MAX_LENGTH,
-          '%name' => $this->field_name,
+          '%name' => $this->getName(),
         )
       ));
     }
 
     // Disallow reserved field names.
-    $disallowed_field_names = array_keys($entity_manager->getBaseFieldDefinitions($this->entity_type));
-    if (in_array($this->field_name, $disallowed_field_names)) {
-      throw new FieldException(String::format('Attempt to create field storage %name which is reserved by entity type %type.', array('%name' => $this->field_name, '%type' => $this->entity_type)));
+    $disallowed_field_names = array_keys($entity_manager->getBaseFieldDefinitions($this->getTargetEntityTypeId()));
+      if (in_array($this->getName(), $disallowed_field_names)) {
+      throw new FieldException(String::format('Attempt to create field storage %name which is reserved by entity type %type.', array('%name' => $this->getName(), '%type' => $this->getTargetEntityTypeId())));
     }
 
     // Check that the field type is known.
-    $field_type = $field_type_manager->getDefinition($this->type, FALSE);
+    $field_type = $field_type_manager->getDefinition($this->getType(), FALSE);
     if (!$field_type) {
-      throw new FieldException(String::format('Attempt to create a field storage of unknown type %type.', array('%type' => $this->type)));
+      throw new FieldException(String::format('Attempt to create a field storage of unknown type %type.', array('%type' => $this->getType())));
     }
     $this->module = $field_type['provider'];
 
+    // 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_manager->getDefaultStorageSettings($this->getType());
+
     // Notify the entity manager.
     $entity_manager->onFieldStorageDefinitionCreate($this);
+    // @todo Or this? (taken from patch at https://www.drupal.org/node/2030633#comment-9015925)
+    // $entity_manager->getStorage($this->getTargetEntityTypeId())->onFieldStorageDefinitionCreate($this);
   }
 
   /**
@@ -320,7 +326,7 @@ protected function preSaveNew(EntityStorageInterface $storage) {
   public function calculateDependencies() {
     parent::calculateDependencies();
     // Ensure the field is dependent on the providing module.
-    $this->addDependency('module', $this->module);
+    $this->addDependency('module', $this->getModule());
     // Ensure the field is dependent on the provider of the entity type.
     $entity_type = \Drupal::entityManager()->getDefinition($this->entity_type);
     $this->addDependency('module', $entity_type->getProvider());
@@ -338,10 +344,10 @@ protected function preSaveUpdated(EntityStorageInterface $storage) {
     $entity_manager = \Drupal::entityManager();
 
     // Some updates are always disallowed.
-    if ($this->type != $this->original->type) {
+    if ($this->getType() != $this->original->getType()) {
       throw new FieldException("Cannot change the field type for an existing field storage.");
     }
-    if ($this->entity_type != $this->original->entity_type) {
+    if ($this->getTargetEntityTypeId() != $this->original->getTargetEntityTypeId()) {
       throw new FieldException("Cannot change the entity type for an existing field storage.");
     }
 
@@ -353,6 +359,8 @@ protected function preSaveUpdated(EntityStorageInterface $storage) {
     // update as invalid by raising an exception, which stops execution before
     // the definition is written to config.
     $entity_manager->onFieldStorageDefinitionUpdate($this, $this->original);
+    // @todo Or this? (taken from patch at https://www.drupal.org/node/2030633#comment-9015925)
+    // $entity_manager->getStorage($this->getTargetEntityTypeId())->onFieldStorageDefinitionUpdate($this, $this->original);
   }
 
   /**
@@ -481,10 +489,11 @@ public function getColumns() {
    * {@inheritdoc}
    */
   public function getBundles() {
-    if (empty($this->deleted)) {
+    $deleted = $this->isDeleted();
+    if (empty($deleted)) {
       $map = \Drupal::entityManager()->getFieldMap();
-      if (isset($map[$this->entity_type][$this->field_name]['bundles'])) {
-        return $map[$this->entity_type][$this->field_name]['bundles'];
+      if (isset($map[$this->getTargetEntityTypeId()][$this->getName()]['bundles'])) {
+        return $map[$this->getTargetEntityTypeId()][$this->getName()]['bundles'];
       }
     }
     return array();
@@ -497,6 +506,33 @@ public function getName() {
     return $this->field_name;
   }
 
+  public function setIndexes(array $indexes) {
+    $this->set('indexes', $indexes);
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setDeleted($deleted) {
+    $this->set('deleted', $deleted);
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isDeleted() {
+    return $this->deleted;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getModule() {
+    return $this->module;
+  }
+
   /**
    * {@inheritdoc}
    */
@@ -514,7 +550,7 @@ public function getSettings() {
     //   within $this.
     $field_type_manager = \Drupal::service('plugin.manager.field.field_type');
 
-    $settings = $field_type_manager->getDefaultStorageSettings($this->type);
+    $settings = $field_type_manager->getDefaultStorageSettings($this->getType());
     return $this->settings + $settings;
   }
 
@@ -540,6 +576,22 @@ public function getSetting($setting_name) {
   /**
    * {@inheritdoc}
    */
+  public function setSetting($setting_name, $value) {
+    $this->settings[$setting_name] = $value;
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setSettings($settings) {
+    $this->set('settings', $settings);
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function isTranslatable() {
     return $this->translatable;
   }
@@ -591,6 +643,14 @@ public function getCardinality() {
   /**
    * {@inheritdoc}
    */
+  public function setCardinality($cardinality) {
+    $this->set('cardinality', $cardinality);
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function isRequired() {
     return FALSE;
   }
@@ -626,6 +686,14 @@ public function isLocked() {
   /**
    * {@inheritdoc}
    */
+  public function setLocked($locked) {
+    $this->set('locked', $locked);
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function getTargetEntityTypeId() {
     return $this->entity_type;
   }
diff --git a/core/modules/field/src/FieldStorageConfigInterface.php b/core/modules/field/src/FieldStorageConfigInterface.php
index de0406b..321a51b 100644
--- a/core/modules/field/src/FieldStorageConfigInterface.php
+++ b/core/modules/field/src/FieldStorageConfigInterface.php
@@ -39,4 +39,92 @@ public function isLocked();
    */
   public function isDeletable();
 
+  /**
+   * Sets the locked flag.
+   *
+   * @param bool $locked
+   *   Sets value of locked flag.
+   *
+   * @return $this
+   */
+  public function setLocked($locked);
+
+  /**
+   * Returns whether the field is deleted or not.
+   *
+   * @return bool
+   *   The deleted property.
+   */
+  public function isDeleted();
+
+  /**
+   * Sets the field config deleted property.
+   *
+   * @param bool $deleted
+   *   The field config deleted property.
+   *
+   * @return $this
+   */
+  public function setDeleted($deleted);
+
+  /**
+   * Sets the maximum number of items allowed for the field.
+   *
+   * @param int $cardinality
+   *   The cardinality value.
+   *
+   * @return $this
+   */
+  public function setCardinality($cardinality);
+
+  /**
+   * Sets the field config indexes.
+   *
+   * @param array $indexes
+   *   The field config indexes.
+   *
+   * @return $this
+   */
+  public function setIndexes(array $indexes);
+
+  /**
+   * Sets the value for a field setting by name.
+   *
+   * @param string $setting_name
+   *   The name of the setting.
+   * @param mixed $value
+   *   The value of the setting.
+   *
+   * @return $this
+   */
+  public function setSetting($setting_name, $value);
+
+  /**
+   * Sets field settings by overwriting the settings array.
+   *
+   * @param string $settings
+   *   The array of field settings.
+   *
+   * @return $this
+   */
+  public function setSettings($settings);
+
+  /**
+   * Returns the name of the module providing the field type.
+   *
+   * @return string
+   *   The name of the module that provides the field type.
+   */
+  public function getModule();
+
+  /**
+   * Sets whether the field is translatable.
+   *
+   * @param bool $translatable
+   *   Whether the field is translatable.
+   *
+   * @return $this
+   */
+  public function setTranslatable($translatable);
+
 }
