private static Expression GetEnumerableSizeAccessor(EnumerableMappingFacts facts, Expression accessSourceCollection)
        {
            Expression accessSourceCollectionSize;

              // If it's an array, we want to access .Length to know its size, if it's ICollection<T>, we want .Count
              // and for anything else we have to use .Count().
              if (facts.SourceIsArray)
              {
            // source.Length
            accessSourceCollectionSize = Expression.Property(accessSourceCollection, "Length");
              }
              else
              {
            if (facts.SourceIsCollection)
            {
              var genericCollection = typeof(ICollection<>).MakeGenericType(facts.SourceElementType);

              var countProperty = genericCollection.GetProperty("Count");

              // source.Count
              accessSourceCollectionSize = Expression.Property(accessSourceCollection, countProperty);
            }
            else
            {
              var genericEnumerable = typeof(IEnumerable<>).MakeGenericType(facts.SourceElementType);

              // source.Count()
              accessSourceCollectionSize = Expression.Call(null, countMethod.MakeGenericMethod(facts.SourceElementType), accessSourceCollection);
            }
              }
              return accessSourceCollectionSize;
        }
        private EnumerableMappingFacts FindEnumerableMappingFacts(
      ParameterExpression source,
      ParameterExpression destination,
      ProposedTypeMapping complexTypeMapping)
        {
            var facts = new EnumerableMappingFacts();

              if (complexTypeMapping.SourceMember != null)
              {
            facts.SourceEnumerableType = complexTypeMapping.SourceMember.PropertyOrFieldType;
              }
              else
              {
            facts.SourceEnumerableType = source.Type;
              }

              if (complexTypeMapping.DestinationMember != null)
              {
            facts.DestinationEnumerableType = complexTypeMapping.DestinationMember.PropertyOrFieldType;
              }
              else
              {
            facts.DestinationEnumerableType = destination.Type;
              }

              facts.DestinationElementType = CollectionTypeHelper.GetTypeInsideEnumerable(facts.DestinationEnumerableType);

              facts.SourceElementType = CollectionTypeHelper.GetTypeInsideEnumerable(facts.SourceEnumerableType);

              facts.CanAssignSourceElementsToDestination = CanAssignSourceElementToDestination(complexTypeMapping, facts.DestinationElementType, facts.SourceElementType);

              // If we're working with a Dictionary as the source
              if (facts.SourceElementType.IsGenericType
            && typeof(KeyValuePair<,>).IsAssignableFrom(facts.SourceElementType.GetGenericTypeDefinition()))
              {
            facts.SourceIsDictionaryType = true;
              }

              // If we're working with a Dictionary as the destination
              if (facts.DestinationElementType.IsGenericType
            && typeof(KeyValuePair<,>).IsAssignableFrom(facts.DestinationElementType.GetGenericTypeDefinition()))
              {
            facts.DestinationIsDictionaryType = true;
              }

              facts.SourceIsArray = facts.SourceEnumerableType.IsArray;

              var genericCollection = typeof(ICollection<>).MakeGenericType(facts.SourceElementType);

              if (genericCollection.IsAssignableFrom(facts.SourceEnumerableType))
              {
            facts.SourceIsCollection = true;
              }
              else
              {
            facts.SourceIsIEnumerable = true;
              }

              facts.DestinationIsArray = facts.DestinationEnumerableType.IsArray;

              if (options.Conventions.PreserveDestinationListContents
              && IsCollectionType(facts.DestinationEnumerableType)
              && !facts.DestinationIsArray)
              {
            facts.PreserveDestinationContents = true;
              }

              if (IsListType(facts.SourceEnumerableType))
              {
            facts.SourceIsList = true;
              }

              if (facts.DestinationEnumerableType.IsAssignableFrom(facts.SourceEnumerableType))
              {
            facts.CanAssignSourceToDestination = true;
              }

              if (facts.DestinationEnumerableType.IsInterface)
              {
            facts.DestinationCouldBeArray = !facts.DestinationIsDictionaryType;
              }
              else if (facts.DestinationIsArray)
              {
            facts.DestinationCouldBeArray = true;
              }

              return facts;
        }