/// <summary>
        /// Verifies the semantic 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");
            }

            info = null;
            bool?passed = null;

            if (FeedCore2001.IsNextLinkPresent(context))
            {
                passed = true;
            }
            else
            {
                passed = !FeedCore2001.IsPartialColleclection(context);
                if (!passed.Value)
                {
                    info = new ExtensionRuleViolationInfo(Resource.PayloadExpectingNextLink, context.Destination, context.ResponsePayload);
                }
            }

            return(passed);
        }
        /// <summary>
        /// Checks whether the context payload is a partial collection of entrities
        /// </summary>
        /// <param name="context">The service context</param>
        /// <returns>True if it is partial collection; false otherwise</returns>
        private static bool IsPartialColleclection(ServiceContext context)
        {
            bool anyNewEntry = false;

            JObject contextResponse = JsonParserHelper.GetResponseObject(context);

            if (contextResponse != null)
            {
                JArray contextEntries = JsonParserHelper.GetEntries(contextResponse);
                if (contextEntries.Count > 0)
                {
                    // if any more entries return, the context response payload was a partial collection
                    Uri prober = FeedCore2001.ConstructProbeUri(context);
                    var resp   = WebHelper.Get(prober, Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders);

                    if (resp == null || string.IsNullOrEmpty(resp.ResponsePayload) || !JsonHelper.IsJsonVerboseFeed(resp.ResponsePayload))
                    {
                        return(false);
                    }

                    JObject response = JsonParserHelper.GetResponseObject(resp.ResponsePayload);
                    if (response != null)
                    {
                        JArray entries = JsonParserHelper.GetEntries(response);

                        if (entries.Count > 0)
                        {
                            // some producers do not respect $skipton;
                            // need to look at each entry to see whether there is any new entry.
                            HashSet <string> contextEntryKeys = new HashSet <string>(EqualityComparer <string> .Default);
                            foreach (var e in contextEntries)
                            {
                                if (e.Type == JTokenType.Object)
                                {
                                    var i = JsonParserHelper.GetTokenOfEntry((JObject)e);
                                    contextEntryKeys.Add(i);
                                }
                            }

                            foreach (var e in entries)
                            {
                                if (e.Type == JTokenType.Object)
                                {
                                    var i = JsonParserHelper.GetTokenOfEntry((JObject)e);
                                    if (!contextEntryKeys.Contains(i))
                                    {
                                        anyNewEntry = true;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(anyNewEntry);
        }