/// <summary>
        /// Processes the public constructor overloads.
        /// </summary>
        /// <param name="exportedType">The <see cref="DocExportedType"/>.</param>
        private void ProcessConstructors(DocExportedType exportedType)
        {
            if (!exportedType.IsClass)
            {
                return;
            }

            exportedType.Constructor = new DocConstructor(exportedType)
            {
                Name = exportedType.Name,
            };

            var ctors = exportedType.Type.GetConstructors().Concat(
                exportedType.Type.GetConstructors(BindingFlags.Static | BindingFlags.NonPublic)).Distinct()
                        .OrderBy(c => c.IsStatic ? 1 : 0).ThenBy(c => c.GetParameters().Length);

            foreach (var ctor in ctors)
            {
                var overload = new DocOverload(ctor, exportedType.Constructor)
                {
                    Name  = MemberUtils.GenerateCodeFor(ctor),
                    XPath = MemberUtils.GetSelector(ctor),
                };

                LinkCache.Register(overload);

                var staticText = ctor.IsStatic ? " static " : " ";

                overload.Code = $"public{staticText}{overload.Name}";

                ProcessParameters(ctor.GetParameters(), overload, overload.Parameters);

                exportedType.Constructor.Overloads.Add(overload);
            }
        }
 /// <summary>
 /// Second pass that deals with relationships.
 /// </summary>
 /// <param name="type">The <see cref="DocExportedType"/> to process.</param>
 private void ProcessTypePass2(DocBaseType type)
 {
     type.Code = MemberUtils.GenerateCodeFor(type.Type);
     type.ImplementedInterfaces = ProcessImplementedInterfaces(type.Type);
     type.TypeParameters        = ProcessTypeParameters(type.Type);
     type.DerivedTypes          = ProcessDerivedTypes(type.Type);
 }
 /// <summary>
 /// Process type information.
 /// </summary>
 /// <param name="type">The <see cref="Type"/> to process.</param>
 /// <param name="target">The <see cref="DocBaseType"/> to process to.</param>
 private void ProcessType(Type type, DocBaseType target)
 {
     target.Name        = type.FullName ?? $"{type.Namespace}.{type.Name}";
     target.Type        = type;
     target.IsInterface = type.IsInterface;
     target.IsEnum      = type.IsEnum;
     target.XPath       = MemberUtils.GetSelector(type);
     LinkCache.Register(target);
 }
        /// <summary>
        /// Process the type parameters for a given type.
        /// </summary>
        /// <param name="type">The <see cref="Type"/> to process.</param>
        /// <returns>The list of parsed type parameters.</returns>
        private IList <DocTypeParameter> ProcessTypeParameters(Type type)
        {
            var result = new List <DocTypeParameter>();

            if (type.IsGenericType)
            {
                foreach (var tParam in type.GetGenericArguments().Where(t => t.IsGenericParameter))
                {
                    var docParameter = new DocTypeParameter {
                        Name = tParam.Name
                    };
                    MemberUtils.ParseGenericTypeConstraints(tParam, docParameter);
                    result.Add(docParameter);
                }
            }

            return(result);
        }
        /// <summary>
        /// Processes the public method overloads.
        /// </summary>
        /// <param name="exportedType">The <see cref="DocExportedType"/>.</param>
        private void ProcessMethods(DocExportedType exportedType)
        {
            var typePropertyMethods = exportedType.Type.GetProperties()
                                      .Select(p => new[] { p.GetMethod, p.SetMethod })
                                      .SelectMany(p => p)
                                      .Where(p => p != null)
                                      .Distinct();

            var typeMethods = exportedType.Type.GetMethods(
                BindingFlags.Public |
                BindingFlags.Static |
                BindingFlags.Instance).Where(m => m.DeclaringType == exportedType.Type)
                              .Except(typePropertyMethods);

            foreach (var methodInfo in typeMethods)
            {
                var method = exportedType.Methods.FirstOrDefault(m => m.Name == methodInfo.Name);

                if (method == null)
                {
                    method = new DocMethod(exportedType)
                    {
                        Name             = methodInfo.Name,
                        MethodReturnType = TypeCache.Cache[methodInfo.ReturnType],
                    };
                    exportedType.Methods.Add(method);
                }

                var methodOverload = new DocMethodOverload(methodInfo, method)
                {
                    Name  = MemberUtils.GenerateCodeFor(methodInfo),
                    XPath = MemberUtils.GetSelector(methodInfo),
                };

                LinkCache.Register(methodOverload);

                methodOverload.Code = methodOverload.Name;

                ProcessParameters(methodInfo.GetParameters(), methodOverload, methodOverload.Parameters);

                method.MethodOverloads.Add(methodOverload);
            }
        }
        /// <summary>
        /// Process property information.
        /// </summary>
        /// <param name="exportedType">The <see cref="DocExportedType"/> to parse.</param>
        private void ProcessProperties(DocExportedType exportedType)
        {
            var defaultRules = typeof(DefaultComparisonRules);

            foreach (var prop in exportedType.Type.GetProperties(
                         BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static))
            {
                if (prop.DeclaringType != exportedType.Type)
                {
                    continue;
                }

                var property = new DocProperty(exportedType)
                {
                    Name           = $"{exportedType.Name}.{prop.Name}",
                    XPath          = MemberUtils.GetSelector(prop),
                    Type           = prop.PropertyType,
                    TypeParameters = ProcessTypeParameters(prop.PropertyType),
                    Code           = MemberUtils.GenerateCodeFor(prop),
                };

                if (exportedType.Type == defaultRules && prop.GetMethod.IsStatic)
                {
                    var expression = prop.GetMethod.Invoke(null, null);
                    property.CustomInfo = expression.ToString();
                }

                LinkCache.Register(property);

                if (prop.GetIndexParameters().Length > 0)
                {
                    property.IsIndexer   = true;
                    property.IndexerType = TypeCache.Cache[prop.GetIndexParameters().First().ParameterType];
                }

                property.TypeParameter = exportedType.TypeParameters.FirstOrDefault(
                    t => t.Name == property.Type.Name);

                exportedType.Properties.Add(property);
            }
        }