diff --git a/core/lib/Drupal/Core/Entity/DatabaseStorageController.php b/core/lib/Drupal/Core/Entity/DatabaseStorageController.php
index 744eb23..70f1c2f 100644
--- a/core/lib/Drupal/Core/Entity/DatabaseStorageController.php
+++ b/core/lib/Drupal/Core/Entity/DatabaseStorageController.php
@@ -649,7 +649,7 @@ protected function doSaveFieldItems(EntityInterface $entity, $update) {
       // Prepare the multi-insert query.
       $do_insert = FALSE;
       $columns = array('entity_id', 'revision_id', 'bundle', 'delta', 'langcode');
-      foreach ($field['columns'] as $column => $attributes) {
+      foreach ($field->getColumns() as $column => $attributes) {
         $columns[] = static::_fieldColumnName($field, $column);
       }
       $query = $this->database->insert($table_name)->fields($columns);
@@ -668,7 +668,7 @@ protected function doSaveFieldItems(EntityInterface $entity, $update) {
             'delta' => $delta,
             'langcode' => $langcode,
           );
-          foreach ($field['columns'] as $column => $attributes) {
+          foreach ($field->getColumns() as $column => $attributes) {
             $column_name = static::_fieldColumnName($field, $column);
             $value = isset($item[$column]) ? $item[$column] : NULL;
             // Serialize the value if specified in the column schema.
@@ -677,7 +677,7 @@ protected function doSaveFieldItems(EntityInterface $entity, $update) {
           $query->values($record);
           $revision_query->values($record);
 
-          if ($field['cardinality'] != FIELD_CARDINALITY_UNLIMITED && ++$delta_count == $field['cardinality']) {
+          if ($field->getFieldCardinality() != FIELD_CARDINALITY_UNLIMITED && ++$delta_count == $field->getFieldCardinality()) {
             break;
           }
         }
@@ -780,7 +780,7 @@ public function onFieldUpdate(FieldInterface $field) {
       }
     }
     else {
-      if ($field['columns'] != $original['columns']) {
+      if ($field->getColumns() != $original->getColumns()) {
         throw new FieldUpdateForbiddenException("The SQL storage cannot change the schema for an existing field with data.");
       }
       // There is data, so there are no column changes. Drop all the prior
@@ -830,7 +830,7 @@ public function onFieldUpdate(FieldInterface $field) {
    */
   public function onFieldDelete(FieldInterface $field) {
     // Mark all data associated with the field for deletion.
-    $field['deleted'] = FALSE;
+    $field->deleted = FALSE;
     $table = static::_fieldTableName($field);
     $revision_table = static::_fieldRevisionTableName($field);
     $this->database->update($table)
@@ -839,7 +839,7 @@ public function onFieldDelete(FieldInterface $field) {
 
     // Move the table to a unique name while the table contents are being
     // deleted.
-    $field['deleted'] = TRUE;
+    $field->deleted = TRUE;
     $new_table = static::_fieldTableName($field);
     $revision_new_table = static::_fieldRevisionTableName($field);
     $this->database->schema()->renameTable($table, $new_table);
@@ -855,11 +855,11 @@ public function onInstanceDelete(FieldInstanceInterface $instance) {
     $revision_name = static::_fieldRevisionTableName($field);
     $this->database->update($table_name)
       ->fields(array('deleted' => 1))
-      ->condition('bundle', $instance['bundle'])
+      ->condition('bundle', $instance->bundle)
       ->execute();
     $this->database->update($revision_name)
       ->fields(array('deleted' => 1))
-      ->condition('bundle', $instance['bundle'])
+      ->condition('bundle', $instance->bundle)
       ->execute();
   }
 
@@ -871,7 +871,7 @@ public function onBundleRename($bundle, $bundle_new) {
     $instances = field_read_instances(array('entity_type' => $this->entityType, 'bundle' => $bundle_new), array('include_deleted' => TRUE, 'include_inactive' => TRUE));
     foreach ($instances as $instance) {
       $field = $instance->getField();
-      if ($field['storage']['type'] == 'field_sql_storage') {
+      if ($field->storage['type'] == 'field_sql_storage') {
         $table_name = static::_fieldTableName($field);
         $revision_name = static::_fieldRevisionTableName($field);
         $this->database->update($table_name)
@@ -945,13 +945,13 @@ public function onFieldPurge(FieldInterface $field) {
    * @see hook_schema()
    */
   public static function _fieldSqlSchema(FieldInterface $field, array $schema = NULL) {
-    if ($field['deleted']) {
-      $description_current = "Data storage for deleted field {$field['id']} ({$field['entity_type']}, {$field['field_name']}).";
-      $description_revision = "Revision archive storage for deleted field {$field['id']} ({$field['entity_type']}, {$field['field_name']}).";
+    if ($field->deleted) {
+      $description_current = "Data storage for deleted field {$field->id()} ({$field->entity_type}, {$field->getFieldName()}).";
+      $description_revision = "Revision archive storage for deleted field {$field->id()} ({$field->entity_type}, {$field->getFieldName()}).";
     }
     else {
-      $description_current = "Data storage for {$field['entity_type']} field {$field['field_name']}.";
-      $description_revision = "Revision archive storage for {$field['entity_type']} field {$field['field_name']}.";
+      $description_current = "Data storage for {$field->entity_type} field {$field->getFieldName()}.";
+      $description_revision = "Revision archive storage for {$field->entity_type} field {$field->getFieldName()}.";
     }
 
     $current = array(
@@ -1076,12 +1076,12 @@ public static function _fieldSqlSchema(FieldInterface $field, array $schema = NU
    *
    */
   static public function _fieldTableName(FieldInterface $field) {
-    if ($field['deleted']) {
+    if ($field->deleted) {
       // When a field is a deleted, the table is renamed to
       // {field_deleted_data_FIELD_UUID}. To make sure we don't end up with
       // table names longer than 64 characters, we hash the uuid and return the
       // first 10 characters so we end up with a short unique ID.
-      return "field_deleted_data_" . substr(hash('sha256', $field['uuid']), 0, 10);
+      return "field_deleted_data_" . substr(hash('sha256', $field->uuid()), 0, 10);
     }
     else {
       return static::_generateFieldTableName($field, FALSE);
@@ -1105,12 +1105,12 @@ static public function _fieldTableName(FieldInterface $field) {
    *   A string containing the generated name for the database table.
    */
   static public function _fieldRevisionTableName(FieldInterface $field) {
-    if ($field['deleted']) {
+    if ($field->deleted) {
       // When a field is a deleted, the table is renamed to
       // {field_deleted_revision_FIELD_UUID}. To make sure we don't end up with
       // table names longer than 64 characters, we hash the uuid and return the
       // first 10 characters so we end up with a short unique ID.
-      return "field_deleted_revision_" . substr(hash('sha256', $field['uuid']), 0, 10);
+      return "field_deleted_revision_" . substr(hash('sha256', $field->uuid()), 0, 10);
     }
     else {
       return static::_generateFieldTableName($field, TRUE);
@@ -1131,7 +1131,7 @@ static public function _fieldRevisionTableName(FieldInterface $field) {
    * @return string
    *   The final table name.
    */
-  static protected function _generateFieldTableName($field, $revision) {
+  static protected function _generateFieldTableName(FieldInterface $field, $revision) {
     $separator = $revision ? '_revision__' : '__';
     $table_name = $field->entity_type . $separator .  $field->name;
     // Limit the string to 48 characters, keeping a 16 characters margin for db
@@ -1141,7 +1141,7 @@ static protected function _generateFieldTableName($field, $revision) {
       // field UUID.
       $separator = $revision ? '_r__' : '__';
       $entity_type = substr($field->entity_type, 0, 38 - strlen($separator));
-      $field_hash = substr(hash('sha256', $field->uuid), 0, 10);
+      $field_hash = substr(hash('sha256', $field->uuid()), 0, 10);
       $table_name = $entity_type . $separator . $field_hash;
     }
     return $table_name;
diff --git a/core/lib/Drupal/Core/Entity/EntityFormController.php b/core/lib/Drupal/Core/Entity/EntityFormController.php
index 07dd8f3..25532e2 100644
--- a/core/lib/Drupal/Core/Entity/EntityFormController.php
+++ b/core/lib/Drupal/Core/Entity/EntityFormController.php
@@ -305,10 +305,13 @@ public function validate(array $form, array &$form_state) {
     // Map errors back to form elements.
     if ($violations) {
       foreach ($violations as $field_name => $field_violations) {
-        $langcode = field_is_translatable($entity_type , field_info_field($entity_type, $field_name)) ? $entity_langcode : Language::LANGCODE_NOT_SPECIFIED;
-        $field_state = field_form_get_state($form['#parents'], $field_name, $langcode, $form_state);
-        $field_state['constraint_violations'] = $field_violations;
-        field_form_set_state($form['#parents'], $field_name, $langcode, $form_state, $field_state);
+        $field = field_info_field($entity->entityType(), $field_name);
+        if ($field) {
+          $langcode = field_is_translatable($entity->entityType(), $field) ? $entity_langcode : Language::LANGCODE_NOT_SPECIFIED;
+          $field_state = field_form_get_state($form['#parents'], $field_name, $langcode, $form_state);
+          $field_state['constraint_violations'] = $field_violations;
+          field_form_set_state($form['#parents'], $field_name, $langcode, $form_state, $field_state);
+        }
       }
 
       field_invoke_method('flagErrors', _field_invoke_widget_target($form_state['form_display']), $entity, $form, $form_state);
@@ -435,13 +438,12 @@ protected function submitEntityLanguage(array $form, array &$form_state) {
 
       foreach (field_info_instances($entity_type, $entity->bundle()) as $instance) {
         $field = $instance->getField();
-        $field_name = $field->name;
+        $field_name = $field->getFieldName();
         if (isset($form[$field_name]['#language'])) {
           $previous_langcode = $form[$field_name]['#language'];
-
           // Handle a possible language change: new language values are inserted,
           // previous ones are deleted.
-          if ($field['translatable'] && $previous_langcode != $current_langcode) {
+          if ($field->translatable && $previous_langcode != $current_langcode) {
             $form_state['values'][$field_name][$current_langcode] = $form_state['values'][$field_name][$previous_langcode];
             $form_state['values'][$field_name][$previous_langcode] = array();
           }
diff --git a/core/lib/Drupal/Core/Entity/FieldableEntityStorageControllerBase.php b/core/lib/Drupal/Core/Entity/FieldableEntityStorageControllerBase.php
index 4911694..ff7fafc 100644
--- a/core/lib/Drupal/Core/Entity/FieldableEntityStorageControllerBase.php
+++ b/core/lib/Drupal/Core/Entity/FieldableEntityStorageControllerBase.php
@@ -86,7 +86,7 @@ protected function loadFieldItems(array $entities, $age) {
           $data = array();
           $instances = field_info_instances($this->entityType, $entity->bundle());
           foreach ($instances as $instance) {
-            $data[$instance['field_name']] = $queried_entities[$id]->{$instance['field_name']};
+            $data[$instance->getFieldName()] = $queried_entities[$id]->{$instance->getFieldName()};
           }
           $cid = "field:{$this->entityType}:$id";
           cache('field')->set($cid, $data);
diff --git a/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php b/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php
index e72a586..903908d 100644
--- a/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php
+++ b/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php
@@ -116,7 +116,8 @@ public function addField($field, $type, $langcode) {
         if ($key < $count) {
           $next = $specifiers[$key + 1];
           // Is this a field column?
-          if (isset($field['columns'][$next]) || in_array($next, Field::getReservedColumns())) {
+          $columns = $field->getColumns();
+          if (isset($columns[$next]) || in_array($next, Field::getReservedColumns())) {
             // Use it.
             $column = $next;
             // Do not process it again.
@@ -150,7 +151,7 @@ public function addField($field, $type, $langcode) {
             // column, i.e. target_id or fid.
             // Otherwise, the code executing the relationship will throw an
             // exception anyways so no need to do it here.
-            if (!$column && isset($propertyDefinitions[$relationship_specifier]) && $entity->{$field['field_name']}->get('entity') instanceof EntityReference) {
+            if (!$column && isset($propertyDefinitions[$relationship_specifier]) && $entity->{$field->getFieldName()}->get('entity') instanceof EntityReference) {
               $column = current(array_keys($propertyDefinitions));
             }
             // Prepare the next index prefix.
@@ -249,10 +250,10 @@ protected function ensureEntityTable($index_prefix, $property, $type, $langcode,
    * @throws \Drupal\Core\Entity\Query\QueryException
    */
   protected function ensureFieldTable($index_prefix, &$field, $type, $langcode, $base_table, $entity_id_field, $field_id_field) {
-    $field_name = $field['field_name'];
+    $field_name = $field->getFieldName();
     if (!isset($this->fieldTables[$index_prefix . $field_name])) {
       $table = $this->sqlQuery->getMetaData('age') == FIELD_LOAD_CURRENT ? DatabaseStorageController::_fieldTableName($field) : DatabaseStorageController::_fieldRevisionTableName($field);
-      if ($field['cardinality'] != 1) {
+      if ($field->getFieldCardinality() != 1) {
         $this->sqlQuery->addMetaData('simple_query', FALSE);
       }
       $entity_type = $this->sqlQuery->getMetaData('entity_type');
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockFieldTest.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockFieldTest.php
index 53f8f5a..5b41fd5 100644
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockFieldTest.php
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockFieldTest.php
@@ -81,12 +81,12 @@ public function testBlockFields() {
     ));
     $this->instance->save();
     entity_get_form_display('custom_block', 'link', 'default')
-      ->setComponent($this->field['field_name'], array(
+      ->setComponent($this->field->id(), array(
         'type' => 'link_default',
       ))
       ->save();
     entity_get_display('custom_block', 'link', 'default')
-      ->setComponent($this->field['field_name'], array(
+      ->setComponent($this->field->id(), array(
         'type' => 'link',
         'label' => 'hidden',
       ))
@@ -96,8 +96,8 @@ public function testBlockFields() {
     $this->drupalGet('block/add/link');
     $edit = array(
       'info' => $this->randomName(8),
-      $this->field['field_name'] . '[und][0][url]' => 'http://example.com',
-      $this->field['field_name'] . '[und][0][title]' => 'Example.com'
+      $this->field->id() . '[und][0][url]' => 'http://example.com',
+      $this->field->id() . '[und][0][title]' => 'Example.com'
     );
     $this->drupalPost(NULL, $edit, t('Save'));
     $block = entity_load('custom_block', 1);
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockTypeTest.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockTypeTest.php
index d5322e1..9f3c0cc 100644
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockTypeTest.php
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockTypeTest.php
@@ -79,7 +79,7 @@ public function testCustomBlockTypeEditing() {
     $this->createCustomBlockType('other');
 
     $instance = field_info_instance('custom_block', 'block_body', 'basic');
-    $this->assertEqual($instance['label'], 'Block body', 'Body field was found.');
+    $this->assertEqual($instance->label(), 'Block body', 'Body field was found.');
 
     // Verify that title and body fields are displayed.
     $this->drupalGet('block/add/basic');
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php
index 4064b22..4ae0960 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php
@@ -71,9 +71,10 @@ function setUp() {
     $this->drupalPost("user/" . $admin_user->id() . "/edit", $edit, t('Save'));
 
     // Make comment body translatable.
-    $field = field_info_field('comment', 'comment_body');
-    $field['translatable'] = TRUE;
+    $field = field_info_field('comment_body');
+    $field->translatable = TRUE;
     $field->save();
+
     $this->assertTrue(field_is_translatable('comment', $field), 'Comment body is translatable.');
   }
 
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentTranslationUITest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentTranslationUITest.php
index 96e2d20..a0009f3 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentTranslationUITest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentTranslationUITest.php
@@ -63,8 +63,8 @@ protected function getTranslatorPermissions() {
    */
   function setupTestFields() {
     parent::setupTestFields();
-    $field = field_info_field('comment', 'comment_body');
-    $field['translatable'] = TRUE;
+    $field = field_info_field('comment_body');
+    $field->translatable = TRUE;
     $field->save();
   }
 
diff --git a/core/modules/content_translation/content_translation.admin.inc b/core/modules/content_translation/content_translation.admin.inc
index 819a63b..b2f6aff 100644
--- a/core/modules/content_translation/content_translation.admin.inc
+++ b/core/modules/content_translation/content_translation.admin.inc
@@ -39,7 +39,7 @@ function content_translation_field_sync_widget(Field $field, FieldInstance $inst
       '#type' => 'checkboxes',
       '#title' => t('Translatable elements'),
       '#options' => $options,
-      '#default_value' => !empty($instance['settings']['translation_sync']) ? $instance['settings']['translation_sync'] : $default,
+      '#default_value' => !empty($instance['settings']['translation_sync']) ? $instance->settings['translation_sync'] : $default,
       '#attached' => array(
         'library' => array(
           array('content_translation', 'drupal.content_translation.admin'),
@@ -97,9 +97,9 @@ function _content_translation_form_language_content_settings_form_alter(array &$
           foreach ($fields as $field_name => $instance) {
             $field = $instance->getField();
             $form['settings'][$entity_type][$bundle]['fields'][$field_name] = array(
-              '#label' => $instance['label'],
+              '#label' => $instance->label(),
               '#type' => 'checkbox',
-              '#default_value' => $field['translatable'],
+              '#default_value' => $field->isFieldTranslatable(),
             );
             $column_element = content_translation_field_sync_widget($field, $instance);
             if ($column_element) {
@@ -338,7 +338,7 @@ function _content_translation_update_field_translatability($settings) {
   foreach ($fields as $entity_type => $entity_type_fields) {
     foreach ($entity_type_fields as $field_name => $translatable) {
       $field = field_info_field($entity_type, $field_name);
-      if ($field['translatable'] != $translatable) {
+      if ($field->isFieldTranslatable() != $translatable) {
         // If a field is untranslatable, it can have no data except under
         // Language::LANGCODE_NOT_SPECIFIED. Thus we need a field to be translatable before
         // we convert data to the entity language. Conversely we need to switch
diff --git a/core/modules/content_translation/content_translation.module b/core/modules/content_translation/content_translation.module
index 3edb6aa..70dadf8 100644
--- a/core/modules/content_translation/content_translation.module
+++ b/core/modules/content_translation/content_translation.module
@@ -620,9 +620,9 @@ function content_translation_form_alter(array &$form, array &$form_state) {
       }
       else {
         foreach (field_info_instances($entity->entityType(), $entity->bundle()) as $instance) {
-          $field_name = $instance['field_name'];
-          $field = $instance->getField();
-          $form[$field_name]['#multilingual'] = !empty($field['translatable']);
+          $field_name = $instance->getFieldName();
+          $field = field_info_field($entity->entityType(), $field_name);
+          $form[$field_name]['#multilingual'] = !empty($field->isFieldTranslatable());
         }
       }
     }
@@ -655,9 +655,9 @@ function content_translation_field_language_alter(&$display_language, $context)
           //   entity language and with Language::LANGCODE_DEFAULT. We need need to unset
           //   both until we remove the BC layer.
           if ($langcode == $entity_langcode) {
-            unset($entity->{$instance['field_name']}[Language::LANGCODE_DEFAULT]);
+            unset($entity->{$instance->getFieldName()}[Language::LANGCODE_DEFAULT]);
           }
-          unset($entity->{$instance['field_name']}[$langcode]);
+          unset($entity->{$instance->getFieldName()}[$langcode]);
         }
       }
     }
@@ -808,9 +808,9 @@ function content_translation_field_extra_fields() {
  */
 function content_translation_form_field_ui_field_edit_form_alter(array &$form, array &$form_state, $form_id) {
   $field = $form['#field'];
-  $entity_type = $field['entity_type'];
-  $field_name = $field['field_name'];
-  $translatable = $field['translatable'];
+  $field_name = $field->getFieldName();
+  $translatable = $field->isFieldTranslatable();
+  $entity_type = $field->entity_type;
   $label = t('Field translation');
 
   if ($field->hasData()) {
@@ -843,7 +843,7 @@ function content_translation_form_field_ui_field_edit_form_alter(array &$form, a
  * Implements hook_form_FORM_ID_alter() for 'field_ui_field_instance_edit_form'.
  */
 function content_translation_form_field_ui_field_instance_edit_form_alter(array &$form, array &$form_state, $form_id) {
-  if ($form['#field']['translatable']) {
+  if ($form['#field']->translatable) {
     module_load_include('inc', 'content_translation', 'content_translation.admin');
     $element = content_translation_field_sync_widget($form['#field'], $form['#instance']);
     if ($element) {
@@ -1025,13 +1025,13 @@ function content_translation_save_settings($settings) {
           foreach ($bundle_settings['columns'] as $field_name => $column_settings) {
             $field = field_info_field($entity_type, $field_name);
             $instance = field_info_instance($entity_type, $field_name, $bundle);
-            if ($field['translatable']) {
-              $instance['settings']['translation_sync'] = $column_settings;
+            if ($field->translatable) {
+              $instance->settings['translation_sync'] = $column_settings;
             }
             // If the field does not have translatable enabled we need to reset
             // the sync settings to their defaults.
             else {
-              unset($instance['settings']['translation_sync']);
+              unset($instance->settings['translation_sync']);
             }
             $instance->save();
           }
diff --git a/core/modules/content_translation/content_translation.pages.inc b/core/modules/content_translation/content_translation.pages.inc
index 966d259..e44e090 100644
--- a/core/modules/content_translation/content_translation.pages.inc
+++ b/core/modules/content_translation/content_translation.pages.inc
@@ -41,7 +41,7 @@ function content_translation_overview(EntityInterface $entity) {
     $translatable = FALSE;
     foreach (field_info_instances($entity->entityType(), $entity->bundle()) as $instance) {
       $field = $instance->getField();
-      if ($field['translatable']) {
+      if ($field->isFieldTranslatable()) {
         $translatable = TRUE;
         break;
       }
@@ -246,7 +246,7 @@ function content_translation_prepare_translation(EntityInterface $entity, Langua
     $instances = field_info_instances($entity->entityType(), $entity->bundle());
     foreach ($instances as $field_name => $instance) {
       $field = $instance->getField();
-      if (!empty($field['translatable'])) {
+      if (!empty($field->isFieldTranslatable())) {
         $value = $entity->get($field_name);
         $value[$target->id] = isset($value[$source->id]) ? $value[$source->id] : array();
         $entity->set($field_name, $value);
diff --git a/core/modules/content_translation/lib/Drupal/content_translation/ContentTranslationController.php b/core/modules/content_translation/lib/Drupal/content_translation/ContentTranslationController.php
index 503bd3b..6eb6144 100644
--- a/core/modules/content_translation/lib/Drupal/content_translation/ContentTranslationController.php
+++ b/core/modules/content_translation/lib/Drupal/content_translation/ContentTranslationController.php
@@ -50,9 +50,9 @@ public function removeTranslation(EntityInterface $entity, $langcode) {
     // @todo Handle properties.
     // Remove field translations.
     foreach (field_info_instances($entity->entityType(), $entity->bundle()) as $instance) {
-      $field_name = $instance['field_name'];
+      $field_name = $instance->getFieldName();
       $field = $instance->getField();
-      if ($field['translatable']) {
+      if ($field->isFieldTranslatable()) {
         $entity->{$field_name}[$langcode] = array();
       }
     }
diff --git a/core/modules/content_translation/lib/Drupal/content_translation/FieldTranslationSynchronizer.php b/core/modules/content_translation/lib/Drupal/content_translation/FieldTranslationSynchronizer.php
index 9fd4b0e..0ab6c5f 100644
--- a/core/modules/content_translation/lib/Drupal/content_translation/FieldTranslationSynchronizer.php
+++ b/core/modules/content_translation/lib/Drupal/content_translation/FieldTranslationSynchronizer.php
@@ -66,14 +66,14 @@ public function synchronizeFields(EntityInterface $entity, $sync_langcode, $orig
 
       // Sync when the field is not empty, when the synchronization translations
       // setting is set, and the field is translatable.
-      if (!$entity->get($field_name)->isEmpty() && !empty($instance['settings']['translation_sync']) && field_is_translatable($entity_type, $field)) {
+      if (!$entity->get($field_name)->isEmpty() && !empty($instance->settings['translation_sync']) && field_is_translatable($entity_type, $field)) {
         // Retrieve all the untranslatable column groups and merge them into
         // single list.
-        $groups = array_keys(array_diff($instance['settings']['translation_sync'], array_filter($instance['settings']['translation_sync'])));
+        $groups = array_keys(array_diff($instance->settings['translation_sync'], array_filter($instance->settings['translation_sync'])));
         if (!empty($groups)) {
           $columns = array();
           foreach ($groups as $group) {
-            $info = $field['settings']['column_groups'][$group];
+            $info = $field->settings['column_groups'][$group];
             // A missing 'columns' key indicates we have a single-column group.
             $columns = array_merge($columns, isset($info['columns']) ? $info['columns'] : array($group));
           }
diff --git a/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationSettingsTest.php b/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationSettingsTest.php
index f4e2f13..d2c8ebf 100644
--- a/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationSettingsTest.php
+++ b/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationSettingsTest.php
@@ -90,7 +90,7 @@ function testSettingsUI() {
     $this->assertSettings('comment', 'comment_node_article', TRUE, $edit);
     field_info_cache_clear();
     $field = field_info_field('comment', 'comment_body');
-    $this->assertTrue($field['translatable'], 'Comment body is translatable.');
+    $this->assertTrue($field->fieldIsTranslatable(), 'Comment body is translatable.');
 
     // Test that language settings are correctly stored.
     $language_configuration = language_get_default_configuration('comment', 'comment_node_article');
diff --git a/core/modules/datetime/datetime.module b/core/modules/datetime/datetime.module
index 0da06cb..9ee20e1 100644
--- a/core/modules/datetime/datetime.module
+++ b/core/modules/datetime/datetime.module
@@ -190,11 +190,11 @@ function datetime_default_value($entity, $field, $instance, $langcode) {
 
   $value = '';
   $date = '';
-  if ($instance['settings']['default_value'] == 'now') {
+  if ($instance->settings['default_value'] == 'now') {
     // A default value should be in the format and timezone used for date
     // storage.
     $date = new DrupalDateTime('now', DATETIME_STORAGE_TIMEZONE);
-    $storage_format = $field['settings']['datetime_type'] == 'date' ? DATETIME_DATE_STORAGE_FORMAT: DATETIME_DATETIME_STORAGE_FORMAT;
+    $storage_format = $field->settings['datetime_type'] == 'date' ? DATETIME_DATE_STORAGE_FORMAT: DATETIME_DATETIME_STORAGE_FORMAT;
     $value = $date->format($storage_format);
   }
 
diff --git a/core/modules/datetime/lib/Drupal/datetime/Tests/DateTimeItemTest.php b/core/modules/datetime/lib/Drupal/datetime/Tests/DateTimeItemTest.php
index f755730..0b4ee54 100644
--- a/core/modules/datetime/lib/Drupal/datetime/Tests/DateTimeItemTest.php
+++ b/core/modules/datetime/lib/Drupal/datetime/Tests/DateTimeItemTest.php
@@ -43,7 +43,7 @@ public function setUp() {
     ));
     $this->field->save();
     $this->instance = entity_create('field_instance', array(
-      'field_name' => $this->field['field_name'],
+      'field_name' => $this->field->getFieldName(),
       'entity_type' => 'entity_test',
       'bundle' => 'entity_test',
       'settings' => array(
diff --git a/core/modules/datetime/lib/Drupal/datetime/Tests/DatetimeFieldTest.php b/core/modules/datetime/lib/Drupal/datetime/Tests/DatetimeFieldTest.php
index 64ba5cd..beff65f 100644
--- a/core/modules/datetime/lib/Drupal/datetime/Tests/DatetimeFieldTest.php
+++ b/core/modules/datetime/lib/Drupal/datetime/Tests/DatetimeFieldTest.php
@@ -163,7 +163,7 @@ function testDateField() {
   function testDatetimeField() {
     $field_name = $this->field->name;
     // Change the field to a datetime field.
-    $this->field['settings']['datetime_type'] = 'datetime';
+    $this->field->settings['datetime_type'] = 'datetime';
     $this->field->save();
 
     // Display creation form.
diff --git a/core/modules/edit/lib/Drupal/edit/Form/EditFieldForm.php b/core/modules/edit/lib/Drupal/edit/Form/EditFieldForm.php
index 6faa0c9..97dfb54 100644
--- a/core/modules/edit/lib/Drupal/edit/Form/EditFieldForm.php
+++ b/core/modules/edit/lib/Drupal/edit/Form/EditFieldForm.php
@@ -114,7 +114,7 @@ protected function buildEntity(array $form, array &$form_state) {
     //   types: http://drupal.org/node/1678002.
     if ($entity->entityType() == 'node' && $entity->isNewRevision() && !isset($entity->log)) {
       $instance = field_info_instance($entity->entityType(), $form_state['field_name'], $entity->bundle());
-      $entity->log = t('Updated the %field-name field through in-place editing.', array('%field-name' => $instance['label']));
+      $entity->log = t('Updated the %field-name field through in-place editing.', array('%field-name' => $instance->label()));
     }
 
     return $entity;
diff --git a/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php b/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php
index 128bc7c..f8b4715 100644
--- a/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php
+++ b/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php
@@ -210,7 +210,7 @@ public function setComponent($name, array $options = array()) {
 
     if ($instance = field_info_instance($this->targetEntityType, $name, $this->bundle)) {
       $field = $instance->getField();
-      $options = $this->pluginManager->prepareConfiguration($field['type'], $options);
+      $options = $this->pluginManager->prepareConfiguration($field->getFieldType(), $options);
 
       // Clear the persisted plugin, if any.
       unset($this->plugins[$name]);
diff --git a/core/modules/entity_reference/entity_reference.module b/core/modules/entity_reference/entity_reference.module
index 10364d8..c075e4e 100644
--- a/core/modules/entity_reference/entity_reference.module
+++ b/core/modules/entity_reference/entity_reference.module
@@ -37,15 +37,15 @@ function entity_reference_field_info_alter(&$info) {
 function entity_reference_entity_field_info_alter(&$info, $entity_type) {
   foreach (field_info_instances($entity_type) as $bundle_name => $instances) {
     foreach ($instances as $field_name => $instance) {
-      $field = $instance->getField();
-      if ($field['type'] != 'entity_reference') {
+      $field = field_info_field($entity_type, $field_name);
+      if ($field->getFieldType() != 'entity_reference') {
         continue;
       }
       if (isset($info['definitions'][$field_name])) {
-        $info['definitions'][$field_name]['settings']['target_type'] = $field['settings']['target_type'];
+        $info['definitions'][$field_name]['settings']['target_type'] = $field->settings['target_type'];
       }
       elseif (isset($info['optional'][$field_name])) {
-        $info['optional'][$field_name]['settings']['target_type'] = $field['settings']['target_type'];
+        $info['optional'][$field_name]['settings']['target_type'] = $field->settings['target_type'];
       }
     }
   }
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/EntityReferenceAutocomplete.php b/core/modules/entity_reference/lib/Drupal/entity_reference/EntityReferenceAutocomplete.php
index 492fa25..8fa080c 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/EntityReferenceAutocomplete.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/EntityReferenceAutocomplete.php
@@ -85,7 +85,7 @@ public function getMatches($field, $instance, $entity_type, $entity_id = '', $pr
 
     if (isset($string)) {
       // Get an array of matching entities.
-      $widget = entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')->getComponent($instance['field_name']);
+      $widget = entity_get_form_display($instance->entity_type, $instance->bundle, 'default')->getComponent($instance->getFieldName());
       $match_operator = !empty($widget['settings']['match_operator']) ? $widget['settings']['match_operator'] : 'CONTAINS';
       $entity_labels = $handler->getReferenceableEntities($string, $match_operator, 10);
 
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/EntityReferenceController.php b/core/modules/entity_reference/lib/Drupal/entity_reference/EntityReferenceController.php
index 426af2c..ce020b1 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/EntityReferenceController.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/EntityReferenceController.php
@@ -77,7 +77,7 @@ public function handleAutocomplete(Request $request, $type, $field_name, $entity
       throw new AccessDeniedHttpException();
     }
 
-    if ($field['type'] != 'entity_reference' || !field_access('edit', $field, $entity_type)) {
+    if ($field->type != 'entity_reference' || !field_access('edit', $field, $entity_type)) {
       throw new AccessDeniedHttpException();
     }
 
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/field_type/ConfigurableEntityReferenceItem.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/field_type/ConfigurableEntityReferenceItem.php
index 786f0da..deaa32c 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/field_type/ConfigurableEntityReferenceItem.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/field_type/ConfigurableEntityReferenceItem.php
@@ -68,8 +68,8 @@ public static function schema(FieldInterface $field) {
 
     // Create a foreign key to the target entity type base type.
     $entity_manager = \Drupal::service('plugin.manager.entity');
-    if (is_subclass_of($entity_manager->getControllerClass($field['settings']['target_type'], 'storage'), 'Drupal\Core\Entity\DatabaseStorageController')) {
-      $entity_info = $entity_manager->getDefinition($field['settings']['target_type']);
+    if (is_subclass_of($entity_manager->getControllerClass($field->settings['target_type'], 'storage'), 'Drupal\Core\Entity\DatabaseStorageController')) {
+      $entity_info = $entity_manager->getDefinition($field->settings['target_type']);
 
       $base_table = $entity_info['base_table'];
       $id_column = $entity_info['entity_keys']['id'];
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionSortTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionSortTest.php
index 6ed2ace..a93300e 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionSortTest.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionSortTest.php
@@ -134,7 +134,7 @@ public function testSort() {
     $this->assertIdentical($result['article'], $expected_result, 'Query sorted by field returned expected values.');
 
     // Assert sort by property.
-    $instance['settings']['handler_settings']['sort'] = array(
+    $instance->settings['handler_settings']['sort'] = array(
       'field' => 'nid',
       'direction' => 'ASC',
     );
diff --git a/core/modules/field/field.attach.inc b/core/modules/field/field.attach.inc
index 29036c7..a46f43f 100644
--- a/core/modules/field/field.attach.inc
+++ b/core/modules/field/field.attach.inc
@@ -128,7 +128,7 @@ function field_invoke_method($method, $target_function, EntityInterface $entity,
 
     if (method_exists($target, $method)) {
       $field = $instance->getField();
-      $field_name = $field['field_name'];
+      $field_name = $field->getFieldName();
 
       // Determine the list of languages to iterate on.
       $available_langcodes = field_available_languages($entity_type, $field);
@@ -217,8 +217,8 @@ function field_invoke_method_multiple($method, $target_function, array $entities
     $entity_instances = _field_invoke_get_instances($entity_type, $entity->bundle(), $options);
 
     foreach ($entity_instances as $instance) {
-      $instance_id = $instance['id'];
-      $field_name = $instance['field_name'];
+      $instance_id = $instance->id();
+      $field_name = $instance->getFieldName();
 
       // Let the closure determine the target object on which the method should
       // be called.
@@ -253,7 +253,7 @@ function field_invoke_method_multiple($method, $target_function, array $entities
 
   // For each instance, invoke the method and collect results.
   foreach ($instances as $instance_id => $instance) {
-    $field_name = $instance['field_name'];
+    $field_name = $instance->getFieldName();
 
     // Iterate over all the field translations.
     foreach ($grouped_items[$instance_id] as $langcode => $items) {
@@ -323,7 +323,7 @@ function _field_invoke_get_instances($entity_type, $bundle, $options) {
       // Single-field mode by field id: we need to loop on each instance to
       // find the right one.
       foreach ($instances as $instance) {
-        if ($instance['field_id'] == $options['field_id']) {
+        if ($instance->getField()->uuid() == $options['field_id']) {
           $instances = array($instance);
           break;
         }
@@ -347,7 +347,7 @@ function _field_invoke_get_instances($entity_type, $bundle, $options) {
  */
 function _field_invoke_widget_target($form_display) {
   return function ($instance) use ($form_display) {
-    return $form_display->getRenderer($instance['field_name']);
+    return $form_display->getRenderer($instance->getFieldName());
   };
 }
 
@@ -371,7 +371,7 @@ function field_attach_preprocess(EntityInterface $entity, $element, &$variables)
   // Ensure we are working with a BC mode entity.
   $entity = $entity->getBCEntity();
   foreach (field_info_instances($entity->entityType(), $entity->bundle()) as $instance) {
-    $field_name = $instance['field_name'];
+    $field_name = $instance->getFieldName();
     if (isset($element[$field_name]['#language'])) {
       $langcode = $element[$field_name]['#language'];
       $variables[$field_name] = isset($entity->{$field_name}[$langcode]) ? $entity->{$field_name}[$langcode] : NULL;
diff --git a/core/modules/field/field.default.inc b/core/modules/field/field.default.inc
new file mode 100644
index 0000000..0bcd490
--- /dev/null
+++ b/core/modules/field/field.default.inc
@@ -0,0 +1,85 @@
+<?php
+
+use Drupal\Core\Entity\EntityInterface;
+
+/**
+ * @file
+ * Default 'implementations' of hook_field_*(): common field housekeeping.
+ *
+ * Those implementations are special, as field.module does not define any field
+ * types. Those functions take care of default stuff common to all field types.
+ * They are called through the _field_invoke_default() iterator, generally in
+ * the corresponding field_attach_[operation]() function.
+ */
+
+use Drupal\Core\Language\Language;
+
+/**
+ * Generic field validation handler.
+ *
+ * Possible error codes:
+ * - 'field_cardinality': The number of values exceeds the field cardinality.
+ *
+ * @see _hook_field_validate()
+ *
+ * @param \Drupal\Core\Entity\EntityInterface $entity
+ *   The entity for the operation.
+ * @param $field
+ *   The field structure for the operation.
+ * @param $instance
+ *   The instance structure for $field in $entity's bundle.
+ * @param $langcode
+ *   The language associated with $items.
+ * @param $items
+ *   $entity->{$field->id()}[$langcode], or an empty array if unset.
+ * @param $errors
+ *   The array of errors, keyed by field name and by value delta, that have
+ *   already been reported for the entity. The function should add its errors to
+ *   this array. Each error is an associative array, with the following keys and
+ *   values:
+ *   - error: An error code (should be a string, prefixed with the module name).
+ *   - message: The human readable message to be displayed.
+ */
+function field_default_validate(EntityInterface $entity, $field, $instance, $langcode, $items, &$errors) {
+  // Filter out empty values.
+  $items = _field_filter_items($field->type, $items);
+
+  // Check that the number of values doesn't exceed the field cardinality.
+  // For form submitted values, this can only happen with 'multiple value'
+  // widgets.
+  if ($field->cardinality != FIELD_CARDINALITY_UNLIMITED && count($items) > $field->cardinality) {
+    $errors[$field->id()][$langcode][0][] = array(
+      'error' => 'field_cardinality',
+      'message' => t('%name: this field cannot hold more than @count values.', array('%name' => $instance->label(), '@count' => $field->cardinality)),
+    );
+  }
+}
+
+/**
+ * Copies source field values into the entity to be prepared.
+ *
+ * @param \Drupal\Core\Entity\EntityInterface $entity
+ *   The entity to be prepared for translation.
+ * @param $field
+ *   The field structure for the operation.
+ * @param $instance
+ *   The instance structure for $field in $entity's bundle.
+ * @param $langcode
+ *   The language the entity has to be translated to.
+ * @param $items
+ *   $entity->{$field->id()}[$langcode], or an empty array if unset.
+ * @param \Drupal\Core\Entity\EntityInterface $source_entity
+ *   The source entity holding the field values to be translated.
+ * @param $source_langcode
+ *   The source language from which to translate.
+ */
+function field_default_prepare_translation(EntityInterface $entity, $field, $instance, $langcode, &$items, EntityInterface $source_entity, $source_langcode) {
+  $field_name = $field->id();
+  // If the field is untranslatable keep using Language::LANGCODE_NOT_SPECIFIED.
+  if ($langcode == Language::LANGCODE_NOT_SPECIFIED) {
+    $source_langcode = Language::LANGCODE_NOT_SPECIFIED;
+  }
+  if (isset($source_entity->{$field_name}[$source_langcode])) {
+    $items = $source_entity->{$field_name}[$source_langcode];
+  }
+}
diff --git a/core/modules/field/field.deprecated.inc b/core/modules/field/field.deprecated.inc
index 25677ac..21bbe09 100644
--- a/core/modules/field/field.deprecated.inc
+++ b/core/modules/field/field.deprecated.inc
@@ -739,8 +739,8 @@ function field_attach_prepare_view($entity_type, array $entities, array $display
   // instance, call the prepareView() method on the formatter object handed by
   // the entity display.
   $target_function = function ($instance) use ($displays) {
-    if (isset($displays[$instance['bundle']])) {
-      return $displays[$instance['bundle']]->getRenderer($instance['field_name']);
+    if (isset($displays[$instance->bundle])) {
+      return $displays[$instance->bundle]->getRenderer($instance->getFieldName());
     }
   };
   $null = NULL;
@@ -785,7 +785,7 @@ function field_attach_view(EntityInterface $entity, EntityDisplay $display, $lan
   // For each instance, call the view() method on the formatter object handed
   // by the entity display.
   $target_function = function ($instance) use ($display) {
-    return $display->getRenderer($instance['field_name']);
+    return $display->getRenderer($instance->getFieldName());
   };
   $null = NULL;
   $output = field_invoke_method('view', $target_function, $entity, $null, $null, $options);
diff --git a/core/modules/field/field.info.inc b/core/modules/field/field.info.inc
index 9bb495c..d5937b4 100644
--- a/core/modules/field/field.info.inc
+++ b/core/modules/field/field.info.inc
@@ -8,6 +8,7 @@
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Language\Language;
 use Drupal\field\Field;
+use Drupal\field\FieldInstanceInterface;
 
 /**
  * @defgroup field_info Field Info API
@@ -50,8 +51,8 @@ function field_info_cache_clear() {
  * @param string $op
  *   The name of the operation. Currently supported: 'default_value',
  *   'multiple_values'.
- * @param array $instance
- *   The field instance array.
+ * @param \Drupal\field\FieldInstanceInterface $instance
+ *   The field instance definition.
  *
  * @return int
  *   One of these values:
@@ -59,9 +60,9 @@ function field_info_cache_clear() {
  *   - FIELD_BEHAVIOR_CUSTOM: Use the widget's callback function.
  *   - FIELD_BEHAVIOR_DEFAULT: Use field.module default behavior.
  */
-function field_behaviors_widget($op, $instance) {
+function field_behaviors_widget($op, FieldInstanceInterface $instance) {
   $info = array();
-  if ($component = entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')->getComponent($instance['field_name'])) {
+  if ($component = entity_get_form_display($instance->entity_type, $instance->bundle, 'default')->getComponent($instance->getFieldName())) {
     $info = \Drupal::service('plugin.manager.field.widget')->getDefinition($component['type']);
   }
   return isset($info[$op]) ? $info[$op] : FIELD_BEHAVIOR_DEFAULT;
diff --git a/core/modules/field/field.module b/core/modules/field/field.module
index 1a673bc..fb07078 100644
--- a/core/modules/field/field.module
+++ b/core/modules/field/field.module
@@ -210,7 +210,7 @@ function field_system_info_alter(&$info, $file, $type) {
       // remains no actual, non-deleted fields)
       $non_deleted = FALSE;
       foreach ($fields as $field) {
-        if (empty($field['deleted'])) {
+        if (empty($field->deleted)) {
           $non_deleted = TRUE;
           break;
         }
@@ -306,7 +306,7 @@ function field_entity_bundle_rename($entity_type, $bundle_old, $bundle_new) {
   $instances = field_read_instances();
   foreach ($instances as $instance) {
     if ($instance->entity_type == $entity_type && $instance->bundle == $bundle_old) {
-      $id_new = $instance['entity_type'] . '.' . $bundle_new . '.' . $instance['field_name'];
+      $id_new = $instance->entity_type . '.' . $bundle_new . '.' . $instance->getFieldName();
       $instance->id = $id_new;
       $instance->bundle = $bundle_new;
       $instance->allowBundleRename();
@@ -708,7 +708,7 @@ function field_view_field(EntityInterface $entity, $field_name, $display_options
     // $display_options, so we cannot let preparation happen internally.
     $field = field_info_field($entity_type, $field_name);
     $formatter_manager = drupal_container()->get('plugin.manager.field.formatter');
-    $display_options = $formatter_manager->prepareConfiguration($field['type'], $display_options);
+    $display_options = $formatter_manager->prepareConfiguration($field->getFieldType(), $display_options);
     $formatter = $formatter_manager->getInstance(array(
       'field_definition' => $instance,
       'view_mode' => $view_mode,
diff --git a/core/modules/field/field.multilingual.inc b/core/modules/field/field.multilingual.inc
index d02595c..f087d7f 100644
--- a/core/modules/field/field.multilingual.inc
+++ b/core/modules/field/field.multilingual.inc
@@ -7,6 +7,7 @@
 
 use Drupal\Core\Language\Language;
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\field\FieldInterface;
 
 /**
  * @defgroup field_language Field Language API
@@ -124,13 +125,13 @@ function field_language_fallback(&$field_langcodes, EntityInterface $entity, $la
  * @return
  *   An array of valid language codes.
  */
-function field_available_languages($entity_type, $field) {
+function field_available_languages($entity_type, FieldInterface $field) {
   static $drupal_static_fast;
   if (!isset($drupal_static_fast)) {
     $drupal_static_fast['field_langcodes'] = &drupal_static(__FUNCTION__);
   }
   $field_langcodes = &$drupal_static_fast['field_langcodes'];
-  $field_name = $field['field_name'];
+  $field_name = $field->getFieldName();
 
   if (!isset($field_langcodes[$entity_type][$field_name])) {
     // If the field has language support enabled we retrieve an (alterable) list
@@ -215,8 +216,8 @@ function field_language_fallback_enabled() {
  * @return
  *   TRUE if the field can be translated.
  */
-function field_is_translatable($entity_type, $field) {
-  return $field['translatable'] && field_has_translation_handler($entity_type);
+function field_is_translatable($entity_type, FieldInterface $field) {
+  return $field->isFieldTranslatable() && field_has_translation_handler($entity_type);
 }
 
 /**
@@ -309,17 +310,17 @@ function field_language(EntityInterface $entity, $field_name = NULL, $langcode =
     // if the field translation is not available. It is up to translation
     // handlers to implement language fallback rules.
     foreach (field_info_instances($entity_type, $bundle) as $instance) {
-      if (isset($entity->{$instance['field_name']}[$langcode])) {
-        $display_langcode[$instance['field_name']] = $langcode;
+      if (isset($entity->{$instance->getFieldName()}[$langcode])) {
+        $display_langcode[$instance->getFieldName()] = $langcode;
       }
       else {
         // If the field has a value for one of the locked languages, then use
         // that language for display. If not, the default one will be
         // Language::LANGCODE_NOT_SPECIFIED.
-        $display_langcode[$instance['field_name']] = Language::LANGCODE_NOT_SPECIFIED;
+        $display_langcode[$instance->getFieldName()] = Language::LANGCODE_NOT_SPECIFIED;
         foreach (language_list(Language::STATE_LOCKED) as $language_locked) {
-          if (isset($entity->{$instance['field_name']}[$language_locked->id])) {
-            $display_langcode[$instance['field_name']] = $language_locked->id;
+          if (isset($entity->{$instance->getFieldName()}[$language_locked->id])) {
+            $display_langcode[$instance->getFieldName()] = $language_locked->id;
             break;
           }
         }
diff --git a/core/modules/field/field.views.inc b/core/modules/field/field.views.inc
index 7e24b44..6835880 100644
--- a/core/modules/field/field.views.inc
+++ b/core/modules/field/field.views.inc
@@ -23,7 +23,7 @@ function field_views_data() {
 
   foreach (field_info_fields() as $field) {
     if (_field_views_is_sql_entity_type($field)) {
-      $result = (array) $module_handler->invoke($field['module'], 'field_views_data', array($field));
+      $result = (array) $module_handler->invoke($field->module, 'field_views_data', array($field));
       if (empty($result)) {
         $result = field_views_field_default_views_data($field);
       }
@@ -49,7 +49,7 @@ function field_views_data() {
 function field_views_data_alter(&$data) {
   foreach (field_info_fields() as $field) {
     if (_field_views_is_sql_entity_type($field)) {
-      $function = $field['module'] . '_field_views_data_views_data_alter';
+      $function = $field->module . '_field_views_data_views_data_alter';
       if (function_exists($function)) {
         $function($data, $field);
       }
@@ -91,8 +91,8 @@ function field_views_field_label($entity_type, $field_name) {
   foreach ($instances as $bundle => $bundle_instances) {
     if (isset($bundle_instances[$field_name])) {
       $instance = $bundle_instances[$field_name];
-      $label_counter[$instance->label] = isset($label_counter[$instance->label]) ? ++$label_counter[$instance->label] : 1;
-      $all_labels[$instance->label] = TRUE;
+      $label_counter[$instance->label()] = isset($label_counter[$instance->label()]) ? ++$label_counter[$instance->label] : 1;
+      $all_labels[$instance->label()] = TRUE;
     }
   }
   if (empty($label_counter)) {
@@ -117,15 +117,16 @@ function field_views_field_default_views_data(FieldInterface $field) {
   $data = array();
 
   // Check the field type is available.
-  if (!\Drupal::service('plugin.manager.entity.field.field_type')->getDefinition($field['type'])) {
+  if (!\Drupal::service('plugin.manager.entity.field.field_type')->getDefinition($field->getFieldType())) {
     return $data;
   }
   // Check the field has instances.
-  if (empty($field['bundles'])) {
+  $field_bundles = $field->getBundles();
+  if (empty($field_bundles)) {
     return $data;
   }
 
-  $field_name = $field['field_name'];
+  $field_name = $field->getFieldName();
 
   // Grab information about the entity type tables.
   $entity_manager = Drupal::entityManager();
@@ -146,13 +147,13 @@ function field_views_field_default_views_data(FieldInterface $field) {
   $field_tables = array(
     FIELD_LOAD_CURRENT => array(
       'table' => DatabaseStorageController::_fieldTableName($field),
-      'alias' => "{$entity_type}__{$field->name}",
+      'alias' => "{$entity_type}__{$field->id()}",
     ),
   );
   if ($supports_revisions) {
     $field_tables[FIELD_LOAD_REVISION] = array(
       'table' => DatabaseStorageController::_fieldRevisionTableName($field),
-      'alias' => "{$entity_type}_revision__{$field->name}",
+      'alias' => "{$entity_type}_revision__{$field->id()}",
     );
   }
 
@@ -182,7 +183,7 @@ function field_views_field_default_views_data(FieldInterface $field) {
   $bundles_names = $field->getBundles();
   // Build the list of additional fields to add to queries.
   $add_fields = array('delta', 'langcode', 'bundle');
-  foreach (array_keys($field['columns']) as $column) {
+  foreach (array_keys($field->getColumns()) as $column) {
     $add_fields[] = DatabaseStorageController::_fieldColumnName($field, $column);
   }
   // Determine the label to use for the field. We don't have a label available
@@ -242,7 +243,7 @@ function field_views_field_default_views_data(FieldInterface $field) {
       $data[$table_alias][$field_alias]['help'] .= ' ' . t('Also known as: !also.', array('!also' => implode(', ', $also_known)));
     }
 
-    $keys = array_keys($field['columns']);
+    $keys = array_keys($field->getColumns());
     $real_field = reset($keys);
     $data[$table_alias][$field_alias]['field'] = array(
       'table' => $table,
@@ -260,7 +261,7 @@ function field_views_field_default_views_data(FieldInterface $field) {
   }
 
   // Expose data for each field property individually.
-  foreach ($field['columns'] as $column => $attributes) {
+  foreach ($field->getColumns() as $column => $attributes) {
     $allow_sort = TRUE;
 
     // Identify likely filters and arguments for each column based on field type.
@@ -287,7 +288,7 @@ function field_views_field_default_views_data(FieldInterface $field) {
         break;
     }
 
-    if (count($field['columns']) == 1 || $column == 'value') {
+    if (count($field->getColumns()) == 1 || $column == 'value') {
       $title = t('@label (!name)', array('@label' => $label, '!name' => $field_name));
       $title_short = $label;
     }
@@ -375,7 +376,7 @@ function field_views_field_default_views_data(FieldInterface $field) {
       }
 
       // Expose additional delta column for multiple value fields.
-      if ($field['cardinality'] > 1 || $field['cardinality'] == FIELD_CARDINALITY_UNLIMITED) {
+      if ($field->getFieldCardinality() > 1 || $field->getFieldCardinality() == FIELD_CARDINALITY_UNLIMITED) {
         $title_delta = t('@label (!name:delta)', array('@label' => $label, '!name' => $field_name));
         $title_short_delta = t('@label:delta', array('@label' => $label));
 
@@ -417,7 +418,7 @@ function field_views_field_default_views_data(FieldInterface $field) {
       }
 
       // Expose additional language column for translatable fields.
-      if (!empty($field['translatable'])) {
+      if ($field->isFieldTranslatable()) {
         $title_language = t('@label (!name:language)', array('@label' => $label, '!name' => $field_name));
         $title_short_language = t('@label:language', array('@label' => $label));
 
diff --git a/core/modules/field/lib/Drupal/field/Entity/Field.php b/core/modules/field/lib/Drupal/field/Entity/Field.php
index 3421461..fc3b5dc 100644
--- a/core/modules/field/lib/Drupal/field/Entity/Field.php
+++ b/core/modules/field/lib/Drupal/field/Entity/Field.php
@@ -454,7 +454,7 @@ public function delete() {
   /**
    * {@inheritdoc}
    */
-  public function getSchema() {
+  public function getSchema($key = '') {
     if (!isset($this->schema)) {
       // Get the schema from the field item class.
       $definition = \Drupal::service('plugin.manager.entity.field.field_type')->getDefinition($this->type);
@@ -475,6 +475,10 @@ public function getSchema() {
       $this->schema = $schema;
     }
 
+    if (!empty($key)) {
+      return $this->schema[$key];
+    }
+
     return $this->schema;
   }
 
@@ -602,58 +606,6 @@ public function isFieldRequired() {
   public function getFieldDefaultValue(EntityInterface $entity) { }
 
   /**
-   * {@inheritdoc}
-   */
-  public function offsetExists($offset) {
-    return isset($this->{$offset}) || in_array($offset, array('columns', 'foreign keys', 'bundles', 'storage_details'));
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function &offsetGet($offset) {
-    switch ($offset) {
-      case 'id':
-        return $this->uuid;
-
-      case 'field_name':
-        return $this->name;
-
-      case 'columns':
-        $this->getSchema();
-        return $this->schema['columns'];
-
-      case 'foreign keys':
-        $this->getSchema();
-        return $this->schema['foreign keys'];
-
-      case 'bundles':
-        $bundles = $this->getBundles();
-        return $bundles;
-    }
-
-    return $this->{$offset};
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function offsetSet($offset, $value) {
-    if (!in_array($offset, array('columns', 'foreign keys', 'bundles', 'storage_details'))) {
-      $this->{$offset} = $value;
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function offsetUnset($offset) {
-    if (!in_array($offset, array('columns', 'foreign keys', 'bundles', 'storage_details'))) {
-      unset($this->{$offset});
-    }
-  }
-
-  /**
    * A list of columns that can not be used as field type columns.
    *
    * @return array
diff --git a/core/modules/field/lib/Drupal/field/Entity/FieldInstance.php b/core/modules/field/lib/Drupal/field/Entity/FieldInstance.php
index eaa0c70..f15b71a 100644
--- a/core/modules/field/lib/Drupal/field/Entity/FieldInstance.php
+++ b/core/modules/field/lib/Drupal/field/Entity/FieldInstance.php
@@ -603,46 +603,6 @@ public function allowBundleRename() {
   }
 
   /**
-   * {@inheritdoc}
-   */
-  public function offsetExists($offset) {
-    return (isset($this->{$offset}) || $offset == 'field_id' || $offset == 'field_name');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function &offsetGet($offset) {
-    if ($offset == 'field_id') {
-      return $this->field_uuid;
-    }
-    if ($offset == 'field_name') {
-      return $this->field->name;
-    }
-    return $this->{$offset};
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function offsetSet($offset, $value) {
-    if ($offset == 'field_id') {
-      $offset = 'field_uuid';
-    }
-    $this->{$offset} = $value;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function offsetUnset($offset) {
-    if ($offset == 'field_id') {
-      $offset = 'field_uuid';
-    }
-    unset($this->{$offset});
-  }
-
-  /**
    * Implements the magic __sleep() method.
    *
    * Using the Serialize interface and serialize() / unserialize() methods
@@ -663,4 +623,4 @@ public function __wakeup() {
     $this->__construct($values);
   }
 
-}
+}
\ No newline at end of file
diff --git a/core/modules/field/lib/Drupal/field/FieldInfo.php b/core/modules/field/lib/Drupal/field/FieldInfo.php
index 8d6bc3a..114744c 100644
--- a/core/modules/field/lib/Drupal/field/FieldInfo.php
+++ b/core/modules/field/lib/Drupal/field/FieldInfo.php
@@ -11,6 +11,8 @@
 use Drupal\Core\Config\ConfigFactory;
 use Drupal\Core\Entity\Field\FieldTypePluginManager;
 use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\field\FieldInterface;
+use Drupal\field\FieldInstanceInterface;
 
 /**
  * Provides field and instance definitions for the current runtime environment.
@@ -234,7 +236,7 @@ public function getFields() {
     else {
       // Collect and prepare fields.
       foreach (field_read_fields(array(), array('include_deleted' => TRUE)) as $field) {
-        $this->fieldsById[$field['uuid']] = $this->prepareField($field);
+        $this->fieldsById[$field->uuid()] = $this->prepareField($field);
       }
 
       // Store in persistent cache.
@@ -243,8 +245,8 @@ public function getFields() {
 
     // Fill the name/ID map.
     foreach ($this->fieldsById as $field) {
-      if (!$field['deleted']) {
-        $this->fieldIdsByName[$field->entity_type][$field->name] = $field['uuid'];
+      if (!$field->deleted) {
+        $this->fieldIdsByName[$field->entity_type][$field->getFieldName()] = $field->uuid();
       }
     }
 
@@ -280,9 +282,9 @@ public function getInstances($entity_type = NULL) {
         $this->getFields();
 
         foreach (field_read_instances() as $instance) {
-          $field = $this->getField($instance['entity_type'], $instance['field_name']);
-          $instance = $this->prepareInstance($instance, $field['type']);
-          $this->bundleInstances[$instance['entity_type']][$instance['bundle']][$instance['field_name']] = $instance;
+          $field = $this->getField($instance->entity_type, $instance->getFieldName());
+          $instance = $this->prepareInstance($instance, $field->getFieldType());
+          $this->bundleInstances[$instance->entity_type][$instance->bundle][$instance->getFieldName()] = $instance;
         }
 
         // Store in persistent cache.
@@ -330,8 +332,8 @@ public function getField($entity_type, $field_name) {
       $field = $this->prepareField($field);
 
       // Save in the "static" cache.
-      $this->fieldsById[$field['uuid']] = $field;
-      $this->fieldIdsByName[$entity_type][$field_name] = $field['uuid'];
+      $this->fieldsById[$field->uuid()] = $field;
+      $this->fieldIdsByName[$entity_type][$field_name] = $field->uuid();
 
       return $field;
     }
@@ -369,9 +371,9 @@ public function getFieldById($field_id) {
       $field = $this->prepareField($field);
 
       // Store in the static cache.
-      $this->fieldsById[$field['uuid']] = $field;
-      if (!$field['deleted']) {
-        $this->fieldIdsByName[$field->entity_type][$field->name] = $field['uuid'];
+      $this->fieldsById[$field->uuid()] = $field;
+      if (!$field->deleted) {
+        $this->fieldIdsByName[$field->entity_type][$field->getFieldName()] = $field->uuid();
       }
 
       return $field;
@@ -412,10 +414,10 @@ public function getBundleInstances($entity_type, $bundle) {
 
       // Extract the field definitions and save them in the "static" cache.
       foreach ($fields as $field) {
-        if (!isset($this->fieldsById[$field['uuid']])) {
-          $this->fieldsById[$field['uuid']] = $field;
-          if (!$field['deleted']) {
-            $this->fieldIdsByName[$field->entity_type][$field->name] = $field['uuid'];
+        if (!isset($this->fieldsById[$field->uuid()])) {
+          $this->fieldsById[$field->uuid()] = $field;
+          if (!$field->deleted) {
+            $this->fieldIdsByName[$field->entity_type][$field->getFieldName()] = $field->uuid();
           }
         }
       }
@@ -459,14 +461,14 @@ public function getBundleInstances($entity_type, $bundle) {
         // Place the fields in our global "static".
         $loaded_fields = entity_load_multiple('field_entity', array_keys($config_ids));
         foreach ($loaded_fields as $field) {
-          if (!isset($this->fieldsById[$field['uuid']])) {
+          if (!isset($this->fieldsById[$field->uuid()])) {
             $field = $this->prepareField($field);
 
-            $this->fieldsById[$field['uuid']] = $field;
-            $this->fieldIdsByName[$field->entity_type][$field->name] = $field['uuid'];
+            $this->fieldsById[$field->uuid()] = $field;
+            $this->fieldIdsByName[$field->entity_type][$field->getFieldName()] = $field->uuid();
           }
 
-          $fields[] = $this->fieldsById[$field['uuid']];
+          $fields[] = $this->fieldsById[$field->uuid()];
         }
 
         // Then collect the instances.
@@ -474,8 +476,8 @@ public function getBundleInstances($entity_type, $bundle) {
         foreach ($loaded_instances as $instance) {
           $field = $instance->getField();
 
-          $instance = $this->prepareInstance($instance, $field['type']);
-          $instances[$field['field_name']] = $instance;
+          $instance = $this->prepareInstance($instance, $field->getFieldType());
+          $instances[$field->getFieldName()] = $instance;
         }
       }
     }
@@ -569,9 +571,9 @@ public function getBundleExtraFields($entity_type, $bundle) {
    * @return
    *   The field definition completed for the current runtime context.
    */
-  public function prepareField($field) {
+  public function prepareField(FieldInterface $field) {
     // Make sure all expected field settings are present.
-    $field['settings'] += $this->fieldTypeManager->getDefaultSettings($field['type']);
+    $field->settings += $this->fieldTypeManager->getDefaultSettings($field->getFieldType());
 
     return $field;
   }
@@ -579,21 +581,21 @@ public function prepareField($field) {
   /**
    * Prepares an instance definition for the current run-time context.
    *
-   * @param $instance
-   *   The raw instance structure as read from the database.
+   * @param \Drupal\field\FieldInstanceInterface $instance
+   *   The instance definition.
    * @param $field_type
    *   The field type.
    *
    * @return
    *   The field instance array completed for the current runtime context.
    */
-  public function prepareInstance($instance, $field_type) {
+  public function prepareInstance(FieldInstanceInterface $instance, $field_type) {
     // Make sure all expected instance settings are present.
-    $instance['settings'] += $this->fieldTypeManager->getDefaultInstanceSettings($field_type);
+    $instance->settings += $this->fieldTypeManager->getDefaultInstanceSettings($field_type);
 
     // Set a default value for the instance.
-    if (field_behaviors_widget('default value', $instance) == FIELD_BEHAVIOR_DEFAULT && !isset($instance['default_value'])) {
-      $instance['default_value'] = NULL;
+    if (field_behaviors_widget('default value', $instance) == FIELD_BEHAVIOR_DEFAULT && !isset($instance->default_value)) {
+      $instance->default_value = NULL;
     }
 
     return $instance;
diff --git a/core/modules/field/lib/Drupal/field/FieldInstanceInterface.php b/core/modules/field/lib/Drupal/field/FieldInstanceInterface.php
index 318bf4f..d9da54c 100644
--- a/core/modules/field/lib/Drupal/field/FieldInstanceInterface.php
+++ b/core/modules/field/lib/Drupal/field/FieldInstanceInterface.php
@@ -13,7 +13,7 @@
 /**
  * Provides an interface defining a field instance entity.
  */
-interface FieldInstanceInterface extends ConfigEntityInterface, FieldDefinitionInterface, \ArrayAccess {
+interface FieldInstanceInterface extends ConfigEntityInterface, FieldDefinitionInterface {
 
   /**
    * Returns the field entity for this instance.
@@ -24,6 +24,14 @@
   public function getField();
 
   /**
+   * Returns the field type from the field for this instance.
+   *
+   * @return $type
+   *   The field type.
+   */
+  public function getFieldType();
+
+  /**
    * Allows a bundle to be renamed.
    *
    * Renaming a bundle on the instance is allowed when an entity's bundle
diff --git a/core/modules/field/lib/Drupal/field/FieldInterface.php b/core/modules/field/lib/Drupal/field/FieldInterface.php
index 2a03aab..7b992ba 100644
--- a/core/modules/field/lib/Drupal/field/FieldInterface.php
+++ b/core/modules/field/lib/Drupal/field/FieldInterface.php
@@ -13,11 +13,14 @@
 /**
  * Provides an interface defining a field entity.
  */
-interface FieldInterface extends ConfigEntityInterface, FieldDefinitionInterface, \ArrayAccess {
+interface FieldInterface extends ConfigEntityInterface, FieldDefinitionInterface {
 
   /**
    * Returns the field schema.
    *
+   * @param string $key
+   *   (optional) A key corresponding to one of the keys in the schema array.
+   *
    * @return array
    *   The field schema, as an array of key/value pairs in the format returned
    *   by hook_field_schema():
@@ -31,7 +34,7 @@
    *     however, that depending on the storage backend specified for the field,
    *     the field data is not necessarily stored in SQL.
    */
-  public function getSchema();
+  public function getSchema($key = '');
 
   /**
    * Returns the field columns, as defined in the field schema.
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php
index 4cf4556..1a54f32 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php
@@ -48,7 +48,6 @@
    */
   public function __construct($plugin_id, array $plugin_definition, FieldDefinitionInterface $field_definition, array $settings) {
     parent::__construct(array(), $plugin_id, $plugin_definition);
-
     $this->fieldDefinition = $field_definition;
     $this->settings = $settings;
   }
diff --git a/core/modules/field/lib/Drupal/field/Tests/BulkDeleteTest.php b/core/modules/field/lib/Drupal/field/Tests/BulkDeleteTest.php
index 0baa951..d015ffa 100644
--- a/core/modules/field/lib/Drupal/field/Tests/BulkDeleteTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/BulkDeleteTest.php
@@ -143,7 +143,7 @@ function setUp() {
       for ($i = 0; $i < 10; $i++) {
         $entity = entity_create($this->entity_type, array('type' => $bundle));
         foreach ($this->fields as $field) {
-          $entity->{$field['field_name']}->setValue($this->_generateTestFieldValues($field->cardinality));
+          $entity->{$field->getFieldName()}->setValue($this->_generateTestFieldValues($field->getFieldCardinality()));
         }
         $entity->save();
       }
@@ -183,7 +183,7 @@ function testDeleteFieldInstance() {
     $instances = field_read_instances(array('field_id' => $field->uuid, 'deleted' => TRUE), array('include_deleted' => TRUE, 'include_inactive' => TRUE));
     $this->assertEqual(count($instances), 1, 'There is one deleted instance');
     $instance = $instances[0];
-    $this->assertEqual($instance['bundle'], $bundle, 'The deleted instance is for the correct bundle');
+    $this->assertEqual($instance->bundle, $bundle, 'The deleted instance is for the correct bundle');
 
     // Check that the actual stored content did not change during delete.
     $schema = DatabaseStorageController::_fieldSqlSchema($field);
diff --git a/core/modules/field/lib/Drupal/field/Tests/CrudTest.php b/core/modules/field/lib/Drupal/field/Tests/CrudTest.php
index 7578ed2..951425e 100644
--- a/core/modules/field/lib/Drupal/field/Tests/CrudTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/CrudTest.php
@@ -310,18 +310,18 @@ function testDeleteField() {
 
     // Test that the first field is not deleted, and then delete it.
     $field = field_read_field('entity_test', $this->field['name'], array('include_deleted' => TRUE));
-    $this->assertTrue(!empty($field) && empty($field['deleted']), 'A new field is not marked for deletion.');
+    $this->assertTrue(!empty($field) && empty($field->deleted), 'A new field is not marked for deletion.');
     field_info_field('entity_test', $this->field['name'])->delete();
 
     // Make sure that the field is marked as deleted when it is specifically
     // loaded.
     $field = field_read_field('entity_test', $this->field['name'], array('include_deleted' => TRUE));
-    $this->assertTrue(!empty($field['deleted']), 'A deleted field is marked for deletion.');
+    $this->assertTrue(!empty($field->deleted), 'A deleted field is marked for deletion.');
 
     // Make sure that this field's instance is marked as deleted when it is
     // specifically loaded.
     $instance = field_read_instance('entity_test', $this->instance_definition['field_name'], $this->instance_definition['bundle'], array('include_deleted' => TRUE));
-    $this->assertTrue(!empty($instance['deleted']), 'An instance for a deleted field is marked for deletion.');
+    $this->assertTrue(!empty($instance->deleted), 'An instance for a deleted field is marked for deletion.');
 
     // Try to load the field normally and make sure it does not show up.
     $field = field_read_field('entity_test', $this->field['name']);
@@ -333,18 +333,18 @@ function testDeleteField() {
 
     // Make sure the other field (and its field instance) are not deleted.
     $another_field = field_read_field('entity_test', $this->another_field['name']);
-    $this->assertTrue(!empty($another_field) && empty($another_field['deleted']), 'A non-deleted field is not marked for deletion.');
+    $this->assertTrue(!empty($another_field) && empty($another_field->deleted), 'A non-deleted field is not marked for deletion.');
     $another_instance = field_read_instance('entity_test', $another_instance_definition['field_name'], $another_instance_definition['bundle']);
-    $this->assertTrue(!empty($another_instance) && empty($another_instance['deleted']), 'An instance of a non-deleted field is not marked for deletion.');
+    $this->assertTrue(!empty($another_instance) && empty($another_instance->deleted), 'An instance of a non-deleted field is not marked for deletion.');
 
     // Try to create a new field the same name as a deleted field and
     // write data into it.
     entity_create('field_entity', $this->field)->save();
     entity_create('field_instance', $this->instance_definition)->save();
     $field = field_read_field('entity_test', $this->field['name']);
-    $this->assertTrue(!empty($field) && empty($field['deleted']), 'A new field with a previously used name is created.');
+    $this->assertTrue(!empty($field) && empty($field->deleted), 'A new field with a previously used name is created.');
     $instance = field_read_instance('entity_test', $this->instance_definition['field_name'], $this->instance_definition['bundle']);
-    $this->assertTrue(!empty($instance) && empty($instance['deleted']), 'A new instance for a previously used field name is created.');
+    $this->assertTrue(!empty($instance) && empty($instance->deleted), 'A new instance for a previously used field name is created.');
 
     // Save an entity with data for the field
     $entity = entity_create('entity_test', array());
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldImportChangeTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldImportChangeTest.php
index 6e4b8b8..5c686be 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldImportChangeTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldImportChangeTest.php
@@ -52,7 +52,7 @@ function testImportChange() {
 
     // Check that the updated config was correctly imported.
     $instance = entity_load('field_instance', $instance_id);
-    $this->assertEqual($instance['label'], $new_label, 'Instance label updated');
+    $this->assertEqual($instance->label, $new_label, 'Instance label updated');
   }
 }
 
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php
index 8c4afcc..cf45bcc 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php
@@ -51,7 +51,7 @@ function setUp() {
     $this->field = entity_create('field_entity', $this->field_definition);
     $this->field->save();
     $this->instance_definition = array(
-      'field_name' => $this->field->name,
+      'field_name' => $this->field->getFieldName(),
       'entity_type' => 'entity_test',
       'bundle' => 'entity_test',
     );
@@ -115,9 +115,9 @@ function testReadFieldInstance() {
 
     // Read the instance back.
     $instance = field_read_instance('entity_test', $this->instance_definition['field_name'], $this->instance_definition['bundle']);
-    $this->assertTrue($this->instance_definition['field_name'] == $instance['field_name'], 'The field was properly read.');
-    $this->assertTrue($this->instance_definition['entity_type'] == $instance['entity_type'], 'The field was properly read.');
-    $this->assertTrue($this->instance_definition['bundle'] == $instance['bundle'], 'The field was properly read.');
+    $this->assertTrue($this->instance_definition['field_name'] == $instance->getFieldName(), 'The field was properly read.');
+    $this->assertTrue($this->instance_definition['entity_type'] == $instance->entity_type, 'The field was properly read.');
+    $this->assertTrue($this->instance_definition['bundle'] == $instance->bundle, 'The field was properly read.');
   }
 
   /**
@@ -128,16 +128,16 @@ function testUpdateFieldInstance() {
 
     // Check that basic changes are saved.
     $instance = field_read_instance('entity_test', $this->instance_definition['field_name'], $this->instance_definition['bundle']);
-    $instance['required'] = !$instance['required'];
-    $instance['label'] = $this->randomName();
-    $instance['description'] = $this->randomName();
-    $instance['settings']['test_instance_setting'] = $this->randomName();
+    $instance->required = !$instance->required;
+    $instance->label = $this->randomName();
+    $instance->description = $this->randomName();
+    $instance->settings['test_instance_setting'] = $this->randomName();
     $instance->save();
 
     $instance_new = field_read_instance('entity_test', $this->instance_definition['field_name'], $this->instance_definition['bundle']);
-    $this->assertEqual($instance['required'], $instance_new['required'], '"required" change is saved');
-    $this->assertEqual($instance['label'], $instance_new['label'], '"label" change is saved');
-    $this->assertEqual($instance['description'], $instance_new['description'], '"description" change is saved');
+    $this->assertEqual($instance->required, $instance_new->required, '"required" change is saved');
+    $this->assertEqual($instance->label(), $instance_new->label, '"label" change is saved');
+    $this->assertEqual($instance->description, $instance_new->description, '"description" change is saved');
 
     // TODO: test failures.
   }
@@ -159,13 +159,13 @@ function testDeleteFieldInstance() {
 
     // Test that the first instance is not deleted, and then delete it.
     $instance = field_read_instance('entity_test', $this->instance_definition['field_name'], $this->instance_definition['bundle'], array('include_deleted' => TRUE));
-    $this->assertTrue(!empty($instance) && empty($instance['deleted']), 'A new field instance is not marked for deletion.');
+    $this->assertTrue(!empty($instance) && empty($instance->deleted), 'A new field instance is not marked for deletion.');
     $instance->delete();
 
     // Make sure the instance is marked as deleted when the instance is
     // specifically loaded.
     $instance = field_read_instance('entity_test', $this->instance_definition['field_name'], $this->instance_definition['bundle'], array('include_deleted' => TRUE));
-    $this->assertTrue(!empty($instance['deleted']), 'A deleted field instance is marked for deletion.');
+    $this->assertTrue(!empty($instance->deleted), 'A deleted field instance is marked for deletion.');
 
     // Try to load the instance normally and make sure it does not show up.
     $instance = field_read_instance('entity_test', $this->instance_definition['field_name'], $this->instance_definition['bundle']);
@@ -173,13 +173,13 @@ function testDeleteFieldInstance() {
 
     // Make sure the other field instance is not deleted.
     $another_instance = field_read_instance('entity_test', $another_instance_definition['field_name'], $another_instance_definition['bundle']);
-    $this->assertTrue(!empty($another_instance) && empty($another_instance['deleted']), 'A non-deleted field instance is not marked for deletion.');
+    $this->assertTrue(!empty($another_instance) && empty($another_instance->deleted), 'A non-deleted field instance is not marked for deletion.');
 
     // Make sure the field is deleted when its last instance is deleted.
     $another_instance->delete();
     $deleted_fields = \Drupal::state()->get('field.field.deleted');
-    $this->assertTrue(isset($deleted_fields[$another_instance['field_id']]), 'A deleted field is marked for deletion.');
-    $field = field_read_field($another_instance['entity_type'], $another_instance['field_name']);
+    $this->assertTrue(isset($deleted_fields[$another_instance->getField()->uuid()]), 'A deleted field is marked for deletion.');
+    $field = field_read_field($another_instance->entity_type, $another_instance->getFieldName());
     $this->assertFalse($field, 'The field marked to be deleted is not found anymore in the configuration.');
   }
 
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldUnitTestBase.php b/core/modules/field/lib/Drupal/field/Tests/FieldUnitTestBase.php
index 7ff7c9d..643602d 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldUnitTestBase.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldUnitTestBase.php
@@ -72,7 +72,7 @@ function createFieldWithInstance($suffix = '', $entity_type = 'entity_test', $bu
       'cardinality' => 4,
     ));
     $this->$field->save();
-    $this->$field_id = $this->{$field}['uuid'];
+    $this->$field_id = $this->{$field}->uuid;
     $this->$instance_definition = array(
       'field_name' => $this->$field_name,
       'entity_type' => $entity_type,
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldValidationTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldValidationTest.php
index 3dd2e32..df98b0c 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldValidationTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldValidationTest.php
@@ -54,14 +54,14 @@ function testCardinalityConstraint() {
     // Check that the expected constraint violations are reported.
     $this->assertEqual(count($violations), 1);
     $this->assertEqual($violations[0]->getPropertyPath(), '');
-    $this->assertEqual($violations[0]->getMessage(), t('%name: this field cannot hold more than @count values.', array('%name' => $this->instance['label'], '@count' => $cardinality)));
+    $this->assertEqual($violations[0]->getMessage(), t('%name: this field cannot hold more than @count values.', array('%name' => $this->instance->label(), '@count' => $cardinality)));
   }
 
   /**
    * Tests that constraints defined by the field type are validated.
    */
   function testFieldConstraints() {
-    $cardinality = $this->field->cardinality;
+    $cardinality = $this->field->getFieldCardinality();
     $entity = $this->entity;
 
     // The test is only valid if the field cardinality is greater than 2.
@@ -76,7 +76,7 @@ function testFieldConstraints() {
       }
       else {
         $value = -1;
-        $expected_violations[$delta . '.value'][] = t('%name does not accept the value -1.', array('%name' => $this->instance['label']));
+        $expected_violations[$delta . '.value'][] = t('%name does not accept the value -1.', array('%name' => $this->instance->label()));
       }
       $entity->{$this->field_name}->offsetGet($delta)->set('value', $value);
     }
diff --git a/core/modules/field/lib/Drupal/field/Tests/FormTest.php b/core/modules/field/lib/Drupal/field/Tests/FormTest.php
index 4ad739a..3628253 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FormTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FormTest.php
@@ -603,8 +603,8 @@ function testFieldFormHiddenWidget() {
     entity_create('field_entity', $field)->save();
     $this->instance = entity_create('field_instance', $this->instance);
     $this->instance->save();
-    entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
-      ->setComponent($this->instance['field_name'], array(
+    entity_get_form_display($this->instance->entity_type, $this->instance->bundle, 'default')
+      ->setComponent($this->instance->getFieldName(), array(
         'type' => 'hidden',
       ))
       ->save();
@@ -625,10 +625,10 @@ function testFieldFormHiddenWidget() {
 
     // Update the instance to remove the default value and switch to the
     // default widget.
-    $this->instance['default_value'] = NULL;
+    $this->instance->default_value = NULL;
     $this->instance->save();
-    entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
-      ->setComponent($this->instance['field_name'], array(
+    entity_get_form_display($this->instance->entity_type, $this->instance->bundle, 'default')
+      ->setComponent($this->instance->getFieldName(), array(
         'type' => 'test_field_widget',
       ))
       ->save();
@@ -647,8 +647,8 @@ function testFieldFormHiddenWidget() {
     $this->assertEqual($entity->{$field_name}->value, $value, 'Field value was updated');
 
     // Update the form display and switch to the Hidden widget again.
-    entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
-      ->setComponent($this->instance['field_name'], array(
+    entity_get_form_display($this->instance->entity_type, $this->instance->bundle, 'default')
+      ->setComponent($this->instance->getFieldName(), array(
         'type' => 'hidden',
       ))
       ->save();
diff --git a/core/modules/field/lib/Drupal/field/Tests/TranslationTest.php b/core/modules/field/lib/Drupal/field/Tests/TranslationTest.php
index 0830af4..f660c6e 100644
--- a/core/modules/field/lib/Drupal/field/Tests/TranslationTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/TranslationTest.php
@@ -154,13 +154,13 @@ function testTranslatableFieldSaveLoad() {
     // Prepare the field translations.
     $entity_type = 'entity_test';
     field_test_entity_info_translatable($entity_type, TRUE);
-    $entity = entity_create($entity_type, array('type' => $this->instance['bundle']));
+    $entity = entity_create($entity_type, array('type' => $this->instance->bundle));
     $field_translations = array();
     $available_langcodes = field_available_languages($entity_type, $this->field);
     $this->assertTrue(count($available_langcodes) > 1, 'Field is translatable.');
     $entity->langcode->value = reset($available_langcodes);
     foreach ($available_langcodes as $langcode) {
-      $field_translations[$langcode] = $this->_generateTestFieldValues($this->field['cardinality']);
+      $field_translations[$langcode] = $this->_generateTestFieldValues($this->field->getFieldCardinality());
       $entity->getTranslation($langcode)->{$this->field_name}->setValue($field_translations[$langcode]);
     }
 
@@ -194,10 +194,10 @@ function testTranslatableFieldSaveLoad() {
     asort($translation_langcodes);
     $translation_langcodes = array_values($translation_langcodes);
 
-    $values = array('type' => $instance['bundle'], 'langcode' => $translation_langcodes[0]);
+    $values = array('type' => $instance->bundle, 'langcode' => $translation_langcodes[0]);
     $entity = entity_create($entity_type, $values);
     foreach ($translation_langcodes as $langcode) {
-      $values[$this->field_name][$langcode] = $this->_generateTestFieldValues($this->field['cardinality']);
+      $values[$this->field_name][$langcode] = $this->_generateTestFieldValues($this->field->getFieldCardinality());
       $entity->getTranslation($langcode, FALSE)->{$this->field_name}->setValue($values[$this->field_name][$langcode]);
     }
 
@@ -212,10 +212,10 @@ function testTranslatableFieldSaveLoad() {
 
     // Check that explicit empty values are not overridden with default values.
     foreach (array(NULL, array()) as $empty_items) {
-      $values = array('type' => $instance['bundle'], 'langcode' => $translation_langcodes[0]);
+      $values = array('type' => $instance->bundle, 'langcode' => $translation_langcodes[0]);
       $entity = entity_create($entity_type, $values);
       foreach ($translation_langcodes as $langcode) {
-        $values[$this->field_name][$langcode] = $this->_generateTestFieldValues($this->field['cardinality']);
+        $values[$this->field_name][$langcode] = $this->_generateTestFieldValues($this->field->getFieldCardinality());
         $entity->getTranslation($langcode)->{$this->field_name}->setValue($values[$this->field_name][$langcode]);
         $entity->getTranslation($langcode)->{$field_name_default}->setValue($empty_items);
         $values[$field_name_default][$langcode] = $empty_items;
@@ -253,9 +253,9 @@ function testFieldDisplayLanguage() {
     entity_create('field_instance', $instance)->save();
 
     $enabled_langcodes = field_content_languages();
-    $entity = entity_create($entity_type, array('id' => 1, 'revision_id' => 1, 'type' => $this->instance['bundle']));;
+    $entity = entity_create($entity_type, array('id' => 1, 'revision_id' => 1, 'type' => $this->instance->bundle));;
     $entity->langcode->value = reset($enabled_langcodes);
-    $instances = field_info_instances($entity_type, $this->instance['bundle']);
+    $instances = field_info_instances($entity_type, $this->instance->bundle);
 
     $langcodes = array();
     // This array is used to store, for each field name, which one of the locked
@@ -265,7 +265,7 @@ function testFieldDisplayLanguage() {
     // Generate field translations for languages different from the first
     // enabled.
     foreach ($instances as $instance) {
-      $field_name = $instance['field_name'];
+      $field_name = $instance->getFieldName();
       $field = $instance->getField();
       do {
         // Index 0 is reserved for the requested language, this way we ensure
@@ -274,7 +274,7 @@ function testFieldDisplayLanguage() {
       }
       while (isset($langcodes[$langcode]));
       $langcodes[$langcode] = TRUE;
-      $entity->getTranslation($langcode)->{$field_name}->setValue($this->_generateTestFieldValues($field['cardinality']));
+      $entity->getTranslation($langcode)->{$field_name}->setValue($this->_generateTestFieldValues($field->getFieldCardinality()));
       // If the langcode is one of the locked languages, then that one
       // will also be used for display. Otherwise, the default one should be
       // used, which is Language::LANGCODE_NOT_SPECIFIED.
@@ -292,7 +292,7 @@ function testFieldDisplayLanguage() {
     $requested_langcode = $enabled_langcodes[0];
     $display_langcodes = field_language($entity, NULL, $requested_langcode);
     foreach ($instances as $instance) {
-      $field_name = $instance['field_name'];
+      $field_name = $instance->getFieldName();
       $this->assertTrue($display_langcodes[$field_name] == $locked_languages[$field_name], format_string('The display language for field %field_name is %language.', array('%field_name' => $field_name, '%language' => $locked_languages[$field_name])));
     }
 
@@ -301,7 +301,7 @@ function testFieldDisplayLanguage() {
     drupal_static_reset('field_language');
     $display_langcodes = field_language($entity, NULL, $requested_langcode);
     foreach ($instances as $instance) {
-      $field_name = $instance['field_name'];
+      $field_name = $instance->getFieldName();
       $langcode = $display_langcodes[$field_name];
       // As the requested language was not assinged to any field, if the
       // returned language is defined for the current field, core fallback rules
diff --git a/core/modules/field/lib/Drupal/field/Tests/TranslationWebTest.php b/core/modules/field/lib/Drupal/field/Tests/TranslationWebTest.php
index d4b95da..0dfd9fe 100644
--- a/core/modules/field/lib/Drupal/field/Tests/TranslationWebTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/TranslationWebTest.php
@@ -106,7 +106,7 @@ function testFieldFormTranslationRevisions() {
     $available_langcodes = array_flip(field_available_languages($this->entity_type, $this->field));
     unset($available_langcodes[Language::LANGCODE_NOT_SPECIFIED]);
     unset($available_langcodes[Language::LANGCODE_NOT_APPLICABLE]);
-    $field_name = $this->field['field_name'];
+    $field_name = $this->field->id();
 
     // Store the field translations.
     $entity->langcode->value = key($available_langcodes);
@@ -135,7 +135,7 @@ function testFieldFormTranslationRevisions() {
    * by the passed arguments were correctly stored.
    */
   private function checkTranslationRevisions($id, $revision_id, $available_langcodes) {
-    $field_name = $this->field['field_name'];
+    $field_name = $this->field->id();
     $entity = entity_revision_load($this->entity_type, $revision_id);
     foreach ($available_langcodes as $langcode => $value) {
       $passed = $entity->getTranslation($langcode)->{$field_name}->value == $value + 1;
diff --git a/core/modules/field/lib/Drupal/field/Tests/Views/FieldTestBase.php b/core/modules/field/lib/Drupal/field/Tests/Views/FieldTestBase.php
index 2f8e5a6..90e3934 100644
--- a/core/modules/field/lib/Drupal/field/Tests/Views/FieldTestBase.php
+++ b/core/modules/field/lib/Drupal/field/Tests/Views/FieldTestBase.php
@@ -74,7 +74,7 @@ function setUpFields($amount = 3) {
   function setUpInstances($bundle = 'page') {
     foreach ($this->fields as $key => $field) {
       $instance = array(
-        'field_name' => $field['name'],
+        'field_name' => $field->getFieldName(),
         'entity_type' => 'node',
         'bundle' => 'page',
       );
diff --git a/core/modules/field/lib/Drupal/field/Tests/Views/HandlerFieldFieldTest.php b/core/modules/field/lib/Drupal/field/Tests/Views/HandlerFieldFieldTest.php
index 985dc7f..5e61d99 100644
--- a/core/modules/field/lib/Drupal/field/Tests/Views/HandlerFieldFieldTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/Views/HandlerFieldFieldTest.php
@@ -72,13 +72,13 @@ protected function setUp() {
 
       for ($key = 0; $key < 3; $key++) {
         $field = $this->fields[$key];
-        $edit[$field['field_name']][0]['value'] = $this->randomName(8);
+        $edit[$field->getFieldName()][0]['value'] = $this->randomName(8);
       }
       for ($j = 0; $j < 5; $j++) {
-        $edit[$this->fields[3]['field_name']][$j]['value'] = $this->randomName(8);
+        $edit[$this->fields[3]->getFieldName()][$j]['value'] = $this->randomName(8);
       }
       // Set this field to be empty.
-      $edit[$this->fields[4]['field_name']] = array(array('value' => NULL));
+      $edit[$this->fields[4]->getFieldName()] = array(array('value' => NULL));
 
       $this->nodes[$i] = $this->drupalCreateNode($edit);
     }
@@ -95,9 +95,9 @@ protected function setUp() {
   protected function prepareView(ViewExecutable $view) {
     $view->initDisplay();
     foreach ($this->fields as $key => $field) {
-      $view->display_handler->options['fields'][$field['field_name']]['id'] = $field['field_name'];
-      $view->display_handler->options['fields'][$field['field_name']]['table'] = 'node__' . $field['field_name'];
-      $view->display_handler->options['fields'][$field['field_name']]['field'] = $field['field_name'];
+      $view->display_handler->options['fields'][$field->getFieldName()]['id'] = $field->getFieldName();
+      $view->display_handler->options['fields'][$field->getFieldName()]['table'] = 'node__' . $field->getFieldName();
+      $view->display_handler->options['fields'][$field->getFieldName()]['field'] = $field->getFieldName();
     }
   }
 
@@ -116,8 +116,8 @@ public function _testSimpleFieldRender() {
     for ($i = 0; $i < 3; $i++) {
       for ($key = 0; $key < 2; $key++) {
         $field = $this->fields[$key];
-        $rendered_field = $view->style_plugin->getField($i, $field['field_name']);
-        $expected_field = $this->nodes[$i]->{$field['field_name']}->value;
+        $rendered_field = $view->style_plugin->getField($i, $field->getFieldName());
+        $expected_field = $this->nodes[$i]->{$field->getFieldName()}->value;
         $this->assertEqual($rendered_field, $expected_field);
       }
     }
@@ -145,7 +145,7 @@ public function _testFormatterSimpleFieldRender() {
 
   public function _testMultipleFieldRender() {
     $view = views_get_view('test_view_fieldapi');
-    $field_name = $this->fields[3]['field_name'];
+    $field_name = $this->fields[3]->getFieldName();
 
     // Test delta limit.
     $this->prepareView($view);
diff --git a/core/modules/field/tests/modules/field_test/field_test.field.inc b/core/modules/field/tests/modules/field_test/field_test.field.inc
index 3ac75fa..c2a9191 100644
--- a/core/modules/field/tests/modules/field_test/field_test.field.inc
+++ b/core/modules/field/tests/modules/field_test/field_test.field.inc
@@ -65,7 +65,7 @@ function field_test_field_widget_info_alter(&$info) {
  * Implements hook_field_update_forbid().
  */
 function field_test_field_update_forbid($field, $prior_field) {
-  if ($field['type'] == 'test_field' && $field['settings']['unchangeable'] != $prior_field['settings']['unchangeable']) {
+  if ($field->type == 'test_field' && $field->settings['unchangeable'] != $prior_field->settings['unchangeable']) {
     throw new FieldException("field_test 'unchangeable' setting cannot be changed'");
   }
 }
@@ -80,7 +80,7 @@ function field_test_field_load($entity_type, $entities, $field, $instances, $lan
   foreach ($items as $id => $item) {
     // To keep the test non-intrusive, only act for instances with the
     // test_hook_field_load setting explicitly set to TRUE.
-    if (!empty($instances[$id]['settings']['test_hook_field_load'])) {
+    if (!empty($instances[$id]->settings['test_hook_field_load'])) {
       foreach ($item as $delta => $value) {
         // Don't add anything on empty values.
         if ($value) {
@@ -127,9 +127,9 @@ function field_test_field_validate(EntityInterface $entity = NULL, $field, $inst
 
   foreach ($items as $delta => $item) {
     if ($item['value'] == -1) {
-      $errors[$field['field_name']][$langcode][$delta][] = array(
+      $errors[$field->id()][$langcode][$delta][] = array(
         'error' => 'field_test_invalid',
-        'message' => t('%name does not accept the value -1.', array('%name' => $instance['label'])),
+        'message' => t('%name does not accept the value -1.', array('%name' => $instance->label())),
       );
     }
   }
@@ -149,7 +149,7 @@ function field_test_field_is_empty($item, $field_type) {
  * Implements hook_field_settings_form().
  */
 function field_test_field_settings_form($field, $instance) {
-  $settings = $field['settings'];
+  $settings = $field->settings;
 
   $form['test_field_setting'] = array(
     '#type' => 'textfield',
@@ -166,7 +166,7 @@ function field_test_field_settings_form($field, $instance) {
  * Implements hook_field_instance_settings_form().
  */
 function field_test_field_instance_settings_form($field, $instance) {
-  $settings = $instance['settings'];
+  $settings = $instance->settings;
 
   $form['test_instance_setting'] = array(
     '#type' => 'textfield',
@@ -202,13 +202,17 @@ function field_test_default_value(EntityInterface $entity, $field, $instance) {
  * Implements hook_field_access().
  */
 function field_test_field_access($op, FieldInterface $field, $entity_type, $entity, $account) {
-  if ($field['field_name'] == "field_no_{$op}_access") {
+  if ($field->id() == "field_no_{$op}_access") {
     return FALSE;
   }
 
   // Only grant view access to test_view_field fields when the user has
   // 'view test_view_field content' permission.
+<<<<<<< HEAD
+  if ($field->id() == 'test_view_field' && $op == 'view' && !user_access('view test_view_field content')) {
+=======
   if ($field['field_name'] == 'test_view_field' && $op == 'view' && !$account->hasPermission('view test_view_field content')) {
+>>>>>>> 8.x
     return FALSE;
   }
 
diff --git a/core/modules/field/tests/modules/field_test/field_test.install b/core/modules/field/tests/modules/field_test/field_test.install
index a079829..5775380 100644
--- a/core/modules/field/tests/modules/field_test/field_test.install
+++ b/core/modules/field/tests/modules/field_test/field_test.install
@@ -17,7 +17,7 @@ function field_test_install() {
  * Implements hook_field_schema().
  */
 function field_test_field_schema($field) {
-  if ($field['type'] == 'test_field') {
+  if ($field->type == 'test_field') {
     return array(
       'columns' => array(
         'value' => array(
@@ -34,13 +34,13 @@ function field_test_field_schema($field) {
   else {
     $foreign_keys = array();
     // The 'foreign keys' key is not always used in tests.
-    if (!empty($field['settings']['foreign_key_name'])) {
+    if (!empty($field->settings['foreign_key_name'])) {
       $foreign_keys['foreign keys'] = array(
         // This is a dummy foreign key definition, references a table that
         // doesn't exist, but that's not a problem.
-        $field['settings']['foreign_key_name'] => array(
-          'table' => $field['settings']['foreign_key_name'],
-          'columns' => array($field['settings']['foreign_key_name'] => 'id'),
+        $field->settings['foreign_key_name'] => array(
+          'table' => $field->settings['foreign_key_name'],
+          'columns' => array($field->settings['foreign_key_name'] => 'id'),
         ),
       );
     }
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php b/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php
index b426759..64b547b 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php
@@ -515,12 +515,12 @@ protected function getExistingFieldOptions() {
         // Do not show:
         // - locked fields,
         // - fields that should not be added via user interface.
-        if (empty($field['locked']) && empty($field_types[$field['type']]['no_ui'])) {
+        if (empty($field->locked) && empty($field_types[$field->getFieldType()]['no_ui'])) {
           $options[$field->name] = array(
-            'type' => $field->type,
-            'type_label' => $field_types[$field->type]['label'],
-            'field' => $field->name,
-            'label' => $instance->label,
+            'type' => $field->getFieldType(),
+            'type_label' => $field_types[$field->getFieldType()]['label'],
+            'field' => $field->getFieldName(),
+            'label' => $instance->label(),
           );
         }
       }
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldDeleteForm.php b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldDeleteForm.php
index 8037ac4..0caacd1 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldDeleteForm.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldDeleteForm.php
@@ -71,7 +71,7 @@ public function submit(array $form, array &$form_state) {
     $bundles = entity_get_bundles();
     $bundle_label = $bundles[$this->entity->entity_type][$this->entity->bundle]['label'];
 
-    if ($field && !$field['locked']) {
+    if ($field && !$field->locked) {
       $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/lib/Drupal/field_ui/Form/FieldEditForm.php b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldEditForm.php
index 135a938..ff2a543 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldEditForm.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldEditForm.php
@@ -110,7 +110,7 @@ public function buildForm(array $form, array &$form_state, FieldInstanceInterfac
     }
 
     // Build the configurable field values.
-    $cardinality = $field['cardinality'];
+    $cardinality = $field->getFieldCardinality();
     $form['field']['cardinality_container'] = array(
       // We can't use the container element because it doesn't support the title
       // or description properties.
@@ -146,10 +146,10 @@ public function buildForm(array $form, array &$form_state, FieldInstanceInterfac
     );
 
     // Build the non-configurable field values.
-    $form['field']['field_name'] = array('#type' => 'value', '#value' => $field['field_name']);
-    $form['field']['type'] = array('#type' => 'value', '#value' => $field['type']);
-    $form['field']['module'] = array('#type' => 'value', '#value' => $field['module']);
-    $form['field']['active'] = array('#type' => 'value', '#value' => $field['active']);
+    $form['field']['field_name'] = array('#type' => 'value', '#value' => $field->getFieldName());
+    $form['field']['type'] = array('#type' => 'value', '#value' => $field->getFieldType());
+    $form['field']['module'] = array('#type' => 'value', '#value' => $field->module);
+    $form['field']['active'] = array('#type' => 'value', '#value' => $field->active);
 
     // Add settings provided by the field module. The field module is
     // responsible for not returning settings that cannot be changed if
@@ -159,9 +159,9 @@ public function buildForm(array $form, array &$form_state, FieldInstanceInterfac
     );
     // Create an arbitrary entity object, so that we can have an instantiated
     // FieldItem.
-    $ids = (object) array('entity_type' => $this->instance['entity_type'], 'bundle' => $this->instance['bundle'], 'entity_id' => NULL);
+    $ids = (object) array('entity_type' => $this->instance->entity_type, 'bundle' => $this->instance->bundle, 'entity_id' => NULL);
     $entity = _field_create_entity_from_ids($ids);
-    $form['field']['settings'] += $this->getFieldItem($entity, $field['field_name'])->settingsForm($form, $form_state, $field->hasData());
+    $form['field']['settings'] += $this->getFieldItem($entity, $field->getFieldName())->settingsForm($form, $form_state, $field->hasData());
 
     $form['actions'] = array('#type' => 'actions');
     $form['actions']['submit'] = array('#type' => 'submit', '#value' => $this->t('Save field settings'));
@@ -199,7 +199,7 @@ public function submitForm(array &$form, array &$form_state) {
     // Merge incoming form values into the existing field.
     $field = $this->instance->getField();
     foreach ($field_values as $key => $value) {
-      $field[$key] = $value;
+      $field->{$key} = $value;
     }
 
     // Update the field.
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldInstanceEditForm.php b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldInstanceEditForm.php
index 4aff6da..430864e 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldInstanceEditForm.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldInstanceEditForm.php
@@ -66,8 +66,8 @@ public function getFormID() {
   public function buildForm(array $form, array &$form_state, FieldInstanceInterface $field_instance = NULL) {
     $this->instance = $form_state['instance'] = $field_instance;
 
-    $bundle = $this->instance['bundle'];
-    $entity_type = $this->instance['entity_type'];
+    $bundle = $this->instance->bundle;
+    $entity_type = $this->instance->entity_type;
     $field = $this->instance->getField();
     $bundles = entity_get_bundles();
 
@@ -78,11 +78,11 @@ public function buildForm(array $form, array &$form_state, FieldInstanceInterfac
 
     $form['#field'] = $field;
     // Create an arbitrary entity object (used by the 'default value' widget).
-    $ids = (object) array('entity_type' => $this->instance['entity_type'], 'bundle' => $this->instance['bundle'], 'entity_id' => NULL);
+    $ids = (object) array('entity_type' => $this->instance->entity_type, 'bundle' => $this->instance->bundle, 'entity_id' => NULL);
     $form['#entity'] = _field_create_entity_from_ids($ids);
     $items = $this->getFieldItems($form['#entity'], $this->instance['field_name']);
 
-    if (!empty($field['locked'])) {
+    if (!empty($field->locked)) {
       $form['locked'] = array(
         '#markup' => $this->t('The field %field is locked and cannot be edited.', array('%field' => $this->instance->label())),
       );
@@ -97,7 +97,7 @@ public function buildForm(array $form, array &$form_state, FieldInstanceInterfac
     // Build the non-configurable instance values.
     $form['instance']['field_name'] = array(
       '#type' => 'value',
-      '#value' => $this->instance['field_name'],
+      '#value' => $this->instance->getFieldName(),
     );
     $form['instance']['entity_type'] = array(
       '#type' => 'value',
@@ -112,7 +112,7 @@ public function buildForm(array $form, array &$form_state, FieldInstanceInterfac
     $form['instance']['label'] = array(
       '#type' => 'textfield',
       '#title' => $this->t('Label'),
-      '#default_value' => $this->instance->label() ?: $field['field_name'],
+      '#default_value' => $this->instance->label() ?: $field->getFieldName(),
       '#required' => TRUE,
       '#weight' => -20,
     );
@@ -120,7 +120,7 @@ public function buildForm(array $form, array &$form_state, FieldInstanceInterfac
     $form['instance']['description'] = array(
       '#type' => 'textarea',
       '#title' => $this->t('Help text'),
-      '#default_value' => !empty($this->instance['description']) ? $this->instance['description'] : '',
+      '#default_value' => !empty($this->instance->description) ? $this->instance->description : '',
       '#rows' => 5,
       '#description' => $this->t('Instructions to present to the user below this field on the editing form.<br />Allowed HTML tags: @tags', array('@tags' => _field_filter_xss_display_allowed_tags())) . '<br />' . $this->t('This field supports tokens.'),
       '#weight' => -10,
@@ -129,7 +129,7 @@ public function buildForm(array $form, array &$form_state, FieldInstanceInterfac
     $form['instance']['required'] = array(
       '#type' => 'checkbox',
       '#title' => $this->t('Required field'),
-      '#default_value' => !empty($this->instance['required']),
+      '#default_value' => !empty($this->instance->required),
       '#weight' => -5,
     );
 
@@ -164,9 +164,36 @@ public function buildForm(array $form, array &$form_state, FieldInstanceInterfac
    * {@inheritdoc}
    */
   public function validateForm(array &$form, array &$form_state) {
+<<<<<<< HEAD
+    // Take the incoming values as the $this->instance definition, so that the 'default
+    // value' gets validated using the instance settings being submitted.
+    $field_name = $this->instance->getFieldName();
+    $entity = $form['#entity'];
+    $entity_form_display = $form['#entity_form_display'];
+
+    if (isset($form['instance']['default_value_widget'])) {
+      $element = $form['instance']['default_value_widget'];
+
+      // Extract the 'default value'.
+      $items = $entity->getNGEntity()->{$field_name};
+      $entity_form_display->getRenderer($this->instance->getField()->id)->extractFormValues($entity, Language::LANGCODE_NOT_SPECIFIED, $items, $element, $form_state);
+      $violations = $items->validate();
+
+      // Report errors.
+      if (count($violations)) {
+        $field_state = field_form_get_state($element['#parents'], $field_name, Language::LANGCODE_NOT_SPECIFIED, $form_state);
+        // Store reported errors in $form_state.
+        $field_state['constraint_violations'] = $violations;
+        field_form_set_state($element['#parents'], $field_name, Language::LANGCODE_NOT_SPECIFIED, $form_state, $field_state);
+
+        // Assign reported errors to the correct form element.
+        $entity_form_display->getRenderer($this->instance->getField()->id)->flagErrors($entity, Language::LANGCODE_NOT_SPECIFIED, $items, $element, $form_state);
+      }
+=======
     if (isset($form['instance']['default_value'])) {
       $items = $this->getFieldItems($form['#entity'], $this->instance['field_name']);
       $items->defaultValuesFormValidate($form['instance']['default_value'], $form, $form_state);
+>>>>>>> 8.x
     }
   }
 
@@ -174,6 +201,13 @@ public function validateForm(array &$form, array &$form_state) {
    * {@inheritdoc}
    */
   public function submitForm(array &$form, array &$form_state) {
+<<<<<<< HEAD
+    $field_name = $this->instance->getFieldName();
+    $entity = $form['#entity'];
+    $entity_form_display = $form['#entity_form_display'];
+
+=======
+>>>>>>> 8.x
     // Handle the default value.
     $default_value = array();
     if (isset($form['instance']['default_value'])) {
@@ -184,7 +218,7 @@ public function submitForm(array &$form, array &$form_state) {
 
     // Merge incoming values into the instance.
     foreach ($form_state['values']['instance'] as $key => $value) {
-      $this->instance[$key] = $value;
+      $this->instance->$key = $value;
     }
     $this->instance->save();
 
@@ -202,11 +236,66 @@ public function delete(array &$form, array &$form_state) {
       $destination = drupal_get_destination();
       unset($_GET['destination']);
     }
-    $form_state['redirect'] = array('admin/structure/types/manage/' . $this->instance['bundle'] . '/fields/' . $this->instance->id() . '/delete', array('query' => $destination));
+    $form_state['redirect'] = array('admin/structure/types/manage/' . $this->instance->bundle . '/fields/' . $this->instance->id() . '/delete', array('query' => $destination));
   }
 
   /**
+<<<<<<< HEAD
+   * Builds the default value widget for a given field instance.
+   */
+  protected function getDefaultValueWidget($field, array &$form, &$form_state) {
+    $entity = $form['#entity'];
+    $entity_form_display = $form['#entity_form_display'];
+
+    $element = array(
+      '#type' => 'details',
+      '#title' => $this->t('Default value'),
+      '#tree' => TRUE,
+      '#description' => $this->t('The default value for this field, used when creating new content.'),
+      // Stick to an empty 'parents' on this form in order not to breaks widgets
+      // that do not use field_widget_[field|instance]() and still access
+      // $form_state['field'] directly.
+      '#parents' => array(),
+    );
+
+    // Adjust the instance definition used for the form element. We want a
+    // non-required input and no description.
+    $this->instance->required = FALSE;
+    $this->instance->description = '';
+
+    // Adjust the instance definition to use the default widget of this field type
+    // instead of the hidden widget.
+    // @todo Clean this up since we don't have $this->instance['widget'] anymore.
+    //   see https://drupal.org/node/2028759
+    if ($this->instance->widget['type'] == 'hidden') {
+      $field_type = $this->fieldTypeManager->getDefinition($field->getFieldType());
+      $default_widget = $this->widgetManager->getDefinition($field_type['default_widget']);
+
+      $this->instance['widget'] = array(
+        'type' => $default_widget['id'],
+        'settings' => $default_widget['settings'],
+        'weight' => 0,
+      );
+    }
+
+    // Insert the widget. Since we do not use the "official" instance definition,
+    // the whole flow cannot use field_invoke_method().
+    $items = $entity->getNGEntity()->{$this->instance->getField()->id};
+    if (!empty($this->instance->default_value)) {
+      $items->setValue((array) $this->instance->default_value);
+    }
+    $element += $entity_form_display->getRenderer($this->instance->getField()->id)->form($entity, Language::LANGCODE_NOT_SPECIFIED, $items, $element, $form_state);
+
+    return $element;
+  }
+
+  /**
+   * Returns a FieldItem object for an entity.
+   *
+   * @todo Remove when all entity types extend EntityNG.
+=======
    * Returns a Field object for an entity.
+>>>>>>> 8.x
    *
    * @param \Drupal\Core\Entity\EntityInterface $entity
    *   An entity.
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldWidgetTypeForm.php b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldWidgetTypeForm.php
new file mode 100644
index 0000000..f257c56
--- /dev/null
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldWidgetTypeForm.php
@@ -0,0 +1,99 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\field_ui\Form\FieldWidgetTypeForm.
+ */
+
+namespace Drupal\field_ui\Form;
+
+use Drupal\field\FieldInstanceInterface;
+
+/**
+ * Provides a form for the widget selection form.
+ */
+class FieldWidgetTypeForm extends FieldInstanceFormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormID() {
+    return 'field_ui_widget_type_form';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, array &$form_state, FieldInstanceInterface $field_instance = NULL) {
+    parent::buildForm($form, $form_state, $field_instance);
+
+    drupal_set_title($this->instance->label());
+
+    $bundle = $this->instance->bundle;
+    $entity_type = $this->instance->entity_type;
+    $field_name = $this->instance->getFieldName();
+
+    $entity_form_display = entity_get_form_display($entity_type, $bundle, 'default');
+    $field = $this->instance->getField();
+    $bundles = entity_get_bundles();
+    $bundle_label = $bundles[$entity_type][$bundle]['label'];
+
+    $form = array(
+      '#bundle' => $bundle,
+      '#entity_type' => $entity_type,
+      '#field_name' => $field_name,
+      '#instance' => $this->instance,
+    );
+
+    $form['widget_type'] = array(
+      '#type' => 'select',
+      '#title' => t('Widget type'),
+      '#required' => TRUE,
+      '#options' => $this->widgetManager->getOptions($field->type),
+      '#default_value' => $entity_form_display->getWidget($field_name)->getPluginId(),
+      '#description' => t('The type of form element you would like to present to the user when creating this field in the %type type.', array('%type' => $bundle_label)),
+    );
+
+    $form['actions'] = array('#type' => 'actions');
+    $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Continue'));
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateForm(array &$form, array &$form_state) {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, array &$form_state) {
+    $form_values = $form_state['values'];
+    $bundle = $form['#bundle'];
+    $entity_type = $form['#entity_type'];
+    $field_name = $form['#field_name'];
+    $instance = $form['#instance'];
+
+    $entity_form_display = entity_get_form_display($entity_type, $bundle, 'default')
+      ->setComponent($field_name, array(
+        'type' => $form_values['widget_type'],
+      ));
+
+    try {
+      $entity_form_display->save();
+      drupal_set_message(t('Changed the widget for field %label.', array('%label' => $instance->label())));
+
+      /*if ($instance->required && empty($instance->default_value) && empty($instance->default_value_function) && $instance['widget']['type'] == 'field_hidden') {
+        drupal_set_message(t('Field %label is required and uses the "hidden" widget. You might want to configure a default value.', array('%label' => $instance->label())), 'warning');
+      }*/
+    }
+    catch (\Exception $e) {
+      drupal_set_message(t('There was a problem changing the widget for field %label.', array('%label' => $instance->label())), 'error');
+    }
+
+    $form_state['redirect'] = $this->getNextDestination();
+  }
+
+}
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php
index d1edd6d..eb81c88 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php
@@ -243,10 +243,6 @@ function testNonInitializedFields() {
     );
     $this->fieldUIAddNewField('admin/structure/types/manage/' . $this->type, $edit);
 
-    // Check that no settings have been set for the 'teaser' mode.
-    $instance = field_info_instance('node', 'field_test', $this->type);
-    $this->assertFalse(isset($instance['display']['teaser']));
-
     // Check that the field appears as 'hidden' on the 'Manage display' page
     // for the 'teaser' mode.
     $this->drupalGet('admin/structure/types/manage/' . $this->type . '/display/teaser');
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php
index 3e09d8f..1705ab0 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php
@@ -225,11 +225,11 @@ function assertFieldSettings($bundle, $field_name, $string = 'dummy test string'
     field_info_cache_clear();
     // Assert field settings.
     $field = field_info_field($entity_type, $field_name);
-    $this->assertTrue($field['settings']['test_field_setting'] == $string, 'Field settings were found.');
+    $this->assertTrue($field->settings['test_field_setting'] == $string, 'Field settings were found.');
 
     // Assert instance settings.
     $instance = field_info_instance($entity_type, $field_name, $bundle);
-    $this->assertTrue($instance['settings']['test_instance_setting'] == $string, 'Field instance settings were found.');
+    $this->assertTrue($instance->settings['test_instance_setting'] == $string, 'Field instance settings were found.');
   }
 
   /**
@@ -302,7 +302,7 @@ function testDefaultValue() {
     $this->assertText("Saved $field_name configuration", 'The form was successfully submitted.');
     field_info_cache_clear();
     $instance = field_info_instance('node', $field_name, $this->type);
-    $this->assertEqual($instance['default_value'], array(array('value' => 1)), 'The default value was correctly saved.');
+    $this->assertEqual($instance->default_value, array(array('value' => 1)), 'The default value was correctly saved.');
 
     // Check that the default value shows up in the form
     $this->drupalGet($admin_path);
@@ -314,10 +314,10 @@ function testDefaultValue() {
     $this->assertText("Saved $field_name configuration", 'The form was successfully submitted.');
     field_info_cache_clear();
     $instance = field_info_instance('node', $field_name, $this->type);
-    $this->assertEqual($instance['default_value'], NULL, 'The default value was correctly saved.');
+    $this->assertEqual($instance->default_value, NULL, 'The default value was correctly saved.');
 
     // Check that the default widget is used when the field is hidden.
-    entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')
+    entity_get_form_display($instance->entity_type, $instance->bundle, 'default')
       ->removeComponent($field_name)->save();
     $this->drupalGet($admin_path);
     $this->assertFieldById($element_id, '', 'The default value widget was displayed when field is hidden.');
diff --git a/core/modules/file/file.field.inc b/core/modules/file/file.field.inc
index a40a44b..c81cfb5 100644
--- a/core/modules/file/file.field.inc
+++ b/core/modules/file/file.field.inc
@@ -7,6 +7,7 @@
 
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\field\FieldInterface;
 
 /**
  * Implements hook_field_info().
@@ -39,8 +40,8 @@ function file_field_info() {
  * Implements hook_field_settings_form().
  */
 function file_field_settings_form($field, $instance) {
-  $defaults = \Drupal::service('plugin.manager.entity.field.field_type')->getDefaultSettings($field['type']);
-  $settings = array_merge($defaults, $field['settings']);
+  $defaults = \Drupal::service('plugin.manager.entity.field.field_type')->getDefaultSettings($field->getFieldType());
+  $settings = array_merge($defaults, $field->settings);
 
   $form['#attached']['library'][] = array('file', 'drupal.file');
 
@@ -82,7 +83,7 @@ function file_field_settings_form($field, $instance) {
  * Implements hook_field_instance_settings_form().
  */
 function file_field_instance_settings_form($field, $instance) {
-  $settings = $instance['settings'];
+  $settings = $instance->settings;
 
   $form['file_directory'] = array(
     '#type' => 'textfield',
@@ -218,8 +219,8 @@ function file_field_update(EntityInterface $entity, $field, $instance, $langcode
   // Compare the original field values with the ones that are being saved.
   $original = $entity->original->getBCEntity();
   $original_fids = array();
-  if (!empty($original->{$field['field_name']}[$langcode])) {
-    foreach ($original->{$field['field_name']}[$langcode] as $original_item) {
+  if (!empty($original->{$field->getFieldName()}[$langcode])) {
+    foreach ($original->{$field->getFieldName()}[$langcode] as $original_item) {
       $original_fids[] = $original_item['target_id'];
       if (isset($original_item['target_id']) && !in_array($original_item['target_id'], $current_fids)) {
         // Decrement the file usage count by 1.
@@ -359,8 +360,8 @@ function file_field_widget_multiple_count_validate($element, &$form_state, $form
   $field = field_info_field($element['#entity_type'], $element['#field_name']);
   $uploaded = count($values['fids']);
   $count = $uploaded + $current;
-  if ($count > $field['cardinality']) {
-    $keep = $uploaded - $count + $field['cardinality'];
+  if ($count > $field->getFieldCardinality()) {
+    $keep = $uploaded - $count + $field->getFieldCardinality();
     $removed_files = array_slice($values['fids'], $keep);
     $removed_names = array();
     foreach ($removed_files as $fid) {
@@ -371,8 +372,8 @@ function file_field_widget_multiple_count_validate($element, &$form_state, $form
       t(
         'Field %field can only hold @max values but there were @count uploaded. The following files have been omitted as a result: %list.',
         array(
-          '%field' => $field['field_name'],
-          '@max' => $field['cardinality'],
+          '%field' => $field->getFieldName(),
+          '@max' => $field->getFieldCardinality(),
           '@count' => $keep,
           '%list' => implode(', ', $removed_names),
         )
@@ -792,8 +793,9 @@ function theme_file_upload_help($variables) {
  *   The field column if the field references {file_managed}.fid, typically
  *   fid, FALSE if it doesn't.
  */
-function file_field_find_file_reference_column($field) {
-  foreach ($field['foreign keys'] as $data) {
+function file_field_find_file_reference_column(FieldInterface $field) {
+  $schema = $field->getSchema();
+  foreach ($schema['foreign keys'] as $data) {
     if ($data['table'] == 'file_managed') {
       foreach ($data['columns'] as $field_column => $column) {
         if ($column == 'fid') {
diff --git a/core/modules/file/file.module b/core/modules/file/file.module
index 3dc1fbb..e941c27 100644
--- a/core/modules/file/file.module
+++ b/core/modules/file/file.module
@@ -1907,7 +1907,7 @@ function file_get_file_references(File $file, $field = NULL, $age = FIELD_LOAD_R
     foreach ($return as $field_name => $data) {
       foreach (array_keys($data) as $entity_type) {
         $current_field = field_info_field($entity_type, $field_name);
-        if (($field_type && $current_field['type'] != $field_type) || ($field && $field['id'] != $current_field['id'])) {
+        if (($field_type && $current_field->getFieldType() != $field_type) || ($field && $field->getFieldName() != $current_field->getFieldName())) {
           unset($return[$field_name][$entity_type]);
         }
       }
diff --git a/core/modules/file/file.views.inc b/core/modules/file/file.views.inc
index 501ce7c..b8d6c2b 100644
--- a/core/modules/file/file.views.inc
+++ b/core/modules/file/file.views.inc
@@ -485,24 +485,24 @@ function file_field_views_data(FieldInterface $field) {
  * Views integration to provide reverse relationships on file fields.
  */
 function file_field_views_data_views_data_alter(array &$data, FieldInterface $field) {
-  $entity_type = $field['entity_type'];
+  $entity_type = $field->entity_type;
   $entity_info = entity_get_info($entity_type);
-  $pseudo_field_name = 'reverse_' . $field['field_name'] . '_' . $entity_type;
+  $pseudo_field_name = 'reverse_' . $field->getFieldName() . '_' . $entity_type;
 
-  list($label,) = field_views_field_label($entity_type, $field['field_name']);
+  list($label,) = field_views_field_label($entity_type, $field->getFieldName());
   $entity_label = ($entity_info['label'] == t('Node')) ? t('Content') : $entity_info['label'];
 
   $data['file_managed'][$pseudo_field_name]['relationship'] = array(
     'title' => t('@entity using @field', array('@entity' => $entity_label, '@field' => $label)),
     'help' => t('Relate each @entity with a @field set to the file.', array('@entity' => $entity_label, '@field' => $label)),
     'id' => 'entity_reverse',
-    'field_name' => $field['field_name'],
-    'entity_type' => $field['entity_type'],
+    'field_name' => $field->getFieldName(),
+    'entity_type' => $field->entity_type,
     'field table' => DatabaseStorageController::_fieldTableName($field),
-    'field field' => $field['field_name'] . '_target_id',
+    'field field' => $field->getFieldName() . '_target_id',
     'base' => $entity_info['base_table'],
     'base field' => $entity_info['entity_keys']['id'],
-    'label' => t('!field_name', array('!field_name' => $field['field_name'])),
+    'label' => t('!field_name', array('!field_name' => $field->getFieldName())),
     'join_extra' => array(
       0 => array(
         'field' => 'deleted',
diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php
index 9558047..46395fc 100644
--- a/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php
+++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php
@@ -101,7 +101,7 @@ function createFileField($name, $entity_type, $bundle, $field_settings = array()
    *   A list of widget settings that will be added to the widget defaults.
    */
   function attachFileField($name, $entity_type, $bundle, $instance_settings = array(), $widget_settings = array()) {
-    $instance = array(
+    $instance_definition = array(
       'field_name' => $name,
       'label' => $name,
       'entity_type' => $entity_type,
@@ -109,8 +109,8 @@ function attachFileField($name, $entity_type, $bundle, $instance_settings = arra
       'required' => !empty($instance_settings['required']),
       'settings' => array(),
     );
-    $instance['settings'] = array_merge($instance['settings'], $instance_settings);
-    entity_create('field_instance', $instance)->save();
+    $instance_definition['settings'] = array_merge($instance_definition['settings'], $instance_settings);
+    entity_create('field_instance', $instance_definition)->save();
 
     entity_get_form_display($entity_type, $bundle, 'default')
       ->setComponent($name, array(
@@ -125,12 +125,12 @@ function attachFileField($name, $entity_type, $bundle, $instance_settings = arra
    */
   function updateFileField($name, $type_name, $instance_settings = array(), $widget_settings = array()) {
     $instance = field_info_instance('node', $name, $type_name);
-    $instance['settings'] = array_merge($instance['settings'], $instance_settings);
+    $instance->settings = array_merge($instance->settings, $instance_settings);
 
     $instance->save();
 
-    entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')
-      ->setComponent($instance['field_name'], array(
+    entity_get_form_display($instance->entity_type, $instance->bundle, 'default')
+      ->setComponent($instance->getFieldName(), array(
         'settings' => $widget_settings,
       ))
       ->save();
@@ -164,7 +164,7 @@ function uploadNodeFile($file, $field_name, $nid_or_type, $new_revision = TRUE,
     // Attach a file to the node.
     $field = field_info_field('node', $field_name);
     $name = 'files[' . $field_name . '_' . $langcode . '_0]';
-    if ($field['cardinality'] != 1) {
+    if ($field->cardinality != 1) {
       $name .= '[]';
     }
     $edit[$name] = drupal_realpath($file->getFileUri());
diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldValidateTest.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldValidateTest.php
index ed9aca1..5338ca6 100644
--- a/core/modules/file/lib/Drupal/file/Tests/FileFieldValidateTest.php
+++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldValidateTest.php
@@ -38,7 +38,7 @@ function testRequired() {
     // Try to post a new node without uploading a file.
     $edit = array("title" => $this->randomName());
     $this->drupalPost('node/add/' . $type_name, $edit, t('Save and publish'));
-    $this->assertRaw(t('!title field is required.', array('!title' => $instance['label'])), 'Node save failed when required file field was empty.');
+    $this->assertRaw(t('!title field is required.', array('!title' => $instance->label)), 'Node save failed when required file field was empty.');
 
     // Create a new node with the uploaded file.
     $nid = $this->uploadNodeFile($test_file, $field_name, $type_name);
@@ -57,7 +57,7 @@ function testRequired() {
     // Try to post a new node without uploading a file in the multivalue field.
     $edit = array('title' => $this->randomName());
     $this->drupalPost('node/add/' . $type_name, $edit, t('Save and publish'));
-    $this->assertRaw(t('!title field is required.', array('!title' => $instance['label'])), 'Node save failed when required multiple value file field was empty.');
+    $this->assertRaw(t('!title field is required.', array('!title' => $instance->label)), 'Node save failed when required multiple value file field was empty.');
 
     // Create a new node with the uploaded file into the multivalue field.
     $nid = $this->uploadNodeFile($test_file, $field_name, $type_name);
diff --git a/core/modules/file/tests/file_module_test.module b/core/modules/file/tests/file_module_test.module
index fc116ad..6e172d0 100644
--- a/core/modules/file/tests/file_module_test.module
+++ b/core/modules/file/tests/file_module_test.module
@@ -88,7 +88,7 @@ function file_module_test_form_submit($form, &$form_state) {
  * Implements hook_file_download_access().
  */
 function file_module_test_file_download_access($field, EntityInterface $entity, File $file) {
-  $instance = field_info_instance($entity->entityType(), $field['field_name'], $entity->bundle());
+  $instance = field_info_instance($entity->entityType(), $field->id(), $entity->bundle());
   // Allow the file to be downloaded only if the given arguments are correct.
   // If any are wrong, $instance will be NULL.
   if (empty($instance)) {
diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module
index 1ed6ac3..0c976ef 100644
--- a/core/modules/forum/forum.module
+++ b/core/modules/forum/forum.module
@@ -174,7 +174,7 @@ function forum_menu_local_tasks(&$data, $router_item, $root_path) {
       $links = array();
       // Loop through all bundles for forum taxonomy vocabulary field.
       $field = field_info_field('node', 'taxonomy_forums');
-      foreach ($field['bundles'] as $type_name) {
+      foreach ($field->getBundles() as $type_name) {
         if (($type = entity_load('node_type', $type_name)) && node_access('create', $type_name)) {
           $links[$type_name] = array(
             '#theme' => 'menu_local_action',
diff --git a/core/modules/image/image.field.inc b/core/modules/image/image.field.inc
index c682747..2e3a574 100644
--- a/core/modules/image/image.field.inc
+++ b/core/modules/image/image.field.inc
@@ -58,8 +58,8 @@ function image_field_info() {
  * Implements hook_field_settings_form().
  */
 function image_field_settings_form($field, $instance) {
-  $defaults = \Drupal::service('plugin.manager.entity.field.field_type')->getDefaultSettings($field['type']);
-  $settings = array_merge($defaults, $field['settings']);
+  $defaults = \Drupal::service('plugin.manager.entity.field.field_type')->getDefaultSettings($field->getFieldtype());
+  $settings = array_merge($defaults, $field->settings);
 
   $scheme_options = array();
   foreach (file_get_stream_wrappers(STREAM_WRAPPERS_WRITE_VISIBLE) as $scheme => $stream_wrapper) {
@@ -80,7 +80,7 @@ function image_field_settings_form($field, $instance) {
     '#title' => t('Default image'),
     '#type' => 'managed_file',
     '#description' => t('If no image is uploaded, this image will be shown on display.'),
-    '#default_value' => empty($field['settings']['default_image']) ? array() : array($field['settings']['default_image']),
+    '#default_value' => empty($field->settings['default_image']) ? array() : array($field->settings['default_image']),
     '#upload_location' => $settings['uri_scheme'] . '://default_images/',
   );
 
@@ -91,7 +91,7 @@ function image_field_settings_form($field, $instance) {
  * Implements hook_field_instance_settings_form().
  */
 function image_field_instance_settings_form($field, $instance) {
-  $settings = $instance['settings'];
+  $settings = $instance->settings;
 
   // Use the file field instance settings form as a basis.
   $form = file_field_instance_settings_form($field, $instance);
@@ -199,7 +199,7 @@ function image_field_instance_settings_form($field, $instance) {
     '#type' => 'managed_file',
     '#description' => t("If no image is uploaded, this image will be shown on display and will override the field's default image."),
     '#default_value' => empty($settings['default_image']) ? array() : array($settings['default_image']),
-    '#upload_location' => $field['settings']['uri_scheme'] . '://default_images/',
+    '#upload_location' => $field->settings['uri_scheme'] . '://default_images/',
   );
 
   return $form;
diff --git a/core/modules/image/image.views.inc b/core/modules/image/image.views.inc
index 356f140..915ddfa 100644
--- a/core/modules/image/image.views.inc
+++ b/core/modules/image/image.views.inc
@@ -22,11 +22,11 @@ function image_field_views_data(FieldInterface $field) {
   $data = field_views_field_default_views_data($field);
   foreach ($data as $table_name => $table_data) {
     // Add the relationship only on the target_id field.
-    $data[$table_name][$field['field_name'] . '_target_id']['relationship'] = array(
+    $data[$table_name][$field->getFieldName() . '_target_id']['relationship'] = array(
       'id' => 'standard',
       'base' => 'file_managed',
       'base field' => 'target_id',
-      'label' => t('image from !field_name', array('!field_name' => $field['field_name'])),
+      'label' => t('image from !field_name', array('!field_name' => $field->getFieldName())),
     );
   }
 
@@ -39,24 +39,24 @@ function image_field_views_data(FieldInterface $field) {
  * Views integration to provide reverse relationships on image fields.
  */
 function image_field_views_data_views_data_alter(array &$data, FieldInterface $field) {
-  $entity_type = $field['entity_type'];
+  $entity_type = $field->entity_type;
   $entity_info = entity_get_info($entity_type);
-  $pseudo_field_name = 'reverse_' . $field['field_name'] . '_' . $entity_type;
+  $pseudo_field_name = 'reverse_' . $field->getFieldName() . '_' . $entity_type;
 
-  list($label,) = field_views_field_label($entity_type, $field['field_name']);
+  list($label,) = field_views_field_label($entity_type, $field->getFieldName());
   $entity_label = ($entity_info['label'] == t('Node')) ? t('Content') : $entity_info['label'];
 
   $data['file_managed'][$pseudo_field_name]['relationship'] = array(
     'title' => t('@entity using @field', array('@entity' => $entity_label, '@field' => $label)),
     'help' => t('Relate each @entity with a @field set to the image.', array('@entity' => $entity_label, '@field' => $label)),
     'id' => 'entity_reverse',
-    'field_name' => $field['field_name'],
-    'entity_type' => $field['entity_type'],
+    'field_name' => $field->getFieldName(),
+    'entity_type' => $field->entity_type,
     'field table' => DatabaseStorageController::_fieldTableName($field),
-    'field field' => $field['field_name'] . '_target_id',
+    'field field' => $field->getFieldName() . '_target_id',
     'base' => $entity_info['base_table'],
     'base field' => $entity_info['entity_keys']['id'],
-    'label' => t('!field_name', array('!field_name' => $field['field_name'])),
+    'label' => t('!field_name', array('!field_name' => $field->getFieldName())),
     'join_extra' => array(
       0 => array(
         'field' => 'deleted',
diff --git a/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php b/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php
index 4d12539..a2ea695 100644
--- a/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php
+++ b/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php
@@ -143,26 +143,26 @@ protected static function replaceImageStyle(ImageStyleInterface $style) {
       // Loop through all fields searching for image fields.
       foreach ($instances as $instance) {
         if ($instance->getField()->type == 'image') {
-          $view_modes = entity_get_view_modes($instance['entity_type']);
+          $view_modes = entity_get_view_modes($instance->entity_type);
           $view_modes = array('default') + array_keys($view_modes);
           foreach ($view_modes as $view_mode) {
-            $display = entity_get_display($instance['entity_type'], $instance['bundle'], $view_mode);
-            $display_options = $display->getComponent($instance['field_name']);
+            $display = entity_get_display($instance->entity_type, $instance->bundle, $view_mode);
+            $display_options = $display->getComponent($instance->getFieldName());
 
             // Check if the formatter involves an image style.
             if ($display_options && $display_options['type'] == 'image' && $display_options['settings']['image_style'] == $style->getOriginalID()) {
               // Update display information for any instance using the image
               // style that was just deleted.
               $display_options['settings']['image_style'] = $style->id();
-              $display->setComponent($instance['field_name'], $display_options)
+              $display->setComponent($instance->getFieldName(), $display_options)
                 ->save();
             }
           }
-          $entity_form_display = entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default');
-          $widget_configuration = $entity_form_display->getComponent($instance['field_name']);
+          $entity_form_display = entity_get_form_display($instance->entity_type, $instance->bundle, 'default');
+          $widget_configuration = $entity_form_display->getComponent($instance->getFieldName());
           if ($widget_configuration['settings']['preview_image_style'] == $style->getOriginalID()) {
             $widget_options['settings']['preview_image_style'] = $style->id();
-            $entity_form_display->setComponent($instance['field_name'], $widget_options)
+            $entity_form_display->setComponent($instance->getFieldName(), $widget_options)
               ->save();
           }
         }
diff --git a/core/modules/image/lib/Drupal/image/Plugin/field/formatter/ImageFormatterBase.php b/core/modules/image/lib/Drupal/image/Plugin/field/formatter/ImageFormatterBase.php
index 0ed0be4..42078a2 100644
--- a/core/modules/image/lib/Drupal/image/Plugin/field/formatter/ImageFormatterBase.php
+++ b/core/modules/image/lib/Drupal/image/Plugin/field/formatter/ImageFormatterBase.php
@@ -26,8 +26,8 @@ public function prepareView(array $entities, $langcode, array $items) {
         $fid = array();
         $instance = field_info_instance($entity->entityType(), $this->fieldDefinition->getFieldName(), $entity->bundle());
         // Use the default for the instance if one is available.
-        if (!empty($instance['settings']['default_image'])) {
-          $fid = array($instance['settings']['default_image']);
+        if (!empty($instance->settings['default_image'])) {
+          $fid = array($instance->settings['default_image']);
         }
         // Otherwise, use the default for the field.
         // Note, that we have to bypass getFieldSetting() as this returns the
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php
index 45b2eef..3bfdfa4 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php
@@ -82,7 +82,7 @@ public function testDefaultImages() {
     ));
     $instance2->save();
 
-    $widget_settings = entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')->getComponent($field_name);
+    $widget_settings = entity_get_form_display($instance->entity_type, $instance->bundle, 'default')->getComponent($field_name);
     entity_get_form_display('node', 'page', 'default')
       ->setComponent($field_name, $widget_settings)
       ->save();
@@ -157,7 +157,7 @@ public function testDefaultImages() {
     );
 
     // Upload a new default for the field.
-    $field['settings']['default_image'] = array($default_images['field_new']->id());
+    $field->settings['default_image'] = array($default_images['field_new']->id());
     $field->save();
 
     // Confirm that the new default is used on the article field settings form.
@@ -192,7 +192,7 @@ public function testDefaultImages() {
     );
 
     // Upload a new default for the article's field instance.
-    $instance['settings']['default_image'] = $default_images['instance_new']->id();
+    $instance->settings['default_image'] = $default_images['instance_new']->id();
     $instance->save();
 
     // Confirm the new field instance default is used on the article field
@@ -231,7 +231,7 @@ public function testDefaultImages() {
     );
 
     // Remove the instance default from articles.
-    $instance['settings']['default_image'] = 0;
+    $instance->settings['default_image'] = 0;
     $instance->save();
 
     // Confirm the article field instance default has been removed.
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
index 221c01e..bc8d013 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
@@ -250,7 +250,7 @@ function testImageFieldDefaultImage() {
     // Clear field info cache so the new default image is detected.
     field_info_cache_clear();
     $field = field_info_field('node', $field_name);
-    $file = file_load($field['settings']['default_image']);
+    $file = file_load($field->settings['default_image']);
     $this->assertTrue($file->isPermanent(), 'The default image status is permanent.');
     $image = array(
       '#theme' => 'image',
@@ -283,7 +283,7 @@ function testImageFieldDefaultImage() {
     // Clear field info cache so the new default image is detected.
     field_info_cache_clear();
     $field = field_info_field('node', $field_name);
-    $this->assertFalse($field['settings']['default_image'], 'Default image removed from field.');
+    $this->assertFalse($field->settings['default_image'], 'Default image removed from field.');
     // Create an image field that uses the private:// scheme and test that the
     // default image works as expected.
     $private_field_name = strtolower($this->randomName());
diff --git a/core/modules/link/lib/Drupal/link/Tests/LinkFieldTest.php b/core/modules/link/lib/Drupal/link/Tests/LinkFieldTest.php
index 8a973d0..2ce7108 100644
--- a/core/modules/link/lib/Drupal/link/Tests/LinkFieldTest.php
+++ b/core/modules/link/lib/Drupal/link/Tests/LinkFieldTest.php
@@ -469,7 +469,7 @@ function testLinkSeparateFormatter() {
         // Update the field formatter settings.
         $display_options['settings'] = array($setting => $new_value);
         entity_get_display('entity_test', 'entity_test', 'full')
-          ->setComponent($this->field['field_name'], $display_options)
+          ->setComponent($this->field->id(), $display_options)
           ->save();
 
         $this->renderTestEntity($id);
diff --git a/core/modules/node/lib/Drupal/node/Plugin/views/wizard/Node.php b/core/modules/node/lib/Drupal/node/Plugin/views/wizard/Node.php
index 29e6a46..32412e7 100644
--- a/core/modules/node/lib/Drupal/node/Plugin/views/wizard/Node.php
+++ b/core/modules/node/lib/Drupal/node/Plugin/views/wizard/Node.php
@@ -279,11 +279,11 @@ protected function buildFilters(&$form, &$form_state) {
     $tag_fields = array();
     foreach ($bundles as $bundle) {
       foreach (field_info_instances($this->entity_type, $bundle) as $instance) {
-        $widget = entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')->getComponent($instance['field_name']);
+        $widget = entity_get_form_display($instance->entity_type, $instance->bundle, 'default')->getComponent($instance->getFieldName());
         // We define "tag-like" taxonomy fields as ones that use the
         // "Autocomplete term widget (tagging)" widget.
         if ($widget['type'] == 'taxonomy_autocomplete') {
-          $tag_fields[] = $instance['field_name'];
+          $tag_fields[] = $instance->getFieldName();
         }
       }
     }
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeTokenReplaceTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeTokenReplaceTest.php
index 1e55f29..05bdff8 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeTokenReplaceTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeTokenReplaceTest.php
@@ -54,8 +54,8 @@ function testNodeTokenReplacement() {
     $tests['[node:type]'] = 'article';
     $tests['[node:type-name]'] = 'Article';
     $tests['[node:title]'] = check_plain($node->getTitle());
-    $tests['[node:body]'] = text_sanitize($instance['settings']['text_processing'], $node->language()->id, $node->body[0]->getValue(), 'value');
-    $tests['[node:summary]'] = text_sanitize($instance['settings']['text_processing'], $node->language()->id, $node->body[0]->getValue(), 'summary');
+    $tests['[node:body]'] = text_sanitize($instance->settings['text_processing'], $node->language()->id, $node->body[0]->getValue(), 'value');
+    $tests['[node:summary]'] = text_sanitize($instance->settings['text_processing'], $node->language()->id, $node->body[0]->getValue(), 'summary');
     $tests['[node:langcode]'] = check_plain($node->language()->id);
     $tests['[node:url]'] = url('node/' . $node->id(), $url_options);
     $tests['[node:edit-url]'] = url('node/' . $node->id() . '/edit', $url_options);
@@ -97,7 +97,7 @@ function testNodeTokenReplacement() {
 
     // Generate and test sanitized token - use full body as expected value.
     $tests = array();
-    $tests['[node:summary]'] = text_sanitize($instance['settings']['text_processing'], $node->language()->id, $node->body[0]->getValue(), 'value');
+    $tests['[node:summary]'] = text_sanitize($instance->settings['text_processing'], $node->language()->id, $node->body[0]->getValue(), 'value');
 
     // Test to make sure that we generated something for each token.
     $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated for node without a summary.');
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeTypeTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeTypeTest.php
index c9e8345..6fccf94 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeTypeTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeTypeTest.php
@@ -84,7 +84,7 @@ function testNodeTypeEditing() {
     $this->drupalLogin($web_user);
 
     $instance = field_info_instance('node', 'body', 'page');
-    $this->assertEqual($instance['label'], 'Body', 'Body field was found.');
+    $this->assertEqual($instance->label(), 'Body', 'Body field was found.');
 
     // Verify that title and body fields are displayed.
     $this->drupalGet('node/add/page');
diff --git a/core/modules/node/node.tokens.inc b/core/modules/node/node.tokens.inc
index 9240497..53c0cc5 100644
--- a/core/modules/node/node.tokens.inc
+++ b/core/modules/node/node.tokens.inc
@@ -144,11 +144,11 @@ function node_tokens($type, $tokens, array $data = array(), array $options = arr
 
             // If the summary was requested and is not empty, use it.
             if ($name == 'summary' && !empty($item->summary)) {
-              $output = $sanitize ? text_sanitize($instance['settings']['text_processing'], $field_langcode, $item->getValue(), 'summary') : $item->summary;
+              $output = $sanitize ? text_sanitize($instance->settings['text_processing'], $field_langcode, $item->getValue(), 'summary') : $item->summary;
             }
             // Attempt to provide a suitable version of the 'body' field.
             else {
-              $output = $sanitize ? text_sanitize($instance['settings']['text_processing'], $field_langcode, $item->getValue(), 'value') : $item->value;
+              $output = $sanitize ? text_sanitize($instance->settings['text_processing'], $field_langcode, $item->getValue(), 'value') : $item->value;
               // A summary was requested.
               if ($name == 'summary') {
                 // Generate an optionally trimmed summary of the body field.
@@ -164,7 +164,7 @@ function node_tokens($type, $tokens, array $data = array(), array $options = arr
                   $length = $settings['trim_length'];
                 }
 
-                $output = text_summary($output, $instance['settings']['text_processing'] ? $item->format : NULL, $length);
+                $output = text_summary($output, $instance->settings['text_processing'] ? $item->format : NULL, $length);
               }
             }
             $replacements[$original] = $output;
diff --git a/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php b/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php
index f777f36..c51c972 100644
--- a/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php
+++ b/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php
@@ -95,7 +95,7 @@ function testNumberDecimalField() {
     // Display creation form.
     $this->drupalGet('entity_test/add');
     $langcode = Language::LANGCODE_NOT_SPECIFIED;
-    $this->assertFieldByName("{$this->field['field_name']}[$langcode][0][value]", '', 'Widget is displayed');
+    $this->assertFieldByName("{$this->field->id()}[$langcode][0][value]", '', 'Widget is displayed');
     $this->assertRaw('placeholder="0.00"');
 
     // Submit a signed decimal value within the allowed precision and scale.
@@ -103,7 +103,7 @@ function testNumberDecimalField() {
     $edit = array(
       'user_id' => 1,
       'name' => $this->randomName(),
-      "{$this->field['field_name']}[$langcode][0][value]" => $value,
+      "{$this->field->id()}[$langcode][0][value]" => $value,
     );
     $this->drupalPost(NULL, $edit, t('Save'));
     preg_match('|entity_test/manage/(\d+)/edit|', $this->url, $match);
@@ -123,10 +123,10 @@ function testNumberDecimalField() {
     foreach ($wrong_entries as $wrong_entry) {
       $this->drupalGet('entity_test/add');
       $edit = array(
-        "{$this->field['field_name']}[$langcode][0][value]" => $wrong_entry,
+        "{$this->field->id()}[$langcode][0][value]" => $wrong_entry,
       );
       $this->drupalPost(NULL, $edit, t('Save'));
-      $this->assertRaw(t('%name must be a number.', array('%name' => $this->field['field_name'])), 'Correctly failed to save decimal value with more than one decimal point.');
+      $this->assertRaw(t('%name must be a number.', array('%name' => $this->field->id())), 'Correctly failed to save decimal value with more than one decimal point.');
     }
 
     // Try to create entries with minus sign not in the first position.
@@ -141,10 +141,10 @@ function testNumberDecimalField() {
     foreach ($wrong_entries as $wrong_entry) {
       $this->drupalGet('entity_test/add');
       $edit = array(
-        "{$this->field['field_name']}[$langcode][0][value]" => $wrong_entry,
+        "{$this->field->id()}[$langcode][0][value]" => $wrong_entry,
       );
       $this->drupalPost(NULL, $edit, t('Save'));
-      $this->assertRaw(t('%name must be a number.', array('%name' => $this->field['field_name'])), 'Correctly failed to save decimal value with minus sign in the wrong position.');
+      $this->assertRaw(t('%name must be a number.', array('%name' => $this->field->id())), 'Correctly failed to save decimal value with minus sign in the wrong position.');
     }
   }
 
diff --git a/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUITest.php b/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUITest.php
index 34f0a87..b2cd397 100644
--- a/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUITest.php
+++ b/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUITest.php
@@ -232,9 +232,9 @@ function testOptionsAllowedValuesBoolean() {
     $this->assertFieldByName('on', $on, t("The 'On' value is stored correctly."));
     $this->assertFieldByName('off', $off, t("The 'Off' value is stored correctly."));
     $field = field_info_field('node', $this->field_name);
-    $this->assertEqual($field['settings']['allowed_values'], $allowed_values, 'The allowed value is correct');
-    $this->assertFalse(isset($field['settings']['on']), 'The on value is not saved into settings');
-    $this->assertFalse(isset($field['settings']['off']), 'The off value is not saved into settings');
+    $this->assertEqual($field->settings['allowed_values'], $allowed_values, 'The allowed value is correct');
+    $this->assertFalse(isset($field->settings['on']), 'The on value is not saved into settings');
+    $this->assertFalse(isset($field->settings['off']), 'The off value is not saved into settings');
   }
 
   /**
@@ -282,7 +282,7 @@ protected function createOptionsField($type) {
    *   element.
    * @param $result
    *   Either an expected resulting array in
-   *   $field['settings']['allowed_values'], or an expected error message.
+   *   $field->settings['allowed_values'], or an expected error message.
    * @param $message
    *   Message to display.
    */
@@ -296,7 +296,7 @@ function assertAllowedValuesInput($input_string, $result, $message) {
     else {
       field_info_cache_clear();
       $field = field_info_field('node', $this->field_name);
-      $this->assertIdentical($field['settings']['allowed_values'], $result, $message);
+      $this->assertIdentical($field->settings['allowed_values'], $result, $message);
     }
   }
 
diff --git a/core/modules/options/lib/Drupal/options/Tests/OptionsWidgetsTest.php b/core/modules/options/lib/Drupal/options/Tests/OptionsWidgetsTest.php
index bf76dc7..e251643 100644
--- a/core/modules/options/lib/Drupal/options/Tests/OptionsWidgetsTest.php
+++ b/core/modules/options/lib/Drupal/options/Tests/OptionsWidgetsTest.php
@@ -558,7 +558,7 @@ function testOnOffCheckboxLabelSetting() {
     ))->save();
 
     entity_get_form_display('node', 'page', 'default')
-      ->setComponent($this->bool['field_name'], array(
+      ->setComponent($this->bool->getFieldName(), array(
         'type' => 'options_onoff',
       ))
       ->save();
diff --git a/core/modules/options/options.install b/core/modules/options/options.install
index 6c2c8af..ae08db2 100644
--- a/core/modules/options/options.install
+++ b/core/modules/options/options.install
@@ -9,7 +9,7 @@
  * Implements hook_field_schema().
  */
 function options_field_schema($field) {
-  switch ($field['type']) {
+  switch ($field->type) {
     case 'list_text':
       $columns = array(
         'value' => array(
diff --git a/core/modules/options/options.module b/core/modules/options/options.module
index 6dedc11..ef83616 100644
--- a/core/modules/options/options.module
+++ b/core/modules/options/options.module
@@ -380,12 +380,12 @@ function options_field_update_forbid($field, $prior_field) {
 /**
  * Checks if a list of values are being used in actual field values.
  */
-function _options_values_in_use($field, $values) {
+function _options_values_in_use(FieldInterface $field, $values) {
   if ($values) {
-    $field = field_info_field_by_id($field['uuid']);
+    $field = field_info_field_by_id($field->uuid());
     $factory = Drupal::service('entity.query');
     $result = $factory->get($field->entity_type)
-      ->condition($field['field_name'] . '.value', $values)
+      ->condition($field->getFieldName() . '.value', $values)
       ->count()
       ->accessCheck(FALSE)
       ->range(0, 1)
diff --git a/core/modules/rest/lib/Drupal/rest/LinkManager/RelationLinkManager.php b/core/modules/rest/lib/Drupal/rest/LinkManager/RelationLinkManager.php
index 9c7815c..a6c26cd 100644
--- a/core/modules/rest/lib/Drupal/rest/LinkManager/RelationLinkManager.php
+++ b/core/modules/rest/lib/Drupal/rest/LinkManager/RelationLinkManager.php
@@ -75,12 +75,12 @@ protected function writeCache() {
     $data = array();
 
     foreach (field_info_fields() as $field) {
-      foreach ($field['bundles'] as $bundle) {
-        $relation_uri = $this->getRelationUri($field->entity_type, $bundle, $field->name);
+      foreach ($field->getBundles() as $bundle) {
+        $relation_uri = $this->getRelationUri($field->entity_type, $bundle, $field->getFieldName());
         $data[$relation_uri] = array(
           'entity_type' => $field->entity_type,
           'bundle' => $bundle,
-          'field_name' => $field->name,
+          'field_name' => $field->getFieldName(),
         );
       }
     }
diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationTest.php
index 7adfda3..5f25d80 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationTest.php
@@ -456,7 +456,7 @@ function testEntityTranslationAPI() {
     $entity = $this->reloadEntity($entity);
     $instance_id = implode('.', array($entity->entityType(), $entity->bundle(), $this->field_name));
     $instance = $this->entityManager->getStorageController('field_instance')->load($instance_id);
-    $instance['default_value_function'] = 'entity_test_field_default_value';
+    $instance->default_value_function = 'entity_test_field_default_value';
     $instance->save();
     $translation = $entity->addTranslation($langcode2);
     $this->assertEqual($translation->get($this->field_name)->value, $this->field_name . '_' . $langcode2, 'Language-aware default values correctly populated.');
diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php
index 59aef23..7803a80 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php
@@ -67,7 +67,7 @@ public function testEntityDisplayUpgrade() {
 
     // Check that the display key in the instance data was removed.
     $body_instance = field_info_instance('node', 'body', 'article');
-    $this->assertTrue(!isset($body_instance['display']));
+    $this->assertTrue(!isset($body_instance->display));
 
     // Check that the 'language' extra field is configured as expected.
     $expected = array(
@@ -106,7 +106,7 @@ public function testEntityFormDisplayUpgrade() {
 
     // Check that the display key in the instance data was removed.
     $body_instance = field_info_instance('node', 'body', 'article');
-    $this->assertTrue(!isset($body_instance['widget']));
+    $this->assertTrue(!isset($body_instance->widget));
 
     // Check that the 'title' extra field is configured as expected.
     $expected = array(
diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/UserPictureUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/UserPictureUpgradePathTest.php
index c8825af..88069a1 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/UserPictureUpgradePathTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/UserPictureUpgradePathTest.php
@@ -42,8 +42,8 @@ public function testUserPictureUpgrade() {
 
     // Retrieve the field instance and check for migrated settings.
     $instance = field_info_instance('user', 'user_picture', 'user');
-    $file = entity_load('file', $instance['settings']['default_image'][0]);
-    $this->assertIdentical($instance['settings']['default_image'][0], $file->id(), 'Default user picture has been migrated.');
+    $file = entity_load('file', $instance->settings['default_image'][0]);
+    $this->assertIdentical($instance->settings['default_image'][0], $file->id(), 'Default user picture has been migrated.');
     $this->assertEqual($file->getFileUri(), 'public://user_pictures_dir/druplicon.png', 'File id matches the uri expected.');
     $this->assertEqual($file->getFilename(), 'druplicon.png');
     $this->assertEqual($file->langcode->value, Language::LANGCODE_NOT_SPECIFIED);
@@ -53,12 +53,12 @@ public function testUserPictureUpgrade() {
     // Check file usage for the default image.
     $usage = file_usage()->listUsage($file);
     $field = field_info_field('user', 'user_picture');
-    $this->assertTrue(isset($usage['image']['default_image'][$field['uuid']]));
+    $this->assertTrue(isset($usage['image']['default_image'][$field->uuid()]));
 
-    $this->assertEqual($instance['settings']['max_resolution'], '800x800', 'User picture maximum resolution has been migrated.');
-    $this->assertEqual($instance['settings']['max_filesize'], '700 KB', 'User picture maximum filesize has been migrated.');
-    $this->assertEqual($instance['description'], 'These are user picture guidelines.', 'User picture guidelines are now the user picture field description.');
-    $this->assertEqual($instance['settings']['file_directory'], 'user_pictures_dir', 'User picture directory path has been migrated.');
+    $this->assertEqual($instance->settings['max_resolution'], '800x800', 'User picture maximum resolution has been migrated.');
+    $this->assertEqual($instance->settings['max_filesize'], '700 KB', 'User picture maximum filesize has been migrated.');
+    $this->assertEqual($instance->description, 'These are user picture guidelines.', 'User picture guidelines are now the user picture field description.');
+    $this->assertEqual($instance->settings['file_directory'], 'user_pictures_dir', 'User picture directory path has been migrated.');
 
     $display_options = entity_get_display('user', 'user', 'default')->getComponent('user_picture');
     $this->assertEqual($display_options['settings']['image_style'], 'thumbnail', 'User picture image style setting has been migrated.');
diff --git a/core/modules/system/tests/modules/entity_test/entity_test.module b/core/modules/system/tests/modules/entity_test/entity_test.module
index b401470..87658f3 100644
--- a/core/modules/system/tests/modules/entity_test/entity_test.module
+++ b/core/modules/system/tests/modules/entity_test/entity_test.module
@@ -476,7 +476,7 @@ function entity_test_entity_test_mul_translation_delete(EntityInterface $transla
  *   The field language code to fill-in with the default value.
  */
 function entity_test_field_default_value(EntityInterface $entity, Field $field, FieldInstance $instance, $langcode) {
-  return array(array('value' => $field['field_name'] . '_' . $langcode));
+  return array(array('value' => $field->getFieldName() . '_' . $langcode));
 }
 
 /**
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php
index 8c20176..4661b54 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php
@@ -122,8 +122,8 @@ public function postSave(EntityStorageControllerInterface $storage_controller, $
       $fields = field_read_fields();
       foreach ($fields as $field_name => $field) {
         $update_field = FALSE;
-        if ($field['type'] == 'taxonomy_term_reference') {
-          foreach ($field['settings']['allowed_values'] as $key => &$value) {
+        if ($field->type == 'taxonomy_term_reference') {
+          foreach ($field->settings['allowed_values'] as $key => &$value) {
             if ($value['vocabulary'] == $this->getOriginalID()) {
               $value['vocabulary'] = $this->id();
               $update_field = TRUE;
@@ -163,14 +163,14 @@ public static function postDelete(EntityStorageControllerInterface $storage_cont
       $modified_field = FALSE;
       // Term reference fields may reference terms from more than one
       // vocabulary.
-      foreach ($taxonomy_field['settings']['allowed_values'] as $key => $allowed_value) {
+      foreach ($taxonomy_field->settings['allowed_values'] as $key => $allowed_value) {
         if (isset($vocabularies[$allowed_value['vocabulary']])) {
-          unset($taxonomy_field['settings']['allowed_values'][$key]);
+          unset($taxonomy_field->settings['allowed_values'][$key]);
           $modified_field = TRUE;
         }
       }
       if ($modified_field) {
-        if (empty($taxonomy_field['settings']['allowed_values'])) {
+        if (empty($taxonomy_field->settings['allowed_values'])) {
           $taxonomy_field->delete();
         }
         else {
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php
index 4cfb173..702e50f 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php
@@ -127,7 +127,7 @@ function testTaxonomyTermFieldMultipleVocabularies() {
 
     // Verify that field and instance settings are correct.
     $field_info = field_info_field('entity_test', $this->field_name);
-    $this->assertEqual(count($field_info['settings']['allowed_values']), 1, 'Only one vocabulary is allowed for the field.');
+    $this->assertEqual(count($field_info->settings['allowed_values']), 1, 'Only one vocabulary is allowed for the field.');
 
     // The widget should still be displayed.
     $this->drupalGet('entity_test/add');
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php
index 1fee5c3..06f4891 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php
@@ -161,7 +161,7 @@ function testTaxonomyTermFieldChangeMachineName() {
 
     // Check that the field instance is still attached to the vocabulary.
     $field = field_info_field('entity_test', $this->field_name);
-    $allowed_values = $field['settings']['allowed_values'];
+    $allowed_values = $field->settings['allowed_values'];
     $this->assertEqual($allowed_values[0]['vocabulary'], $new_name, 'Index 0: Machine name was updated correctly.');
     $this->assertEqual($allowed_values[1]['vocabulary'], $new_name, 'Index 1: Machine name was updated correctly.');
     $this->assertEqual($allowed_values[2]['vocabulary'], 'foo', 'Index 2: Machine name was left untouched.');
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
index 53e65b4..a7ad2ac 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
@@ -56,7 +56,7 @@ function setUp() {
       ))
       ->save();
     entity_get_display('node', 'article', 'default')
-      ->setComponent($this->instance['field_name'], array(
+      ->setComponent($this->instance->getFieldName(), array(
         'type' => 'taxonomy_term_reference_link',
       ))
       ->save();
@@ -114,7 +114,7 @@ function testTaxonomyNode() {
     $langcode = Language::LANGCODE_NOT_SPECIFIED;
     $edit["title"] = $this->randomName();
     $edit["body[$langcode][0][value]"] = $this->randomName();
-    $edit[$this->instance['field_name'] . '[' . $langcode . '][]'] = $term1->id();
+    $edit[$this->instance->getFieldName() . '[' . $langcode . '][]'] = $term1->id();
     $this->drupalPost('node/add/article', $edit, t('Save'));
 
     // Check that the term is displayed when the node is viewed.
@@ -128,8 +128,8 @@ function testTaxonomyNode() {
     $this->assertText($term1->label(), 'Term is displayed after saving the node with no changes.');
 
     // Edit the node with a different term.
-    $edit[$this->instance['field_name'] . '[' . $langcode . '][]'] = $term2->id();
-    $this->drupalPost('node/' . $node->id() . '/edit', $edit, t('Save'));
+    $edit[$this->instance->getFieldName() . '[' . $langcode . '][]'] = $term2->id();
+    $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
 
     $this->drupalGet('node/' . $node->id());
     $this->assertText($term2->label(), 'Term is displayed when viewing the node.');
@@ -147,8 +147,8 @@ function testTaxonomyNode() {
   function testNodeTermCreationAndDeletion() {
     // Enable tags in the vocabulary.
     $instance = $this->instance;
-    entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')
-      ->setComponent($instance['field_name'], array(
+    entity_get_form_display($instance->entity_type, $instance->bundle, 'default')
+      ->setComponent($instance->getFieldName(), array(
         'type' => 'taxonomy_autocomplete',
         'settings' => array(
           'placeholder' => 'Start typing here.',
@@ -168,7 +168,7 @@ function testNodeTermCreationAndDeletion() {
     $edit["body[$langcode][0][value]"] = $this->randomName();
     // Insert the terms in a comma separated list. Vocabulary 1 is a
     // free-tagging field created by the default profile.
-    $edit[$instance['field_name'] . "[$langcode]"] = drupal_implode_tags($terms);
+    $edit[$instance->getFieldName() . "[$langcode]"] = drupal_implode_tags($terms);
 
     // Verify the placeholder is there.
     $this->drupalGet('node/add/article');
@@ -512,8 +512,8 @@ function testTaxonomyGetTermByName() {
   function testReSavingTags() {
     // Enable tags in the vocabulary.
     $instance = $this->instance;
-    entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')
-      ->setComponent($instance['field_name'], array(
+    entity_get_form_display($instance->entity_type, $instance->bundle, 'default')
+      ->setComponent($instance->getFieldName(), array(
         'type' => 'taxonomy_autocomplete',
       ))
       ->save();
@@ -524,7 +524,7 @@ function testReSavingTags() {
     $edit = array();
     $edit["title"] = $this->randomName(8);
     $edit["body[$langcode][0][value]"] = $this->randomName(16);
-    $edit[$this->instance['field_name'] . '[' . $langcode . ']'] = $term->label();
+    $edit[$this->instance->getFieldName() . '[' . $langcode . ']'] = $term->label();
     $this->drupalPost('node/add/article', $edit, t('Save'));
 
     // Check that the term is displayed when editing and saving the node with no
diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module
index 5769da0..8a09615 100644
--- a/core/modules/taxonomy/taxonomy.module
+++ b/core/modules/taxonomy/taxonomy.module
@@ -1122,7 +1122,7 @@ function taxonomy_build_node_index($node) {
     foreach (field_info_instances('node', $node->getType()) as $instance) {
       $field = $instance->getField();
       $field_name = $field->getFieldName();
-      if ($field['module'] == 'taxonomy') {
+      if ($field->module == 'taxonomy') {
         foreach ($node->getTranslationLanguages() as $language) {
           foreach ($node->getTranslation($language->id)->$field_name as $item) {
             if (!$item->isEmpty()) {
diff --git a/core/modules/taxonomy/taxonomy.views.inc b/core/modules/taxonomy/taxonomy.views.inc
index 9b37e9e..e44e8b7 100644
--- a/core/modules/taxonomy/taxonomy.views.inc
+++ b/core/modules/taxonomy/taxonomy.views.inc
@@ -344,16 +344,16 @@ function taxonomy_field_views_data(FieldInterface $field) {
     foreach ($table_data as $field_name => $field_data) {
       if (isset($field_data['filter']) && $field_name != 'delta') {
         $data[$table_name][$field_name]['filter']['id'] = 'taxonomy_index_tid';
-        $data[$table_name][$field_name]['filter']['vocabulary'] = $field['settings']['allowed_values'][0]['vocabulary'];
+        $data[$table_name][$field_name]['filter']['vocabulary'] = $field->settings['allowed_values'][0]['vocabulary'];
       }
     }
 
     // Add the relationship only on the tid field.
-    $data[$table_name][$field['field_name'] . '_target_id']['relationship'] = array(
+    $data[$table_name][$field->getFieldName() . '_target_id']['relationship'] = array(
       'id' => 'standard',
       'base' => 'taxonomy_term_data',
       'base field' => 'tid',
-      'label' => t('term from !field_name', array('!field_name' => $field['field_name'])),
+      'label' => t('term from !field_name', array('!field_name' => $field->getFieldName())),
     );
 
   }
@@ -367,24 +367,24 @@ function taxonomy_field_views_data(FieldInterface $field) {
  * Views integration to provide reverse relationships on term references.
  */
 function taxonomy_field_views_data_views_data_alter(array &$data, FieldInterface $field) {
-  $entity_type = $field['entity_type'];
+  $entity_type = $field->entity_type;
   $entity_info = entity_get_info($entity_type);
-  $pseudo_field_name = 'reverse_' . $field['field_name'] . '_' . $entity_type;
+  $pseudo_field_name = 'reverse_' . $field->getFieldName() . '_' . $entity_type;
 
-  list($label,) = field_views_field_label($entity_type, $field['field_name']);
+  list($label,) = field_views_field_label($entity_type, $field->getFieldName());
   $entity_label = ($entity_info['label'] == t('Node')) ? t('Content') : $entity_info['label'];
 
   $data['taxonomy_term_data'][$pseudo_field_name]['relationship'] = array(
     'title' => t('@entity using @field', array('@entity' => $entity_label, '@field' => $label)),
     'help' => t('Relate each @entity with a @field set to the term.', array('@entity' => $entity_label, '@field' => $label)),
     'id' => 'entity_reverse',
-    'field_name' => $field['field_name'],
-    'entity_type' => $field['entity_type'],
+    'field_name' => $field->getFieldName(),
+    'entity_type' => $field->entity_type,
     'field table' => DatabaseStorageController::_fieldTableName($field),
-    'field field' => $field['field_name'] . '_target_id',
+    'field field' => $field->getFieldName() . '_target_id',
     'base' => $entity_info['base_table'],
     'base field' => $entity_info['entity_keys']['id'],
-    'label' => t('!field_name', array('!field_name' => $field['field_name'])),
+    'label' => t('!field_name', array('!field_name' => $field->getFieldName())),
     'join_extra' => array(
       0 => array(
         'field' => 'deleted',
diff --git a/core/modules/text/lib/Drupal/text/TextProcessed.php b/core/modules/text/lib/Drupal/text/TextProcessed.php
index 352420d..fe7b181 100644
--- a/core/modules/text/lib/Drupal/text/TextProcessed.php
+++ b/core/modules/text/lib/Drupal/text/TextProcessed.php
@@ -69,7 +69,7 @@ public function getValue($langcode = NULL) {
     $entity = $field->getParent();
     $instance = field_info_instance($entity->entityType(), $field->getName(), $entity->bundle());
 
-    if (!empty($instance['settings']['text_processing']) && $this->format->getValue()) {
+    if (!empty($instance->settings['text_processing']) && $this->format->getValue()) {
       return check_markup($this->text->getValue(), $this->format->getValue(), $entity->language()->id);
     }
     else {
diff --git a/core/modules/text/text.install b/core/modules/text/text.install
index 72d879f..d87d7f7 100644
--- a/core/modules/text/text.install
+++ b/core/modules/text/text.install
@@ -9,12 +9,12 @@
  * Implements hook_field_schema().
  */
 function text_field_schema($field) {
-  switch ($field['type']) {
+  switch ($field->type) {
     case 'text':
       $columns = array(
         'value' => array(
           'type' => 'varchar',
-          'length' => $field['settings']['max_length'],
+          'length' => $field->settings['max_length'],
           'not null' => FALSE,
         ),
       );
diff --git a/core/modules/views_ui/admin.inc b/core/modules/views_ui/admin.inc
index aeea6b2..0c15197 100644
--- a/core/modules/views_ui/admin.inc
+++ b/core/modules/views_ui/admin.inc
@@ -226,8 +226,8 @@ function views_ui_taxonomy_autocomplete_validate($element, &$form_state) {
     // vocabulary IDs.
     $field = field_info_field($element['#entity_type'], $element['#field_name']);
     $vocabularies = array();
-    if (!empty($field['settings']['allowed_values'])) {
-      foreach ($field['settings']['allowed_values'] as $tree) {
+    if (!empty($field->settings['allowed_values'])) {
+      foreach ($field->settings['allowed_values'] as $tree) {
         if ($vocabulary = entity_load('taxonomy_vocabulary', $tree['vocabulary'])) {
           $vocabularies[$vocabulary->id()] = $tree['vocabulary'];
         }
diff --git a/core/scripts/generate-d7-content.sh b/core/scripts/generate-d7-content.sh
index 87ec22a..8a86cef 100644
--- a/core/scripts/generate-d7-content.sh
+++ b/core/scripts/generate-d7-content.sh
@@ -98,7 +98,7 @@
   foreach ($node_types as $bundle) {
     $instance = array(
       'label' => $vocabulary->name,
-      'field_name' => $field['field_name'],
+      'field_name' => $field->id(),
       'bundle' => $bundle,
       'entity_type' => 'node',
       'settings' => array(),
