///-------------------------------------------------------------------------------------------------
        /// <summary>
        ///  Initializes a new instance of the <see cref="UndoManager" /> class.
        /// </summary>
        /// <param name="store">
        ///  The store.
        /// </param>
        /// <param name="capacity">
        ///  (Optional)
        /// </param>
        ///-------------------------------------------------------------------------------------------------
        public UndoManager(IHyperstore store, int capacity = 100)
        {
            Contract.Requires(store, "store");
            Contract.Requires(capacity > 0, "capacity");

            _store        = store;
            _domainModels = new Dictionary <string, DomainInfo>(StringComparer.OrdinalIgnoreCase);
            _undos        = new RecursiveStack <SessionEvents>(capacity);
            _redos        = new RecursiveStack <SessionEvents>(capacity);
            Capacity      = capacity;
        }
        private void PerformPop(RecursiveStack <SessionEvents> mainStack, RecursiveStack <SessionEvents> altStack, SessionMode mode, int?toSavePoint)
        {
            var notify = false;

            lock (_sync)
            {
                int sid    = 0;
                var events = new List <IUndoableEvent>();
                using (var session = _store.BeginSession(new SessionConfiguration {
                    Mode = mode
                }))
                {
                    IEventDispatcher dispatcher      = null;
                    string           domainModelName = null;
                    while (mainStack.Count > 0)
                    {
                        if (toSavePoint != null && mainStack.Peek().SessionId == toSavePoint)
                        {
                            break;
                        }

                        var ci = mainStack.Pop();
                        foreach (var @event in Enumerable.Reverse(ci.Events))
                        {
                            var evt = @event.GetReverseEvent(session.SessionId);
                            if (evt == null)
                            {
                                continue;
                            }
                            if (domainModelName != evt.Domain)
                            {
                                dispatcher      = _domainModels[evt.Domain].Dispatcher;
                                domainModelName = evt.Domain;
                            }
                            dispatcher.HandleEvent(evt);

                            if (evt is IUndoableEvent)
                            {
                                events.Add(evt as IUndoableEvent);
                            }
                        }

                        sid = ci.SessionId;
                        if (toSavePoint == null)
                        {
                            break;
                        }
                    }

                    session.AcceptChanges();
                }

                if (events.Count > 0)
                {
                    notify = true;
                    altStack.Push(new SessionEvents
                    {
                        SessionId = sid,
                        Events    = events.ToList()
                    });
                }
            }

            if (notify)
            {
                OnPropertyChanged("CanUndo");
                OnPropertyChanged("CanRedo");
            }
        }