diff --git a/core/modules/translation_entity/lib/Drupal/translation_entity/EntityTranslationController.php b/core/modules/translation_entity/lib/Drupal/translation_entity/EntityTranslationController.php
index 33d7b96..94b92c4 100644
--- a/core/modules/translation_entity/lib/Drupal/translation_entity/EntityTranslationController.php
+++ b/core/modules/translation_entity/lib/Drupal/translation_entity/EntityTranslationController.php
@@ -375,6 +375,8 @@ public function entityFormEntityBuild($entity_type, EntityInterface $entity, arr
     }
 
     // Set contextual information that can be reused during the storage phase.
+    // @todo Remove this once we have an EntityLanguageDecorator to deal with
+    //   the active language.
     $attributes = drupal_container()->get('request')->attributes;
     $attributes->set('working_langcode', $form_langcode);
     $attributes->set('source_langcode', $source_langcode);
diff --git a/core/modules/translation_entity/lib/Drupal/translation_entity/FieldTranslationSynchronizer.php b/core/modules/translation_entity/lib/Drupal/translation_entity/FieldTranslationSynchronizer.php
index c011186..8137dd4 100644
--- a/core/modules/translation_entity/lib/Drupal/translation_entity/FieldTranslationSynchronizer.php
+++ b/core/modules/translation_entity/lib/Drupal/translation_entity/FieldTranslationSynchronizer.php
@@ -8,7 +8,6 @@
 namespace Drupal\translation_entity;
 
 use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Entity\EntityManager;
 
 /**
  * Provides field translation synchronization capabilities.
@@ -16,23 +15,6 @@
 class FieldTranslationSynchronizer {
 
   /**
-   * The entity manager to be used to load the unchanged entity if needed.
-   *
-   * @var \Drupal\Core\Entity\EntityManager
-   */
-  protected $entityManager;
-
-  /**
-   * Initializes an instance of the field translation synchronizer.
-   *
-   * @param \Drupal\Core\Entity\EntityManager $entityManager
-   *   An entity manager instance.
-   */
-  public function __construct(EntityManager $entityManager) {
-    $this->entityManager = $entityManager;
-  }
-
-  /**
    * Performs field column synchronization on the given entity.
    *
    * Field column synchronization takes care of propagating any change in the
@@ -46,14 +28,14 @@ public function __construct(EntityManager $entityManager) {
    *
    * @param \Drupal\Core\Entity\EntityInterface $entity
    *   The entity whose values should be synchronized.
-   * @param $sync_langcode
+   * @param string $sync_langcode
    *   The language of the translation whose values should be used as source for
    *   synchronization.
-   * @param $original_langcode
+   * @param string $original_langcode
    *   (optional) If a new translation is being created, this should be the
-   *   language code of the original values. Defaults to FALSE.
+   *   language code of the original values. Defaults to NULL.
    */
