diff --git a/README.txt b/README.txt
index e027040..c611bdd 100644
--- a/README.txt
+++ b/README.txt
@@ -1,4 +1,3 @@
-
 Field collection
 -----------------
 Provides a field collection field, to which any number of fields can be attached.
@@ -28,9 +27,20 @@ field collection item may also be viewed and edited separately.
     module might provide such widgets itself too.
 
 
-Restrictions
--------------
+ Using field collection with entity translation
+ -----------------------------------------------
+
+  * Field collection items must be selected as a translatable entity type at
+    Admin -> Config -> Regional -> Entity Translation.
+
+  * The common use case is to leave the field collection field untranslatable
+    and set the necessary fields inside it to translatable.  There is currently
+    a known issue where a host can not be translated unless it has at least
+    one other field that is translatable, even if some fields inside one of
+    its field collections are translatable.
 
-  * As of now, the field collection field does not properly respect field
-    translation. Thus, for now it is suggested to only use the field for
-    entities that are not translatable.
+  * The alternate use case is to make the field collection field in the host
+    translatable.  If this is done it does not matter whether the inner fields
+    are set to translatable or not, they will all be translatable as every
+    language for the host will have a completely separate copy of the field
+    collection item(s).
diff --git a/field_collection.entity.inc b/field_collection.entity.inc
index 2e8a11b..9369bc4 100644
--- a/field_collection.entity.inc
+++ b/field_collection.entity.inc
@@ -215,9 +215,20 @@ class FieldCollectionItemEntity extends Entity {
    *
    * @param object $entity
    *   Host entity.
+   * @param string $host_entity_type
+   *   The entity type of the entity the field collection is attached to.
    */
-  public function updateHostEntity($entity) {
+  public function updateHostEntity($entity, $host_entity_type = NULL) {
     $this->fetchHostDetails();
+    // If it isn't possible to retrieve hostEntityType due to the fact that it's
+    // not saved in the DB yet then fill in info about the hostEntity manually.
+    // This happens when creating a new revision of a field collection entity
+    // and it needs to relate to the new revision of the host entity.
+    if (!$this->hostEntityType) {
+      $this->hostEntityType = $host_entity_type;
+      $this->hostEntity = $entity;
+      list($this->hostEntityId, $this->hostEntityRevisionId) = entity_extract_ids($this->hostEntityType, $this->hostEntity);
+    }
     list($recieved_id) = entity_extract_ids($this->hostEntityType, $entity);
 
     if ($this->isInUse()) {
@@ -231,8 +242,8 @@ class FieldCollectionItemEntity extends Entity {
     if ($current_id == $recieved_id) {
       $this->hostEntity = $entity;
       $delta = $this->delta();
-      if (isset($entity->{$this->field_name}[$this->langcode][$delta]['entity'])) {
-        $entity->{$this->field_name}[$this->langcode][$delta]['entity'] = $this;
+      if (isset($entity->{$this->field_name}[$this->langcode()][$delta]['entity'])) {
+        $entity->{$this->field_name}[$this->langcode()][$delta]['entity'] = $this;
       }
     }
     else {
@@ -326,14 +337,34 @@ class FieldCollectionItemEntity extends Entity {
   public function delta() {
     if (($entity = $this->hostEntity()) && isset($entity->{$this->field_name})) {
       foreach ($entity->{$this->field_name} as $langcode => &$data) {
-        foreach ($data as $delta => $item) {
-          if (isset($item['value']) && $item['value'] == $this->item_id) {
-            $this->langcode = $langcode;
-            return $delta;
+        if (!empty($data)) {
+          foreach ($data as $delta => $item) {
+            if (isset($item['value']) && $item['value'] == $this->item_id) {
+              $this->langcode = $langcode;
+              return $delta;
+            }
+            elseif (isset($item['entity']) && $item['entity'] === $this) {
+              $this->langcode = $langcode;
+              return $delta;
+            }
           }
-          elseif (isset($item['entity']) && $item['entity'] === $this) {
-            $this->langcode = $langcode;
-            return $delta;
+        }
+      }
+      // If we don't find the delta in the current values (cause the item
+      // is being deleted, for example), we search the delta in the originalcontent.
+      if (!empty($entity->original)) {
+        foreach ($entity->original->{$this->field_name} as $langcode => &$data) {
+          if (!empty($data)) {
+            foreach ($data as $delta => $item) {
+              if (isset($item['value']) && $item['value'] == $this->item_id) {
+                $this->langcode = $langcode;
+                return $delta;
+              }
+              elseif (isset($item['entity']) && $item['entity'] === $this) {
+                $this->langcode = $langcode;
+                return $delta;
+              }
+            }
           }
         }
       }
@@ -344,9 +375,15 @@ class FieldCollectionItemEntity extends Entity {
    * Determines the language code under which the item is stored.
    */
   public function langcode() {
-    if ($this->delta() !== NULL) {
-      return $this->langcode;
+    if ($this->delta() === NULL || empty($this->langcode)) {
+      $this->langcode = field_collection_entity_language('field_collection_item', $this);
     }
+
+    if (empty($this->langcode) || ($this->langcode != LANGUAGE_NONE && (!module_exists('entity_translation') || !entity_translation_enabled('field_collection_item')))) {
+      $this->langcode = LANGUAGE_NONE;
+    }
+
+    return $this->langcode;
   }
 
   /**
@@ -388,6 +425,11 @@ class FieldCollectionItemEntity extends Entity {
       throw new Exception("Unable to create a field collection item without a given host entity.");
     }
 
+    // Copy the values of translatable fields for a new field collection item.
+    if (field_collection_item_is_translatable() && !empty($this->is_new) && $this->langcode() == LANGUAGE_NONE) {
+      $this->copyTranslations();
+    }
+
     // Only save directly if we are told to skip saving the host entity. Else,
     // we always save via the host as saving the host might trigger saving
     // field collection items anyway (e.g. if a new revision is created).
@@ -410,11 +452,12 @@ class FieldCollectionItemEntity extends Entity {
       // @see field_collection_field_presave()
       $delta = $this->delta();
       if (isset($delta)) {
-        $host_entity->{$this->field_name}[$this->langcode][$delta] = array('entity' => $this);
+        $host_entity->{$this->field_name}[$this->langcode()][$delta] = array('entity' => $this);
       }
       else {
-        $host_entity->{$this->field_name}[$this->langcode][] =  array('entity' => $this);
+        $host_entity->{$this->field_name}[$this->langcode()][] = array('entity' => $this);
       }
+
       return entity_save($this->hostEntityType, $host_entity);
     }
   }
@@ -428,16 +471,59 @@ class FieldCollectionItemEntity extends Entity {
   }
 
   /**
+   * Copies text to all languages the collection item has a translation for.
+   *
+   * @param $source_language
+   *   Language code to copy the text from.
+   */
+  public function copyTranslations($source_language = NULL) {
+    // Get a handler for Entity Translation if there is one.
+    $host_et_handler = NULL;
+    if (module_exists('entity_translation')) {
+      $host_et_handler = entity_translation_get_handler($this->hostEntityType(), $this->hostEntity());
+    }
+    if (is_null($host_et_handler)) {
+      return;
+    }
+
+    $host_languages = array_keys($host_et_handler->getTranslations()->data);
+    if (empty($host_languages)) {
+      $host_languages = array(entity_language($this->hostEntityType(), $this->hostEntity()));
+    }
+    $source_language = isset($source_language) ? $source_language : $host_et_handler->getLanguage();
+    $target_languages = array_diff($host_languages, array($source_language));
+    $fields_instances = array_keys(field_info_instances('field_collection_item', $this->field_name));
+    $fields = field_info_fields();
+
+    foreach ($fields_instances as $translatable_field) {
+      if ($fields[$translatable_field]['translatable'] == 1) {
+        foreach ($target_languages as $langcode) {
+          if (isset($this->{$translatable_field}[$source_language])) {
+            //Source (translatable_field) is set, therefore continue processing.
+            if(!isset($this->{$translatable_field}[$langcode])) {
+              //Destination (translatable_field) is not set, therefore safe to copy the translation.
+              $this->{$translatable_field}[$langcode] = $this->{$translatable_field}[$source_language];
+            }
+          }
+        }
+        if ($source_language == LANGUAGE_NONE && count($this->{$translatable_field}) > 1) {
+          $this->{$translatable_field}[$source_language] = NULL;
+        }
+      }
+    }
+  }
+
+  /**
    * Deletes the host entity's reference of the field collection item.
    */
   protected function deleteHostEntityReference() {
     $delta = $this->delta();
     if ($this->item_id && isset($delta)) {
-      unset($this->hostEntity->{$this->field_name}[$this->langcode][$delta]);
+      unset($this->hostEntity->{$this->field_name}[$this->langcode()][$delta]);
       // Do not save when the host entity is being deleted. See
       // field_collection_field_delete().
       if (empty($this->hostEntity->field_collection_deleting)) {
-        entity_save($this->hostEntityType, $this->hostEntity);
+        entity_save($this->hostEntityType(), $this->hostEntity());
       }
     }
   }
@@ -449,7 +535,6 @@ class FieldCollectionItemEntity extends Entity {
    * a field collection item on the default revision of the host should not
    * delete the collection item from archived revisions too. Instead, we delete
    * the current default revision and archive the field collection.
-   *
    */
   public function deleteRevision($skip_host_update = FALSE) {
     if (!$this->revision_id) {
@@ -473,11 +558,8 @@ class FieldCollectionItemEntity extends Entity {
         ->condition('revision_id', $this->revision_id, '<>')
         ->execute()
         ->fetchAssoc();
-      // If no other revision is left, delete. Else archive the item.
-      if (!$row) {
-        $this->delete();
-      }
-      else {
+
+      if ($row) {
         // Make the other revision the default revision and archive the item.
         db_update('field_collection_item')
           ->fields(array('archived' => 1, 'revision_id' => $row['revision_id']))
@@ -486,6 +568,10 @@ class FieldCollectionItemEntity extends Entity {
         entity_get_controller('field_collection_item')->resetCache(array($this->item_id));
         entity_revision_delete('field_collection_item', $this->revision_id);
       }
+      if (!$row && !isset($this->hostEntity()->{$this->field_name}[$this->langcode()][$this->delta()])) {
+        // Delete if there is no existing revision or translation to be saved.
+        $this->delete();
+      }
     }
   }
 
@@ -507,6 +593,15 @@ class FieldCollectionItemEntity extends Entity {
   }
 
   /**
+   * Generate an array for rendering the field collection item.
+   */
+  public function view($view_mode = 'full', $langcode = NULL, $page = NULL) {
+    // Allow modules to change the view mode.
+    $view_mode = key(entity_view_mode_prepare($this->entityType, array($this->item_id => $this), $view_mode, $langcode));
+    return parent::view($view_mode, $langcode, $page);
+  }
+
+  /**
    * Magic method to only serialize what's necessary.
    */
   public function __sleep() {
diff --git a/field_collection.info b/field_collection.info
index 30f4440..ed56eda 100644
--- a/field_collection.info
+++ b/field_collection.info
@@ -2,9 +2,11 @@ name = Field collection
 description = Provides a field collection field, to which any number of fields can be attached.
 core = 7.x
 dependencies[] = entity
+test_dependencies[] = entity_translation
 files[] = field_collection.test
 files[] = field_collection.entity.inc
 files[] = field_collection.info.inc
+files[] = includes/translation.handler.field_collection_item.inc
 files[] = views/field_collection_handler_relationship.inc
 files[] = field_collection.migrate.inc
 configure = admin/structure/field-collections
diff --git a/field_collection.install b/field_collection.install
index d2b1892..7296346 100644
--- a/field_collection.install
+++ b/field_collection.install
@@ -85,6 +85,7 @@ function field_collection_field_schema($field) {
   return array(
     'columns' => $columns,
     'indexes' => array(
+      'value' => array('value'),
       'revision_id' => array('revision_id'),
     ),
   );
@@ -328,3 +329,55 @@ function field_collection_update_7006() {
     }
   }
 }
+
+/**
+ * Add index on {$field_collection_field}_value column for all tables.
+ */
+function field_collection_update_7007() {
+  foreach (field_read_fields(array('type' => 'field_collection')) as $field_name => $field) {
+    if (!isset($field['indexes']['value'])) {
+      // Add index on the value column and update the field.
+      $field['indexes']['value'] = array('value');
+      field_update_field($field);
+    }
+
+    $table_prefixes = array('field_data', 'field_revision');
+    foreach ($table_prefixes as $table_prefix) {
+      $table = "{$table_prefix}_{$field_name}";
+      $value_column = "{$field_name}_value";
+      if (!db_index_exists($table, $value_column)) {
+        // Add index on the value column.
+        db_add_index($table, $value_column, array($value_column));
+      }
+    }
+  }
+}
+
+/**
+ * Update fields in field collections already set to use Entity Translation.
+ */
+function field_collection_update_7008() {
+  // Include FieldCollectionItemEntity class.
+  module_load_include('inc', 'field_collection', 'field_collection.entity');
+
+  $results = array();
+  foreach (field_info_fields() as $f_name => $field) {
+    if ($field['translatable'] == 1 && isset($field['bundles']['field_collection_item'])) {
+      $query = new EntityFieldQuery();
+      $query->entityCondition('entity_type', 'field_collection_item')
+            ->fieldLanguageCondition($f_name, LANGUAGE_NONE);
+      $query_result = $query->execute();
+      if (isset($query_result['field_collection_item'])) {
+        $results = $results + $query_result['field_collection_item'];
+      }
+    }
+  }
+  if (count($results)) {
+    $ids = array_keys($results);
+    $field_collection_items = entity_load('field_collection_item', $ids);
+    foreach ($field_collection_items as $item) {
+      $item->copyTranslations(LANGUAGE_NONE);
+      $item->save();
+    }
+  }
+}
diff --git a/field_collection.module b/field_collection.module
index db7b859..3ab2a76 100644
--- a/field_collection.module
+++ b/field_collection.module
@@ -19,6 +19,20 @@ function field_collection_help($path, $arg) {
 }
 
 /**
+ * Implements hook_form_alter().
+ *
+ * Checks for a value set by the embedded widget so fields are not displayed
+ * with the 'all languages' hint incorrectly.
+ */
+function field_collection_form_alter(&$form, &$form_state) {
+  if (!empty($form['#field_collection_translation_fields'])) {
+    foreach ($form['#field_collection_translation_fields'] as $address) {
+      drupal_array_set_nested_value($form, array_merge($address, array('#multilingual')), TRUE);
+    }
+  }
+}
+
+/**
  * Implements hook_ctools_plugin_directory().
  */
 function field_collection_ctools_plugin_directory($module, $plugin) {
@@ -57,7 +71,12 @@ function field_collection_entity_info() {
     ),
     'access callback' => 'field_collection_item_access',
     'deletion callback' => 'field_collection_item_delete',
-    'metadata controller class' => 'FieldCollectionItemMetadataController'
+    'metadata controller class' => 'FieldCollectionItemMetadataController',
+    'translation' => array(
+      'entity_translation' => array(
+        'class' => 'EntityTranslationFieldCollectionItemHandler',
+      ),
+    ),
   );
 
   // Add info about the bundles. We do not use field_info_fields() but directly
@@ -73,6 +92,19 @@ function field_collection_entity_info() {
         'access arguments' => array('administer field collections'),
       ),
     );
+
+    $path = field_collection_field_get_path($field) . '/%field_collection_item';
+    // Enable the first available path scheme as default one.
+    if (!isset($return['field_collection_item']['translation']['entity_translation']['base path'])) {
+      $return['field_collection_item']['translation']['entity_translation']['base path'] = $path;
+      $return['field_collection_item']['translation']['entity_translation']['path wildcard'] = '%field_collection_item';
+      $return['field_collection_item']['translation']['entity_translation']['default_scheme'] = $field_name;
+    }
+    else {
+      $return['field_collection_item']['translation']['entity_translation']['path schemes'][$field_name] = array(
+        'base path' => $path,
+      );
+    }
   }
 
   if (module_exists('entitycache')) {
@@ -84,6 +116,30 @@ function field_collection_entity_info() {
 }
 
 /**
+ * Provide the original entity language.
+ *
+ * If a language property is defined for the current entity we synchronize the
+ * field value using the entity language, otherwise we fall back to
+ * LANGUAGE_NONE.
+ *
+ * @param $entity_type
+ * @param $entity
+ *
+ * @return
+ *   A language code
+ */
+function field_collection_entity_language($entity_type, $entity) {
+  if (module_exists('entity_translation') && entity_translation_enabled($entity_type)) {
+    $handler = entity_translation_get_handler($entity_type, $entity);
+    $langcode = $handler->getLanguage();
+  }
+  else {
+    $langcode = entity_language($entity_type, $entity);
+  }
+  return !empty($langcode) ? $langcode : LANGUAGE_NONE;
+}
+
+/**
  * Menu callback for loading the bundle names.
  */
 function field_collection_field_name_load($arg) {
@@ -291,7 +347,7 @@ function field_collection_item_access($op, FieldCollectionItemEntity $item = NUL
  */
 function field_collection_item_delete($id) {
   $fci = field_collection_item_load($id);
-  if ($fci) {
+  if (!empty($fci)) {
     $fci->delete();
   }
 }
@@ -326,6 +382,7 @@ function field_collection_field_info() {
       'settings' => array(
         'path' => '',
         'hide_blank_items' => TRUE,
+        'hide_initial_item' => FALSE,
       ),
       // Add entity property info.
       'property_type' => 'field_collection_item',
@@ -375,12 +432,11 @@ function field_collection_field_get_path($field) {
  * Implements hook_field_settings_form().
  */
 function field_collection_field_settings_form($field, $instance) {
-
   $form['hide_blank_items'] = array(
     '#type' => 'checkbox',
     '#title' => t('Hide blank items'),
     '#default_value' => $field['settings']['hide_blank_items'],
-    '#description' => t("A blank item is always added to any unlimited valued field's form. If checked, any additional blank items are hidden except of the first item which is always shown."),
+    '#description' => t('Ordinarily a new blank item will be added to unlimited cardinality fields whenever they appear in a form.  Checking this will prevent the blank item from appearing if the field already contains data.'),
     '#weight' => 10,
     '#states' => array(
       // Show the setting if the cardinality is -1.
@@ -389,6 +445,20 @@ function field_collection_field_settings_form($field, $instance) {
       ),
     ),
   );
+  $form['hide_initial_item'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Hide initial item'),
+    '#default_value' => $field['settings']['hide_initial_item'],
+    '#description' => t('Prevent the default blank item from appearing even if the field has no data yet.  If checked, the user must explicitly add the field collection.'),
+    '#weight' => 11,
+    '#states' => array(
+      // Show the setting if the cardinality is -1 and hide_blank_items is checked.
+      'visible' => array(
+        ':input[name="field[cardinality]"]' => array('value' => '-1'),
+        ':input[name="field[settings][hide_blank_items]"]' => array('checked' => TRUE),
+      ),
+    ),
+  );
   return $form;
 }
 
@@ -409,7 +479,7 @@ function field_collection_field_insert($host_entity_type, $host_entity, $field,
         $entity = $new_entity;
       }
       if (!empty($entity->is_new)) {
-        $entity->setHostEntity($host_entity_type, $host_entity, LANGUAGE_NONE, FALSE);
+        $entity->setHostEntity($host_entity_type, $host_entity, field_collection_entity_language($host_entity_type, $host_entity), FALSE);
       }
       $entity->save(TRUE);
       $item = array(
@@ -424,37 +494,44 @@ function field_collection_field_insert($host_entity_type, $host_entity, $field,
  * Implements hook_field_update().
  *
  * Care about removed field collection items.
+ *
  * Support saving field collection items in @code $item['entity'] @endcode. This
  * may be used to seamlessly create field collection items during host-entity
  * creation or to save changes to the host entity and its collections at once.
  */
 function field_collection_field_update($host_entity_type, $host_entity, $field, $instance, $langcode, &$items) {
-  // Prevent workbench moderation from deleting field collections on node_save()
-  // during workbench_moderation_store(), when $host_entity->revision == 0.
-  if (!empty($host_entity->workbench_moderation['updating_live_revision'])) {
+  // When entity language is changed field values are moved to the new language
+  // and old values are marked as removed. We need to avoid processing them in
+  // this case.
+  $entity_langcode = field_collection_entity_language($host_entity_type, $host_entity);
+  $original = isset($host_entity->original) ? $host_entity->original : $host_entity;
+  $original_langcode = field_collection_entity_language($host_entity_type, $original);
+  $langcode = $langcode == $original_langcode ? $entity_langcode : $langcode;
+
+  $top_host = $host_entity;
+  while (method_exists($top_host, 'hostEntity')) {
+    $top_host = $top_host->hostEntity();
+  }
+
+  // Prevent workbench moderation from deleting field collections or paragraphs
+  // on node_save() during workbench_moderation_store(), when
+  // $host_entity->revision == 0.
+  if (!empty($top_host->workbench_moderation['updating_live_revision'])) {
     return;
   }
 
-  $items_original = !empty($host_entity->original->{$field['field_name']}[$langcode]) ? $host_entity->original->{$field['field_name']}[$langcode] : array();
+  // Load items from the original entity.
+  $items_original = !empty($original->{$field['field_name']}[$langcode]) ? $original->{$field['field_name']}[$langcode] : array();
   $original_by_id = array_flip(field_collection_field_item_to_ids($items_original));
 
-  foreach ($items as &$item) {
+  foreach ($items as $delta => &$item) {
     // In case the entity has been changed / created, save it and set the id.
     // If the host entity creates a new revision, save new item-revisions as
     // well.
     if (isset($item['entity']) || !empty($host_entity->revision)) {
-
       if ($entity = field_collection_field_get_entity($item)) {
-
-        if (!empty($entity->is_new)) {
-          $entity->setHostEntity($host_entity_type, $host_entity, LANGUAGE_NONE, FALSE);
-        }
-        else {
-          $entity->updateHostEntity($host_entity);
-        }
-
         // If the host entity is saved as new revision, do the same for the item.
-        if (!empty($host_entity->revision)) {
+        if (!empty($host_entity->revision) || !empty($host_entity->is_new_revision)) {
           $entity->revision = TRUE;
           // Without this cache clear entity_revision_is_default will
           // incorrectly return false here when creating a new published revision
@@ -474,6 +551,14 @@ function field_collection_field_update($host_entity_type, $host_entity, $field,
             $entity->default_revision = FALSE;
           }
         }
+
+        if (!empty($entity->is_new)) {
+          $entity->setHostEntity($host_entity_type, $host_entity, $langcode, FALSE);
+        }
+        else {
+          $entity->updateHostEntity($host_entity, $host_entity_type);
+        }
+
         $entity->save(TRUE);
 
         $item = array(
@@ -482,6 +567,7 @@ function field_collection_field_update($host_entity_type, $host_entity, $field,
         );
       }
     }
+
     unset($original_by_id[$item['value']]);
   }
 
@@ -498,8 +584,17 @@ function field_collection_field_update($host_entity_type, $host_entity, $field,
         ->execute();
     }
     else {
+      // Load items from the original entity from all languages checking which
+      // are the unused items.
+      $current_items = array();
+      $languages = language_list();
+      foreach ($languages as $langcode_value) {
+        $current_items += !empty($host_entity->{$field['field_name']}[$langcode_value->language]) ? $host_entity->{$field['field_name']}[$langcode_value->language] : array();
+        $current_by_id = field_collection_field_item_to_ids($current_items);
+      }
+      $items_to_remove = array_diff($ids, $current_by_id);
       // Delete unused field collection items now.
-      foreach (field_collection_item_load_multiple($ids) as $un_item) {
+      foreach (field_collection_item_load_multiple($items_to_remove) as $un_item) {
         $un_item->updateHostEntity($host_entity);
         $un_item->deleteRevision(TRUE);
       }
@@ -511,9 +606,8 @@ function field_collection_field_update($host_entity_type, $host_entity, $field,
  * Implements hook_field_delete().
  */
 function field_collection_field_delete($entity_type, $entity, $field, $instance, $langcode, &$items) {
-  $ids = field_collection_field_item_to_ids($items);
   // Also delete all embedded entities.
-  if ($ids && field_info_field($field['field_name'])) {
+  if ($ids = field_collection_field_item_to_ids($items)) {
     // We filter out entities that are still being referenced by other
     // host-entities. This should never be the case, but it might happened e.g.
     // when modules cloned a node without knowing about field-collection.
@@ -532,10 +626,20 @@ function field_collection_field_delete($entity_type, $entity, $field, $instance,
         // Filter this $id out.
         unset($ids[$id_key]);
       }
+
+      // Set a flag to remember that the host entity is being deleted. See
+      // FieldCollectionItemEntity::deleteHostEntityReference().
+      // Doing this on $entity is not sufficient because the cache for $entity
+      // may have been reset since it was loaded.  That would cause
+      // hostEntity() to load it from the database later without the flag.
+      $field_collection_item = field_collection_item_load($id);
+      if ($field_collection_item) {
+        $hostEntity = $field_collection_item->hostEntity();
+        if (!empty($hostEntity)) {
+          $hostEntity->field_collection_deleting = TRUE;
+        }
+      }
     }
-    // Set a flag to remember that the host entity is being deleted. See
-    // FieldCollectionItemEntity::deleteHostEntityReference().
-    $entity->field_collection_deleting = TRUE;
 
     entity_delete_multiple('field_collection_item', $ids);
   }
@@ -639,6 +743,7 @@ function field_collection_field_formatter_info() {
       'field types' => array('field_collection'),
       'settings' =>  array(
         'edit' => t('Edit'),
+        'translate' => t('Translate'),
         'delete' => t('Delete'),
         'add' => t('Add'),
         'description' => TRUE,
@@ -674,22 +779,29 @@ function field_collection_field_formatter_settings_form($field, $instance, $view
   $elements = array();
 
   if ($display['type'] != 'field_collection_fields') {
+    $elements['add'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Add link title'),
+      '#default_value' => $settings['add'],
+      '#description' => t('Leave the title empty, to hide the link.'),
+    );
     $elements['edit'] = array(
       '#type' => 'textfield',
       '#title' => t('Edit link title'),
       '#default_value' => $settings['edit'],
       '#description' => t('Leave the title empty, to hide the link.'),
+      '#access' => field_collection_item_is_translatable(),
     );
-    $elements['delete'] = array(
+    $elements['translate'] = array(
       '#type' => 'textfield',
-      '#title' => t('Delete link title'),
-      '#default_value' => $settings['delete'],
+      '#title' => t('Translate link title'),
+      '#default_value' => $settings['translate'],
       '#description' => t('Leave the title empty, to hide the link.'),
     );
-    $elements['add'] = array(
+    $elements['delete'] = array(
       '#type' => 'textfield',
-      '#title' => t('Add link title'),
-      '#default_value' => $settings['add'],
+      '#title' => t('Delete link title'),
+      '#default_value' => $settings['delete'],
       '#description' => t('Leave the title empty, to hide the link.'),
     );
     $elements['description'] = array(
@@ -730,7 +842,7 @@ function field_collection_field_formatter_settings_summary($field, $instance, $v
   $output = array();
 
   if ($display['type'] !== 'field_collection_fields') {
-    $links = array_filter(array_intersect_key($settings, array_flip(array('add', 'edit', 'delete'))));
+    $links = field_collection_get_operations($settings, TRUE);
     if ($links) {
       $output[] = t('Links: @links', array('@links' => check_plain(implode(', ', $links))));
     }
@@ -763,7 +875,7 @@ function field_collection_field_formatter_view($entity_type, $entity, $field, $i
         if ($field_collection = field_collection_field_get_entity($item)) {
           $output = l($field_collection->label(), $field_collection->path());
           $links = array();
-          foreach (array('edit', 'delete') as $op) {
+          foreach (field_collection_get_operations($settings) as $op => $label) {
             if ($settings[$op] && field_collection_item_access($op == 'edit' ? 'update' : $op, $field_collection)) {
               $title = entity_i18n_string("field:{$field['field_name']}:{$instance['bundle']}:setting_$op", $settings[$op]);
               $links[] = l($title, $field_collection->path() . '/' . $op, array('query' => drupal_get_destination()));
@@ -793,7 +905,7 @@ function field_collection_field_formatter_view($entity_type, $entity, $field, $i
             '#theme' => 'links__field_collection_view',
           );
           $links['#attributes']['class'][] = 'field-collection-view-links';
-          foreach (array('edit', 'delete') as $op) {
+          foreach (field_collection_get_operations($settings) as $op => $label) {
             if ($settings[$op] && field_collection_item_access($op == 'edit' ? 'update' : $op, $field_collection)) {
               $links['#links'][$op] = array(
                 'title' => entity_i18n_string("field:{$field['field_name']}:{$instance['bundle']}:setting_$op", $settings[$op]),
@@ -826,6 +938,29 @@ function field_collection_field_formatter_view($entity_type, $entity, $field, $i
 }
 
 /**
+ * Returns an array of enabled operations.
+ */
+function field_collection_get_operations($settings, $add = FALSE) {
+  $operations = array();
+
+  if ($add) {
+    $operations[] = 'add';
+  }
+  $operations[] = 'edit';
+  if (field_collection_item_is_translatable()) {
+    $operations[] = 'translate';
+  }
+  $operations[] = 'delete';
+
+  global $field_collection_operation_keys;
+  $field_collection_operation_keys = array_flip($operations);
+  $operations = array_filter(array_intersect_key($settings, $field_collection_operation_keys));
+  asort($operations);
+
+  return $operations;
+}
+
+/**
  * Helper function to add links to a field collection field.
  */
 function field_collection_field_formatter_links(&$element, $entity_type, $entity, $field, $instance, $langcode, $items, $display) {
@@ -835,7 +970,7 @@ function field_collection_field_formatter_links(&$element, $entity_type, $entity
   if ($settings['add'] && ($field['cardinality'] == FIELD_CARDINALITY_UNLIMITED || count($items) < $field['cardinality'])) {
     // Check whether the current is allowed to create a new item.
     $field_collection_item = entity_create('field_collection_item', array('field_name' => $field['field_name']));
-    $field_collection_item->setHostEntity($entity_type, $entity, LANGUAGE_NONE, FALSE);
+    $field_collection_item->setHostEntity($entity_type, $entity, $langcode, FALSE);
 
     if (field_collection_item_access('create', $field_collection_item)) {
       $allow_create_item = TRUE;
@@ -944,7 +1079,7 @@ function field_collection_field_widget_form(&$form, &$form_state, $field, $insta
       }
       elseif (field_collection_hide_blank_items($field) && $field_state['items_count'] == 0) {
         // We show one item, so also specify that as item count. So when the
-        // add button is pressed the item count will be 2 and we show to items.
+        // add button is pressed the item count will be 2 and we show two items.
         $field_state['items_count'] = 1;
       }
 
@@ -959,15 +1094,56 @@ function field_collection_field_widget_form(&$form, &$form_state, $field, $insta
         // load.
         if (empty($field_collection_item)) {
           $field_collection_item = entity_create('field_collection_item', array('field_name' => $field_name));
-          $field_collection_item->setHostEntity($element['#entity_type'], $element['#entity']);
+          $field_collection_item->setHostEntity($element['#entity_type'], $element['#entity'], $langcode);
         }
 
         // Put our entity in the form state, so FAPI callbacks can access it.
         $field_state['entity'][$delta] = $field_collection_item;
       }
 
+      // Register a child entity translation handler to properly deal with the
+      // entity form language.
+      if (field_collection_item_is_translatable()) {
+        $element['#host_entity_type'] = $element['#entity_type'];
+        $element['#host_entity'] = $element['#entity'];
+        // Give each field collection item a unique entity translation handler
+        // ID, otherwise an infinite loop occurs when adding values to nested
+        // field collection items.
+        if (!isset($field_collection_item->entity_translation_handler_id)) {
+          list($id, $revision_id) = entity_extract_ids('field_collection_item', $field_collection_item);
+          $revision_id = isset($revision_id) ? $revision_id : 0;
+          $field_collection_item->entity_translation_handler_id = 'field_collection_item' . '-' . (!empty($id) ? 'eid-' . $id . '-' . $revision_id : 'new-' . rand());
+        }
+        $element['#field_collection_item'] = $field_collection_item;
+        field_collection_add_child_translation_handler($element);
+        // Ensure this is executed even with cached forms. This is mainly useful
+        // when dealing with AJAX calls.
+        $element['#process'][] = 'field_collection_add_child_translation_handler';
+        // Flag the field to be processed in field_collection_form_alter to
+        // avoid adding incorrect translation hints.
+        $address = array_slice($element['#parents'], 0, -2);
+        if (empty($form['#field_collection_translation_fields']) || !in_array($address, $form['#field_collection_translation_fields'])) {
+          $form['#field_collection_translation_fields'][] = $address;
+        }
+      }
+
+      // Add the subform
       field_form_set_state($field_parents, $field_name, $language, $form_state, $field_state);
-      field_attach_form('field_collection_item', $field_collection_item, $element, $form_state, $language);
+      // Set the language to to parent entity language, because
+      // field_content_languages() will always set $language to LANGUAGE_NONE.
+      if (field_collection_item_is_translatable()) {
+        field_attach_form('field_collection_item', $field_collection_item, $element, $form_state, entity_language($element['#host_entity_type'], $element['#host_entity']));
+      }
+      else {
+        field_attach_form('field_collection_item', $field_collection_item, $element, $form_state, $language);
+      }
+
+      // Make sure subfields get translatable clues (like 'all languages')
+      if (field_collection_item_is_translatable() && variable_get('entity_translation_shared_labels', TRUE)) {
+        foreach (element_children($element) as $key) {
+          $element[$key]['#process'][] = 'entity_translation_element_translatability_clue';
+        }
+      }
 
       if (empty($element['#required'])) {
         $element['#after_build'][] = 'field_collection_field_widget_embed_delay_required_validation';
@@ -997,6 +1173,29 @@ function field_collection_field_widget_form(&$form, &$form_state, $field, $insta
 }
 
 /**
+ * Implements hook_entity_translation_source_field_state_alter()
+ */
+function field_collection_entity_translation_source_field_state_alter(&$field_state) {
+  if (isset($field_state['entity'])) {
+    module_load_include('inc', 'entity', 'includes/entity.ui');
+    foreach ($field_state['entity'] as $delta => $entity) {
+      if ($entity instanceof FieldCollectionItemEntity) {
+        $field_state['entity'][$delta] = entity_ui_clone_entity('field_collection_item', $entity);
+      }
+    }
+  }
+}
+
+/**
+ * Registers a child entity translation handler for the given element.
+ */
+function field_collection_add_child_translation_handler($element) {
+  $handler = entity_translation_get_handler($element['#host_entity_type'], $element['#host_entity']);
+  $handler->addChild('field_collection_item', $element['#field_collection_item']);
+  return $element;
+}
+
+/**
  * Implements hook_field_attach_form().
  *
  * Corrects #max_delta when we hide the blank field collection item.
@@ -1016,6 +1215,16 @@ function field_collection_field_attach_form($entity_type, $entity, &$form, &$for
       if ($form[$field_name][$element_langcode]['#max_delta'] > 0) {
         $form[$field_name][$element_langcode]['#max_delta']--;
       }
+      // Remove blank form elements and force user to explicitly add a field
+      // collection if both 'hide_initial_item' and 'hide_blank_items' are TRUE.
+      if ($field['settings']['hide_initial_item']
+          && $field['settings']['hide_blank_items']
+          && field_collection_item_is_empty($form[$field_name][$element_langcode][0]['#entity'])) {
+
+        _field_collection_process_children_attached($form[$field_name][$element_langcode][0]);
+        unset($form[$field_name][$element_langcode][0]);
+        unset($form_state['field']['#parents'][$field_name][$element_langcode][0]);
+      }
     }
 
     if ($field['type'] == 'field_collection'
@@ -1033,6 +1242,36 @@ function field_collection_field_attach_form($entity_type, $entity, &$form, &$for
       }
     }
   }
+
+  // If FCs are translatable, make sure we mark any necessary sub-fields in the
+  // FC widget as translatable as well.
+  if ($entity_type == 'field_collection_item'
+      && field_collection_item_is_translatable()
+  ) {
+    foreach (field_info_instances($entity_type, $form['#bundle']) as $field_name => $instance) {
+      $field = field_info_field($field_name);
+      if (isset($field['translatable'])) {
+        $form[$field_name]['#multilingual'] = (boolean) $field['translatable'];
+      }
+    }
+  }
+}
+
+/**
+ * Recurses through field children and processes thier attachments.
+ */
+function _field_collection_process_children_attached($elements) {
+  if (empty($elements)) {
+    return;
+  }
+
+  if (isset($elements['#attached'])) {
+    drupal_process_attached($elements);
+  }
+
+  foreach (element_children($elements) as $key) {
+    _field_collection_process_children_attached($elements[$key]);
+  }
 }
 
 /**
@@ -1078,6 +1317,7 @@ function field_collection_remove_submit($form, &$form_state) {
 
   // Where in the form we'll find the parent element.
   $address = array_slice($button['#array_parents'], 0, -2);
+  $values_address = array_slice($button['#parents'], 0, -2);
 
   // Go one level up in the form, to the widgets container.
   $parent_element = drupal_array_get_nested_value($form, $address);
@@ -1087,19 +1327,25 @@ function field_collection_remove_submit($form, &$form_state) {
 
   $field_state = field_form_get_state($parents, $field_name, $langcode, $form_state);
 
+  // Use the actual array of field collection items as the upper limit of this
+  // for loop rather than 'item_count'. This is because it will be creating extra
+  // dummy items here and the two measures go out of sync after the fist delete.
+  $field_collection_item_count = count($field_state['entity']) - 1;
+
   // Go ahead and renumber everything from our delta to the last
   // item down one. This will overwrite the item being removed.
-  for ($i = $delta; $i <= $field_state['items_count']; $i++) {
+  for ($i = $delta; $i <= $field_collection_item_count; $i++) {
     $old_element_address = array_merge($address, array($i + 1));
-    $new_element_address = array_merge($address, array($i));
+    $old_element_values_address = array_merge($values_address, array($i + 1));
+    $new_element_values_address = array_merge($values_address, array($i));
 
     $moving_element = drupal_array_get_nested_value($form, $old_element_address);
-    $moving_element_value = drupal_array_get_nested_value($form_state['values'], $old_element_address);
-    $moving_element_input = drupal_array_get_nested_value($form_state['input'], $old_element_address);
+    $moving_element_value = drupal_array_get_nested_value($form_state['values'], $old_element_values_address);
+    $moving_element_input = drupal_array_get_nested_value($form_state['input'], $old_element_values_address);
     $moving_element_field = drupal_array_get_nested_value($form_state['field']['#parents'], $old_element_address);
 
     // Tell the element where it's being moved to.
-    $moving_element['#parents'] = $new_element_address;
+    $moving_element['#parents'] = $new_element_values_address;
 
     // Move the element around.
     form_set_value($moving_element, $moving_element_value, $form_state);
@@ -1135,7 +1381,7 @@ function field_collection_remove_submit($form, &$form_state) {
   // if I have items weight weights 3 and 4, and I change 4 to 3 but leave
   // the 3, the order of the two 3s now is undefined and may not match what
   // the user had selected.
-  $input = drupal_array_get_nested_value($form_state['input'], $address);
+  $input = drupal_array_get_nested_value($form_state['input'], $values_address);
   // Sort by weight
   uasort($input, '_field_sort_items_helper');
 
@@ -1147,7 +1393,7 @@ function field_collection_remove_submit($form, &$form_state) {
     }
   }
 
-  drupal_array_set_nested_value($form_state['input'], $address, $input);
+  drupal_array_set_nested_value($form_state['input'], $values_address, $input);
   field_form_set_state($parents, $field_name, $langcode, $form_state, $field_state);
 
   $form_state['rebuild'] = TRUE;
@@ -1170,7 +1416,7 @@ function field_collection_field_get_entity(&$item, $field_name = NULL) {
   elseif (isset($item['value'])) {
     // By default always load the default revision, so caches get used.
     $entity = field_collection_item_load($item['value']);
-    if ($entity->revision_id != $item['revision_id']) {
+    if ($entity && $entity->revision_id != $item['revision_id']) {
       // A non-default revision is a referenced, so load this one.
       $entity = field_collection_item_revision_load($item['revision_id']);
     }
@@ -1223,32 +1469,77 @@ function field_collection_field_widget_render_required($element) {
  * FAPI validation of an individual field collection element.
  */
 function field_collection_field_widget_embed_validate($element, &$form_state, $complete_form) {
-  $instance = field_widget_instance($element, $form_state);
   $field = field_widget_field($element, $form_state);
   $field_parents = $element['#field_parents'];
   $field_name = $element['#field_name'];
   $language = $element['#language'];
 
   $field_state = field_form_get_state($field_parents, $field_name, $language, $form_state);
-  $field_collection_item = $field_state['entity'][$element['#delta']];
+
+  // We have to populate the field_collection_item before we can attach it to
+  // the form.
+  if (isset($field_state['entity'][$element['#delta']])) {
+    $field_collection_item = $field_state['entity'][$element['#delta']];
+  }
+  else {
+    $field_values = drupal_array_get_nested_value($form_state['values'], $field_state['array_parents']);
+    if ($field_values[$element['#delta']]) {
+      $field_collection_item = entity_create('field_collection_item', array('field_name' => $field['field_name']));
+      foreach ($field_values[$element['#delta']] as $key => $value) {
+        if (property_exists($field_collection_item, $key)) {
+          $field_collection_item->{$key} = $value;
+        }
+      }
+    }
+  }
 
   // Attach field API validation of the embedded form.
   field_attach_form_validate('field_collection_item', $field_collection_item, $element, $form_state);
 
+  // Handle a possible language change.
+  if (field_collection_item_is_translatable()) {
+    $handler = entity_translation_get_handler('field_collection_item', $field_collection_item);
+    $element_values = &drupal_array_get_nested_value($form_state['values'], $field_state['array_parents']);
+    $element_form_state = array('values' => &$element_values[$element['#delta']]);
+    $handler->entityFormLanguageWidgetSubmit($element, $element_form_state);
+  }
+
   // Now validate required elements if the entity is not empty.
   if (!field_collection_item_is_empty($field_collection_item) && !empty($element['#field_collection_required_elements'])) {
     foreach ($element['#field_collection_required_elements'] as &$elements) {
 
       // Copied from _form_validate().
-      // #1676206: Modified to support options widget.
       if (isset($elements['#needs_validation'])) {
         $is_empty_multiple = (!count($elements['#value']));
         $is_empty_string = (is_string($elements['#value']) && drupal_strlen(trim($elements['#value'])) == 0);
         $is_empty_value = ($elements['#value'] === 0);
         $is_empty_option = (isset($elements['#options']['_none']) && $elements['#value'] == '_none');
-        if ($is_empty_multiple || $is_empty_string || $is_empty_value || $is_empty_option) {
+
+        // Validate fields with hook_field_is_empty. This will handle cases when
+        // file entity passes validation when it shouldn't.
+        $is_empty_field = FALSE;
+        if (isset($elements['#field_name'])) {
+          $field = field_info_field($elements['#field_name']);
+          // Extract field values array with all columns from form_state.
+          // The field we're looking at is always 3 levels deeper than field
+          // collection field.
+          $field_depth = count($elements['#field_parents']) + 3;
+          $field_values = drupal_array_get_nested_value($form_state['values'], array_slice($elements['#array_parents'], 0, $field_depth));
+
+          // Special case lists since we don't get the correct array_parents.
+          if (count($elements['#array_parents']) < $field_depth && is_array($field_values)) {
+            $field_values = reset($field_values);
+          }
+
+          $is_empty_field = module_invoke($field['module'], 'field_is_empty', $field_values, $field);
+        }
+
+        if ($is_empty_multiple || $is_empty_string || $is_empty_value || $is_empty_option || $is_empty_field) {
           if (isset($elements['#title'])) {
-            form_error($elements, t('@name field is required.', array('@name' => $elements['#title'])));
+            form_error($elements, t('@name field is required in the @collection collection.', array(
+              '@name' => $elements['#title'],
+              '@collection' => $field_state['instance']['label'],
+            )));
           }
           else {
             form_error($elements);
@@ -1273,12 +1564,17 @@ function field_collection_field_widget_embed_validate($element, &$form_state, $c
       $item['_weight'] = $element['_weight']['#value'];
     }
 
+    // Ensure field columns are poroperly populated.
+    $item['value'] = $field_collection_item->item_id;
+    $item['revision_id'] = $field_collection_item->revision_id;
+
     // Put the field collection item in $item['entity'], so it is saved with
     // the host entity via hook_field_presave() / field API if it is not empty.
     // @see field_collection_field_presave()
     $item['entity'] = $field_collection_item;
     form_set_value($element, $item, $form_state);
   }
+
 }
 
 /**
@@ -1325,12 +1621,16 @@ function field_collection_i18n_string_list_field_alter(&$properties, $type, $ins
 
       foreach ($instance['display'] as $view_mode => $display) {
         if ($display['type'] != 'field_collection_fields') {
-          $display['settings'] += array('edit' => 'edit', 'delete' => 'delete', 'add' => 'add');
+          $display['settings'] += array('edit' => 'edit', 'translate' => 'translate', 'delete' => 'delete', 'add' => 'add');
 
           $properties['field'][$instance['field_name']][$instance['bundle']]['setting_edit'] = array(
             'title' => t('Edit link title'),
             'string' => $display['settings']['edit'],
           );
+          $properties['field'][$instance['field_name']][$instance['bundle']]['setting_translate'] = array(
+            'title' => t('Edit translate title'),
+            'string' => $display['settings']['translate'],
+          );
           $properties['field'][$instance['field_name']][$instance['bundle']]['setting_delete'] = array(
             'title' => t('Delete link title'),
             'string' => $display['settings']['delete'],
@@ -1406,6 +1706,7 @@ function field_collection_entity_metadata_property_callback(&$info, $entity_type
   // Set the bundle as we know it is the name of the field.
   $property['bundle'] = $field['field_name'];
   $property['getter callback'] = 'field_collection_field_property_get';
+  $property['setter callback'] = 'field_collection_field_property_set';
 }
 
 /**
@@ -1421,7 +1722,10 @@ function field_collection_item_set_host_entity($item, $property_name, $wrapper)
   if (!isset($wrapper->{$item->field_name})) {
     throw new EntityMetadataWrapperException('The specified entity has no such field collection field.');
   }
-  $item->setHostEntity($wrapper->type(), $wrapper->value());
+  $entity_type = $wrapper->type();
+  $field = field_info_field($item->field_name);
+  $langcode = field_is_translatable($entity_type, $field) ? field_collection_entity_language($entity_type, $wrapper->value()) : LANGUAGE_NONE;
+  $item->setHostEntity($wrapper->type(), $wrapper->value(), $langcode);
 }
 
 /**
@@ -1460,6 +1764,42 @@ function field_collection_field_property_get($entity, array $options, $name, $en
 }
 
 /**
+ * Entity property info setter callback for the field collection items.
+ *
+ * Like entity_metadata_field_property_set(), but additionally supports
+ * saving the revision id.
+ */
+function field_collection_field_property_set($entity, $name, $value, $langcode, $entity_type) {
+  $field = field_info_field($name);
+  $columns = array_keys($field['columns']);
+  $langcode = entity_metadata_field_get_language($entity_type, $entity, $field, $langcode);
+  $values = $field['cardinality'] == 1 ? array($value) : (array) $value;
+
+  $items = array();
+  foreach ($values as $delta => $value) {
+    if (isset($value)) {
+      if ($value instanceof FieldCollectionItemEntity) {
+        $items[$delta][$columns[0]] = $value->item_id;
+        $items[$delta][$columns[1]] = $value->revision_id;
+      }
+      elseif (is_array($value) && isset($value['value']) && isset($value['revision_id'])) {
+        $items[$delta][$columns[0]] = $value['value'];
+        $items[$delta][$columns[1]] = $value['revision_id'];
+      }
+      else {
+        $item = field_collection_item_load($value);
+        $items[$delta][$columns[0]] = $item->item_id;
+        $items[$delta][$columns[1]] = $item->revision_id;
+      }
+    }
+  }
+  $entity->{$name}[$langcode] = $items;
+  // Empty the static field language cache, so the field system picks up any
+  // possible new languages.
+  drupal_static_reset('field_language');
+}
+
+/**
  * Implements hook_devel_generate().
  */
 function field_collection_devel_generate($object, $field, $instance, $bundle) {
@@ -1479,6 +1819,47 @@ function field_collection_devel_generate($object, $field, $instance, $bundle) {
 }
 
 /**
+ * Determine if field collection items can be translated.
+ *
+ * @return
+ *   Boolean indicating whether field collection items can be translated.
+ */
+function field_collection_item_is_translatable() {
+  return (bool) module_invoke('entity_translation', 'enabled', 'field_collection_item');
+}
+
+/**
+ * Implements hook_entity_translation_delete().
+ */
+function field_collection_entity_translation_delete($entity_type, $entity, $langcode) {
+  if (field_collection_item_is_translatable()) {
+    list(, , $bundle) = entity_extract_ids($entity_type, $entity);
+
+    foreach (field_info_instances($entity_type, $bundle) as $instance) {
+      $field_name = $instance['field_name'];
+      $field = field_info_field($field_name);
+
+      if ($field['type'] == 'field_collection') {
+        $field_langcode = field_is_translatable($entity_type, $field) ? $langcode : LANGUAGE_NONE;
+
+        if (!empty($entity->{$field_name}[$field_langcode])) {
+          foreach ($entity->{$field_name}[$field_langcode] as $delta => $item) {
+            $field_collection_item = field_collection_field_get_entity($item);
+            $handler = entity_translation_get_handler('field_collection_item', $field_collection_item);
+            $translations = $handler->getTranslations();
+
+            if (isset($translations->data[$langcode])) {
+              $handler->removeTranslation($langcode);
+              $field_collection_item->save(TRUE);
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+/**
  * Determines if the additional blank items should be displayed or not.
  *
  * @param array $field
@@ -1505,3 +1886,42 @@ function field_collection_admin_menu_map() {
     return $map;
   }
 }
+
+/**
+ * implements hook_entity_translation_insert
+ */
+function field_collection_entity_translation_insert($entity_type, $entity, $translation, $values = array()) {
+  // Check if some of the values inserted are of a field_collection field
+  if (!empty($values)) {
+    foreach ($values as $field_name => $value) {
+      $field = field_info_field($field_name);
+
+      if ($field['type'] == 'field_collection') {
+        // We have found a field collection
+        $language = $translation['language'];
+        $source_language = $translation['source'];
+
+        if (!empty($value[$language])) {
+          $source_items = !empty($entity->{$field_name}[$source_language]) ? field_collection_field_item_to_ids($entity->{$field_name}[$source_language]) : array();
+          foreach ($value[$language] as $delta => $field_value) {
+            if (!isset($field_value['entity'])) {
+              if ($fc_entity = field_collection_field_get_entity($field_value)) {
+                // Check if this field collection item belongs to the source language
+                if (in_array($fc_entity->item_id, $source_items)) {
+                  // Clone the field collection item
+                  $new_fc_entity = clone $fc_entity;
+                  $new_fc_entity->item_id = NULL;
+                  $new_fc_entity->revision_id = NULL;
+                  $new_fc_entity->is_new = TRUE;
+
+                  // Set the new entity for saving it later
+                  $entity->{$field_name}[$language][$delta]['entity'] = $new_fc_entity;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/field_collection.pages.inc b/field_collection.pages.inc
index b88e9ed..4d12151 100644
--- a/field_collection.pages.inc
+++ b/field_collection.pages.inc
@@ -30,7 +30,8 @@ function field_collection_item_form($form, &$form_state, $field_collection_item)
   // @todo: Fix core and remove the hack.
   $form['field_name'] = array('#type' => 'value', '#value' => $field_collection_item->field_name);
 
-  field_attach_form('field_collection_item', $field_collection_item, $form, $form_state);
+  $langcode = entity_language('field_collection_item', $field_collection_item);
+  field_attach_form('field_collection_item', $field_collection_item, $form, $form_state, $langcode);
 
   $form['actions'] = array('#type' => 'actions', '#weight' => 50);
   $form['actions']['submit'] = array(
@@ -114,7 +115,8 @@ function field_collection_item_add($field_name, $entity_type, $entity_id, $revis
 
   // Check field cardinality.
   $field = field_info_field($field_name);
-  $langcode = LANGUAGE_NONE;
+  $langcode = !empty($field['translatable']) ? entity_language($entity_type, $entity) : LANGUAGE_NONE;
+
   if (!($field['cardinality'] == FIELD_CARDINALITY_UNLIMITED || !isset($entity->{$field_name}[$langcode]) || count($entity->{$field_name}[$langcode]) < $field['cardinality'])) {
     drupal_set_message(t('Too many items.'), 'error');
     return '';
@@ -125,7 +127,7 @@ function field_collection_item_add($field_name, $entity_type, $entity_id, $revis
   // as during the form-workflow we have multiple field collection item entity
   // instances, which we don't want link all with the host.
   // That way the link is going to be created when the item is saved.
-  $field_collection_item->setHostEntity($entity_type, $entity, LANGUAGE_NONE, FALSE);
+  $field_collection_item->setHostEntity($entity_type, $entity, $langcode, FALSE);
 
   $label = $field_collection_item->translatedInstanceLabel();
   $title = ($field['cardinality'] == 1) ? $label : t('Add new !instance_label', array('!instance_label' => $label));
diff --git a/field_collection.test b/field_collection.test
index b39b1e2..051ee46 100644
--- a/field_collection.test
+++ b/field_collection.test
@@ -641,3 +641,631 @@ class FieldCollectionContentTranslationTestCase extends DrupalWebTestCase {
   }
 
 }
+
+/**
+ * Test using field collection with content that gets translated with Entity Translation.
+ */
+class FieldCollectionEntityTranslationTestCase extends DrupalWebTestCase {
+  const TRANS_FIELD_EN = 'Translatable EN';
+  const TRANS_FIELD_DE = 'Translatable DE';
+  const TRANS_FIELD_DE_MOD = 'Translatable DE Mod';
+  const UNTRANS_FIELD_EN = 'Untranslatable EN';
+  const UNTRANS_FIELD_DE = 'Untranslatable DE';
+  const UNTRANS_FIELD_DE_MOD = 'Untranslatable DE Mod';
+  const NUM_VALUES = 4;
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Field collection entity translation',
+      'description' => 'Tests using content under translation with Entity Translation.',
+      'group' => 'Field types',
+      'dependencies' => array('entity_translation'),
+    );
+  }
+
+  /**
+   * Login the given user only if she has not changed.
+   */
+  function login($user) {
+    if (!isset($this->current_user) || $this->current_user->uid != $user->uid) {
+      $this->current_user = $user;
+      $this->drupalLogin($user);
+    }
+  }
+
+  /**
+   * Returns a user with administration rights.
+   *
+   * @param $permissions
+   *   Additional permissions for administrative user.
+   */
+  function getAdminUser(array $permissions = array()) {
+    if (!isset($this->admin_user)) {
+      $this->admin_user = $this->drupalCreateUser(array_merge(array(
+        'bypass node access',
+        'administer nodes',
+        'administer languages',
+        'administer content types',
+        'administer blocks',
+        'access administration pages',
+        'administer site configuration',
+        'administer entity translation',
+      ), $permissions));
+    }
+    return $this->admin_user;
+  }
+
+  /**
+   * Returns a user with minimal translation rights.
+   *
+   * @param $permissions
+   *   Additional permissions for administrative user.
+   */
+  function getTranslatorUser(array $permissions = array()) {
+    if (!isset($this->translator_user)) {
+      $this->translator_user = $this->drupalCreateUser(array_merge(array(
+        'create page content',
+        'edit own page content',
+        'delete own page content',
+        'translate any entity',
+      ), $permissions));
+    }
+    return $this->translator_user;
+  }
+
+  /**
+   * Install a specified language if it has not been already, otherwise make sure that the language is enabled.
+   *
+   * @param $langcode
+   *   The language code to check.
+   */
+  function addLanguage($langcode) {
+    // Check to make sure that language has not already been installed.
+    $this->drupalGet('admin/config/regional/language');
+
+    if (strpos($this->drupalGetContent(), 'enabled[' . $langcode . ']') === FALSE) {
+      // Doesn't have language installed so add it.
+      $edit = array();
+      $edit['langcode'] = $langcode;
+      $this->drupalPost('admin/config/regional/language/add', $edit, t('Add language'));
+
+      // Make sure we are not using a stale list.
+      drupal_static_reset('language_list');
+      $languages = language_list('language');
+      $this->assertTrue(array_key_exists($langcode, $languages), t('Language was installed successfully.'));
+
+      if (array_key_exists($langcode, $languages)) {
+        $this->assertRaw(t('The language %language has been created and can now be used. More information is available on the <a href="@locale-help">help screen</a>.', array('%language' => $languages[$langcode]->name, '@locale-help' => url('admin/help/locale'))), t('Language has been created.'));
+      }
+    }
+    elseif ($this->xpath('//input[@type="checkbox" and @name=:name and @checked="checked"]', array(':name' => 'enabled[' . $langcode . ']'))) {
+      // It is installed and enabled. No need to do anything.
+      $this->assertTrue(TRUE, 'Language [' . $langcode . '] already installed and enabled.');
+    }
+    else {
+      // It is installed but not enabled. Enable it.
+      $this->assertTrue(TRUE, 'Language [' . $langcode . '] already installed.');
+      $this->drupalPost(NULL, array('enabled[' . $langcode . ']' => TRUE), t('Save configuration'));
+      $this->assertRaw(t('Configuration saved.'), t('Language successfully enabled.'));
+    }
+  }
+
+  public function setUp() {
+    parent::setUp(array('field_collection', 'entity_translation'));
+    $language_none = LANGUAGE_NONE;
+    // Login with an admin user.
+    $this->login($this->getAdminUser());
+    // Add English and German languages.
+    $this->addLanguage('en');
+    $this->addLanguage('de');
+
+    // Set "Article" content type to use multilingual support with translation.
+    $edit = array();
+    $edit['language_content_type'] = ENTITY_TRANSLATION_ENABLED;
+    $this->drupalPost('admin/structure/types/manage/page', $edit, t('Save content type'));
+    $this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Basic page')), t('Basic page content type has been updated.'));
+
+    // Create a field collection field to use for the tests.
+    $this->field_name = 'field_test_collection';
+    $this->field_base = "{$this->field_name}[$language_none]";
+    $this->field = array(
+      'field_name' => $this->field_name,
+      'type' => 'field_collection',
+      'cardinality' => -1,
+      'translatable' => TRUE,
+    );
+    $this->field = field_create_field($this->field);
+    $this->field_id = $this->field['id'];
+
+    $this->instance = array(
+      'field_name' => $this->field_name,
+      'entity_type' => 'node',
+      'bundle' => 'page',
+      'label' => $this->randomName() . '_label',
+      'description' => $this->randomName() . '_description',
+      'weight' => mt_rand(0, 127),
+      'settings' => array(),
+      'widget' => array(
+        'type' => 'field_collection_embed',
+        'label' => 'Test',
+        'settings' => array(),
+      ),
+    );
+    $this->instance = field_create_instance($this->instance);
+
+    // Enable entity translation of field collections.
+    $this->drupalGet('admin/config/regional/entity_translation');
+    $this->drupalPost('admin/config/regional/entity_translation', array('entity_translation_entity_types[field_collection_item]' => TRUE), t('Save configuration'));
+    $this->assertRaw(t('The configuration options have been saved.'), t('Entity translation of field collections enabled.'));
+
+    // Add an untraslatable field to the collection.
+    $this->field_untrans_name = 'field_text_untrans';
+    $this->field_untrans_base = "[{$this->field_untrans_name}][$language_none][0][value]";
+    $field = array(
+      'field_name' => $this->field_untrans_name,
+      'type' => 'text',
+      'cardinality' => 1,
+      'translatable' => FALSE,
+    );
+    field_create_field($field);
+    $instance = array(
+      'entity_type' => 'field_collection_item',
+      'field_name' => $this->field_untrans_name,
+      'bundle' => $this->field_name,
+      'label' => 'Test untranslatable text field',
+      'widget' => array(
+        'type' => 'text_textfield',
+      ),
+    );
+    field_create_instance($instance);
+
+    // Add a translatable field to the collection.
+    $this->field_trans_name = 'field_text_trans';
+    $this->field_trans_base = "[{$this->field_trans_name}][$language_none][0][value]";
+    $this->field_trans_dest = "[{$this->field_trans_name}][de][0][value]";
+    $field = array(
+      'field_name' => $this->field_trans_name,
+      'type' => 'text',
+      'cardinality' => 1,
+      'translatable' => TRUE,
+    );
+    field_create_field($field);
+    $instance = array(
+      'entity_type' => 'field_collection_item',
+      'field_name' => $this->field_trans_name,
+      'bundle' => $this->field_name,
+      'label' => 'Test translatable text field',
+      'widget' => array(
+        'type' => 'text_textfield',
+      ),
+    );
+    field_create_instance($instance);
+
+    $this->login($this->getTranslatorUser());
+  }
+
+  /**
+   * Creates a basic page with a value in the field collection.
+   *
+   *  @param integer $num_values
+   *    The number of values to include in the field collection.
+   *  @param string $langcode
+   *    Language for the node.
+   */
+  protected function createPage($num_values, $langcode = 'en') {
+    // Check if num_values is greater than the field cardinality.
+    if ($num_values > self::NUM_VALUES) {
+      $num_values = self::NUM_VALUES;
+    }
+
+    $title = $this->randomName();
+
+    $this->drupalGet('node/add/page');
+
+    $edit = array();
+    $edit['title'] = $title;
+    for ($i = 0; $i < $num_values; $i++) {
+      if ($i != 0) {
+        $this->drupalPost(NULL, array(), t('Add another item'));
+      }
+      $edit[$this->field_base . '[' . $i . ']' . $this->field_untrans_base] = self::UNTRANS_FIELD_EN . '_' . $i;
+      $edit[$this->field_base . '[' . $i . ']' . $this->field_trans_base] = self::TRANS_FIELD_EN . '_' . $i;
+    }
+
+    $edit['language'] = $langcode;
+    $this->drupalPost(NULL, $edit, t('Save'));
+    $this->assertRaw(t('Basic page %title has been created.', array('%title' => $title)), t('Basic page created.'));
+
+    // Check to make sure the node was created.
+    $node = $this->drupalGetNodeByTitle($title);
+    $this->assertTrue($node, t('Node found in database.'));
+
+    return $node;
+
+  }
+
+  /**
+   * Create a translation using the Entity Translation Form.
+   *
+   * @param $node
+   *   Node of the basic page to create translation for.
+   * @param $langcode
+   *   The language code of the translation.
+   * @param $source_langcode
+   *   The original language code.
+   */
+  protected function createTranslationForm($node, $langcode, $source_langcode = 'en') {
+    $language_none = LANGUAGE_NONE;
+    $edit = array();
+
+    $this->drupalGet('node/' . $node->nid . '/edit/add/' . $source_langcode . '/' .$langcode);
+
+    // Get the field collection in the original language.
+    $fc_values = $node->{$this->field_name}[$source_langcode];
+
+    // Check if all the fields were populated and fill it with the new value.
+    foreach ($fc_values as $delta => $fc_value) {
+      // Load the field collection item.
+      $fc_item_array = entity_load('field_collection_item', array($fc_value['value']));
+      $fc_item = reset($fc_item_array);
+      $fc_untrans_key = "{$this->field_name}[$langcode][$delta]{$this->field_untrans_base}";
+      $fc_trans_key = "{$this->field_name}[$langcode][$delta]{$this->field_trans_dest}";
+      $this->assertFieldByXPath(
+          "//input[@name='$fc_untrans_key']",
+          $fc_item->{$this->field_untrans_name}[LANGUAGE_NONE][0]['value'],
+          'Original value of untranslatable field correctly populated'
+              );
+      $this->assertFieldByXPath(
+          "//input[@name='$fc_trans_key']",
+          $fc_item->{$this->field_trans_name}['en'][0]['value'],
+          'Original value of translatable field correctly populated'
+              );
+
+      $edit[$fc_untrans_key] = self::UNTRANS_FIELD_DE . '_' . $delta;
+      $edit[$fc_trans_key] = self::TRANS_FIELD_DE . '_' . $delta;
+    }
+
+    // Save the translation.
+    $this->drupalPost(NULL, $edit, t('Save'));
+    $this->drupalGet('node/' . $node->nid . '/translate');
+    $this->assertLinkByHref('node/' . $node->nid . '/edit/' . $langcode, 0, t('Translation edit link found. Translation created.'));
+
+    // Reload the node.
+    $node = node_load($node->nid, NULL, TRUE);
+
+    // Check the values of the translated field.
+    $this->checkFieldCollectionContent($node, $langcode);
+
+    // Check the values of the field in the original language.
+    $this->checkFieldCollectionContent($node, $source_langcode);
+
+    return $node;
+  }
+
+  /**
+   * Removes a translation using the entity translation form.
+   *
+   * @param mixed $node
+   *   The node to remove the translation from.
+   * @param unknown $langcode
+   *   The language of the translation to remove.
+   * @param unknown $source_langcode
+   *   The source language of the node.
+   */
+  protected function removeTranslationForm($node, $langcode, $source_langcode) {
+    // Number of field collection items in the source language.
+    $num_original_fc_items = count($node->{$this->field_name}[$source_langcode]);
+
+    // Fetch the translation edit form.
+    $this->drupalGet('node/' . $node->nid . '/edit/' . $langcode);
+
+    // Remove the translation.
+    $this->drupalPost(NULL, array(), t('Delete translation'));
+    // Confirm deletion.
+    $this->drupalPost(NULL, array(), t('Delete'));
+
+    // Reload the node.
+    $node = node_load($node->nid, NULL, TRUE);
+
+    // Check that the translation is removed.
+    $this->drupalGet('node/' . $node->nid . '/translate');
+    $this->assertLinkByHref('node/' . $node->nid . '/edit/add/' . $source_langcode . '/' . $langcode, 0, 'The add translation link appears');
+    $this->assert(empty($node->{$this->field_name}[$langcode]));
+
+    // Check that the field collection in the original language has not changed.
+    $num_fc_items = count($node->{$this->field_name}[$source_langcode]);
+    $this->assertEqual($num_original_fc_items, $num_fc_items, 'The number of field collection items in the original language has not changed.');
+    $this->checkFieldCollectionContent($node, $source_langcode);
+  }
+
+  /**
+   * Creates a translation programmatically using Entity Translation.
+   *
+   * @param $node
+   *   Node of the basic page to create translation for.
+   * @param $langcode
+   *   The language code of the translation.
+   * @param $source_langcode
+   *   The source language code.
+   */
+  protected function createTranslation($node, $langcode) {
+    $source_langcode = $node->language;
+
+    // Get the Entity Translation Handler.
+    $handler = entity_translation_get_handler('node', $node, TRUE);
+    // Variable to hold the fields values.
+    $values = array();
+    // Translation settings.
+    $translation = array(
+      'translate' => 0,
+      'status' => 1,
+      'language' => $langcode,
+      'source' => $source_langcode,
+      'uid' => $node->uid,
+    );
+    // Copy field values.
+    foreach (field_info_instances('node', $node->type) as $instance) {
+      $field_name = $instance['field_name'];
+      $field = field_info_field($field_name);
+      $field_value = array();
+      // Copy the value of the translated field if it's translatable.
+      if ($field['translatable']) {
+        if (isset($node->{$field_name}[$node->language])) {
+          $field_value = $node->{$field_name}[$source_langcode];
+          $values[$field_name][$langcode] = $field_value;
+          $node->{$field_name}[$langcode] = $field_value;
+        }
+      }
+    }
+
+    $handler->setTranslation($translation, $values);
+    $handler->saveTranslations();
+    field_attach_update('node', $node);
+
+    // Reload an return the node.
+    $node = node_load($node->nid, null, TRUE);
+    return $node;
+  }
+
+  /**
+   * Removes a translation programmatically using the entity translation api.
+   *
+   * @param mixed $node
+   *   The node to remove the translation from.
+   * @param unknown $langcode
+   *   The language of the translation to remove.
+   */
+  protected function removeTranslation($node, $langcode) {
+    // Get a translation entity handler.
+    $handler = entity_translation_get_handler('node', $node, TRUE);
+
+    // Remove the translation.
+    $handler->removeTranslation($langcode);
+    node_save($node);
+
+    // Reload and return the node.
+    $node = node_load($node->nid, null, TRUE);
+
+    return $node;
+  }
+
+  /**
+   * Creates a new revision of the node and checks the result.
+   *
+   * @param $node
+   * @param $langcode
+   * @param $source_langcode
+   * @return
+   *   The new revision of the node.
+   */
+  protected function createRevision($node, $langcode, $source_langcode) {
+    $node_original_revision = $node->vid;
+    // The original entries of the translated field.
+    $original_fc_item_ids = $node->{$this->field_name}[$langcode];
+
+    // Create the revision.
+    $node->revision = TRUE;
+    node_save($node);
+
+    // The new entries of the translated field.
+    $new_fc_item_ids = $node->{$this->field_name}[$langcode];
+
+    // Check that the field collection items are the same and a new revision of
+    // each one has been created.
+    foreach ($original_fc_item_ids as $delta => $value) {
+      $this->assertEqual($value['value'], $new_fc_item_ids[$delta]['value'], t('We have the same field collection item'));
+      $this->assertNotEqual($value['revision_id'], $new_fc_item_ids[$delta]['revision_id'], t('We have a new revision of the field collection item'));
+    }
+
+    return $node;
+  }
+
+  /**
+   * Check the content of the field collection for a specified language.
+   *
+   * @param mixed $node
+   *   The node to check.
+   * @param string $langcode
+   *   The language to check.
+   */
+  protected function checkFieldCollectionContent($node, $langcode) {
+    switch($langcode) {
+      case 'en':
+        $untrans_field = self::UNTRANS_FIELD_EN;
+        $trans_field = self::TRANS_FIELD_EN;
+        break;
+      case 'de':
+        $untrans_field = self::UNTRANS_FIELD_DE;
+        $trans_field = self::TRANS_FIELD_DE;
+        break;
+    }
+    // Get the field collection in the specified language.
+    $fc_values = $node->{$this->field_name}[$langcode];
+
+    foreach ($fc_values as $delta => $fc_value) {
+      // Load the field collection item.
+      $fc_item_array = entity_load('field_collection_item', array($fc_value['value']));
+      $fc_item = reset($fc_item_array);
+      $fc_untrans_key = "{$this->field_name}[$langcode][$delta]{$this->field_untrans_base}";
+      $fc_trans_key = "{$this->field_name}[$langcode][$delta]{$this->field_trans_base}";
+
+      $this->assertEqual($untrans_field . '_' . $delta, $fc_item->{$this->field_untrans_name}[LANGUAGE_NONE][0]['value']);
+      $this->assertEqual($trans_field . '_' . $delta, $fc_item->{$this->field_trans_name}[$langcode][0]['value']);
+    }
+  }
+
+  /**
+   * Returns the text field values of an specified node, language and delta.
+   *
+   * @param mixed $node
+   * @param string $langcode
+   * @param integer $delta
+   * @return array
+   */
+  protected function getFieldValues($node, $langcode, $delta) {
+    $return = array();
+
+    if (isset($node->{$this->field_name}[$langcode][$delta]['value'])) {
+      $fc_item_id = $node->{$this->field_name}[$langcode][$delta]['value'];
+      // Load the field collection.
+      $fc_item_array = entity_load('field_collection_item', array($fc_item_id));
+      $fc_item = reset($fc_item_array);
+
+      $return = array(
+        'field_untrans' => $fc_item->{$this->field_untrans_name}[LANGUAGE_NONE][0]['value'],
+        'field_trans' => $fc_item->{$this->field_trans_name}[$langcode][0]['value'],
+      );
+    }
+
+    return $return;
+  }
+
+  /**
+   * Ensures the right behaviour in all Entity Translation use cases.
+   */
+  public function testEntityTranslation() {
+    $source_langcode = 'en';
+    $translation_langcode = 'de';
+
+    /*
+     * Test with a page with only one value in the field collection
+     */
+    // Create an article in the original language with only one field collection
+    // value.
+    $node = $this->createPage(1, $source_langcode);
+
+    // Create a traslation of the page through the entity translation form.
+    $node = $this->createTranslationForm($node, $translation_langcode, $source_langcode);
+
+    /*
+     * Test with a page with multiple values in the field collection.
+     */
+    $num_values = 4;
+    // Create a page in the original language with multiple field collection
+    // values.
+    $node = $this->createPage($num_values, $source_langcode);
+
+    // Create a traslation of the page through the entity translation form.
+    $node = $this->createTranslationForm($node, $translation_langcode, $source_langcode);
+
+    // Assign a new field collection item to an existing node.
+    $values = array();
+    $values['field_name'] = $this->field_name;
+    $fc_entity = entity_create('field_collection_item', $values);
+    $fc_entity->setHostEntity('node', $node, $translation_langcode);
+
+    $fc_entity->{$this->field_untrans_name}[LANGUAGE_NONE][0]['value'] = self::UNTRANS_FIELD_DE_MOD;
+    $fc_entity->{$this->field_trans_name}['de'][0]['value'] = self::TRANS_FIELD_DE_MOD;
+    $fc_entity->save(TRUE);
+
+    node_save($node);
+
+    // Reload the node to check it.
+    $node = node_load($node->nid, NULL, TRUE);
+    // Check that there is a new element in the translation.
+    $this->assertEqual($num_values + 1, count($node->{$this->field_name}[$translation_langcode]), t('We have one item more in translation.'));
+    // Check that the new element is correctly saved.
+    $fc_item_values = $this->getFieldValues($node, $translation_langcode, $num_values);
+    $this->assertEqual($fc_item_values['field_untrans'], self::UNTRANS_FIELD_DE_MOD);
+    $this->assertEqual($fc_item_values['field_trans'], self::TRANS_FIELD_DE_MOD);
+    // Check that we have the same items in the original language.
+    $this->assertEqual($num_values, count($node->{$this->field_name}[$source_langcode]), t('We have same items in the original language.'));
+
+    // Remove a field collection item from the translation.
+    $fc_item_id = $node->{$this->field_name}[$translation_langcode][0]['value'];
+    unset($node->{$this->field_name}[$translation_langcode][0]);
+    node_save($node);
+    // Reload the node.
+    $node = node_load($node->nid, NULL, TRUE);
+    // Check that we have one item less in the translation.
+    // We should take into account that we added a field one step before.
+    $this->assertEqual($num_values, count($node->{$this->field_name}[$translation_langcode]), t('We have one item less in translation.'));
+    // Check that we have the same items in the original language.
+    $this->assertEqual($num_values, count($node->{$this->field_name}[$source_langcode]), t('We have same items in the original language.'));
+    // Check that the field collection is removed from the database.
+    $fc_items = entity_load('field_collection_item', array($fc_item_id));
+    $this->assert(empty($fc_items), t('The field collection item has been removed from the database.'));
+
+    // Delete the translation.
+    $this->removeTranslationForm($node, $translation_langcode, $source_langcode);
+
+    /*
+     * Check the revisioning of an entity with translations.
+     */
+    $num_values = 4;
+    // Create a page in the original language with multiple field collection
+    // values.
+    $node_rev = $this->createPage($num_values, $source_langcode);
+
+    // Create a traslation of the page.
+    $node_rev = $this->createTranslationForm($node_rev, $translation_langcode, $source_langcode);
+
+    $original_revision = $node_rev->vid;
+
+    // Create a new revision of the node.
+    $node_rev = $this->createRevision($node_rev, $translation_langcode, $source_langcode);
+
+    /*
+     * Test creating programmatically.
+     */
+    $num_values = 4;
+    // Create a page in the original language.
+    $node_prog = $this->createPage($num_values, $source_langcode);
+
+    // Create programmatically a translation of the page.
+    $node_prog = $this->createTranslation($node_prog, $translation_langcode);
+
+    $orig_fc_items = $node_prog->{$this->field_name}[$source_langcode];
+    $trans_fc_items = $node_prog->{$this->field_name}[$translation_langcode];
+
+    $orig_fc_item_ids = array();
+    $trans_fc_item_ids = array();
+
+    // Check each item.
+    foreach ($orig_fc_items as $delta => $value) {
+      $orig_fc_item_ids[] = $value['value'];
+      $trans_fc_item_ids[] = $trans_fc_items[$delta]['value'];
+
+      // Check if we have new items for the translation.
+      $this->assertNotEqual($value['value'], $trans_fc_items[$delta]['value'], t('New item generated for translation.'));
+    }
+
+    // Check that the original item still exists in the database.
+    $fc_items = entity_load('field_collection_item', $orig_fc_item_ids);
+    $this->assert(!empty($fc_items), t('Field Collections in the source language still exist.'));
+    // Check that the translated item exists in the database.
+    $fc_items = entity_load('field_collection_item', $trans_fc_item_ids);
+    $this->assert(!empty($fc_items), t('Translations for the Field Collection exist.'));
+
+    // Remove the translation and check that the original field collection items
+    // are still there.
+    $node_prog = $this->removeTranslation($node, $translation_langcode);
+
+    // Check the content in the source language.
+    $this->checkFieldCollectionContent($node_prog, $source_langcode);
+
+    // Check that the field translated content has been removed.
+    $this->assert(empty($node->{$this->field_name}[$translation_langcode]), t('Translated content removed.'));
+  }
+
+}
diff --git a/includes/translation.handler.field_collection_item.inc b/includes/translation.handler.field_collection_item.inc
new file mode 100644
index 0000000..2599013
--- /dev/null
+++ b/includes/translation.handler.field_collection_item.inc
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * @file
+ * Field Collection Item translation handler for the Entity Translation module.
+ */
+
+/**
+ * Field Collection Item translation handler.
+ *
+ * Overrides default behaviours for Field Collection Item properties.
+ */
+class EntityTranslationFieldCollectionItemHandler extends EntityTranslationDefaultHandler {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function __construct($entity_type, $entity_info, $entity) {
+    parent::__construct('field_collection_item', $entity_info, $entity);
+
+    // Initialize the path scheme for the current bundle, unless we are dealing
+    // with the "default" bundle.
+    if ($this->bundle != $entity_info['translation']['entity_translation']['default_scheme']) {
+      $this->setPathScheme($this->bundle);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getAccess($op) {
+    return field_collection_item_access($op, $this->entity);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getLanguage() {
+    // Do not use $this->entity->langcode() as this will finally call
+    // field_collection_entity_language() which again calls us!
+    // If the current field is untranslatable, try inherit the host entity
+    // language.
+    if (($host_entity_type = $this->entity->hostEntityType()) && entity_translation_enabled($host_entity_type) && ($host_entity = $this->entity->hostEntity())) {
+      $handler = $this->factory->getHandler($host_entity_type, $host_entity);
+      $langcode = $handler->getFormLanguage();
+    }
+    // If the host entity is not translatable, use the default language
+    // fallback.
+    else {
+      $langcode = parent::getLanguage();
+    }
+    return $langcode;
+  }
+
+}
