/// <summary>
 /// Called whenever a exception is thrown by a command
 /// during recovery.<br />
 /// Notify the specified delegate of the exception.
 ///
 /// </summary>
 /// <param name="handler">a delegate that should be notified of the exception</param>
 /// <param name="command">commands that has thrown the exception</param>
 /// <param name="exception">the exception</param>
 protected virtual void OnExceptionDuringRecovery(ExceptionDuringRecoveryHandler handler, ICommand command, Exception exception)
 {
     if (null != handler)
     {
         handler(this, new ExceptionDuringRecoveryEventArgs(command, exception));
     }
     System.Diagnostics.Trace.WriteLine(string.Format("Exception {0} during recovery of the command {1}", exception, command));
 }
 private void RecoverSystem(System.Type systemType, CommandLogReader reader, ExceptionDuringRecoveryHandler handler)
 {
     _system = reader.ReadLastSnapshot();
     if (null == _system)
     {
         _system = System.Activator.CreateInstance(systemType);
     }
     RecoverCommands(reader, handler);
 }
        private void RecoverCommands(CommandLogReader reader, ExceptionDuringRecoveryHandler handler)
        {
            ShareCurrentObject();

            try
            {
                Clock.Pause();
                try
                {
                    foreach (ContextRecoveryCommand contextRecoveryCommand in reader)
                    {
                        Clock.Recover(contextRecoveryCommand.DateTime);

                        ICommand command = contextRecoveryCommand.Command;
                        try
                        {
                            command.Execute(_system);
                        }
                        catch (System.Exception x)
                        {
                            // commands are allowed to throw exceptions
                            // it is up to the client to decide what to
                            // do with them
                            OnExceptionDuringRecovery(handler, command, x);
                        }
                    }
                }
                finally
                {
                    Clock.Resume();
                }
            }
            finally
            {
                UnshareCurrentObject();
            }
        }
		/// <summary>
		/// Called whenever a exception is thrown by a command
		/// during recovery.<br />
		/// Notify the specified delegate of the exception.
		/// 
		/// </summary>
		/// <param name="handler">a delegate that should be notified of the exception</param>
		/// <param name="command">commands that has thrown the exception</param>
		/// <param name="exception">the exception</param>
		protected virtual void OnExceptionDuringRecovery(ExceptionDuringRecoveryHandler handler, ICommand command, Exception exception)
		{
			if (null != handler)
			{
				handler(this, new ExceptionDuringRecoveryEventArgs(command, exception));
			}
			System.Diagnostics.Trace.WriteLine(string.Format("Exception {0} during recovery of the command {1}", exception, command));
		}
		private void RecoverCommands(CommandLogReader reader, ExceptionDuringRecoveryHandler handler)
		{
			ShareCurrentObject();

			try
			{
				Clock.Pause();
				try
				{
					foreach (ContextRecoveryCommand contextRecoveryCommand in reader)
					{
						Clock.Recover(contextRecoveryCommand.DateTime);
						
						ICommand command = contextRecoveryCommand.Command;
						try
						{							
							command.Execute(_system);
						}
						catch (System.Exception x)
						{
							// commands are allowed to throw exceptions
							// it is up to the client to decide what to
							// do with them
							OnExceptionDuringRecovery(handler, command, x);
						}
					}
				}
				finally
				{
					Clock.Resume();
				}
			}
			finally
			{				
				UnshareCurrentObject();
			}
		}
		private void RecoverSystem(System.Type systemType, CommandLogReader reader, ExceptionDuringRecoveryHandler handler)
		{
			_system = reader.ReadLastSnapshot();			
			if (null == _system)
			{
				_system = System.Activator.CreateInstance(systemType);
			}
			RecoverCommands(reader, handler);
		}
		/// <summary>
		/// See <see cref="PrevalenceActivator.CreateEngine(System.Type, string)"/>
		/// </summary>
		/// <param name="systemType"></param>
		/// <param name="prevalenceBase"></param>
		/// <param name="formatter"></param>
		/// <param name="handler"></param>
		internal PrevalenceEngine(System.Type systemType, string prevalenceBase, BinaryFormatter formatter, ExceptionDuringRecoveryHandler handler)
		{				
			_clock = new AlarmClock();

			CommandLogReader reader = new CommandLogReader(CheckPrevalenceBase(prevalenceBase), formatter);
			RecoverSystem(systemType, reader, handler);
			_commandLog = reader.ToWriter();
			_lock = new ReaderWriterLock();
			_decorators = GetCommandDecorators(systemType);
			_paused = false;
		}
        /// <summary>
        /// See <see cref="PrevalenceActivator.CreateEngine(System.Type, string)"/>
        /// </summary>
        /// <param name="systemType"></param>
        /// <param name="prevalenceBase"></param>
        /// <param name="formatter"></param>
        /// <param name="handler"></param>
        internal PrevalenceEngine(System.Type systemType, string prevalenceBase, BinaryFormatter formatter, ExceptionDuringRecoveryHandler handler)
        {
            _clock = new AlarmClock();

            CommandLogReader reader = new CommandLogReader(CheckPrevalenceBase(prevalenceBase), formatter);

            RecoverSystem(systemType, reader, handler);
            _commandLog = reader.ToWriter();
            _lock       = new ReaderWriterLock();
            _decorators = GetCommandDecorators(systemType);
            _paused     = false;
        }