public static GenericMenu GetPreferedTypesSelectionMenu(Type type, Action <Type> callback, bool showInterfaces = true, GenericMenu menu = null, string subCategory = null)
        {
            if (menu == null)
            {
                menu = new GenericMenu();
            }

            if (subCategory != null)
            {
                subCategory = subCategory + "/";
            }

            GenericMenu.MenuFunction2 Selected = delegate(object t){
                callback((Type)t);
            };

            var listTypes = new Dictionary <Type, string>();

            foreach (var t in UserTypePrefs.GetPreferedTypesList(typeof(object), true))
            {
                if (type.IsAssignableFrom(t) || (t.IsInterface && showInterfaces))
                {
                    var nsString    = string.IsNullOrEmpty(t.Namespace)? "No Namespace/" : (t.Namespace.Replace(".", "/") + "/");
                    var finalString = nsString + t.FriendlyName();
                    menu.AddItem(new GUIContent(subCategory + finalString), false, Selected, t);
                    // listTypes.Add( typeof(List<>).MakeGenericType(new Type[]{t}), finalString );
                    listTypes[typeof(List <>).MakeGenericType(new Type[] { t })] = finalString;
                }
            }

            //menu.AddSeparator(subCategory + "/");
            foreach (var tPair in listTypes)
            {
                menu.AddItem(new GUIContent(subCategory + "List<T>/" + tPair.Value), false, Selected, tPair.Key);
            }

            menu.AddItem(new GUIContent(subCategory + "Add Type..."), false, () => { PreferedTypesEditorWindow.ShowWindow(); });

            return(menu);
        }
        /// !* Providing an open GenericTypeDefinition for 'baseType', wraps the Preferred Types wihin the 1st Generic Argument of that Definition *!
        public static GenericMenu GetPreferedTypesSelectionMenu(Type baseType, Action <Type> callback, GenericMenu menu = null, string subCategory = null, bool showAddTypeOption = false)
        {
            if (menu == null)
            {
                menu = new GenericMenu();
            }

            if (subCategory != null)
            {
                subCategory = subCategory + "/";
            }

            var constrainType     = baseType;
            var isGeneric         = baseType.IsGenericTypeDefinition && baseType.GetGenericArguments().Length == 1;
            var genericDefinition = isGeneric? baseType : null;

            if (isGeneric)
            {
                var arg1       = genericDefinition.GetGenericArguments().First();
                var constrains = arg1.GetGenericParameterConstraints();
                constrainType = constrains.Length == 0? typeof(object) : constrains.First();
            }

            GenericMenu.MenuFunction2 Selected = delegate(object t){
                callback((Type)t);
            };

            var listTypes = new Dictionary <Type, string>();
            var dictTypes = new Dictionary <Type, string>();

            foreach (var t in UserTypePrefs.GetPreferedTypesList(constrainType, true))
            {
                var nsString    = t.NamespaceToPath() + "/";
                var finalType   = isGeneric? genericDefinition.MakeGenericType(t) : t;
                var finalString = nsString + finalType.FriendlyName();
                menu.AddItem(new GUIContent(subCategory + finalString), false, Selected, finalType);

                var listType      = typeof(List <>).MakeGenericType(t);
                var finalListType = isGeneric? genericDefinition.MakeGenericType(listType) : listType;
                if (constrainType.IsAssignableFrom(finalListType))
                {
                    listTypes[finalListType] = nsString;
                }

                var dictType      = typeof(Dictionary <,>).MakeGenericType(typeof(string), t);
                var finalDictType = isGeneric? genericDefinition.MakeGenericType(dictType) : dictType;
                if (constrainType.IsAssignableFrom(finalDictType))
                {
                    dictTypes[finalDictType] = nsString;
                }
            }

            foreach (var tPair in listTypes)
            {
                menu.AddItem(new GUIContent(subCategory + UserTypePrefs.LIST_MENU_STRING + tPair.Value + tPair.Key.FriendlyName()), false, Selected, tPair.Key);
            }

            foreach (var tPair in dictTypes)
            {
                menu.AddItem(new GUIContent(subCategory + UserTypePrefs.DICT_MENU_STRING + tPair.Value + tPair.Key.FriendlyName()), false, Selected, tPair.Key);
            }

            if (showAddTypeOption)
            {
                menu.AddItem(new GUIContent(subCategory + "Add Type..."), false, () => { PreferedTypesEditorWindow.ShowWindow(); });
            }

            return(menu);
        }