commit a1cafe7e823717621ec6a0b954ad2da15d927832
Author: Assos Assos <assos+forge@centrale-marseille.fr>
Date:   Wed Sep 4 23:34:55 2019 +0200

    Weekly update of contrib modules

diff --git a/drupal7/sites/all/modules/field_collection/README.txt b/drupal7/sites/all/modules/field_collection/README.txt
index e8c94e98..28cd6e8b 100644
--- a/drupal7/sites/all/modules/field_collection/README.txt
+++ b/drupal7/sites/all/modules/field_collection/README.txt
@@ -1,6 +1,18 @@
-Field collection
------------------
-Provides a field collection field, to which any number of fields can be attached.
+CONTENTS OF THIS FILE
+---------------------
+
+ * Introduction
+ * Requirements
+ * Installation
+ * Configuration
+ * Using field collection with entity translation
+ * Maintainers
+
+
+INTRODUCTION
+------------
+
+Provides a field collection field to which any number of fields can be attached.
 
 Each field collection item is internally represented as an entity, which is
 referenced via the field collection field in the host entity. While
@@ -8,29 +20,45 @@ conceptually field collections are treated as part of the host entity, each
 field collection item may also be viewed and edited separately.
 
 
- Usage
- ------
+REQUIREMENTS
+------------
+
+This project require the following projects:
+
+ * Entity API (https://www.drupal.org/project/entity)
+
 
-  * Add a field collection field to any entity, e.g. to a node. For that use the
-   the usual "Manage fields" interface provided by the "field ui" module of
-   Drupal, e.g. "Admin -> Structure-> Content types -> Article -> Manage fields".
+INSTALLATION
+------------
 
-  * Then go to "Admin -> Structure-> Field collection" to define some fields for
+Install as you would normally install a contributed Drupal. See:
+https://drupal.org/documentation/install/modules-themes/modules-7 for further
+information.
+
+
+CONFIGURATION
+-------------
+
+ * Add a field collection field to any entity, e.g. to a node. For that use the
+   the usual "Manage fields" interface provided by the "field ui" project of
+   Drupal, e.g "Admin -> Structure -> Content types -> Article -> Manage fields"
+
+ * Then go to "Admin -> Structure-> Field Collection" to define some fields for
    the created field collection.
 
-  * By the default, the field collection is not shown during editing of the host
+ * By the default, the field collection is not shown during editing of the host
     entity. However, some links for adding, editing or deleting field collection
     items is shown when the host entity is viewed.
 
-  * Widgets for embedding the form for creating field collections in the
+ * Widgets for embedding the form for creating field collections in the
     host-entity can be provided by any module. In future the field collection
-    module might provide such widgets itself too.
+    project might provide such widgets itself too.
 
 
- Using field collection with entity translation
- -----------------------------------------------
+USING FIELD COLLECTION WITH ENTITY TRANSLATION
+-----------
 
-  * Field collection items must be selected as a translatable entity type at
+  * 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
@@ -45,11 +73,24 @@ field collection item may also be viewed and edited separately.
     language for the host will have a completely separate copy of the field
     collection item(s).
 
-  * When using nested field collections the configuration of the fields and
+  * When using nested field collections, the configuration of the fields and
     field collections is very important. The recommended approach is to first
-    enable entity translation as defined in step 1, and set the outer 
-    field collection field as translatable, and all it’s sub-fields to language
-    undefined. Also the sub-field collections and it’s sub-fields should be
+    enable entity translation as defined in step 1, and set the outer
+    field collection field as translatable and all its sub-fields to language
+    undefined. The sub-field collections and its sub-fields should also be
     set to language undefined. This will ensure that every language of the host
     will have a completely separate copy of the field collection item(s) and
-    it’s fields.
\ No newline at end of file
+    its fields.
+
+
+MAINTAINERS
+-----------
+
+Current maintainers:
+ * Joel Muzzerall (jmuzz) - https://www.drupal.org/user/2607886
+ * Joel Farris (Senpai) - https://www.drupal.org/user/65470
+ * Lee Rowlands (larowlan) - https://www.drupal.org/user/395439
+ * Nedjo Rogers (nedjo) - https://www.drupal.org/user/4481
+ * Ra Mänd (ram4nd) - https://www.drupal.org/user/601534
+ * Renato Gonçalves (RenatoG) - https://www.drupal.org/user/3326031
+ * Wolfgang Ziegler (fago) - https://www.drupal.org/user/16747
diff --git a/drupal7/sites/all/modules/field_collection/ctools/relationships/field_collection_from_field.inc b/drupal7/sites/all/modules/field_collection/ctools/relationships/field_collection_from_field.inc
index ab33e5f4..8fbd0992 100644
--- a/drupal7/sites/all/modules/field_collection/ctools/relationships/field_collection_from_field.inc
+++ b/drupal7/sites/all/modules/field_collection/ctools/relationships/field_collection_from_field.inc
@@ -78,6 +78,15 @@ function field_collection_field_collection_from_field_context($context, $conf) {
   if (isset($entity->{$plugin_info['field_name']})) {
 
     $items = field_get_items($plugin_info['entity_type'], $entity, $plugin_info['field_name']);
+
+    // Use negative delta to get item from the end.
+    if ($delta < 0) {
+      // Add negative pseudo-delta to total amount of items to get the real
+      // delta. Example (field_collection with 5 elements): count() == 5:
+      // 5 + -1 = 4, which would be the last element in this example.
+      $delta = count($items) + $delta;
+    }
+
     if (!empty($items) && isset($items[$delta]['value'])) {
       $field_collection_item = field_collection_item_load($items[$delta]['value']);
     }
@@ -98,7 +107,7 @@ function field_collection_field_collection_from_field_edit_form($form, &$form_st
     '#type' => 'textfield',
     '#title' => t('Delta'),
     '#size' => 3,
-    '#description' => t('The relationship can only create one context, but multiple items can be related. Please type in the number you want. The first one will be 0.'),
+    '#description' => t('The relationship can only create one context, but multiple items can be related. Please type in the number you want. The first one will be 0. Use negative delta to get items from the end. The last item will be -1'),
     '#default_value' => empty($conf['delta']) ? 0 : $conf['delta'],
   );
 
diff --git a/drupal7/sites/all/modules/field_collection/field_collection.api.php b/drupal7/sites/all/modules/field_collection/field_collection.api.php
index 5644244c..4fa56ee9 100644
--- a/drupal7/sites/all/modules/field_collection/field_collection.api.php
+++ b/drupal7/sites/all/modules/field_collection/field_collection.api.php
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Contains API documentation and examples for the Field collection module.
+ * Contains API documentation and examples for the Field Collection.
  */
 
 /**
@@ -66,7 +66,8 @@ function hook_field_collection_item_insert(FieldCollectionItemEntity $field_coll
 /**
  * Acts on a field collection item being inserted or updated.
  *
- * This hook is invoked before the field collection item is saved to the database.
+ * This hook is invoked before the field collection item is saved to the
+ * database.
  *
  * @param FieldCollectionItemEntity $field_collection_item
  *   The field collection item that is being inserted or updated.
@@ -140,7 +141,7 @@ function hook_field_collection_item_view($field_collection_item, $view_mode, $la
 /**
  * Alter the results of entity_view() for field collection items.
  *
-  * This hook is called after the content has been assembled in a structured
+ * This hook is called after the content has been assembled in a structured
  * array and may be used for doing processing which requires that the complete
  * field collection item content structure has been built.
  *
diff --git a/drupal7/sites/all/modules/field_collection/field_collection.diff.inc b/drupal7/sites/all/modules/field_collection/field_collection.diff.inc
index 7e48a981..f918ed04 100644
--- a/drupal7/sites/all/modules/field_collection/field_collection.diff.inc
+++ b/drupal7/sites/all/modules/field_collection/field_collection.diff.inc
@@ -2,11 +2,11 @@
 
 /**
  * @file
- * Provide diff field functions for the Field collection module.
+ * Provide diff field functions for the Field Collection.
  */
 
 /**
- * Diff field callback for parsing Field collection fields comparative values.
+ * Diff field callback for parsing Field Collection fields comparative values.
  */
 function field_collection_field_diff_view($items, $context) {
   $diff_items = array();
@@ -25,7 +25,7 @@ function field_collection_field_render_revision($item, $context) {
   $view_mode = $context['view_mode'];
   $entity = entity_revision_load($entity_type, $item['revision_id']);
 
-  if(empty($entity)) {
+  if (empty($entity)) {
     return array();
   }
 
@@ -40,7 +40,7 @@ function field_collection_field_render_revision($item, $context) {
     $field_context['custom_settings'] = FALSE;
   }
   $view_mode_settings = field_view_mode_settings($entity_type, $bundle_name);
-  $actual_mode = (!empty($view_mode_settings[$view_mode]['custom_settings'])) ? $view_mode : 'default';
+  $actual_mode = !empty($view_mode_settings[$view_mode]['custom_settings']) ? $view_mode : 'default';
   if (!isset($field_context['custom_settings'])) {
     $field_context['custom_settings'] = $actual_mode && $actual_mode == $view_mode;
   }
@@ -50,7 +50,8 @@ function field_collection_field_render_revision($item, $context) {
 
   $result = array();
   foreach ($instances as $instance) {
-    // Any view mode is supported in relation to hiding fields, but only if selected.
+    // Any view mode is supported in relation to hiding fields, but only if
+    // selected.
     if ($actual_mode && $instance['display'][$actual_mode]['type'] == 'hidden') {
       continue;
     }
@@ -67,19 +68,30 @@ function field_collection_field_render_revision($item, $context) {
       $field_context['settings'] = diff_get_field_settings($field_context);
       $field_context['display'] = $instance['display'][$actual_mode];
 
+      $old_items = array();
+      $new_items = array();
+      if (!empty($entity->{$field_name}[$langcode])) {
+        $new_items = $entity->{$field_name}[$langcode];
+      }
+
+      $func = $field['module'] . '_field_diff_view_prepare';
+      if (function_exists($func)) {
+        $func($old_items, $new_items, $field_context);
+      }
+
       $func = $field['module'] . '_field_diff_view';
       if (!function_exists($func)) {
         $func = 'diff_field_diff_view';
       }
 
-      if (!empty($entity->{$field_name}[$langcode])) {
-        $raw_values = $func($entity->{$field_name}[$langcode], $field_context);
+      if (!empty($new_items)) {
+        $raw_values = $func($new_items, $field_context);
         $values = array();
         foreach ($raw_values as $raw_value) {
-          $values[] = is_array($raw_value) ? implode(", ", $raw_value) : $raw_value;
+          $values[] = is_array($raw_value) ? implode(', ', $raw_value) : $raw_value;
         }
 
-        $result[] = check_plain($instance['label'] . ': ' . implode(", ", $values));
+        $result[] = check_plain($instance['label'] . ': ' . implode(', ', $values));
       }
     }
   }
diff --git a/drupal7/sites/all/modules/field_collection/field_collection.entity.inc b/drupal7/sites/all/modules/field_collection/field_collection.entity.inc
index e4f44156..1f9306d9 100644
--- a/drupal7/sites/all/modules/field_collection/field_collection.entity.inc
+++ b/drupal7/sites/all/modules/field_collection/field_collection.entity.inc
@@ -6,7 +6,7 @@
 class FieldCollectionItemEntity extends Entity {
 
   /**
-   * Field collection field info.
+   * Field Collection field info.
    *
    * @var array
    */
@@ -55,7 +55,7 @@ class FieldCollectionItemEntity extends Entity {
   public $item_id;
 
   /**
-   * Field collection revision ID.
+   * Field Collection revision ID.
    *
    * @var integer
    */
@@ -145,15 +145,16 @@ class FieldCollectionItemEntity extends Entity {
       if ($new_label = module_invoke_all('field_collection_item_label', $this, $host, $field, $label)) {
         return array_pop($new_label);
       }
-      elseif ($field['cardinality'] == 1) {
+
+      if ($field['cardinality'] == 1) {
         return $label;
       }
-      elseif ($this->item_id) {
+
+      if ($this->item_id) {
         return t('!instance_label @count', array('!instance_label' => $label, '@count' => $this->delta() + 1));
       }
-      else {
-        return t('New !instance_label', array('!instance_label' => $label));
-      }
+
+      return t('New !instance_label', array('!instance_label' => $label));
     }
     return t('Unconnected field collection item');
   }
@@ -220,24 +221,31 @@ class FieldCollectionItemEntity extends Entity {
    *   The entity type of the entity the field collection is attached to.
    */
   public function updateHostEntity($entity, $host_entity_type = NULL) {
-    $this->fetchHostDetails();
+    $this->fetchHostDetails($entity);
     // 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) {
+    if (!$this->hostEntityType || isset($entity->tid)) {
       $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() && !empty($this->hostEntityId)) {
-      $current_id = $this->hostEntityId;
+    if (!empty($this->hostEntityId) && $this->isInUse()) {
+      if (is_array($this->hostEntityId)) {
+        $current_id = in_array($recieved_id, $this->hostEntityId)
+          ? $recieved_id
+          : FALSE;
+      }
+      else {
+        $current_id = $this->hostEntityId;
+      }
     }
     else {
       $current_host = entity_revision_load($this->hostEntityType, $this->hostEntityRevisionId);
-      list($current_id) = entity_extract_ids($this->hostEntityType, $current_host);
+      list($current_id) = $current_host ? entity_extract_ids($this->hostEntityType, $current_host) : array($recieved_id);
     }
 
     if ($current_id == $recieved_id) {
@@ -300,13 +308,33 @@ class FieldCollectionItemEntity extends Entity {
     }
   }
 
-  protected function fetchHostDetails() {
+  /**
+   * Collects info about the field collection's host.
+   *
+   * @param $hostEntity
+   *   The host entity object. (optional)
+   */
+  protected function fetchHostDetails($hostEntity = NULL) {
     if (!isset($this->hostEntityId) || (!$this->hostEntityId && $this->hostEntityRevisionId)) {
       if ($this->item_id) {
         // For saved field collections, query the field data to determine the
         // right host entity.
         $query = new EntityFieldQuery();
-        $query->fieldCondition($this->fieldInfo(), 'revision_id', $this->revision_id);
+        $field_info = $this->fieldInfo();
+        $query->fieldCondition($field_info, 'revision_id', $this->revision_id);
+        if ($hostEntity) {
+          $entity_type = key($field_info['bundles']);
+          $bundle = current($field_info['bundles'][$entity_type]);
+          $entity_info = entity_get_info($entity_type);
+          $key = $entity_info['entity keys']['id'];
+          $query->entityCondition('entity_type', $entity_type);
+          $query->entityCondition('entity_id', $hostEntity->{$key});
+          $query->entityCondition('bundle', $bundle);
+          if (isset($entity_info['entity keys']['language'])) {
+            $query->propertyCondition('language', $hostEntity->language);
+          }
+        }
+        $query->addTag('DANGEROUS_ACCESS_CHECK_OPT_OUT');
         if (!$this->isInUse()) {
           $query->age(FIELD_LOAD_REVISION);
         }
@@ -353,7 +381,8 @@ class FieldCollectionItemEntity extends Entity {
               $this->langcode = $langcode;
               return $delta;
             }
-            elseif (isset($item['entity']) && $item['entity'] === $this) {
+
+            if (isset($item['entity']) && $item['entity'] === $this) {
               $this->langcode = $langcode;
               return $delta;
             }
@@ -370,7 +399,8 @@ class FieldCollectionItemEntity extends Entity {
                 $this->langcode = $langcode;
                 return $delta;
               }
-              elseif (isset($item['entity']) && $item['entity'] === $this) {
+
+              if (isset($item['entity']) && $item['entity'] === $this) {
                 $this->langcode = $langcode;
                 return $delta;
               }
@@ -385,7 +415,7 @@ class FieldCollectionItemEntity extends Entity {
    * Determines the language code under which the item is stored.
    */
   public function langcode() {
-    if ($this->delta() === NULL || empty($this->langcode)) {
+    if (empty($this->langcode) || $this->delta() === NULL) {
       $this->langcode = field_collection_entity_language('field_collection_item', $this);
     }
 
@@ -399,7 +429,7 @@ class FieldCollectionItemEntity extends Entity {
   /**
    * Determines whether this field collection item revision is in use.
    *
-   * Field collection items may be contained in from non-default host entity
+   * Field Collection items may be contained in from non-default host entity
    * revisions. If the field collection item does not appear in the default
    * host entity revision, the item is actually not used by default and so
    * marked as 'archived'.
@@ -432,11 +462,11 @@ class FieldCollectionItemEntity extends Entity {
   public function save($skip_host_save = FALSE) {
     // Make sure we have a host entity during creation.
     if (!empty($this->is_new) && !(isset($this->hostEntityId) || isset($this->hostEntity) || isset($this->hostEntityRevisionId))) {
-      throw new Exception("Unable to create a field collection item without a given host 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) {
+    if (!empty($this->is_new) && field_collection_item_is_translatable() && $this->langcode() == LANGUAGE_NONE) {
       $this->copyTranslations();
     }
 
@@ -446,30 +476,29 @@ class FieldCollectionItemEntity extends Entity {
     if ($skip_host_save) {
       return entity_get_controller($this->entityType)->save($this);
     }
-    else {
-      $host_entity = $this->hostEntity();
-      if (!$host_entity) {
-        throw new Exception("Unable to save a field collection item without a valid reference to a host entity.");
-      }
-      // If this is creating a new revision, also do so for the host entity.
-      if (!empty($this->revision) || !empty($this->is_new_revision)) {
-        $host_entity->revision = TRUE;
-        if (!empty($this->default_revision)) {
-          entity_revision_set_default($this->hostEntityType, $host_entity);
-        }
-      }
-      // Set the host entity reference, so the item will be saved with the host.
-      // @see field_collection_field_presave()
-      $delta = $this->delta();
-      if (isset($delta)) {
-        $host_entity->{$this->field_name}[$this->langcode()][$delta] = array('entity' => $this);
-      }
-      else {
-        $host_entity->{$this->field_name}[$this->langcode()][] = array('entity' => $this);
-      }
 
-      return entity_save($this->hostEntityType, $host_entity);
+    $host_entity = $this->hostEntity();
+    if (!$host_entity) {
+      throw new Exception('Unable to save a field collection item without a valid reference to a host entity.');
+    }
+    // If this is creating a new revision, also do so for the host entity.
+    if (!empty($this->revision) || !empty($this->is_new_revision)) {
+      $host_entity->revision = TRUE;
+      if (!empty($this->default_revision)) {
+        entity_revision_set_default($this->hostEntityType, $host_entity);
+      }
+    }
+    // Set the host entity reference, so the item will be saved with the host.
+    // @see field_collection_field_presave()
+    $delta = $this->delta();
+    if (isset($delta)) {
+      $host_entity->{$this->field_name}[$this->langcode()][$delta] = array('entity' => $this);
     }
+    else {
+      $host_entity->{$this->field_name}[$this->langcode()][] = array('entity' => $this);
+    }
+
+    return entity_save($this->hostEntityType, $host_entity);
   }
 
   /**
@@ -510,12 +539,13 @@ class FieldCollectionItemEntity extends Entity {
     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];
-            }
+          // Source (translatable_field) is set, therefore continue
+          // processing.
+          if (isset($this->{$translatable_field}[$source_language])
+            && !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) {
@@ -580,7 +610,7 @@ 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()])) {
+      else {
         // Delete if there is no existing revision or translation to be saved.
         $this->delete($skip_host_update);
       }
@@ -630,12 +660,4 @@ class FieldCollectionItemEntity extends Entity {
     return drupal_map_assoc(array_keys($vars));
   }
 
-  /**
-   * Magic method to invoke setUp() on unserialization.
-   *
-   * @todo: Remove this once it appears in a released entity API module version.
-   */
-  public function __wakeup() {
-    $this->setUp();
-  }
 }
diff --git a/drupal7/sites/all/modules/field_collection/field_collection.info b/drupal7/sites/all/modules/field_collection/field_collection.info
index f9565070..b312deea 100644
--- a/drupal7/sites/all/modules/field_collection/field_collection.info
+++ b/drupal7/sites/all/modules/field_collection/field_collection.info
@@ -1,4 +1,4 @@
-name = Field collection
+name = Field Collection
 description = Provides a field collection field, to which any number of fields can be attached.
 core = 7.x
 dependencies[] = entity
@@ -12,8 +12,8 @@ files[] = field_collection.migrate.inc
 configure = admin/structure/field-collections
 package = Fields
 
-; Information added by Drupal.org packaging script on 2019-01-25
-version = "7.x-1.0-beta13"
+; Information added by Drupal.org packaging script on 2019-09-03
+version = "7.x-1.1"
 core = "7.x"
 project = "field_collection"
-datestamp = "1548457085"
+datestamp = "1567537827"
diff --git a/drupal7/sites/all/modules/field_collection/field_collection.info.inc b/drupal7/sites/all/modules/field_collection/field_collection.info.inc
index bfeed96c..e8680a89 100644
--- a/drupal7/sites/all/modules/field_collection/field_collection.info.inc
+++ b/drupal7/sites/all/modules/field_collection/field_collection.info.inc
@@ -24,6 +24,26 @@ class FieldCollectionItemMetadataController extends EntityDefaultMetadataControl
       'required' => TRUE,
     );
 
+    // Also add type-specific host entity references for all entity types that
+    // have at least one field collection field.
+    $field_collection_fields = field_read_fields(array('type' => 'field_collection'));
+    $entity_types = entity_get_info();
+    foreach (field_info_instances() as $entity_type => $bundles) {
+      foreach ($bundles as $bundle => $fields) {
+        if (array_intersect_key($fields, $field_collection_fields)) {
+          $args = array('@type' => $entity_types[$entity_type]['label']);
+          $properties["host_entity_$entity_type"] = array(
+            'label' => t('Host entity (@type)', $args),
+            'type' => $entity_type,
+            'description' => t('The @type containing the field collection field (empty if this field collection is attached to an item of a different type).', $args),
+            'getter callback' => 'field_collection_item_get_specific_type_host_entity',
+            'computed' => TRUE,
+          );
+          break;
+        }
+      }
+    }
+
     return $info;
   }
 
diff --git a/drupal7/sites/all/modules/field_collection/field_collection.install b/drupal7/sites/all/modules/field_collection/field_collection.install
index d26f35ea..c2d8b82e 100644
--- a/drupal7/sites/all/modules/field_collection/field_collection.install
+++ b/drupal7/sites/all/modules/field_collection/field_collection.install
@@ -63,6 +63,12 @@ function field_collection_schema() {
       ),
     ),
   );
+
+  if (module_exists('entitycache')) {
+    $schema['cache_entity_field_collection_item'] = drupal_get_schema_unprocessed('system', 'cache');
+    $schema['cache_entity_field_collection_item']['description'] = 'Cache table used to store field_collection_item entity records.';
+  }
+  
   return $schema;
 }
 
@@ -228,7 +234,7 @@ function field_collection_update_7002() {
       ->condition('archived', 0);
     $select->leftJoin('field_data_' . $field_name, 'field', "field.{$field_name}_value = fci.item_id ");
     $select->isNull('field.entity_id');
-    $ids = $select->execute()->fetchCol(0);
+    $ids = $select->execute()->fetchCol();
 
     entity_delete_multiple('field_collection_item', $ids);
     drupal_set_message(t('Deleted @count orphaned field collection items.', array('@count' => count($ids))));
@@ -368,7 +374,7 @@ function field_collection_update_7008() {
         ->fieldLanguageCondition($f_name, LANGUAGE_NONE);
       $query_result = $query->execute();
       if (isset($query_result['field_collection_item'])) {
-        $results = $results + $query_result['field_collection_item'];
+        $results += $query_result['field_collection_item'];
       }
     }
   }
@@ -393,3 +399,176 @@ function field_collection_update_7008() {
     }
   }
 }
+
+/**
+ * Update revisions created before revision support was implemented.
+ */
+function field_collection_update_7009(&$sandbox) {
+  $items_per_pass = 10;
+  $field_collection_fields = field_read_fields(array('type' => 'field_collection'));
+
+  // If you don't have any field_collecton fields then skip this update.
+  if (empty($field_collection_fields)) {
+    return;
+  }
+
+  if (!isset($sandbox['current_field'])) {
+    $sandbox['field_collection_fields'] = array_keys($field_collection_fields);
+    $sandbox['current_field'] = 0;
+    $sandbox['current_field_collection_item'] = 0;
+    $sandbox['field_name'] = $sandbox['field_collection_fields'][$sandbox['current_field']];
+    $sandbox['inner_fields'] = field_read_instances(array('entity_type' => 'field_collection_item', 'bundle' => $sandbox['field_name']));
+  }
+
+  // Find field collection items with duplicate revision ids.
+  $query = db_select("field_revision_{$sandbox['field_name']}", 't')
+    ->fields('t', array("{$sandbox['field_name']}_revision_id"))
+    ->range($sandbox['current_field_collection_item'], $items_per_pass)
+    ->groupBy("t.{$sandbox['field_name']}_revision_id");
+  $query->addExpression("COUNT(t.{$sandbox['field_name']}_revision_id)", 'vidcount');
+  $query->havingCondition('vidcount', 2, '>=');
+  $vids = $query->execute()->fetchCol();
+
+  // Each revision ID that occurs more than once.
+  foreach ($vids as $field_collection_duplicated_revision_id) {
+    // Find every instance of this revision ID.
+    $copies = db_select("field_revision_{$sandbox['field_name']}", 't')
+      ->fields('t')
+      ->condition("{$sandbox['field_name']}_revision_id", $field_collection_duplicated_revision_id)
+      ->execute()
+      ->fetchAllAssoc('revision_id');
+
+    $first_copy = reset($copies);
+    $field_collection_item_id = $first_copy->{"{$sandbox['field_name']}_value"};
+
+    // Find the currently used revision of this field collection item.
+    $field_collection_item_current_revision = db_select('field_collection_item', 'fci')
+      ->fields('fci', array('revision_id'))
+      ->condition('item_id', $field_collection_item_id)
+      ->execute()
+      ->fetchField();
+
+    // Find new revisions of this field collection item that were made after
+    // revisions were enabled in update_7003.
+    $modern_revisions = db_select("field_revision_{$sandbox['field_name']}", 't')
+      ->fields('t')
+      ->condition("{$sandbox['field_name']}_revision_id", $field_collection_duplicated_revision_id, '<>')
+      ->condition("{$sandbox['field_name']}_value", $field_collection_item_id)
+      ->orderBy('revision_id')
+      ->execute()
+      ->fetchAllAssoc('revision_id');
+
+    // Intentionally skip the first instance as it doesn't need to be modified.
+    while (FALSE !== ($row_to_replace = next($copies))) {
+      $new_revision_id = _field_collection_update_7009_new_revision($field_collection_item_id, $row_to_replace, $sandbox['inner_fields'], $sandbox['field_name']);
+
+      // Create copies of inner fields with new revision number.
+      foreach ($sandbox['inner_fields'] as $field) {
+        // Get the data to copy.
+        $data_rows = db_select("field_revision_{$field['field_name']}", 't')
+          ->fields('t')
+          ->condition('entity_type', 'field_collection_item')
+          ->condition('revision_id', $field_collection_duplicated_revision_id)
+          ->execute();
+
+        // Add new copy of data with new revision id.
+        while ($each_row = $data_rows->fetchAssoc()) {
+          $each_row['revision_id'] = $new_revision_id;
+          db_insert("field_revision_{$field['field_name']}")
+            ->fields(array_keys($each_row), array_values($each_row))
+            ->execute();
+        }
+      }
+
+      // Update the host's field data with new revision number.
+      db_update("field_revision_{$sandbox['field_name']}")
+        ->fields(array("{$sandbox['field_name']}_revision_id" => $new_revision_id))
+        ->condition('entity_type', $row_to_replace->entity_type)
+        ->condition('revision_id', $row_to_replace->revision_id)
+        ->condition('delta', $row_to_replace->delta)
+        ->condition('language', $row_to_replace->language)
+        ->execute();
+    }
+
+    if ($field_collection_item_current_revision == $field_collection_duplicated_revision_id) {
+      _field_collection_update_7009_update_data($new_revision_id, $field_collection_duplicated_revision_id);
+
+      // Update the current field collection item data in its host.
+      db_update("field_data_{$sandbox['field_name']}")
+        ->fields(array('revision_id' => $new_revision))
+        ->condition('revision_id', $old_revision)
+        ->condition('entity_type', $row_to_replace->entity_type)
+        ->execute();
+    }
+
+    foreach ($modern_revisions as $each_modern_revision) {
+      $new_revision_id = _field_collection_update_7009_new_revision($field_collection_item_id, $each_modern_revision, $sandbox['inner_fields'], $sandbox['field_name']);
+
+      // Update inner fields with new revision number.
+      foreach ($sandbox['inner_fields'] as $field) {
+        db_update("field_revision_{$field['field_name']}")
+          ->fields(array('revision_id' => $new_revision_id))
+          ->condition('revision_id', $each_modern_revision->{$sandbox['field_name'] . '_revision_id'})
+          ->condition('entity_type', 'field_collection_item')
+          ->execute();
+      }
+
+      // Update the host's field data with new revision number.
+      db_update("field_revision_{$sandbox['field_name']}")
+        ->fields(array("{$sandbox['field_name']}_revision_id" => $new_revision_id))
+        ->condition('entity_type', $each_modern_revision->entity_type)
+        ->condition('revision_id', $each_modern_revision->revision_id)
+        ->condition('delta', $each_modern_revision->delta)
+        ->condition('language', $each_modern_revision->language)
+        ->execute();
+
+      if ($field_collection_item_current_revision == $each_modern_revision->{"{$sandbox['field_name']}_revision_id"}) {
+        _field_collection_update_7009_update_data($new_revision_id, $each_modern_revision->{"{$sandbox['field_name']}_revision_id"});
+
+        // Update the current field collection item data in its host.
+        db_update("field_data_{$sandbox['field_name']}")
+          ->fields(array('revision_id' => $new_revision))
+          ->condition('revision_id', $old_revision)
+          ->condition('entity_type', $each_modern_revision->entity_type)
+          ->execute();
+      }
+
+      // Remove old copy of revision.
+      db_delete('field_collection_item_revision')
+        ->condition('revision_id', $each_modern_revision->revision_id)
+        ->execute();
+    }
+
+    $sandbox['current_field_collection_item']++;
+  }
+
+  $sandbox['#finished'] = 0;
+
+  if (count($vids) < $items_per_pass) {
+    $sandbox['current_field']++;
+    if ($sandbox['current_field'] == count($sandbox['field_collection_fields'])) {
+      $sandbox['#finished'] = 1;
+      return;
+    }
+    $sandbox['current_field_collection_item'] = 0;
+    $sandbox['field_name'] = $sandbox['field_collection_fields'][$sandbox['current_field']];
+    $sandbox['inner_fields'] = field_read_instances(array('entity_type' => 'field_collection_item', 'bundle' => $sandbox['field_name']));
+  }
+}
+
+function _field_collection_update_7009_new_revision($field_collection_item_id, $row_to_replace, $inner_fields, $field_name) {
+  // Add to field_collection_item_revision table.
+  $new_revision_id = db_insert('field_collection_item_revision')
+    ->fields(array('item_id'), array($field_collection_item_id))
+    ->execute();
+
+  return $new_revision_id;
+}
+
+function _field_collection_update_7009_update_data($new_revision, $old_revision) {
+  // Update the current field collection item.
+  db_update('field_collection_item')
+    ->fields(array('revision_id' => $new_revision))
+    ->condition('revision_id', $old_revision)
+    ->execute();
+}
diff --git a/drupal7/sites/all/modules/field_collection/field_collection.migrate.inc b/drupal7/sites/all/modules/field_collection/field_collection.migrate.inc
index 1162ebea..16ad444c 100644
--- a/drupal7/sites/all/modules/field_collection/field_collection.migrate.inc
+++ b/drupal7/sites/all/modules/field_collection/field_collection.migrate.inc
@@ -83,10 +83,10 @@ class MigrateDestinationFieldCollection extends MigrateDestinationEntity {
   /**
    * Import a single field collection item.
    *
-   * @param $collection
+   * @param \stdClass $collection
    *   Collection object to build. Pre-filled with any fields mapped in the
    *   migration.
-   * @param $row
+   * @param \stdClass $row
    *   Raw source data object - passed through to prepare/complete handlers.
    *
    * @return array|bool
@@ -139,7 +139,8 @@ class MigrateDestinationFieldCollection extends MigrateDestinationEntity {
         if ('field_' != substr($field, 0, 6)) {
           continue;
         }
-        elseif (property_exists($entity_old, $field) && !property_exists($collection, $field)) {
+
+        if (property_exists($entity_old, $field) && !property_exists($collection, $field)) {
           $entity->$field = $entity_old->$field;
         }
       }
@@ -149,7 +150,7 @@ class MigrateDestinationFieldCollection extends MigrateDestinationEntity {
     $status = entity_save('field_collection_item', $entity);
     migrate_instrument_stop('field_collection_save');
 
-    if (in_array($this->hostEntityType, array('node', 'field_collection_item')) || ($status !== FALSE)) {
+    if ($status !== FALSE || in_array($this->hostEntityType, array('node', 'field_collection_item'))) {
       $this->complete($entity, $row);
       if ($updating) {
         $this->numUpdated++;
@@ -159,9 +160,8 @@ class MigrateDestinationFieldCollection extends MigrateDestinationEntity {
       }
       return array($entity->item_id);
     }
-    else {
-      return FALSE;
-    }
+
+    return FALSE;
   }
 
   /**
diff --git a/drupal7/sites/all/modules/field_collection/field_collection.module b/drupal7/sites/all/modules/field_collection/field_collection.module
index 3c4d2788..8e1b8092 100644
--- a/drupal7/sites/all/modules/field_collection/field_collection.module
+++ b/drupal7/sites/all/modules/field_collection/field_collection.module
@@ -184,7 +184,11 @@ function field_collection_item_load($item_id, $reset = FALSE) {
  * Loads a field collection revision.
  *
  * @param $revision_id
- *   The field collection revision ID.
+ *   The id of the revision to load.
+ *
+ * @return
+ *   The entity object, or FALSE if there is no entity with the given revision
+ *   id.
  */
 function field_collection_item_revision_load($revision_id) {
   return entity_revision_load('field_collection_item', $revision_id);
@@ -193,6 +197,16 @@ function field_collection_item_revision_load($revision_id) {
 /**
  * Loads field collection items.
  *
+ * @param $ids
+ *   An array of entity IDs, or FALSE to load all entities.
+ * @param $conditions
+ *   (deprecated) An associative array of conditions on the base table, where
+ *   the keys are the database fields and the values are the values those
+ *   fields must have. Instead, it is preferable to use EntityFieldQuery to
+ *   retrieve a list of entity IDs loadable by this function.
+ * @param $reset
+ *   Whether to reset the internal cache for the requested entity type.
+ *
  * @return
  *   An array of field collection item entities.
  */
@@ -220,7 +234,7 @@ function field_collection_menu() {
   foreach (field_info_fields() as $field) {
     if ($field['type'] == 'field_collection') {
       $path = field_collection_field_get_path($field);
-      $count = count(explode('/', $path));
+      $count = substr_count($path, '/') + 1;
 
       $items[$path . '/%field_collection_item'] = array(
         'page callback' => 'field_collection_item_page_view',
@@ -280,7 +294,7 @@ function field_collection_menu() {
  * Implements hook_menu_alter() to fix the field collections admin UI tabs.
  */
 function field_collection_menu_alter(&$items) {
-  if (module_exists('field_ui') && isset($items['admin/structure/field-collections/%field_collection_field_name/fields'])) {
+  if (isset($items['admin/structure/field-collections/%field_collection_field_name/fields']) && module_exists('field_ui')) {
     // Make the fields task the default local task.
     $items['admin/structure/field-collections/%field_collection_field_name'] = $items['admin/structure/field-collections/%field_collection_field_name/fields'];
     $item = &$items['admin/structure/field-collections/%field_collection_field_name'];
@@ -299,6 +313,8 @@ function field_collection_menu_alter(&$items) {
 
 /**
  * Menu title callback.
+ *
+ * return string
  */
 function field_collection_admin_page_title($field_name) {
   return t('Field collection @field_name', array('@field_name' => $field_name));
@@ -306,6 +322,8 @@ function field_collection_admin_page_title($field_name) {
 
 /**
  * Implements hook_admin_paths().
+ *
+ * @return array
  */
 function field_collection_admin_paths() {
   if (variable_get('node_admin_theme')) {
@@ -326,6 +344,10 @@ function field_collection_permission() {
       'title' => t('Administer field collections'),
       'description' => t('Create and delete fields on field collections.'),
     ),
+    'edit field collections' => array(
+      'title' => t('Edit field collections'),
+      'description' => t('Edit field collections.'),
+    ),
   );
 }
 
@@ -339,6 +361,7 @@ function field_collection_permission() {
  *   items is determined.
  * @param $account
  *   The user to check for. Leave it to NULL to check for the global user.
+ *
  * @return boolean
  *   Whether access is allowed or not.
  */
@@ -346,9 +369,12 @@ function field_collection_item_access($op, FieldCollectionItemEntity $item = NUL
   // We do not support editing field collection revisions that are not used at
   // the hosts default revision as saving the host might result in a new default
   // revision.
-  if (isset($item) && !$item->isInUse() && $op != 'view') {
+  if ($op != 'view' && isset($item) && !$item->isInUse()) {
     return FALSE;
   }
+  if (user_access('edit field collections', $account)) {
+    return TRUE;
+  }
   if (user_access('administer field collections', $account)) {
     return TRUE;
   }
@@ -356,10 +382,13 @@ function field_collection_item_access($op, FieldCollectionItemEntity $item = NUL
     return FALSE;
   }
   $op = $op == 'view' ? 'view' : 'edit';
+
   // Access is determined by the entity and field containing the reference.
   $field = field_info_field($item->field_name);
-  $entity_access = entity_access($op == 'view' ? 'view' : 'update', $item->hostEntityType(), $item->hostEntity(), $account);
-  return $entity_access && field_access($op, $field, $item->hostEntityType(), $item->hostEntity(), $account);
+  $hostEntity = $item->hostEntity() !== FALSE ? $item->hostEntity() : NULL;
+  $entity_access = entity_access($op == 'view' ? 'view' : 'update', $item->hostEntityType(), $hostEntity, $account);
+
+  return $entity_access && field_access($op, $field, $item->hostEntityType(), $hostEntity, $account);
 }
 
 /**
@@ -548,7 +577,7 @@ function field_collection_field_update($host_entity_type, $host_entity, $field,
     // 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 (!empty($host_entity->revision) || isset($item['entity'])) {
       if ($entity = field_collection_field_get_entity($item)) {
         // If the host entity is saved as new revision, do the same for the item.
         if (!empty($host_entity->revision) || !empty($host_entity->is_new_revision)) {
@@ -615,7 +644,7 @@ function field_collection_field_update($host_entity_type, $host_entity, $field,
       $items_to_remove = array_diff($ids, $current_by_id);
       // Delete unused field collection items now.
       foreach (field_collection_item_load_multiple($items_to_remove) as $un_item) {
-        $un_item->updateHostEntity($host_entity);
+        $un_item->updateHostEntity($host_entity, $host_entity_type);
         $un_item->deleteRevision(TRUE);
       }
     }
@@ -626,8 +655,9 @@ 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_collection_field_item_to_ids($items)) {
+  if ($ids && field_info_field($field['field_name'])) {
     // 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.
@@ -665,15 +695,31 @@ function field_collection_field_delete($entity_type, $entity, $field, $instance,
   }
 }
 
+/**
+ * Implements hook_field_load().
+ *
+ * Invokes the load hooks for the fields contained in new, unsaved field
+ * collection items. This allows images inside a field collection item to be
+ * seen on a node's preview page before it's saved.
+ */
+function field_collection_field_load($entity_type, $entities, $field, $instances, $langcode, &$items, $age) {
+  foreach ($items as &$each_item) {
+    foreach ($each_item as &$each_field_collection_item) {
+      if (!empty($each_field_collection_item['entity'])) {
+        _field_invoke_multiple('load', 'field_collection_item', array(NULL => &$each_field_collection_item['entity']));
+      }
+    }
+  }
+}
+
 /**
  * Implements hook_field_delete_revision().
  */
 function field_collection_field_delete_revision($entity_type, $entity, $field, $instance, $langcode, &$items) {
   foreach ($items as $item) {
-    if (!empty($item['revision_id'])) {
-      if ($entity = field_collection_item_revision_load($item['revision_id'])) {
-        $entity->deleteRevision(TRUE);
-      }
+    if (!empty($item['revision_id'])
+      && $entity = field_collection_item_revision_load($item['revision_id'])) {
+      $entity->deleteRevision(TRUE);
     }
   }
 }
@@ -698,7 +744,8 @@ function field_collection_field_is_empty($item, $field) {
   if (!empty($item['value'])) {
     return FALSE;
   }
-  elseif (isset($item['entity'])) {
+
+  if (isset($item['entity'])) {
     return field_collection_item_is_empty($item['entity']);
   }
   return TRUE;
@@ -882,6 +929,75 @@ function field_collection_field_formatter_settings_summary($field, $instance, $v
   return implode('<br>', $output);
 }
 
+function field_collection_entity_preload($entities, $langcode, &$items, $fields) {
+  static $local_entity_cache = array();
+
+  $fc_ids = array();
+
+  // Collect every possible term attached to any of the fieldable entities.
+  foreach ($entities as $id => $entity) {
+    foreach ($items[$id] as $delta => $item) {
+
+      // Check if this item is in our local entity cache
+      if (isset($local_entity_cache[$item['value']])) {
+        $items[$id][$delta]['field_collection'] = $local_entity_cache[$item['value']];
+        continue;
+      }
+
+      // Force the array key to prevent duplicates.
+      $fc_ids[$item['value']] = $item['value'];
+    }
+  }
+
+  if ($fc_ids) {
+    $new_entities = array();
+    $terms = field_collection_item_load_multiple($fc_ids);
+
+    // Iterate through the fieldable entities again to attach the loaded
+    // field collection data.
+    foreach ($entities as $id => $entity) {
+      $rekey = FALSE;
+
+      foreach ($items[$id] as $delta => $item) {
+        // Check whether the field collection field instance value could be loaded.
+        if (isset($terms[$item['value']])) {
+          // Replace the instance value with the term data.
+          $e = $terms[$item['value']];
+          $local_entity_cache[$item['value']] = $e;
+          $items[$id][$delta]['field_collection'] = $e;
+
+	  foreach ($fields as $field_name => $field) {
+            if (isset($e->$field_name)) {
+              $field_data = $e->$field_name;
+              if (isset($field_data[$langcode])) {
+                $new_entities[$e->item_id] = $e->item_id;
+                $items[$e->item_id] = $field_data[$langcode];
+              }
+            }
+          }
+        }
+        // Otherwise, unset the instance value, since the field colletion entity does not exist.
+        else {
+          unset($items[$id][$delta]);
+          $rekey = TRUE;
+        }
+      }
+
+      if ($rekey) {
+        // Rekey the items array.
+        $items[$id] = array_values($items[$id]);
+      }
+    }
+
+    field_collection_entity_preload($new_entities, $langcode, $items, $fields);
+  }
+}
+
+function field_collection_field_formatter_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items, $displays) {
+  $fields = field_read_fields(array('type' => 'field_collection'));
+  field_collection_entity_preload($entities, $langcode, $items, $fields);
+}
+
 /**
  * Implements hook_field_formatter_view().
  */
@@ -915,8 +1031,18 @@ function field_collection_field_formatter_view($entity_type, $entity, $field, $i
 
       $view_mode = !empty($display['settings']['view_mode']) ? $display['settings']['view_mode'] : 'full';
       foreach ($items as $delta => $item) {
-        if ($field_collection = field_collection_field_get_entity($item)) {
-          $element[$delta]['entity'] = $field_collection->view($view_mode, $langcode);
+        // Existing field collections should be loaded without cache so that
+        // node Preview will work for both existing nodes and new ones.
+        if (isset($item['entity']->item_id)) {
+          // Load without cache.
+          $field_collection = field_collection_item_load($item['entity']->item_id, TRUE);
+        }
+        else {
+          $field_collection = field_collection_field_get_entity($item);
+        }
+
+        if ($field_collection) {
+          $element[$delta]['entity'] = $field_collection->view($view_mode);
           $element[$delta]['#theme_wrappers'] = array('field_collection_view');
           $element[$delta]['#attributes']['class'][] = 'field-collection-view';
           $element[$delta]['#attributes']['class'][] = 'clearfix';
@@ -949,7 +1075,7 @@ function field_collection_field_formatter_view($entity_type, $entity, $field, $i
       $view_mode = !empty($display['settings']['view_mode']) ? $display['settings']['view_mode'] : 'full';
       foreach ($items as $delta => $item) {
         if ($field_collection = field_collection_field_get_entity($item)) {
-          $element[$delta]['entity'] = $field_collection->view($view_mode, $langcode);
+          $element[$delta]['entity'] = $field_collection->view($view_mode);
         }
       }
       break;
@@ -998,7 +1124,7 @@ function field_collection_field_formatter_links(&$element, $entity_type, $entity
       $path = field_collection_field_get_path($field);
       list($id) = entity_extract_ids($entity_type, $entity);
       $element['#suffix'] = '';
-      if (!empty($settings['description']) && $entity_type != 'node') {
+      if ($entity_type != 'node' && !empty($settings['description'])) {
         $element['#suffix'] .= '<div class="description field-collection-description">' . field_filter_xss($instance['description']) . '</div>';
       }
       $title = entity_i18n_string("field:{$field['field_name']}:{$instance['bundle']}:setting_add", $settings['add']);
@@ -1052,6 +1178,14 @@ function field_collection_field_widget_info() {
         'default value' => FIELD_BEHAVIOR_NONE,
       ),
     ),
+    'field_collection_sorter' => array(
+      'label' => t('Sortable only'),
+      'field types' => array('field_collection'),
+      'behaviors' => array(
+        'multiple values' => FIELD_BEHAVIOR_CUSTOM,
+        'default value' => FIELD_BEHAVIOR_DEFAULT,
+      ),
+    ),
   );
 }
 
@@ -1092,13 +1226,14 @@ function field_collection_field_widget_form(&$form, &$form_state, $field, $insta
 
       $field_state = field_form_get_state($field_parents, $field_name, $language, $form_state);
 
-      if (field_collection_hide_blank_items($field) && $delta == $field_state['items_count'] && $delta > 0) {
+      if ($delta > 0 && $delta == $field_state['items_count'] && field_collection_hide_blank_items($field)) {
         // Do not add a blank item. Also see
         // field_collection_field_attach_form() for correcting #max_delta.
         $recursion--;
         return FALSE;
       }
-      elseif (field_collection_hide_blank_items($field) && $field_state['items_count'] == 0) {
+
+      if ($field_state['items_count'] == 0 && field_collection_hide_blank_items($field)) {
         // 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 two items.
         $field_state['items_count'] = 1;
@@ -1191,6 +1326,66 @@ function field_collection_field_widget_form(&$form, &$form_state, $field, $insta
 
       $recursion--;
       return $element;
+
+    case 'field_collection_sorter':
+      $elements = array();
+
+      $field_name = $field['field_name'];
+      $parents = $form['#parents'];
+      $field_state = field_form_get_state($parents, $field_name, $langcode, $form_state);
+      $count = $field_state['items_count'];
+
+      for ($delta = 0; $delta < $count; $delta++) {
+        $item_id = isset($items[$delta]['value']) ? $items[$delta]['value'] : NULL;
+        $revision_id = isset($items[$delta]['revision_id']) ? $items[$delta]['revision_id'] : NULL;
+
+        // add a label component to visually identify this field collection item
+        $element['label'] = array();
+        if ($item_id) {
+          $item = field_collection_item_load($item_id);
+          $element['label']['#markup'] = $item ? $item->label() : $item_id;
+        }
+
+        // the field stored value (item_id) and revision_id values
+        // so we need hidden fields to represent them
+        $element['value'] = array(
+          '#type' => 'hidden',
+          '#default_value' => $item_id,
+        );
+        $element['revision_id'] = array(
+          '#type' => 'hidden',
+          '#default_value' => $revision_id,
+        );
+
+        // Input field for the delta (drag-n-drop reordering).
+        // We name the element '_weight' to avoid clashing with elements
+        // defined by widget.
+        $element['_weight'] = array(
+          '#type' => 'weight',
+          '#title' => t('Weight for row @number', array('@number' => $delta + 1)),
+          '#title_display' => 'invisible',
+          // Note: this 'delta' is the FAPI 'weight' element's property.
+          '#delta' => $count,
+          '#default_value' => isset($items[$delta]['_weight']) ? $items[$delta]['_weight'] : $delta,
+          '#weight' => 100,
+        );
+
+        $elements[$delta] = $element;
+      }
+
+      if ($elements) {
+        $elements += array(
+          '#theme' => 'field_multiple_value_form',
+          '#field_name' => $field['field_name'],
+          '#cardinality' => $field['cardinality'],
+          '#title' => check_plain($instance['label']),
+          '#required' => FALSE,
+          '#description' => field_filter_xss($instance['description']),
+          '#max_delta' => $count-1,
+        );
+      }
+
+      return $elements;
   }
 }
 
@@ -1231,7 +1426,7 @@ function field_collection_field_attach_form($entity_type, $entity, &$form, &$for
     $field = field_info_field($field_name);
 
     if ($field['type'] == 'field_collection' && field_collection_hide_blank_items($field)
-        && field_access('edit', $field, $entity_type) && $instance['widget']['type'] == 'field_collection_embed') {
+        && field_access('edit', $field, $entity_type)) {
 
       $element_langcode = $form[$field_name]['#language'];
       if ($form[$field_name][$element_langcode]['#max_delta'] > 0) {
@@ -1240,8 +1435,9 @@ function field_collection_field_attach_form($entity_type, $entity, &$form, &$for
       // 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['settings']['hide_blank_items']
+        && $form[$field_name][$element_langcode][0]['#entity'] instanceof FieldCollectionItemEntity
+        && 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]);
@@ -1249,11 +1445,11 @@ function field_collection_field_attach_form($entity_type, $entity, &$form, &$for
       }
     }
 
-    if ($field['type'] == 'field_collection'
-        && $field['cardinality'] == FIELD_CARDINALITY_UNLIMITED
+    if ($field['cardinality'] == FIELD_CARDINALITY_UNLIMITED
         && empty($form_state['programmed'])
+        && $instance['widget']['type'] === 'field_collection_embed'
         && field_access('edit', $field, $entity_type)
-        && $instance['widget']['type'] == 'field_collection_embed') {
+        && $field['type'] === 'field_collection') {
 
       $element_langcode = $form[$field_name]['#language'];
       $element_wrapper = $form[$field_name][$element_langcode]['add_more']['#ajax']['wrapper'];
@@ -1267,7 +1463,7 @@ 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'
+  if ($entity_type === 'field_collection_item'
       && field_collection_item_is_translatable()
   ) {
     foreach (field_info_instances($entity_type, $form['#bundle']) as $field_name => $instance) {
@@ -1433,9 +1629,16 @@ function field_collection_remove_submit($form, &$form_state) {
  */
 function field_collection_field_get_entity(&$item, $field_name = NULL) {
   if (isset($item['entity']) && ($item['entity']->entityType() == 'field_collection_item')) {
+    if (count($item) > 1) {
+      // If $item contains more thing than 'entity', then it is sent from VBO.
+      // We clone the object to avoid that the same field collection item of the
+      // faked object is attached to multiple host objects.
+      return clone $item['entity'];
+    }
     return $item['entity'];
   }
-  elseif (isset($item['value'])) {
+
+  if (isset($item['value'])) {
     // By default always load the default revision, so caches get used.
     $entity = field_collection_item_load($item['value']);
     if ($entity && $entity->revision_id != $item['revision_id']) {
@@ -1444,7 +1647,8 @@ function field_collection_field_get_entity(&$item, $field_name = NULL) {
     }
     return $entity;
   }
-  elseif (!isset($item['entity']) && isset($field_name)) {
+
+  if (isset($field_name) && !isset($item['entity'])) {
     $item['entity'] = entity_create('field_collection_item', array('field_name' => $field_name));
     return $item['entity'];
   }
@@ -1527,7 +1731,7 @@ function field_collection_field_widget_embed_validate($element, &$form_state, $c
   }
 
   // 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'])) {
+  if (!empty($element['#field_collection_required_elements']) && !field_collection_item_is_empty($field_collection_item)) {
     foreach ($element['#field_collection_required_elements'] as &$elements) {
 
       // Copied from _form_validate().
@@ -1550,7 +1754,7 @@ function field_collection_field_widget_embed_validate($element, &$form_state, $c
           $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)) {
+          if (is_array($field_values) && count($elements['#array_parents']) < $field_depth) {
             $field_values = reset($field_values);
           }
 
@@ -1574,7 +1778,7 @@ function field_collection_field_widget_embed_validate($element, &$form_state, $c
 
   // Only if the form is being submitted, finish the collection entity and
   // prepare it for saving.
-  if ($form_state['submitted'] && !form_get_errors()) {
+  if ($form_state['submitted'] && !form_get_error($element)) {
 
     field_attach_submit('field_collection_item', $field_collection_item, $element, $form_state);
 
@@ -1759,6 +1963,17 @@ function field_collection_item_get_host_entity($item) {
   return entity_metadata_wrapper($item->hostEntityType(), $item->hostEntity());
 }
 
+/**
+ * Entity property info getter callback for the host entity property.
+ */
+function field_collection_item_get_specific_type_host_entity($item, array $options, $name) {
+  // These properties' machine names have the form "host_entity_TYPE".
+  if (substr($name, 0, 12) !== 'host_entity_') {
+    return NULL;
+  }
+  return $item->hostEntityType() === substr($name, 12) ? $item->hostEntity() : NULL;
+}
+
 /**
  * Entity property info getter callback for the field collection items.
  *
@@ -1805,7 +2020,7 @@ function field_collection_field_property_set($entity, $name, $value, $langcode,
         $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'])) {
+      elseif (is_array($value) && isset($value['value'], $value['revision_id'])) {
         $items[$delta][$columns[0]] = $value['value'];
         $items[$delta][$columns[1]] = $value['revision_id'];
       }
@@ -1826,6 +2041,14 @@ function field_collection_field_property_set($entity, $name, $value, $langcode,
  * Implements hook_devel_generate().
  */
 function field_collection_devel_generate($object, $field, $instance, $bundle) {
+  if (field_behaviors_widget('multiple values', $instance) == FIELD_BEHAVIOR_CUSTOM) {
+    return devel_generate_multiple('_field_collection_devel_generate', $object, $field, $instance, $bundle);
+  }
+
+  return _field_collection_devel_generate($object, $field, $instance, $bundle);
+}
+
+function _field_collection_devel_generate($object, $field, $instance, $bundle) {
   // Create a new field collection object and add fake data to its fields.
   $field_collection = entity_create('field_collection_item', array('field_name' => $field['field_name']));
   $field_collection->language = $object->language;
@@ -1927,24 +2150,308 @@ function field_collection_entity_translation_insert($entity_type, $entity, $tran
         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;
-                }
-              }
+            // Check if this field collection item belongs to the source language
+            if (!isset($field_value['entity'])
+              && ($fc_entity = field_collection_field_get_entity($field_value))
+              && 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;
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+
+/**
+ * Implements hook_feeds_processor_targets_alter()
+ */
+function field_collection_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_name) {
+
+  // Load up.
+  $loaded = &drupal_static(__FUNCTION__, FALSE);
+
+  if (!$loaded) {
+    $loaded = TRUE;
+    $path = drupal_get_path('module', 'feeds') . '/mappers';
+    $files = drupal_system_listing('/.*\.inc$/', $path, 'name', 0);
+    foreach ($files as $file) {
+      if (strpos($file->uri, '/mappers/') !== FALSE) {
+        require_once DRUPAL_ROOT . '/' . $file->uri;
+      }
+    }
+  }
+
+  foreach (field_info_instances($entity_type, $bundle_name) as $name => $instance) {
+    $info = field_info_field($name);
+    if ($info['type'] == 'field_collection') {
+
+      $sub_type = 'field_collection_item';
+      $new_targets = module_invoke_all('feeds_processor_targets', $sub_type, $info['field_name']);
+      drupal_alter('feeds_processor_targets', $new_targets, $sub_type, $info['field_name']);
+
+      foreach ($new_targets as $sub_name => $target) {
+        $new_name = t($info['field_name']) . ':' . t($sub_name);
+        $targets[$new_name] = $target;
+        if (isset($target['name'])) {
+          $targets[$new_name]['name'] = $instance['label'] . ':' . $target['name'];
+        }
+        // We override callback for now and retrieve original later.
+        $targets[$new_name]['callback'] = 'field_collection_feeds_set_target';
+      }
+    }
+  }
+
+}
+
+
+/**
+ * Process Field Collection items.
+ *
+ * @param  [type] $source       [description]
+ * @param  [type] $entity       [description]
+ * @param  [type] $target       [description]
+ * @param  [type] $value        [description]
+ * @param  [type] $main_mapping [description]
+ * @return [type]               [description]
+ */
+function field_collection_feeds_set_target($source, $entity, $target, $value, $main_mapping) {
+  $sub_targets = &drupal_static(__FUNCTION__, array());
+
+  $args = explode(':', $target);
+  $target = array_shift($args);
+  $sub_target = implode(':', $args);
+
+  $sub_type = 'field_collection_item';
+  $new_targets = module_invoke_all('feeds_processor_targets', $sub_type, $target);
+  drupal_alter('feeds_processor_targets', $new_targets, $sub_type, $target);
+
+  // Now we retrieve old callbacks and keep then on a static cache.
+  if (!isset($sub_targets[$target])) {
+    $sub_targets[$target] = array();
+    drupal_alter('feeds_processor_targets', $sub_targets[$target], $sub_type, $target);
+  }
+
+  $_sub_targets = $new_targets;
+
+  $value = is_array($value) ? $value : array($value);
+  $info = field_info_field($target);
+
+  // Iterate over all values.
+  $delta = 0;
+  $field = isset($entity->$target) ? $entity->$target : array();
+  try {
+
+    // $delta = which FC instance.
+    // We iterate by subfield, not by FC.
+    while (isset($value[$delta])) {
+
+      // Zero out.
+      $field_collection_item = null;
+
+      // FC is already set on host entity.
+      if (isset($field[LANGUAGE_NONE][$delta]['entity'])) {
+        $field_collection_item = $field[LANGUAGE_NONE][$delta]['entity'];
+      }
+      // FC is on host entity, we have FC item_id, but FC is not loaded.
+      elseif (isset($field[LANGUAGE_NONE][$delta]['value'])) {
+        $field_collection_item = field_collection_item_load($field[LANGUAGE_NONE][$delta]['value']);
+
+        // Zero out field so that we don't just keep accumulating values.
+        unset($field_collection_item->{$sub_target}[LANGUAGE_NONE] );
+      }
+
+      // Host entity does not have any attached FCs yet.
+      if (empty($field_collection_item)) {
+        $field_collection_item = entity_create('field_collection_item', array('field_name' => $target));
+        $field_collection_item->setHostEntity($entity->feeds_item->entity_type, $entity);
+      }
+
+      $sub_mapping = array();
+      $config = $source->importer()->getConfig();
+      if (!empty($config['processor']['config']['mappings'])) {
+        foreach ($config['processor']['config']['mappings'] as $mapping) {
+          if ($mapping['target'] == $target . ':' . $sub_target) {
+            $sub_mapping = $mapping;
+            $sub_mapping['target'] = $sub_target;
+            // Needs language or feeds mappers shout php notices.
+            $sub_mapping['language'] = !empty($config['processor']['config']['language']) ? $config['processor']['config']['language'] : LANGUAGE_NONE;
+            break;
+          }
+        }
+      }
+
+      if (isset($_sub_targets[$sub_target]['callback']) && function_exists($_sub_targets[$sub_target]['callback'])) {
+        $callback = $_sub_targets[$sub_target]['callback'];
+
+        // Normalize
+        if (!is_array($value[$delta])) {
+          $value[$delta] = array($value[$delta]);
+        }
+
+        // Check for a limit and force that limit.
+        if ($info['cardinality'] !== '-1') {
+          $value[$delta] = array_slice($value[$delta], 0, $info['cardinality']);
+        }
+
+        // HiJack the file callback so we can make it work.
+        if ($callback == 'file_feeds_set_target') {
+          $callback = 'field_collection_file_feeds_set_target';
+        }
+
+        // Allow altering with many parameters. Cannot use drupal_alter here.
+        $implements = module_implements('sub_target_pre_callback_parse');
+        foreach ($implements as $module_name) {
+          $hook = $module_name . '_' . 'sub_target_pre_callback_parse';
+          $hook($target, $sub_target, $entity, $field, $field_collection_item, $value[$delta]);
+        }
+
+        $callback($source, $field_collection_item, $sub_target, $value[$delta], $sub_mapping);
+      }
+
+      // No need to save the field collection here. Just wait until the node is saved.
+      // If we save the FC here we get a huge performance degregation.
+      $field[LANGUAGE_NONE][$delta]['entity'] = $field_collection_item;
+
+      // Break when only hitting the max delta.
+      if ($info['cardinality'] == $delta) {
+        break;
+      }
+
+      $delta++;
+    }
+
+  }
+  catch (Exception $e) {
+    drupal_set_message($e->getMessage(), 'error');
+    watchdog_exception('field_collection', $e, $e->getMessage());
+    throw $e;
+  }
+
+  $entity->{$target} = $field;
+}
+
+/**
+ * Wrapper function for file_feeds_set_target as it doesn't do the nested stuff.
+ */
+function field_collection_file_feeds_set_target($source, $entity, $target, $value) {
+
+  if (empty($value)) {
+    return;
+  }
+  module_load_include('inc', 'file');
+
+  // Make sure $value is an array of objects of type FeedsEnclosure.
+  if (!is_array($value)) {
+    $value = array($value);
+  }
+  foreach ($value as $k => $v) {
+    if (!($v instanceof FeedsEnclosure)) {
+      if (is_string($v)) {
+        $value[$k] = new FeedsEnclosure($v, file_get_mimetype($v));
+      }
+      else {
+        unset($value[$k]);
+      }
+    }
+  }
+  if (empty($value)) {
+    return;
+  }
+
+  $entity_type = 'field_collection_item';
+  $bundle = $entity->field_name;
+
+  // Determine file destination.
+  // @todo This needs review and debugging.
+  $instance_info = field_info_instance($entity_type, $target, $bundle);
+  $info = field_info_field($target);
+  $data = array();
+  if (!empty($entity->uid)) {
+    $data[$entity_type] = $entity;
+  }
+  $destination = file_field_widget_uri($info, $instance_info, $data);
+
+  // Populate entity.
+  $i = 0;
+  $field = isset($entity->$target) ? $entity->$target : array();
+  foreach ($value as $v) {
+    $file = FALSE;
+    try {
+      $v->setAllowedExtensions($instance_info['settings']['file_extensions']);
+      $file = $v->getFile($destination);
+    }
+    catch (Exception $e) {
+      watchdog('feeds', check_plain($e->getMessage()));
+    }
+    if ($file) {
+      $field[LANGUAGE_NONE][$i] = (array)$file;
+      $field[LANGUAGE_NONE][$i]['display'] = 1; // @todo: Figure out how to properly populate this field.
+      if ($info['cardinality'] == 1) {
+        break;
+      }
+      $i++;
+    }
+  }
+  $entity->{$target} = $field;
+
+}
+
+
+/**
+ * Implementation of hook_feeds_presave().
+ * Invoked before a feed item is saved.
+ *
+ * @param FeedsSource $source
+ *   FeedsSource object that describes the source that is being imported.
+ * @param $entity
+ *   The entity object.
+ * @param array $item
+ *   The parser result for this entity.
+ * @param int|null $entity_id
+ *   The id of the current item which is going to be updated. If this is a new
+ *   item, then NULL is passed.
+ */
+function field_collection_feeds_presave(FeedsSource $source, $entity, $item, $entity_id) {
+  $feed_config = $source->importer()->getConfig();
+  $mappings = $feed_config['processor']['config']['mappings'];
+
+  // Only hook in when updating the entity.
+  if (empty($entity_id)) {
+
+    // Go through $mappings and find the FC fields.
+    foreach ($mappings as $mapping) {
+
+      if (strpos($mapping['target'], ':') !== FALSE) {
+        $parts = explode(':', $mapping['target']);
+        $fc_name = array_shift($parts);
+        $info = field_info_field($fc_name);
+
+        // If the field is not a field collection, skip it.
+        if ($info['type'] != 'field_collection') {
+          continue;
+        }
+
+        if (isset($entity->{$fc_name})) {
+          foreach ($entity->{$fc_name}[LANGUAGE_NONE] as $delta => $fc_unloaded) {
+
+            // If an FC is not loaded, we don't want it. Unset it so it won't save.
+            if (!isset($entity->{$fc_name}[LANGUAGE_NONE][$delta]['entity'])) {
+              unset($entity->{$fc_name}[LANGUAGE_NONE][$delta]);
             }
           }
+
         }
       }
     }
   }
 }
+
diff --git a/drupal7/sites/all/modules/field_collection/field_collection.pages.inc b/drupal7/sites/all/modules/field_collection/field_collection.pages.inc
index 8543390d..1d3a5a20 100644
--- a/drupal7/sites/all/modules/field_collection/field_collection.pages.inc
+++ b/drupal7/sites/all/modules/field_collection/field_collection.pages.inc
@@ -8,7 +8,7 @@
 // TODO: fix being embedded in a host with revisions.
 
 /**
- * Field collection item view page.
+ * Field Collection item view page.
  */
 function field_collection_item_page_view($field_collection_item) {
   // @todo: Set breadcrumb including the host.
@@ -86,7 +86,7 @@ function field_collection_item_delete_confirm($form, &$form_state, $field_collec
  */
 function field_collection_item_delete_confirm_submit($form, &$form_state) {
   $field_collection_item = $form_state['field_collection_item'];
-  $field_collection_item->deleteRevision();
+  entity_delete('field_collection_item',$field_collection_item->item_id);
   drupal_set_message(t('%label has been deleted.', array('%label' => drupal_ucfirst($field_collection_item->label()))));
   $form_state['redirect'] = '<front>';
 }
diff --git a/drupal7/sites/all/modules/field_collection/field_collection.test b/drupal7/sites/all/modules/field_collection/field_collection.test
index a9acc32e..82b311b6 100644
--- a/drupal7/sites/all/modules/field_collection/field_collection.test
+++ b/drupal7/sites/all/modules/field_collection/field_collection.test
@@ -70,7 +70,7 @@ class FieldCollectionBasicTestCase extends DrupalWebTestCase {
     if (!isset($message)) {
       $message = $text;
     }
-    return $this->assertTrue(array_search($text, $_SESSION['entity_crud_hook_test']) !== FALSE, $message, $group);
+    return $this->assertTrue(in_array($text, $_SESSION['entity_crud_hook_test']), $message, $group);
   }
 
   /**
@@ -95,7 +95,7 @@ class FieldCollectionBasicTestCase extends DrupalWebTestCase {
     if (!isset($message)) {
       $message = $text;
     }
-    return $this->assertFalse(array_search($text, $_SESSION['entity_crud_hook_test']) !== FALSE, $message, $group);
+    return $this->assertFalse(in_array($text, $_SESSION['entity_crud_hook_test']), $message, $group);
   }
 
   /**
@@ -153,7 +153,7 @@ class FieldCollectionBasicTestCase extends DrupalWebTestCase {
     $this->clearHookMessages();
     node_delete($node->nid);
     $this->assertNoHookMessage('entity_crud_hook_test_entity_presave called for type node');
-    $this->assertTrue(entity_load('field_collection_item', FALSE) === array(), 'Field collections are deleted when the host is deleted.');
+    $this->assertTrue(entity_load('field_collection_item') === array(), 'Field collections are deleted when the host is deleted.');
 
     // Try deleting nodes with collections without any values.
     $node = $this->drupalCreateNode(array('type' => 'article'));
@@ -344,15 +344,15 @@ class FieldCollectionBasicTestCase extends DrupalWebTestCase {
     $this->drupalPost($path, $edit, t('Save'));
     $this->assertText(t('The changes have been saved.'), 'Field collection saved.');
 
-    $this->assertText($edit['field_text[und][0][value]'], "Added field value is shown.");
+    $this->assertText($edit['field_text[und][0][value]'], 'Added field value is shown.');
 
     $edit['field_text[und][0][value]'] = $this->randomName();
     $this->drupalPost('field-collection/field-test-collection/1/edit', $edit, t('Save'));
     $this->assertText(t('The changes have been saved.'), 'Field collection saved.');
-    $this->assertText($edit['field_text[und][0][value]'], "Field collection has been edited.");
+    $this->assertText($edit['field_text[und][0][value]'], 'Field collection has been edited.');
 
     $this->drupalGet('field-collection/field-test-collection/1');
-    $this->assertText($edit['field_text[und][0][value]'], "Field collection can be viewed.");
+    $this->assertText($edit['field_text[und][0][value]'], 'Field collection can be viewed.');
 
     // Add further 3 items, so we have reached 4 == maxium cardinality.
     $this->drupalPost($path, $edit, t('Save'));
@@ -737,7 +737,7 @@ class FieldCollectionEntityTranslationTestCase extends DrupalWebTestCase {
 
       // Make sure we are not using a stale list.
       drupal_static_reset('language_list');
-      $languages = language_list('language');
+      $languages = language_list();
       $this->assertTrue(array_key_exists($langcode, $languages), t('Language was installed successfully.'));
 
       if (array_key_exists($langcode, $languages)) {
@@ -1013,12 +1013,11 @@ class FieldCollectionEntityTranslationTestCase extends DrupalWebTestCase {
       $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;
-        }
+      if ($field['translatable']
+        && 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;
       }
     }
 
diff --git a/drupal7/sites/all/modules/field_collection/field_collection.tokens.inc b/drupal7/sites/all/modules/field_collection/field_collection.tokens.inc
index e26de34f..96912953 100644
--- a/drupal7/sites/all/modules/field_collection/field_collection.tokens.inc
+++ b/drupal7/sites/all/modules/field_collection/field_collection.tokens.inc
@@ -28,6 +28,10 @@ function field_collection_token_info() {
     'name' => t('Host entity ID'),
     'description' => t('The entity ID of the host. For nodes this is <code>nid</code>, for users <code>uid</code>.'),
   );
+  $host['delta'] = array(
+    'name' => t('Host entity item delta'),
+    'description' => t('The delta of the reference pointing to this field collection item.'),
+  );
 
   // Chained tokens.
   foreach (field_collection_host_entity_types() as $entity_type => $entity_info) {
@@ -96,6 +100,7 @@ function field_collection_tokens($type, $tokens, array $data = array(), array $o
         'type' => 'hostEntityType',
         'bundle' => 'hostEntityBundle',
         'id' => 'hostEntityId',
+        'delta' => 'delta',
       );
       $entity_types = field_collection_host_entity_types();
       foreach ($tokens as $name => $orig) {
diff --git a/drupal7/sites/all/modules/field_collection/includes/translation.handler.field_collection_item.inc b/drupal7/sites/all/modules/field_collection/includes/translation.handler.field_collection_item.inc
index 866fdc5b..c305b716 100644
--- a/drupal7/sites/all/modules/field_collection/includes/translation.handler.field_collection_item.inc
+++ b/drupal7/sites/all/modules/field_collection/includes/translation.handler.field_collection_item.inc
@@ -42,7 +42,7 @@ class EntityTranslationFieldCollectionItemHandler extends EntityTranslationDefau
     // 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();
+      $langcode = $handler->getLanguage();
     }
     // If the host entity is not translatable, use the default language
     // fallback.
diff --git a/drupal7/sites/all/modules/field_collection/views/field_collection.views.inc b/drupal7/sites/all/modules/field_collection/views/field_collection.views.inc
index ebb5cfb0..6553ed13 100644
--- a/drupal7/sites/all/modules/field_collection/views/field_collection.views.inc
+++ b/drupal7/sites/all/modules/field_collection/views/field_collection.views.inc
@@ -57,6 +57,17 @@ function field_collection_field_views_data($field) {
       'base' => $entity_info['base table'],
       'base field' => $entity_info['entity keys']['id'],
       'label' => t('!field_name', array('!field_name' => $field['field_name'])),
+      'join_extra' => array(
+        0 => array(
+          'field' => 'entity_type',
+          'value' => $entity_type,
+        ),
+        1 => array(
+          'field' => 'deleted',
+          'value' => 0,
+          'numeric' => TRUE,
+        ),
+      ),
     );
   }
 
