/// <summary>
        /// Launch the elevated child process, if not already running and start an IPC listener thread.
        /// </summary>
        /// <returns>True if success, false otherwise.</returns>
        private bool InitiateBroker()
        {
            if (!Broker.IsActive())
            {
                if (!Broker.LaunchChildProcess())
                {
                    return(false);
                }
            }

            brokerIPC = Manager.Broker.GetBrokerIPC();
            return(true);
        }
        /// <summary>
        /// Sends a disconnect command to the Broker.
        /// </summary>
        /// <param name="runBroker">Creates a new broker instance if there isn't one already available.</param>
        /// <returns>True if successfully sent disconnection command.</returns>
        public bool Disconnect(bool runBroker = true)
        {
            uptimeStart = DateTime.MinValue;
            SetDisconnecting();
            Manager.Broker.ReportHeartbeat();

            if (!runBroker && !Broker.IsActive())
            {
                ClearConnectionTransitionState();
                return(false);
            }

            if (!InitiateBroker())
            {
                ClearConnectionTransitionState();
                return(false);
            }

            var connectMessage = new IPCMessage(IPCCommand.IpcDisconnect);

            brokerIPC.WriteToPipe(connectMessage);

            return(true);
        }
        /// <summary>
        /// Retrieves the current connection status of the Tunnel.
        /// </summary>
        /// <returns>Object depicting the current status.</returns>
        public Models.ConnectionStatus ConnectionStatus()
        {
            // Broker process checks
            if (!Broker.IsActive())
            {
                if (IsConnecting == false && IsDisconnecting == false)
                {
                    // Not connecting, not disconnecting, tunnel is not up and user is unprotected
                    return(new Models.ConnectionStatus()
                    {
                        Status = Models.ConnectionState.Unprotected
                    });
                }
                else if (IsConnecting == true)
                {
                    // We are currently only connecting
                    return(new Models.ConnectionStatus()
                    {
                        Status = Models.ConnectionState.Connecting
                    });
                }
                else if (IsDisconnecting == true)
                {
                    // We are currently only disconnecting
                    return(new Models.ConnectionStatus()
                    {
                        Status = Models.ConnectionState.Disconnecting
                    });
                }
            }

            // Broker process is running, do tunnel service checks
            if (Service.IsTunnelServiceRunning())
            {
                // Service is now running, clear transitioning states and query statistics
                ClearConnectionTransitionState();
                return(QueryConnectionStatisticsFromTunnel());
            }

            if (!Service.IsTunnelServiceRunning() && IsDisconnecting)
            {
                // Service is not running, we should clear the connection transition state as the disconnection is now complete
                ClearConnectionTransitionState();
            }

            // Broker process is running, but the tunnel service is not running
            if (IsConnecting == false)
            {
                // We are not in a connecting state, meaning if the tunnel service is down, the user is unprotected
                return(new Models.ConnectionStatus()
                {
                    Status = Models.ConnectionState.Unprotected
                });
            }
            else if (IsConnecting == true)
            {
                // We are currently only connecting
                return(new Models.ConnectionStatus()
                {
                    Status = Models.ConnectionState.Connecting
                });
            }
            else if (IsDisconnecting == true)
            {
                // We are currently only disconnecting
                return(new Models.ConnectionStatus()
                {
                    Status = Models.ConnectionState.Disconnecting
                });
            }

            // No previous checks apply, the user is unprotected
            return(new Models.ConnectionStatus()
            {
                Status = Models.ConnectionState.Unprotected
            });
        }