/// <summary>
        /// Returns the "pretty" name of this <see cref="MemberInfo"/> (including the full type-name)
        /// and also return the member-type (if any) into <b>prefix</b> and method-parameters (if any) into <b>postfix</b>
        /// </summary>
        /// <param name="member">Type-member to get the name of</param>
        /// <param name="memberKind">Receives the member-kind, this member represents</param>
        /// <param name="prefix">Receives the field/property-type or method return-type</param>
        /// <param name="postfix">Receives the method-parameters, if this member is a method</param>
        /// <returns>The full name of this member or null if this member is compiler-generated</returns>
        /// <remarks>
        /// Properties and events in .NET are actually methods with a special naming-convention.
        /// (i.e. get_<b>Name</b> / set_<b>Name</b> for properties and add_<b>Name</b> / remove_<b>Name</b> for events)
        /// As we're not interested in these methods, but in the properties/events they represent,
        /// we detect these methods here and return the name of the property/event instead while setting <b>memberKind</b> accordingly
        /// </remarks>
        public static string GetPrettyName(this MemberInfo member, out SymbolKind memberKind, out string prefix, out string postfix)
        {
            memberKind = SymbolKind.SYMBOL_FIELD;
            prefix     = "";
            postfix    = "";
            if (member.Name.Contains("<") || member.IsMemberOfCompilerGeneratedClass())  // compiler-generated
            {
                return(null);
            }

            if (member is ConstructorInfo ctor)
            {
                memberKind = SymbolKind.SYMBOL_METHOD;
                prefix     = ctor.GetModifiers();
                if (ctor.IsGenericMethod)
                {
                    postfix += "<"
                               + string.Join(", ", ctor.GetGenericArguments()
                                             .Select(a => NameHelper.TranslateTypeName(a, true)))
                               + ">";
                }
                postfix += SerializeParameters(ctor.GetParameters());
                return(ctor.DeclaringType.GetPrettyName() + ctor.Name);
            }
            if (member is MethodInfo method)
            {
                // method generated by compiler (i.e. lambdas) ?
                var match = rxInternName.Match(method.Name);
                if (match.Success)
                {
                    if (member.DeclaringType.DeclaringType != null)
                    {
                        Debug.Assert(false, "Checkme");
                    }
                    var name = match.Groups["name"].Value;
                    // map getter/setter to correct property/event
                    if (IsPropertyOrEventMethod(method, name, out prefix, out string propertyOrEventName))
                    {
                        return(method.DeclaringType.GetPrettyName() + "." + propertyOrEventName);
                    }
                    else
                    {
                        foreach (var meth in method.DeclaringType.GetMethods(flags))
                        {
                            if (meth.Name == name)
                            {
                                if (meth.DeclaringType.Name.Contains("<"))
                                {
                                    Debug.Assert(false, "Checkme");
                                }
                                memberKind = SymbolKind.SYMBOL_METHOD;
                                prefix     = meth.GetModifiers() + meth.ReturnType.GetPrettyName();
                                return(meth.DeclaringType.GetPrettyName() + "." + meth.Name);
                            }
                        }
                        Debug.Assert(false, "Method not found");
                    }
                }
                else
                {
                    // regular method
                    var name = method.Name;
                    // map getter/setter to correct property/event
                    if (IsPropertyOrEventMethod(method, name, out prefix, out string propertyOrEventName))
                    {
                        return(method.DeclaringType.GetPrettyName() + "." + propertyOrEventName);
                    }
                    else
                    {
                        memberKind = SymbolKind.SYMBOL_METHOD;
                        prefix     = method.GetModifiers() + NameHelper.TranslateTypeName(method.ReturnType);
                        if (method.IsGenericMethod)
                        {
                            postfix += "<" + string.Join(", ", method.GetGenericArguments().Select(a => NameHelper.TranslateTypeName(a, true))) + ">";
                        }
                        postfix += SerializeParameters(method.GetParameters());
                        return(method.DeclaringType.GetPrettyName() + "." + method.Name);
                    }
                }
            }
            else if (member is PropertyInfo property)
            {
                if (member.DeclaringType.Name.Contains("<"))
                {
                    return(null);
                }
                prefix = property.GetModifiers() + property.PropertyType.GetPrettyName();
                return(property.DeclaringType.GetPrettyName() + "." + property.Name);
            }
            else if (member is FieldInfo field)
            {
                // ignore auto-generated backing fields for properties
                if (member.DeclaringType.Name.Contains("<") || field.Name.StartsWith("<"))
                {
                    return(null);
                }
                prefix = field.GetModifiers() + field.FieldType.GetPrettyName();
                return(field.DeclaringType.GetPrettyName() + "." + field.Name);
            }
            else if (member is EventInfo eventInfo)
            {
                if (member.DeclaringType.Name.Contains("<"))
                {
                    return(null);
                }
                prefix = eventInfo.GetModifiers() + eventInfo.EventHandlerType.GetPrettyName();
                return(eventInfo.DeclaringType.GetPrettyName() + "." + eventInfo.Name);
            }
            else if (member is TypeInfo nestedType)
            {
                if (nestedType.Name.Contains("<"))
                {
                    return(null);
                }
                memberKind = SymbolKind.SYMBOL_CLASS;
                return(nestedType.DeclaringType.GetPrettyName() + "." + nestedType.Name);
            }
            return(null);
        }
 /// <summary>
 /// Returns the "pretty" name of this <see cref="Type"/>
 /// </summary>
 public static string GetPrettyName(this Type type)
 {
     return(NameHelper.TranslateTypeName(type));
 }