diff --git a/core/lib/Drupal/Core/Entity/EntityManager.php b/core/lib/Drupal/Core/Entity/EntityManager.php
index e34adb6..8d0f752 100644
--- a/core/lib/Drupal/Core/Entity/EntityManager.php
+++ b/core/lib/Drupal/Core/Entity/EntityManager.php
@@ -283,7 +283,7 @@ protected function processDefinition(&$definition, $plugin_id) {
     }
     // Prepare entity schema fields SQL info for
     // Drupal\Core\Entity\DatabaseStorageControllerInterface::buildQuery().
-    if (isset($definition['base_table'])) {
+    if (isset($definition['base_table']) && drupal_get_schema($definition['base_table']) !== FALSE) {
       $definition['schema_fields_sql']['base_table'] = drupal_schema_fields_sql($definition['base_table']);
       if (isset($definition['revision_table'])) {
         $definition['schema_fields_sql']['revision_table'] = drupal_schema_fields_sql($definition['revision_table']);
diff --git a/core/modules/comment/comment.install b/core/modules/comment/comment.install
index 48bb5a4..2c6d416 100644
--- a/core/modules/comment/comment.install
+++ b/core/modules/comment/comment.install
@@ -16,7 +16,7 @@ function comment_uninstall() {
   variable_del('comment_block_count');
   $node_types = array_keys(node_type_get_types());
   foreach ($node_types as $node_type) {
-    field_attach_delete_bundle('comment', 'comment_node_' . $node_type);
+    field_attach_delete_bundle('comment', 'comment_node_' . $node_type, FALSE);
     variable_del('comment_' . $node_type);
     variable_del('comment_anonymous_' . $node_type);
     variable_del('comment_controls_' . $node_type);
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentFieldsTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentFieldsTest.php
index ab03d41..6fd47ab 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentFieldsTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentFieldsTest.php
@@ -41,7 +41,7 @@ function testCommentDefaultFields() {
       $this->assertTrue(isset($instances['comment_node_' . $type_name]['comment_body']), format_string('The comment_body field is present for comments on type @type', array('@type' => $type_name)));
 
       // Delete the instance along the way.
-      field_delete_instance($instances['comment_node_' . $type_name]['comment_body']);
+      field_delete_instance($instances['comment_node_' . $type_name]['comment_body']->getArray());
     }
 
     // Check that the 'comment_body' field is deleted.
diff --git a/core/modules/field/field.attach.inc b/core/modules/field/field.attach.inc
index 29ebd3b..aa0d361 100644
--- a/core/modules/field/field.attach.inc
+++ b/core/modules/field/field.attach.inc
@@ -1585,11 +1585,19 @@ function field_attach_create_bundle($entity_type, $bundle) {
  *   The new name of the bundle.
  */
 function field_attach_rename_bundle($entity_type, $bundle_old, $bundle_new) {
-  db_update('field_config_instance')
-    ->fields(array('bundle' => $bundle_new))
-    ->condition('entity_type', $entity_type)
-    ->condition('bundle', $bundle_old)
-    ->execute();
+  $instances = field_read_instances();
+  foreach ($instances as $id => $instance) {
+    if ($instance['entity_type'] == $entity_type && $instance['bundle'] == $bundle_old) {
+      // @fieldcmi
+      $new_instance_id = $instance['entity_type'] . '.' . $bundle_new . '.' . $instance['field_name'];
+      config('field.instance.' . $instance['entity_type'] . '.' . $bundle_old . '.' . $instance['field_name'])->rename('field.instance.' . $new_instance_id);
+      config('field.instance.' . $instance['entity_type'] . '.' . $bundle_new . '.' . $instance['field_name'])
+        ->set('data.bundle', $bundle_new)
+        ->set('id', $new_instance_id)
+        ->set('label', $new_instance_id)
+        ->save();
+    }
+  }
 
   // Clear the cache.
   field_cache_clear();
@@ -1605,7 +1613,7 @@ function field_attach_rename_bundle($entity_type, $bundle_old, $bundle_new) {
 }
 
 /**
- * Notifies field.module the a bundle was deleted.
+ * Notifies field.module that a bundle was deleted.
  *
  * This deletes the data for the field instances as well as the field instances
  * themselves. This function actually just marks the data and field instances as
@@ -1618,14 +1626,18 @@ function field_attach_rename_bundle($entity_type, $bundle_old, $bundle_new) {
  *   The entity type to which the bundle is bound.
  * @param $bundle
  *   The bundle to delete.
+ * @param $field_cleanup
+ *   If TRUE, the field will be deleted as well if its last instance is being
+ *   deleted. If FALSE, it is the caller's responsibility to handle the case of
+ *   fields left without instances. Defaults to TRUE.
  */
-function field_attach_delete_bundle($entity_type, $bundle) {
+function field_attach_delete_bundle($entity_type, $bundle, $field_cleanup = TRUE) {
   // First, delete the instances themselves. field_read_instances() must be
   // used here since field_info_instances() does not return instances for
   // disabled entity types or bundles.
   $instances = field_read_instances(array('entity_type' => $entity_type, 'bundle' => $bundle), array('include_inactive' => 1));
   foreach ($instances as $instance) {
-    field_delete_instance($instance);
+    field_delete_instance($instance, $field_cleanup);
   }
 
   // Clear the cache.
diff --git a/core/modules/field/field.crud.inc b/core/modules/field/field.crud.inc
index b8e2015..06e6297 100644
--- a/core/modules/field/field.crud.inc
+++ b/core/modules/field/field.crud.inc
@@ -6,6 +6,7 @@
  */
 
 use Drupal\field\FieldException;
+use Drupal\Field\FieldInstance;
 
 /**
  * @defgroup field_crud Field CRUD API
@@ -148,52 +149,48 @@ function field_create_field($field) {
   );
   $field['indexes'] += $schema['indexes'];
 
-  // The serialized 'data' column contains everything from $field that does not
-  // have its own column and is not automatically populated when the field is
-  // read.
-  $data = $field;
-  unset($data['columns'], $data['field_name'], $data['type'], $data['active'], $data['module'], $data['storage_type'], $data['storage_active'], $data['storage_module'], $data['locked'], $data['cardinality'], $data['deleted']);
-  // Additionally, do not save the 'bundles' property populated by
-  // field_info_field().
-  unset($data['bundles']);
-
-  $record = array(
-    'field_name' => $field['field_name'],
-    'type' => $field['type'],
-    'module' => $field['module'],
-    'active' => $field['active'],
+  $field += array(
     'storage_type' => $field['storage']['type'],
     'storage_module' => $field['storage']['module'],
     'storage_active' => $field['storage']['active'],
-    'locked' => $field['locked'],
-    'data' => $data,
-    'cardinality' => $field['cardinality'],
-    'translatable' => $field['translatable'],
-    'deleted' => $field['deleted'],
   );
 
-  // Store the field and get the id back.
-  drupal_write_record('field_config', $record);
-  $field['id'] = $record['id'];
+  // Do not save the 'bundles' property populated by
+  // field_info_field().
+  unset($field['bundles']);
+
+  // Generate id for the field.
+  $field['id'] = field_generate_id();
+
+  // Save the configuration.
+  // @fieldcmi
+
+  $e_field = entity_create('fieldentity', array(
+    'id' => $field['field_name'],
+    'label' => $field['field_name'],
+    'data' => $field,
+  ));
+//  $e_field->data = $field;
+  $e_field->save();
+  //config('field.field.' . $field['field_name'])->setData($field)->save();
 
   // Invoke hook_field_storage_create_field after the field is
   // complete (e.g. it has its id).
   try {
-    // Invoke hook_field_storage_create_field after
-    // drupal_write_record() sets the field id.
+    // Invoke hook_field_storage_create_field.
     module_invoke($storage_type['module'], 'field_storage_create_field', $field);
   }
   catch (Exception $e) {
     // If storage creation failed, remove the field_config record before
     // rethrowing the exception.
-    db_delete('field_config')
-      ->condition('id', $field['id'])
-      ->execute();
+    // @fieldcmi
+    entity_delete_multiple('fieldentity', array($field['field_name']));
+    //config('field.field.' . $field['field_name'])->delete();
     throw $e;
   }
 
   // Clear caches
-  field_cache_clear(TRUE);
+  field_cache_clear();
 
   // Invoke external hooks after the cache is cleared for API consistency.
   module_invoke_all('field_create_field', $field);
@@ -272,26 +269,19 @@ function field_update_field($field) {
   $storage_type = field_info_storage_types($field['storage']['type']);
   module_invoke($storage_type['module'], 'field_storage_update_field', $field, $prior_field, $has_data);
 
-  // Save the new field definition. @todo: refactor with
-  // field_create_field.
-
-  // The serialized 'data' column contains everything from $field that does not
-  // have its own column and is not automatically populated when the field is
-  // read.
-  $data = $field;
-  unset($data['columns'], $data['field_name'], $data['type'], $data['locked'], $data['module'], $data['cardinality'], $data['active'], $data['deleted']);
   // Additionally, do not save the 'bundles' property populated by
   // field_info_field().
-  unset($data['bundles']);
-
-  $field['data'] = $data;
+  unset($field['bundles']);
 
-  // Store the field and create the id.
-  $primary_key = array('id');
-  drupal_write_record('field_config', $field, $primary_key);
+  // Store the field.
+  // @fieldcmi
+  $e_field = entity_load('fieldentity',  $field['field_name']);
+  $e_field->data = $field;
+  $e_field->save();
+  //config('field.field.' . $field['field_name'])->setData($field)->save();
 
   // Clear caches
-  field_cache_clear(TRUE);
+  field_cache_clear();
 
   // Invoke external hooks after the cache is cleared for API consistency.
   module_invoke_all('field_update_field', $field, $prior_field, $has_data);
@@ -341,50 +331,46 @@ function field_read_field($field_name, $include_additional = array()) {
  *   field ID, otherwise it is keyed by field name.
  */
 function field_read_fields($params = array(), $include_additional = array()) {
-  $query = db_select('field_config', 'fc', array('fetch' => PDO::FETCH_ASSOC));
-  $query->fields('fc');
-
-  // Turn the conditions into a query.
-  foreach ($params as $key => $value) {
-    // Allow filtering on the 'entity_type' and 'bundle' columns of the
-    // field_config_instance table.
-    if ($key == 'entity_type' || $key == 'bundle') {
-      if (empty($fci_join)) {
-        $fci_join = $query->join('field_config_instance', 'fci', 'fc.id = fci.field_id');
-      }
-      $key = 'fci.' . $key;
-    }
+  $fields = array();
 
-    $query->condition($key, $value);
+  // Check if we need to retrieve deleted fields.
+  $include_deleted = (isset($include_additional['include_deleted']) && $include_additional['include_deleted']) || (isset($params['deleted']) && $params['deleted']);
+  if ($include_deleted) {
+    $deleted_fields = state()->get('field.field.deleted') ?: array();
   }
 
+  // Add active and storage active parameters.
   if (!isset($include_additional['include_inactive']) || !$include_additional['include_inactive']) {
-    $query
-      ->condition('fc.active', 1)
-      ->condition('fc.storage_active', 1);
+    $params['active'] = 1;
+    $params['storage_active'] = 1;
   }
-  $include_deleted = (isset($include_additional['include_deleted']) && $include_additional['include_deleted']);
-  if (!$include_deleted) {
-    $query->condition('fc.deleted', 0);
+
+  // Get configuration fields.
+  // @fieldcmi
+  // $config_fields = config_get_storage_names_with_prefix('field.field');
+  $config_fields = entity_load_multiple('fieldentity');
+  // Merge deleted fields.
+  if (!empty($deleted_fields)) {
+    $config_fields += $deleted_fields;
   }
 
-  $fields = array();
-  $results = $query->execute();
-  foreach ($results as $record) {
-    $field = unserialize($record['data']);
-    $field['id'] = $record['id'];
-    $field['field_name'] = $record['field_name'];
-    $field['type'] = $record['type'];
-    $field['module'] = $record['module'];
-    $field['active'] = $record['active'];
-    $field['storage']['type'] = $record['storage_type'];
-    $field['storage']['module'] = $record['storage_module'];
-    $field['storage']['active'] = $record['storage_active'];
-    $field['locked'] = $record['locked'];
-    $field['cardinality'] = $record['cardinality'];
-    $field['translatable'] = $record['translatable'];
-    $field['deleted'] = $record['deleted'];
+  foreach ($config_fields as $config) {
+    // @fieldcmi
+    if (is_object($config)) {
+      $field = $config->data;
+    }
+    else {
+      $field = $config;
+    }
+
+    // Conditions.
+    foreach ($params as $key => $value) {
+      if ($field[$key] != $value) {
+        continue 2;
+      }
+    }
 
+    // Invoke read field.
     module_invoke_all('field_read_field', $field);
 
     // Populate storage information.
@@ -411,11 +397,12 @@ function field_read_fields($params = array(), $include_additional = array()) {
 function field_delete_field($field_name) {
   // Delete all non-deleted instances.
   $field = field_info_field($field_name);
+
   if (isset($field['bundles'])) {
     foreach ($field['bundles'] as $entity_type => $bundles) {
       foreach ($bundles as $bundle) {
         $instance = field_info_instance($entity_type, $field_name, $bundle);
-        field_delete_instance($instance, FALSE);
+        field_delete_instance($instance->getArray(), FALSE);
       }
     }
   }
@@ -423,14 +410,19 @@ function field_delete_field($field_name) {
   // Mark field data for deletion.
   module_invoke($field['storage']['module'], 'field_storage_delete_field', $field);
 
-  // Mark the field for deletion.
-  db_update('field_config')
-    ->fields(array('deleted' => 1))
-    ->condition('field_name', $field_name)
-    ->execute();
+  // Delete the configuration of this field and save the field configuration
+  // in the key_value table so we can use it later during field_purge_batch().
+  // This makes sure a new field can be created immediately with the same name.
+  $deleted_fields = state()->get('field.field.deleted') ?: array();
+  $field['deleted'] = TRUE;
+  $deleted_fields[$field['id']] = $field;
+  state()->set('field.field.deleted', $deleted_fields);
+  // @fieldcmi
+  entity_delete_multiple('fieldentity', array($field['field_name']));
+  //config('field.field.' . $field['field_name'])->delete();
 
   // Clear the cache.
-  field_cache_clear(TRUE);
+  field_cache_clear();
 
   module_invoke_all('field_delete_field', $field);
 }
@@ -490,6 +482,9 @@ function field_create_instance(&$instance) {
   // Set the field id.
   $instance['field_id'] = $field['id'];
 
+  // Generate id for the instance.
+  $instance['id'] = field_generate_id();
+
   // Note that we do *not* prevent creating a field on non-existing bundles,
   // because that would break the 'Body as field' upgrade for contrib
   // node types.
@@ -509,7 +504,7 @@ function field_create_instance(&$instance) {
     throw new FieldException($message);
   }
 
-  _field_write_instance($instance);
+  _field_write_instance($instance, TRUE);
 
   // Clear caches
   field_cache_clear();
@@ -554,7 +549,7 @@ function field_update_instance($instance) {
   $instance['id'] = $prior_instance['id'];
   $instance['field_id'] = $prior_instance['field_id'];
 
-  _field_write_instance($instance, TRUE);
+  _field_write_instance($instance);
 
   // Clear caches.
   field_cache_clear();
@@ -567,10 +562,8 @@ function field_update_instance($instance) {
  *
  * @param $instance
  *   An instance structure.
- * @param $update
- *   Whether this is a new or existing instance.
  */
-function _field_write_instance(&$instance, $update = FALSE) {
+function _field_write_instance(&$instance, $create = TRUE) {
   $field = field_read_field($instance['field_name']);
   $field_type = field_info_field_types($field['type']);
 
@@ -595,7 +588,6 @@ function _field_write_instance(&$instance, $update = FALSE) {
 
   // Set default instance settings.
   $instance['settings'] += field_info_instance_settings($field['type']);
-
   // Set default widget and settings.
   $instance['widget'] += array(
     // TODO: what if no 'default_widget' specified ?
@@ -636,30 +628,21 @@ function _field_write_instance(&$instance, $update = FALSE) {
     $instance['display'][$view_mode] = $display;
   }
 
-  // The serialized 'data' column contains everything from $instance that does
-  // not have its own column and is not automatically populated when the
-  // instance is read.
-  $data = $instance;
-  unset($data['id'], $data['field_id'], $data['field_name'], $data['entity_type'], $data['bundle'], $data['deleted']);
-
-  $record = array(
-    'field_id' => $instance['field_id'],
-    'field_name' => $instance['field_name'],
-    'entity_type' => $instance['entity_type'],
-    'bundle' => $instance['bundle'],
-    'data' => $data,
-    'deleted' => $instance['deleted'],
-  );
-  // We need to tell drupal_update_record() the primary keys to trigger an
-  // update.
-  if ($update) {
-    $record['id'] = $instance['id'];
-    drupal_write_record('field_config_instance', $record, array('id'));
+  // Save into config.
+  //config('field.instance.' . $instance['entity_type'] . '.' . $instance['bundle'] . '.' . $instance['field_name'])->setData($instance)->save();
+  // @fieldcmi
+  if ($create) {
+    $e_instance = entity_create('instance', array(
+      'id' => $instance['entity_type'] . '.' . $instance['bundle'] . '.' . $instance['field_name'],
+      'label' => $instance['entity_type'] . '.' . $instance['bundle'] . '.' . $instance['field_name'],
+      'data' => $instance,
+    ));
   }
   else {
-    drupal_write_record('field_config_instance', $record);
-    $instance['id'] = $record['id'];
+    $e_instance = entity_load('instance', $instance['entity_type'] . '.' . $instance['bundle'] . '.' . $instance['field_name']);
+    $e_instance->data = $instance;
   }
+  $e_instance->save();
 }
 
 /**
@@ -694,8 +677,8 @@ function field_read_instance($entity_type, $field_name, $bundle, $include_additi
  *
  * @param $param
  *   An array of properties to use in selecting a field instance. Valid keys
- *   include any column of the field_config_instance table. If NULL, all
- *   instances will be returned.
+ *  include any property of the instance config object, except for data.
+ *  If NULL, all instances will be returned.
  * @param $include_additional
  *   The default behavior of this function is to not return field instances that
  *   have been marked deleted, or whose field is inactive. Setting
@@ -706,44 +689,77 @@ function field_read_instance($entity_type, $field_name, $bundle, $include_additi
  *   An array of instances matching the arguments.
  */
 function field_read_instances($params = array(), $include_additional = array()) {
-  $include_inactive = isset($include_additional['include_inactive']) && $include_additional['include_inactive'];
-  $include_deleted = isset($include_additional['include_deleted']) && $include_additional['include_deleted'];
+  $instances = array();
 
-  $query = db_select('field_config_instance', 'fci', array('fetch' => PDO::FETCH_ASSOC));
-  $query->join('field_config', 'fc', 'fc.id = fci.field_id');
-  $query->fields('fci');
+  $deleted_fields = state()->get('field.field.deleted');
+  $include_inactive = isset($include_additional['include_inactive']) && $include_additional['include_inactive'];
+  $include_deleted = (isset($include_additional['include_deleted']) && $include_additional['include_deleted']) || (isset($params['deleted']) && $params['deleted']);
 
-  // Turn the conditions into a query.
-  foreach ($params as $key => $value) {
-    $query->condition('fci.' . $key, $value);
+  if ($include_deleted) {
+    $deleted_instances = state()->get('field.instance.deleted') ?: array();
   }
-  if (!$include_inactive) {
-    $query
-      ->condition('fc.active', 1)
-      ->condition('fc.storage_active', 1);
-  }
-  if (!$include_deleted) {
-    $query->condition('fc.deleted', 0);
-    $query->condition('fci.deleted', 0);
+
+  // Get configuration instances.
+  // @fieldcmi
+  //$config_instances = config_get_storage_names_with_prefix('field.instance');
+  $config_instances = entity_load_multiple('instance');
+  // Merge deleted instances.
+  if (!empty($deleted_instances)) {
+    $config_instances += $deleted_instances;
   }
 
-  $instances = array();
-  $results = $query->execute();
+  foreach ($config_instances as $config) {
+    if (is_object($config)) {
+      $instance = $config->data;
+    }
+    else {
+      $instance = $config;
+    }
+
+    $entity_info = entity_get_info($instance['entity_type']);
+
+    // Get data from the field. If the field is marked as deleted, we
+    // need to get it from the state storage.
+    //$field = config('field.field.' . $instance['field_name'])->get();
+    $field = entity_load('fieldentity', $instance['field_name']);
+    if (is_object($field)) {
+      $field = $field->data;
+    }
+    if ($include_deleted) {
+      if (empty($field) && isset($deleted_fields[$instance['field_id']])) {
+        $field = $deleted_fields[$instance['field_id']];
+      }
+    }
+    if (empty($field)) {
+      continue;
+    }
+
+    $instance['active'] = $field['active'];
+    $instance['locked'] = $field['locked'];
+    $instance['type'] = $field['type'];
+    $instance['module'] = $field['module'];
+    $instance['storage_type'] = $field['storage_type'];
+    $instance['storage_active'] = $field['storage_active'];
+    $instance['storage_module'] = $field['storage_module'];
 
-  foreach ($results as $record) {
-    // Filter out instances on unknown entity types (for instance because the
-    // module exposing them was disabled).
-    $entity_info = entity_get_info($record['entity_type']);
     if ($include_inactive || $entity_info) {
-      $instance = unserialize($record['data']);
-      $instance['id'] = $record['id'];
-      $instance['field_id'] = $record['field_id'];
-      $instance['field_name'] = $record['field_name'];
-      $instance['entity_type'] = $record['entity_type'];
-      $instance['bundle'] = $record['bundle'];
-      $instance['deleted'] = $record['deleted'];
+      // Conditions.
+      if (!$include_inactive) {
+        $params['active'] = 1;
+        $params['storage_active'] = 1;
+      }
+      if (!$include_deleted) {
+        $params['deleted'] = 0;
+      }
+      foreach ($params as $key => $value) {
+        if ($instance[$key] != $value) {
+          continue 2;
+        }
+      }
 
+      // Invoke read instance.
       module_invoke_all('field_read_instance', $instance);
+
       $instances[] = $instance;
     }
   }
@@ -761,13 +777,16 @@ function field_read_instances($params = array(), $include_additional = array())
  *   fields left without instances. Defaults to TRUE.
  */
 function field_delete_instance($instance, $field_cleanup = TRUE) {
-  // Mark the field instance for deletion.
-  db_update('field_config_instance')
-    ->fields(array('deleted' => 1))
-    ->condition('field_name', $instance['field_name'])
-    ->condition('entity_type', $instance['entity_type'])
-    ->condition('bundle', $instance['bundle'])
-    ->execute();
+
+  // Delete the configuration of this instance and save the configuration
+  // in the key_value table so we can use it later during field_purge_batch().
+  $deleted_instances = state()->get('field.instance.deleted') ?: array();
+  $instance['deleted'] = TRUE;
+  $deleted_instances[$instance['id']] = $instance;
+  state()->set('field.instance.deleted', $deleted_instances);
+  // @fieldcmi
+  entity_load('instance', $instance['entity_type'] . '.' . $instance['bundle'] . '.' . $instance['field_name'])->delete();
+  //config('field.instance.' . $instance['entity_type'] . '.' . $instance['bundle'] . '.' . $instance['field_name'])->delete();
 
   // Clear the cache.
   field_cache_clear();
@@ -915,8 +934,8 @@ function field_purge_batch($batch_size) {
   }
 
   // Retrieve all deleted fields. Any that have no instances can be purged.
-  $fields = field_read_fields(array('deleted' => 1), array('include_deleted' => 1));
-  foreach ($fields as $field) {
+  $deleted_fields = state()->get('field.field.deleted') ?: array();
+  foreach ($deleted_fields as $field) {
     $instances = field_read_instances(array('field_id' => $field['id']), array('include_deleted' => 1));
     if (empty($instances)) {
       field_purge_field($field);
@@ -966,14 +985,14 @@ function field_purge_data($entity_type, $entity, $field, $instance) {
  *   The instance record to purge.
  */
 function field_purge_instance($instance) {
-  db_delete('field_config_instance')
-    ->condition('id', $instance['id'])
-    ->execute();
-
   // Notify the storage engine.
   $field = field_info_field_by_id($instance['field_id']);
   module_invoke($field['storage']['module'], 'field_storage_purge_instance', $instance);
 
+  $deleted_instances = state()->get('field.instance.deleted');
+  unset($deleted_instances[$instance['id']]);
+  state()->set('field.instance.deleted', $deleted_instances);
+
   // Clear the cache.
   field_info_cache_clear();
 
@@ -996,9 +1015,9 @@ function field_purge_field($field) {
     throw new FieldException(t('Attempt to purge a field @field_name that still has instances.', array('@field_name' => $field['field_name'])));
   }
 
-  db_delete('field_config')
-    ->condition('id', $field['id'])
-    ->execute();
+  $deleted_fields = state()->get('field.field.deleted');
+  unset($deleted_fields[$field['id']]);
+  state()->set('field.field.deleted', $deleted_fields);
 
   // Notify the storage engine.
   module_invoke($field['storage']['module'], 'field_storage_purge_field', $field);
diff --git a/core/modules/field/field.info b/core/modules/field/field.info
index 88529e2..75b1bed 100644
--- a/core/modules/field/field.info
+++ b/core/modules/field/field.info
@@ -3,6 +3,5 @@ description = Field API to add fields to entities like nodes and users.
 package = Core
 version = VERSION
 core = 8.x
-dependencies[] = field_sql_storage
 required = TRUE
 stylesheets[all][] = theme/field.css
diff --git a/core/modules/field/field.install b/core/modules/field/field.install
index bc566d6..398d7c5 100644
--- a/core/modules/field/field.install
+++ b/core/modules/field/field.install
@@ -9,158 +9,7 @@
  * Implements hook_schema().
  */
 function field_schema() {
-  // Static (meta) tables.
-  $schema['field_config'] = array(
-    'fields' => array(
-      'id' => array(
-        'type' => 'serial',
-        'not null' => TRUE,
-        'description' => 'The primary identifier for a field',
-      ),
-      'field_name' => array(
-        'type' => 'varchar',
-        'length' => 32,
-        'not null' => TRUE,
-        'description' => 'The name of this field. Non-deleted field names are unique, but multiple deleted fields can have the same name.',
-      ),
-      'type' => array(
-        'type' => 'varchar',
-        'length' => 128,
-        'not null' => TRUE,
-        'description' => 'The type of this field.',
-      ),
-     'module' => array(
-        'type' => 'varchar',
-        'length' => 128,
-        'not null' => TRUE,
-        'default' => '',
-        'description' => 'The module that implements the field type.',
-      ),
-      'active' => array(
-        'type' => 'int',
-        'size' => 'tiny',
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'Boolean indicating whether the module that implements the field type is enabled.',
-      ),
-      'storage_type' => array(
-        'type' => 'varchar',
-        'length' => 128,
-        'not null' => TRUE,
-        'description' => 'The storage backend for the field.',
-      ),
-      'storage_module' => array(
-        'type' => 'varchar',
-        'length' => 128,
-        'not null' => TRUE,
-        'default' => '',
-        'description' => 'The module that implements the storage backend.',
-      ),
-      'storage_active' => array(
-        'type' => 'int',
-        'size' => 'tiny',
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'Boolean indicating whether the module that implements the storage backend is enabled.',
-      ),
-      'locked' => array(
-        'type' => 'int',
-        'size' => 'tiny',
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => '@TODO',
-      ),
-      'data' => array(
-        'type' => 'blob',
-        'size' => 'big',
-        'not null' => TRUE,
-        'serialize' => TRUE,
-        'description' => 'Serialized data containing the field properties that do not warrant a dedicated column.',
-      ),
-      'cardinality' => array(
-        'type' => 'int',
-        'size' => 'tiny',
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-      'translatable' => array(
-        'type' => 'int',
-        'size' => 'tiny',
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-      'deleted' => array(
-        'type' => 'int',
-        'size' => 'tiny',
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-    ),
-    'primary key' => array('id'),
-    'indexes' => array(
-      'field_name' => array('field_name'),
-      // Used by field_read_fields().
-      'active' => array('active'),
-      'storage_active' => array('storage_active'),
-      'deleted' => array('deleted'),
-      // Used by field_sync_field_status().
-      'module' => array('module'),
-      'storage_module' => array('storage_module'),
-      'type' => array('type'),
-      'storage_type' => array('storage_type'),
-    ),
-  );
-  $schema['field_config_instance'] = array(
-    'fields' => array(
-      'id' => array(
-        'type' => 'serial',
-        'not null' => TRUE,
-        'description' => 'The primary identifier for a field instance',
-      ),
-      'field_id' => array(
-        'type' => 'int',
-        'not null' => TRUE,
-        'description' => 'The identifier of the field attached by this instance',
-      ),
-      'field_name' => array(
-        'type' => 'varchar',
-        'length' => 32,
-        'not null' => TRUE,
-        'default' => ''
-      ),
-      'entity_type'       => array(
-        'type' => 'varchar',
-        'length' => 32,
-        'not null' => TRUE,
-        'default' => ''
-      ),
-      'bundle' => array(
-        'type' => 'varchar',
-        'length' => 128,
-        'not null' => TRUE,
-        'default' => ''
-      ),
-      'data' => array(
-        'type' => 'blob',
-        'size' => 'big',
-        'not null' => TRUE,
-        'serialize' => TRUE,
-      ),
-      'deleted' => array(
-        'type' => 'int',
-        'size' => 'tiny',
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-    ),
-    'primary key' => array('id'),
-    'indexes' => array(
-      // Used by field_delete_instance().
-      'field_name_bundle' => array('field_name', 'entity_type', 'bundle'),
-      // Used by field_read_instances().
-      'deleted' => array('deleted'),
-    ),
-  );
+
   $schema['cache_field'] = drupal_get_schema_unprocessed('system', 'cache');
   $schema['cache_field']['description'] = 'Cache table for the Field module to store already built field informations.';
 
@@ -271,7 +120,6 @@ function _update_7000_field_delete_field($field_name) {
     ->execute();
 }
 
-
 /**
  * Deletes an instance and all its data of a field stored in SQL Storage.
  *
@@ -382,15 +230,131 @@ function _update_7000_field_create_instance($field, &$instance) {
  */
 
 /**
- * Reassign all list.module fields to be controlled by options.module.
+ * Convert Field API to CMI.
  */
 function field_update_8001() {
-  db_update('field_config')
-    ->fields(array(
-      'module' => 'options',
-    ))
-    ->condition('module', 'list')
-    ->execute();
+
+  // Changes field language into langcode. This used to be in field_sql_storage
+  // but needs to be here, because otherwhise _update_7000_field_read_fields()
+  // would fail.
+
+  // Prepare updated schema data structures.
+  $primary_key_data = array (
+    'entity_type',
+    'entity_id',
+    'deleted',
+    'delta',
+    'langcode',
+  );
+  $primary_key_revision = array (
+    'entity_type',
+    'entity_id',
+    'revision_id',
+    'deleted',
+    'delta',
+    'langcode',
+  );
+  $langcode_index = array(
+    'langcode',
+  );
+  $field_langcode = array(
+    'type' => 'varchar',
+    'length' => 32,
+    'not null' => true,
+    'default' => '',
+  );
+
+  // Retrieve field data.
+  $fields = _update_7000_field_read_fields(array('storage_type' => 'field_sql_storage'));
+
+  // Update schema.
+  foreach ($fields as $field) {
+    $data_table = _field_sql_storage_tablename($field);
+    if (db_table_exists($data_table)) {
+      $revision_table = _field_sql_storage_revision_tablename($field);
+      $table_info = array($data_table => $primary_key_data, $revision_table => $primary_key_revision);
+
+      foreach ($table_info as $table => $primary_key) {
+        db_drop_primary_key($table);
+        db_drop_index($table, 'language');
+        db_change_field($table, 'language', 'langcode', $field_langcode);
+        db_add_primary_key($table, $primary_key);
+        db_add_index($table, 'langcode', $langcode_index);
+      }
+    }
+  }
+
+  // Convert to CMI.
+  $deleted_fields = state()->get('field.field.deleted') ?: array();
+  $deleted_instances = state()->get('field.instance.deleted') ?: array();
+
+  $field_ids = array();
+  $fields = db_query("SELECT * FROM {field_config}")->fetchAll(PDO::FETCH_ASSOC);
+  foreach ($fields as $field) {
+    $field += unserialize($field['data']);
+    unset($field['data']);
+
+    // Generate id for the field.
+    $old_id = $field['id'];
+    $field['id'] = field_generate_id();
+
+    // Reassign all list.module fields to be controlled by options.module.
+    if ($field['module'] == 'list') {
+      $field['module'] = 'options';
+    }
+
+    $field['storage_type'] = $field['storage']['type'];
+    $field['storage_module'] = $field['storage']['module'];
+    $field['storage_active'] = $field['storage']['active'];
+
+    if (!$field['deleted']) {
+      // @fieldcmi
+      $e_field = entity_create('fieldentity', array(
+        'id' => $field['field_name'],
+        'label' => $field['field_name'],
+        'data' => $field,
+      ));
+      $e_field->save();
+    }
+    else {
+      $deleted_fields[$field['field_name']] = $field;
+    }
+    $field_ids[$old_id] = array(
+      'id' => $field['id'],
+    );
+  }
+
+  $instances = db_query("SELECT * FROM {field_config_instance}")->fetchAll(PDO::FETCH_ASSOC);
+  foreach ($instances as $instance) {
+    $instance += unserialize($instance['data']);
+    unset($instance['data']);
+
+    // Map old field id to new UUID.
+    $old_id = $instance['field_id'];
+    $instance['field_id'] = $field_ids[$old_id]['id'];
+
+    // Generate id for the instance.
+    $instance['id'] = field_generate_id();
+
+    if (!$instance['deleted']) {
+      entity_create('instance', array(
+        'id' => $instance['entity_type'] . '.' . $instance['bundle'] . '.' . $instance['field_name'],
+        'label' => $instance['entity_type'] . '.' . $instance['bundle'] . '.' . $instance['field_name'],
+        'data' => $instance,
+      ))->save();
+    }
+    else {
+      $deleted_instances[$instance['id']] = $instance;
+    }
+  }
+
+  // Save the deleted fields and instances.
+  state()->set('field.field.deleted', $deleted_fields);
+  state()->set('field.instance.deleted', $deleted_instances);
+
+  // Drop the tables.
+  db_drop_table('field_config');
+  db_drop_table('field_config_instance');
 }
 
 /**
diff --git a/core/modules/field/field.module b/core/modules/field/field.module
index bb948ac..777e1e6 100644
--- a/core/modules/field/field.module
+++ b/core/modules/field/field.module
@@ -6,6 +6,7 @@
 
 use Drupal\Core\Template\Attribute;
 use Drupal\Core\Entity\Query\QueryFactory;
+use Drupal\Component\Uuid\Uuid;
 
 /*
  * Load all public Field API functions. Drupal currently has no
@@ -327,6 +328,79 @@ function field_cron() {
   field_purge_batch($limit);
 }
 
+ /**
+ * Implements hook_config_import_create().
+ */
+// @fieldcmi
+function field_config_import_create($name, $new_config, $old_config) {
+
+  list($module, $type) = explode('.', $name);
+  if ($module != 'field') {
+    return;
+  }
+
+  $config = $new_config->get('data');
+
+  switch ($type) {
+    case 'field':
+      field_create_field($config);
+      break;
+    case 'instance':
+      field_create_instance($config);
+      break;
+  }
+}
+
+/**
+ * Implements hook_config_import_change().
+ */
+// @fieldcmi
+function field_config_import_change($name, $new_config, $old_config) {
+
+  list($module, $type) = explode('.', $name);
+  if ($module != 'field') {
+    return;
+  }
+
+  $config = $new_config->get('data');
+
+  switch ($type) {
+    case 'field':
+      field_update_field($config);
+      break;
+    case 'instance':
+      field_update_instance($config);
+      break;
+  }
+}
+
+/**
+ * Implements hook_config_import_delete().
+ */
+// @fieldcmi
+function field_config_import_delete($name, $new_config, $old_config) {
+
+  list($module, $type) = explode('.', $name);
+  if ($module != 'field') {
+    return;
+  }
+
+  switch ($type) {
+    case 'field':
+      $config = $old_config->get('data');
+      field_delete_field($config['field_name']);
+      break;
+    case 'instance':
+      $config = $old_config->get('data');
+      // In case the field has been deleted through this import hook,
+      // the instance will be deleted by that already.
+      if (!empty($config)) {
+        field_delete_instance($config);
+      }
+      break;
+  }
+}
+
 /**
  * Implements hook_system_info_alter().
  *
@@ -334,7 +408,9 @@ function field_cron() {
  * required if there are any active fields of that type.
  */
 function field_system_info_alter(&$info, $file, $type) {
-  if ($type == 'module' && module_hook($file->name, 'field_info')) {
+  // During a Drupal 7 to Drupal 8 upgrade it is only safe to call
+  // field_read_fields() once field_update_8001() has finished.
+  if ($type == 'module' && module_hook($file->name, 'field_info') && drupal_get_installed_schema_version('field') >= 8001) {
     $fields = field_read_fields(array('module' => $file->name), array('include_deleted' => TRUE));
     if ($fields) {
       $info['required'] = TRUE;
@@ -499,23 +575,47 @@ function field_modules_disabled($modules) {
 }
 
 /**
- * Refreshes the 'active' and 'storage_active' columns for fields.
+ * Refreshes the 'active' and 'storage_active' values for fields.
  */
 function field_sync_field_status() {
-  // Refresh the 'active' and 'storage_active' columns according to the current
+
+  $deleted_fields = state()->get('field.field.deleted') ?: array();
+  $fields = field_read_fields(array(), array('include_deleted' => 1 ,'include_inactive' => 1));
+  // Refresh the 'active' and 'storage_active' values according to the current
   // set of enabled modules.
   $modules = module_list();
   foreach ($modules as $module_name) {
-    field_associate_fields($module_name);
+    $fields = field_associate_fields($module_name, $fields);
   }
-  db_update('field_config')
-    ->fields(array('active' => 0))
-    ->condition('module', $modules, 'NOT IN')
-    ->execute();
-  db_update('field_config')
-    ->fields(array('storage_active' => 0))
-    ->condition('storage_module', $modules, 'NOT IN')
-    ->execute();
+
+  foreach ($fields as $id => $field) {
+    if (!in_array($field['module'], $modules)) {
+      $fields[$id]['active'] = 0;
+    }
+    if (!in_array($field['storage_module'], $modules)) {
+      $fields[$id]['storage_active'] = 0;
+    }
+  }
+
+  foreach ($fields as $id => $field) {
+    if (!$field['deleted']) {
+      // We can not use field_update_field because the prior_field does not
+      // check whether a field is really there or not.
+      // @fieldcmi
+      $e_field = entity_load('fieldentity',  $field['field_name']);
+      $e_field->data = $field;
+      $e_field->save();
+      // config('field.field.' . $field['field_name'])->setData($field)->save();
+    }
+    else {
+      $deleted_fields[$field['id']] = $field;
+    }
+  }
+
+  // Save the deleted fields.
+  state()->set('field.field.deleted', $deleted_fields);
+
+  field_cache_clear();
 }
 
 /**
@@ -523,24 +623,37 @@ function field_sync_field_status() {
  *
  * @param $module
  *   The name of the module to update on.
+ * @param $fields
+ *   A collection of fields.
  */
-function field_associate_fields($module) {
+function field_associate_fields($module, $fields) {
+
   // Associate field types.
   $field_types = (array) module_invoke($module, 'field_info');
+
   if ($field_types) {
-    db_update('field_config')
-      ->fields(array('module' => $module, 'active' => 1))
-      ->condition('type', array_keys($field_types))
-      ->execute();
+    $field_types = array_keys($field_types);
+    foreach ($fields as $id => $field) {
+      if (in_array($field['type'], $field_types)) {
+        $fields[$id]['module'] = $module;
+        $fields[$id]['active'] = TRUE;
+      }
+    }
   }
+
   // Associate storage backends.
   $storage_types = (array) module_invoke($module, 'field_storage_info');
   if ($storage_types) {
-    db_update('field_config')
-      ->fields(array('storage_module' => $module, 'storage_active' => 1))
-      ->condition('storage_type', array_keys($storage_types))
-      ->execute();
+    $storage_types = array_keys($storage_types);
+    foreach ($fields as $id => $field) {
+      if (in_array($field['storage_type'], $storage_types)) {
+        $fields[$id]['storage_module'] = $module;
+        $fields[$id]['storage_active'] = TRUE;
+      }
+    }
   }
+
+  return $fields;
 }
 
 /**
@@ -799,6 +912,21 @@ function field_cache_clear() {
 }
 
 /**
+ * Generate an id for fields or instances.
+ *
+ * When a field is a deleted, the tables are renamed to {field_data_field_id}
+ * and {field_revision_field_id}. To make sure alternative uuid implementations
+ * don't generate longer uuid's and using str_replace() to replace dashes
+ * to underscores might end up in table names longer than 64 characters, we
+ * hash the uuid and then take the first 6 characters so we end up with a short
+ * unique id.
+ */
+function field_generate_id() {
+  $uuid = new Uuid();
+  return substr(hash('sha256', $uuid->generate()), 0, 6);
+}
+
+/**
  * Filters an HTML string to prevent cross-site-scripting (XSS) vulnerabilities.
  *
  * Like filter_xss_admin(), but with a shorter list of allowed tags.
diff --git a/core/modules/field/lib/Drupal/field/FieldInfo.php b/core/modules/field/lib/Drupal/field/FieldInfo.php
index d203e42..f21e369 100644
--- a/core/modules/field/lib/Drupal/field/FieldInfo.php
+++ b/core/modules/field/lib/Drupal/field/FieldInfo.php
@@ -142,17 +142,10 @@ public function getFieldMap() {
 
     $map = array();
 
-    $query = db_select('field_config_instance', 'fci');
-    $query->join('field_config', 'fc', 'fc.id = fci.field_id');
-    $query->fields('fc', array('type'));
-    $query->fields('fci', array('field_name', 'entity_type', 'bundle'))
-      ->condition('fc.active', 1)
-      ->condition('fc.storage_active', 1)
-      ->condition('fc.deleted', 0)
-      ->condition('fci.deleted', 0);
-    foreach ($query->execute() as $row) {
-      $map[$row->field_name]['bundles'][$row->entity_type][] = $row->bundle;
-      $map[$row->field_name]['type'] = $row->type;
+    $instances = field_read_instances();
+    foreach ($instances as $key => $instance) {
+      $map[$instance['field_name']]['bundles'][$instance['entity_type']][] = $instance['bundle'];
+      $map[$instance['field_name']]['type'] = $instance['type'];
     }
 
     // Save in "static" and persistent caches.
@@ -376,7 +369,7 @@ public function getBundleInstances($entity_type, $bundle) {
 
     // Collect the fields in the bundle.
     $params = array('entity_type' => $entity_type, 'bundle' => $bundle);
-    $fields = field_read_fields($params);
+    $fields = field_read_fields();
 
     // This iterates on non-deleted instances, so deleted fields are kept out of
     // the persistent caches.
@@ -407,6 +400,7 @@ public function getBundleInstances($entity_type, $bundle) {
 
     // The persistent cache additionally contains the definitions of the fields
     // involved in the bundle.
+    uasort($instances, array($this, '_orderInstances'));
     $cache = array(
       'instances' => $instances,
       'fields' => array()
@@ -565,4 +559,11 @@ public function prepareExtraFields($extra_fields, $entity_type, $bundle) {
 
     return $result;
   }
+
+  /**
+   * Helper function to sort the instances on the widget weight.
+   */
+  function _orderInstances($a, $b) {
+    return ($a['widget']['weight'] < $b['widget']['weight']) ? -1 : 1;
+  }
 }
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/FieldEntity.php b/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/FieldEntity.php
new file mode 100644
index 0000000..9d27515
--- /dev/null
+++ b/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/FieldEntity.php
@@ -0,0 +1,60 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\field\Plugin\Core\Entity\Field.
+ */
+
+namespace Drupal\field\Plugin\Core\Entity;
+
+use Drupal\Core\Config\Entity\ConfigEntityBase;
+use Drupal\Core\Annotation\Plugin;
+use Drupal\Core\Annotation\Translation;
+
+/**
+ * Defines the Field entity.
+ *
+ * @Plugin(
+ *   id = "fieldentity",
+ *   label = @Translation("Field Entity"),
+ *   module = "field",
+ *   controller_class = "Drupal\Core\Config\Entity\ConfigStorageController",
+ *   config_prefix = "field.field",
+ *   entity_keys = {
+ *     "id" = "id",
+ *     "label" = "label",
+ *     "uuid" = "uuid"
+ *   }
+ * )
+ */
+class FieldEntity extends ConfigEntityBase {
+  /**
+   * The field ID (config name).
+   *
+   * @var string
+   */
+  public $id;
+
+  /**
+   * The field UUID.
+   *
+   * @var string
+   */
+  public $uuid;
+
+  /**
+   * The field name (machine name) as specified by theme or module.
+   *
+   * @var string
+   */
+  public $name;
+
+  /**
+   * The field label.
+   *
+   * @var string
+   */
+  public $label;
+
+  public $data;
+}
\ No newline at end of file
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/Instance.php b/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/Instance.php
new file mode 100644
index 0000000..a44a4c9
--- /dev/null
+++ b/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/Instance.php
@@ -0,0 +1,60 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\field\Plugin\Core\Entity\Field.
+ */
+
+namespace Drupal\field\Plugin\Core\Entity;
+
+use Drupal\Core\Config\Entity\ConfigEntityBase;
+use Drupal\Core\Annotation\Plugin;
+use Drupal\Core\Annotation\Translation;
+
+/**
+ * Defines the Field entity.
+ *
+ * @Plugin(
+ *   id = "instance",
+ *   label = @Translation("Instance"),
+ *   module = "field",
+ *   controller_class = "Drupal\Core\Config\Entity\ConfigStorageController",
+ *   config_prefix = "field.instance",
+ *   entity_keys = {
+ *     "id" = "id",
+ *     "label" = "label",
+ *     "uuid" = "uuid"
+ *   }
+ * )
+ */
+class Instance extends ConfigEntityBase {
+  /**
+   * The field ID (config name).
+   *
+   * @var string
+   */
+  public $id;
+
+  /**
+   * The field UUID.
+   *
+   * @var string
+   */
+  public $uuid;
+
+  /**
+   * The field name (machine name) as specified by theme or module.
+   *
+   * @var string
+   */
+  public $name;
+
+  /**
+   * The field label.
+   *
+   * @var string
+   */
+  public $label;
+
+  public $data;
+}
\ No newline at end of file
diff --git a/core/modules/field/lib/Drupal/field/Tests/BulkDeleteTest.php b/core/modules/field/lib/Drupal/field/Tests/BulkDeleteTest.php
index cc47e59..c5df419 100644
--- a/core/modules/field/lib/Drupal/field/Tests/BulkDeleteTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/BulkDeleteTest.php
@@ -7,6 +7,8 @@
 
 namespace Drupal\field\Tests;
 
+use Drupal\Field\FieldInstance;
+
 /**
  * Unit test class for field bulk delete and batch purge functionality.
  */
@@ -167,7 +169,7 @@ function testDeleteFieldInstance() {
 
     // Delete the instance.
     $instance = field_info_instance($this->entity_type, $field['field_name'], $bundle);
-    field_delete_instance($instance);
+    field_delete_instance($instance->getArray());
 
     // The instance still exists, deleted.
     $instances = field_read_instances(array('field_id' => $field['id'], 'deleted' => 1), array('include_deleted' => 1, 'include_inactive' => 1));
@@ -217,7 +219,7 @@ function testPurgeInstance() {
 
     // Delete the instance.
     $instance = field_info_instance($this->entity_type, $field['field_name'], $bundle);
-    field_delete_instance($instance);
+    field_delete_instance($instance->getArray());
 
     // No field hooks were called.
     $mem = field_test_memorize();
@@ -281,7 +283,7 @@ function testPurgeField() {
     // Delete the first instance.
     $bundle = reset($this->bundles);
     $instance = field_info_instance($this->entity_type, $field['field_name'], $bundle);
-    field_delete_instance($instance);
+    field_delete_instance($instance->getArray());
 
     // Assert that hook_field_delete() was not called yet.
     $mem = field_test_memorize();
@@ -312,7 +314,7 @@ function testPurgeField() {
     // Delete the second instance.
     $bundle = next($this->bundles);
     $instance = field_info_instance($this->entity_type, $field['field_name'], $bundle);
-    field_delete_instance($instance);
+    field_delete_instance($instance->getArray());
 
     // Assert that hook_field_delete() was not called yet.
     $mem = field_test_memorize();
diff --git a/core/modules/field/lib/Drupal/field/Tests/CrudTest.php b/core/modules/field/lib/Drupal/field/Tests/CrudTest.php
index 4e7557e..a6a91a1 100644
--- a/core/modules/field/lib/Drupal/field/Tests/CrudTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/CrudTest.php
@@ -45,10 +45,11 @@ function testCreateField() {
     $mem = field_test_memorize();
     $this->assertIdentical($mem['field_test_field_create_field'][0][0], $field_definition, 'hook_field_create_field() called with correct arguments.');
 
-    // Read the raw record from the {field_config_instance} table.
-    $result = db_query('SELECT * FROM {field_config} WHERE field_name = :field_name', array(':field_name' => $field_definition['field_name']));
-    $record = $result->fetchAssoc();
-    $record['data'] = unserialize($record['data']);
+    // Read the configuration.
+    // @fieldcmi
+    $e_record = entity_load('fieldentity', $field_definition['field_name']);
+    $record = $e_record->data;
+    //$record = config('field.field.' . $field_definition['field_name'])->get();
 
     // Ensure that basic properties are preserved.
     $this->assertEqual($record['field_name'], $field_definition['field_name'], 'The field name is properly saved.');
@@ -59,7 +60,7 @@ function testCreateField() {
 
     // Ensure that default settings are present.
     $field_type = field_info_field_types($field_definition['type']);
-    $this->assertIdentical($record['data']['settings'], $field_type['settings'], 'Default field settings have been written.');
+    $this->assertEqual($record['settings'], $field_type['settings'], 'Default field settings have been written.');
 
     // Ensure that default storage was set.
     $this->assertEqual($record['storage_type'], variable_get('field_storage_default'), 'The field type is properly saved.');
@@ -157,11 +158,12 @@ function testCreateField() {
   function testCreateFieldFail() {
     $field_name = 'duplicate';
     $field_definition = array('field_name' => $field_name, 'type' => 'test_field', 'storage' => array('type' => 'field_test_storage_failure'));
-    $query = db_select('field_config')->condition('field_name', $field_name)->countQuery();
+    //$field = config('field.field.' . $field_name)->get();
+    // @fieldcmi
+    $field = entity_load('fieldentity', $field_name);
 
-    // The field does not appear in field_config.
-    $count = $query->execute()->fetchField();
-    $this->assertEqual($count, 0, 'A field_config row for the field does not exist.');
+    // The field does not exist.
+    $this->assertFalse($field, 'The field does not exist.');
 
     // Try to create the field.
     try {
@@ -172,9 +174,10 @@ function testCreateFieldFail() {
       $this->assertTrue(TRUE, 'Field creation (correctly) fails.');
     }
 
-    // The field does not appear in field_config.
-    $count = $query->execute()->fetchField();
-    $this->assertEqual($count, 0, 'A field_config row for the field does not exist.');
+    // The field does not exist.
+    // $field = config('field.field.' . $field_name)->get();
+    $field = entity_load('fieldentity', $field_name);
+    $this->assertFalse($field, 'The field does not exist.');
   }
 
   /**
@@ -268,8 +271,8 @@ function testDeleteField() {
 
     // Make sure that the field is marked as deleted when it is specifically
     // loaded.
-    $field = field_read_field($this->field['field_name'], array('include_deleted' => TRUE));
-    $this->assertTrue(!empty($field['deleted']), 'A deleted field is marked for deletion.');
+    $deleted_fields = state()->get('field.field.deleted');
+    $this->assertTrue(isset($deleted_fields[$field['id']]), 'A deleted field is marked for deletion.');
 
     // Make sure that this field's instance is marked as deleted when it is
     // specifically loaded.
@@ -470,6 +473,6 @@ function _testActiveHelper($field_definition, $modules) {
     // Check that the field is active again after all modules have been
     // enabled.
     $field = field_read_field($field_name);
-    $this->assertTrue($field_definition <= $field, 'The field was was marked active.');
+    $this->assertTrue($field_definition <= $field, 'The field was marked active.');
   }
 }
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldImportChangeTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldImportChangeTest.php
new file mode 100644
index 0000000..d94c14e
--- /dev/null
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldImportChangeTest.php
@@ -0,0 +1,69 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\field\Tests\FieldImportChangeTest.
+ */
+
+namespace Drupal\field\Tests;
+
+use Drupal\simpletest\WebTestBase;
+
+/**
+ * Tests the functionality of deleting fields and instances
+ * on hook_config_import_change().
+ */
+class FieldImportChangeTest extends WebTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('field_test_config');
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Field CMI change tests',
+      'description' => 'Update field and instances during CMI change hook invocation.',
+      'group' => 'Field API',
+    );
+  }
+
+  function setUp() {
+    parent::setUp();
+
+    $this->instance_manifest = 'manifest.field.instance';
+    $this->instance_name = 'field.instance.node.test_import.field_test_import';
+    $this->drupalCreateContentType(array('type' => 'test_import', 'name' => 'Test import'));
+
+    $admin_user = $this->drupalCreateUser(array('access administration pages', 'access content overview', 'administer nodes', 'bypass node access'));
+    $this->drupalLogin($admin_user);
+  }
+
+  /**
+   * Test importing changes.
+   */
+  function testImportChange() {
+
+    // Assert default test import.
+    $this->drupalGet('node/add/test_import');
+    $this->assertRaw('Test import field');
+
+    // Change label.
+    $active = $this->container->get('config.storage');
+    $staging = $this->container->get('config.storage.staging');
+    $manifest = $active->read($this->instance_manifest);
+    $instance = $active->read($this->instance_name);
+    $instance['data']['label'] = 'Test update import field';
+    $staging->write($this->instance_name, $instance);
+    $staging->write($this->instance_manifest, $manifest);
+
+    // Import.
+    config_import();
+
+    // Assert updated label.
+    $this->drupalGet('node/add/test_import');
+    $this->assertText('Test update import field');
+  }
+}
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldImportCreateTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldImportCreateTest.php
new file mode 100644
index 0000000..82b390e
--- /dev/null
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldImportCreateTest.php
@@ -0,0 +1,87 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\field\Tests\FieldImportCreateTest.
+ */
+
+namespace Drupal\field\Tests;
+
+use Drupal\simpletest\WebTestBase;
+use Symfony\Component\Yaml\Parser;
+
+/**
+ * Tests the functionality of creating fields and instances
+ * on hook_config_import_create().
+ */
+class FieldImportCreateTest extends WebTestBase {
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Field CMI create tests',
+      'description' => 'Create field and instances during CMI create hook invocation.',
+      'group' => 'Field API',
+    );
+  }
+
+  function setUp() {
+    parent::setUp();
+
+    $this->field_test_import_staging = 'field.field.field_test_import_staging';
+    $this->instance_test_import_staging = 'field.instance.node.test_import.field_test_import_staging';
+    $this->field_manifest = 'manifest.field.field';
+    $this->instance_manifest = 'manifest.field.instance';
+    $this->drupalCreateContentType(array('type' => 'test_import', 'name' => 'Test import'));
+
+    $admin_user = $this->drupalCreateUser(array('access administration pages', 'access content overview', 'administer nodes', 'bypass node access'));
+    $this->drupalLogin($admin_user);
+  }
+
+  /**
+   * Test importing new fields.
+   */
+  function testImportCreate() {
+
+    // Assert default test import.
+    $this->drupalGet('node/add/test_import');
+    $this->assertNoText('Test import field');
+
+    // Enable field_test_config module and assert the test import
+    // field and instance is available on the Test content type.
+    // This tests creating fields and instances that are provided
+    // by a module.
+    module_enable(array('field_test_config'));
+    $this->drupalGet('node/add/test_import');
+    $this->assertText('Test import field');
+    $module_path = drupal_get_path('module', 'field_test_config');
+
+    // Copy another field and instance to the staging directory
+    // on the Test content type and run config_import() to test
+    // importing from the staging directory.
+    $active = $this->container->get('config.storage');
+    $staging = $this->container->get('config.storage.staging');
+    $field_manifest = $active->read($this->field_manifest);
+    $instance_manifest = $active->read($this->instance_manifest);
+
+    // Copy the files.
+    $copied = file_unmanaged_copy($module_path .'/staging/' . $this->field_test_import_staging . '.yml', 'public://config_staging/' . $this->field_test_import_staging . '.yml');
+    $this->assertTrue($copied);
+    $copied = file_unmanaged_copy($module_path .'/staging/' . $this->instance_test_import_staging . '.yml', 'public://config_staging/' . $this->instance_test_import_staging . '.yml');
+    $this->assertTrue($copied);
+
+    // Add to manifest.
+    $field_manifest['field_test_import_staging'] = array('name' => $this->field_test_import_staging);
+    $instance_manifest['node.test_import.field_test_import_staging'] = array('name' => $this->instance_test_import_staging);
+
+    // Write to manifest and new config.
+    $staging->write($this->field_manifest, $field_manifest);
+    $staging->write($this->instance_manifest, $instance_manifest);
+
+    // Import.
+    config_import();
+
+    // Assert the staging field is there.
+    $this->drupalGet('node/add/test_import');
+    $this->assertText('Import from staging');
+  }
+}
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldImportDeleteTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldImportDeleteTest.php
new file mode 100644
index 0000000..96daa94
--- /dev/null
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldImportDeleteTest.php
@@ -0,0 +1,100 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\field\Tests\FieldImportDeleteTest.
+ */
+
+namespace Drupal\field\Tests;
+
+use Drupal\simpletest\WebTestBase;
+
+/**
+ * Tests the functionality of deleting fields and instances
+ * on hook_config_import_delete().
+ */
+class FieldImportDeleteTest extends WebTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('field_test_config');
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Field CMI delete tests',
+      'description' => 'Delete field and instances during CMI delete hook invocation.',
+      'group' => 'Field API',
+    );
+  }
+
+  function setUp() {
+    parent::setUp();
+
+    $this->body_field_name = 'field.field.body';
+    $this->test_import_field_name = 'field.field.test_import';
+    $this->body_instance_name = 'field.instance.node.test_import.body';
+    $this->test_import_instance_name = 'field.instance.node.test_import.field_test_import';
+    $this->field_manifest = 'manifest.field.field';
+    $this->instance_manifest = 'manifest.field.instance';
+    $this->drupalCreateContentType(array('type' => 'test_import', 'name' => 'Test import'));
+
+    $admin_user = $this->drupalCreateUser(array('access administration pages', 'access content overview', 'administer nodes', 'bypass node access'));
+    $this->drupalLogin($admin_user);
+  }
+
+  /**
+   * Test importing deletions.
+   */
+  function testImportDelete() {
+
+    $body_field = field_info_field('body');
+    $field_test_import = field_info_field('field_test_import');
+
+    // Assert default test import.
+    $this->drupalGet('node/add/test_import');
+    $this->assertRaw('Test import field');
+    $this->assertRaw('Body');
+
+    // Delete body field and instance, the test import instance
+    // from the manifest.
+    $active = $this->container->get('config.storage');
+    $staging = $this->container->get('config.storage.staging');
+    $field_manifest = $active->read($this->field_manifest);
+    $instance_manifest = $active->read($this->instance_manifest);
+    unset($field_manifest['body']);
+    unset($instance_manifest['node.test_import.body']);
+    unset($instance_manifest['node.test_import.field_test_import']);
+    $staging->write($this->field_manifest, $field_manifest);
+    $staging->write($this->instance_manifest, $instance_manifest);
+
+    // Import.
+    config_import();
+
+    // Assert the field and instance are gone from the form.
+    $this->drupalGet('node/add/test_import');
+    $this->assertNoText('Test import field');
+    $this->assertNoText('Body');
+
+    // Check the body and import field are in state of deleted fields.
+    $deleted_fields = state()->get('field.field.deleted') ?: array();
+    $this->assertTrue(isset($deleted_fields[$body_field['id']]));
+    $this->assertTrue(isset($deleted_fields[$field_test_import['id']]));
+
+    // Run purge_batch().
+    field_purge_batch(10);
+
+    // Check the deleted fields are removed from state.
+    $deleted_fields = state()->get('field.field.deleted') ?: array();
+    $this->assertTrue(empty($deleted_fields), 'Fields are deleted');
+
+    // Check all config files are gone.
+    $active = $this->container->get('config.storage');
+    $this->assertIdentical($active->listAll($this->body_field_name), array());
+    $this->assertIdentical($active->listAll($this->test_import_field_name), array());
+    $this->assertIdentical($active->listAll($this->body_instance_name), array());
+    $this->assertIdentical($active->listAll($this->test_import_instance_name), array());
+  }
+}
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php
index cfc1718..bef8bda 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php
@@ -133,13 +133,12 @@ function testFieldPrepare() {
     // Simulate a stored field definition missing a field setting (e.g. a
     // third-party module adding a new field setting has been enabled, and
     // existing fields do not know the setting yet).
-    $data = db_query('SELECT data FROM {field_config} WHERE field_name = :field_name', array(':field_name' => $field_definition['field_name']))->fetchField();
-    $data = unserialize($data);
-    $data['settings'] = array();
-    db_update('field_config')
-      ->fields(array('data' => serialize($data)))
-      ->condition('field_name', $field_definition['field_name'])
-      ->execute();
+    // @fieldcmi
+    //$field = config('field.field.' . $field_definition['field_name'])->get();
+    $e_field = entity_load('fieldentity', $field_definition['field_name']);
+    $field = $e_field->data;
+    $field['data']['settings'] = array();
+    field_update_field($field);
 
     field_cache_clear();
 
@@ -148,7 +147,7 @@ function testFieldPrepare() {
 
     // Check that all expected settings are in place.
     $field_type = field_info_field_types($field_definition['type']);
-    $this->assertIdentical($field['settings'], $field_type['settings'], 'All expected default field settings are present.');
+    $this->assertEqual($field['settings'], $field_type['settings'], 'All expected default field settings are present.');
   }
 
   /**
@@ -170,18 +169,16 @@ function testInstancePrepare() {
     // Simulate a stored instance definition missing various settings (e.g. a
     // third-party module adding instance, widget or display settings has been
     // enabled, but existing instances do not know the new settings).
-    $data = db_query('SELECT data FROM {field_config_instance} WHERE field_name = :field_name AND bundle = :bundle', array(':field_name' => $instance_definition['field_name'], ':bundle' => $instance_definition['bundle']))->fetchField();
-    $data = unserialize($data);
-    $data['settings'] = array();
-    $data['widget']['settings'] = 'unavailable_widget';
-    $data['widget']['settings'] = array();
-    $data['display']['default']['type'] = 'unavailable_formatter';
-    $data['display']['default']['settings'] = array();
-    db_update('field_config_instance')
-      ->fields(array('data' => serialize($data)))
-      ->condition('field_name', $instance_definition['field_name'])
-      ->condition('bundle', $instance_definition['bundle'])
-      ->execute();
+    //$instance = config('field.instance.' . $instance_definition['entity_type'] . '.' . $instance_definition['bundle'] . '.' . $instance_definition['field_name'])->get();
+    $e_instance = entity_load('instance', $instance_definition['entity_type'] . '.' . $instance_definition['bundle'] . '.' . $instance_definition['field_name']);
+    $instance = $e_instance->data;
+    $instance['settings'] = array();
+    $instance['widget']['settings'] = 'unavailable_widget';
+    $instance['widget']['settings'] = array();
+    $instance['display']['default']['type'] = 'unavailable_formatter';
+    $instance['display']['default']['settings'] = array();
+
+    field_update_instance($instance);
 
     field_cache_clear();
 
@@ -190,7 +187,7 @@ function testInstancePrepare() {
 
     // Check that all expected instance settings are in place.
     $field_type = field_info_field_types($field_definition['type']);
-    $this->assertIdentical($instance['settings'], $field_type['instance_settings'] , 'All expected instance settings are present.');
+    $this->assertEqual($instance['settings'], $field_type['instance_settings'] , 'All expected instance settings are present.');
 
     // Check that the default widget is used and expected settings are in place.
     $widget = $instance->getWidget();
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php
index 84cee72..50311d7 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php
@@ -8,6 +8,7 @@
 namespace Drupal\field\Tests;
 
 use Drupal\field\FieldException;
+use Drupal\field\FieldInstance;
 
 class FieldInstanceCrudTest extends FieldTestBase {
 
@@ -55,11 +56,10 @@ function setUp() {
   function testCreateFieldInstance() {
     field_create_instance($this->instance_definition);
 
-    // Read the raw record from the {field_config_instance} table.
-    $result = db_query('SELECT * FROM {field_config_instance} WHERE field_name = :field_name AND bundle = :bundle', array(':field_name' => $this->instance_definition['field_name'], ':bundle' => $this->instance_definition['bundle']));
-    $record = $result->fetchAssoc();
-    $record['data'] = unserialize($record['data']);
-
+    // Read the configuration.
+    //$record = config('field.instance.' . $this->instance_definition['entity_type'] . '.' . $this->instance_definition['bundle'] . '.' . $this->instance_definition['field_name'])->get();
+    $e_record = entity_load('instance', $this->instance_definition['entity_type'] . '.' . $this->instance_definition['bundle'] . '.' . $this->instance_definition['field_name']);
+    $record = $e_record->data;
     $field_type = field_info_field_types($this->field['type']);
     $widget_type = field_info_widget_types($field_type['default_widget']);
     $formatter_type = field_info_formatter_types($field_type['default_formatter']);
@@ -68,17 +68,17 @@ function testCreateFieldInstance() {
     $this->assertIdentical($record['id'], $this->instance_definition['id'], 'The instance id is filled in');
 
     // Check that default values are set.
-    $this->assertIdentical($record['data']['required'], FALSE, 'Required defaults to false.');
-    $this->assertIdentical($record['data']['label'], $this->instance_definition['field_name'], 'Label defaults to field name.');
-    $this->assertIdentical($record['data']['description'], '', 'Description defaults to empty string.');
-    $this->assertIdentical($record['data']['widget']['type'], $field_type['default_widget'], 'Default widget has been written.');
-    $this->assertTrue(isset($record['data']['display']['default']), 'Display for "full" view_mode has been written.');
-    $this->assertIdentical($record['data']['display']['default']['type'], $field_type['default_formatter'], 'Default formatter for "full" view_mode has been written.');
+    $this->assertEqual($record['required'], FALSE, 'Required defaults to false.');
+    $this->assertIdentical($record['label'], $this->instance_definition['field_name'], 'Label defaults to field name.');
+    $this->assertIdentical($record['description'], '', 'Description defaults to empty string.');
+    $this->assertIdentical($record['widget']['type'], $field_type['default_widget'], 'Default widget has been written.');
+    $this->assertTrue(isset($record['display']['default']), 'Display for "full" view_mode has been written.');
+    $this->assertIdentical($record['display']['default']['type'], $field_type['default_formatter'], 'Default formatter for "full" view_mode has been written.');
 
     // Check that default settings are set.
-    $this->assertIdentical($record['data']['settings'], $field_type['instance_settings'] , 'Default instance settings have been written.');
-    $this->assertIdentical($record['data']['widget']['settings'], $widget_type['settings'] , 'Default widget settings have been written.');
-    $this->assertIdentical($record['data']['display']['default']['settings'], $formatter_type['settings'], 'Default formatter settings for "full" view_mode have been written.');
+    $this->assertEqual($record['settings'], $field_type['instance_settings'] , 'Default instance settings have been written.');
+    $this->assertIdentical($record['widget']['settings'], $widget_type['settings'] , 'Default widget settings have been written.');
+    $this->assertIdentical($record['display']['default']['settings'], $formatter_type['settings'], 'Default formatter settings for "full" view_mode have been written.');
 
     // Guarantee that the field/bundle combination is unique.
     try {
@@ -143,7 +143,14 @@ function testReadFieldInstance() {
 
     // Read the instance back.
     $instance = field_read_instance('test_entity', $this->instance_definition['field_name'], $this->instance_definition['bundle']);
-    $this->assertTrue($this->instance_definition == $instance, 'The field was properly read.');
+    $this->assertTrue($this->instance_definition['id'] == $instance['id'], 'The field was properly read.');
+    $this->assertTrue($this->instance_definition['label'] == $instance['label'], 'The field was properly read.');
+    $this->assertTrue($this->instance_definition['field_id'] == $instance['field_id'], '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['settings'] == $instance['settings'], 'The field was properly read.');
+    $this->assertTrue($this->instance_definition['display'] == $instance['display'], 'The field was properly read.');
+    $this->assertTrue($this->instance_definition['widget'] == $instance['widget'], 'The field was properly read.');
   }
 
   /**
@@ -239,7 +246,9 @@ function testDeleteFieldInstance() {
 
     // Make sure the field is deleted when its last instance is deleted.
     field_delete_instance($another_instance);
-    $field = field_read_field($another_instance['field_name'], array('include_deleted' => TRUE));
-    $this->assertTrue(!empty($field['deleted']), 'A deleted field is marked for deletion after all its instances have been marked for deletion.');
+    $deleted_fields = 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(array('field_name' => $another_instance['field_name']));
+    $this->assertFalse($field, 'The field marked to be deleted is not found anymore in the configuration.');
   }
 }
diff --git a/core/modules/field/modules/field_sql_storage/field_sql_storage.install b/core/modules/field/modules/field_sql_storage/field_sql_storage.install
index 4d4fe57..364d594 100644
--- a/core/modules/field/modules/field_sql_storage/field_sql_storage.install
+++ b/core/modules/field/modules/field_sql_storage/field_sql_storage.install
@@ -11,16 +11,22 @@
 function field_sql_storage_schema() {
   $schema = array();
 
-  // Dynamic (data) tables.
-  if (db_table_exists('field_config')) {
-    $fields = field_read_fields(array(), array('include_deleted' => TRUE, 'include_inactive' => TRUE));
+  // During a Drupal 7 to Drupal 8 upgrade it is only safe to call
+  // field configurations once field_update_8001() has finished.
+  if (drupal_get_installed_schema_version('field') >= 8001) {
+    // Dynamic (data) tables.
+    // We don't call field_read_fields() as this will cause endless loops
+    // in entity_get_info().
+    $fields = config_get_storage_names_with_prefix('field.field');
     drupal_load('module', 'field_sql_storage');
-    foreach ($fields as $field) {
+    foreach ($fields as $name) {
+      $field = config($name)->get('data');
       if ($field['storage']['type'] == 'field_sql_storage') {
         $schema += _field_sql_storage_schema($field);
       }
     }
   }
+
   return $schema;
 }
 
@@ -78,51 +84,3 @@ function _update_8000_field_sql_storage_write($entity_type, $bundle, $entity_id,
   }
 }
 
-/**
- * Changes field language into langcode.
- */
-function field_sql_storage_update_8000(&$sandbox) {
-  // Prepare updated schema data structures.
-  $primary_key_data = array (
-    'entity_type',
-    'entity_id',
-    'deleted',
-    'delta',
-    'langcode',
-  );
-  $primary_key_revision = array (
-    'entity_type',
-    'entity_id',
-    'revision_id',
-    'deleted',
-    'delta',
-    'langcode',
-  );
-  $langcode_index = array(
-    'langcode',
-  );
-  $field_langcode = array(
-    'type' => 'varchar',
-    'length' => 32,
-    'not null' => true,
-    'default' => '',
-  );
-
-  // Retrieve field data.
-  $fields = _update_7000_field_read_fields(array('storage_type' => 'field_sql_storage'));
-
-  // Update schema.
-  foreach ($fields as $field) {
-    $data_table = _field_sql_storage_tablename($field);
-    $revision_table = _field_sql_storage_revision_tablename($field);
-    $table_info = array($data_table => $primary_key_data, $revision_table => $primary_key_revision);
-
-    foreach ($table_info as $table => $primary_key) {
-      db_drop_primary_key($table);
-      db_drop_index($table, 'language');
-      db_change_field($table, 'language', 'langcode', $field_langcode);
-      db_add_primary_key($table, $primary_key);
-      db_add_index($table, 'langcode', $langcode_index);
-    }
-  }
-}
diff --git a/core/modules/field/tests/modules/field_test_config/config/field.field.field_test_import.yml b/core/modules/field/tests/modules/field_test_config/config/field.field.field_test_import.yml
new file mode 100644
index 0000000..b9d108d
--- /dev/null
+++ b/core/modules/field/tests/modules/field_test_config/config/field.field.field_test_import.yml
@@ -0,0 +1,53 @@
+id: field_test_import
+uuid: fb38277f-1fd4-49d5-8d09-9d7037fdcce9
+name: ''
+label: field_test_import
+data:
+  field_name: field_test_import
+  type: text
+  translatable: false
+  entity_types: {  }
+  cardinality: '1'
+  locked: false
+  settings:
+    max_length: '255'
+  storage:
+    type: field_sql_storage
+    settings: {  }
+    module: field_sql_storage
+    active: 1
+    details:
+      sql:
+        FIELD_LOAD_CURRENT:
+          field_data_field_test_import:
+            value: field_test_import_value
+            format: field_test_import_format
+        FIELD_LOAD_REVISION:
+          field_revision_field_test_import:
+            value: field_test_import_value
+            format: field_test_import_format
+  deleted: 0
+  module: text
+  active: 1
+  columns:
+    value:
+      type: varchar
+      length: '255'
+      'not null': false
+    format:
+      type: varchar
+      length: 255
+      'not null': false
+  'foreign keys':
+    format:
+      table: filter_format
+      columns:
+        format: format
+  indexes:
+    format:
+      - format
+  storage_type: field_sql_storage
+  storage_module: field_sql_storage
+  storage_active: 1
+  id: b5a22b
+langcode: und
diff --git a/core/modules/field/tests/modules/field_test_config/config/field.instance.node.test_import.field_test_import.yml b/core/modules/field/tests/modules/field_test_config/config/field.instance.node.test_import.field_test_import.yml
new file mode 100644
index 0000000..b1218a1
--- /dev/null
+++ b/core/modules/field/tests/modules/field_test_config/config/field.instance.node.test_import.field_test_import.yml
@@ -0,0 +1,40 @@
+id: node.test_import.field_test_import
+uuid: 392b4e9d-6157-412e-9603-3d622512f498
+name: ''
+label: node.test_import.field_test_import
+data:
+  field_name: field_test_import
+  entity_type: node
+  bundle: test_import
+  label: 'Test import field'
+  widget:
+    weight: '-2'
+    type: text_textfield
+    module: text
+    active: 0
+    settings:
+      size: '60'
+  field_id: b5a22b
+  id: 948dff
+  settings:
+    text_processing: '0'
+    user_register_form: false
+  display:
+    default:
+      label: above
+      type: text_default
+      settings: {  }
+      module: text
+      weight: 2
+  required: 0
+  description: ''
+  deleted: 0
+  active: 1
+  locked: false
+  type: text
+  module: text
+  storage_type: field_sql_storage
+  storage_active: 1
+  storage_module: field_sql_storage
+  default_value: null
+langcode: und
diff --git a/core/modules/field/tests/modules/field_test_config/field_test_config.info b/core/modules/field/tests/modules/field_test_config/field_test_config.info
new file mode 100644
index 0000000..49b0509
--- /dev/null
+++ b/core/modules/field/tests/modules/field_test_config/field_test_config.info
@@ -0,0 +1,6 @@
+name = "Field API configuration tests"
+description = "Support module for the Field API configuration tests."
+core = 8.x
+package = Testing
+version = VERSION
+hidden = TRUE
diff --git a/core/modules/field/tests/modules/field_test_config/field_test_config.module b/core/modules/field/tests/modules/field_test_config/field_test_config.module
new file mode 100644
index 0000000..e208464
--- /dev/null
+++ b/core/modules/field/tests/modules/field_test_config/field_test_config.module
@@ -0,0 +1,6 @@
+<?php
+
+/**
+ * @file
+ * Helper module for the Field API CMI tests.
+ */
diff --git a/core/modules/field/tests/modules/field_test_config/staging/field.field.field_test_import_staging.yml b/core/modules/field/tests/modules/field_test_config/staging/field.field.field_test_import_staging.yml
new file mode 100644
index 0000000..1b600c0
--- /dev/null
+++ b/core/modules/field/tests/modules/field_test_config/staging/field.field.field_test_import_staging.yml
@@ -0,0 +1,53 @@
+id: field_test_import_staging
+uuid: 0bf654cc-f14a-4881-b94c-76959e47466b
+name: ''
+label: field_test_import_staging
+data:
+  field_name: field_test_import_staging
+  type: text
+  translatable: '0'
+  entity_types: {  }
+  cardinality: '1'
+  locked: '0'
+  settings:
+    max_length: '255'
+  storage:
+    type: field_sql_storage
+    settings: {  }
+    module: field_sql_storage
+    active: '1'
+    details:
+      sql:
+        FIELD_LOAD_CURRENT:
+          field_data_field_test_import_staging:
+            value: field_test_import_staging_value
+            format: field_test_import_staging_format
+        FIELD_LOAD_REVISION:
+          field_revision_field_test_import_staging:
+            value: field_test_import_staging_value
+            format: field_test_import_staging_format
+  deleted: '0'
+  module: text
+  active: '1'
+  columns:
+    value:
+      type: varchar
+      length: '255'
+      'not null': '0'
+    format:
+      type: varchar
+      length: '255'
+      'not null': '0'
+  'foreign keys':
+    format:
+      table: filter_format
+      columns:
+        format: format
+  indexes:
+    format:
+      - format
+  storage_type: field_sql_storage
+  storage_module: field_sql_storage
+  storage_active: '1'
+  id: 7f0fa9
+langcode: und
diff --git a/core/modules/field/tests/modules/field_test_config/staging/field.instance.node.test_import.field_test_import_staging.yml b/core/modules/field/tests/modules/field_test_config/staging/field.instance.node.test_import.field_test_import_staging.yml
new file mode 100644
index 0000000..c21a3d6
--- /dev/null
+++ b/core/modules/field/tests/modules/field_test_config/staging/field.instance.node.test_import.field_test_import_staging.yml
@@ -0,0 +1,31 @@
+id: node.test_import.field_test_import_staging
+uuid: ea711065-6940-47cd-813d-618f64095481
+name: ''
+label: node.test_import.field_test_import_staging
+data:
+  field_name: field_test_import_staging
+  entity_type: node
+  bundle: test_import
+  label: 'Import from staging'
+  widget:
+    type: text_textfield
+    weight: '-3'
+    settings:
+      size: '60'
+    module: text
+  field_id: 7f0fa9
+  id: 103db5
+  settings:
+    text_processing: '0'
+    user_register_form: '0'
+  display:
+    default:
+      label: above
+      type: text_default
+      settings: {  }
+      module: text
+      weight: '1'
+  required: '0'
+  description: ''
+  deleted: '0'
+langcode: und
diff --git a/core/modules/field_ui/field_ui.admin.inc b/core/modules/field_ui/field_ui.admin.inc
index d301d76..907130b 100644
--- a/core/modules/field_ui/field_ui.admin.inc
+++ b/core/modules/field_ui/field_ui.admin.inc
@@ -759,7 +759,7 @@ function field_ui_field_delete_form_submit($form, &$form_state) {
   $bundle_label = $bundles[$entity_type][$bundle]['label'];
 
   if (!empty($bundle) && $field && !$field['locked'] && $form_values['confirm']) {
-    field_delete_instance($instance);
+    field_delete_instance($instance->getArray());
     drupal_set_message(t('The field %field has been deleted from the %type content type.', array('%field' => $instance['label'], '%type' => $bundle_label)));
   }
   else {
diff --git a/core/modules/file/file.install b/core/modules/file/file.install
index ca6e1fd..a8c7b0c 100644
--- a/core/modules/file/file.install
+++ b/core/modules/file/file.install
@@ -125,8 +125,8 @@ function file_schema() {
       ),
       'id' => array(
         'description' => 'The primary key of the object using the file.',
-        'type' => 'int',
-        'unsigned' => TRUE,
+        'type' => 'varchar',
+        'length' => 64,
         'not null' => TRUE,
         'default' => 0,
       ),
@@ -232,3 +232,29 @@ function file_requirements($phase) {
 
   return $requirements;
 }
+
+/**
+ * @defgroup updates-7.x-to-8.x Updates from 7.x to 8.x
+ * @{
+ * Update functions from 7.x to 8.x.
+ */
+
+/**
+ * Convert the id column in file_usage table for Field API.
+ */
+function file_update_8001() {
+  $spec = array(
+    'description' => 'The primary key of the object using the file.',
+    'type' => 'varchar',
+    'length' => 64,
+    'not null' => TRUE,
+    'default' => '',
+  );
+  db_change_field('file_usage', 'id', 'id', $spec);
+}
+
+/**
+ * @} End of "defgroup updates-7.x-to-8.x".
+ * The next series of updates should start at 9000.
+ */
+
diff --git a/core/modules/forum/forum.install b/core/modules/forum/forum.install
index 56f8402..9e56db6 100644
--- a/core/modules/forum/forum.install
+++ b/core/modules/forum/forum.install
@@ -22,10 +22,6 @@ function forum_install() {
  * Implements hook_enable().
  */
 function forum_enable() {
-  // If we enable forum at the same time as taxonomy we need to call
-  // field_associate_fields() as otherwise the field won't be enabled until
-  // hook modules_enabled is called which takes place after hook_enable events.
-  field_associate_fields('taxonomy');
 
   // Create the forum vocabulary if it does not exist.
   // @todo Change Forum module so forum.settings can contain the vocabulary's
@@ -55,7 +51,7 @@ function forum_enable() {
   }
 
   // Create the 'taxonomy_forums' field if it doesn't already exist.
-  if (!field_info_field('taxonomy_forums')) {
+  if (!field_read_field('taxonomy_forums', array('include_inactive' => TRUE))) {
     $field = array(
       'field_name' => 'taxonomy_forums',
       'type' => 'taxonomy_term_reference',
diff --git a/core/modules/rest/lib/Drupal/rest/Tests/DeleteTest.php b/core/modules/rest/lib/Drupal/rest/Tests/DeleteTest.php
index 187c386..fa4d6da 100644
--- a/core/modules/rest/lib/Drupal/rest/Tests/DeleteTest.php
+++ b/core/modules/rest/lib/Drupal/rest/Tests/DeleteTest.php
@@ -34,6 +34,12 @@ public static function getInfo() {
    */
   public function testDelete() {
     foreach (entity_get_info() as $entity_type => $info) {
+
+      // Skip fieldentity and instance.
+      if (in_array($entity_type, array('fieldentity', 'instance'))) {
+        continue;
+      }
+
       // Enable web API for this entity type.
       $config = config('rest');
       $config->set('resources', array(
diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php
new file mode 100644
index 0000000..50d4950
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php
@@ -0,0 +1,46 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\system\Tests\Upgrade\FieldUpgradePath.
+ */
+
+namespace Drupal\system\Tests\Upgrade;
+
+/**
+ * Tests upgrade of fields and instances.
+ */
+class FieldUpgradePathTest extends UpgradePathTestBase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Field API upgrade test',
+      'description' => 'Upgrade tests for Field API.',
+      'group' => 'Upgrade path',
+    );
+  }
+
+  public function setUp() {
+    $this->databaseDumpFiles = array(
+      drupal_get_path('module', 'system') . '/tests/upgrade/drupal-7.filled.standard_all.database.php.gz',
+    );
+    parent::setUp();
+  }
+
+  /**
+   * Test the upgrade path for fields and instances to the new
+   * configuration system.
+   */
+  function testFieldConfigUpgrade() {
+    $this->assertTrue($this->performUpgrade(), t('The upgrade was completed successfully.'));
+
+    // Assert the field_config and field_config_instance tables are gone.
+    $this->assertTrue(!db_table_exists('field_config'), 'The field_config table has been removed.');
+    $this->assertTrue(!db_table_exists('field_config_instance'), 'The field_config_instance table has been removed.');
+
+    // Assert the body field and instance on the article are converted to CMI.
+    $body_field = field_info_field('body');
+    $this->assertNotNull($body_field, 'The body field has been found.');
+    $body_field_instance = field_info_instance('node', 'body', 'article');
+    $this->assertNotNull($body_field, 'The body field instance on the article content type has been found.');
+  }
+}
