public void Undo()
        {
            TextWidgetUndoData undoData = (TextWidgetUndoData)undoBuffer.GetPrevUndoObject();

            if (undoData != null)
            {
                undoData.ExtractData(this);
                FixBarPosition(DesiredXPositionOnLine.Set);
            }
        }
        public override void OnKeyDown(KeyEventArgs keyEvent)
        {
            RestartBarFlash();

            bool SetDesiredBarPosition = true;
            bool turnOffSelection      = false;

            if (!ShiftKeyIsDown(keyEvent))
            {
                if (keyEvent.Control)
                {
                    // don't let control keys get into the stream
                    keyEvent.SuppressKeyPress = true;
                    keyEvent.Handled          = true;
                }
                else if (Selecting)
                {
                    turnOffSelection = true;
                }
            }

            switch (keyEvent.KeyCode)
            {
            case Keys.Escape:
                if (Selecting)
                {
                    turnOffSelection          = true;
                    keyEvent.SuppressKeyPress = true;
                    keyEvent.Handled          = true;
                }
                break;

            case Keys.Left:
                StartSelectionIfRequired(keyEvent);
                if (keyEvent.Control)
                {
                    GotoBeginingOfPreviousToken();
                }
                else if (CharIndexToInsertBefore > 0)
                {
                    if (turnOffSelection)
                    {
                        CharIndexToInsertBefore = Math.Min(CharIndexToInsertBefore, SelectionIndexToStartBefore);
                    }
                    else
                    {
                        CharIndexToInsertBefore--;
                    }
                }
                keyEvent.SuppressKeyPress = true;
                keyEvent.Handled          = true;
                break;

            case Keys.Right:
                StartSelectionIfRequired(keyEvent);
                if (keyEvent.Control)
                {
                    GotoBeginingOfNextToken();
                }
                else if (CharIndexToInsertBefore < internalTextWidget.Text.Length)
                {
                    if (turnOffSelection)
                    {
                        CharIndexToInsertBefore = Math.Max(CharIndexToInsertBefore, SelectionIndexToStartBefore);
                    }
                    else
                    {
                        CharIndexToInsertBefore++;
                    }
                }
                keyEvent.SuppressKeyPress = true;
                keyEvent.Handled          = true;
                break;

            case Keys.Up:
                StartSelectionIfRequired(keyEvent);
                if (turnOffSelection)
                {
                    CharIndexToInsertBefore = Math.Min(CharIndexToInsertBefore, SelectionIndexToStartBefore);
                }
                GotoLineAbove();
                SetDesiredBarPosition     = false;
                keyEvent.SuppressKeyPress = true;
                keyEvent.Handled          = true;
                break;

            case Keys.Down:
                StartSelectionIfRequired(keyEvent);
                if (turnOffSelection)
                {
                    CharIndexToInsertBefore = Math.Max(CharIndexToInsertBefore, SelectionIndexToStartBefore);
                }
                GotoLineBelow();
                SetDesiredBarPosition     = false;
                keyEvent.SuppressKeyPress = true;
                keyEvent.Handled          = true;
                break;

            case Keys.Space:
                keyEvent.Handled = true;
                break;

            case Keys.End:
                StartSelectionIfRequired(keyEvent);
                if (keyEvent.Control)
                {
                    CharIndexToInsertBefore = internalTextWidget.Text.Length;
                }
                else
                {
                    GotoEndOfCurrentLine();
                }

                keyEvent.SuppressKeyPress = true;
                keyEvent.Handled          = true;
                break;

            case Keys.Home:
                StartSelectionIfRequired(keyEvent);
                if (keyEvent.Control)
                {
                    CharIndexToInsertBefore = 0;
                }
                else
                {
                    GotoStartOfCurrentLine();
                }

                keyEvent.SuppressKeyPress = true;
                keyEvent.Handled          = true;
                break;

            case Keys.Back:
                if (!Selecting &&
                    CharIndexToInsertBefore > 0)
                {
                    SelectionIndexToStartBefore = CharIndexToInsertBefore - 1;
                    Selecting = true;
                }

                DeleteSelection();

                keyEvent.Handled          = true;
                keyEvent.SuppressKeyPress = true;
                break;

            case Keys.Delete:
                if (ShiftKeyIsDown(keyEvent))
                {
                    CopySelection();
                    DeleteSelection();
                    keyEvent.Handled          = true;
                    keyEvent.SuppressKeyPress = true;
                }
                else
                {
                    if (!Selecting &&
                        CharIndexToInsertBefore < internalTextWidget.Text.Length)
                    {
                        SelectionIndexToStartBefore = CharIndexToInsertBefore + 1;
                        Selecting = true;
                    }

                    DeleteSelection();
                }

                turnOffSelection          = true;
                keyEvent.Handled          = true;
                keyEvent.SuppressKeyPress = true;
                break;

            case Keys.Enter:
                if (!Multiline)
                {
                    // TODO: do the right thing.
                    keyEvent.Handled          = true;
                    keyEvent.SuppressKeyPress = true;

                    if (EnterPressed != null)
                    {
                        EnterPressed(this, keyEvent);
                    }

                    if (TextHasChanged())
                    {
                        OnEditComplete(keyEvent);
                    }
                }
                break;

            case Keys.Insert:
                if (ShiftKeyIsDown(keyEvent))
                {
                    turnOffSelection = true;
                    PasteFromClipboard();
                    keyEvent.Handled          = true;
                    keyEvent.SuppressKeyPress = true;
                }
                if (keyEvent.Control)
                {
                    turnOffSelection = false;
                    CopySelection();
                    keyEvent.Handled          = true;
                    keyEvent.SuppressKeyPress = true;
                }
                break;

            case Keys.A:
                if (keyEvent.Control)
                {
                    SelectAll();
                    keyEvent.Handled          = true;
                    keyEvent.SuppressKeyPress = true;
                }
                break;

            case Keys.X:
                if (keyEvent.Control)
                {
                    CopySelection();
                    DeleteSelection();
                    keyEvent.Handled          = true;
                    keyEvent.SuppressKeyPress = true;
                }
                break;

            case Keys.C:
                if (keyEvent.Control)
                {
                    turnOffSelection = false;
                    CopySelection();
                    keyEvent.Handled          = true;
                    keyEvent.SuppressKeyPress = true;
                }
                break;

            case Keys.V:
                if (keyEvent.Control)
                {
                    PasteFromClipboard();
                    keyEvent.Handled          = true;
                    keyEvent.SuppressKeyPress = true;
                }
                break;

            case Keys.Z:
                if (keyEvent.Control)
                {
                    Undo();
                    keyEvent.Handled          = true;
                    keyEvent.SuppressKeyPress = true;
                }
                break;

            case Keys.Y:
                if (keyEvent.Control)
                {
                    TextWidgetUndoData undoData = (TextWidgetUndoData)undoBuffer.GetNextRedoObject();
                    if (undoData != null)
                    {
                        undoData.ExtractData(this);
                    }
                    keyEvent.Handled          = true;
                    keyEvent.SuppressKeyPress = true;
                }
                break;
            }

            base.OnKeyDown(keyEvent);

            if (SetDesiredBarPosition)
            {
                FixBarPosition(DesiredXPositionOnLine.Set);
            }
            else
            {
                FixBarPosition(DesiredXPositionOnLine.Maintain);
            }

            // if we are not going to type a character, and therefore replace the selection, turn off the selection now if needed.
            if (keyEvent.SuppressKeyPress && turnOffSelection)
            {
                Selecting = false;
            }

            Invalidate();
        }