/// <summary>
            /// Returns the entity set for the given payload element (only for entries and feeds).
            /// </summary>
            /// <param name="expectedTypeAnnotation">The expected type annotation.</param>
            /// <param name="model">The model to get the type from.</param>
            /// <param name="payloadElement">The payload element to get the expected type for.</param>
            /// <returns>The expected type for the specified payload element.</returns>
            private static IEdmEntitySet GetExpectedEntitySet(ExpectedTypeODataPayloadElementAnnotation expectedTypeAnnotation, IEdmModel model, ODataPayloadElement payloadElement)
            {
                ExceptionUtilities.Assert(model != null, "model != null");
                ExceptionUtilities.Assert(payloadElement != null, "payloadElement != null");

                if (payloadElement.GetAnnotation <IgnoreEntitySetAnnotation>() != null)
                {
                    // Entity set information is explicitly ignored
                    return(null);
                }

                if (expectedTypeAnnotation != null)
                {
                    if (expectedTypeAnnotation.EdmEntitySet != null)
                    {
                        return(expectedTypeAnnotation.EdmEntitySet);
                    }
                    EntitySet entitySet = expectedTypeAnnotation.EntitySet;
                    if (entitySet != null)
                    {
                        return(model.EntityContainersAcrossModels().Select(m => m.FindEntitySet(entitySet.Name)).FirstOrDefault(s => s != null));
                    }
                }

                EntityModelTypeAnnotation typeAnnotation = payloadElement.GetAnnotation <EntityModelTypeAnnotation>();

                if (typeAnnotation != null)
                {
                    var edmEntityType = typeAnnotation.EdmModelType;
                    return(model.EntityContainersAcrossModels().First().EntitySets().SingleOrDefault(es => es.EntityType().FullName() == edmEntityType.FullName()));
                }

                return(null);
            }
            /// <summary>
            /// Returns the entity set for the given payload element (only for entries and feeds).
            /// </summary>
            /// <param name="expectedTypeAnnotation">The expected type annotation.</param>
            /// <param name="model">The model to get the type from.</param>
            /// <param name="payloadElement">The payload element to get the expected type for.</param>
            /// <returns>The expected type for the specified payload element.</returns>
            private static IEdmEntitySet GetExpectedEntitySet(ExpectedTypeODataPayloadElementAnnotation expectedTypeAnnotation, IEdmModel model, ODataPayloadElement payloadElement)
            {
                ExceptionUtilities.Assert(model != null, "model != null");
                ExceptionUtilities.Assert(payloadElement != null, "payloadElement != null");

                if (payloadElement.GetAnnotation<IgnoreEntitySetAnnotation>() != null)
                {
                    // Entity set information is explicitly ignored
                    return null;
                }

                if (expectedTypeAnnotation != null)
                {
                    if (expectedTypeAnnotation.EdmEntitySet != null)
                    {
                        return expectedTypeAnnotation.EdmEntitySet;
                    }
                    EntitySet entitySet = expectedTypeAnnotation.EntitySet;
                    if (entitySet != null)
                    {
                        return model.EntityContainersAcrossModels().Select(m => m.FindEntitySet(entitySet.Name)).FirstOrDefault(s => s != null);
                    }
                }

                EntityModelTypeAnnotation typeAnnotation = payloadElement.GetAnnotation<EntityModelTypeAnnotation>();
                if (typeAnnotation != null)
                {
                    var edmEntityType = typeAnnotation.EdmModelType;
                    return model.EntityContainersAcrossModels().First().EntitySets().SingleOrDefault(es => es.EntityType().FullName() == edmEntityType.FullName());
                }

                return null;
            }
        /// <summary>
        /// Adds or modifies a property's ExpectedTypeODataPayloadElementAnnotation, to aid generation of the context uri.
        /// </summary>
        /// <param name="property">The property to annotate.</param>
        /// <param name="propertyValueType">The type of the property's value.</param>
        /// <param name="matchesProperty">Delegate for matching the property instance to a MemberProperty.</param>
        /// <remarks>
        /// If the method cannot resolve the parent type of the property, one will be created and added to the test descriptor's
        /// PayloadModel. The descriptor's cached model will be reset.
        /// </remarks>
        private void AddExpectedTypeToProperty(PropertyInstance property, IEdmTypeReference propertyValueType, Func <IEdmProperty, bool> matchesProperty)
        {
            if (property.Annotations.OfType <JsonLightContextUriAnnotation>().Any())
            {
                return;
            }

            var typeAnnotation = property.Annotations.OfType <ExpectedTypeODataPayloadElementAnnotation>().SingleOrDefault();

            if (typeAnnotation == null || (typeAnnotation.MemberProperty == null && string.IsNullOrEmpty(typeAnnotation.OpenMemberPropertyName)))
            {
                ExpectedTypeODataPayloadElementAnnotation annotation = typeAnnotation ?? new ExpectedTypeODataPayloadElementAnnotation();

                IEdmModel model = this.testDescriptor.PayloadEdmModel;

                var entityType = model.EntityTypes().SingleOrDefault(t => t.Properties().Any(matchesProperty));
                if (entityType != null)
                {
                    annotation.EdmEntitySet  = FindEntitySet(model, entityType);
                    annotation.EdmOwningType = entityType;
                    annotation.EdmProperty   = entityType.Properties().FirstOrDefault(matchesProperty);
                }
                else
                {
                    var complexType = model.SchemaElements.OfType <IEdmComplexType>().SingleOrDefault(t => t.Properties().Any(matchesProperty));
                    if (complexType != null)
                    {
                        var complexProperty = complexType.Properties().Single(p => p.Name == property.Name);

                        annotation.EdmOwningType   = complexType;
                        annotation.EdmProperty     = complexProperty;
                        annotation.EdmExpectedType = complexProperty.Type;
                    }
                    else
                    {
                        // Add new entity type to the model and use that
                        IEdmTypeReference propertyType = annotation.EdmExpectedType ?? propertyValueType;

                        EdmEntityType newEntityType   = model.FindDeclaredType("TestModel.NewType") as EdmEntityType;
                        IEdmEntitySet newEntitySet    = null;
                        IEdmProperty  newProperty     = null;
                        string        newPorpertyName = property.Name ?? propertyType.FullName() ?? "EmptyName";

                        if (newEntityType == null)
                        {
                            newEntityType = new EdmEntityType("TestModel", "NewType");
                            newProperty   = newEntityType.AddStructuralProperty(newPorpertyName, propertyType);
                            ((EdmModel)model).AddElement(newEntityType);
                            var container = model.EntityContainersAcrossModels().Single() as EdmEntityContainer;
                            newEntitySet = container.AddEntitySet("NewTypes", newEntityType);
                        }
                        else
                        {
                            newProperty  = newEntityType.AddStructuralProperty(newPorpertyName, propertyType);
                            newEntitySet = FindEntitySet(model, newEntityType);
                        }

                        annotation.EdmEntitySet    = newEntitySet;
                        annotation.EdmOwningType   = newEntityType;
                        annotation.EdmProperty     = newProperty;
                        annotation.EdmExpectedType = propertyType;

                        this.testDescriptor.PayloadEdmModel = model;
                        this.testDescriptor.ResetCachedModel();
                    }
                }

                property.SetAnnotation(annotation);
            }
        }