/// <summary>
        /// Gets or creates an <see cref="IEdmCollectionType"/> for the <paramref name="itemResourceType"/>.
        /// </summary>
        /// <param name="collectionResourceType">The collection resource type that the edm type is being created from.</param>
        /// <param name="itemResourceType">The item resource type to create an EDM collection type for.</param>
        /// <param name="customAnnotations">The optional annotations for the resource type; the annotations can contain facets that need to be applied to the type reference.</param>
        /// <returns>An <see cref="IEdmCollectionType"/> instance for the <paramref name="itemResourceType"/> item type.</returns>
        /// <remarks>
        /// Materialization state: none required. No change in materialization state.
        /// Cache state: none required. No change in cache state.
        /// </remarks>
        private IEdmCollectionType EnsureCollectionItemTypeIsPrimitiveOrComplex(CollectionResourceType collectionResourceType, ResourceType itemResourceType, List<KeyValuePair<string, object>> customAnnotations)
        {
            Debug.Assert(itemResourceType != null, "itemResourceType != null");

            IEdmCollectionType collectionType;
            if (this.primitiveOrComplexCollectionTypeCache.TryGetValue(itemResourceType, out collectionType))
            {
                return collectionType;
            }

            IEdmTypeReference elementTypeReference;
            switch (itemResourceType.ResourceTypeKind)
            {
                case ResourceTypeKind.ComplexType:
                    // WCF DS forces the item types of collection types to not be nullable. Only starting v3, can complex properties be nullable. 
                    // For providers, like reflection providers, we need to ensure complex items continue to be non-nullable.
                    elementTypeReference = this.EnsureTypeReference(itemResourceType, customAnnotations);
                    elementTypeReference = elementTypeReference.IsNullable != PrimitiveOrComplexCollectionItemTypeDefaultNullability
                        ? elementTypeReference.Clone(PrimitiveOrComplexCollectionItemTypeDefaultNullability)
                        : elementTypeReference;
                    break;
                case ResourceTypeKind.Primitive:
                    // WCF DS forces the item types of collection types to not be nullable
                    MetadataProviderUtils.GetAndRemoveNullableFacet(customAnnotations);
                    IEdmPrimitiveTypeReference primitiveTypeReference = MetadataProviderUtils.CreatePrimitiveTypeReference(itemResourceType, customAnnotations);
                    elementTypeReference = primitiveTypeReference.IsNullable != PrimitiveOrComplexCollectionItemTypeDefaultNullability
                        ? primitiveTypeReference.Clone(PrimitiveOrComplexCollectionItemTypeDefaultNullability)
                        : primitiveTypeReference;

                    break;
                case ResourceTypeKind.EntityType:       // fall through
                case ResourceTypeKind.Collection:       // fall through
                case ResourceTypeKind.EntityCollection: // fall through
                default:
                    throw new InvalidOperationException(Microsoft.OData.Service.Strings.MetadataProviderEdmModel_UnsupportedCollectionItemType_PrimitiveOrComplex(itemResourceType.ResourceTypeKind.ToString()));
            }

            collectionType = new MetadataProviderEdmCollectionType(collectionResourceType, elementTypeReference);
            this.primitiveOrComplexCollectionTypeCache.Add(itemResourceType, collectionType);
            return collectionType;
        }
        /// <summary>
        /// Gets or creates an <see cref="IEdmCollectionType"/> for the <paramref name="itemResourceType"/>.
        /// </summary>
        /// <param name="itemResourceType">The item resource type to create an EDM collection type for.</param>
        /// <param name="collectionResourceType">The collection resource type to create an EDM collection type for.</param>
        /// <param name="customAnnotations">The optional annotations for the resource type; the annotations can contain facets that need to be applied to the type reference.</param>
        /// <returns>An <see cref="IEdmCollectionType"/> instance for the <paramref name="itemResourceType"/> item type.</returns>
        /// <remarks>
        /// Materialization state: none required. No change in materialization state.
        /// Cache state: none required. No change in cache state.
        /// </remarks>
        private IEdmCollectionType EnsureCollectionItemTypeIsEntityPrimitiveOrComplex(ResourceType itemResourceType, ResourceType collectionResourceType, List<KeyValuePair<string, object>> customAnnotations)
        {
            Debug.Assert(itemResourceType != null, "itemResourceType != null");

            IEdmCollectionType collectionType;
            if (this.entityPrimitiveOrComplexCollectionTypeCache.TryGetValue(itemResourceType, out collectionType))
            {
                return collectionType;
            }

            IEdmTypeReference elementTypeReference;
            switch (itemResourceType.ResourceTypeKind)
            {
                case ResourceTypeKind.ComplexType:
                    elementTypeReference = this.EnsureTypeReference(itemResourceType, customAnnotations);
                    break;
                case ResourceTypeKind.Primitive:
                    elementTypeReference = MetadataProviderUtils.CreatePrimitiveTypeReference(itemResourceType, customAnnotations);
                    break;
                case ResourceTypeKind.EntityType:
                    elementTypeReference = this.EnsureTypeReference(itemResourceType, customAnnotations);
                    break;
                case ResourceTypeKind.Collection:       // fall through
                case ResourceTypeKind.EntityCollection: // fall through
                default:
                    throw new InvalidOperationException(Microsoft.OData.Service.Strings.MetadataProviderEdmModel_UnsupportedCollectionItemType_EntityPrimitiveOrComplex(itemResourceType.ResourceTypeKind.ToString()));
            }

            collectionType = new MetadataProviderEdmCollectionType(collectionResourceType, elementTypeReference);
            this.entityPrimitiveOrComplexCollectionTypeCache.Add(itemResourceType, collectionType);
            return collectionType;
        }