private bool ProcessElementAssignmentConflictCheck(ElementAssignmentChange entry) {
            Player player = ReInput.players.GetPlayer(entry.playerId);
            if(player == null) return true;
            if(entry.controllerMap == null) return true;
            if(entry.state == QueueEntry.State.Canceled) return true; // user canceled

            // Check for user confirmation
            if(entry.state == QueueEntry.State.Confirmed) {
                
                entry.changeType = ElementAssignmentChangeType.Add; // set the change type back to add before we add the assignment
                
                if(entry.response == UserResponse.Confirm) { // remove and add

                    ReInput.controllers.conflictChecking.RemoveElementAssignmentConflicts(entry.ToElementAssignmentConflictCheck()); // remove conflicts
                    entry.ReplaceOrCreateActionElementMap(); // create or replace the element

                } else if(entry.response == UserResponse.Custom1) { // add without removing

                    entry.ReplaceOrCreateActionElementMap(); // add the element

                } else throw new System.NotImplementedException();


                return true; // finished
            }

            // Do a detailed conflict check
            bool protectedConflictFound = false;
            foreach(ElementAssignmentConflictInfo info in ReInput.controllers.conflictChecking.ElementAssignmentConflicts(entry.ToElementAssignmentConflictCheck())) {
                // Check if this conflict is with a protected assignment
                if(!info.isUserAssignable) {
                    protectedConflictFound = true;
                    break;
                }
            }

            // Open a different dialog depending on if a protected conflict was found
            if(protectedConflictFound) {
                string message = entry.elementName + " is already in use and is protected from reassignment. You cannot remove the protected assignment, but you can still assign the action to this element. If you do so, the element will trigger multiple actions when activated.";

                // Create dialog and start waiting for user assignment
                dialog.StartModal(entry.id, DialogHelper.DialogType.AssignElement, new WindowProperties {
                    title = "Assignment Conflict",
                    message = message,
                    rect = GetScreenCenteredRect(defaultModalWidth, defaultModalHeight),
                    windowDrawDelegate = DrawElementAssignmentProtectedConflictWindow
                },
                DialogResultCallback);

            } else {
                string message = entry.elementName + " is already in use. You may replace the other conflicting assignments, add this assignment anyway which will leave multiple actions assigned to this element, or cancel this assignment.";

                // Create dialog and start waiting for user assignment
                dialog.StartModal(entry.id, DialogHelper.DialogType.AssignElement, new WindowProperties {
                    title = "Assignment Conflict",
                    message = message,
                    rect = GetScreenCenteredRect(defaultModalWidth, defaultModalHeight),
                    windowDrawDelegate = DrawElementAssignmentNormalConflictWindow
                },
                DialogResultCallback);

            }

            return false;
        }
        private bool ProcessAddOrReplaceElementAssignment(ElementAssignmentChange entry) {
            Player player = ReInput.players.GetPlayer(entry.playerId);
            if(player == null) return true;
            if(entry.controllerMap == null) return true;
            if(entry.state == QueueEntry.State.Canceled) return true; // user canceled

            // Check for user confirmation
            if(entry.state == QueueEntry.State.Confirmed) { // the action assignment has been confirmed
                if(Event.current.type != EventType.Layout) return false; // only make changes in layout to avoid GUI errors when new controls appear

                // Do a check for element assignment conflicts
                if(!ReInput.controllers.conflictChecking.DoesElementAssignmentConflict(entry.ToElementAssignmentConflictCheck())) {  // no conflicts
                    entry.ReplaceOrCreateActionElementMap(); // make the assignment, done

                } else { // we had conflicts
                    
                    // Enqueue a conflict check
                    ElementAssignmentChange newEntry = new ElementAssignmentChange(entry); // clone the entry
                    newEntry.changeType = ElementAssignmentChangeType.ConflictCheck; // set the new type to check for conflicts
                    actionQueue.Enqueue(newEntry); // enqueue the new entry
                }
                
                return true; // finished
            }

            // Customize the message for different controller types and different platforms
            string message;
            if(entry.controllerType == ControllerType.Keyboard) {

                if(Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.OSXPlayer || Application.platform == RuntimePlatform.OSXWebPlayer) {
                    message = "Press any key to assign it to this action. You may also use the modifier keys Command, Control, Alt, and Shift. If you wish to assign a modifier key ifselt this action, press and hold the key for 1 second.";
                } else {
                    message = "Press any key to assign it to this action. You may also use the modifier keys Control, Alt, and Shift. If you wish to assign a modifier key itself to this action, press and hold the key for 1 second.";
                }

                // Editor modifier key disclaimer
                if(Application.isEditor) {
                    message += "\n\nNOTE: Some modifier key combinations will not work in the Unity Editor, but they will work in a game build.";
                }

            } else if(entry.controllerType == ControllerType.Mouse) {
                message = "Press any mouse button or axis to assign it to this action.\n\nTo assign mouse movement axes, move the mouse quickly in the direction you want mapped to the action. Slow movements will be ignored.";
            } else {
                message = "Press any button or axis to assign it to this action.";
            }

            // Create dialog and start waiting for user assignment
            dialog.StartModal(entry.id, DialogHelper.DialogType.AssignElement, new WindowProperties {
                title = "Assign",
                message = message,
                rect = GetScreenCenteredRect(defaultModalWidth, defaultModalHeight),
                windowDrawDelegate = DrawElementAssignmentWindow
            },
            DialogResultCallback,
            assignmentTimeout);

            return false;
        }