/// <summary>
        /// Create a new subscription to this hub for the supplied repository information and shared secret.
        /// </summary>
        /// <param name="repositoryXml"></param>
        /// <remarks></remarks>
        /// <returns>The client repository information retrieved from the server.</returns>
        public async Task <ClientRepositoryXml> CreateSubscription(ClientRepositoryXml repositoryXml)
        {
            var request = new ClientRepositoryUploadRequest(repositoryXml);

            //we have to use distinct credentials for this so we have to swap the credentials on the connection.
            var channel = await GetCurrentChannel().ConfigureAwait(false);

            bool retry;

            do
            {
                retry = false; //so we'll exit by default
                try
                {
                    await channel.ExecuteRequest(request, 1).ConfigureAwait(false);
                }
                catch (WebChannelAuthorizationException ex)
                {
                    //request better credentials..
                    Logger.Write(LogMessageSeverity.Warning, ex, true, LogCategory,
                                 "Requesting updated credentials for the server connection due to " + ex.GetType(),
                                 "We're going to assume the user can provide current credentials.\r\nDetails: {0}", ex.Message);
                    retry = CachedCredentialsManager.UpdateCredentials(channel, m_ClientRepositoryId, true);

                    if (retry == false)
                    {
                        throw;
                    }
                }
            } while (retry);

            return(request.ResponseRepository);
        }
        /// <summary>
        /// Execute the provided request.
        /// </summary>
        /// <param name="newRequest"></param>
        /// <param name="maxRetries">The maximum number of times to retry the connection.  Use -1 to retry indefinitely.</param>
        public async Task ExecuteRequest(IWebRequest newRequest, int maxRetries)
        {
            //make sure we have a channel
            WebChannel channel = await GetCurrentChannel().ConfigureAwait(false); //this throws exceptions when it can't connect and is thread safe.

            //if we have a channel and NOW get an exception, here is where we would recheck the status of our connection.
            bool retryAuthentication = false;
            bool resetAndRetry       = false;

            try
            {
                await channel.ExecuteRequest(newRequest, maxRetries).ConfigureAwait(false);
            }
            catch (WebChannelAuthorizationException ex)
            {
                //request better credentials..
                Logger.Write(LogMessageSeverity.Warning, ex, true, LogCategory,
                             "Requesting updated credentials for the server connection due to " + ex.GetType(),
                             "We're going to assume the user can provide current credentials.\r\nDetails: {0}", ex.Message);
                if (CachedCredentialsManager.UpdateCredentials(channel, m_ClientRepositoryId, false))
                {
                    //they entered new creds.. lets give them a go.
                    retryAuthentication = true;
                }
                else
                {
                    //they canceled, lets call it.
                    throw;
                }
            }
            catch (WebChannelConnectFailureException)
            {
                //clear our current channel and try again if we're on a child server.
                if (IsRootHub(channel.HostName, channel.Port, channel.UseSsl, channel.ApplicationBaseDirectory) == false)
                {
                    resetAndRetry = true;
                }
            }

            if (retryAuthentication)
            {
                await ExecuteRequest(newRequest, maxRetries).ConfigureAwait(false);
            }
            else if (resetAndRetry)
            {
                await ResetChannel().ConfigureAwait(false); //safely clears the current channel and gets a fresh one if possible
            }
        }
        /// <summary>
        /// Connect to the hub (or another hub if the configured hub is redirecting)
        /// </summary>
        /// <returns>The last web channel it was able to connect to after processing redirections, if that channel is available.</returns>
        private async Task <HubConnectionStatus> Connect()
        {
            var connectionStatus = await Connect(m_RootConfiguration).ConfigureAwait(false);

            if (connectionStatus.Channel != null)
            {
                //copy our current settings into it.
                lock (m_Lock)
                {
                    connectionStatus.Channel.EnableLogging = m_EnableLogging;

                    if (m_UseCredentials)
                    {
                        connectionStatus.Channel.AuthenticationProvider = CachedCredentialsManager.GetCredentials(connectionStatus.Channel, m_UseRepositoryCredentials, m_ClientRepositoryId, m_KeyContainerName, m_UseMachineStore);
                    }

                    System.Threading.Monitor.PulseAll(m_Lock);
                }
            }

            return(connectionStatus);
        }