/// <summary>
        ///     Runs the redirected process and waits for it to return.
        /// </summary>
        public RedirectedProcessResult Run()
        {
            var processStandardOutput = new List <string>();
            var processStandardError  = new List <string>();

            AddOutputProcessing(output =>
            {
                lock (processStandardOutput)
                {
                    processStandardOutput.Add(output);
                }
            });

            AddErrorProcessing(error =>
            {
                lock (processStandardError)
                {
                    processStandardError.Add(error);
                }
            });

            var(process, outputLog) = SetupProcess();

            using (process)
            {
                Start(process);
                process.WaitForExit();

                var trimmedOutput = outputLog?.ToString().TrimStart();

                var result = new RedirectedProcessResult
                {
                    ExitCode = process.ExitCode,
                    Stdout   = processStandardOutput,
                    Stderr   = processStandardError
                };

                if (string.IsNullOrEmpty(trimmedOutput))
                {
                    return(result);
                }

                if (process.ExitCode == 0)
                {
                    Debug.Log(trimmedOutput);
                }
                else
                {
                    Debug.LogError(trimmedOutput);
                }

                return(result);
            }
        }
        /// <summary>
        ///     Runs the redirected process and returns a task which can be waited on.
        /// </summary>
        /// <param name="token">A cancellation token which can be used for cancelling the underlying process. Default is <see cref="CancellationToken.None"/>.</param>
        /// <returns>A task which would return the exit code and output.</returns>
        public Task <RedirectedProcessResult> RunAsync(CancellationToken token = default)
        {
            var processStandardOutput = new List <string>();
            var processStandardError  = new List <string>();

            AddOutputProcessing(output =>
            {
                lock (processStandardOutput)
                {
                    processStandardOutput.Add(output);
                }
            });

            AddErrorProcessing(error =>
            {
                lock (processStandardOutput)
                {
                    processStandardError.Add(error);
                }
            });

            var(process, outputLog) = SetupProcess();

            var taskCompletionSource = new TaskCompletionSource <RedirectedProcessResult>(TaskCreationOptions.RunContinuationsAsynchronously);

            // Register a handler to process the output when it exits.
            process.Exited += (sender, args) =>
            {
                var result = new RedirectedProcessResult
                {
                    ExitCode = process.ExitCode,
                    Stdout   = processStandardOutput,
                    Stderr   = processStandardError
                };

                taskCompletionSource.SetResult(result);

                var trimmedOutput = outputLog?.ToString().TrimStart();

                if (string.IsNullOrEmpty(trimmedOutput))
                {
                    process.Dispose();
                    return;
                }

                if (process.ExitCode == 0)
                {
                    Debug.Log(trimmedOutput);
                }
                else
                {
                    Debug.LogError(trimmedOutput);
                }

                process.Dispose();
            };

            Start(process);

            // Register a handler for when a cancel is requested, we kill the process.
            token.Register(() =>
            {
                if (process.HasExited)
                {
                    return;
                }

                process.Kill();
            });

            return(taskCompletionSource.Task);
        }