public static void GenerateRegistrations <T>(EnvironmentState environmentState) where T : class, IRegistrations, new()
        {
            var reg  = new T();
            var info = reg.Create();
            var time = Time.realtimeSinceStartup;

            FilterRegistrations(info.Registrations, environmentState);
            GenerateRegisterCommand(info);

            var now  = Time.realtimeSinceStartup;
            var diff = now - time;

            Debug.Log(info.FilePath + " >>> " + diff);

            AssetDatabase.Refresh();
        }
        private static void FilterRegistrations(IList <RegistrationData> registrations, EnvironmentState state)
        {
            var typeMap = new Dictionary <Type, List <RegistrationData> >();

            foreach (var registration in registrations)
            {
                foreach (var interfaceType in registration.InterfaceTypes)
                {
                    var list = typeMap.Retrieve(interfaceType);
                    list.Add(registration);
                }
            }

            foreach (var pair in typeMap)
            {
                var targetType = pair.Key;
                var candidates = pair.Value;

                if (candidates.Count > 1)
                {
                    RegistrationData bestCandidate = null;
                    var maxRating = 0;

                    foreach (var candidate in candidates)
                    {
                        if (candidate.Platforms.Has(state.platform) &&
                            candidate.Editor.Has(state.editor) &&
                            candidate.Envs.Has(state.env) &&
                            candidate.Providers.Has(state.provider))
                        {
                            var rating = GetRating(state.editor, candidate);
                            Debug.Log("Rating for " + candidate.ClassType + ": " + rating);

                            if (rating >= maxRating)
                            {
                                maxRating     = rating;
                                bestCandidate = candidate;
                            }
//							else if (rating == maxRating && bestCandidate != candidate)
//							{
//								throw new Exception(candidate + " and " + bestCandidate + " have the same rating of " + rating);
//							}
                        }
                    }

                    if (bestCandidate == null)
                    {
                        throw new Exception("no suitable candidate for " + targetType);
                    }

                    candidates.Remove(bestCandidate);

                    foreach (var rejected in candidates)
                    {
                        registrations.Remove(rejected);
                    }
                }
            }
        }