// We have three ways that cause the input system to be initialized:
        // 1. Normal game/editor startup.
        // 2. Domain reload in editor (after script changes or when entering playmode).
        // 3. Manual Reset() from tests.
        //
        // 1 is initiated from InitializeOnLoad on editor startup and from RuntimeInitializeOnLoadMethod
        // in the player.
        //
        // 2 is initiated from RuntimeInitializeOnLoadMethod both in the editor and in the player. However,
        // InitializeOnLoad will *also* trigger in the editor.
        //
        // 3 is triggered from the Reset() method below.

        static InputSystem()
        {
#if UNITY_EDITOR
            // This gets run after every appdomain initialization. If it's a domain reload,
            // we probably have an InputSystemManager sticking around from before.
            //
            // NOTE: InitializeOnLoad in the editor will get executed *before* heap state is
            //       restored, so it is paramount that we do not attempt to access any of the
            //       serialized state until after OnEnable() has been called on InputSystemManager.
            InputSystemManager[] array = Resources.FindObjectsOfTypeAll <InputSystemManager>();
            s_Input = array.Length > 0 ? array[0] : null;
#endif
            if (s_Input == null)
            {
                Reset();
            }
        }
        internal static void Reset()
        {
            // Grab the manager for native devices as we want those to survive the reset.
            NativeInputDeviceManager oldNativeDeviceManager = null;

            if (s_Input != null)
            {
                oldNativeDeviceManager = s_Input.nativeDeviceManager;
            }

            // Also, we want all profiles to survive the reset.
            InputDeviceProfileManager oldProfileManager = null;

            if (s_Input != null)
            {
                oldProfileManager = s_Input.profileManager;
            }

            // And we want no native events still going to the old native event manager.
            if (s_Input != null)
            {
                s_Input.nativeEventManager.Uninitialize();
            }

            // Create blank input system state.
            s_Input           = ScriptableObject.CreateInstance <InputSystemManager>();
            s_Input.hideFlags = HideFlags.HideAndDontSave;

            // Hand existing profiles over to the new profile manager. We can't simply replace
            // the profile manager with the old one because InputSystemManager has already wired
            // up state using the new profile manager.
            if (oldProfileManager != null)
            {
                s_Input.profileManager.StealProfilesFrom(oldProfileManager);
            }

            // Recreate native devices, if we had them before.
            if (oldNativeDeviceManager != null)
            {
                s_Input.nativeDeviceManager.RecreateNativeDevicesFrom(oldNativeDeviceManager);
                oldNativeDeviceManager.Uninitialize();
            }
        }