private JsonRpcMethod TryBindToMethod(ICollection <JsonRpcMethod> candidates, JObject paramsObj)
        {
            Debug.Assert(paramsObj != null);
            JsonRpcMethod firstMatch = null;
            Dictionary <string, JToken> requestProp = null;

            foreach (var m in candidates)
            {
                if (!m.AllowExtensionData)
                {
                    // Strict match
                    requestProp = paramsObj.Properties().ToDictionary(p => p.Name, p => p.Value);
                }
                foreach (var p in m.Parameters)
                {
                    var jp = paramsObj[p.ParameterName];
                    if (jp == null || jp.Type == JTokenType.Undefined)
                    {
                        if (!p.IsOptional)
                        {
                            goto NEXT;
                        }
                        else
                        {
                            continue;
                        }
                    }
                    if (!p.MatchJTokenType(jp.Type))
                    {
                        goto NEXT;
                    }
                    requestProp?.Remove(p.ParameterName);
                }
                // Check whether we have extra parameters.
                if (requestProp != null && requestProp.Count > 0)
                {
                    goto NEXT;
                }
                if (firstMatch != null)
                {
                    throw new AmbiguousMatchException();
                }
                firstMatch = m;
NEXT:
                ;
            }
            return(firstMatch);
        }
        private JsonRpcMethod TryBindToParameterlessMethod(ICollection <JsonRpcMethod> candidates)
        {
            JsonRpcMethod firstMatch = null;

            foreach (var m in candidates)
            {
                if (m.Parameters.Count == 0 || m.Parameters.All(p => p.IsOptional))
                {
                    if (firstMatch != null)
                    {
                        throw new AmbiguousMatchException();
                    }
                    firstMatch = m;
                }
            }
            return(firstMatch);
        }
        private JsonRpcMethod TryBindToMethod(ICollection <JsonRpcMethod> candidates, JArray paramsArray)
        {
            Debug.Assert(paramsArray != null);
            JsonRpcMethod firstMatch = null;

            foreach (var m in candidates)
            {
                if (!m.AllowExtensionData && paramsArray.Count > m.Parameters.Count)
                {
                    goto NEXT;
                }
                for (var i = 0; i < m.Parameters.Count; i++)
                {
                    var param  = m.Parameters[i];
                    var jparam = i < paramsArray.Count ? paramsArray[i] : null;
                    if (jparam == null || jparam.Type == JTokenType.Undefined)
                    {
                        if (!param.IsOptional)
                        {
                            goto NEXT;
                        }
                        else
                        {
                            continue;
                        }
                    }
                    if (!param.MatchJTokenType(jparam.Type))
                    {
                        goto NEXT;
                    }
                }
                if (firstMatch != null)
                {
                    throw new AmbiguousMatchException();
                }
                firstMatch = m;
NEXT:
                ;
            }
            return(firstMatch);
        }