private static List <Type> GetFilteredTypes(ClassTypeConstraintAttribute filter)
        {
            var types = new List <Type>();

            var excludedTypes = (ExcludedTypeCollectionGetter != null ? ExcludedTypeCollectionGetter() : null);

            foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
            {
                FilterTypes(asm, filter, excludedTypes, types);
            }

            //var assembly = Assembly.GetExecutingAssembly();
            //FilterTypes(assembly, filter, excludedTypes, types);

            //foreach (var referencedAssembly in assembly.GetReferencedAssemblies())
            //	FilterTypes(Assembly.Load(referencedAssembly), filter, excludedTypes, types);

            types.Sort((a, b) => a.FullName.CompareTo(b.FullName));

            return(types);
        }
        private static void FilterTypes(Assembly assembly, ClassTypeConstraintAttribute filter, ICollection <Type> excludedTypes, List <Type> output)
        {
            foreach (var type in assembly.GetTypes())
            {
                if (!type.IsVisible || !type.IsClass)
                {
                    continue;
                }

                if (filter != null && !filter.IsConstraintSatisfied(type))
                {
                    continue;
                }

                if (excludedTypes != null && excludedTypes.Contains(type))
                {
                    continue;
                }

                output.Add(type);
            }
        }
        private static void DrawTypeSelectionControl(Rect position, SerializedProperty property, GUIContent label, ClassTypeConstraintAttribute filter)
        {
            try {
                bool restoreShowMixedValue = EditorGUI.showMixedValue;
                EditorGUI.showMixedValue = property.hasMultipleDifferentValues;

                property.stringValue = DrawTypeSelectionControl(position, label, property.stringValue, filter);

                EditorGUI.showMixedValue = restoreShowMixedValue;
            }
            finally {
                ExcludedTypeCollectionGetter = null;
            }
        }
        private static string DrawTypeSelectionControl(Rect position, GUIContent label, string classRef, ClassTypeConstraintAttribute filter)
        {
            if (label != null && label != GUIContent.none)
            {
                position = EditorGUI.PrefixLabel(position, label);
            }

            int controlID = GUIUtility.GetControlID(s_ControlHint, FocusType.Keyboard, position);

            bool triggerDropDown = false;

            switch (Event.current.GetTypeForControl(controlID))
            {
            case EventType.ExecuteCommand:
                if (Event.current.commandName == "TypeReferenceUpdated")
                {
                    if (s_SelectionControlID == controlID)
                    {
                        if (classRef != s_SelectedClassRef)
                        {
                            classRef    = s_SelectedClassRef;
                            GUI.changed = true;
                        }

                        s_SelectionControlID = 0;
                        s_SelectedClassRef   = null;
                    }
                }
                break;

            case EventType.MouseDown:
                if (GUI.enabled && position.Contains(Event.current.mousePosition))
                {
                    GUIUtility.keyboardControl = controlID;
                    triggerDropDown            = true;
                    Event.current.Use();
                }
                break;

            case EventType.KeyDown:
                if (GUI.enabled && GUIUtility.keyboardControl == controlID)
                {
                    if (Event.current.keyCode == KeyCode.Return || Event.current.keyCode == KeyCode.Space)
                    {
                        triggerDropDown = true;
                        Event.current.Use();
                    }
                }
                break;

            case EventType.Repaint:
                // Remove assembly name from content of popup control.
                var classRefParts = classRef.Split(',');

                s_TempContent.text = classRefParts[0].Trim();
                if (s_TempContent.text == "")
                {
                    s_TempContent.text = "(None)";
                }
                else if (ResolveType(classRef) == null)
                {
                    s_TempContent.text += " {Missing}";
                }

                EditorStyles.popup.Draw(position, s_TempContent, controlID);
                break;
            }

            if (triggerDropDown)
            {
                s_SelectionControlID = controlID;
                s_SelectedClassRef   = classRef;

                var filteredTypes = GetFilteredTypes(filter);
                DisplayDropDown(position, filteredTypes, ResolveType(classRef), filter.Grouping);
            }

            return(classRef);
        }