/// <summary>
        /// Validates the value type of a property meets the derived type constraints.
        /// </summary>
        /// <param name="propertySerializationInfo">The property serialization info.</param>
        /// <remarks>This does NOT validate the value of the property, just the type of property.</remarks>
        internal static void ValidatePropertyDerivedTypeConstraint(PropertySerializationInfo propertySerializationInfo)
        {
            Debug.Assert(propertySerializationInfo != null, "propertySerializationInfo != null");

            // Skip the undeclared property
            if (propertySerializationInfo.MetadataType.IsUndeclaredProperty)
            {
                return;
            }

            PropertyValueTypeInfo valueType = propertySerializationInfo.ValueType;

            if (valueType == null || valueType.TypeReference == null)
            {
                return;
            }

            // make sure the same type can pass the validation.
            if (propertySerializationInfo.MetadataType.TypeReference.Definition == valueType.TypeReference.Definition)
            {
                return;
            }

            string fullTypeName = valueType.TypeReference.FullName();

            if (propertySerializationInfo.MetadataType.DerivedTypeConstraints == null ||
                propertySerializationInfo.MetadataType.DerivedTypeConstraints.Any(d => d == fullTypeName))
            {
                return;
            }

            throw new ODataException(Strings.WriterValidationUtils_ValueTypeNotAllowedInDerivedTypeConstraint(fullTypeName, "property", propertySerializationInfo.PropertyName));
        }
        /// <summary>
        /// Validates the value type of a property meets the derived type constraints.
        /// </summary>
        /// <param name="propertySerializationInfo">The property serialization info.</param>
        /// <remarks>This does NOT validate the value of the property, just the type of property.</remarks>
        internal static void ValidatePropertyDerivedTypeConstraint(PropertySerializationInfo propertySerializationInfo)
        {
            Debug.Assert(propertySerializationInfo != null, "propertySerializationInfo != null");

            // Skip the undeclared property
            if (propertySerializationInfo.MetadataType.IsUndeclaredProperty)
            {
                return;
            }

            PropertyValueTypeInfo valueType = propertySerializationInfo.ValueType;

            if (valueType == null || valueType.TypeReference == null)
            {
                return;
            }

            // make sure the same type can pass the validation.
            if (propertySerializationInfo.MetadataType.TypeReference.Definition == valueType.TypeReference.Definition)
            {
                return;
            }

            string fullTypeName = valueType.TypeReference.FullName();

            if (propertySerializationInfo.MetadataType.DerivedTypeConstraints == null)
            {
                return;
            }

            // this runs in a hot path, hence the use of a loop instead of LINQ to avoid allocations
            foreach (string d in propertySerializationInfo.MetadataType.DerivedTypeConstraints)
            {
                if (d == fullTypeName)
                {
                    return;
                }
            }

            throw new ODataException(Strings.WriterValidationUtils_ValueTypeNotAllowedInDerivedTypeConstraint(fullTypeName, "property", propertySerializationInfo.PropertyName));
        }