static BuildSettingsSearcherDatabase Populate <T>(HashSet <Type> types, Func <Type, string> displayNameResolver)
        {
            var list = new List <SearcherItem>();
            var dict = new Dictionary <string, SearcherItem>();

            var collection = TypeCache.GetTypesDerivedFrom <T>();

            foreach (var type in collection)
            {
                if (type.IsGenericType || type.IsAbstract || type.ContainsGenericParameters || type.IsInterface)
                {
                    continue;
                }

                if (!TypeConstruction.HasParameterLessConstructor(type))
                {
                    continue;
                }

                try
                {
                    if (types.Contains(type))
                    {
                        continue;
                    }

                    var category = string.Empty;
                    TypeSearcherItem typeItem = null;

                    // Fully type-based
                    if (null == displayNameResolver)
                    {
                        typeItem = new TypeSearcherItem(type);
                        category = type.Namespace ?? "Global";
                    }
                    // We control the naming
                    else
                    {
                        var displayName = displayNameResolver.Invoke(type);
                        var prefixIndex = displayName.IndexOf("/", StringComparison.InvariantCultureIgnoreCase);
                        category = prefixIndex >= 0 ? displayName.Substring(0, prefixIndex) : "Other";
                        var name = displayName.Substring(prefixIndex >= 0 ? prefixIndex + 1 : 0);
                        typeItem = new TypeSearcherItem(type, name);
                    }

                    if (!dict.TryGetValue(category, out var item))
                    {
                        dict[category] = item = new SearcherItem(category);
                        list.Add(item);
                    }

                    item.AddChild(typeItem);
                }
                catch (Exception)
                {
                    // ignored
                }
            }

            foreach (var kvp in dict)
            {
                kvp.Value.Children.Sort(CompareByName);
            }

            list.Sort(CompareByName);

            return(new BuildSettingsSearcherDatabase(list));
        }