string GetParameterDoc(System.Reflection.MethodInfo method, System.Reflection.ParameterInfo parameter)
        {
            if (method.DeclaringType == null)
            {
                return(null);
            }

            XmlNode methoddoc = GetMethodDocFromType(method.DeclaringType, method);

            XmlNode paramdoc = methoddoc?.SelectSingleNode($"param[@name='{parameter.Name}']");

            return(ExtractSummary(paramdoc));
        }
        string GetMethodDoc(System.Reflection.MethodInfo method)
        {
            if (method.DeclaringType == null)
            {
                return(null);
            }

            XmlNode methoddoc   = GetMethodDocFromType(method.DeclaringType, method);
            XmlNode remarksnode = methoddoc?.SelectSingleNode("remarks");

            if (remarksnode != null)
            {
                return(ExtractSummary(methoddoc.SelectSingleNode("summary")) + "\n" + ExtractSummary(remarksnode));
            }
            return(ExtractSummary(methoddoc?.SelectSingleNode("summary")));
        }
        string GetReturnType(System.Reflection.MethodInfo method, Type hosttype)
        {
            if (method.ReturnType.IsGenericParameter)
            {
                if (method.ReturnType.GenericParameterPosition < hosttype.GenericTypeArguments.Length)
                {
                    return(hosttype.GenericTypeArguments[method.ReturnType.GenericParameterPosition].GetTypeName());
                }
                // TODO: see whether it makes sense to resolve the generic type
                return(typeof(object).GetTypeName());
            }

            if (method.ReturnType.ContainsGenericParameters)
            {
                if (method.ReturnType.BaseType == typeof(Array) && hosttype.GenericTypeArguments.Length > 0)
                {
                    return(hosttype.GenericTypeArguments[0].MakeArrayType().GetTypeName());
                }
                return(typeof(object).GetTypeName());
            }

            return(method.ReturnType != typeof(void) ? method.ReturnType.GetTypeName() : null);
        }
        XmlNode GetMethodDocFromType(Type type, System.Reflection.MethodInfo method)
        {
            XmlDocument doc        = GetAssemblyDoc(type.Assembly);
            string      membername = $"{type.FullName}.{method.Name}({string.Join(",", method.GetParameters().Select(p => p.ParameterType.FullName))})";

            XmlNode doctag = doc?.SelectSingleNode($"doc/members/member[@name='M:{membername}']");

            if (doctag == null)
            {
                return(null);
            }

            if (doctag.ChildNodes.Cast <XmlNode>().Any(c => c.Name == "inheritdoc"))
            {
                foreach (Type interfacetype in type.GetInterfaces())
                {
                    XmlNode summarydoc = GetMethodDocFromType(interfacetype, method);
                    if (summarydoc != null)
                    {
                        return(summarydoc);
                    }
                }

                if (type.BaseType != null && type != typeof(object))
                {
                    XmlNode summarydoc = GetMethodDocFromType(type.BaseType, method);
                    if (summarydoc != null)
                    {
                        return(summarydoc);
                    }
                }
                return(null);
            }

            return(doctag);
        }