private void ThreadSafeDisplayDefect(string caseId, string projectName, string areaName)
        {
            if (InvokeRequired)
            {
                ThreadSafeDisplayDefectInvoker invoker = ThreadSafeDisplayDefect;
                Invoke(invoker, new object[] { caseId, projectName, areaName });
            }
            else
            {
                try
                {
                    //now add these items to the project selection area.
                    ProjectSelection.Items.Clear();
                    ProjectSelection.DataSource = new List <string>(m_ProjectsAndAreas.Keys); //data source requires a list

                    int           lastMessageIndex = m_LogMessages.Count - 1;
                    StringBuilder builder          = new StringBuilder();

                    // Use compact formatting of all but the last message
                    for (int i = 0; i < lastMessageIndex; i++)
                    {
                        LogMessageFormatter preludeFormatter = new LogMessageFormatter(m_LogMessages[i]);
                        builder.Append(preludeFormatter.GetLogMessageSummary());
                    }

                    // Skip a line between last "prelude" message and the primary message
                    if (lastMessageIndex > 0)
                    {
                        builder.AppendLine();
                    }

                    // The primary message is the last of the selected messages
                    LogMessageFormatter formatter = new LogMessageFormatter(m_PrimaryMessage);
                    builder.Append(formatter.GetLogMessageDetails());

                    // Add session details after the primary message
                    builder.AppendLine();
                    builder.AppendFormat("Session Details:\r\n");
                    LogMessageFormatter.AppendDivider(builder);
                    builder.Append(formatter.GetSessionDetails());

                    // This will be applied later, after user editing is done
                    m_SessionIdMessage = formatter.GetSessionIdMessage();

                    // Check the fingerprint of the primary message to determine if
                    // a case for this error already exists in FogBugz
                    if (string.IsNullOrEmpty(caseId))
                    {
                        // If there is no existing case, check if this session has an
                        // affinity for a particular project (i.e. is there a
                        // MappingTarget associated with this MappingSource in the config?)
                        // If so, default the project selection accordingly.
                        Mapping target = m_Controller.FindTarget(m_PrimaryMessage.Session);
                        m_Context.Log.Verbose(LogCategory, "No existing case found, user will be able to select project", "The current mapping information for the message is:\r\n{0}", (target == null) ? "(No mapping found)" : target.Project);
                        ProjectSelection.SelectedItem = target == null ? null : target.Project;
                        ProjectSelection.Enabled      = true;
                        AreaSelection.Enabled         = true;
                        CaseLabel.Tag  = null;
                        CaseLabel.Text = "(New Case)";
                        Text           = "Create New Case";
                    }
                    else
                    {
                        // If a case already exists, get info about it from FogBugz
                        ProjectSelection.SelectedItem = projectName;
                        ProjectSelection.Enabled      = false;

                        AreaSelection.SelectedItem = areaName;
                        AreaSelection.Enabled      = false;
                        m_Context.Log.Verbose(LogCategory, "Existing case fond, user will not be able to change project / area", "The current case is in:\r\n {0} {1}", projectName, areaName);

                        CaseLabel.Tag  = caseId;
                        CaseLabel.Text = caseId;
                        Text           = "Edit Case " + caseId;
                    }

                    TitleTextBox.Text            = formatter.GetTitle();
                    TitleTextBox.SelectionStart  = 0;
                    TitleTextBox.SelectionLength = 0;
                    TitleTextBox.Enabled         = true;

                    DescriptionTextBox.Text            = builder.ToString();
                    DescriptionTextBox.SelectionStart  = 0;
                    DescriptionTextBox.SelectionLength = 0;
                    DescriptionTextBox.Enabled         = true;

                    DescriptionTextBox.Select();
                    DescriptionTextBox.Focus(); //this is what they should edit.

                    ValidateData();
                }
                finally
                {
                    //one way or the other, we're done so the user shouldn't be given the impression we're waiting around.
                    UseWaitCursor = false;
                }
            }
        }