IEnumerable<string> FormatType(TypeInfo type)
        {
            if (type.IsEnum)
            {
                return $"{type.Name}".InArray()
                        .Concat("{")
                        .Concat(Enum.GetValues(type.AsType()).Cast<Enum>().Select(v => $"    {v} = {(int)(object)v}"))
                        .Concat("}");
            }

            var kind = type.IsInterface
                ? "interface"
                : type.IsAbstract
                    ? "abstract class"
                    : "class";

            var interfaces = type.GetInterfaces();
            var members = type.GetMembers(BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly | BindingFlags.Public)
                .OrderBy(t => t.Name)
                .ToArray();

            var fields = members.OfType<FieldInfo>().ToArray();
            var ctors = members.OfType<ConstructorInfo>().ToArray();
            var properties = members.OfType<PropertyInfo>().ToArray();
            var events = members.OfType<EventInfo>().ToArray();
            var methods = members.OfType<MethodInfo>().ToArray();
            var types = members.OfType<TypeInfo>().ToArray();
            var other = members.Except(methods).Except(properties).Except(fields).Except(ctors).Except(events).Except(types).ToArray();

            var body = fields.Select(f => $"{Static(f.IsStatic)}{f.FieldType} {f.Name}")
                .Concat(events.Select(e => $"event {FormatTypeName(e.EventHandlerType)} {e.Name}"))
                .Concat(ctors.SelectMany(FormatCtor))
                .Concat(properties.Select(p => $"{FormatProperty(p)}"))
                .Concat(methods.SelectMany(FormatMethods))
                .Concat(other.Select(o => $"UNKNOWN {o.GetType().Name} {o.Name}"))
                .Concat(types.SelectMany(FormatType));

            return
                $"{kind} {type.Name}".InArray()
                    .Concat(interfaces.Select(i => $"  {FormatTypeName(i)}"))
                    .Concat("{")
                    .Concat(body.Select(l => "  " + l))
                    .Concat("}");
        }