/// <summary>
        /// Gets all updates for InspectorPreferences.
        /// Update files should be located in the same directory as the PreferencesAsset inside
        /// a folder named "Updates"
        /// </summary>
        /// <param name="preferences"></param>
        /// <returns></returns>
        public static InspectorPreferencesUpdate[] GetAllUpdates([NotNull] InspectorPreferences preferences)
        {
            var preferencesPath = AssetDatabase.GetAssetPath(preferences);
            var directoryPath   = FileUtility.GetParentDirectory(preferencesPath);

            directoryPath = FileUtility.GetChildDirectory(directoryPath, "Updates");

            if (!AssetDatabase.IsValidFolder(directoryPath))
            {
                                #if DEV_MODE
                Debug.LogWarning(preferences.name + " had no Updates folder next to it.");
                                #endif
                return(ArrayPool <InspectorPreferencesUpdate> .ZeroSizeArray);
            }

            var updateGuids = AssetDatabase.FindAssets("t:InspectorPreferencesUpdate", ArrayExtensions.TempStringArray(directoryPath));
            int count       = updateGuids.Length;
            var results     = new InspectorPreferencesUpdate[count];

            for (int n = updateGuids.Length - 1; n >= 0; n--)
            {
                var updatePath = AssetDatabase.GUIDToAssetPath(updateGuids[n]);
                results[n] = AssetDatabase.LoadAssetAtPath <InspectorPreferencesUpdate>(updatePath);
            }

            return(results);
        }
        public bool OnGUI(ref bool addedComponent)
        {
            bool dirty = false;

            var e         = Event.current;
            var eventType = e.type;

            switch (eventType)
            {
            case EventType.KeyDown:
                if (OnKeyboardInputGiven(e))
                {
                    return(true);
                }
                break;

            case EventType.MouseDown:
            case EventType.MouseMove:
                dirty = true;
                break;

            case EventType.Layout:
                if (goBackLevelNextLayout)
                {
                    goBackLevelNextLayout = false;
                    GoBackLevel();
                }
                                        #if UNITY_EDITOR
                else if (openCreateNewScriptViewNextLayout)
                {
                    openCreateNewScriptViewNextLayout = false;

                    string inNamespace = null;
                    string saveIn      = null;
                    if (activeItem != null)
                    {
                        var type = activeItem.TypeOrAnyChildType();
                        if (type != null)
                        {
                            var existingScript = FileUtility.FindScriptFile(type);
                            if (existingScript != null)
                            {
                                inNamespace = type.Namespace;
                                saveIn      = FileUtility.GetParentDirectory(UnityEditor.AssetDatabase.GetAssetPath(existingScript));
                            }
                        }
                    }

                    if (inNamespace == null)
                    {
                        inNamespace = InspectorUtility.Preferences.defaultNamespace;
                    }

                    if (saveIn == null)
                    {
                        saveIn = InspectorUtility.Preferences.defaultScriptPath;
                    }

                    if (filter.Length > 0)
                    {
                        Platform.Active.SetPrefs("PI.CreateScriptWizard/Name", filter);
                    }
                    Platform.Active.SetPrefs("PI.CreateScriptWizard/Namespace", inNamespace);
                    Platform.Active.SetPrefs("PI.CreateScriptWizard/SaveIn", saveIn);

                    Platform.Active.SetPrefs("PI.CreateScriptWizard/Template", "MonoBehaviour");
                    Platform.Active.SetPrefs("PI.CreateScriptWizard/AttachTo", target.UnityObject.GetInstanceID());

                    inspector.OnNextLayout(() => DrawGUI.ExecuteMenuItem(PowerInspectorMenuItemPaths.CreateScriptWizardFromCreateMenu));

                    Close();
                    return(true);
                }
                                        #endif
                else if (clearTextNextLayout)
                {
                    clearTextNextLayout = false;
                    ClearText();
                }
                break;
            }

            if (Draw(ref addedComponent))
            {
                dirty = true;
            }

            return(dirty);
        }
        public void ResetToDefaults()
        {
            UndoHandler.RegisterUndoableAction(this, "Reset To Defaults");

                        #if UNITY_EDITOR          // in UnityEditor use Presets or EditorJsonUtility
                        #if UNITY_2018_1_OR_NEWER // Presets were introduced in Unity 2018.1
                        #if UNITY_2019_3_OR_NEWER // GetDefaultForObject became obsolete in Unity 2019.3
            var presets = Preset.GetDefaultPresetsForObject(this);
            var preset  = presets.Length > 0 ? presets[0] : null;
                        #else
            var preset = Preset.GetDefaultForObject(this);
                        #endif

            // if no default preset has been assigned for preferences asset, then try finding a preset
            // in the same directory with the preferences asset
            if (preset == null)
            {
                var preferencesPath = AssetDatabase.GetAssetPath(this);
                var directoryPath   = FileUtility.GetParentDirectory(preferencesPath);
                var updateGuids     = AssetDatabase.FindAssets("t:Preset", ArrayExtensions.TempStringArray(directoryPath));
                for (int n = updateGuids.Length - 1; n >= 0; n--)
                {
                    var path = AssetDatabase.GUIDToAssetPath(updateGuids[n]);
                    preset = AssetDatabase.LoadAssetAtPath <Preset>(path);
                    if (!string.Equals(preset.GetTargetFullTypeName(), typeof(InspectorPreferences).FullName, StringComparison.OrdinalIgnoreCase))
                    {
                        preset = null;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            if (preset != null)
            {
                preset.ApplyTo(this);
            }
            else
                        #endif
            {
                var freshInstance = CreateInstance <InspectorPreferences>();
                var jsonString    = EditorJsonUtility.ToJson(freshInstance);
                Platform.Active.Destroy(freshInstance);
                EditorJsonUtility.FromJsonOverwrite(jsonString, this);
            }
                        #else
            // at runtime use JsonUtility to reset values to those of a freshly created instance
            var freshInstance = CreateInstance <InspectorPreferences>();
            var jsonString    = JsonUtility.ToJson(freshInstance);
            Platform.Active.Destroy(freshInstance);
            JsonUtility.FromJsonOverwrite(jsonString, this);
                        #endif

            setupDone         = false;
            isFirstOnValidate = true;

            if (Event.current != null)
            {
                Setup();
            }

            Platform.Active.SetDirty(this);

            if (onSettingsChanged != null)
            {
                onSettingsChanged(this);
            }
        }