// Makes an OAuth signature out of the HTTP method, the base URI and the headers
        static string MakeSignature(string method, string base_uri, Dictionary <string, string> headers)
        {
            var items = from k in headers.Keys
                        orderby k
                        select k + "%3D" + OAuthUtils.PercentEncode(headers[k]);

            return(method + "&" + OAuthUtils.PercentEncode(base_uri) + "&" +
                   string.Join("%26", items.ToArray()));
        }
        /// <summary>Acquires the request token.</summary>
        ///
        /// <returns>true if it succeeds, false if it fails.</returns>
        public bool AcquireRequestToken()
        {
            var headers = new Dictionary <string, string>()
            {
                { "oauth_callback", OAuthUtils.PercentEncode(provider.CallbackUrl) },
                { "oauth_consumer_key", provider.ConsumerKey },
                { "oauth_nonce", MakeNonce() },
                { "oauth_signature_method", "HMAC-SHA1" },
                { "oauth_timestamp", MakeTimestamp() },
                { "oauth_version", "1.0" }
            };

            var uri = new Uri(provider.RequestTokenUrl);

            var signatureHeaders = new Dictionary <string, string>(headers);

            var nvc = HttpUtility.ParseQueryString(uri.Query);

            foreach (string key in nvc)
            {
                if (key != null)
                {
                    signatureHeaders.Add(key, OAuthUtils.PercentEncode(nvc[key]));
                }
            }

            string signature           = MakeSignature("POST", uri.GetLeftPart(UriPartial.Path), signatureHeaders);
            string compositeSigningKey = MakeSigningKey(provider.ConsumerSecret, null);
            string oauth_signature     = MakeOAuthSignature(compositeSigningKey, signature);

            var wc = new WebClient();

            headers.Add("oauth_signature", OAuthUtils.PercentEncode(oauth_signature));
            wc.Headers[HttpRequestHeader.Authorization] = HeadersToOAuth(headers);

            try
            {
                var result = HttpUtility.ParseQueryString(wc.UploadString(new Uri(provider.RequestTokenUrl), ""));

                if (result["oauth_callback_confirmed"] != null)
                {
                    RequestToken       = result["oauth_token"];
                    RequestTokenSecret = result["oauth_token_secret"];

                    return(true);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                string responseBody = e.GetResponseBody();
                responseBody.Print();
                // fallthrough for errors
            }
            return(false);
        }
        //
        // Assign the result to the Authorization header, like this:
        // request.Headers [HttpRequestHeader.Authorization] = AuthorizeRequest (...)
        //
        public static string AuthorizeRequest(OAuthProvider provider, string oauthToken, string oauthTokenSecret, string method, Uri uri, string data)
        {
            var headers = new Dictionary <string, string>()
            {
                { "oauth_consumer_key", provider.ConsumerKey },
                { "oauth_nonce", MakeNonce() },
                { "oauth_signature_method", "HMAC-SHA1" },
                { "oauth_timestamp", MakeTimestamp() },
                { "oauth_token", oauthToken },
                { "oauth_version", "1.0" }
            };
            var signatureHeaders = new Dictionary <string, string>(headers);

            // Add the data and URL query string to the copy of the headers for computing the signature
            if (data != null && data != "")
            {
                var parsed = HttpUtility.ParseQueryString(data);
                foreach (string k in parsed.Keys)
                {
                    signatureHeaders.Add(k, OAuthUtils.PercentEncode(parsed[k]));
                }
            }

            var nvc = HttpUtility.ParseQueryString(uri.Query);

            foreach (string key in nvc)
            {
                if (key != null)
                {
                    signatureHeaders.Add(key, OAuthUtils.PercentEncode(nvc[key]));
                }
            }

            string signature           = MakeSignature(method, uri.GetLeftPart(UriPartial.Path), signatureHeaders);
            string compositeSigningKey = MakeSigningKey(provider.ConsumerSecret, oauthTokenSecret);
            string oauth_signature     = MakeOAuthSignature(compositeSigningKey, signature);

            headers.Add("oauth_signature", OAuthUtils.PercentEncode(oauth_signature));

            return(HeadersToOAuth(headers));
        }
        //
        // Used to authorize an HTTP request going to TwitPic
        //
        public static void AuthorizeTwitPic(OAuthProvider provider, HttpWebRequest wc, string oauthToken, string oauthTokenSecret)
        {
            var headers = new Dictionary <string, string>()
            {
                { "oauth_consumer_key", provider.ConsumerKey },
                { "oauth_nonce", MakeNonce() },
                { "oauth_signature_method", "HMAC-SHA1" },
                { "oauth_timestamp", MakeTimestamp() },
                { "oauth_token", oauthToken },
                { "oauth_version", "1.0" },
                //{ "realm", "http://api.twitter.com" }
            };
            string signurl = "http://api.twitter.com/1/account/verify_credentials.xml";
            // The signature is not done against the *actual* url, it is done against the verify_credentials.json one
            string signature           = MakeSignature("GET", signurl, headers);
            string compositeSigningKey = MakeSigningKey(provider.ConsumerSecret, oauthTokenSecret);
            string oauth_signature     = MakeOAuthSignature(compositeSigningKey, signature);

            headers.Add("oauth_signature", OAuthUtils.PercentEncode(oauth_signature));

            //Util.Log ("Headers: " + HeadersToOAuth (headers));
            wc.Headers.Add("X-Verify-Credentials-Authorization", HeadersToOAuth(headers));
            wc.Headers.Add("X-Auth-Service-Provider", signurl);
        }
        // Invoked after the user has authorized us
        //
        // TODO: this should return the stream error for invalid passwords instead of
        // just true/false.
        public bool AcquireAccessToken()
        {
            var headers = new Dictionary <string, string>()
            {
                { "oauth_consumer_key", provider.ConsumerKey },
                { "oauth_nonce", MakeNonce() },
                { "oauth_signature_method", "HMAC-SHA1" },
                { "oauth_timestamp", MakeTimestamp() },
                { "oauth_version", "1.0" }
            };
            var content = "";

            if (xAuthUsername == null)
            {
                headers.Add("oauth_token", OAuthUtils.PercentEncode(AuthorizationToken));
                headers.Add("oauth_verifier", OAuthUtils.PercentEncode(AuthorizationVerifier));
            }
            else
            {
                headers.Add("x_auth_username", OAuthUtils.PercentEncode(xAuthUsername));
                headers.Add("x_auth_password", OAuthUtils.PercentEncode(xAuthPassword));
                headers.Add("x_auth_mode", "client_auth");
                content = String.Format("x_auth_mode=client_auth&x_auth_password={0}&x_auth_username={1}", OAuthUtils.PercentEncode(xAuthPassword), OAuthUtils.PercentEncode(xAuthUsername));
            }

            string signature           = MakeSignature("POST", provider.AccessTokenUrl, headers);
            string compositeSigningKey = MakeSigningKey(provider.ConsumerSecret, RequestTokenSecret);
            string oauth_signature     = MakeOAuthSignature(compositeSigningKey, signature);

            var wc = new WebClient();

            headers.Add("oauth_signature", OAuthUtils.PercentEncode(oauth_signature));
            if (xAuthUsername != null)
            {
                headers.Remove("x_auth_username");
                headers.Remove("x_auth_password");
                headers.Remove("x_auth_mode");
            }
            wc.Headers[HttpRequestHeader.Authorization] = HeadersToOAuth(headers);

            try
            {
                var result = HttpUtility.ParseQueryString(wc.UploadString(new Uri(provider.AccessTokenUrl), content));

                if (result["oauth_token"] != null)
                {
                    AccessToken       = result["oauth_token"];
                    AccessTokenSecret = result["oauth_token_secret"];
                    AuthInfo          = result.ToDictionary();

                    return(true);
                }
            }
            catch (WebException e)
            {
                var x = e.Response.GetResponseStream();
                var j = new System.IO.StreamReader(x);
                Console.WriteLine(j.ReadToEnd());
                Console.WriteLine(e);
                // fallthrough for errors
            }
            return(false);
        }
 static string MakeSigningKey(string consumerSecret, string oauthTokenSecret)
 {
     return(OAuthUtils.PercentEncode(consumerSecret) + "&" + (oauthTokenSecret != null ? OAuthUtils.PercentEncode(oauthTokenSecret) : ""));
 }