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 ();

			ExternalTestRunner runner = new ExternalTestRunner ();
			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 ();
					
				result = runner.Run (localMonitor, filter, AssemblyPath, "", new List<string> (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 {
				if (console != null)
					console.Dispose ();
				cancelReg.Dispose ();
				runner.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 ();
						runner.Connect (ld.NUnitVersion).Wait ();
						ld.Info = runner.GetTestInfo (ld.Path, ld.SupportAssemblies).Result;
					}
				} catch (Exception ex) {
					Console.WriteLine (ex);
					ld.Error = ex;
				}
				finally {
					try {
						if (runner != null)
							runner.Dispose ();
					} catch {}
				}

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