A data object that generates property change notifications and can be used for rich data binding to test results. Does keep a reference to all results.
Inheritance: PropertyChangedBase, IProvideResultReports
        /// <summary>
        /// Process a result.
        /// </summary>
        /// <param name="result">The result data.</param>
        private void ProcessResult(ScenarioResult result)
        {
            TestClassData  tac = GetClassModel(result.TestClass);
            TestMethodData tmd = GetMethodModel(result.TestMethod, tac);

            tmd.IsRunning = false;

            tmd.IsNotable = !tmd.Passed;

            if (_d == null)
            {
                return;
            }

            // Link to previous
            tmd.PreviousResult = _lastResult;
            _lastResult        = tmd;

            _d.RunScenarios++;
            if (result.Result != TestOutcome.Passed)
            {
                _d.FailedScenarios++;

                // Link to previous failure
                tmd.PreviousFailingResult = _lastFailingResult;
                _lastFailingResult        = tmd;

                // Automatically check the item for the user
                tmd.IsChecked = true;
            }

            tmd.Result = result;
        }
        /// <summary>
        /// Handles navigation back or forward.
        /// </summary>
        /// <param name="sender">The source object.</param>
        /// <param name="e">The event arguments.</param>
        private void OnResultNavigationClick(object sender, RoutedEventArgs e)
        {
            Button b   = (Button)sender;
            string tag = (string)b.Tag;

            TestMethodData tmd = (TestMethodData)b.DataContext;
            TestMethodData to  = null;

            switch (tag)
            {
            case "Previous":
                to = tmd.PreviousResult;
                break;

            case "PreviousFailure":
                to = tmd.PreviousFailingResult;
                break;

            case "NextFailure":
                to = tmd.NextFailingResult;
                break;

            case "Next":
                to = tmd.NextResult;
                break;

            default:
                throw new InvalidOperationException();
            }

            if (to != null)
            {
                resultsTreeView.SelectItem(to);
            }
        }
        /// <summary>
        /// Offers clipboard interface support for copying test run results.
        /// </summary>
        /// <param name="sender">The source object.</param>
        /// <param name="e">The event arguments.</param>
        protected virtual void OnClipboardButtonClick(object sender, EventArgs e)
        {
            Button b    = (Button)sender;
            string tag  = (string)b.Tag;
            string text = string.Empty;

            switch (tag)
            {
            case "CopyAllChecked":
                StringBuilder sb    = new StringBuilder();
                int           count = 0;
                foreach (KeyValuePair <object, TreeViewItem> item in resultsTreeView.GetCheckedItemsAndContainers())
                {
                    // Only want the actual leaf nodes
                    TestMethodData tmd = item.Key as TestMethodData;
                    if (tmd != null)
                    {
                        sb.AppendLine(tmd.GetResultReport());
                        count++;
                    }
                }
                if (count == 0)
                {
                    sb.AppendLine("There were no checked results.");
                    text = sb.ToString();
                }
                else
                {
                    text = "There were " +
                           count.ToString() +
                           " results checked." +
                           Environment.NewLine +
                           Environment.NewLine +
                           sb.ToString();
                }

                break;

            case "CopyResults":
                IProvideResultReports result = resultsTreeView.SelectedItem as IProvideResultReports;
                if (result != null)
                {
                    text = result.GetResultReport();
                }
                break;

            default:
            case "Close":
                ClipboardContents.Text         = string.Empty;
                ClipboardHelperGrid.Visibility = Visibility.Collapsed;
                return;
            }

            SetClipboardText(text);
        }
        /// <summary>
        /// Handles the completion of a test method.
        /// </summary>
        /// <param name="sender">The source object.</param>
        /// <param name="e">The event arguments.</param>
        private void OnTestMethodCompleted(object sender, TestMethodCompletedEventArgs e)
        {
            ScenarioResult result = e.Result;

            if (result.Result != TestOutcome.Passed)
            {
                TestMethodData tmd = _model.GetMethodModel(
                    e.Result.TestMethod,
                    _model.GetClassModel(e.Result.TestClass));
            }
        }
        /// <summary>
        /// Process the start of a test method.
        /// </summary>
        /// <param name="sender">The source object.</param>
        /// <param name="e">The event data.</param>
        private void OnTestMethodStarting(object sender, TestMethodStartingEventArgs e)
        {
            TestClassData  tac = GetClassModel(e.TestClass);
            TestMethodData tmd = GetMethodModel(e.TestMethod, tac);

            if (!tac.IsExpanded)
            {
                tac.IsExpanded = true;
            }
            tmd.IsRunning = true;

            _d.CurrentTestMethod = e.TestMethod.Name;
        }
        /// <summary>
        /// Gets or creates the data model object for a test method.
        /// </summary>
        /// <param name="testMethod">The test method.</param>
        /// <param name="parentTestClass">The parent test class data object.</param>
        /// <returns>Returns the data object.</returns>
        public TestMethodData GetMethodModel(ITestMethod testMethod, TestClassData parentTestClass)
        {
            TestMethodData data;

            if (!_methodData.TryGetValue(testMethod, out data))
            {
                data = new TestMethodData(testMethod, parentTestClass);
                _methodData.Add(testMethod, data);

                // Make sure in parent collection
                parentTestClass.TestMethods.Add(data);
            }

            return(data);
        }
        /// <summary>
        /// Gets or creates the data model object for a test method.
        /// </summary>
        /// <param name="testMethod">The test method.</param>
        /// <param name="parentTestClass">The parent test class data object.</param>
        /// <returns>Returns the data object.</returns>
        public TestMethodData GetMethodModel(ITestMethod testMethod, TestClassData parentTestClass)
        {
            TestMethodData data;
            if (!_methodData.TryGetValue(testMethod, out data))
            {
                data = new TestMethodData(testMethod, parentTestClass);
                _methodData.Add(testMethod, data);

                // Make sure in parent collection
                parentTestClass.TestMethods.Add(data);
            }

            return data;
        }
        /// <summary>
        /// Process a result.
        /// </summary>
        /// <param name="result">The result data.</param>
        private void ProcessResult(ScenarioResult result)
        {
            TestClassData tac = GetClassModel(result.TestClass);
            TestMethodData tmd = GetMethodModel(result.TestMethod, tac);

            tmd.IsRunning = false;

            tmd.IsNotable = !tmd.Passed;

            if (_d == null)
            {
                return;
            }

            // Link to previous
            tmd.PreviousResult = _lastResult;
            _lastResult = tmd;

            _d.RunScenarios++;
            if (result.Result != TestOutcome.Passed)
            {
                _d.FailedScenarios++;

                // Link to previous failure
                tmd.PreviousFailingResult = _lastFailingResult;
                _lastFailingResult = tmd;

                // Automatically check the item for the user
                tmd.IsChecked = true;
            }

            tmd.Result = result;
        }