/// <summary>
        /// Allows OAuth applications to directly exchange Twitter usernames and passwords for OAuth access tokens and secrets.
        /// </summary>
        /// <param name="consumerKey">The consumer key.</param>
        /// <param name="consumerSecret">The consumer secret.</param>
        /// <param name="username">The username.</param>
        /// <param name="password">The password.</param>
        /// <returns>A <see cref="OAuthTokenResponse"/> instance.</returns>
        public static OAuthTokenResponse GetAccessTokens(string consumerKey, string consumerSecret, string username, string password)
        {
            if (string.IsNullOrEmpty(consumerKey))
            {
                throw new ArgumentNullException("consumerKey");
            }

            if (string.IsNullOrEmpty(consumerSecret))
            {
                throw new ArgumentNullException("consumerSecret");
            }

            if (string.IsNullOrEmpty(username))
            {
                throw new ArgumentNullException("username");
            }

            if (string.IsNullOrEmpty(password))
            {
                throw new ArgumentNullException("password");
            }

            OAuthTokenResponse response = new OAuthTokenResponse();

            try
            {
                WebRequestBuilder builder = new WebRequestBuilder(
                    new Uri("https://api.twitter.com/oauth/access_token"),
                    HTTPVerb.POST,
                    new OAuthTokens() { ConsumerKey = consumerKey, ConsumerSecret = consumerSecret },
                    "");

                builder.Parameters.Add("x_auth_username", username);
                builder.Parameters.Add("x_auth_password", password);
                builder.Parameters.Add("x_auth_mode", "client_auth");

                string responseBody = new StreamReader(builder.ExecuteRequest().GetResponseStream()).ReadToEnd();

                response.Token = Regex.Match(responseBody, @"oauth_token=([^&]+)").Groups[1].Value;
                response.TokenSecret = Regex.Match(responseBody, @"oauth_token_secret=([^&]+)").Groups[1].Value;
                if (responseBody.Contains("user_id="))
                    response.UserId = long.Parse(Regex.Match(responseBody, @"user_id=([^&]+)").Groups[1].Value, CultureInfo.CurrentCulture);
                response.ScreenName = Regex.Match(responseBody, @"screen_name=([^&]+)").Groups[1].Value;
            }
            catch (WebException wex)
            {
                throw new Exception(wex.Message, wex);
            }

            return response;
        }
        public string GetUserInfo()
        {
            string requestUrl = string.Format("https://api.twitter.com/1/users/show.json?screen_name={0}&include_entities=false", this.ScreenName);

            OAuthTokens authTokens = new OAuthTokens() {

                AccessToken = this.AccessToken,
                AccessTokenSecret = this.AccessTokenSecret,
                ConsumerKey = this.ConsumerKey,
                ConsumerSecret = this.ConsumerSecret

            };

            WebRequestBuilder builder = new WebRequestBuilder(new Uri(requestUrl), OAuthLib.HTTPVerb.GET, authTokens, string.Empty);

            try
            {

                HttpWebResponse response = builder.ExecuteRequest();

                using (StreamReader sr = new StreamReader(response.GetResponseStream()))
                {
                    return sr.ReadToEnd();
                }//end using st

            } catch (Exception ex)
            {

                throw ex;

            }//end try catch
        }
        /// <summary>
        /// Share something on LinkedIn
        /// </summary>
        /// <returns>
        /// True if it succeeds. Otherwise throws an exception.
        /// </returns>
        /// <param name='message'>
        /// The message to send.
        /// </param>
        /// <param name='userID'>
        /// Not needed for LinkedIn. Just pass string.Empty.
        /// </param>
        public bool PostToFeed(string message, string userID)
        {
            // Share
            //string requestUrl = string.Format("http://api.linkedin.com/v1/people/~/shares");
            // Activity
            string requestUrl = "http://api.linkedin.com/v1/people/~/person-activities";

            OAuthTokens authTokens = new OAuthTokens() {

                ConsumerKey = this.ConsumerKey,
                ConsumerSecret = this.ConsumerSecret,
                AccessToken = this.AccessToken,
                AccessTokenSecret = this.AccessTokenSecret

            };

            WebRequestBuilder builder = new WebRequestBuilder(new Uri(requestUrl), HTTPVerb.POST, authTokens, string.Empty);
            byte[] postDataBuffer = Encoding.UTF8.GetBytes(message);

            try
            {

                HttpWebRequest request = builder.PrepareRequest();
                request.ContentType = "application/xml";
                request.ContentLength = postDataBuffer.Length;

                using (Stream s = request.GetRequestStream())
                {
                    s.Write(postDataBuffer, 0, postDataBuffer.Length);
                }//end using s

                using (StreamReader sr = new StreamReader(request.GetResponse().GetResponseStream()))
                {
                    #if(DEBUG)
                    Console.WriteLine("Response: {0}", sr.ReadToEnd());
                    #endif
                }//end using sr

                return true;

            } catch (Exception ex)
            {

                throw ex;

            }//end try catch
        }
        public string GetUserInfo()
        {
            string requestUrl = "http://api.linkedin.com/v1/people/~:(id,first-name,last-name,picture-url,date-of-birth,site-standard-profile-request,email-address)";

            OAuthTokens authTokens = new OAuthTokens() {

                ConsumerKey = this.ConsumerKey,
                ConsumerSecret = this.ConsumerSecret,
                AccessToken = this.AccessToken,
                AccessTokenSecret = this.AccessTokenSecret

            };

            WebRequestBuilder builder = new WebRequestBuilder(new Uri(requestUrl), OAuthLib.HTTPVerb.GET, authTokens, string.Empty);

            try
            {

                HttpWebResponse response = builder.ExecuteRequest();

                using (StreamReader sr = new StreamReader(response.GetResponseStream()))
                {
                    return sr.ReadToEnd();
                }//end using sr

            } catch (Exception ex)
            {
                throw ex;
            }//end try catch
        }
        public string GetUserFriends(int startIndex, int count)
        {
            string requestUrl = string.Format("http://api.linkedin.com/v1/people/~/connections:(id,first-name,last-name,picture-url,date-of-birth)?start={0}&count={1}", startIndex, count);

            OAuthTokens authTokens = new OAuthTokens() {

                ConsumerKey = this.ConsumerKey,
                ConsumerSecret = this.ConsumerSecret,
                AccessToken = this.AccessToken,
                AccessTokenSecret = this.AccessTokenSecret

            };

            WebRequestBuilder builder = new WebRequestBuilder(new Uri(requestUrl), OAuthLib.HTTPVerb.GET, authTokens, string.Empty);

            try
            {

                HttpWebResponse response = builder.ExecuteRequest();

                using (StreamReader sr = new StreamReader(response.GetResponseStream()))
                {
                    return sr.ReadToEnd();
                }//end using sr

            } catch (Exception ex)
            {
                throw ex;
            }//end try catch
        }
        public static OAuthTokenResponse GetAccessToken(string consumerKey, string consumerSecret, string requestToken, string accessTokenSecret, string verifier, string accessTokenUrl, HTTPVerb httpVerb, ServiceType serviceType)
        {
            if (string.IsNullOrEmpty(consumerKey))
            {
                throw new ArgumentNullException("consumerKey");
            }

            if (string.IsNullOrEmpty(consumerSecret))
            {
                throw new ArgumentNullException("consumerSecret");
            }

            if (string.IsNullOrEmpty(requestToken))
            {
                throw new ArgumentNullException("requestToken");
            }

            WebRequestBuilder builder = new WebRequestBuilder(
                new Uri(accessTokenUrl),
                httpVerb,
                //new OAuthTokens { ConsumerKey = consumerKey, ConsumerSecret = consumerSecret },
                new OAuthTokens { ConsumerKey = consumerKey, ConsumerSecret = consumerSecret, AccessToken = requestToken, AccessTokenSecret = accessTokenSecret },
                "");

            if (!string.IsNullOrEmpty(verifier))
            {
                builder.Parameters.Add("oauth_verifier", verifier);
            }

            builder.Parameters.Add("oauth_token", requestToken);

            string responseBody;

            try
            {
                HttpWebResponse webResponse = builder.ExecuteRequest();

                responseBody = new StreamReader(webResponse.GetResponseStream()).ReadToEnd();
            }
            catch (WebException wex)
            {
                throw new Exception(wex.Message, wex);
            }

            OAuthTokenResponse response = new OAuthTokenResponse();
            response.Token = Regex.Match(responseBody, @"oauth_token=([^&]+)").Groups[1].Value;
            response.TokenSecret = Regex.Match(responseBody, @"oauth_token_secret=([^&]+)").Groups[1].Value;

            if (serviceType == ServiceType.Twitter)
            {
                response.UserId = long.Parse(Regex.Match(responseBody, @"user_id=([^&]+)").Groups[1].Value, CultureInfo.CurrentCulture);
                response.ScreenName = Regex.Match(responseBody, @"screen_name=([^&]+)").Groups[1].Value;

            } else if (serviceType == ServiceType.DropBox)
            {

                response.UserId = long.Parse(Regex.Match(responseBody, @"uid=([^&]+)").Groups[1].Value, CultureInfo.CurrentCulture);

            }//end if
            return response;
        }
        //        #if !LITE && !SILVERLIGHT
        //        /// <summary>
        //        /// Gets the access token during callback.
        //        /// </summary>
        //        /// <param name="consumerKey">The consumer key.</param>
        //        /// <param name="consumerSecret">The consumer secret.</param>
        //        /// <returns>
        //        /// Access tokens returned by the Twitter API
        //        /// </returns>
        //        public static OAuthTokenResponse GetAccessTokenDuringCallback(string consumerKey, string consumerSecret)
        //        {
        //            
        //            HttpContext context = HttpContext.Current;
        //            if (context == null || context.Request == null)
        //            {
        //                throw new ApplicationException("Could not located the HTTP context. GetAccessTokenDuringCallback can only be used in ASP.NET applications.");
        //            }
        //
        //            string requestToken = context.Request.QueryString["oauth_token"];
        //            string verifier = context.Request.QueryString["oauth_verifier"];
        //
        //            if (string.IsNullOrEmpty(requestToken))
        //            {
        //                throw new ApplicationException("Could not locate the request token.");
        //            }
        //
        //            if (string.IsNullOrEmpty(verifier))
        //            {
        //                throw new ApplicationException("Could not locate the verifier value.");
        //            }
        //
        //            return GetAccessToken(consumerKey, consumerSecret, requestToken, verifier);
        //        }
        //
        //        /// <summary>
        //        /// Adds the OAuth Echo header to the supplied web request.
        //        /// </summary>
        //        /// <param name="request">The request.</param>
        //        /// <param name="tokens">The tokens.</param>
        //        public static void AddOAuthEchoHeader(WebRequest request, OAuthTokens tokens)
        //        {
        //            WebRequestBuilder builder = new WebRequestBuilder(
        //                new Uri("https://api.twitter.com/1/account/verify_credentials.json"),
        //                HTTPVerb.POST,
        //                tokens,
        //                "");
        //
        //            builder.PrepareRequest();
        //
        //            request.Headers.Add("X-Verify-Credentials-Authorization", builder.GenerateAuthorizationHeader());
        //            request.Headers.Add("X-Auth-Service-Provider", "https://api.twitter.com/1/account/verify_credentials.json");
        //        }
        //#endif

        #endregion Other

        #if !SILVERLIGHT

        public static OAuthTokenResponse GetRequestToken(string consumerKey, string consumerSecret, string callbackAddress, WebProxy proxy, string requestTokenUrl, HTTPVerb httpVerb)
        {
            if (string.IsNullOrEmpty(consumerKey))
            {
                throw new ArgumentNullException("consumerKey");
            }

            if (string.IsNullOrEmpty(consumerSecret))
            {
                throw new ArgumentNullException("consumerSecret");
            }

            if (string.IsNullOrEmpty(callbackAddress))
            {
                throw new ArgumentNullException("callbackAddress", @"You must always provide a callback url when obtaining a request token. For PIN-based authentication, use ""oob"" as the callback url.");
            }

            WebRequestBuilder builder = new WebRequestBuilder(
                new Uri(requestTokenUrl),
                httpVerb,
                new OAuthTokens { ConsumerKey = consumerKey, ConsumerSecret = consumerSecret },
                "") { Proxy = proxy };

            if (!string.IsNullOrEmpty(callbackAddress))
            {
                builder.Parameters.Add("oauth_callback", callbackAddress);
            }

            string responseBody = null;

            try
            {
                HttpWebResponse webResponse = builder.ExecuteRequest();
                Stream responseStream = webResponse.GetResponseStream();
                if (responseStream != null) responseBody = new StreamReader(responseStream).ReadToEnd();
            }
            catch (WebException wex)
            {
                throw new Exception(wex.Message, wex);
            }

            Match matchedValues = Regex.Match(responseBody,
                                              @"oauth_token=(?<token>[^&]+)|oauth_token_secret=(?<secret>[^&]+)|oauth_verifier=(?<verifier>[^&]+)");

            return new OAuthTokenResponse
            {
                Token = matchedValues.Groups["token"].Value,
                TokenSecret = matchedValues.Groups["secret"].Value,
                VerificationString = matchedValues.Groups["verifier"].Value
            };
        }
        /// <summary>
        /// Gets the request token.
        /// </summary>
        /// <param name="consumerKey">The consumer key.</param>
        /// <param name="consumerSecret">The consumer secret.</param>
        /// <param name="callbackAddress">The callback address. For PIN-based authentication "oob" should be supplied.</param>
        /// <returns></returns>
        public static OAuthTokenResponse GetRequestToken(string consumerKey, string consumerSecret, string callbackAddress, string requestTokenUrl, HTTPVerb httpVerb)
        {
            if (string.IsNullOrEmpty(consumerKey))
            {
                throw new ArgumentNullException("consumerKey");
            }

            if (string.IsNullOrEmpty(consumerSecret))
            {
                throw new ArgumentNullException("consumerSecret");
            }

            if (string.IsNullOrEmpty(callbackAddress))
            {
                throw new ArgumentNullException("callbackAddress", @"You must always provide a callback url when obtaining a request token. For PIN-based authentication, use ""oob"" as the callback url.");
            }

            WebRequestBuilder builder = new WebRequestBuilder(
                new Uri(requestTokenUrl),
                httpVerb,
                new OAuthTokens { ConsumerKey = consumerKey, ConsumerSecret = consumerSecret },
                "");

            if (!string.IsNullOrEmpty(callbackAddress))
            {
                builder.Parameters.Add("oauth_callback", callbackAddress);
            }

            string responseBody = null;

            try
            {
                HttpWebResponse webResponse = builder.ExecuteRequest();
                Stream responseStream = webResponse.GetResponseStream();
                if (responseStream != null) responseBody = new StreamReader(responseStream).ReadToEnd();
            }
            catch (WebException wex)
            {
                throw new Exception(wex.Message, wex);
            }

            return new OAuthTokenResponse
            {
                Token = ParseQuerystringParameter("oauth_token", responseBody),
                TokenSecret = ParseQuerystringParameter("oauth_token_secret", responseBody),
                VerificationString = ParseQuerystringParameter("oauth_verifier", responseBody)
            };
        }