/// <summary>
        /// This is the one where all the magic starts.  Main() so to speak.  I will load the settings, connect to tfs and apply the aggregation rules.
        /// </summary>
        public EventNotificationStatus ProcessEvent(TeamFoundationRequestContext requestContext, NotificationType notificationType, object notificationEventArgs,
                                                    out int statusCode, out string statusMessage, out ExceptionPropertyCollection properties)
        {
            var result = new ProcessingResult();

            try
            {
                //Check if we have a workitem changed event before proceeding
                if (notificationType == NotificationType.Notification && notificationEventArgs is WorkItemChangedEvent)
                {
                    var context      = new RequestContextWrapper(requestContext);
                    var notification = new NotificationWrapper(notificationType, notificationEventArgs as WorkItemChangedEvent);
                    result = eventProcessor.ProcessEvent(context, notification);
                }
            }
            catch (Exception e)
            {
                string message = String.Format("Exception encountered processing notification: {0} \nStack Trace:{1}", e.Message, e.StackTrace);
                if (e.InnerException != null)
                {
                    message += String.Format("\n    Inner Exception: {0} \nStack Trace:{1}", e.InnerException.Message, e.InnerException.StackTrace);
                }
                MiscHelpers.LogMessage(message, true);
            }

            statusCode    = result.StatusCode;
            statusMessage = result.StatusMessage;
            properties    = result.ExceptionProperties;
            return(result.NotificationStatus);
        }
        /// <summary>
        /// This is the one where all the magic starts.  Main() so to speak.  I will load the settings, connect to TFS and apply the aggregation rules.
        /// </summary>
        public EventNotificationStatus ProcessEvent(
            TeamFoundationRequestContext requestContext,
            NotificationType notificationType,
            object notificationEventArgs,
            out int statusCode,
            out string statusMessage,
            out ExceptionPropertyCollection properties)
        {
            var runtime = RuntimeContext.GetContext(
                GetServerSettingsFullPath,
                new RequestContextWrapper(requestContext),
                new ServerEventLogger(LogLevel.Normal));

            if (runtime.HasErrors)
            {
                statusCode    = 99;
                statusMessage = string.Join(". ", runtime.Errors);
                properties    = null;
                return(EventNotificationStatus.ActionPermitted);
            }

            // HACK: remove cast for ProcessEventException
            var logger = (ServerEventLogger)runtime.Logger;

            var result = new ProcessingResult();

            try
            {
                // Check if we have a workitem changed event before proceeding
                if (notificationType == NotificationType.Notification && notificationEventArgs is WorkItemChangedEvent)
                {
                    var uri = this.GetCollectionUriFromContext(requestContext);

                    IdentityDescriptor toImpersonate = null;
                    if (runtime.Settings.AutoImpersonate)
                    {
                        toImpersonate = this.GetIdentityToImpersonate(requestContext, notificationEventArgs as WorkItemChangedEvent);
                    }

                    using (EventProcessor eventProcessor = new EventProcessor(uri.AbsoluteUri, toImpersonate, runtime))
                    {
                        var context      = runtime.RequestContext;
                        var notification = new NotificationWrapper(
                            notificationType,
                            notificationEventArgs as WorkItemChangedEvent);

                        logger.StartingProcessing(context, notification);
                        result = eventProcessor.ProcessEvent(context, notification);
                        logger.ProcessingCompleted(result);
                    }
                }
            }
            catch (Exception e)
            {
                logger.ProcessEventException(e);

                // notify failure
                result.StatusCode         = -1;
                result.StatusMessage      = "Unexpected error: " + e.Message;
                result.NotificationStatus = EventNotificationStatus.ActionPermitted;
            }

            statusCode    = result.StatusCode;
            statusMessage = result.StatusMessage;
            properties    = result.ExceptionProperties;
            return(result.NotificationStatus);
        }