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 d99560b..b45707c 100644
--- a/core/modules/translation_entity/lib/Drupal/translation_entity/FieldTranslationSynchronizer.php
+++ b/core/modules/translation_entity/lib/Drupal/translation_entity/FieldTranslationSynchronizer.php
@@ -101,10 +101,7 @@ public function synchronizeEntity(EntityInterface $entity, $sync_langcode, $orig
    * 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. The synchronized column values are assumed to
-   * be unique among the various items, this is necessary to detect and replay
-   * changes in the order. They are also assumed to change simultanously, so
-   * that a change in any column indicates that all of them have changed.
+   * must be integer or strings.
    *
    * @param array $field_values
    *   The field values to be synchronized.
@@ -132,24 +129,16 @@ public function synchronizeField(&$field_values, $unchanged_items, $sync_langcod
     // values will allow us to detect any change in the order of the new items
     // for each column.
     for ($delta = 0; $delta < $total; $delta++) {
-      foreach ($columns as $column) {
-        // Store the delta for the unchanged column value.
-        if (isset($unchanged_items[$delta][$column])) {
-          $value = $unchanged_items[$delta][$column];
-          $this->validateValue($value);
-          $change_map[$column][$value]['old'] = $delta;
-        }
-        // Store the delta for the new column value.
-        if (isset($source_items[$delta][$column])) {
-          $value = $source_items[$delta][$column];
-          $this->validateValue($value);
-          $change_map[$column][$value]['new'] = $delta;
+      foreach (array('old' => $unchanged_items, 'new' => $source_items) as $key => $items) {
+        if ($item_id = $this->itemIdentifier($items, $delta, $columns)) {
+          $change_map[$item_id][$key][] = $delta;
         }
       }
     }
 
-    // Backup field values.
+    // Backup field values and the change map.
     $original_field_values = $field_values;
+    $original_change_map = $change_map;
 
     // Reset field values so that no spurious one is stored. Source values must
     // be preserved in any case.
@@ -159,6 +148,10 @@ public function synchronizeField(&$field_values, $unchanged_items, $sync_langcod
     foreach ($translations as $langcode) {
       // We need to synchronize only values different from the source ones.
       if ($langcode != $sync_langcode) {
+        // Reinitialize the change map as it is emptied while processing each
+        // language.
+        $change_map = $original_change_map;
+
         // By using the maximum cardinality we ensure to process removed items.
         for ($delta = 0; $delta < $total; $delta++) {
           // By inspecting the map we built before we can tell whether a value
@@ -166,12 +159,18 @@ public function synchronizeField(&$field_values, $unchanged_items, $sync_langcod
           // a new value, in fact it did not exist before.
           $created = TRUE;
           $removed = TRUE;
-          foreach ($columns as $column) {
-            if (isset($source_items[$delta][$column])) {
-              $value = $source_items[$delta][$column];
-              $created = $created && !isset($change_map[$column][$value]['old']);
-              $removed = $removed && !isset($change_map[$column][$value]['new']);
+          $old_delta = -1;
+          $new_delta = -1;
+
+          if ($item_id = $this->itemIdentifier($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;
           }
 
           // If an item has been removed we do not store its translations.
@@ -186,9 +185,7 @@ public function synchronizeField(&$field_values, $unchanged_items, $sync_langcod
           // 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.
-          elseif (!empty($change_map[$column][$value])) {
-            $old_delta = $change_map[$column][$value]['old'];
-            $new_delta = $change_map[$column][$value]['new'];
+          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
             // the new values are at least propagated to all the translations.
@@ -221,16 +218,44 @@ protected function loadUnchanged($entity_type, $id) {
   }
 
   /**
+   * Computes an identifier string for the specified item.
+   *
+   * @param array $items
+   *   An array of field items.
+   * @param integer $delta
+   *   The delta identifying the item to be processed.
+   * @param array $columns
+   *   An array of column names to be synchronized.
+   *
+   * @returns string
+   *   An identifier string.
+   */
+  protected function itemIdentifier(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]);
+        }
+      }
+    }
+    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_int($value) && !is_string($value)) {
-      throw new \InvalidArgumentException('A synchronized value can only be an integer or a string.');
+    if (!is_numeric($value) && !is_string($value)) {
+      throw new \InvalidArgumentException('A synchronized value can only be a number or a string.');
     }
-    return TRUE;
+    return $value;
   }
 
 }
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 4a209d5..33a1eb7 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
@@ -73,7 +73,7 @@ protected function setUp() {
 
     $this->synchronizer = new FieldTranslationSynchronizer(drupal_container()->get('plugin.manager.entity'));
     $this->synchronized = array('sync1', 'sync2');
-    $this->columns = array_merge($this->synchronized, array('value1', 'value2'));
+    $this->columns = array_merge($this->synchronized, array('var1', 'var2'));
     $this->langcodes = array('en', 'it', 'fr', 'de', 'es');
     $this->cardinality = 4;
     $this->unchangedFieldValues = array();
@@ -182,4 +182,81 @@ public function testFieldSync() {
     $this->assertTrue($result, 'Scrambled items have been correctly synchronized.');
   }
 
+  /**
+   * Tests that items holding the same values are correctly synchronized.
+   */
+  public function testMultipleSyncedValues() {
+    $sync_langcode = $this->langcodes[1];
+    $unchanged_items = $this->unchangedFieldValues[$sync_langcode];
+
+    // Determine whether the unchanged values should be altered depending on
+    // their delta.
+    $delta_callbacks = array(
+      // Continuous field values: all of values are equal.
+      function($delta) { return TRUE; },
+      // Alternated field values: only the even ones are equal.
+      function($delta) { return $delta % 2 !== 0; },
+      // Sparse field values: only the "middle" ones are equal.
+      function($delta) { return $delta === 1 || $delta === 2; },
+      // Sparse field values: only the "extreme" ones are equal.
+      function($delta) { return $delta === 0 || $delta === 3; },
+    );
+
+    foreach ($delta_callbacks as $delta_callback) {
+      $field_values = $this->unchangedFieldValues;
+
+      for ($delta = 0; $delta < $this->cardinality; $delta++) {
+        if ($delta_callback($delta)) {
+          foreach ($this->columns as $column) {
+            $field_values[$sync_langcode][$delta][$column] = $field_values[$sync_langcode][0][$column];
+          }
+        }
+      }
+
+      $changed_items = $field_values[$sync_langcode];
+      $this->synchronizer->synchronizeField($field_values, $unchanged_items, $sync_langcode, $this->langcodes, $this->synchronized);
+
+      $result = TRUE;
+      foreach ($this->unchangedFieldValues as $langcode => $unchanged_items) {
+        for ($delta = 0; $delta < $this->cardinality; $delta++) {
+          foreach ($this->columns as $column) {
+            // The first item is always unchanged hence it is retained by the
+            // synchronization process. The other ones are retained or synced
+            // depending on the logic implemented by the delta callback.
+            $value = $delta > 0 && $delta_callback($delta) ? $changed_items[0][$column] : $unchanged_items[$delta][$column];
+            $result = $result && ($field_values[$langcode][$delta][$column] == $value);
+          }
+        }
+      }
+      $this->assertTrue($result, 'Multiple synced items have been correctly synchronized.');
+    }
+  }
+
+  /**
+   * Tests that one change in a synchronized column triggers a change in all columns.
+   */
+  public function testDifferingSyncedColumns() {
+    $sync_langcode = $this->langcodes[2];
+    $unchanged_items = $this->unchangedFieldValues[$sync_langcode];
+    $field_values = $this->unchangedFieldValues;
+
+    for ($delta = 0; $delta < $this->cardinality; $delta++) {
+      $index = ($delta % 2) + 1;
+      $field_values[$sync_langcode][$delta]['sync' . $index] .= '-updated';
+    }
+
+    $changed_items = $field_values[$sync_langcode];
+    $this->synchronizer->synchronizeField($field_values, $unchanged_items, $sync_langcode, $this->langcodes, $this->synchronized);
+
+    $result = TRUE;
+    foreach ($this->unchangedFieldValues as $langcode => $unchanged_items) {
+      for ($delta = 0; $delta < $this->cardinality; $delta++) {
+        foreach ($this->columns as $column) {
+          $result = $result && ($field_values[$langcode][$delta][$column] == $changed_items[$delta][$column]);
+        }
+      }
+    }
+    $this->assertTrue($result, 'Differing synced columns have been correctly synchronized.');
+  }
+
 }
