diff --git a/core/modules/comment/src/Form/CommentTypeDeleteForm.php b/core/modules/comment/src/Form/CommentTypeDeleteForm.php
index 7ac7ce7..26d8db3 100644
--- a/core/modules/comment/src/Form/CommentTypeDeleteForm.php
+++ b/core/modules/comment/src/Form/CommentTypeDeleteForm.php
@@ -118,7 +118,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     $caption = '';
     foreach (array_keys($this->commentManager->getFields($entity_type)) as $field_name) {
       /** @var \Drupal\field\FieldStorageConfigInterface $field_storage */
-      if (($field_storage = FieldStorageConfig::loadByName($entity_type, $field_name)) && $field_storage->getSetting('comment_type') == $this->entity->id() && !$field_storage->deleted) {
+      if (($field_storage = FieldStorageConfig::loadByName($entity_type, $field_name)) && $field_storage->getSetting('comment_type') == $this->entity->id() && !$field_storage->isDeleted()) {
         $caption .= '<p>' . $this->t('%label is used by the %field field on your site. You can not remove this comment type until you have removed the field.', array(
           '%label' => $this->entity->label(),
           '%field' => $field_storage->label(),
diff --git a/core/modules/comment/src/Tests/CommentLanguageTest.php b/core/modules/comment/src/Tests/CommentLanguageTest.php
index ab70e7d..1ee8bfe 100644
--- a/core/modules/comment/src/Tests/CommentLanguageTest.php
+++ b/core/modules/comment/src/Tests/CommentLanguageTest.php
@@ -71,7 +71,7 @@ protected function setUp() {
 
     // Make comment body translatable.
     $field_storage = FieldStorageConfig::loadByName('comment', 'comment_body');
-    $field_storage->translatable = TRUE;
+    $field_storage->setTranslatable(TRUE);
     $field_storage->save();
     $this->assertTrue($field_storage->isTranslatable(), 'Comment body is translatable.');
   }
diff --git a/core/modules/comment/src/Tests/CommentTranslationUITest.php b/core/modules/comment/src/Tests/CommentTranslationUITest.php
index 64afbd7..21f14e3 100644
--- a/core/modules/comment/src/Tests/CommentTranslationUITest.php
+++ b/core/modules/comment/src/Tests/CommentTranslationUITest.php
@@ -76,7 +76,7 @@ protected function getTranslatorPermissions() {
   function setupTestFields() {
     parent::setupTestFields();
     $field_storage = FieldStorageConfig::loadByName('comment', 'comment_body');
-    $field_storage->translatable = TRUE;
+    $field_storage->setTranslatable(TRUE);
     $field_storage->save();
   }
 
diff --git a/core/modules/comment/src/Tests/Views/CommentFieldFilterTest.php b/core/modules/comment/src/Tests/Views/CommentFieldFilterTest.php
index a054288..8049d0d 100644
--- a/core/modules/comment/src/Tests/Views/CommentFieldFilterTest.php
+++ b/core/modules/comment/src/Tests/Views/CommentFieldFilterTest.php
@@ -47,7 +47,7 @@ function setUp() {
     // Make the comment body field translatable. The title is already
     // translatable by definition.
     $field_storage = FieldStorageConfig::loadByName('comment', 'comment_body');
-    $field_storage->translatable = TRUE;
+    $field_storage->setTranslatable(TRUE);
     $field_storage->save();
 
     // Set up comment titles.
diff --git a/core/modules/datetime/src/Tests/DateTimeFieldTest.php b/core/modules/datetime/src/Tests/DateTimeFieldTest.php
index 35811bc..92673fe 100644
--- a/core/modules/datetime/src/Tests/DateTimeFieldTest.php
+++ b/core/modules/datetime/src/Tests/DateTimeFieldTest.php
@@ -163,7 +163,7 @@ function testDateField() {
   function testDatetimeField() {
     $field_name = $this->fieldStorage->getName();
     // Change the field to a datetime field.
-    $this->fieldStorage->settings['datetime_type'] = 'datetime';
+    $this->fieldStorage->setSetting('datetime_type', 'datetime');
     $this->fieldStorage->save();
 
     // Display creation form.
@@ -229,7 +229,7 @@ function testDatetimeField() {
   function testDatelistWidget() {
     $field_name = $this->fieldStorage->getName();
     // Change the field to a datetime field.
-    $this->fieldStorage->settings['datetime_type'] = 'datetime';
+    $this->fieldStorage->setSetting('datetime_type', 'datetime');
     $this->fieldStorage->save();
 
     // Change the widget to a datelist widget.
@@ -393,7 +393,7 @@ function testDefaultValue() {
   function testInvalidField() {
 
     // Change the field to a datetime field.
-    $this->fieldStorage->settings['datetime_type'] = 'datetime';
+    $this->fieldStorage->setSetting('datetime_type', 'datetime');
     $this->fieldStorage->save();
     $field_name = $this->fieldStorage->getName();
 
diff --git a/core/modules/editor/src/Tests/QuickEditIntegrationTest.php b/core/modules/editor/src/Tests/QuickEditIntegrationTest.php
index 33077c3..ab48237 100644
--- a/core/modules/editor/src/Tests/QuickEditIntegrationTest.php
+++ b/core/modules/editor/src/Tests/QuickEditIntegrationTest.php
@@ -145,7 +145,7 @@ public function testEditorSelection() {
     $this->assertEqual('editor', $this->getSelectedEditor($entity->id(), $this->fieldName), "With cardinality 1, and the full_html text format, the 'editor' editor is selected.");
 
     // Editor selection with text processing, cardinality >1
-    $this->fields->field_textarea_field_storage->cardinality = 2;
+    $this->fields->field_textarea_field_storage->setCardinality(2);
     $this->fields->field_textarea_field_storage->save();
     $this->assertEqual('form', $this->getSelectedEditor($entity->id(), $this->fieldName), "With cardinality >1, and both items using the full_html text format, the 'form' editor is selected.");
   }
diff --git a/core/modules/entity_reference/entity_reference.module b/core/modules/entity_reference/entity_reference.module
index 6d4280b..ed1e2a3 100644
--- a/core/modules/entity_reference/entity_reference.module
+++ b/core/modules/entity_reference/entity_reference.module
@@ -69,7 +69,7 @@ function entity_reference_field_widget_info_alter(&$info) {
  * Reset the instance handler settings, when the target type is changed.
  */
 function entity_reference_field_storage_config_update(FieldStorageConfigInterface $field_storage) {
-  if ($field_storage->type != 'entity_reference') {
+  if ($field_storage->getType() != 'entity_reference') {
     // Only act on entity reference fields.
     return;
   }
diff --git a/core/modules/entity_reference/src/Tests/EntityReferenceFormatterTest.php b/core/modules/entity_reference/src/Tests/EntityReferenceFormatterTest.php
index 2d7e938..d932062 100644
--- a/core/modules/entity_reference/src/Tests/EntityReferenceFormatterTest.php
+++ b/core/modules/entity_reference/src/Tests/EntityReferenceFormatterTest.php
@@ -232,7 +232,7 @@ public function testLabelFormatter() {
     // \Drupal\Core\Entity\EntityInterface::urlInfo() will throw an exception
     // and the label formatter will output only the label instead of a link.
     $field_storage_config = FieldStorageConfig::loadByName($this->entityType, $this->fieldName);
-    $field_storage_config->settings['target_type'] = 'entity_test_label';
+    $field_storage_config->setSetting('target_type', 'entity_test_label');
     $field_storage_config->save();
 
     $referenced_entity_with_no_link_template = entity_create('entity_test_label', array(
diff --git a/core/modules/field/field.module b/core/modules/field/field.module
index 143e8c5..113acbe 100644
--- a/core/modules/field/field.module
+++ b/core/modules/field/field.module
@@ -135,7 +135,7 @@ function field_system_info_alter(&$info, Extension $file, $type) {
       // remains no actual, non-deleted fields)
       $non_deleted = FALSE;
       foreach ($field_storages as $field_storage) {
-        if (empty($field_storage->deleted)) {
+        if (!$field_storage->isDeleted()) {
           $non_deleted = TRUE;
           break;
         }
diff --git a/core/modules/field/field.purge.inc b/core/modules/field/field.purge.inc
index 73de63f..4af0f4e 100644
--- a/core/modules/field/field.purge.inc
+++ b/core/modules/field/field.purge.inc
@@ -84,7 +84,7 @@ function field_purge_batch($batch_size, $field_storage_uuid = NULL) {
 
   $info = \Drupal::entityManager()->getDefinitions();
   foreach ($fields as $field) {
-    $entity_type = $field->entity_type;
+    $entity_type = $field->getTargetEntityTypeId();
 
     // We cannot purge anything if the entity type is unknown (e.g. the
     // providing module was uninstalled).
@@ -117,7 +117,7 @@ function field_purge_batch($batch_size, $field_storage_uuid = NULL) {
     // We cannot purge anything if the entity type is unknown (e.g. the
     // providing module was uninstalled).
     // @todo Revisit after https://drupal.org/node/2080823.
-    if (!isset($info[$field_storage->entity_type])) {
+    if (!isset($info[$field_storage->getTargetEntityTypeId()])) {
       continue;
     }
 
@@ -170,7 +170,7 @@ function field_purge_field_storage(FieldStorageConfigInterface $field_storage) {
   $state->set('field.storage.deleted', $deleted_storages);
 
   // Notify the storage layer.
-  \Drupal::entityManager()->getStorage($field_storage->entity_type)->finalizePurge($field_storage);
+  \Drupal::entityManager()->getStorage($field_storage->getTargetEntityTypeId())->finalizePurge($field_storage);
 
   // Invoke external hooks after the cache is cleared for API consistency.
   \Drupal::moduleHandler()->invokeAll('field_purge_field_storage', array($field_storage));
diff --git a/core/modules/field/field.views.inc b/core/modules/field/field.views.inc
index cc26366..467065f 100644
--- a/core/modules/field/field.views.inc
+++ b/core/modules/field/field.views.inc
@@ -23,7 +23,7 @@ function field_views_data() {
 
   foreach (\Drupal::entityManager()->getStorage('field_storage_config')->loadMultiple() as $field_storage) {
     if (_field_views_get_entity_type_storage($field_storage)) {
-      $result = (array) $module_handler->invoke($field_storage->module, 'field_views_data', array($field_storage));
+      $result = (array) $module_handler->invoke($field_storage->getModule(), 'field_views_data', array($field_storage));
       if (empty($result)) {
         $result = field_views_field_default_views_data($field_storage);
       }
@@ -49,7 +49,7 @@ function field_views_data() {
 function field_views_data_alter(&$data) {
   foreach (\Drupal::entityManager()->getStorage('field_storage_config')->loadMultiple() as $field_storage) {
     if (_field_views_get_entity_type_storage($field_storage)) {
-      $function = $field_storage->module . '_field_views_data_views_data_alter';
+      $function = $field_storage->getModule() . '_field_views_data_views_data_alter';
       if (function_exists($function)) {
         $function($data, $field_storage);
       }
diff --git a/core/modules/field/src/ConfigImporterFieldPurger.php b/core/modules/field/src/ConfigImporterFieldPurger.php
index 55294b2..63bd3a0 100644
--- a/core/modules/field/src/ConfigImporterFieldPurger.php
+++ b/core/modules/field/src/ConfigImporterFieldPurger.php
@@ -40,7 +40,7 @@ public static function process(array &$context, ConfigImporter $config_importer)
       $context['sandbox']['field']['current_storage_id'] = $field_storage->id();
       // If the storage has not been deleted yet we need to do that. This is the
       // case when the storage deletion is staged.
-      if (!$field_storage->deleted) {
+      if (!$field_storage->isDeleted()) {
         $field_storage->delete();
       }
     }
@@ -140,7 +140,7 @@ public static function getFieldStoragesToPurge(array $extensions, array $deletes
     // Gather deleted fields from modules that are being uninstalled.
     $field_storages = entity_load_multiple_by_properties('field_storage_config', array('deleted' => TRUE, 'include_deleted' => TRUE));
     foreach ($field_storages as $field_storage) {
-      if (!in_array($field_storage->module, $providers)) {
+      if (!in_array($field_storage->getModule(), $providers)) {
         $storages_to_delete[$field_storage->id()] = $field_storage;
       }
     }
diff --git a/core/modules/field/src/Entity/FieldConfig.php b/core/modules/field/src/Entity/FieldConfig.php
index a8d9c0a..8bf5136 100644
--- a/core/modules/field/src/Entity/FieldConfig.php
+++ b/core/modules/field/src/Entity/FieldConfig.php
@@ -141,7 +141,7 @@ public function preSave(EntityStorageInterface $storage) {
     // Filter out unknown settings and make sure all settings are present, so
     // that a complete field definition is passed to the various hooks and
     // written to config.
-    $default_settings = $field_type_manager->getDefaultFieldSettings($storage_definition->type);
+    $default_settings = $field_type_manager->getDefaultFieldSettings($storage_definition->getType());
     $this->settings = array_intersect_key($this->settings, $default_settings) + $default_settings;
 
     if ($this->isNew()) {
diff --git a/core/modules/field/src/Entity/FieldStorageConfig.php b/core/modules/field/src/Entity/FieldStorageConfig.php
index 9ae0fc4..2ed3c24 100644
--- a/core/modules/field/src/Entity/FieldStorageConfig.php
+++ b/core/modules/field/src/Entity/FieldStorageConfig.php
@@ -51,7 +51,7 @@ class FieldStorageConfig extends ConfigEntityBase implements FieldStorageConfigI
    *
    * @var string
    */
-  public $id;
+  protected $id;
 
   /**
    * The field name.
@@ -87,7 +87,7 @@ class FieldStorageConfig extends ConfigEntityBase implements FieldStorageConfigI
    *
    * @var string
    */
-  public $module;
+  protected $module;
 
   /**
    * Field-type specific settings.
@@ -97,7 +97,7 @@ class FieldStorageConfig extends ConfigEntityBase implements FieldStorageConfigI
    *
    * @var array
    */
-  public $settings = array();
+  protected $settings = array();
 
   /**
    * The field cardinality.
@@ -108,7 +108,7 @@ class FieldStorageConfig extends ConfigEntityBase implements FieldStorageConfigI
    *
    * @var int
    */
-  public $cardinality = 1;
+  protected $cardinality = 1;
 
   /**
    * Flag indicating whether the field is translatable.
@@ -117,7 +117,7 @@ class FieldStorageConfig extends ConfigEntityBase implements FieldStorageConfigI
    *
    * @var bool
    */
-  public $translatable = TRUE;
+  protected $translatable = TRUE;
 
   /**
    * Flag indicating whether the field is available for editing.
@@ -131,7 +131,7 @@ class FieldStorageConfig extends ConfigEntityBase implements FieldStorageConfigI
    *
    * @var bool
    */
-  public $locked = FALSE;
+  protected $locked = FALSE;
 
   /**
    * Flag indicating whether the field storage should be deleted when orphaned.
@@ -164,7 +164,7 @@ class FieldStorageConfig extends ConfigEntityBase implements FieldStorageConfigI
    *
    * @var array
    */
-  public $indexes = array();
+  protected $indexes = array();
 
   /**
    * Flag indicating whether the field is deleted.
@@ -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();
@@ -500,6 +509,20 @@ public function getName() {
   /**
    * {@inheritdoc}
    */
+  public function isDeleted() {
+    return $this->deleted;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getModule() {
+    return $this->module;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function getType() {
     return $this->type;
   }
@@ -514,7 +537,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 +563,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 +630,14 @@ public function getCardinality() {
   /**
    * {@inheritdoc}
    */
+  public function setCardinality($cardinality) {
+    $this->set('cardinality', $cardinality);
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function isRequired() {
     return FALSE;
   }
@@ -626,6 +673,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..84a73f3 100644
--- a/core/modules/field/src/FieldStorageConfigInterface.php
+++ b/core/modules/field/src/FieldStorageConfigInterface.php
@@ -39,4 +39,72 @@ 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 maximum number of items allowed for the field.
+   *
+   * @param int $cardinality
+   *   The cardinality value.
+   *
+   * @return $this
+   */
+  public function setCardinality($cardinality);
+
+  /**
+   * 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);
+
 }
diff --git a/core/modules/field/src/FieldStorageConfigStorage.php b/core/modules/field/src/FieldStorageConfigStorage.php
index d865d85..eacf7dc 100644
--- a/core/modules/field/src/FieldStorageConfigStorage.php
+++ b/core/modules/field/src/FieldStorageConfigStorage.php
@@ -135,13 +135,24 @@ public function loadByProperties(array $conditions = array()) {
       foreach ($conditions as $key => $value) {
         // Extract the actual value against which the condition is checked.
         switch ($key) {
-          case 'uuid';
+          case 'uuid':
             $checked_value = $field->uuid();
             break;
 
+          case 'deleted':
+            $checked_value = $field->isDeleted();
+            break;
+
+          case 'module':
+            $checked_value = $field->getModule();
+            break;
+
+          case 'type':
+            $checked_value = $field->getType();
+            break;
+
           default:
             $checked_value = $field->$key;
-            break;
         }
 
         // Skip to the next field as soon as one condition does not match.
diff --git a/core/modules/field/src/Tests/BulkDeleteTest.php b/core/modules/field/src/Tests/BulkDeleteTest.php
index 4ae227b..be306e5 100644
--- a/core/modules/field/src/Tests/BulkDeleteTest.php
+++ b/core/modules/field/src/Tests/BulkDeleteTest.php
@@ -314,7 +314,7 @@ function testPurgeFieldStorage() {
     $this->assertEqual(count($fields), 0, 'The field is purged.');
     // The field storage still exists, not deleted.
     $storages = entity_load_multiple_by_properties('field_storage_config', array('uuid' => $field_storage->uuid(), 'include_deleted' => TRUE));
-    $this->assertTrue(isset($storages[$field_storage->uuid()]) && !$storages[$field_storage->uuid()]->deleted, 'The field storage exists and is not deleted');
+    $this->assertTrue(isset($storages[$field_storage->uuid()]) && !$storages[$field_storage->uuid()]->isDeleted(), 'The field storage exists and is not deleted');
 
     // Delete the second field.
     $bundle = next($this->bundles);
@@ -341,7 +341,7 @@ function testPurgeFieldStorage() {
     $fields = entity_load_multiple_by_properties('field_config', array('uuid' => $field->uuid(), 'include_deleted' => TRUE));
     $this->assertTrue(isset($fields[$field->uuid()]) && $fields[$field->uuid()]->deleted, 'The field exists and is deleted');
     $storages = entity_load_multiple_by_properties('field_storage_config', array('uuid' => $field_storage->uuid(), 'include_deleted' => TRUE));
-    $this->assertTrue(isset($storages[$field_storage->uuid()]) && $storages[$field_storage->uuid()]->deleted, 'The field storage exists and is deleted');
+    $this->assertTrue(isset($storages[$field_storage->uuid()]) && $storages[$field_storage->uuid()]->isDeleted(), 'The field storage exists and is deleted');
 
     // Purge again to purge the field and the storage.
     field_purge_batch(0);
diff --git a/core/modules/field/src/Tests/FieldStorageCrudTest.php b/core/modules/field/src/Tests/FieldStorageCrudTest.php
index 94fb1d2..e4a2b1a 100644
--- a/core/modules/field/src/Tests/FieldStorageCrudTest.php
+++ b/core/modules/field/src/Tests/FieldStorageCrudTest.php
@@ -305,13 +305,13 @@ function testDelete() {
 
     // Test that the first field is not deleted, and then delete it.
     $field_storage = current(entity_load_multiple_by_properties('field_storage_config', array('field_name' => $field_storage_definition['field_name'], 'include_deleted' => TRUE)));
-    $this->assertTrue(!empty($field_storage) && empty($field_storage->deleted), 'A new storage is not marked for deletion.');
+    $this->assertTrue(!empty($field_storage) && !$field_storage->isDeleted(), 'A new storage is not marked for deletion.');
     FieldStorageConfig::loadByName('entity_test', $field_storage_definition['field_name'])->delete();
 
     // Make sure that the field is marked as deleted when it is specifically
     // loaded.
     $field_storage = current(entity_load_multiple_by_properties('field_storage_config', array('field_name' => $field_storage_definition['field_name'], 'include_deleted' => TRUE)));
-    $this->assertTrue(!empty($field_storage->deleted), 'A deleted storage is marked for deletion.');
+    $this->assertTrue($field_storage->isDeleted(), 'A deleted storage is marked for deletion.');
 
     // Make sure that this field is marked as deleted when it is
     // specifically loaded.
@@ -328,7 +328,7 @@ function testDelete() {
 
     // Make sure the other field and its storage are not deleted.
     $another_field_storage = entity_load('field_storage_config', 'entity_test.' . $another_field_storage_definition['field_name']);
-    $this->assertTrue(!empty($another_field_storage) && empty($another_field_storage->deleted), 'A non-deleted storage is not marked for deletion.');
+    $this->assertTrue(!empty($another_field_storage) && !$another_field_storage->isDeleted(), 'A non-deleted storage is not marked for deletion.');
     $another_field = FieldConfig::load('entity_test.' . $another_field_definition['bundle'] . '.' . $another_field_definition['field_name']);
     $this->assertTrue(!empty($another_field) && empty($another_field->deleted), 'A field whose storage was not deleted is not marked for deletion.');
 
@@ -337,7 +337,7 @@ function testDelete() {
     entity_create('field_storage_config', $field_storage_definition)->save();
     entity_create('field_config', $field_definition)->save();
     $field_storage = entity_load('field_storage_config', 'entity_test.' . $field_storage_definition['field_name']);
-    $this->assertTrue(!empty($field_storage) && empty($field_storage->deleted), 'A new storage with a previously used name is created.');
+    $this->assertTrue(!empty($field_storage) && !$field_storage->isDeleted(), 'A new storage with a previously used name is created.');
     $field = FieldConfig::load('entity_test.' . $field_definition['bundle'] . '.' . $field_definition['field_name'] );
     $this->assertTrue(!empty($field) && empty($field->deleted), 'A new field for a previously used field name is created.');
 
@@ -363,7 +363,11 @@ function testUpdateFieldType() {
     $field_storage->save();
 
     try {
-      $field_storage->type = 'integer';
+      // Set the field storage type to 'integer.' Since $type is protected,
+      // we have to use reflection.
+      $ref_field_storage_type = new \ReflectionProperty($field_storage, 'type');
+      $ref_field_storage_type->setAccessible(TRUE);
+      $ref_field_storage_type->setValue($field_storage, 'integer');
       $field_storage->save();
       $this->fail(t('Cannot update a field to a different type.'));
     }
@@ -403,13 +407,13 @@ function testUpdate() {
       }
       // Load back and assert there are $cardinality number of values.
       $entity = $this->entitySaveReload($entity);
-      $this->assertEqual(count($entity->field_update), $field_storage->cardinality);
+      $this->assertEqual(count($entity->field_update), $field_storage->getCardinality());
       // Now check the values themselves.
       for ($delta = 0; $delta < $cardinality; $delta++) {
         $this->assertEqual($entity->field_update[$delta]->value, $delta + 1);
       }
       // Increase $cardinality and set the field cardinality to the new value.
-      $field_storage->cardinality = ++$cardinality;
+      $field_storage->setCardinality(++$cardinality);
       $field_storage->save();
     } while ($cardinality < 6);
   }
@@ -427,7 +431,7 @@ function testUpdateForbid() {
         'unchangeable' => 0
     )));
     $field_storage->save();
-    $field_storage->settings['changeable']++;
+    $field_storage->setSetting('changeable', $field_storage->getSetting('changeable') + 1);
     try {
       $field_storage->save();
       $this->pass(t("A changeable setting can be updated."));
@@ -435,7 +439,7 @@ function testUpdateForbid() {
     catch (FieldStorageDefinitionUpdateForbiddenException $e) {
       $this->fail(t("An unchangeable setting cannot be updated."));
     }
-    $field_storage->settings['unchangeable']++;
+    $field_storage->setSetting('unchangeable', $field_storage->getSetting('unchangeable') + 1);
     try {
       $field_storage->save();
       $this->fail(t("An unchangeable setting can be updated."));
diff --git a/core/modules/field/src/Tests/FieldValidationTest.php b/core/modules/field/src/Tests/FieldValidationTest.php
index 4454c23..f4a4591 100644
--- a/core/modules/field/src/Tests/FieldValidationTest.php
+++ b/core/modules/field/src/Tests/FieldValidationTest.php
@@ -48,7 +48,7 @@ protected function setUp() {
    * Tests that the number of values is validated against the field cardinality.
    */
   function testCardinalityConstraint() {
-    $cardinality = $this->fieldTestData->field_storage->cardinality;
+    $cardinality = $this->fieldTestData->field_storage->getCardinality();
     $entity = $this->entity;
 
     for ($delta = 0; $delta < $cardinality + 1; $delta++) {
diff --git a/core/modules/field/src/Tests/reEnableModuleFieldTest.php b/core/modules/field/src/Tests/reEnableModuleFieldTest.php
index 2b8f4c1..2139f6e 100644
--- a/core/modules/field/src/Tests/reEnableModuleFieldTest.php
+++ b/core/modules/field/src/Tests/reEnableModuleFieldTest.php
@@ -39,6 +39,8 @@ protected function setUp() {
 
   /**
    * Test the behavior of a field module after being disabled and re-enabled.
+   *
+   * @see \field_system_info_alter()
    */
   function testReEnabledField() {
 
diff --git a/core/modules/field_ui/src/FieldConfigListBuilder.php b/core/modules/field_ui/src/FieldConfigListBuilder.php
index ea5170f..3535134 100644
--- a/core/modules/field_ui/src/FieldConfigListBuilder.php
+++ b/core/modules/field_ui/src/FieldConfigListBuilder.php
@@ -149,7 +149,7 @@ public function buildRow(EntityInterface $field_config) {
     // Add the operations.
     $row['data'] = $row['data'] + parent::buildRow($field_config);
 
-    if (!empty($field_storage->locked)) {
+    if ($field_storage->isLocked()) {
       $row['data']['operations'] = array('data' => array('#markup' => $this->t('Locked')));
       $row['class'][] = 'menu-disabled';
     }
diff --git a/core/modules/field_ui/src/FieldStorageConfigListBuilder.php b/core/modules/field_ui/src/FieldStorageConfigListBuilder.php
index a512046..ad99896 100644
--- a/core/modules/field_ui/src/FieldStorageConfigListBuilder.php
+++ b/core/modules/field_ui/src/FieldStorageConfigListBuilder.php
@@ -98,7 +98,7 @@ public function buildHeader() {
    * {@inheritdoc}
    */
   public function buildRow(EntityInterface $field_storage) {
-    if ($field_storage->locked) {
+    if ($field_storage->isLocked()) {
       $row['class'] = array('menu-disabled');
       $row['data']['id'] =  t('@field_name (Locked)', array('@field_name' => $field_storage->field_name));
     }
diff --git a/core/modules/field_ui/src/Form/FieldConfigDeleteForm.php b/core/modules/field_ui/src/Form/FieldConfigDeleteForm.php
index b1ddb05..20080ed 100644
--- a/core/modules/field_ui/src/Form/FieldConfigDeleteForm.php
+++ b/core/modules/field_ui/src/Form/FieldConfigDeleteForm.php
@@ -73,7 +73,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     $bundles = entity_get_bundles();
     $bundle_label = $bundles[$this->entity->entity_type][$this->entity->bundle]['label'];
 
-    if ($field_storage && !$field_storage->locked) {
+    if ($field_storage && !$field_storage->isLocked()) {
       $this->entity->delete();
       drupal_set_message($this->t('The field %field has been deleted from the %type content type.', array('%field' => $this->entity->label(), '%type' => $bundle_label)));
     }
diff --git a/core/modules/field_ui/src/Form/FieldStorageEditForm.php b/core/modules/field_ui/src/Form/FieldStorageEditForm.php
index 5cd57b7..dbe5a1f 100644
--- a/core/modules/field_ui/src/Form/FieldStorageEditForm.php
+++ b/core/modules/field_ui/src/Form/FieldStorageEditForm.php
@@ -150,7 +150,7 @@ public function buildForm(array $form, FormStateInterface $form_state, FieldConf
     // Build the non-configurable field values.
     $form['field_storage']['field_name'] = array('#type' => 'value', '#value' => $field_storage->getName());
     $form['field_storage']['type'] = array('#type' => 'value', '#value' => $field_storage->getType());
-    $form['field_storage']['module'] = array('#type' => 'value', '#value' => $field_storage->module);
+    $form['field_storage']['module'] = array('#type' => 'value', '#value' => $field_storage->getModule());
     $form['field_storage']['translatable'] = array('#type' => 'value', '#value' => $field_storage->isTranslatable());
 
     $form['actions'] = array('#type' => 'actions');
@@ -194,7 +194,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     // Merge incoming form values into the existing field.
     $field_storage = $this->field->getFieldStorageDefinition();
     foreach ($field_values as $key => $value) {
-      $field_storage->{$key} = $value;
+      $field_storage->set($key,$value);
     }
 
     // Update the field.
diff --git a/core/modules/field_ui/src/Tests/ManageFieldsTest.php b/core/modules/field_ui/src/Tests/ManageFieldsTest.php
index 9efd340..912318d8 100644
--- a/core/modules/field_ui/src/Tests/ManageFieldsTest.php
+++ b/core/modules/field_ui/src/Tests/ManageFieldsTest.php
@@ -361,7 +361,7 @@ function testDefaultValue() {
     // Check that the default value can be empty when the field is marked as
     // required and can store unlimited values.
     $field_storage = FieldStorageConfig::loadByName('node', $field_name);
-    $field_storage->cardinality = FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED;
+    $field_storage->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
     $field_storage->save();
 
     $this->drupalGet($admin_path);
diff --git a/core/modules/image/image.module b/core/modules/image/image.module
index f1faacb..02ad43b 100644
--- a/core/modules/image/image.module
+++ b/core/modules/image/image.module
@@ -7,6 +7,7 @@
 
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Routing\RouteMatchInterface;
+use Drupal\field\Entity\FieldConfig;
 use Drupal\file\Entity\File;
 use Drupal\field\FieldStorageConfigInterface;
 use Drupal\field\FieldConfigInterface;
@@ -321,42 +322,45 @@ 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) {
-  $field_storage = FALSE;
-  $entity_type_id = $entity->getEntityTypeId();
-  if ($entity_type_id == 'field_config') {
-    $field_storage = $entity->getFieldStorageDefinition();
-    $default_settings = \Drupal::service('plugin.manager.field.field_type')->getDefaultFieldSettings('image');
-  }
-  elseif ($entity_type_id == 'field_storage_config') {
-    $field_storage = $entity;
-    $default_settings = \Drupal::service('plugin.manager.field.field_type')->getDefaultStorageSettings('image');
+
+  // Get the default image settings, return if not saving an image field storage
+  // or image field entity.
+  if (($entity instanceof FieldStorageConfigInterface || $entity instanceof FieldConfigInterface) && $entity->getType() == 'image') {
+    $default_image = $entity->getSetting('default_image');
   }
-  // Exit, if not saving an image field storage or image field entity.
-  if (!$field_storage || $field_storage->type != 'image') {
+  else {
     return;
   }
 
-  if ($field_storage->isSyncing()) {
+  if ($entity->isSyncing()) {
     return;
   }
 
-  $fid = $entity->settings['default_image']['fid'];
+  $fid = $default_image['fid'];
   if ($fid) {
-    $original_fid = isset($entity->original) ? $entity->original->settings['default_image']['fid'] : NULL;
+    $original_fid = isset($entity->original) ? $entity->original->getSetting('default_image')['fid'] : NULL;
     if ($fid != $original_fid) {
       $file = file_load($fid);
       if ($file) {
         $image = \Drupal::service('image.factory')->get($file->getFileUri());
-        $entity->settings['default_image']['width'] = $image->getWidth();
-        $entity->settings['default_image']['height'] = $image->getHeight();
+        $default_image['width'] = $image->getWidth();
+        $default_image['height'] = $image->getHeight();
       }
       else {
-        $entity->settings['default_image']['fid'] = NULL;
+        $default_image['fid'] = NULL;
       }
     }
   }
 
-  $entity->settings['default_image'] += $default_settings['default_image'];
+  // @todo Simplify this in https://www.drupal.org/node/2030637, when both
+  //   interfaces have a setSetting() method.
+  if ($entity instanceof FieldStorageConfigInterface) {
+    $entity->setSetting('default_image', $default_image);
+  }
+  elseif ($entity instanceof FieldConfig) {
+    $entity->settings['default_image'] = $default_image;
+  }
+
 }
 
 /**
@@ -371,8 +375,8 @@ function image_field_storage_config_update(FieldStorageConfigInterface $field_st
   $prior_field_storage = $field_storage->original;
 
   // The value of a managed_file element can be an array if #extended == TRUE.
-  $fid_new = $field_storage->settings['default_image']['fid'];
-  $fid_old = $prior_field_storage->settings['default_image']['fid'];
+  $fid_new = $field_storage->getSetting('default_image')['fid'];
+  $fid_old = $prior_field_storage->getSetting('default_image')['fid'];
 
   $file_new = $fid_new ? file_load($fid_new) : FALSE;
 
@@ -392,8 +396,8 @@ function image_field_storage_config_update(FieldStorageConfigInterface $field_st
   }
 
   // If the upload destination changed, then move the file.
-  if ($file_new && (file_uri_scheme($file_new->getFileUri()) != $field_storage->settings['uri_scheme'])) {
-    $directory = $field_storage->settings['uri_scheme'] . '://default_images/';
+  if ($file_new && (file_uri_scheme($file_new->getFileUri()) != $field_storage->getSetting('uri_scheme'))) {
+    $directory = $field_storage->getSetting('uri_scheme') . '://default_images/';
     file_prepare_directory($directory, FILE_CREATE_DIRECTORY);
     file_move($file_new, $directory . $file_new->filename);
   }
@@ -411,7 +415,7 @@ function image_field_config_update(FieldConfigInterface $field) {
 
   $prior_instance = $field->original;
 
-  $fid_new = $field->settings['default_image']['fid'];
+  $fid_new = $field->getSetting('default_image')['fid'];
   $fid_old = $prior_instance->settings['default_image']['fid'];
 
   // If the old and new files do not match, update the default accordingly.
@@ -430,8 +434,8 @@ function image_field_config_update(FieldConfigInterface $field) {
   }
 
   // If the upload destination changed, then move the file.
-  if ($file_new && (file_uri_scheme($file_new->getFileUri()) != $field_storage->settings['uri_scheme'])) {
-    $directory = $field_storage->settings['uri_scheme'] . '://default_images/';
+  if ($file_new && (file_uri_scheme($file_new->getFileUri()) != $field_storage->getSetting('uri_scheme'))) {
+    $directory = $field_storage->getSetting('uri_scheme') . '://default_images/';
     file_prepare_directory($directory, FILE_CREATE_DIRECTORY);
     file_move($file_new, $directory . $file_new->filename);
   }
@@ -447,7 +451,7 @@ function image_field_storage_config_delete(FieldStorageConfigInterface $field) {
   }
 
   // The value of a managed_file element can be an array if #extended == TRUE.
-  $fid = $field->settings['default_image']['fid'];
+  $fid = $field->getSettings()['default_image']['fid'];
   if ($fid && ($file = file_load($fid))) {
     \Drupal::service('file.usage')->delete($file, 'image', 'default_image', $field->uuid());
   }
diff --git a/core/modules/image/src/Tests/ImageFieldDefaultImagesTest.php b/core/modules/image/src/Tests/ImageFieldDefaultImagesTest.php
index c5dd44d..09c6328 100644
--- a/core/modules/image/src/Tests/ImageFieldDefaultImagesTest.php
+++ b/core/modules/image/src/Tests/ImageFieldDefaultImagesTest.php
@@ -175,7 +175,9 @@ public function testDefaultImages() {
     );
 
     // Upload a new default for the field storage.
-    $field_storage->settings['default_image']['fid'] = $default_images['field_new']->id();
+    $default_image_settings = $field_storage->getSetting('default_image');
+    $default_image_settings['fid'] = $default_images['field_new']->id();
+    $field_storage->setSetting('default_image', $default_image_settings);
     $field_storage->save();
 
     // Confirm that the new default is used on the article field settings form.
diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateFieldTest.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateFieldTest.php
index 2f1c179..c621630 100644
--- a/core/modules/migrate_drupal/src/Tests/d6/MigrateFieldTest.php
+++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateFieldTest.php
@@ -49,7 +49,7 @@ public function testFields() {
     $expected = array('max_length' => 255);
     $this->assertEqual($field_storage->type, "text",  t('Field type is @fieldtype. It should be text.', array('@fieldtype' => $field_storage->type)));
     $this->assertEqual($field_storage->status(), TRUE, "Status is TRUE");
-    $this->assertEqual($field_storage->settings, $expected, "Field type text settings are correct");
+    $this->assertEqual($field_storage->getSettings(), $expected, "Field type text settings are correct");
 
     // Integer field.
     $field_storage = entity_load('field_storage_config', 'node.field_test_two');
@@ -87,10 +87,10 @@ public function testFields() {
     // Decimal field with radio buttons.
     $field_storage = entity_load('field_storage_config', 'node.field_test_decimal_radio_buttons');
     $this->assertEqual($field_storage->type, "list_float",  t('Field type is @fieldtype. It should be list_float.', array('@fieldtype' => $field_storage->type)));
-    $this->assertNotNull($field_storage->settings['allowed_values']['1.2'], t('First allowed value key is set to 1.2'));
-    $this->assertNotNull($field_storage->settings['allowed_values']['2.1'], t('Second allowed value key is set to 2.1'));
-    $this->assertEqual($field_storage->settings['allowed_values']['1.2'], '1.2', t('First allowed value is set to 1.2'));
-    $this->assertEqual($field_storage->settings['allowed_values']['2.1'], '2.1', t('Second allowed value is set to 1.2'));
+    $this->assertNotNull($field_storage->getSetting('allowed_values')['1.2'], t('First allowed value key is set to 1.2'));
+    $this->assertNotNull($field_storage->getSetting('allowed_values')['2.1'], t('Second allowed value key is set to 2.1'));
+    $this->assertEqual($field_storage->getSetting('allowed_values')['1.2'], '1.2', t('First allowed value is set to 1.2'));
+    $this->assertEqual($field_storage->getSetting('allowed_values')['2.1'], '2.1', t('Second allowed value is set to 1.2'));
 
     // Float field with a single checkbox.
     $field_storage = entity_load('field_storage_config', 'node.field_test_float_single_checkbox');
@@ -99,14 +99,14 @@ public function testFields() {
     // Integer field with a select list.
     $field_storage = entity_load('field_storage_config', 'node.field_test_integer_selectlist');
     $this->assertEqual($field_storage->type, "list_integer",  t('Field type is @fieldtype. It should be list_integer.', array('@fieldtype' => $field_storage->type)));
-    $this->assertNotNull($field_storage->settings['allowed_values']['1234'], t('First allowed value key is set to 1234'));
-    $this->assertNotNull($field_storage->settings['allowed_values']['2341'], t('Second allowed value key is set to 2341'));
-    $this->assertNotNull($field_storage->settings['allowed_values']['3412'], t('Third allowed value key is set to 3412'));
-    $this->assertNotNull($field_storage->settings['allowed_values']['4123'], t('Fourth allowed value key is set to 4123'));
-    $this->assertEqual($field_storage->settings['allowed_values']['1234'], '1234', t('First allowed value is set to 1234'));
-    $this->assertEqual($field_storage->settings['allowed_values']['2341'], '2341', t('Second allowed value is set to 2341'));
-    $this->assertEqual($field_storage->settings['allowed_values']['3412'], '3412', t('Third allowed value is set to 3412'));
-    $this->assertEqual($field_storage->settings['allowed_values']['4123'], '4123', t('Fourth allowed value is set to 4123'));
+    $this->assertNotNull($field_storage->getSetting('allowed_values')['1234'], t('First allowed value key is set to 1234'));
+    $this->assertNotNull($field_storage->getSetting('allowed_values')['2341'], t('Second allowed value key is set to 2341'));
+    $this->assertNotNull($field_storage->getSetting('allowed_values')['3412'], t('Third allowed value key is set to 3412'));
+    $this->assertNotNull($field_storage->getSetting('allowed_values')['4123'], t('Fourth allowed value key is set to 4123'));
+    $this->assertEqual($field_storage->getSetting('allowed_values')['1234'], '1234', t('First allowed value is set to 1234'));
+    $this->assertEqual($field_storage->getSetting('allowed_values')['2341'], '2341', t('Second allowed value is set to 2341'));
+    $this->assertEqual($field_storage->getSetting('allowed_values')['3412'], '3412', t('Third allowed value is set to 3412'));
+    $this->assertEqual($field_storage->getSetting('allowed_values')['4123'], '4123', t('Fourth allowed value is set to 4123'));
 
     // Text field with a single checkbox.
     $field_storage = entity_load('field_storage_config', 'node.field_test_text_single_checkbox');
diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateUserProfileFieldTest.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateUserProfileFieldTest.php
index 735e045..24643ab 100644
--- a/core/modules/migrate_drupal/src/Tests/d6/MigrateUserProfileFieldTest.php
+++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateUserProfileFieldTest.php
@@ -41,7 +41,7 @@ public function testUserProfileFields() {
     // Migrated a text field.
     $field_storage = entity_load('field_storage_config', 'user.profile_color');
     $this->assertEqual($field_storage->type, 'text', 'Field type is text.');
-    $this->assertEqual($field_storage->cardinality, 1, 'Text field has correct cardinality');
+    $this->assertEqual($field_storage->getCardinality(), 1, 'Text field has correct cardinality');
 
     // Migrated a textarea.
     $field_storage = entity_load('field_storage_config', 'user.profile_biography');
@@ -69,7 +69,7 @@ public function testUserProfileFields() {
     // Migrated list field.
     $field_storage = entity_load('field_storage_config', 'user.profile_bands');
     $this->assertEqual($field_storage->type, 'text', 'Field type is text.');
-    $this->assertEqual($field_storage->cardinality, -1, 'List field has correct cardinality');
+    $this->assertEqual($field_storage->getCardinality(), -1, 'List field has correct cardinality');
 
 /*
     // Migrated URL field.
@@ -80,7 +80,7 @@ public function testUserProfileFields() {
     // Migrated date field.
     $field_storage = entity_load('field_storage_config', 'user.profile_birthdate');
     $this->assertEqual($field_storage->type, 'datetime', 'Field type is datetime.');
-    $this->assertEqual($field_storage->settings['datetime_type'], 'date');
+    $this->assertEqual($field_storage->getSetting('datetime_type'), 'date');
   }
 
 }
diff --git a/core/modules/node/src/Tests/NodeFieldMultilingualTest.php b/core/modules/node/src/Tests/NodeFieldMultilingualTest.php
index dc8897b..dd8aec2 100644
--- a/core/modules/node/src/Tests/NodeFieldMultilingualTest.php
+++ b/core/modules/node/src/Tests/NodeFieldMultilingualTest.php
@@ -53,7 +53,7 @@ protected function setUp() {
 
     // Make node body translatable.
     $field_storage = FieldStorageConfig::loadByName('node', 'body');
-    $field_storage->translatable = TRUE;
+    $field_storage->setTranslatable(TRUE);
     $field_storage->save();
   }
 
diff --git a/core/modules/node/src/Tests/Views/NodeFieldFilterTest.php b/core/modules/node/src/Tests/Views/NodeFieldFilterTest.php
index 599b126..005a8d5 100644
--- a/core/modules/node/src/Tests/Views/NodeFieldFilterTest.php
+++ b/core/modules/node/src/Tests/Views/NodeFieldFilterTest.php
@@ -51,7 +51,7 @@ function setUp() {
     // Make the body field translatable. The title is already translatable by
     // definition.
     $field_storage = FieldStorageConfig::loadByName('node', 'body');
-    $field_storage->translatable = TRUE;
+    $field_storage->setTranslatable(TRUE);
     $field_storage->save();
 
     // Set up node titles.
diff --git a/core/modules/node/src/Tests/Views/NodeLanguageTest.php b/core/modules/node/src/Tests/Views/NodeLanguageTest.php
index 0195b44..4ced144 100644
--- a/core/modules/node/src/Tests/Views/NodeLanguageTest.php
+++ b/core/modules/node/src/Tests/Views/NodeLanguageTest.php
@@ -57,7 +57,7 @@ protected function setUp() {
     // Make the body field translatable. The title is already translatable by
     // definition.
     $field_storage = FieldStorageConfig::loadByName('node', 'body');
-    $field_storage->translatable = TRUE;
+    $field_storage->setTranslatable(TRUE);
     $field_storage->save();
 
     // Set up node titles. They should not include the words "French",
diff --git a/core/modules/options/options.module b/core/modules/options/options.module
index 54cf4b3..9264a24 100644
--- a/core/modules/options/options.module
+++ b/core/modules/options/options.module
@@ -106,12 +106,12 @@ function options_allowed_values(FieldStorageDefinitionInterface $definition, Fie
  * Implements hook_field_storage_config_update_forbid().
  */
 function options_field_storage_config_update_forbid(FieldStorageConfigInterface $field_storage, FieldStorageConfigInterface $prior_field_storage) {
-  if ($field_storage->module == 'options' && $field_storage->hasData()) {
+  if ($field_storage->getModule() == 'options' && $field_storage->hasData()) {
     // Forbid any update that removes allowed values with actual data.
     $allowed_values = $field_storage->getSetting('allowed_values');
     $prior_allowed_values = $prior_field_storage->getSetting('allowed_values');
     $lost_keys = array_keys(array_diff_key($prior_allowed_values, $allowed_values));
-    if (_options_values_in_use($field_storage->entity_type, $field_storage->getName(), $lost_keys)) {
+    if (_options_values_in_use($field_storage->getTargetEntityTypeId(), $field_storage->getName(), $lost_keys)) {
       throw new FieldStorageDefinitionUpdateForbiddenException(t('A list field (@field_name) with existing data cannot have its keys changed.', array('@field_name' => $field_storage->getName())));
     }
   }
diff --git a/core/modules/options/src/Tests/OptionsFieldTest.php b/core/modules/options/src/Tests/OptionsFieldTest.php
index a6f0b97..5ad5953 100644
--- a/core/modules/options/src/Tests/OptionsFieldTest.php
+++ b/core/modules/options/src/Tests/OptionsFieldTest.php
@@ -39,7 +39,7 @@ function testUpdateAllowedValues() {
     $entity = entity_create('entity_test');
     $entity->{$this->fieldName}->value = 1;
     $entity->save();
-    $this->fieldStorage->settings['allowed_values'] = array(2 => 'Two');
+    $this->fieldStorage->setSetting('allowed_values', [2 => 'Two']);
     try {
       $this->fieldStorage->save();
       $this->fail(t('Cannot update a list field storage to not include keys with existing data.'));
@@ -52,7 +52,7 @@ function testUpdateAllowedValues() {
     $entity->save();
 
     // Removed options do not appear.
-    $this->fieldStorage->settings['allowed_values'] = array(2 => 'Two');
+    $this->fieldStorage->setSetting('allowed_values', [2 => 'Two']);
     $this->fieldStorage->save();
     $entity = entity_create('entity_test');
     $form = \Drupal::service('entity.form_builder')->getForm($entity);
@@ -61,7 +61,7 @@ function testUpdateAllowedValues() {
     $this->assertTrue(empty($form[$this->fieldName]['widget'][3]), 'Option 3 does not exist');
 
     // Completely new options appear.
-    $this->fieldStorage->settings['allowed_values'] = array(10 => 'Update', 20 => 'Twenty');
+    $this->fieldStorage->setSetting('allowed_values', [10 => 'Update', 20 => 'Twenty']);
     $this->fieldStorage->save();
     // The entity holds an outdated field object with the old allowed values
     // setting, so we need to reintialize the entity object.
diff --git a/core/modules/options/src/Tests/OptionsWidgetsTest.php b/core/modules/options/src/Tests/OptionsWidgetsTest.php
index e1e52fe..e859126 100644
--- a/core/modules/options/src/Tests/OptionsWidgetsTest.php
+++ b/core/modules/options/src/Tests/OptionsWidgetsTest.php
@@ -140,7 +140,7 @@ function testRadioButtons() {
     $this->assertFieldValues($entity_init, 'card_1', array());
 
     // Check that required radios with one option is auto-selected.
-    $this->card_1->settings['allowed_values'] = array(99 => 'Only allowed value');
+    $this->card_1->setSetting('allowed_values', [99 => 'Only allowed value']);
     $this->card_1->save();
     $field->required = TRUE;
     $field->save();
@@ -229,7 +229,7 @@ function testCheckBoxes() {
     $this->assertFieldValues($entity_init, 'card_2', array());
 
     // Required checkbox with one option is auto-selected.
-    $this->card_2->settings['allowed_values'] = array(99 => 'Only allowed value');
+    $this->card_2->setSetting('allowed_values', [99 => 'Only allowed value']);
     $this->card_2->save();
     $field->required = TRUE;
     $field->save();
@@ -307,8 +307,8 @@ function testSelectListSingle() {
 
     // Test optgroups.
 
-    $this->card_1->settings['allowed_values'] = array();
-    $this->card_1->settings['allowed_values_function'] = 'options_test_allowed_values_callback';
+    $this->card_1->setSetting('allowed_values', []);
+    $this->card_1->setSetting('allowed_values_function', 'options_test_allowed_values_callback');
     $this->card_1->save();
 
     // Display form: with no field data, nothing is selected
@@ -426,8 +426,8 @@ function testSelectListMultiple() {
     // Test optgroups.
 
     // Use a callback function defining optgroups.
-    $this->card_2->settings['allowed_values'] = array();
-    $this->card_2->settings['allowed_values_function'] = 'options_test_allowed_values_callback';
+    $this->card_2->setSetting('allowed_values', []);
+    $this->card_2->setSetting('allowed_values_function', 'options_test_allowed_values_callback');
     $this->card_2->save();
     $field->required = FALSE;
     $field->save();
diff --git a/core/modules/quickedit/src/Tests/EditorSelectionTest.php b/core/modules/quickedit/src/Tests/EditorSelectionTest.php
index 336fbec..d148408 100644
--- a/core/modules/quickedit/src/Tests/EditorSelectionTest.php
+++ b/core/modules/quickedit/src/Tests/EditorSelectionTest.php
@@ -74,7 +74,7 @@ public function testText() {
     $this->assertEqual('plain_text', $this->getSelectedEditor($entity->id(), $field_name), "With cardinality 1, the 'plain_text' editor is selected.");
 
     // With cardinality >1
-    $this->fields->field_text_field_storage->cardinality = 2;
+    $this->fields->field_text_field_storage->setCardinality(2);
     $this->fields->field_text_field_storage->save();
     $this->assertEqual('form', $this->getSelectedEditor($entity->id(), $field_name), "With cardinality >1, the 'form' editor is selected.");
 
@@ -119,7 +119,7 @@ public function testTextWysiwyg() {
     $this->assertEqual('wysiwyg', $this->getSelectedEditor($entity->id(), $field_name), "With cardinality 1, and the full_html text format, the 'wysiwyg' editor is selected.");
 
     // Editor selection with text field, cardinality >1.
-    $this->fields->field_textarea_field_storage->cardinality = 2;
+    $this->fields->field_textarea_field_storage->setCardinality(2);
     $this->fields->field_textarea_field_storage->save();
     $this->assertEqual('form', $this->getSelectedEditor($entity->id(), $field_name), "With cardinality >1, and both items using the full_html text format, the 'form' editor is selected.");
   }
@@ -150,7 +150,7 @@ public function testNumber() {
     $this->assertEqual('form', $this->getSelectedEditor($entity->id(), $field_name), "With cardinality 1, the 'form' editor is selected.");
 
     // Editor selection with cardinality >1.
-    $this->fields->field_nr_field_storage->cardinality = 2;
+    $this->fields->field_nr_field_storage->setCardinality(2);
     $this->fields->field_nr_field_storage->save();
     $this->assertEqual('form', $this->getSelectedEditor($entity->id(), $field_name), "With cardinality >1, the 'form' editor is selected.");
   }
diff --git a/core/modules/search/src/Tests/SearchLanguageTest.php b/core/modules/search/src/Tests/SearchLanguageTest.php
index d576983..8a59d6c 100644
--- a/core/modules/search/src/Tests/SearchLanguageTest.php
+++ b/core/modules/search/src/Tests/SearchLanguageTest.php
@@ -38,7 +38,7 @@ protected function setUp() {
     // definition. The parent class has already created the article and page
     // content types.
     $field_storage = FieldStorageConfig::loadByName('node', 'body');
-    $field_storage->translatable = TRUE;
+    $field_storage->setTranslatable(TRUE);
     $field_storage->save();
 
     // Create a few page nodes with multilingual body values.
diff --git a/core/modules/search/src/Tests/SearchMultilingualEntityTest.php b/core/modules/search/src/Tests/SearchMultilingualEntityTest.php
index 49196be..5b02525 100644
--- a/core/modules/search/src/Tests/SearchMultilingualEntityTest.php
+++ b/core/modules/search/src/Tests/SearchMultilingualEntityTest.php
@@ -59,7 +59,7 @@ protected function setUp() {
     // definition. The parent class has already created the article and page
     // content types.
     $field_storage = FieldStorageConfig::loadByName('node', 'body');
-    $field_storage->translatable = TRUE;
+    $field_storage->setTranslatable(TRUE);
     $field_storage->save();
 
     // Create a few page nodes with multilingual body values.
diff --git a/core/modules/system/src/Tests/Entity/EntityTranslationFormTest.php b/core/modules/system/src/Tests/Entity/EntityTranslationFormTest.php
index cee9a0b..933f8dd 100644
--- a/core/modules/system/src/Tests/Entity/EntityTranslationFormTest.php
+++ b/core/modules/system/src/Tests/Entity/EntityTranslationFormTest.php
@@ -99,7 +99,7 @@ function testEntityFormLanguage() {
 
     // Make body translatable.
     $field_storage = FieldStorageConfig::loadByName('node', 'body');
-    $field_storage->translatable = TRUE;
+    $field_storage->setTranslatable(TRUE);
     $field_storage->save();
     $field_storage = FieldStorageConfig::loadByName('node', 'body');
     $this->assertTrue($field_storage->isTranslatable(), 'Field body is translatable.');
diff --git a/core/modules/system/src/Tests/Entity/FieldSqlStorageTest.php b/core/modules/system/src/Tests/Entity/FieldSqlStorageTest.php
index 8fdb484..417d7e0 100644
--- a/core/modules/system/src/Tests/Entity/FieldSqlStorageTest.php
+++ b/core/modules/system/src/Tests/Entity/FieldSqlStorageTest.php
@@ -332,7 +332,7 @@ function testUpdateFieldSchemaWithData() {
     $entity->save();
 
     // Attempt to update the field in a way that would work without data.
-    $field_storage->settings['scale'] = 3;
+    $field_storage->setSetting('scale', 3);
     try {
       $field_storage->save();
       $this->fail(t('Cannot update field schema with data.'));
@@ -357,7 +357,7 @@ function testFieldUpdateFailure() {
 
     // Attempt to update the field in a way that would break the storage.
     $prior_field_storage = $field_storage;
-    $field_storage->settings['max_length'] = -1;
+    $field_storage->setSetting('max_length', -1);
     try {
       $field_storage->save();
       $this->fail(t('Update succeeded.'));
@@ -411,15 +411,23 @@ function testFieldUpdateIndexesWithData() {
     $entity->enforceIsNew();
     $entity->save();
 
-    // Add an index.
-    $field_storage->indexes = array('value' => array(array('value', 255)));
+    // Add an index. Since $indexes is protected, we have to use reflection.
+    $ref_field_storage_indexes = new \ReflectionProperty($field_storage, 'indexes');
+    $ref_field_storage_indexes->setAccessible(TRUE);
+    $ref_field_storage_indexes->setValue(
+      $field_storage,
+      array('value' => array(array('value', 255)))
+    );
     $field_storage->save();
     foreach ($tables as $table) {
       $this->assertTrue(Database::getConnection()->schema()->indexExists($table, "{$field_name}_value"), t("Index on value created in @table", array('@table' => $table)));
     }
 
     // Add a different index, removing the existing custom one.
-    $field_storage->indexes = array('value_format' => array(array('value', 127), array('format', 127)));
+    $ref_field_storage_indexes->setValue(
+      $field_storage,
+      array('value_format' => array(array('value', 127), array('format', 127)))
+    );
     $field_storage->save();
     foreach ($tables as $table) {
       $this->assertTrue(Database::getConnection()->schema()->indexExists($table, "{$field_name}_value_format"), t("Index on value_format created in @table", array('@table' => $table)));
@@ -455,7 +463,7 @@ function testFieldSqlStorageForeignKeys() {
 
     // Update the field settings, it should update the foreign key definition too.
     $foreign_key_name = 'color';
-    $field_storage->settings['foreign_key_name'] = $foreign_key_name;
+    $field_storage->setSetting('foreign_key_name', $foreign_key_name);
     $field_storage->save();
     // Reload the field schema after the update.
     $schema = $field_storage->getSchema();
diff --git a/core/modules/taxonomy/src/Entity/Vocabulary.php b/core/modules/taxonomy/src/Entity/Vocabulary.php
index e650551..f793ae9 100644
--- a/core/modules/taxonomy/src/Entity/Vocabulary.php
+++ b/core/modules/taxonomy/src/Entity/Vocabulary.php
@@ -116,7 +116,7 @@ public function postSave(EntityStorageInterface $storage, $update = TRUE) {
       foreach ($field_storages as $field_storage) {
         $update_storage = FALSE;
 
-        foreach ($field_storage->settings['allowed_values'] as &$value) {
+        foreach ($field_storage->getSetting('allowed_values') as &$value) {
           if ($value['vocabulary'] == $this->getOriginalId()) {
             $value['vocabulary'] = $this->id();
             $update_storage = TRUE;
@@ -165,14 +165,17 @@ public static function postDelete(EntityStorageInterface $storage, array $entiti
       $modified_storage = FALSE;
       // Term reference fields may reference terms from more than one
       // vocabulary.
-      foreach ($field_storage->settings['allowed_values'] as $key => $allowed_value) {
+      foreach ($field_storage->getSetting('allowed_values') as $key => $allowed_value) {
         if (isset($vocabularies[$allowed_value['vocabulary']])) {
-          unset($field_storage->settings['allowed_values'][$key]);
+          $allowed_values = $field_storage->getSetting('allowed_values');
+          unset($allowed_values[$key]);
+          $field_storage->setSetting('allowed_values', $allowed_values);
           $modified_storage = TRUE;
         }
       }
       if ($modified_storage) {
-        if (empty($field_storage->settings['allowed_values'])) {
+        $allowed_values = $field_storage->getSetting('allowed_values');
+        if (empty($allowed_values)) {
           $field_storage->delete();
         }
         else {
diff --git a/core/modules/taxonomy/src/Tests/TermFieldTest.php b/core/modules/taxonomy/src/Tests/TermFieldTest.php
index 50d23e8..80f0b37 100644
--- a/core/modules/taxonomy/src/Tests/TermFieldTest.php
+++ b/core/modules/taxonomy/src/Tests/TermFieldTest.php
@@ -149,7 +149,7 @@ function testTaxonomyTermFieldSettingsAutocompleteWidget() {
   function testTaxonomyTermFieldChangeMachineName() {
     // Add several entries in the 'allowed_values' setting, to make sure that
     // they all get updated.
-    $this->field_storage->settings['allowed_values'] = array(
+    $this->field_storage->setSetting('allowed_values', [
       array(
         'vocabulary' => $this->vocabulary->id(),
         'parent' => '0',
@@ -162,7 +162,7 @@ function testTaxonomyTermFieldChangeMachineName() {
         'vocabulary' => 'foo',
         'parent' => '0',
       ),
-    );
+    ]);
     $this->field_storage->save();
     // Change the machine name.
     $new_name = Unicode::strtolower($this->randomMachineName());
diff --git a/core/modules/taxonomy/src/Tests/Views/TaxonomyFieldFilterTest.php b/core/modules/taxonomy/src/Tests/Views/TaxonomyFieldFilterTest.php
index b7fe1e9..a386b80 100644
--- a/core/modules/taxonomy/src/Tests/Views/TaxonomyFieldFilterTest.php
+++ b/core/modules/taxonomy/src/Tests/Views/TaxonomyFieldFilterTest.php
@@ -66,7 +66,7 @@ function setUp() {
       'entity_type' => 'taxonomy_term',
       'type' => 'text',
     ));
-    $field->translatable = TRUE;
+    $field->setTranslatable(TRUE);
     $field->save();
     entity_create('field_config', array(
       'field_name' => 'field_foo',
diff --git a/core/modules/user/src/Tests/UserRegistrationTest.php b/core/modules/user/src/Tests/UserRegistrationTest.php
index 853891a..594dbed 100644
--- a/core/modules/user/src/Tests/UserRegistrationTest.php
+++ b/core/modules/user/src/Tests/UserRegistrationTest.php
@@ -247,7 +247,7 @@ function testRegistrationWithUserFields() {
     $this->assertEqual($new_user->test_user_field->value, $value, 'The field value was correclty saved.');
 
     // Check that the 'add more' button works.
-    $field_storage->cardinality = FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED;
+    $field_storage->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
     $field_storage->save();
     foreach (array('js', 'nojs') as $js) {
       $this->drupalGet('user/register');
