internal UnitTestResult RunUnitTest(UnitTest test, string suiteName, string pathName, string testName, TestContext testContext)
        {
            var runnerExe = GetCustomConsoleRunnerCommand();

            if (runnerExe != null)
            {
                return(RunWithConsoleRunner(runnerExe, test, suiteName, pathName, testName, testContext));
            }

            var console = testContext.ExecutionContext.ConsoleFactory.CreateConsole(
                OperationConsoleFactory.CreateConsoleOptions.Default.WithTitle(GettextCatalog.GetString("Unit Tests")));

            ExternalTestRunner runner = new ExternalTestRunner(Path.GetDirectoryName(AssemblyPath));

            runner.ProcessExecutionArchitecture = AssemblyUtilities.GetProcessExecutionArchitectureForAssembly(AssemblyPath);
            runner.Connect(NUnitVersion, testContext.ExecutionContext.ExecutionHandler, console).Wait();
            LocalTestMonitor localMonitor = new LocalTestMonitor(testContext, test, suiteName, testName != null);

            string[] filter = null;
            if (test != null)
            {
                if (test is UnitTestGroup && NUnitVersion == NUnitVersion.NUnit2)
                {
                    filter = CollectTests((UnitTestGroup)test);
                }
                else if (test.TestId != null)
                {
                    filter = new string [] { test.TestId };
                }
            }

            RunData rd = new RunData();

            rd.Runner       = runner;
            rd.Test         = this;
            rd.LocalMonitor = localMonitor;

            var cancelReg = testContext.Monitor.CancellationToken.Register(rd.Cancel);

            UnitTestResult result;
            var            crashLogFile = Path.GetTempFileName();

            try {
                if (string.IsNullOrEmpty(AssemblyPath))
                {
                    string msg = GettextCatalog.GetString("Could not get a valid path to the assembly. There may be a conflict in the project configurations.");
                    throw new Exception(msg);
                }

                string testRunnerAssembly, testRunnerType;
                GetCustomTestRunner(out testRunnerAssembly, out testRunnerType);

                testContext.Monitor.CancellationToken.ThrowIfCancellationRequested();

                var supportAssemblies = new List <string> (GetSupportAssembliesAsync().Result);
                result = runner.Run(localMonitor, filter, AssemblyPath, "", supportAssemblies, testRunnerType, testRunnerAssembly, crashLogFile).Result;
                if (testName != null)
                {
                    result = localMonitor.SingleTestResult;
                }

                ReportCrash(testContext, crashLogFile);
            } catch (Exception ex) {
                if (ReportCrash(testContext, crashLogFile))
                {
                    result = UnitTestResult.CreateFailure(GettextCatalog.GetString("Unhandled exception"), null);
                }
                else if (!localMonitor.Canceled)
                {
                    LoggingService.LogError(ex.ToString());
                    if (localMonitor.RunningTest != null)
                    {
                        RuntimeErrorCleanup(testContext, localMonitor.RunningTest, ex);
                    }
                    else
                    {
                        testContext.Monitor.ReportRuntimeError(null, ex);
                        throw;
                    }
                    result = UnitTestResult.CreateFailure(ex);
                }
                else
                {
                    result = UnitTestResult.CreateFailure(GettextCatalog.GetString("Canceled"), null);
                }
            } finally {
                // Dispose the runner before the console, to make sure the console is available until the runner is disposed.
                runner.Disconnect().Wait();
                runner.Dispose();
                if (console != null)
                {
                    console.Dispose();
                }
                cancelReg.Dispose();
                File.Delete(crashLogFile);
            }

            return(result);
        }
        static void RunAsyncLoadTest()
        {
            while (true)
            {
                LoadData ld;
                lock (loadQueue) {
                    if (loadQueue.Count == 0)
                    {
                        if (!Monitor.Wait(loadQueue, 5000, true))
                        {
                            loaderRunning = false;
                            return;
                        }
                    }
                    ld = (LoadData)loadQueue.Dequeue();
                }

                try {
                    // If the information is cached in a file and it is up to date information,
                    // there is no need to parse again the assembly.

                    if (ld.TestInfoCachePath != null && File.Exists(ld.TestInfoCachePath))
                    {
                        ld.InfoCache = TestInfoCache.Read(ld.TestInfoCachePath);
                        NunitTestInfo info = ld.InfoCache.GetInfo(ld.Path);
                        if (info != null)
                        {
                            ld.Info = info;
                            ld.Callback(ld);
                            continue;
                        }
                    }
                } catch (Exception ex) {
                    LoggingService.LogError(ex.ToString());
                }

                ExternalTestRunner runner = null;

                try {
                    if (File.Exists(ld.Path))
                    {
                        runner = new ExternalTestRunner(Path.GetDirectoryName(ld.Path));
                        runner.ProcessExecutionArchitecture = AssemblyUtilities.GetProcessExecutionArchitectureForAssembly(ld.Path);
                        runner.Connect(ld.NUnitVersion).Wait();
                        var supportAssemblies = new List <string> (ld.SupportAssemblies.Result);
                        ld.Info = runner.GetTestInfo(ld.Path, supportAssemblies).Result;
                    }
                } catch (AggregateException exception) {
                    var baseException = exception.GetBaseException();
                    Console.WriteLine(baseException);
                    ld.Error = baseException;
                } catch (Exception exception) {
                    Console.WriteLine(exception);
                    ld.Error = exception;
                }
                finally {
                    try {
                        if (runner != null)
                        {
                            runner.Dispose();
                        }
                    } catch {}
                }

                try {
                    ld.Callback(ld);
                } catch {
                }
            }
        }