/// <summary>
        /// Get an <see cref="OAuthRequestToken"/> for the given callback URL.
        /// </summary>
        /// <remarks>Specify 'oob' as the callback for no callback to be performed.</remarks>
        /// <param name="callback">The callback Uri, or 'oob' if no callback is to be performed.</param>
        /// <returns></returns>
        public OAuthRequestToken OAuthGetRequestToken(string callback)
        {
            string url = "http://www.flickr.com/services/oauth/request_token";

            Dictionary <string, string> parameters = OAuthGetBasicParameters(false);

            parameters.Add("oauth_callback", callback);

            string sig = OAuthCalculateSignature("POST", url, parameters, null);

            parameters.Add("oauth_signature", sig);

            string response = FlickrResponder.GetDataResponse(this, url, parameters);;

            return(OAuthRequestToken.ParseResponse(response));
        }
        private T GetResponse <T>(Dictionary <string, string> parameters) where T : IFlickrParsable, new()
        {
            // Flow for GetResponse.
            // 2. Calculate Cache URL.
            // 3. Check Cache for URL.
            // 4. Get Response if not in cache.
            // 5. Write Cache.
            // 6. Parse Response.

            OAuthGetBasicParameters(parameters);

            string responseXml = FlickrResponder.GetDataResponse(this, BaseUri.AbsoluteUri, parameters);

            var reader = new XmlTextReader(new StringReader(responseXml))
            {
                WhitespaceHandling = WhitespaceHandling.None
            };

            if (!reader.ReadToDescendant("rsp"))
            {
                throw new XmlException("Unable to find response element 'rsp' in Flickr response");
            }
            while (reader.MoveToNextAttribute())
            {
                if (reader.LocalName == "stat" && reader.Value == "fail")
                {
                    //TODO:
                    //throw ExceptionHandler.CreateResponseException(reader);
                }
            }

            reader.MoveToElement();
            reader.Read();

            var item = new T();

            item.Load(reader);

            return(item);
        }
        /// <summary>
        /// For a given request token and verifier string return an access token.
        /// </summary>
        /// <param name="requestToken"></param>
        /// <param name="requestTokenSecret"></param>
        /// <param name="verifier"></param>
        /// <returns></returns>
        public OAuthAccessToken OAuthGetAccessToken(string requestToken, string requestTokenSecret, string verifier)
        {
            string url = "http://www.flickr.com/services/oauth/access_token";

            Dictionary <string, string> parameters = OAuthGetBasicParameters(false);

            parameters.Add("oauth_verifier", verifier);
            parameters.Add("oauth_token", requestToken);

            string sig = OAuthCalculateSignature("POST", url, parameters, requestTokenSecret);

            parameters.Add("oauth_signature", sig);

            string response = FlickrResponder.GetDataResponse(this, url, parameters);

            var accessToken = FlickrNet.OAuthAccessToken.ParseResponse(response);

            // Set current access token.
            OAuthAccessToken       = accessToken.Token;
            OAuthAccessTokenSecret = accessToken.TokenSecret;

            return(accessToken);
        }
        async private Task <string> UploadData(Stream imageStream, string fileName, Uri uploadUri, Dictionary <string, string> parameters, IProgress <UploadProgressChangedEventArgs> progress)
        {
            //string boundary = "FLICKR_MIME_" + DateTime.Now.ToString("yyyyMMddhhmmss", System.Globalization.DateTimeFormatInfo.InvariantInfo);

            //string authHeader = FlickrResponder.OAuthCalculateAuthHeader(parameters);
            //byte[] dataBuffer = CreateUploadData(imageStream, fileName, parameters, boundary);

            //HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(uploadUri);
            //req.Method = "POST";

            //req.Timeout = HttpTimeout;
            //req.ContentType = "multipart/form-data; boundary=" + boundary;
            ////req.Expect = String.Empty;
            //if (!String.IsNullOrEmpty(authHeader))
            //{
            //    req.Headers["Authorization"] = authHeader;
            //}

            //req.ContentLength = dataBuffer.Length;

            //using (Stream reqStream = req.GetRequestStream())
            //{
            //    int bufferSize = 32 * 1024;
            //    if (dataBuffer.Length / 100 > bufferSize) bufferSize = bufferSize * 2;

            //    int uploadedSoFar = 0;

            //    while (uploadedSoFar < dataBuffer.Length)
            //    {
            //        reqStream.Write(dataBuffer, uploadedSoFar, Math.Min(bufferSize, dataBuffer.Length - uploadedSoFar));
            //        uploadedSoFar += bufferSize;

            //        if (OnUploadProgress != null)
            //        {
            //            UploadProgressEventArgs args = new UploadProgressEventArgs(uploadedSoFar, dataBuffer.Length);
            //            OnUploadProgress(this, args);
            //        }
            //    }
            //    reqStream.Close();
            //}

            //HttpWebResponse res = (HttpWebResponse)req.GetResponse();

            //StreamReader sr = new StreamReader(res.GetResponseStream());
            //string s = sr.ReadToEnd();
            //sr.Close();
            //return s;

            string boundary = "FLICKR_MIME_" + DateTime.Now.ToString("yyyyMMddhhmmss", System.Globalization.DateTimeFormatInfo.InvariantInfo);

            string authHeader = FlickrResponder.OAuthCalculateAuthHeader(parameters);

            byte[] dataBuffer = CreateUploadData(imageStream, fileName, parameters, boundary);

            WebClient2 webClient = new WebClient2();

            //webClient.Timeout = (int)TimeSpan.FromMinutes(10).TotalMilliseconds;
            webClient.UploadProgressChanged += ((a, b) =>
            {
                if (progress != null)
                {
                    progress.Report(b);
                }
                if (FlickrLogic.CancellationToken.IsCancellationRequested)
                {
                    ((WebClient2)a).CancelAsync();
                }
            });

            webClient.ContentType = "multipart/form-data; boundary=" + boundary;

            if (!String.IsNullOrEmpty(authHeader))
            {
                webClient.Headers["Authorization"] = authHeader;
            }

            webClient.ContentLength = dataBuffer.Length;

            FlickrLogic.UploadEventList.Add(new Notice()
            {
                Type     = NoticeType.Upload,
                FullPath = fileName,
                Note     = "Ready to upload.",
            });
            byte[] responseArray = null;
            try
            {
                responseArray = await webClient.UploadDataTaskAsync(uploadUri, dataBuffer);
            }
            catch (Exception ex)
            {
                responseArray = null;
            }


            string s = System.Text.Encoding.UTF8.GetString(responseArray);

            return(s);
        }