public void Flush(bool retrySucceeded)
            {
                foreach (var message in _messages)
                {
                    // in case of retry succeeded, convert all failure to skip (ignored)
                    if (retrySucceeded && message is TestFailed)
                    {
                        var failed = (TestFailed)message;
                        var reason = new StringBuilder();
                        reason.AppendLine(String.Join(Environment.NewLine, failed.ExceptionTypes));
                        reason.AppendLine(String.Join(Environment.NewLine, failed.Messages));
                        reason.AppendLine(String.Join(Environment.NewLine, failed.StackTraces));

                        // xunit does not report output if skipped (ignored) tests.
                        // put it as reason instead.
                        reason.AppendLine("====================================================================================");
                        reason.AppendLine(failed.Output);

                        var skipped = new TestSkipped(failed.Test, reason.ToString());
                        _innerBus.QueueMessage(skipped.SanitizeXml());
                    }
                    else
                    {
                        _innerBus.QueueMessage(message.SanitizeXml());
                    }
                }
            }
        // making sure all texts are Xml valid
        public static IMessageSinkMessage SanitizeXml(this IMessageSinkMessage message)
        {
            var failed = message as TestFailed;
            if (failed != null)
            {
                return new TestFailed(failed.Test,
                                      failed.ExecutionTime,
                                      XmlUtility.Sanitize(failed.Output),
                                      failed.ExceptionTypes,
                                      failed.Messages == null ? null : failed.Messages.Select(m => XmlUtility.Sanitize(m)).ToArray(),
                                      failed.StackTraces,
                                      failed.ExceptionParentIndices);
            }

            var skipped = message as TestSkipped;
            if (skipped != null)
            {
                skipped = new TestSkipped(skipped.Test, XmlUtility.Sanitize(skipped.Reason));
                skipped.SetOutput(XmlUtility.Sanitize(skipped.Output));
                return skipped;
            }

            var passed = message as TestPassed;
            if (passed != null)
            {
                return new TestPassed(passed.Test, passed.ExecutionTime, XmlUtility.Sanitize(passed.Output));
            }

            return message;
        }
        public async Task<RunSummary> RunScenarioAsync()
        {
            var runSummary = new RunSummary { Total = 1 };
            var output = string.Empty;

            if (!MessageBus.QueueMessage(new TestStarting(Test)))
                CancellationTokenSource.Cancel();
            else
            {
                AfterTestStarting();

                if (!string.IsNullOrEmpty(SkipReason))
                {
                    runSummary.Skipped++;

                    if (!MessageBus.QueueMessage(new TestSkipped(Test, SkipReason)))
                        CancellationTokenSource.Cancel();
                }
                else
                {
                    var aggregator = new ExceptionAggregator(Aggregator);

                    if (!aggregator.HasExceptions)
                    {
                        var tuple = await aggregator.RunAsync(() => InvokeTestAsync(aggregator));
                        runSummary.Time = tuple.Item1;
                        output = tuple.Item2;
                    }

                    var exception = aggregator.ToException();
                    TestResultMessage testResult;

                    if (exception == null)
                        testResult = new TestPassed(Test, runSummary.Time, output);
                    else if (exception is IgnoreException)
                    {
                        testResult = new TestSkipped(Test, exception.Message);
                        runSummary.Skipped++;
                    }
                    else
                    {
                        testResult = new TestFailed(Test, runSummary.Time, output, exception);
                        runSummary.Failed++;
                    }

                    if (!CancellationTokenSource.IsCancellationRequested)
                        if (!MessageBus.QueueMessage(testResult))
                            CancellationTokenSource.Cancel();
                }

                Aggregator.Clear();
                BeforeTestFinished();

                if (Aggregator.HasExceptions)
                    if (!MessageBus.QueueMessage(new TestCleanupFailure(Test, Aggregator.ToException())))
                        CancellationTokenSource.Cancel();
            }

            if (!MessageBus.QueueMessage(new TestFinished(Test, runSummary.Time, output)))
                CancellationTokenSource.Cancel();

            return runSummary;
        }