internal static void MigrateUserSpecifiedPrefKeys(
            IEnumerable <MethodInfo> methodsWithFormerlyPrefKeyAs, List <ShortcutEntry> entries
            )
        {
            foreach (var method in methodsWithFormerlyPrefKeyAs)
            {
                var shortcutAttr =
                    Attribute.GetCustomAttribute(method, typeof(ShortcutAttribute), true) as ShortcutAttribute;
                if (shortcutAttr == null)
                {
                    continue;
                }

                var entry = entries.Find(e => string.Equals(e.identifier.path, shortcutAttr.identifier));
                // ignore former PrefKeys if the shortcut profile has already loaded and applied an override
                if (entry == null || entry.overridden)
                {
                    continue;
                }

                var prefKeyAttr =
                    (FormerlyPrefKeyAsAttribute)Attribute.GetCustomAttribute(method, typeof(FormerlyPrefKeyAsAttribute));
                var    prefKeyDefaultValue = $"{prefKeyAttr.name};{prefKeyAttr.defaultValue}";
                string name;
                Event  keyboardEvent;
                string shortcut;
                if (!PrefKey.TryParseUniquePrefString(prefKeyDefaultValue, out name, out keyboardEvent, out shortcut))
                {
                    continue;
                }
                var prefKeyDefaultKeyCombination = KeyCombination.FromPrefKeyKeyboardEvent(keyboardEvent);

                // Parse current pref key value (falling back on default pref key value)
                if (!PrefKey.TryParseUniquePrefString(EditorPrefs.GetString(prefKeyAttr.name, prefKeyDefaultValue), out name, out keyboardEvent, out shortcut))
                {
                    continue;
                }
                var prefKeyCurrentKeyCombination = KeyCombination.FromPrefKeyKeyboardEvent(keyboardEvent);

                // only migrate pref keys that the user actually overwrote
                if (!prefKeyCurrentKeyCombination.Equals(prefKeyDefaultKeyCombination))
                {
                    entry.SetOverride(new List <KeyCombination> {
                        prefKeyCurrentKeyCombination
                    });
                }
            }
        }
        void MigrateUserSpecifiedPrefKeys()
        {
            // If migration already happened then don't do anything
            if (EditorPrefs.GetBool(k_ProfileMigratedEditorPrefKey, false))
            {
                return;
            }

            EditorPrefs.SetBool(k_ProfileMigratedEditorPrefKey, true);

            // Find shortcut entries that might need to be migrated
            var allShortcuts = new List <ShortcutEntry>();

            directory.GetAllShortcuts(allShortcuts);

            // Find existing or create migrated profile and make it active so we can amend it
            var originalActiveProfile         = profileManager.activeProfile;
            var migratedProfile               = profileManager.GetProfileById(k_MigratedProfileId);
            var migratedProfileAlreadyExisted = migratedProfile != null;

            if (!migratedProfileAlreadyExisted)
            {
                migratedProfile = profileManager.CreateProfile(k_MigratedProfileId);
            }
            profileManager.activeProfile = migratedProfile;

            var migratedProfileModified = false;

            var tempKeyCombinations          = new KeyCombination[1];
            var methodsWithFormerlyPrefKeyAs = EditorAssemblies.GetAllMethodsWithAttribute <FormerlyPrefKeyAsAttribute>();

            foreach (var method in methodsWithFormerlyPrefKeyAs)
            {
                var shortcutAttr = Attribute.GetCustomAttribute(method, typeof(ShortcutAttribute), true) as ShortcutAttribute;
                if (shortcutAttr == null)
                {
                    continue;
                }

                var entry = allShortcuts.Find(e => string.Equals(e.identifier.path, shortcutAttr.identifier));
                if (entry == null)
                {
                    continue;
                }

                // Ignore former PrefKey if it is overriden in existing migrated profile
                if (entry.overridden)
                {
                    continue;
                }

                // Parse default pref key value from FormerlyPrefKeyAs attribute
                var    prefKeyAttr            = (FormerlyPrefKeyAsAttribute)Attribute.GetCustomAttribute(method, typeof(FormerlyPrefKeyAsAttribute));
                var    editorPrefDefaultValue = $"{prefKeyAttr.name};{prefKeyAttr.defaultValue}";
                string name;
                Event  keyboardEvent;
                string shortcut;
                if (!TryParseUniquePrefKeyString(editorPrefDefaultValue, out name, out keyboardEvent, out shortcut))
                {
                    continue;
                }
                var prefKeyDefaultKeyCombination = KeyCombination.FromPrefKeyKeyboardEvent(keyboardEvent);

                // Parse current pref key value (falling back on default pref key value)
                if (!TryParseUniquePrefKeyString(EditorPrefs.GetString(prefKeyAttr.name, editorPrefDefaultValue), out name, out keyboardEvent, out shortcut))
                {
                    continue;
                }
                var prefKeyCurrentKeyCombination = KeyCombination.FromPrefKeyKeyboardEvent(keyboardEvent);

                // Only migrate pref keys that the user actually overwrote
                if (prefKeyCurrentKeyCombination.Equals(prefKeyDefaultKeyCombination))
                {
                    continue;
                }

                string invalidBindingMessage;
                tempKeyCombinations[0] = prefKeyCurrentKeyCombination;
                if (!bindingValidator.IsBindingValid(tempKeyCombinations, out invalidBindingMessage))
                {
                    Debug.LogWarning($"Could not migrate existing binding for shortcut \"{entry.identifier.path}\" with invalid binding.\n{invalidBindingMessage}.");
                    continue;
                }

                profileManager.ModifyShortcutEntry(entry.identifier, new List <KeyCombination> {
                    prefKeyCurrentKeyCombination
                });

                migratedProfileModified = true;
            }

            // Delete migrated profile if it was created and not modified
            if (!migratedProfileAlreadyExisted && !migratedProfileModified)
            {
                profileManager.DeleteProfile(migratedProfile);
            }

            // Restore original active profile unless last loaded profile was null and the migrated profile was created
            if (originalActiveProfile != null || migratedProfileAlreadyExisted)
            {
                profileManager.activeProfile = originalActiveProfile;
            }
        }