public async void GetPhotoSetListAsync(string userId)
        {
            string timestamp = DateTimeUtils.GetTimestamp();
            string nonce = Guid.NewGuid().ToString().Replace("-", null);

            string paramString = "oauth_nonce=" + nonce;
            paramString += "&oauth_consumer_key=" + consumerKey;
            paramString += "&oauth_signature_method=HMAC-SHA1";
            paramString += "&oauth_timestamp=" + timestamp;
            paramString += "&oauth_version=1.0";
            paramString += "&oauth_token=" + AccessToken;
            paramString += "&format=json&nojsoncallback=1";
            paramString += "&user_id=" + userId;
            paramString += "&method=flickr.photosets.getList";

            string signature = GenerateSignature("GET", AccessTokenSecret, "https://api.flickr.com/services/rest/", paramString);
            string requestUrl = "https://api.flickr.com/services/rest/?" + paramString + "&oauth_signature=" + signature;
            HttpWebResponse response = await DispatchRequest("GET", requestUrl, null).ConfigureAwait(false);
            using (StreamReader reader = new StreamReader(response.GetResponseStream()))
            {
                GetPhotoSetListExceptionEventArgs exceptionEvt = null;

                if (response.StatusCode != HttpStatusCode.OK)
                {
                    HandleHTTPException(response);

                    exceptionEvt = new GetPhotoSetListExceptionEventArgs();
                    exceptionEvt.UserId = userId;
                    GetPhotoSetListException.DispatchEvent(this, exceptionEvt);
                    return;
                }

                string jsonString = await reader.ReadToEndAsync().ConfigureAwait(false);
                if (!TryHandleResponseException(jsonString, () => { GetPhotoSetListAsync(userId); }))
                {
                    exceptionEvt = new GetPhotoSetListExceptionEventArgs();
                    exceptionEvt.UserId = userId;
                    GetPhotoSetListException.DispatchEvent(this, exceptionEvt);

                    return;
                }

                PhotoSetListEventArgs evt = new PhotoSetListEventArgs();
                evt.UserId = userId;
                evt.Response = jsonString;
                PhotoSetListReturned.DispatchEvent(this, evt);
            }

        }
        private void PhotoListReturned(object sender, PhotoSetListEventArgs e)
        {
            JObject json = JObject.Parse(e.Response);
            JObject photosetJson = (JObject)json["photosets"];

            bool canCreate = photosetJson["cancreate"].ToString().ParseBool();
            int page = int.Parse(photosetJson["page"].ToString());
            int perPage = int.Parse(photosetJson["perpage"].ToString());
            int numTotal = int.Parse(photosetJson["total"].ToString());

            PhotoSetList.Clear();
            foreach (var ps in photosetJson["photoset"])
            {
                PhotoSet photoset = PhotoSetFactory.PhotoSetWithJObject((JObject)ps);
                PhotoSetList.Add(photoset);
            }

            // Dispatch event
            PhotoSetListUpdatedEventArgs args = new PhotoSetListUpdatedEventArgs();
            args.CanCreate = canCreate;
            args.Page = page;
            args.PerPage = perPage;
            args.TotalCount = numTotal;
            args.UserId = e.UserId;
            PhotoSetListUpdated.DispatchEvent(this, args);
        }