public void ProcessFunctionKey(FunctionKeys functionKey)
        {
            Log.DebugFormat("Processing captured function key '{0}'", functionKey);

            lastTextChangeWasSuggestion = false;

            switch (functionKey)
            {
            case FunctionKeys.BackMany:
                if (!string.IsNullOrEmpty(Text))
                {
                    var backManyCount = Text.CountBackToLastCharCategoryBoundary();

                    dictionaryService.DecrementEntryUsageCount(Text.Substring(Text.Length - backManyCount, backManyCount).Trim());

                    var textAfterBackMany     = Text.Substring(0, Text.Length - backManyCount);
                    var textChangedByBackMany = Text != textAfterBackMany;
                    Text = textAfterBackMany;

                    if (backManyCount == 0)
                    {
                        backManyCount = 1;                         //Always publish at least one backspace
                    }
                    for (int i = 0; i < backManyCount; i++)
                    {
                        PublishKeyPress(FunctionKeys.BackOne);
                        ReleaseUnlockedKeys();
                    }

                    if (textChangedByBackMany ||
                        string.IsNullOrEmpty(Text))
                    {
                        AutoPressShiftIfAppropriate();
                    }

                    StoreLastTextChange(null);
                    GenerateAutoCompleteSuggestions();

                    Log.Debug("Suppressing next auto space.");
                    suppressNextAutoSpace = true;
                }
                else
                {
                    //Scratchpad is empty, but publish 1 backspace anyway, as per the behaviour for 'BackOne'
                    PublishKeyPress(FunctionKeys.BackOne);
                }
                break;

            case FunctionKeys.BackOne:
                var backOneCount = string.IsNullOrEmpty(lastTextChange)
                        ? 1 //Default to removing one character if no lastTextChange
                        : lastTextChange.Length;

                var textChangedByBackOne = false;

                if (!string.IsNullOrEmpty(Text))
                {
                    if (Text.Length < backOneCount)
                    {
                        backOneCount = Text.Length;     //Coallesce backCount if somehow the Text length is less
                    }

                    var textAfterBackOne = Text.Substring(0, Text.Length - backOneCount);
                    textChangedByBackOne = Text != textAfterBackOne;

                    if (backOneCount > 1)
                    {
                        //Removing more than one character - only decrement removed string
                        dictionaryService.DecrementEntryUsageCount(Text.Substring(Text.Length - backOneCount, backOneCount).Trim());
                    }
                    else if (!string.IsNullOrEmpty(lastTextChange) &&
                             lastTextChange.Length == 1 &&
                             !char.IsWhiteSpace(lastTextChange[0]))
                    {
                        dictionaryService.DecrementEntryUsageCount(Text.InProgressWord(Text.Length));             //We are removing a non-whitespace character - decrement the in progress word
                        dictionaryService.IncrementEntryUsageCount(textAfterBackOne.InProgressWord(Text.Length)); //And increment the in progress word that is left after the removal
                    }

                    Text = textAfterBackOne;
                }

                for (int i = 0; i < backOneCount; i++)
                {
                    PublishKeyPress(FunctionKeys.BackOne);
                    ReleaseUnlockedKeys();
                }

                if (textChangedByBackOne ||
                    string.IsNullOrEmpty(Text))
                {
                    AutoPressShiftIfAppropriate();
                }

                StoreLastTextChange(null);
                GenerateAutoCompleteSuggestions();

                Log.Debug("Suppressing next auto space.");
                suppressNextAutoSpace = true;
                break;

            case FunctionKeys.ClearScratchpad:
                Text = null;
                StoreLastTextChange(null);
                ClearSuggestions();
                AutoPressShiftIfAppropriate();
                Log.Debug("Suppressing next auto space.");
                suppressNextAutoSpace = true;
                break;

            case FunctionKeys.Suggestion1:
                SwapLastTextChangeForSuggestion(0);
                lastTextChangeWasSuggestion = true;
                break;

            case FunctionKeys.Suggestion2:
                SwapLastTextChangeForSuggestion(1);
                lastTextChangeWasSuggestion = true;
                break;

            case FunctionKeys.Suggestion3:
                SwapLastTextChangeForSuggestion(2);
                lastTextChangeWasSuggestion = true;
                break;

            case FunctionKeys.Suggestion4:
                SwapLastTextChangeForSuggestion(3);
                lastTextChangeWasSuggestion = true;
                break;

            case FunctionKeys.Suggestion5:
                SwapLastTextChangeForSuggestion(4);
                lastTextChangeWasSuggestion = true;
                break;

            case FunctionKeys.Suggestion6:
                SwapLastTextChangeForSuggestion(5);
                lastTextChangeWasSuggestion = true;
                break;

            default:
                if (functionKey.ToVirtualKeyCode() != null)
                {
                    //Key corresponds to physical keyboard key
                    GenerateAutoCompleteSuggestions();

                    //If the key cannot be pressed or locked down (these are handled in
                    //ReactToPublishableKeyDownStateChanges) then publish it and release unlocked keys
                    var keyValue = new KeyValue(functionKey);
                    if (!KeyValues.KeysWhichCanBePressedOrLockedDown.Contains(keyValue))
                    {
                        PublishKeyPress(functionKey);
                        ReleaseUnlockedKeys();
                    }
                }

                if (functionKey == FunctionKeys.LeftShift)
                {
                    shiftStateSetAutomatically = false;
                }
                break;
            }
        }