/// <summary>
        /// Verifies the extension rule.
        /// </summary>
        /// <param name="context">The Interop service context</param>
        /// <param name="info">out parameter to return violation information when rule does not pass</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            info = null;

            if (context.PayloadType == RuleEngine.PayloadType.Feed)
            {
                JObject feed;
                context.ResponsePayload.TryToJObject(out feed);
                var entries = JsonParserHelper.GetEntries(feed);

                foreach (JObject entry in entries)
                {
                    if (entry != null && entry.Type == JTokenType.Object)
                    {
                        var jProps = entry.Children();

                        foreach (JProperty jProp in jProps)
                        {
                            if (JsonSchemaHelper.IsJSONArrayOrPrimitiveAnnotation(jProp.Name))
                            {
                                passed = null;
                                string[] splitedStr = jProp.Name.Split('@');

                                JProperty nextProp = jProp.Next as JProperty;
                                JProperty prevProp = jProp.Previous as JProperty;

                                string annotatedPropName = nextProp.Name == splitedStr[0] ? nextProp.Name : prevProp.Name;

                                if (annotatedPropName.Contains(splitedStr[0]))
                                {
                                    if (jProp.Name == annotatedPropName + Constants.V4OdataType)
                                    {
                                        passed = true;
                                        continue;
                                    }
                                    else
                                    {
                                        passed = false;
                                        info   = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload);
                                        return(passed);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else if (context.PayloadType == RuleEngine.PayloadType.Entry)
            {
                JObject entry;
                context.ResponsePayload.TryToJObject(out entry);

                if (entry != null && entry.Type == JTokenType.Object)
                {
                    var jProps = entry.Children();

                    foreach (JProperty jProp in jProps)
                    {
                        if (JsonSchemaHelper.IsJSONArrayOrPrimitiveAnnotation(jProp.Name))
                        {
                            passed = null;
                            string[] splitedStr = jProp.Name.Split('@');

                            JProperty nextProp = jProp.Next as JProperty;
                            JProperty prevProp = jProp.Previous as JProperty;

                            string annotatedPropName = nextProp.Name == splitedStr[0] ? nextProp.Name : prevProp.Name;

                            if (annotatedPropName.Contains(splitedStr[0]))
                            {
                                if (jProp.Name == annotatedPropName + Constants.V4OdataType)
                                {
                                    passed = true;
                                    continue;
                                }
                                else
                                {
                                    passed = false;
                                    info   = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload);
                                    return(passed);
                                }
                            }
                        }
                    }
                }
            }

            return(passed);
        }
        /// <summary>
        /// Verify Common.Core.4403
        /// </summary>
        /// <param name="context">Service context</param>
        /// <param name="info">out parameter to return violation information when rule fail</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            info = null;
            JObject allobject;

            context.ResponsePayload.TryToJObject(out allobject);

            // If PayloadType is Feed, verify as below, else is Entry.
            if (context.PayloadType.Equals(RuleEngine.PayloadType.Feed))
            {
                var entries = JsonParserHelper.GetEntries(allobject);
                foreach (JObject entry in entries)
                {
                    var jProps = entry.Children();
                    foreach (JProperty jProp in jProps)
                    {
                        // Whether the property name contains odata.type.
                        if (jProp.Name.EndsWith(Constants.V4OdataType) && !jProp.Name.Equals(Constants.V4OdataType))
                        {
                            // Whether the property is built-in primitive types.
                            bool isBuiltInPriType = JsonSchemaHelper.IsBuiltInPrimitiveTypes(jProp, context);

                            if (!isBuiltInPriType)
                            {
                                string typeValue = jProp.Value.ToString().StripOffDoubleQuotes().TrimStart('#');

                                // Whether the value of  odata.type is absolute or relative URl.
                                if (Uri.IsWellFormedUriString(typeValue, UriKind.RelativeOrAbsolute))
                                {
                                    passed = true;
                                    continue;
                                }
                                else
                                {
                                    passed = false;
                                    info   = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload);
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                var jProps = allobject.Children();
                foreach (JProperty jProp in jProps)
                {
                    // Whether the property name contains odata.type.
                    if (jProp.Name.EndsWith(Constants.V4OdataType) && !jProp.Name.Equals(Constants.V4OdataType))
                    {
                        // Whether the property is built-in primitive types.
                        bool isBuiltInPriType = JsonSchemaHelper.IsBuiltInPrimitiveTypes(jProp, context);

                        if (!isBuiltInPriType)
                        {
                            string typeValue = jProp.Value.ToString().StripOffDoubleQuotes().TrimStart('#');

                            // Whether the value of  odata.type is absolute or relative URl.
                            if (Uri.IsWellFormedUriString(typeValue, UriKind.RelativeOrAbsolute))
                            {
                                passed = true;
                                continue;
                            }
                            else
                            {
                                passed = false;
                                info   = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload);
                                break;
                            }
                        }
                    }
                }
            }

            return(passed);
        }
        /// <summary>
        /// Verifies the extension rule.
        /// </summary>
        /// <param name="context">The Interop service context</param>
        /// <param name="info">out parameter to return violation information when rule does not pass</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = true;
            ExtensionRuleResultDetail detail = new ExtensionRuleResultDetail(this.Name);

            var payloadFormat = context.ServiceDocument.GetFormatFromPayload();

            string[] feeds            = ContextHelper.GetFeeds(context.ServiceDocument, payloadFormat).ToArray();
            string   entitySetName    = feeds.First().MapEntitySetURLToEntitySetName();
            Uri      firstFeedFullUrl = new Uri(string.Format("{0}/{1}", context.DestinationBasePath, entitySetName));
            Response response         = WebHelper.Get(firstFeedFullUrl, Constants.V4AcceptHeaderJsonFullMetadata, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);

            detail = new ExtensionRuleResultDetail(this.Name, firstFeedFullUrl.AbsoluteUri, "GET", StringHelper.MergeHeaders(Constants.V4AcceptHeaderJsonFullMetadata, context.RequestHeaders), response);

            if (response != null && response.StatusCode != null)
            {
                JObject feed;
                response.ResponsePayload.TryToJObject(out feed);
                var entries = JsonParserHelper.GetEntries(feed);

                foreach (JObject entry in entries)
                {
                    var jProps = entry.Children();

                    foreach (JProperty jProp in jProps)
                    {
                        if (JsonSchemaHelper.IsAnnotation(jProp.Name) && jProp.Name.EndsWith("@" + Constants.OdataType) && !jProp.Name.StartsWith("@" + Constants.OdataType))
                        {
                            string typeValue = jProp.Value.ToString().TrimStart('#');

                            if (typeValue.Contains("Collection("))
                            {
                                typeValue = typeValue.Substring(typeValue.IndexOf("(") + 1, typeValue.LastIndexOf(")") - typeValue.IndexOf("(") - 1);
                            }

                            // Don't contains dot means it is primitive value or collection.
                            if (!typeValue.Contains("."))
                            {
                                if (PrimitiveDataTypes.NonQualifiedTypes.Contains(typeValue))
                                {
                                    passed = true;
                                }
                                else
                                {
                                    passed = false;
                                    detail.ErrorMessage += string.Format("The type {0} is not defined in OData-CSDL.", typeValue);
                                    break;
                                }
                            }
                        }
                    }

                    if (passed == false)  // Break to foreach all if anyone of them cannot match the rule
                    {
                        break;
                    }
                }
            }
            else
            {
                passed = false;
                detail.ErrorMessage = string.Format(Constants.ErrorURI, "GET", firstFeedFullUrl.AbsoluteUri, "failed");
            }

            info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail);
            return(passed);
        }