/// <summary>
        /// Retrieve a signin link for a user based on the Connection Name. This is then used for the user to click and authenticate, generating a token returned back to the Token store.
        /// </summary>
        /// <param name="userId">The user id value.</param>
        /// <param name="credentialProvider">The credential provider value.</param>
        /// <param name="connectionName">The connection name value.</param>
        /// <param name="finalRedirect">The final redirect value.</param>
        /// <returns>Sign in link string value.</returns>
        public async Task <string> GetSignInLinkAsync(string userId, ICredentialProvider credentialProvider, string connectionName, string finalRedirect)
        {
            // The BotFramework Adapter, Bot ApplicationID and Bot Secret is required to access the Token APIs
            // These must match the Bot making use of the Linked Accounts feature.
            var adapter        = new BotFrameworkAdapter(credentialProvider);
            var botAppId       = ((ConfigurationCredentialProvider)credentialProvider).AppId;
            var botAppPassword = ((ConfigurationCredentialProvider)credentialProvider).Password;

            string link = null;

            using (var context = new TurnContext(adapter, new Microsoft.Bot.Schema.Activity {
            }))
            {
                var connectorClient = new ConnectorClient(new Uri(TokenServiceUrl), botAppId, botAppPassword);
                context.TurnState.Add <IConnectorClient>(connectorClient);

                // Retrieve a signin link for a given Connection Name and UserId
                link = await adapter.GetOauthSignInLinkAsync(context, connectionName, userId, finalRedirect);

                // Add on code_challenge (SessionId) into the redirect
                var sessionId = SessionController.Sessions.FirstOrDefault(s => s.Key == userId).Value;

                if (!string.IsNullOrEmpty(sessionId))
                {
                    link += HttpUtility.UrlEncode($"&code_challenge={sessionId}");
                }
            }

            return(link);
        }