private void browser_Navigating(object sender, Microsoft.Phone.Controls.NavigatingEventArgs e)
        {
            // show the overlay
            //
            overlay.Visibility = System.Windows.Visibility.Visible;
            browser.Visibility = System.Windows.Visibility.Collapsed;

            // if we somehow got to the home page, redirect to the login page.
            // this will kick off our login process and result in us getting an access token.
            //
            if (FacebookUrls.IsFacebookHome(e.Uri))
            {
                GotoLoginPage();
                e.Cancel = true;
                return;
            }

            // if we see the redirect URL that we passed as part of the login process,
            // we know that we need to start looking for parameters.
            //
            if (FacebookUrls.IsRedirectUrl(e.Uri))
            {
                Status = "Processing Login...";
                string query = e.Uri.Query;
                if (!ProcessParams(query))
                {
                    e.Cancel = true;
                }
            }
        }
        /// <summary>
        /// This function walks parameters looking for tokens, etc.
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        private bool ProcessParams(string query)
        {
            // pick out all of the params.
            Match queryParams = Regex.Match(query, "(?<name>[^?=&]+)(=(?<value>[^&]*)?)");

            string access_token       = null;
            string code               = null;
            int    expires_in_seconds = -1;
            bool?  fail               = null;
            string error              = null;

            // walk through the matches looking for code, access_token, and expiration.
            //
            while (queryParams.Success)
            {
                string value = queryParams.Groups["value"].Value;

                switch (queryParams.Groups["name"].Value)
                {
                // Due to the URL # problem in the WebBrowser control, we need to do this process in two steps,
                // which is to first get a code that we can then exchange for a token.  This code parameter is
                // what we need.
                //
                case "code":
                    code = value;
                    string tokenAccessUrl = FacebookUrls.GetTokenUrl(code);

                    // now just use a web request rather than the browser to load up the
                    // actual page that will have the access token..
                    HttpWebRequest hwr = HttpWebRequest.CreateHttp(tokenAccessUrl);

                    hwr.BeginGetResponse(
                        (asyncObject) =>
                    {
                        try {
                            HttpWebResponse resp = (HttpWebResponse)hwr.EndGetResponse(asyncObject);

                            var c = resp.StatusCode;
                            if (c == HttpStatusCode.OK)
                            {
                                string html = new StreamReader(resp.GetResponseStream()).ReadLine();
                                Dispatcher.BeginInvoke(
                                    () =>
                                {
                                    // recurse with the content of the page.
                                    ProcessParams(html);
                                });
                            }
                        }
                        catch (WebException ex) {
                            Debug.WriteLine(ex.ToString());
                        }
                    }
                        , null);

                    return(false);

                case "access_token":
                    access_token = value;
                    fail         = false;
                    break;

                case "state":
                    fail = (value != FacebookUrls.VerificationState);
                    break;

                case "error":
                    fail = true;
                    break;

                case "error_description":
                    fail  = true;
                    error = value;
                    break;

                case "expires":
                    expires_in_seconds = int.Parse(value);
                    break;
                }
                queryParams = queryParams.NextMatch();
            }

            // if we don't hae a failure and we do have an access token,
            // fire the completion event.
            //
            if (!fail.GetValueOrDefault() && access_token != null)
            {
                FacebookLoginEventArgs args = new FacebookLoginEventArgs {
                    AccessToken = access_token,
                    Error       = error,
                    Expiration  = DateTime.Now.AddSeconds(expires_in_seconds)
                };
                OnComplete(args);
            }
            return(true);
        }