private string GetSummary(TypeScriptClass @class)
        {
            var itemSummary = @class.Comment?.ShortText;

            if (string.IsNullOrEmpty(itemSummary))
            {
                var properties = @class.GetSignificantProperties();
                var methods    = @class.GetSignificantMethods();

                if (!properties.Any() && !methods.Any())
                {
                    properties = @class.Properties.Where(p => !p.IsPrivate).Take(5);
                    methods    = @class.Methods.Where(m => !m.IsPrivate).Take(5);
                }

                if (properties.Any() || methods.Any())
                {
                    itemSummary = BuildHTMLList(@class.GetPath().MakeUriFromString(), properties, methods);
                }

                if (string.IsNullOrEmpty(itemSummary))
                {
                    //prevent autoexcerpt
                    itemSummary = " ";
                }
            }

            return(itemSummary);
        }
        private void BuildIndex(MarkdownBuilder mb, TypeScriptClass @class)
        {
            var publicMethods    = @class.Methods.Where(m => !m.IsStatic && !m.IsPrivate && !m.IsProtected).ToList();
            var protectedMethods = @class.Methods.Where(m => m.IsProtected).ToList();
            var staticMethods    = @class.Methods.Where(m => m.IsStatic && !m.IsPrivate).ToList();


            var publicProperties    = @class.Properties.Where(p => !p.IsStatic && !p.IsPrivate && !p.IsProtected).ToList();
            var protectedProperties = @class.Properties.Where(p => p.IsProtected).ToList();
            var staticProperties    = @class.Properties.Where(p => p.IsStatic && !p.IsPrivate).ToList();

            var publicAccessors    = @class.Accessors.Where(m => !m.IsPrivate && !m.IsProtected).ToList();
            var protectedAccessors = @class.Accessors.Where(p => p.IsProtected).ToList();

            var path = @class.GetPath().MakeUriFromString();

            //Index region
            mb.Header(2, "Index");
            if (@class.Constructor != null)
            {
                mb.HeaderWithLink(3, "Constructors", CombineWithRootUrl(path.CombineWithUri("#constructors-1")));
                mb.ListLink("constructor", CombineWithRootUrl(path.CombineWithUri("#constructor")));

                mb.AppendLine();
            }

            if (publicProperties.Any())
            {
                mb.HeaderWithLink(3, "Public Properties", CombineWithRootUrl(path.CombineWithUri("#public-properties-1")));

                foreach (var property in publicProperties)
                {
                    mb.ListLink(property.Name, CombineWithRootUrl(path.CombineWithUri("#" + property.Name.MakeUriFromString())));
                }

                mb.AppendLine();
            }

            if (protectedProperties.Any())
            {
                mb.HeaderWithLink(3, "Protected Properties", CombineWithRootUrl(path.CombineWithUri("#protected-properties-1")));

                foreach (var property in protectedProperties)
                {
                    mb.ListLink(property.Name, CombineWithRootUrl(path.CombineWithUri("#" + property.Name.MakeUriFromString())));
                }

                mb.AppendLine();
            }

            if (staticProperties.Any())
            {
                mb.HeaderWithLink(3, "Static Properties", CombineWithRootUrl(path.CombineWithUri("#static-properties-1")));

                foreach (var property in staticProperties)
                {
                    mb.ListLink(property.Name, CombineWithRootUrl(path.CombineWithUri("#" + property.Name.MakeUriFromString())));
                }

                mb.AppendLine();
            }

            if (publicAccessors.Any())
            {
                mb.HeaderWithLink(3, "Public Accessors", CombineWithRootUrl(path.CombineWithUri("#public-accessors-1")));

                foreach (var accessor in publicAccessors)
                {
                    mb.ListLink(accessor.Name, CombineWithRootUrl(path.CombineWithUri("#" + accessor.Name.MakeUriFromString())));
                }

                mb.AppendLine();
            }

            if (protectedAccessors.Any())
            {
                mb.HeaderWithLink(3, "Protected Accessors", CombineWithRootUrl(path.CombineWithUri("#protected-accessors-1")));

                foreach (var accessor in protectedAccessors)
                {
                    mb.ListLink(accessor.Name, CombineWithRootUrl(path.CombineWithUri("#" + accessor.Name.MakeUriFromString())));
                }

                mb.AppendLine();
            }

            if (publicMethods.Any())
            {
                mb.HeaderWithLink(3, "Public Methods", CombineWithRootUrl(path.CombineWithUri("#public-methods-1")));
                foreach (var method in publicMethods)
                {
                    mb.ListLink(method.Name, CombineWithRootUrl(path.CombineWithUri("#" + method.Name.MakeUriFromString())));
                }
                mb.AppendLine();
            }

            if (protectedMethods.Any())
            {
                mb.HeaderWithLink(3, "Protected Methods", CombineWithRootUrl(path.CombineWithUri("#protected-methods-1")));
                foreach (var method in protectedMethods)
                {
                    mb.ListLink(method.Name, CombineWithRootUrl(path.CombineWithUri("#" + method.Name.MakeUriFromString())));
                }
                mb.AppendLine();
            }

            if (staticMethods.Any())
            {
                mb.HeaderWithLink(3, "Static Methods", CombineWithRootUrl(path.CombineWithUri("#static-methods-1")));
                foreach (var property in staticMethods)
                {
                    mb.ListLink(property.Name, CombineWithRootUrl(path.CombineWithUri("#" + property.Name.MakeUriFromString())));
                }
                mb.AppendLine();
            }
            mb.AppendLine();
        }
        private string BuildContent(TypeScriptClass @class)
        {
            var mb = new MarkdownBuilder();

            if (!string.IsNullOrEmpty(@class.Comment?.ShortText))
            {
                mb.AppendLine(@class.Comment.ShortText);
                mb.AppendLine();
            }

            BuildExample(mb, @class.Comment);

            BuildImplementedTypes(mb, @class);
            BuildExtendedTypes(mb, @class);

            BuildIndex(mb, @class);

            if (@class.Constructor != null)
            {
                mb.Header(2, "Constructors");
                mb.AppendSeparateLine();
                mb.Header(4, "constructor");
                mb.AppendLine();

                if (!string.IsNullOrEmpty(@class.Constructor.Signatures.First().Comment?.ShortText))
                {
                    mb.AppendLine(@class.Constructor.Signatures.First().Comment.ShortText);
                }

                foreach (var signature in @class.Constructor.Signatures)
                {
                    mb.AppendLine("⊕ " + signature.Format(_lib));
                    mb.AppendLine();
                }


                BuildParameters(mb, @class.Constructor.Signatures.Last().Parameters);

                BuildExample(mb, @class.Constructor.Signatures.First().Comment);

                mb.AppendSeparateLine();
            }

            mb.AppendLine();


            var publicMethods    = @class.Methods.Where(m => !m.IsStatic && !m.IsPrivate && !m.IsProtected).ToList();
            var protectedMethods = @class.Methods.Where(m => m.IsProtected).ToList();
            var staticMethods    = @class.Methods.Where(m => m.IsStatic && !m.IsPrivate).ToList();


            var publicProperties    = @class.Properties.Where(p => !p.IsStatic && !p.IsPrivate && !p.IsProtected).ToList();
            var protectedProperties = @class.Properties.Where(p => p.IsProtected).ToList();
            var staticProperties    = @class.Properties.Where(p => p.IsStatic && !p.IsPrivate).ToList();

            var publicAccessors   = @class.Accessors.Where(a => !a.IsPrivate && !a.IsProtected).ToList();
            var protectedAccesors = @class.Accessors.Where(a => a.IsProtected).ToList();

            if (publicProperties.Any())
            {
                mb.Header(2, "Public Properties");
                mb.AppendSeparateLine();
                foreach (var property in publicProperties)
                {
                    BuildContent(mb, property);
                }
            }

            if (protectedProperties.Any())
            {
                mb.Header(2, "Protected Properties");
                mb.AppendSeparateLine();
                foreach (var property in protectedProperties)
                {
                    BuildContent(mb, property);
                }
            }

            if (staticProperties.Any())
            {
                mb.Header(2, "Static Properties");
                mb.AppendSeparateLine();
                foreach (var property in staticProperties)
                {
                    BuildContent(mb, property);
                }
            }

            if (publicAccessors.Any())
            {
                mb.Header(2, "Public Accessors");
                mb.AppendSeparateLine();
                foreach (var accessor in publicAccessors)
                {
                    BuildContent(mb, accessor);
                }
            }

            if (protectedAccesors.Any())
            {
                mb.Header(2, "Protected Accessors");
                mb.AppendSeparateLine();
                foreach (var accessor in protectedAccesors)
                {
                    BuildContent(mb, accessor);
                }
            }

            if (publicMethods.Any())
            {
                mb.Header(2, "Public Methods");
                mb.AppendSeparateLine();
                foreach (var method in publicMethods)
                {
                    BuildContent(mb, method);
                }
            }

            if (protectedMethods.Any())
            {
                mb.Header(2, "Protected Methods");
                mb.AppendSeparateLine();
                foreach (var method in protectedMethods)
                {
                    BuildContent(mb, method);
                }
            }

            if (staticMethods.Any())
            {
                mb.Header(2, "Static Methods");
                mb.AppendSeparateLine();
                foreach (var method in staticMethods)
                {
                    BuildContent(mb, method);
                }
            }

            return(mb.ToString());
        }
        private void LoadFromJObject(TypeScriptPackage package, JObject jobject)
        {
            if (jobject.TryGetValue("name", out var nameToken))
            {
                package.Name = nameToken.ToString();
            }


            if (jobject.TryGetValue("children", out var childrenToken))
            {
                //expects here extenral modules
                var children = childrenToken.ToObject <List <JObject> >();


                foreach (var child in children)
                {
                    var childKind = child["kind"].ToObject <TypeScriptTokenKind>();
                    if (childKind == TypeScriptTokenKind.Class)
                    {
                        var @class = new TypeScriptClass(package);
                        LoadFromJObject(@class, child);
                        package.Classes.Add(@class);
                    }
                    else if (childKind == TypeScriptTokenKind.Interface)
                    {
                        var @interface = new TypeScriptInterface(package);
                        LoadFromJObject(@interface, child);
                        package.Interfaces.Add(@interface);
                    }
                    else if (childKind == TypeScriptTokenKind.Function)
                    {
                        var function = new TypeScriptFunction(package);
                        LoadFromJObject(function, child);
                        package.Functions.Add(function);
                    }
                    else if (childKind == TypeScriptTokenKind.Namespace)
                    {
                        var @namespace = new TypeScriptNamespace(package);
                        LoadFromJObject(@namespace, child);
                        package.Namespaces.Add(@namespace);
                    }
                    else if (childKind == TypeScriptTokenKind.Enumeration)
                    {
                        var @enum = new TypeScriptEnumeration(package);
                        LoadFromJObject(@enum, child);
                        package.Enumerations.Add(@enum);
                    }
                    else if (childKind == TypeScriptTokenKind.Varialbe)
                    {
                        var @var = new TypeScriptVariable(package);
                        LoadFromJObject(var, child);
                        package.Variables.Add(@var);
                    }
                }


                if (jobject.TryGetValue("comment", out var commentToken))
                {
                    package.Comment = new TypeScriptComment();
                    LoadFromJObject(package.Comment, commentToken.ToObject <JObject>());
                }
            }
        }
        private void LoadFromJObject(TypeScriptClass @class, JObject jobject)
        {
            if (jobject.TryGetValue("id", out var idToken))
            {
                @class.Id = idToken.ToObject <int>();
            }

            if (jobject.TryGetValue("name", out var nameTokent))
            {
                @class.Name = nameTokent.ToString();
            }

            if (jobject.TryGetValue("flags", out var flagsToken))
            {
                var flagsObj = flagsToken.ToObject <JObject>();

                if (flagsObj.TryGetValue("isExported", out var isExportedToken))
                {
                    @class.IsExported = isExportedToken.ToObject <bool>();
                }
            }

            if (jobject.TryGetValue("children", out var childrenToken))
            {
                var children = childrenToken.ToObject <List <JObject> >();

                foreach (var child in children)
                {
                    var childKind = child["kind"].ToObject <TypeScriptTokenKind>();
                    if (childKind == TypeScriptTokenKind.Property)
                    {
                        var property = new TypeScriptProperty();
                        LoadFromJObject(property, child);
                        @class.Properties.Add(property);
                    }
                    else if (childKind == TypeScriptTokenKind.Method)
                    {
                        var method = new TypeScriptMethod();
                        LoadFromJObject(method, child);
                        @class.Methods.Add(method);
                    }
                    else if (childKind == TypeScriptTokenKind.Constructor)
                    {
                        @class.Constructor = new TypeScriptMethod();
                        LoadFromJObject(@class.Constructor, child);
                    }
                }
            }

            if (jobject.TryGetValue("comment", out var commentToken))
            {
                @class.Comment = new TypeScriptComment();
                LoadFromJObject(@class.Comment, commentToken.ToObject <JObject>());
            }

            if (jobject.TryGetValue("implementedTypes", out var impTypesToken))
            {
                var typeObjs = impTypesToken.ToObject <List <JObject> >();
                foreach (var typeObj in typeObjs)
                {
                    @class.ImplementedTypes.Add(LoadTypeFromJObject(typeObj));
                }
            }

            if (jobject.TryGetValue("extendedTypes", out var exToken))
            {
                var typeObjs = exToken.ToObject <List <JObject> >();
                foreach (var typeObj in typeObjs)
                {
                    @class.ExtendedTypes.Add(LoadTypeFromJObject(typeObj));
                }
            }
        }
        private void LoadFromJObject(TypeScriptNamespace @namespace, JObject jobject)
        {
            if (jobject.TryGetValue("name", out var nameToken))
            {
                @namespace.Name = nameToken.ToString();;
            }

            if (jobject.TryGetValue("flags", out var flagsToken))
            {
                var flagsObj = flagsToken.ToObject <JObject>();

                if (flagsObj.TryGetValue("isExported", out var isExportedToken))
                {
                    @namespace.IsExported = isExportedToken.ToObject <bool>();
                }
            }

            if (jobject.TryGetValue("children", out var childrenToken))
            {
                var children = childrenToken.ToObject <List <JObject> >();

                foreach (var child in children)
                {
                    var childKind = child["kind"].ToObject <TypeScriptTokenKind>();
                    if (childKind == TypeScriptTokenKind.Class)
                    {
                        var @class = new TypeScriptClass(@namespace);
                        LoadFromJObject(@class, child);
                        @namespace.Classes.Add(@class);
                    }
                    else if (childKind == TypeScriptTokenKind.Interface)
                    {
                        var @interface = new TypeScriptInterface(@namespace);
                        LoadFromJObject(@interface, child);
                        @namespace.Interfaces.Add(@interface);
                    }
                    else if (childKind == TypeScriptTokenKind.Function)
                    {
                        var function = new TypeScriptFunction(@namespace);
                        LoadFromJObject(function, child);
                        @namespace.Functions.Add(function);
                    }
                    else if (childKind == TypeScriptTokenKind.Namespace)
                    {
                        var nspace = new TypeScriptNamespace(@namespace);
                        LoadFromJObject(nspace, child);
                        @namespace.Namespaces.Add(nspace);
                    }
                    else if (childKind == TypeScriptTokenKind.Enumeration)
                    {
                        var @enum = new TypeScriptEnumeration(@namespace);
                        LoadFromJObject(@enum, child);
                        @namespace.Enumerations.Add(@enum);
                    }
                    else if (childKind == TypeScriptTokenKind.Varialbe)
                    {
                        var @var = new TypeScriptVariable(@namespace);
                        LoadFromJObject(var, child);
                        @namespace.Variables.Add(@var);
                    }
                }
            }

            if (jobject.TryGetValue("comment", out var commentToken))
            {
                @namespace.Comment = new TypeScriptComment();
                LoadFromJObject(@namespace.Comment, commentToken.ToObject <JObject>());
            }
        }