/// <summary>
        /// Process a user's Add Defect request
        /// </summary>
        public DialogResult AddDefect(IRepositoryContext context, IList<ILogMessage> messages, RepositoryController controller, FBApi api)
        {
            // It shouldn't happen that we get called with no messages selected,
            // but check for it anyway.
            if (messages.Count <= 0)
                return DialogResult.Cancel;

            UseWaitCursor = true;

            //store off our initial state
            m_Context = context;
            m_Controller = controller;
            m_LogMessages = messages;
            int lastMessageIndex = messages.Count - 1;
            m_PrimaryMessage = messages[lastMessageIndex];
            ErrorInfo errorInfo = new ErrorInfo(m_PrimaryMessage);
            m_Fingerprint = errorInfo.Fingerprint;

            //Blank our display
            ClearDisplay();

            //now go to the background to initialize it
            ThreadPool.QueueUserWorkItem(AsyncInitializeData, api);

            DialogResult result = ShowDialog();
            if (result == DialogResult.OK)
            {
                Submit(api);
            }
            else
            {
                m_Context.Log.Verbose(LogCategory, "User canceled dialog, no changes will be submitted", null);
            }

            return DialogResult;
        }
        /// <summary>
        /// Process the provided session
        /// </summary>
        /// <param name="session"></param>
        private void ActionProcessSession(ISession session)
        {
            // Ignore sessions that do not contain any errors
            if (session.ErrorCount == 0)
            {
                Log.Verbose(LogCategory, "Skipping session because there are no errors to inspect", null);
                return;
            }

            // Only process this session if there is a matching target project in FogBugz
            Mapping target = m_Controller.FindTarget(session);
            if (target == null)
            {
                Log.Verbose(LogCategory, "Skipping session because it doesn't match any target in the configuration file", null);
                return; // this could be perfectly normal
            }

            // Throws an exception if we can't connect with FogBugz
            FBApi api;
            try
            {
                api = m_Controller.GetApi();
            }
            catch(Exception ex)
            {
                Log.Error(ex, LogCategory, "Unable to analyze session because FogBugz server is not available", "When connecting to the FogBugz API an exception was thrown.  We will assume it is not available.");
                throw; //we really do want to abort out to our caller who is designed to handle failures like this.
            }

            // Process each unique error (as defined in IssuesByClass)
            Dictionary<string, ErrorInfo> errorList = new Dictionary<string, ErrorInfo>();

            foreach (ILogMessage message in session.GetMessages())
            {
                //process errors
                if (message.Severity > LogMessageSeverity.Error)
                    continue;

                ErrorInfo currentError = new ErrorInfo(message);
                ErrorInfo previousError;

                // This error is either new or another instance of a previous error
                if (errorList.TryGetValue(currentError.Fingerprint, out previousError))
                    previousError.Messages.Add(message);
                else
                    errorList.Add(currentError.Fingerprint, currentError);
            }

            foreach (KeyValuePair<string, ErrorInfo> pair in errorList)
            {
                ErrorInfo error = pair.Value;
                FogBugzCaseWriter fogBugzCase = new FogBugzCaseWriter(Log, error);
                fogBugzCase.Submit(api, target);
            }            
        }
 public FogBugzCaseWriter(ILog log, ErrorInfo error)
 {
     Log = log;
     Error = error;
 }