diff --git a/core/lib/Drupal/Core/TypedData/TypedDataManager.php b/core/lib/Drupal/Core/TypedData/TypedDataManager.php
index b08bff9..29be6cd 100644
--- a/core/lib/Drupal/Core/TypedData/TypedDataManager.php
+++ b/core/lib/Drupal/Core/TypedData/TypedDataManager.php
@@ -57,7 +57,10 @@ class TypedDataManager extends PluginManagerBase {
   protected $prototypes = array();
 
   public function __construct() {
-    $this->discovery = new CacheDecorator(new DerivativeDiscoveryDecorator(new HookDiscovery('data_type_info')), 'typed_data:types');
+    $this->discovery = new HookDiscovery('data_type_info');
+    $this->discovery = new ProcessDecorator($this->discovery, array($this, 'processDefinition'));
+    $this->discovery = new DerivativeDiscoveryDecorator($this->discovery);
+    $this->discovery = new CacheDecorator($this->discovery, 'typed_data:types');
     $this->factory = new TypedDataFactory($this->discovery);
   }
 
diff --git a/core/modules/field_sql_storage/lib/Drupal/field_sql_storage/Entity/Tables.php b/core/modules/field_sql_storage/lib/Drupal/field_sql_storage/Entity/Tables.php
index a387cf4..11e34db 100644
--- a/core/modules/field_sql_storage/lib/Drupal/field_sql_storage/Entity/Tables.php
+++ b/core/modules/field_sql_storage/lib/Drupal/field_sql_storage/Entity/Tables.php
@@ -9,6 +9,7 @@
 
 use Drupal\Core\Database\Query\SelectInterface;
 use Drupal\Core\Entity\Query\QueryException;
+use Drupal\Core\Entity\Field\Type\EntityReference;
 
 /**
  * Adds tables and fields to the SQL entity query.
@@ -192,7 +193,7 @@ function addField($field, $type, $langcode) {
           $next_index_prefix = $relationship_specifier;
         }
         // Check for a valid relationship.
-        if (isset($propertyDefinitions[$relationship_specifier]['constraints']['EntityType']) && isset($propertyDefinitions[$relationship_specifier]['settings']['id source'])) {
+        if (isset($propertyDefinitions[$relationship_specifier]['constraints']['EntityType']) && $entity->{$specifier}->get('entity') instanceof EntityReference) {
           // If it is, use the entity type.
           $entity_type = $propertyDefinitions[$relationship_specifier]['constraints']['EntityType'];
           $entity_info = entity_get_info($entity_type);
diff --git a/core/modules/image/lib/Drupal/image/Type/ImageItem.php b/core/modules/image/lib/Drupal/image/Type/ImageItem.php
index f6cedf2..104e678 100644
--- a/core/modules/image/lib/Drupal/image/Type/ImageItem.php
+++ b/core/modules/image/lib/Drupal/image/Type/ImageItem.php
@@ -31,6 +31,9 @@ public function getPropertyDefinitions() {
       static::$propertyDefinitions['fid'] = array(
         'type' => 'integer',
         'label' => t('Referenced file id.'),
+        'constraints' => array(
+          'Range' => array('min' => 0),
+        ),
       );
       static::$propertyDefinitions['alt'] = array(
         'type' => 'boolean',
@@ -49,7 +52,7 @@ public function getPropertyDefinitions() {
         'label' => t('The height of the image in pixels.'),
       );
       static::$propertyDefinitions['entity'] = array(
-        'type' => 'entity',
+        'type' => 'entity_reference',
         'constraints' => array(
           'EntityType' => 'file',
         ),
@@ -68,15 +71,35 @@ public function getPropertyDefinitions() {
    * Overrides \Drupal\Core\Entity\Field\FieldItemBase::get().
    */
   public function setValue($values, $notify = TRUE) {
-    // Treat the values as property value of the entity property, if no array is
-    // given.
     if (isset($values) && !is_array($values)) {
-      $values = array('entity' => $values);
+      // Directly update the property instead of invoking the parent, so it can
+      // handle objects and IDs.
+      $this->properties['entity']->setValue($values, $notify);
+      // If notify was FALSE, ensure the fid property gets synched.
+      if (!$notify) {
+        $this->set('fid', $this->properties['entity']->getTargetIdentifier(), FALSE);
+      }
+    }
+    else {
+      // Make sure that the 'entity' property gets set as 'fid'.
+      if (isset($values['fid']) && !isset($values['entity'])) {
+        $values['entity'] = $values['fid'];
+      }
+      parent::setValue($values, $notify);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function onChange($property_name) {
+    // Make sure that the target ID and the target property stay in sync.
+    if ($property_name == 'fid') {
+      $this->properties['entity']->setValue($this->fid, FALSE);
     }
-    // Make sure that the 'entity' property gets set as 'fid'.
-    if (isset($values['fid']) && !isset($values['entity'])) {
-      $values['entity'] = $values['fid'];
+    elseif ($property_name == 'entity') {
+      $this->set('fid', $this->properties['entity']->getTargetIdentifier(), FALSE);
     }
-    parent::setValue($values, $notify);
+    parent::onChange($property_name);
   }
 }
diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleContentTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleContentTest.php
index d69d083..a45a17e 100644
--- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleContentTest.php
+++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleContentTest.php
@@ -95,6 +95,7 @@ function testContentTypeLanguageConfiguration() {
     $this->drupalPost("admin/structure/types/manage/{$type2->type}", $edit, t('Save content type'));
     $this->assertRaw(t('The content type %type has been updated.', array('%type' => $type2->name)));
     $this->drupalLogout();
+    drupal_static_reset('language_list');
 
     // Verify language selection is not present on the node add form.
     $this->drupalLogin($web_user);
@@ -218,6 +219,7 @@ function testNodeAdminLanguageFilter() {
     // Enable multiple languages.
     $this->drupalPost('admin/config/regional/language/edit/en', array('locale_translate_english' => TRUE), t('Save language'));
     $this->drupalPost('admin/config/regional/language/add', array('predefined_langcode' => 'zh-hant'), t('Add language'));
+    drupal_static_reset('language_list');
 
     // Create two nodes: English and Chinese.
     $node_en = $this->drupalCreateNode(array('langcode' => 'en'));
