/// <summary>
        /// Checks whether a property is mapped in the entity type definition
        /// </summary>
        /// <param name="meta">The metadata document</param>
        /// <param name="entityType">The entity type</param>
        /// <param name="propertyName">The property</param>
        /// <param name="mappedTarget">Output parameter of mapped target path</param>
        /// <returns>flag of proerty being mapped</returns>
        private static bool PropertyIsMapped(XElement meta, string entityType, string propertyName, out string mappedTarget)
        {
            const string tmplXPath2EntityType = @"//*[local-name()='EntityType' and @Name = '{0}']";
            const string tmplXPath2Property   = @"./*[local-name()='Property' and @Name='{0}']";

            string typeShortName = ResourcePathHelper.GetBaseName(entityType);

            mappedTarget = null;

            string xPath2EntityType = string.Format(tmplXPath2EntityType, typeShortName);
            var    nodeEntityType   = meta.XPathSelectElement(xPath2EntityType, ODataNamespaceManager.Instance);

            string xpath2prop   = string.Format(tmplXPath2Property, propertyName);
            var    nodeProperty = nodeEntityType.XPathSelectElement(xpath2prop);

            if (nodeProperty != null)
            {
                string attrFC_KeepInContent = nodeProperty.GetAttributeValue("m:FC_KeepInContent", ODataNamespaceManager.Instance);
                if (!string.IsNullOrEmpty(attrFC_KeepInContent))
                {
                    mappedTarget = nodeProperty.GetAttributeValue("m:FC_TargetPath", ODataNamespaceManager.Instance);
                    return(!Convert.ToBoolean(attrFC_KeepInContent));
                }
                else
                {
                    return(false);
                }
            }
            else
            {
                string baseType = nodeEntityType.GetAttributeValue("BaseType");
                return(PropertyIsMapped(meta, baseType, propertyName, out mappedTarget));
            }
        }
        /// <summary>
        /// Verify the rule
        /// </summary>
        /// <param name="context">Service context</param>
        /// <param name="info">out paramater 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;

            var    qs        = HttpUtility.ParseQueryString(context.Destination.Query);
            string qExpand   = qs["$expand"];
            var    branches  = ResourcePathHelper.GetBranchedSegments(qExpand);
            var    brHeaders = from br in branches select br.FirstOrDefault();

            // to get collection of navigatio properties which is not expanded
            List <string> navProps = new List <string>();
            XElement      meta     = XElement.Parse(context.MetadataDocument);
            const string  fmtXPathToTypeProperty = "//*[local-name()='Schema' and @Namespace='{0}']/*[local-name()='EntityType' and @Name='{1}']/*[local-name()='NavigationProperty' and @Name]";
            string        xpath = string.Format(fmtXPathToTypeProperty, ResourcePathHelper.GetNamespaceName(context.EntityTypeFullName), ResourcePathHelper.GetBaseName(context.EntityTypeFullName));
            var           nodes = meta.XPathSelectElements(xpath);

            foreach (var n in nodes)
            {
                var name = ResourcePathHelper.GetBaseName(n.Attribute("Name").Value);
                if (!brHeaders.Any(x => x.Equals(name, StringComparison.Ordinal)))
                {
                    navProps.Add(name);
                }
            }

            if (navProps.Count() > 0)
            {
                JObject jo      = JObject.Parse(context.ResponsePayload);
                var     version = JsonParserHelper.GetPayloadODataVersion(jo);

                var    propSchemas    = navProps.Select(x => string.Format(fmtCore, x));
                string coreProperties = string.Join("\r\n,", propSchemas);
                string CoreObject     = string.Format(fmtObj, coreProperties);
                string jSchema        = JsonSchemaHelper.WrapJsonSchema(CoreObject, version);

                TestResult result;
                passed = JsonParserHelper.ValidateJson(jSchema, context.ResponsePayload, out result);
                if (!passed.HasValue)
                {
                    info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload, result != null ? result.LineNumberInError : -1);
                }
            }

            return(passed);
        }
        /// <summary>
        /// Verify the code rule
        /// </summary>
        /// <param name="context">Service context</param>
        /// <param name="info">out paramater 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;

            var     edmxHelper = new EdmxHelper(XElement.Parse(context.MetadataDocument));
            var     segments   = ResourcePathHelper.GetPathSegments(context);
            UriType uriType;
            var     target = edmxHelper.GetTargetType(segments, out uriType);

            if (uriType == UriType.URI3)
            {
                XElement meta       = XElement.Parse(context.MetadataDocument);
                string   targetType = ((EdmProperty)target).TypeUsage.EdmType.FullName;

                var complexType = ResourcePathHelper.GetComplexType(targetType, meta);
                if (complexType != null)
                {
                    XElement    payload  = XElement.Parse(context.ResponsePayload);
                    string      schema   = GetRngSchema(ResourcePathHelper.GetBaseName(targetType), payload.Name.NamespaceName);
                    RngVerifier verifier = new RngVerifier(schema);
                    TestResult  result;
                    passed = verifier.Verify(context, out result);
                    if (passed.HasValue && !passed.Value)
                    {
                        info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload, result.LineNumberInError);
                    }
                }
            }

            return(passed);
        }