protected override async Task RunTestAsync()
        {
            var projectDir = System.IO.Path.GetDirectoryName(ProjectFile);
            var name       = System.IO.Path.GetFileName(projectDir);

            using (var resource = await NotifyAndAcquireDesktopResourceAsync()) {
                using (var proc = new Process()) {
                    proc.StartInfo.FileName = "/Library/Frameworks/Mono.framework/Commands/mono";
                    var reporter = System.IO.Path.Combine(WorkingDirectory, "xtro-report/bin/Debug/xtro-report.exe");
                    var results  = System.IO.Path.Combine(Logs.Directory, $"xtro-{Timestamp}");
                    proc.StartInfo.Arguments = $"--debug {reporter} {WorkingDirectory} {results}";

                    Jenkins.MainLog.WriteLine("Executing {0} ({1})", TestName, Mode);
                    var log = Logs.Create($"execute-xtro-{Timestamp}.txt", LogType.ExecutionLog.ToString());
                    log.WriteLine("{0} {1}", proc.StartInfo.FileName, proc.StartInfo.Arguments);
                    if (!Harness.DryRun)
                    {
                        ExecutionResult = TestExecutingResult.Running;

                        var snapshot = new CrashReportSnapshot()
                        {
                            Device = false, Harness = Harness, Log = log, Logs = Logs, LogDirectory = LogDirectory
                        };
                        await snapshot.StartCaptureAsync();

                        try {
                            var timeout = TimeSpan.FromMinutes(20);

                            var result = await ProcessManager.RunAsync(proc, log, timeout);

                            if (result.TimedOut)
                            {
                                FailureMessage = $"Execution timed out after {timeout.TotalSeconds} seconds.";
                                log.WriteLine(FailureMessage);
                                ExecutionResult = TestExecutingResult.TimedOut;
                            }
                            else if (result.Succeeded)
                            {
                                ExecutionResult = TestExecutingResult.Succeeded;
                            }
                            else
                            {
                                ExecutionResult = TestExecutingResult.Failed;
                                FailureMessage  = result.ExitCode != 1 ? $"Test run crashed (exit code: {result.ExitCode})." : "Test run failed.";
                                log.WriteLine(FailureMessage);
                            }
                        } finally {
                            await snapshot.EndCaptureAsync(TimeSpan.FromSeconds(Succeeded ? 0 : 5));
                        }
                    }
                    Jenkins.MainLog.WriteLine("Executed {0} ({1})", TestName, Mode);

                    Logs.AddFile(System.IO.Path.Combine(results, "index.html"), "HTML Report");
                }
            }
        }
        protected override async Task RunTestAsync()
        {
            var projectDir = System.IO.Path.GetDirectoryName(ProjectFile);
            var name       = System.IO.Path.GetFileName(projectDir);

            if (string.Equals("mac", name, StringComparison.OrdinalIgnoreCase))
            {
                name = System.IO.Path.GetFileName(System.IO.Path.GetDirectoryName(projectDir));
            }
            var suffix = string.Empty;

            switch (Platform)
            {
            case TestPlatform.Mac_Modern:
                suffix = "-modern";
                break;

            case TestPlatform.Mac_Full:
                suffix = "-full";
                break;

            case TestPlatform.Mac_System:
                suffix = "-system";
                break;
            }
            if (ProjectFile.EndsWith(".sln", StringComparison.Ordinal))
            {
                Path = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(ProjectFile), "bin", BuildTask.ProjectPlatform, BuildTask.ProjectConfiguration + suffix, name + ".app", "Contents", "MacOS", name);
            }
            else
            {
                var project = new XmlDocument();
                project.LoadWithoutNetworkAccess(ProjectFile);
                var outputPath   = project.GetOutputPath(BuildTask.ProjectPlatform, BuildTask.ProjectConfiguration).Replace('\\', '/');
                var assemblyName = project.GetAssemblyName();
                Path = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(ProjectFile), outputPath, assemblyName + ".app", "Contents", "MacOS", assemblyName);
            }

            using (var resource = await NotifyAndAcquireDesktopResourceAsync()) {
                using (var proc = new Process()) {
                    proc.StartInfo.FileName = Path;
                    if (IsUnitTest)
                    {
                        var xml = Logs.CreateFile($"test-{Platform}-{Timestamp}.xml", LogType.NUnitResult.ToString());
                        proc.StartInfo.Arguments = StringUtils.FormatArguments($"-result=" + xml);
                    }
                    if (!Harness.GetIncludeSystemPermissionTests(Platform, false))
                    {
                        proc.StartInfo.EnvironmentVariables ["DISABLE_SYSTEM_PERMISSION_TESTS"] = "1";
                    }
                    proc.StartInfo.EnvironmentVariables ["MONO_DEBUG"] = "no-gdb-backtrace";
                    Jenkins.MainLog.WriteLine("Executing {0} ({1})", TestName, Mode);
                    var log = Logs.Create($"execute-{Platform}-{Timestamp}.txt", LogType.ExecutionLog.ToString());
                    if (!Harness.DryRun)
                    {
                        ExecutionResult = TestExecutingResult.Running;

                        var snapshot = new CrashReportSnapshot()
                        {
                            Device = false, Harness = Harness, Log = log, Logs = Logs, LogDirectory = LogDirectory
                        };
                        await snapshot.StartCaptureAsync();

                        ProcessExecutionResult result = null;
                        try {
                            var timeout = TimeSpan.FromMinutes(20);

                            result = await ProcessManager.RunAsync(proc, log, timeout);

                            if (result.TimedOut)
                            {
                                FailureMessage = $"Execution timed out after {timeout.TotalSeconds} seconds.";
                                log.WriteLine(FailureMessage);
                                ExecutionResult = TestExecutingResult.TimedOut;
                            }
                            else if (result.Succeeded)
                            {
                                ExecutionResult = TestExecutingResult.Succeeded;
                            }
                            else
                            {
                                ExecutionResult = TestExecutingResult.Failed;
                                FailureMessage  = result.ExitCode != 1 ? $"Test run crashed (exit code: {result.ExitCode})." : "Test run failed.";
                                log.WriteLine(FailureMessage);
                            }
                        } finally {
                            await snapshot.EndCaptureAsync(TimeSpan.FromSeconds(Succeeded ? 0 : result?.ExitCode > 1 ? 120 : 5));
                        }
                    }
                    Jenkins.MainLog.WriteLine("Executed {0} ({1})", TestName, Mode);
                }
            }
        }