private bool TryStartClient()
        {
            var authenticationToken = Context.Next.ClientAuthenticationToken.ToString("D");
            var executablePath      = Context.Next.AppConfig.ClientExecutablePath;
            var logFilePath         = $"{'"' + Context.Next.AppConfig.ClientLogFilePath + '"'}";
            var logLevel            = Context.Next.Settings.LogLevel.ToString();
            var runtimeHostUri      = Context.Next.AppConfig.RuntimeAddress;
            var uiMode = Context.Next.Settings.UserInterfaceMode.ToString();

            var clientReady             = false;
            var clientReadyEvent        = new AutoResetEvent(false);
            var clientReadyEventHandler = new CommunicationEventHandler(() => clientReadyEvent.Set());

            var clientTerminated             = false;
            var clientTerminatedEventHandler = new ProcessTerminatedEventHandler(_ => { clientTerminated = true; clientReadyEvent.Set(); });

            logger.Info("Starting new client process...");
            runtimeHost.AllowConnection     = true;
            runtimeHost.AuthenticationToken = Context.Next.ClientAuthenticationToken;
            runtimeHost.ClientReady        += clientReadyEventHandler;
            ClientProcess             = processFactory.StartNew(executablePath, logFilePath, logLevel, runtimeHostUri, authenticationToken, uiMode);
            ClientProcess.Terminated += clientTerminatedEventHandler;

            logger.Info("Waiting for client to complete initialization...");
            clientReady = clientReadyEvent.WaitOne();

            runtimeHost.AllowConnection     = false;
            runtimeHost.AuthenticationToken = default(Guid?);
            runtimeHost.ClientReady        -= clientReadyEventHandler;
            ClientProcess.Terminated       -= clientTerminatedEventHandler;

            if (clientReady && !clientTerminated)
            {
                return(TryStartCommunication());
            }

            if (!clientReady)
            {
                logger.Error($"Failed to start client!");
            }

            if (clientTerminated)
            {
                logger.Error("Client instance terminated unexpectedly during initialization!");
            }

            return(false);
        }
        private bool TryStopClient()
        {
            var success = false;

            var disconnected             = false;
            var disconnectedEvent        = new AutoResetEvent(false);
            var disconnectedEventHandler = new CommunicationEventHandler(() => disconnectedEvent.Set());

            var terminated             = false;
            var terminatedEvent        = new AutoResetEvent(false);
            var terminatedEventHandler = new ProcessTerminatedEventHandler((_) => terminatedEvent.Set());

            if (ClientProxy != null)
            {
                runtimeHost.ClientDisconnected += disconnectedEventHandler;
                ClientProcess.Terminated       += terminatedEventHandler;

                logger.Info("Instructing client to initiate shutdown procedure.");
                ClientProxy.InitiateShutdown();

                logger.Info("Disconnecting from client communication host.");
                ClientProxy.Disconnect();

                logger.Info("Waiting for client to disconnect from runtime communication host...");
                disconnected = disconnectedEvent.WaitOne(timeout_ms / 2);

                if (!disconnected)
                {
                    logger.Error($"Client failed to disconnect within {timeout_ms / 2 / 1000} seconds!");
                }

                logger.Info("Waiting for client process to terminate...");
                terminated = terminatedEvent.WaitOne(timeout_ms / 2);

                if (!terminated)
                {
                    logger.Error($"Client failed to terminate within {timeout_ms / 2 / 1000} seconds!");
                }

                runtimeHost.ClientDisconnected -= disconnectedEventHandler;
                ClientProcess.Terminated       -= terminatedEventHandler;
            }

            if (disconnected && terminated)
            {
                logger.Info("Client has been successfully terminated.");
                success = true;
            }
            else
            {
                logger.Warn("Attempting to kill client process since graceful termination failed!");
                success = TryKillClient();
            }

            if (success)
            {
                ClientProcess = null;
                ClientProxy   = null;
            }

            return(success);
        }