public override string ToString()
        {
            var mb = new MarkdownBuilder();

            mb.HeaderWithCode(1, Beautifier.BeautifyTypeWithLink(type, GenerateTypeRelativeLinkPath, false));
            mb.AppendLine();

            var desc = commentLookup[type.FullName].FirstOrDefault(x => x.MemberType == MemberType.Type)?.Summary ?? "";

            if (desc != "")
            {
                mb.AppendLine(desc);
            }
            {
                var sb = new StringBuilder();

                var stat = (type.IsAbstract && type.IsSealed) ? "static " : "";
                var abst = (type.IsAbstract && !type.IsInterface && !type.IsSealed) ? "abstract " : "";
                var classOrStructOrEnumOrInterface = type.IsInterface ? "interface" : type.IsEnum ? "enum" : type.IsValueType ? "struct" : "class";

                sb.AppendLine($"public {stat}{abst}{classOrStructOrEnumOrInterface} {Beautifier.BeautifyType(type, true)}");
                var impl = string.Join(", ", new[] { type.BaseType }.Concat(type.GetInterfaces()).Where(x => x != null && x != typeof(object) && x != typeof(ValueType)).Select(x => Beautifier.BeautifyType(x)));
                if (impl != "")
                {
                    sb.AppendLine("    : " + impl);
                }

                mb.Code("csharp", sb.ToString());
            }

            mb.AppendLine();

            if (type.IsEnum)
            {
                var enums = Enum.GetNames(type)
                            .Select(x => new {
                    Name = x,
                    //Value = ((Int32)Enum.Parse(type),
                    Value = x
                })
                            .OrderBy(x => x.Value)
                            .ToArray();

                BuildTable(mb, "Enum", enums, commentLookup[type.FullName], x => x.Value, x => x.Name, x => x.Name);
            }
            else
            {
                BuildTable(mb, "Fields", GetFields(), commentLookup[type.FullName], x => Beautifier.BeautifyTypeWithLink(x.FieldType, GenerateTypeRelativeLinkPath), x => x.Name, x => x.Name);
                BuildTable(mb, "Properties", GetProperties(), commentLookup[type.FullName], x => Beautifier.BeautifyTypeWithLink(x.PropertyType, GenerateTypeRelativeLinkPath), x => x.Name, x => x.Name);
                BuildTable(mb, "Events", GetEvents(), commentLookup[type.FullName], x => Beautifier.BeautifyTypeWithLink(x.EventHandlerType, GenerateTypeRelativeLinkPath), x => x.Name, x => x.Name);
                BuildTable(mb, "Constructors", GetConstructors(), commentLookup[type.FullName], x => "void", x => x.Name, x => Beautifier.ToMarkdownConstructorInfo(x, GenerateTypeRelativeLinkPath));
                BuildTable(mb, "Methods", GetMethods(), commentLookup[type.FullName], x => Beautifier.BeautifyTypeWithLink(x.ReturnType, GenerateTypeRelativeLinkPath), x => x.Name, x => Beautifier.ToMarkdownMethodInfo(x, GenerateTypeRelativeLinkPath));
                BuildTable(mb, "Static Fields", GetStaticFields(), commentLookup[type.FullName], x => Beautifier.BeautifyTypeWithLink(x.FieldType, GenerateTypeRelativeLinkPath), x => x.Name, x => x.Name);
                BuildTable(mb, "Static Properties", GetStaticProperties(), commentLookup[type.FullName], x => Beautifier.BeautifyTypeWithLink(x.PropertyType, GenerateTypeRelativeLinkPath), x => x.Name, x => x.Name);
                BuildTable(mb, "Static Methods", GetStaticMethods(), commentLookup[type.FullName], x => Beautifier.BeautifyTypeWithLink(x.ReturnType, GenerateTypeRelativeLinkPath), x => x.Name, x => Beautifier.ToMarkdownMethodInfo(x, GenerateTypeRelativeLinkPath));
                BuildTable(mb, "Static Events", GetStaticEvents(), commentLookup[type.FullName], x => Beautifier.BeautifyTypeWithLink(x.EventHandlerType, GenerateTypeRelativeLinkPath), x => x.Name, x => x.Name);
            }

            return(mb.ToString());
        }
        public override string ToString()
        {
            var mb = new MarkdownBuilder();

            var typeCategory = type.IsClass ? " Class" : type.IsInterface ? " Interface" : string.Empty;

            mb.HeaderWithCode(2, Beautifier.BeautifyType(type, false) + typeCategory);
            mb.AppendLine();
            mb.AppendLine($"Namespace: {type.Namespace}");
            mb.AppendLine();
            mb.AppendLine($"Assembly: {type.Assembly.ManifestModule.Name}");
            mb.AppendLine();

            var summary = commentLookup[type.FullName].FirstOrDefault(x => x.MemberType == MemberType.Type)?.Summary ?? "";

            if (summary != "")
            {
                mb.AppendLine(summary);
                mb.AppendLine();
            }

            var sb = new StringBuilder();

            var isStatic = type.IsAbstract && type.IsSealed;
            var @sealed  = !type.IsAbstract && type.IsSealed ? "sealed " : "";
            var stat     = isStatic ? "static " : "";
            var abst     = (type.IsAbstract && !type.IsInterface && !type.IsSealed) ? "abstract " : "";
            var classOrStructOrEnumOrInterface = type.IsInterface ? "interface" : type.IsEnum ? "enum" : type.IsValueType ? "struct" : "class";

            sb.AppendLine($"public {stat}{@sealed}{abst}{classOrStructOrEnumOrInterface} {Beautifier.BeautifyType(type, true)}");
            var impl = string.Join(", ", new[] { type.BaseType }.Concat(type.GetInterfaces()).Where(x => x != null && x != typeof(object) && x != typeof(ValueType)).Select(x => Beautifier.BeautifyType(x)));

            if (impl != "")
            {
                sb.AppendLine("    : " + impl);
            }

            mb.Code("csharp", sb.ToString());

            var typeParameters = commentLookup[type.FullName].FirstOrDefault(x => x.MemberType == MemberType.Type)?.TypeParameters;

            if (typeParameters.Count > 0)
            {
                mb.Header(3, "Type Parameters");
                mb.AppendLine();
                mb.Table(new[] { "Name", "Summary" }, typeParameters.Select(x => new[] { x.Key, x.Value }));
            }

            mb.AppendLine();

            if (type.IsEnum)
            {
                var underlyingEnumType = Enum.GetUnderlyingType(type);

                var enums = Enum.GetNames(type)
                            .Select(x => new { Name = x, Value = (Convert.ChangeType(Enum.Parse(type, x), underlyingEnumType)) })
                            .OrderBy(x => x.Value)
                            .ToArray();

                BuildTable(mb, "Enum", enums, commentLookup[type.FullName], x => x.Value.ToString(), x => x.Name, x => x.Name);
            }
            else
            {
                BuildTable(mb, "Constructors", GetConstructors(), commentLookup[type.FullName], x => Beautifier.BeautifyType(x.DeclaringType), x => "#ctor", x => Beautifier.ToMarkdownConstructorInfo(x));
                BuildTable(mb, "Fields", GetFields(), commentLookup[type.FullName], x => Beautifier.BeautifyType(x.FieldType), x => x.Name, x => x.Name);
                BuildTable(mb, "Properties", GetProperties(), commentLookup[type.FullName], x => Beautifier.BeautifyType(x.PropertyType), x => x.Name, x => x.Name);
                BuildTable(mb, "Events", GetEvents(), commentLookup[type.FullName], x => Beautifier.BeautifyType(x.EventHandlerType), x => x.Name, x => x.Name);
                BuildTable(mb, "Methods", GetMethods(), commentLookup[type.FullName], x => Beautifier.BeautifyType(x.ReturnType), x => x.Name, x => Beautifier.ToMarkdownMethodInfoWithoutParamNames(x));
                BuildTable(mb, "Static Fields", GetStaticFields(), commentLookup[type.FullName], x => Beautifier.BeautifyType(x.FieldType), x => x.Name, x => x.Name);
                BuildTable(mb, "Static Properties", GetStaticProperties(), commentLookup[type.FullName], x => Beautifier.BeautifyType(x.PropertyType), x => x.Name, x => x.Name);
                BuildTable(mb, "Static Methods", GetStaticMethods(), commentLookup[type.FullName], x => Beautifier.BeautifyType(x.ReturnType), x => x.Name, x => Beautifier.ToMarkdownMethodInfo(x));
                BuildTable(mb, "Static Events", GetStaticEvents(), commentLookup[type.FullName], x => Beautifier.BeautifyType(x.EventHandlerType), x => x.Name, x => x.Name);
            }

            return(mb.ToString());
        }
        public string BuildMethodPage(MethodInfo methodInfo)
        {
            var mb = new MarkdownBuilder();

            mb.HeaderWithCode(2, $"{Beautifier.BeautifyType(type)}.{Beautifier.ToMarkdownMethodInfoWithoutParamNames(methodInfo, true)} Method");
            mb.AppendLine();
            mb.AppendLine($"Namespace: {type.Namespace}");
            mb.AppendLine();
            mb.AppendLine($"Assembly: {type.Assembly.ManifestModule.Name}");
            mb.AppendLine();

            var comment = commentLookup[type.FullName].FirstOrDefault(x => x.MemberName == methodInfo.Name || x.MemberName.StartsWith(methodInfo.Name + "`"));

            var summary = comment?.Summary ?? string.Empty;

            if (summary != string.Empty)
            {
                mb.AppendLine(summary);
                mb.AppendLine();
            }

            var sb         = new StringBuilder();
            var stat       = methodInfo.IsStatic ? "static " : "";
            var abst       = methodInfo.IsAbstract ? "abstract " : "";
            var returnType = Beautifier.BeautifyType(methodInfo.ReturnType);

            sb.Append($"public {stat}{abst}{returnType} {Beautifier.ToMarkdownMethodInfo(methodInfo, true)}");
            mb.Code("csharp", sb.ToString());

            mb.AppendLine();

            if (comment.TypeParameters.Count > 0)
            {
                mb.Header(3, "Type Parameters");
                mb.AppendLine();
                foreach (var tp in comment.TypeParameters)
                {
                    mb.CodeQuote(tp.Key);
                    mb.AppendLine();
                    mb.AppendLine();
                    mb.AppendLine(tp.Value);
                }

                mb.AppendLine();
            }

            if (comment.Parameters.Count > 0)
            {
                mb.Header(3, "Parameters");
                mb.AppendLine();
                foreach (var parameter in comment.Parameters)
                {
                    mb.CodeQuote(parameter.Key);
                    mb.AppendLine();
                    mb.AppendLine();
                    mb.AppendLine(parameter.Value);
                }

                mb.AppendLine();
            }

            if (comment.Returns.Length > 0 && !comment.Returns.Equals("void"))
            {
                mb.Header(3, "Returns");
                mb.AppendLine();
                mb.CodeQuote(returnType);
                mb.AppendLine();
                mb.AppendLine();
                mb.AppendLine(comment.Returns);
            }

            return(mb.ToString());
        }