/// <summary>
 /// If a scope is active, buffers the event. Otherwise, directly raises it.
 /// </summary>
 public static void RaiseOrBufferEvent(Action raiseEvent)
 {
     if (Current != null)
     {
         tracer.Verbose(Resources.StoreEventBufferingScope_BufferingEvent);
         Current.AddEvent(raiseEvent);
     }
     else
     {
         raiseEvent();
     }
 }
        /// <summary>
        /// Releases unmanaged and - optionally - managed resources.
        /// </summary>
        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                while (Current != this && Current != null)
                {
                    Current.IsCanceled = this.IsCanceled;
                    // This would automatically pop the nested scopes.
                    Current.Dispose();
                }

                // Pop myself now.
                scopes.Pop();

                if (this.IsCanceled)
                {
                    tracer.Verbose(Resources.StoreEventBufferingScope_CancelledScopeIgnoringEvent);

                    // If we have been cancelled, we don't waste time copying our events to the potential parent
                    // scope as they will never be raised anyways.
                }
                else if (this.completed || this.autoComplete)
                {
                    if (Current != null)
                    {
                        tracer.Verbose(Resources.StoreEventBufferingScope_CompleteEnqueingOnParent);

                        // There's another parent scope. Append our events to the
                        // end of its queue for it to raise them later when it is itself
                        // disposed in turn.
                        this.events.ForEach(ev => Current.AddEvent(ev));
                    }
                    else
                    {
                        tracer.Verbose(Resources.StoreEventBufferingScope_RaisingEvents);

                        // We're the topmost scope, so we raise all buffered events now.
                        foreach (var raiseEvent in this.events)
                        {
                            RaisingEvents = true;
                            try
                            {
                                raiseEvent();
                            }
                            finally
                            {
                                RaisingEvents = false;
                            }
                        }
                    }
                }
                else
                {
                    tracer.Verbose(Resources.StoreEventBufferingScope_DisposingNonComplete);
                }

                // Propagate cancellation flag upwards.
                if (Current != null)
                {
                    Current.IsCanceled = this.IsCanceled;
                }

                this.disposed = true;
            }
        }