/// <inheritdoc />
        public Report Run(TestPackage testPackage, TestExplorationOptions testExplorationOptions, TestExecutionOptions testExecutionOptions, IProgressMonitor progressMonitor)
        {
            if (testPackage == null)
                throw new ArgumentNullException("testPackageConfig");
            if (testExplorationOptions == null)
                throw new ArgumentNullException("testExplorationOptions");
            if (testExecutionOptions == null)
                throw new ArgumentNullException("testExecutionOptions");
            if (progressMonitor == null)
                throw new ArgumentNullException("progressMonitor");

            ThrowIfDisposed();
            if (state != State.Initialized)
                throw new InvalidOperationException("The test runner must be initialized before this operation is performed.");

            testPackage = testPackage.Copy();
            testExplorationOptions = testExplorationOptions.Copy();
            testExecutionOptions = testExecutionOptions.Copy();
            GenericCollectionUtils.ForEach(testRunnerOptions.Properties, x => testPackage.AddProperty(x.Key, x.Value));

            using (progressMonitor.BeginTask("Running the tests.", 10))
            {
                Stopwatch stopwatch = Stopwatch.StartNew();
                Report report = new Report()
                {
                    TestPackage = new TestPackageData(testPackage),
                    TestModel = new TestModelData(),
                    TestPackageRun = new TestPackageRun()
                    {
                        StartTime = DateTime.Now
                    }
                };
                var reportLockBox = new LockBox<Report>(report);

                eventDispatcher.NotifyRunStarted(new RunStartedEventArgs(testPackage, testExplorationOptions,
                    testExecutionOptions, reportLockBox));

                bool success;
                using (Listener listener = new Listener(eventDispatcher, tappedLogger, reportLockBox))
                {
                    try
                    {
                        ITestDriver testDriver = testFrameworkManager.GetTestDriver(
                            testPackage.CreateTestFrameworkSelector(), tappedLogger);

                        using (testIsolationContext.BeginBatch(progressMonitor.SetStatus))
                        {
                            testDriver.Run(testIsolationContext, testPackage, testExplorationOptions,
                                testExecutionOptions, listener, progressMonitor.CreateSubProgressMonitor(10));
                        }

                        success = true;
                    }
                    catch (Exception ex)
                    {
                        success = false;

                        tappedLogger.Log(LogSeverity.Error,
                            "A fatal exception occurred while running tests.  Possible causes include invalid test runner parameters and stack overflows.",
                            ex);
                        report.TestModel.Annotations.Add(new AnnotationData(AnnotationType.Error,
                            CodeLocation.Unknown, CodeReference.Unknown,
                            "A fatal exception occurred while running tests.  See log for details.", null));
                    }
                    finally
                    {
                        report.TestPackageRun.EndTime = DateTime.Now;
                        report.TestPackageRun.Statistics.Duration = stopwatch.Elapsed.TotalSeconds;
                    }
                }

                eventDispatcher.NotifyRunFinished(new RunFinishedEventArgs(success, report));

                return report;
            }
        }