/// <summary>
        /// The methods provided in this section are simply used to allow
        /// NavigationHelper to respond to the page's navigation methods.
        /// <para>
        /// Page specific logic should be placed in event handlers for the
        /// <see cref="NavigationHelper.LoadState"/>
        /// and <see cref="NavigationHelper.SaveState"/>.
        /// The navigation parameter is available in the LoadState method
        /// in addition to page state preserved during an earlier session.
        /// </para>
        /// </summary>
        /// <param name="e">Provides data for navigation methods and event
        /// handlers that cannot cancel the navigation request.</param>
        protected async override void OnNavigatedTo(NavigationEventArgs e)
        {
            this.navigationHelper.OnNavigatedTo(e);
            var tuple = e.Parameter as Tuple <Config, Uri, Guid>;

            if (tuple == null)
            {
                textOutput.Text = "";
                return;
            }
            // authorization response
            var config   = tuple.Item1;
            var response = tuple.Item2;
            var state    = tuple.Item3;

            // show authorization response
            textOutput.Text = response.ToString();
            // get access token with authorization code
            TokenResponse accessToken = await RelyingParty.GetAccessToken(config, response, state);

            if (accessToken == null)
            {
                return;
            }
            // show access token
            textOutput.Text = accessToken.AccessToken;
            // get userinfo with access token
            UserInfo userinfo = await RelyingParty.GetUserInfo(config, accessToken);

            if (userinfo == null)
            {
                return;
            }
            // show email or username
            textOutput.Text = string.IsNullOrWhiteSpace(userinfo.Mail)
                ? userinfo.UserName
                : userinfo.Mail;
        }