public override ServiceMessage Trace(string message)
		{
			var traceMessage = new ServiceMessage
			{
				Level = EnumServiceMessageLevel.Trace,
				Message = message,
				Detail = message,
				MessageDateTimeUtc = DateTime.UtcNow
			};
			this.WriteServiceMessage(traceMessage);
			return traceMessage;
		}
		public override ServiceMessage Exception(Exception err, object dataObject = null)
		{
			var exceptionMessage = new ServiceMessage
			{
				Level = EnumServiceMessageLevel.Error,
				Message = err.Message,
				Detail = err.ToString(),
				MessageDateTimeUtc = DateTime.UtcNow,
				DataObjectJson = (dataObject != null) ? dataObject.ToJson(true) : null
			};
			this.WriteServiceMessage(exceptionMessage);
			return exceptionMessage;
		}
		public override ServiceMessage WarningForObject(string message, object dataObject)
		{
			var warningMessage = new ServiceMessage
			{
				Level = EnumServiceMessageLevel.Warning,
				Message = message,
				Detail = message,
				MessageDateTimeUtc = DateTime.UtcNow,
				DataObjectJson = (dataObject != null) ? dataObject.ToJson() : null
			};
			this.WriteServiceMessage(warningMessage);
			return warningMessage;
		}
		public virtual ServiceMessage WarningForObject(string message, object dataObject)
		{
			var warningMessage = new ServiceMessage
			{
				Level = EnumServiceMessageLevel.Warning,
				Message = message,
				Detail = message,
				MessageDateTimeUtc = DateTime.UtcNow,
				DataObjectJson = GetDataObjectJson(dataObject)
			};
            //this.DocumentSession.Store(warningMessage);
            this.DocumentSession.SaveChanges();
			return warningMessage;
		}
		public void PurgesTraceMessages()
		{
			using(var session = EmbeddedRavenProvider.DocumentStore.OpenSession())
			{
				Mock<IEventReporter> eventReporter = new Mock<IEventReporter>();
				var configuration = new LogPurgeJobConfiguration
				{
					TraceAgeMinutes = 1000
				};
				DateTime now = DateTime.UtcNow;
				DateTime cutoff = now.AddMinutes(0-configuration.TraceAgeMinutes.Value);
				for(int i = 0; i < 10; i++)
				{
					var oldMessage = new ServiceMessage
					{
						Level = EnumServiceMessageLevel.Trace,
						Message = Guid.NewGuid().ToString(),
						MessageDateTimeUtc = cutoff.AddMinutes(0-10)
					};
					session.Store(oldMessage);

					var newMessage = new ServiceMessage
					{
						Level = EnumServiceMessageLevel.Trace,
						Message = Guid.NewGuid().ToString(),
						MessageDateTimeUtc = cutoff.AddMinutes(0+10)
					};
					session.Store(newMessage);
				}
				session.SaveChanges();
				var beforeMessages= session.Query<ServiceMessage>().OrderBy(i=>i.MessageDateTimeUtc).ToList();
				int originalOldMesssageCount = session.Query<ServiceMessage>().Where(i=>i.MessageDateTimeUtc < cutoff).Count();
				int originalNewMessageCount = session.Query<ServiceMessage>().Where(i=>i.MessageDateTimeUtc > cutoff).Count();
				configuration.UtcNow = now;
				var logPurger = new LogPurger(eventReporter.Object, session);
				var sut = new LogPurgeJob(eventReporter.Object, logPurger);
				sut.Run(configuration);

				var afterMesages = session.Query<ServiceMessage>().OrderBy(i => i.MessageDateTimeUtc).ToList();
				int newOldMesssageCount = session.Query<ServiceMessage>().Customize(i=>i.WaitForNonStaleResultsAsOfNow()).Where(i => i.MessageDateTimeUtc < cutoff).Count();
				int newNewMessageCount = session.Query<ServiceMessage>().Customize(i=>i.WaitForNonStaleResultsAsOfNow()).Where(i=>i.MessageDateTimeUtc > cutoff).Count();

				Assert.AreEqual(0, newOldMesssageCount);
				Assert.GreaterOrEqual(newNewMessageCount, originalNewMessageCount);

			}
		}
		public void Exception(ServiceMessage exception)
		{
			try
			{
				string subject = "DataServiceException: " + exception.Message + "(" + exception.Id + ")";
				StringBuilder body = new StringBuilder();
				body.AppendLine(string.Format("Exception Date: {0}", exception.MessageDateTimeUtc));
				body.AppendLine(string.Format("Exception Message: {0}", exception.Message));
				body.AppendLine("Exception Detail:");
				body.AppendLine(exception.Detail);
				if (!string.IsNullOrWhiteSpace(exception.DataObjectJson))
				{
					body.AppendLine();
					body.AppendLine("Data Object JSON: ");
					body.AppendLine(exception.DataObjectJson);
				}

				var settings = _settingsManager.Get<CoreDataServiceSettings>();

				var from = new MailAddress(settings.ExceptionNotificationFromEmailAddress);
				var toList = new List<MailAddress>();
				if(settings.ExceptionNotificationFromEmailAddress != null)
				{
					foreach(var item in settings.ExceptionNotificationEmailAddressList)
					{
						var to = new MailAddress(item);
						toList.Add(to);
					}
				}
                _emailQueuer.SendEmail(settings.EmailSettingSource, settings.EmailSettingKey, subject, body.ToString(), toList, from, null);
			}
			catch (Exception err)
			{
				Debug.WriteLine("Error sending email: " + err.ToString());
				//Who you gonna go cry to now?
			}
		}
		public virtual ServiceMessage Exception(Exception err, object dataObject = null)
		{
			var exceptionMessage = new ServiceMessage
			{
				Level = EnumServiceMessageLevel.Error,
				Message = err.Message,
				Detail = err.ToString(),
				MessageDateTimeUtc = DateTime.UtcNow,
                DataObjectJson = GetDataObjectJson(dataObject)
			};
			this.DocumentSession.Store(exceptionMessage);
			this.DocumentSession.SaveChanges();
			return exceptionMessage;
		}
		private void WriteServiceMessage(ServiceMessage message)
		{
			StringBuilder sb = new StringBuilder();
			sb.AppendFormat("[{0}: {1}] {2} - {3}",message.Level, message.MessageDateTimeUtc, message.Message, message.Detail);
			if(!string.IsNullOrEmpty(message.DataObjectJson))
			{
				sb.AppendLine();
				sb.AppendLine("JSON:");
				sb.AppendLine(message.DataObjectJson);
				sb.AppendLine();
			}
			sb.AppendLine();

			Console.WriteLine(sb.ToString());
		}