/// <summary>
        /// Twitter と通信をする。
        /// </summary>
        /// <param name="method">通信メソッド</param>
        /// <param name="url">URL</param>
        /// <param name="query">クエリ文字列</param>
        /// <returns></returns>
        private WebResponse BasicTwitterAccess(string method, string url)
        {
            string nonce = GetNonce();
            long time = GetTime();

            string signature = GetSignature(this._consumersecret, this._accesstokensecret,
                method + "&" + UrlEncode(url) + "&" + UrlEncode(GetParamString(_consumerkey, nonce, null, time, this._accesstoken, null, null)));

            HttpWebRequest hwr = (HttpWebRequest)HttpWebRequest.Create(url);
            hwr.Method = method;
            hwr.Headers.Add(HttpRequestHeader.Authorization, GetHeaderAuthorityString(this._consumerkey, nonce, signature, time, this._accesstoken));

            WebResponse r = null;

            try
            {
                r = hwr.GetResponse();
            }
            catch
            {
                this._status = TwitterLibraryStatus.Failed;
            }

            this._status = TwitterLibraryStatus.Success;
            return r;
        }
        public TwitterLibrary(string consumerkey, string consumersecret)
        {
            this._consumerkey = consumerkey;
            this._consumersecret = consumersecret;

            this._status = TwitterLibraryStatus.NeedPinOrToken;
            if (this._accesstokensecret != null && this._accesstoken != null)
            {
                this._status = TwitterLibraryStatus.Authorized;
                return;
            }
        }
        /// <summary>
        /// つぶやく。
        /// </summary>
        /// <param name="str">つぶやき内容</param>
        /// <param name="reply_status_id">Reply を送るときの対象ID</param>
        /// <returns>成功かどうか</returns>
        public bool Update(string str, string reply_status_id = null)
        {
            string nonce = GetNonce();
            long time = GetTime();

            string tweet = UrlEncode(str);

            string signature = GetSignature(this._consumersecret, this._accesstokensecret,
                "POST&" + UrlEncode(this._update_url) + "&" + (reply_status_id != null ? ("in_reply_to_status_id%3D" + reply_status_id + "%26") : "") +
                "include_entities%3Dtrue" +
                "%26" + UrlEncode(GetParamString(_consumerkey, nonce, null, time, this._accesstoken, null, tweet)));

            HttpWebRequest hwr = (HttpWebRequest)HttpWebRequest.Create(this._update_url);
            hwr.Method = "POST";
            hwr.ServicePoint.Expect100Continue = false;
            hwr.ContentType = "application/x-www-form-urlencoded";
            hwr.Headers.Add(HttpRequestHeader.Authorization, GetHeaderAuthorityString(this._consumerkey, nonce, signature, time, this._accesstoken));

            var message = new StreamWriter(hwr.GetRequestStream());
            message.Write("status=" + tweet + "&include_entities=true" + (reply_status_id != null ? ("&in_reply_to_status_id=" + reply_status_id) : ""));
            message.Close();

            try
            {
                var ret = hwr.GetResponse();
                ret.Close();
            }
            catch
            {
                this._status = TwitterLibraryStatus.Failed;
                return false;
            }

            this._status = TwitterLibraryStatus.Success;
            return true;
        }
        /// <summary>
        /// ツイート検索
        /// </summary>
        /// <param name="query">検索</param>
        public void Search(string query)
        {
            HttpWebRequest hwr = (HttpWebRequest)HttpWebRequest.Create(this._search_url + "?q=" + UrlEncode(query));
            hwr.Method = "GET";

            WebResponse r = null;

            try
            {
                r = hwr.GetResponse();
            }
            catch
            {
                this._status = TwitterLibraryStatus.Failed;
                return;
            }

            this._status = TwitterLibraryStatus.Success;

            if (r != null)
            {
                var stream = new StreamReader(r.GetResponseStream());
                var tweets = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(stream.ReadToEnd())["results"] as ArrayList;

                for (int i = tweets.Count - 1; i >= 0; i--)
                {
                    var info = tweets[i] as Dictionary<string, object>;
                    UserStreams(info["id_str"] as string, info["from_user"] as string, info["from_user_name"] as string, info["text"] as string);
                }
            }
        }
        /// <summary>
        /// Twitter にログインを行う。
        /// </summary>
        /// <returns>認証成功かどうか。</returns>
        public bool Login()
        {
            string nonce = GetNonce();
            long time = GetTime();

            if (this._accesstokensecret != null && this._accesstoken != null)
            {
                this._status = TwitterLibraryStatus.Authorized;
                return true;
            }
            if (this._pin == "")
            {
                this._status = TwitterLibraryStatus.NeedPinOrToken;
                return false;
            }

            var signature = GetSignature(this._consumersecret, null,
                        "POST&" + UrlEncode(this._accesstoken_url) + "&" + GetParamString(this._consumerkey, nonce, null, time, this._request_token, this._pin, null));
            var hwr = (HttpWebRequest)HttpWebRequest.Create(this._accesstoken_url + "?" + GetParamString(this._consumerkey, nonce, signature, time, this._request_token, this._pin, null));
            hwr.Method = "POST";
            hwr.Headers.Add("Authorization", "OAuth");

            WebResponse webret;

            try
            {
                webret = hwr.GetResponse();
            }
            catch
            {
                this._status = TwitterLibraryStatus.AuthorizationFailed;
                return false;
            }

            string[] response = new StreamReader(webret.GetResponseStream()).ReadToEnd().Split('&');

            foreach (string s in response)
            {
                if (s.IndexOf("oauth_token=") != -1)
                    this._accesstoken = s.Substring(s.IndexOf("=") + 1);

                if (s.IndexOf("oauth_token_secret=") != -1)
                    this._accesstokensecret = s.Substring(s.IndexOf("=") + 1);
            }

            this._status = TwitterLibraryStatus.Authorized;

            return true;
        }
        /// <summary>
        /// 指定ユーザの直近20件のタイムラインを取得する。
        /// <param name="screenname">Twitter ID ex.) mimura1133</param>
        /// </summary>
        public void GetUserTimeline(string screenname)
        {
            HttpWebRequest hwr = (HttpWebRequest)HttpWebRequest.Create(this._getusertimeline_url + "?include_entities=true&screen_name=" + screenname);
            hwr.Method = "GET";

            WebResponse r = null;

            try
            {
                r = hwr.GetResponse();
            }
            catch
            {
                this._status = TwitterLibraryStatus.Failed;
                return;
            }

            this._status = TwitterLibraryStatus.Success;

            var stream = new StreamReader(r.GetResponseStream());
            var tweets = new JavaScriptSerializer().Deserialize<ArrayList>(stream.ReadToEnd());

            for (int i = tweets.Count - 1; i >= 0; i--)
            {
                var tweet = tweets[i] as Dictionary<string, object>;

                if (tweet.ContainsKey("user") && tweet.ContainsKey("text"))
                {
                    var user = tweet["user"] as Dictionary<string, object>;
                    this.UserStreams(tweet["id_str"] as string, user["screen_name"] as string, user["name"] as string, tweet["text"] as string);
                }
            }
        }
        /// <summary>
        /// PIN コード取得画面を出す。
        /// </summary>
        /// <returns>URL</returns>
        public string GetPinURL()
        {
            string nonce = GetNonce();
            long time = GetTime();

            var signature = GetSignature(this._consumersecret, null, "POST&" + UrlEncode(this._requesttoken_url) + "&" + UrlEncode(GetParamString(this._consumerkey, nonce, null, time, null, null, null)));
            var hwr = (HttpWebRequest)HttpWebRequest.Create(this._requesttoken_url + "?" + GetParamString(this._consumerkey, nonce, signature, time, null, null, null));
            hwr.Method = "POST";

            WebResponse webret;

            try
            {
                webret = hwr.GetResponse();
            }
            catch
            {
                this._status = TwitterLibraryStatus.AuthorizationFailed;
                return "";
            }

            string[] response = new StreamReader(webret.GetResponseStream()).ReadToEnd().Split('&');

            foreach (string s in response)
            {
                if (s.IndexOf("oauth_token=") != -1)
                    this._request_token = s.Substring(s.IndexOf("=") + 1);

                if (s.IndexOf("oauth_token_secret=") != -1)
                    this._request_token_secret = s.Substring(s.IndexOf("=") + 1);
            }

            this._status = TwitterLibraryStatus.NeedPinOrToken;
            return this._authorize_url + "?oauth_token=" + this._request_token;
        }