/// <summary> Performs the given action and adds it to the undoable stack. </summary>
        /// <param name="undoableAction"> The undoable action. </param>
        public void Do(UndoableAction undoableAction)
        {
            bool wasMerged = false;

            var newestEntry = new UndoStackEntry(undoableAction, DateTimeOffset.UtcNow);

            if (_toUndoStack.Count > 0)
            {
                var lastEntry = _toUndoStack.Peek();

                if (_mergePolicy.ShouldTryMerge(lastEntry, newestEntry))
                {
                    wasMerged = lastEntry.Action.TryMerge(_context, undoableAction);
                }
            }

            undoableAction.Do(_context);

            if (!wasMerged)
            {
                // it was merged into the previous command, so no need to add it to the stack
                _toUndoStack.Push(newestEntry);
            }

            _toRedoStack.Clear();
        }
 public UndoStackEntry(UndoableAction action, DateTimeOffset insertTime)
 {
     Action     = action;
     InsertTime = insertTime;
 }
 /// <summary> Attempts to merge the given action into this instance. </summary>
 /// <param name="context"> The context in which the action should be merged. </param>
 /// <param name="action"> The action to merge, if possible. </param>
 /// <returns> True if the action was merged, false otherwise. </returns>
 public virtual bool TryMerge(DocumentEditorContext context, UndoableAction action)
 {
     return(false);
 }