public static async Task<PhotoStreamPayload> GetPhotoStream(string pageNum)
        {
            string endpoint = CreateEndpointUrl("flickr.people.getPublicPhotos",
                new List<string>() 
                { 
                    "user_id=" + userId,
                    "extras=url_c,url_s,media,description,date_taken",
                    "page=" + pageNum
                });

            string payload = await GetJsonStringPayloadFrom(endpoint);
            string trimmedPayload = TrimFlickrString(payload);

            var photoStreamDTO =
                JsonConvert.DeserializeObject<PhotoStreamDTO>(trimmedPayload);

            var photoStreamList = new List<FlickrMedia>();

            foreach (var p in photoStreamDTO.photos.photo)
            {
                FlickrMedia photo = new FlickrMedia()
                {
                    PhotoId = UInt64.Parse(p.id),
                    Secret = p.secret,
                    Title = p.title,
                    Description = p.description._content,
                    IsVideo = p.media != "photo",
                    DateTaken = GetDTFromTimestamp(p.datetaken),
                    ImgUrlLarge = p.url_c,
                    ImgUrlSmall = p.url_s
                };

                photo.VideoUrlHq = (photo.IsVideo) ?
                    CreateVideoUrl(photo.PhotoId, photo.Secret, true) : null;
                photo.VideoUrlLq = (photo.IsVideo) ?
                    CreateVideoUrl(photo.PhotoId, photo.Secret, false) : null;

                photoStreamList.Add(photo);
            }

            var psPayload = new PhotoStreamPayload()
            {
                photos = photoStreamList,
                total = photoStreamDTO.photos.total
            };

            return psPayload;
        }
        public static async Task<AlbumPhotosPayload> GetAlbumPhotos(string albumId, string pageNum)
        {
            string endpoint = CreateEndpointUrl("flickr.photosets.getPhotos",
                new List<string>() 
                { 
                    "user_id=" + userId,
                    "photoset_id=" + albumId,
                    "extras=url_c,url_s,media,description,date_taken",
                    "page=" + pageNum,
                    "per_page=100"
                });

            string payload = await GetJsonStringPayloadFrom(endpoint);
            string trimmedPayload = TrimFlickrString(payload);

            var albumPhotosDTO =
                JsonConvert.DeserializeObject<AlbumPhotosDTO>(trimmedPayload);

            AlbumPhotosPayload albumPhotosDetails = new AlbumPhotosPayload()
            {
                Title = albumPhotosDTO.photoset.title,
                Total = albumPhotosDTO.photoset.total
            };

            List<FlickrMedia> photoList = new List<FlickrMedia>();
            foreach (var p in albumPhotosDTO.photoset.photo)
            {
                FlickrMedia photo = new FlickrMedia()
                {
                    PhotoId = UInt64.Parse(p.id),
                    Secret = p.secret,
                    Title = p.title,
                    Description = p.description._content,
                    IsVideo = p.media != "photo",
                    DateTaken = GetDTFromTimestamp(p.datetaken),
                    ImgUrlLarge = p.url_c,
                    ImgUrlSmall = p.url_s
                };

                photo.VideoUrlHq = (photo.IsVideo) ?
                    CreateVideoUrl(photo.PhotoId, photo.Secret, true) : null;
                photo.VideoUrlLq = (photo.IsVideo) ?
                    CreateVideoUrl(photo.PhotoId, photo.Secret, false) : null;

                photoList.Add(photo);
            }
   
            string description = await GetAlbumDescription(albumId);
            albumPhotosDetails.Photos = photoList;
            albumPhotosDetails.Description = description;

            return albumPhotosDetails;
        }
        private static async Task<FlickrMedia> AddPhotoInfo(FlickrMedia photo)
        {
            string endpoint = CreateEndpointUrl("flickr.photos.getInfo",
                new List<string>() 
                { 
                    "photo_id=" + photo.PhotoId.ToString()
                });

            string payload = await GetJsonStringPayloadFrom(endpoint);
            string trimmedPayload = TrimFlickrString(payload);

            var flickrPhotoInfoDTO = 
                JsonConvert.DeserializeObject<PhotoInfoDTO>(trimmedPayload);

            photo.Secret = flickrPhotoInfoDTO.photo.secret;
            photo.Title = flickrPhotoInfoDTO.photo.title._content;
            photo.Description = flickrPhotoInfoDTO.photo.description._content;
            photo.IsVideo = flickrPhotoInfoDTO.photo.media == "video";
            photo.DateTaken = GetDTFromTimestamp(flickrPhotoInfoDTO.photo.dates.taken);

            return photo;
        }
        private static async Task<FlickrMedia> AddPhotoURLs(FlickrMedia photo)
        {
            string endpoint = CreateEndpointUrl("flickr.photos.getSizes",
                new List<string>() 
                { 
                    "photo_id=" + photo.PhotoId.ToString()
                });

            string payload = await GetJsonStringPayloadFrom(endpoint);
            string trimmedPayload = TrimFlickrString(payload);

            var flickrPhotoSizesDTO =
                JsonConvert.DeserializeObject<PhotoSizesDTO>(trimmedPayload);

            photo.ImgUrlLarge =
                flickrPhotoSizesDTO.sizes.size
                .Where(s => s.label == "Original")
                .FirstOrDefault()
                .source;

            photo.ImgUrlSmall =
                flickrPhotoSizesDTO.sizes.size
                .Where(s => s.label == "Small 320")
                .FirstOrDefault()
                .source;

            if (photo.IsVideo)
            {
                photo.VideoUrlHq =
                    flickrPhotoSizesDTO.sizes.size
                    .Where(s => s.label == "HD MP4")
                    .FirstOrDefault()
                    .source;

                photo.VideoUrlLq =
                    flickrPhotoSizesDTO.sizes.size
                    .Where(s => s.label == "Mobile MP4")
                    .FirstOrDefault()
                    .source;
            }

            return photo;
        }
        public static async Task<FlickrMedia> GetPhoto(ulong photoId)
        {
            FlickrMedia photo = new FlickrMedia() { PhotoId = photoId };

            // Getting a single photo's FlickrMedia property values requires
            // 2 different Flickr API calls
            photo = await AddPhotoInfo(photo);
            photo = await AddPhotoURLs(photo);

            return photo;
        }