private bool SupportedPluginsGUI(AbstractPluginDefinition.PluginCategory category)
        {
            List <AbstractPluginDefinition> plugins;

            try
            {
                plugins = supportedPluginsCache[category];
                if (plugins.Count > 0)
                {
                    EditorGUILayout.BeginVertical("Box");


                    float columnWidth = EditorGUIUtility.currentViewWidth / 3;
                    EditorGUILayout.LabelField("Supported but not installed");
                    foreach (AbstractPluginDefinition defn in supportedPluginsCache[category])
                    {
                        if (GUILayout.Button("Learn more about " + defn.GetReadableName() + "... "))
                        {
                            Application.OpenURL(defn.GetURL());
                        }
                    }

                    EditorGUILayout.EndVertical();
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            catch (KeyNotFoundException e)
            {
                return(false);
            }
        }
        private bool AvailablePluginsGUI(AbstractPluginDefinition.PluginCategory category)
        {
            List <AbstractPluginDefinition> plugins;

            try
            {
                plugins = availablePluginsCache[category];
                if (plugins.Count > 0)
                {
                    EditorGUILayout.LabelField("Available for use");
                    for (int i = availablePluginsCache[category].Count - 1; i >= 0; i--)
                    {
                        AbstractPluginDefinition defn = availablePluginsCache[category][i];

                        EditorGUILayout.BeginHorizontal();
                        EditorGUI.indentLevel++;

                        float columnWidth = EditorGUIUtility.currentViewWidth / 3;
                        EditorGUILayout.LabelField(defn.GetReadableName(), GUILayout.Width(columnWidth));

                        bool hasManager = manager.gameObject.GetComponentInChildren(defn.GetManagerType()) != null;
                        if (!hasManager || defn.MultipleAllowed)
                        {
                            if (GUILayout.Button("Enable"))
                            {
                                defn.Enable();
                                timeOfNextPluginRefresh = DateTime.Now;
                                UpdateAllPluginDefinitions();
                            }
                            if (GUILayout.Button("Learn more"))
                            {
                                Application.OpenURL(defn.GetURL());
                            }
                        }

                        EditorGUI.indentLevel--;
                        EditorGUILayout.EndHorizontal();
                    }
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            catch (KeyNotFoundException e)
            {
                return(false);
            }
        }
        private bool EnabledPluginsGUI(AbstractPluginDefinition.PluginCategory category)
        {
            try {
                if (enabledPluginsCache[category].Count > 0)
                {
                    GUILayout.Label("Currently Enabled");
                    for (int i = enabledPluginsCache[category].Count - 1; i >= 0; i--)
                    {
                        AbstractPluginDefinition defn = enabledPluginsCache[category][i];

                        Component pluginManager = manager.gameObject.GetComponentsInChildren(defn.GetManagerType())[i];

                        EditorGUILayout.BeginHorizontal();
                        EditorGUI.indentLevel++;

                        float columnWidth = EditorGUIUtility.currentViewWidth / 3;
                        EditorGUILayout.LabelField(pluginManager.name + " (" + defn.GetReadableName() + ")", GUILayout.Width(columnWidth));

                        if (GUILayout.Button("Disable"))
                        {
                            DestroyImmediate(pluginManager.gameObject);
                            timeOfNextPluginRefresh = DateTime.Now;
                            UpdateAllPluginDefinitions();
                        }
                        if (GUILayout.Button("Learn more"))
                        {
                            Application.OpenURL(defn.GetURL());
                        }

                        EditorGUI.indentLevel--;
                        EditorGUILayout.EndHorizontal();
                    }
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            catch (KeyNotFoundException e)
            {
                return(false);
            }
        }
        /// <summary>
        /// Find all the plugins of a a given type known to the system and display
        /// a UI for working with them.
        /// </summary>
        /// <param name="category">The AbstractPluginDefinition.PluginCategory of plugins to display in the GUI</param>
        private void PluginSelectionGUI(AbstractPluginDefinition.PluginCategory category)
        {
            GUILayout.BeginVertical("Box");
            string categoryName = category.ToString().Prettify();

            GUILayout.Label(categoryName + " Plugins", EditorStyles.boldLabel);

            GUILayout.BeginVertical("Box");
            bool displayedAtLeastOne = EnabledPluginsGUI(category);

            displayedAtLeastOne |= AvailablePluginsGUI(category);
            displayedAtLeastOne |= SupportedPluginsGUI(category);


            if (!displayedAtLeastOne)
            {
                EditorGUILayout.LabelField("Cannot find any plugins in this category.");
            }

            GUILayout.EndVertical();

            GUILayout.EndVertical();
        }