-  public function synchronizeEntity(EntityInterface $entity, $sync_langcode, $original_langcode = FALSE) {
+  public function synchronizeEntity(EntityInterface $entity, $sync_langcode, $original_langcode = NULL) {
     $translations = $entity->getTranslationLanguages();
 
     // If we have no information about what to sync to, if we are creating a new
@@ -65,7 +47,7 @@ public function synchronizeEntity(EntityInterface $entity, $sync_langcode, $orig
 
     // If the entity language is being changed there is nothing to synchronize.
     $entity_type = $entity->entityType();
-    $entity_unchanged = isset($entity->original) ? $entity->original : $this->loadUnchanged($entity_type, $entity->id());
+    $entity_unchanged = isset($entity->original) ? $entity->original : entity_load_unchanged($entity_type, $entity->id());
     if ($entity->language()->langcode != $entity_unchanged->language()->langcode) {
       return;
     }
@@ -100,8 +82,7 @@ public function synchronizeEntity(EntityInterface $entity, $sync_langcode, $orig
    * All the column values of the "active" language are compared to the
    * unchanged values to detect any addition, removal or change in the items
    * order. Subsequently the detected changes are performed on the field items
-   * in other available languages. For this to properly work the column values
-   * must be integer or strings.
+   * in other available languages.
    *
    * @param array $field_values
    *   The field values to be synchronized.
@@ -130,7 +111,7 @@ public function synchronizeField(array &$field_values, array $unchanged_items, $
     // for each column.
     for ($delta = 0; $delta < $total; $delta++) {
       foreach (array('old' => $unchanged_items, 'new' => $source_items) as $key => $items) {
-        if ($item_id = $this->itemIdentifier($items, $delta, $columns)) {
+        if ($item_id = $this->itemHash($items, $delta, $columns)) {
           $change_map[$item_id][$key][] = $delta;
         }
       }
@@ -159,18 +140,18 @@ public function synchronizeField(array &$field_values, array $unchanged_items, $
           // a new value, in fact it did not exist before.
           $created = TRUE;
           $removed = TRUE;
-          $old_delta = -1;
-          $new_delta = -1;
+          $old_delta = NULL;
+          $new_delta = NULL;
 
-          if ($item_id = $this->itemIdentifier($source_items, $delta, $columns)) {
+          if ($item_id = $this->itemHash($source_items, $delta, $columns)) {
             if (!empty($change_map[$item_id]['old'])) {
               $old_delta = array_shift($change_map[$item_id]['old']);
             }
             if (!empty($change_map[$item_id]['new'])) {
               $new_delta = array_shift($change_map[$item_id]['new']);
             }
-            $created = $created && $old_delta < 0;
-            $removed = $removed && $new_delta < 0;
+            $created = $created && !isset($old_delta);
+            $removed = $removed && !isset($new_delta);
           }
 
           // If an item has been removed we do not store its translations.
@@ -182,9 +163,7 @@ public function synchronizeField(array &$field_values, array $unchanged_items, $
           elseif ($created) {
             $field_values[$langcode][$delta] = $source_items[$delta];
           }
-          // Otherwise the current item might have been reordered. We assume
-          // that if a synchronized column changes all the other ones belonging
-          // to the same item change accordingly.
+          // Otherwise the current item might have been reordered.
           elseif ($old_delta >= 0 && $new_delta >= 0) {
             // If for any reason the old value is not defined for the current
             // language we fall back to the new source value, this way we ensure
@@ -200,25 +179,7 @@ public function synchronizeField(array &$field_values, array $unchanged_items, $
   }
 
   /**
-   * Loads the unchanged, i.e. not modified, entity from the database.
-   *
-   * @param string $entity_type
-   *   The entity type to load.
-   * @param mixed $id
-   *   The ID of the entity to load.
-   *
-   * @return
-   *   The unchanged entity, or FALSE if the entity cannot be loaded.
-   */
-  protected function loadUnchanged($entity_type, $id) {
-    $controller = $this->entityManager->getStorageController($entity_type);
-    $controller->resetCache(array($id));
-    $result = $controller->load(array($id));
-    return reset($result);
-  }
-
-  /**
-   * Computes an identifier string for the specified item.
+   * Computes a hash code for the specified item.
    *
    * @param array $items
    *   An array of field items.
@@ -228,34 +189,27 @@ protected function loadUnchanged($entity_type, $id) {
    *   An array of column names to be synchronized.
    *
    * @returns string
-   *   An identifier string.
+   *   A hash code that can be used to identify the item.
    */
-  protected function itemIdentifier(array $items, $delta, array $columns) {
+  protected function itemHash(array $items, $delta, array $columns) {
     $values = array();
+
     if (isset($items[$delta])) {
       foreach ($columns as $column) {
-        if (isset($items[$delta][$column])) {
-          $values[] = $this->validateValue($items[$delta][$column]);
+        if (!empty($items[$delta][$column])) {
+          $value = $items[$delta][$column];
+          // String and integer values are by far the most common item values,
+          // thus we special-case them to improve performance.
+          $values[] = is_string($value) || is_int($value) ? $value : md5(serialize($value));
+        }
+        else {
+          // Explicitly track also empty values.
+          $values[] = '';
         }
       }
     }
-    return !empty($values) ? implode('.', $values) : FALSE;
-  }
 
-  /**
-   * Checks whether a value to be synchronized has the expected type.
-   *
-   * @param mixed $value
-   *   The value to be checked.
-   *
-   * @return mixed
-   *   The given value.
-   */
-  protected function validateValue($value) {
-    if (!is_numeric($value) && !is_string($value)) {
-      throw new \InvalidArgumentException('A synchronized value can only be a number or a string.');
-    }
-    return $value;
+    return implode('.', $values);
   }
 
 }
diff --git a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationSyncUnitTest.php b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationSyncUnitTest.php
index 33a1eb7..482a1aa 100644
--- a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationSyncUnitTest.php
+++ b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationSyncUnitTest.php
@@ -63,7 +63,7 @@ class EntityTranslationSyncUnitTest extends DrupalUnitTestBase {
   public static function getInfo() {
     return array(
       'name' => 'Field synchronization',
-      'description' => 'Tests the field synchronization algorithm.',
+      'description' => 'Tests the field synchronization logic.',
       'group' => 'Entity Translation UI',
     );
   }
@@ -71,7 +71,7 @@ public static function getInfo() {
   protected function setUp() {
     parent::setUp();
 
-    $this->synchronizer = new FieldTranslationSynchronizer(drupal_container()->get('plugin.manager.entity'));
+    $this->synchronizer = new FieldTranslationSynchronizer();
     $this->synchronized = array('sync1', 'sync2');
     $this->columns = array_merge($this->synchronized, array('var1', 'var2'));
     $this->langcodes = array('en', 'it', 'fr', 'de', 'es');
@@ -192,7 +192,7 @@ public function testMultipleSyncedValues() {
     // Determine whether the unchanged values should be altered depending on
     // their delta.
     $delta_callbacks = array(
-      // Continuous field values: all of values are equal.
+      // Continuous field values: all values are equal.
       function($delta) { return TRUE; },
       // Alternated field values: only the even ones are equal.
       function($delta) { return $delta % 2 !== 0; },
diff --git a/core/modules/translation_entity/translation_entity.module b/core/modules/translation_entity/translation_entity.module
index 182dda4..45ddce1 100644
--- a/core/modules/translation_entity/translation_entity.module
+++ b/core/modules/translation_entity/translation_entity.module
@@ -797,7 +797,7 @@ function translation_entity_field_info_alter(&$info) {
  */
 function translation_entity_field_attach_presave(EntityInterface $entity) {
   if (translation_entity_enabled($entity->entityType(), $entity->bundle())) {
-    $synchronizer = new FieldTranslationSynchronizer(drupal_container()->get('plugin.manager.entity'));
+    $synchronizer = new FieldTranslationSynchronizer();
     $attributes = drupal_container()->get('request')->attributes;
     $synchronizer->synchronizeEntity($entity, $attributes->get('working_langcode'), $attributes->get('source_langcode'));
   }
