// Photo stream updated
        private void OnPhotoStreamUpdated(object sender, PhotoStreamUpdatedEventArgs e)
        {
            Dispatcher.BeginInvoke(() =>
            {
                if (e.UserId != Cinderella.CinderellaCore.CurrentUser.ResourceId)
                    return;

                if (e.NewPhotos.Count == 0 && PhotoCollection.Count != 0)
                    return;

                // Always fill in first page
                List<Photo> photos = null;
                if (PhotoCollection.Count == 0)
                {
                    StatusProgressBar.Visibility = Visibility.Collapsed;

                    StatusView.Visibility = Visibility.Collapsed;
                    photos = Cinderella.CinderellaCore.CurrentUser.Photos;
                }
                else
                    photos = e.NewPhotos;

                foreach (var photo in photos)
                {
                    SelectablePhoto photoItem = new SelectablePhoto();
                    photoItem.PhotoSource = photo;
                    photoItem.Selected = (SelectedPhotos.Contains(photo.ResourceId));
                    PhotoCollection.Add(photoItem);
                }
            });
        }
        // Photo stream updated
        private void OnPhotoStreamUpdated(object sender, PhotoStreamUpdatedEventArgs e)
        {
            Dispatcher.BeginInvoke(() => {
                if (e.UserId != UserSource.ResourceId)
                    return;

                if (SystemTray.ProgressIndicator != null)
                    SystemTray.ProgressIndicator.IsVisible = false;

                if (e.NewPhotos.Count == 0 && PhotoCollection.Count == 0)
                {
                    StatusLabel.Text = AppResources.GenericNoContentFound;
                    StatusLabel.Visibility = Visibility.Visible;
                    PhotoStreamListView.Visibility = Visibility.Collapsed;
                    return;
                }

                StatusLabel.Visibility = Visibility.Collapsed;
                PhotoStreamListView.Visibility = Visibility.Visible;

                if (e.NewPhotos.Count == 0)
                    return;

                if (e.Page == 1)
                    PhotoCollection.Clear();

                List<PhotoGroup> newGroups = rendererFactory.GeneratePhotoGroups(e.NewPhotos);
                foreach (var group in newGroups)
                {
                    PhotoCollection.Add(group);
                }
            });
        }
        // Photo stream retrieved for a user
        private void PhotoStreamReturned(object sender, GetPhotoStreamEventArgs e)
        {
            // Find the user
            if (!UserCache.ContainsKey(e.UserId))
                return;

            User user = UserCache[e.UserId];

            JObject rawJson = JObject.Parse(e.Response);
            JObject rootJson = (JObject)rawJson["photos"];
            user.PhotoCount = int.Parse(rootJson["total"].ToString());
            int page = int.Parse(rootJson["page"].ToString());
            int numPages = int.Parse(rootJson["pages"].ToString());
            int perPage = int.Parse(rootJson["perpage"].ToString());

            List<Photo> newPhotos = new List<Photo>();
            foreach (var entry in rootJson["photo"])
            {
                JObject json = (JObject)entry;
                Photo photo = PhotoFactory.PhotoWithJObject(json);

                if (!user.Photos.Contains(photo))
                {
                    user.Photos.Add(photo);
                    newPhotos.Add(photo);
                }
            }

            // Dispatch event
            PhotoStreamUpdatedEventArgs evt = new PhotoStreamUpdatedEventArgs();
            evt.Page = page;
            evt.PageCount = numPages;
            evt.PerPage = perPage;
            evt.NewPhotos = newPhotos;
            evt.UserId = e.UserId;
            PhotoStreamUpdated.DispatchEvent(this, evt);
        }
        // Photo stream updated
        private void OnPhotoStreamUpdated(object sender, PhotoStreamUpdatedEventArgs e)
        {
            Dispatcher.BeginInvoke(() => {
                if (e.UserId != Cinderella.CinderellaCore.CurrentUser.ResourceId)
                    return;

                if (Cinderella.CinderellaCore.CurrentUser.Photos.Count == 0)
                {
                    StatusLabel.Text = "No photos available";
                    StatusLabel.Visibility = Visibility.Visible;
                    PhotoStreamListView.Visibility = Visibility.Collapsed;
                    return;
                }

                StatusLabel.Visibility = Visibility.Collapsed;
                PhotoStreamListView.Visibility = Visibility.Visible;

                if (e.NewPhotos.Count == 0)
                    return;

                List<PhotoGroup> newGroups = null;
                if (PhotoCollection.Count >= 1 && PhotoCollection[0].IsHeadline)
                {
                    newGroups = rendererFactory.GeneratePhotoGroups(e.NewPhotos);
                }
                else
                {
                    newGroups = rendererFactory.GeneratePhotoGroupsWithHeadline(e.NewPhotos);
                }

                foreach (var group in newGroups)
                {
                    PhotoCollection.Add(group);
                }

                UpdateStreamVisibility();

                // Update live tiles
                var tilePhotos = new List<Photo>();
                for (int i = 0; i < Math.Min(LiveTileUpdateService.MAX_TILE_IMAGE_COUNT, e.NewPhotos.Count); i++)
                {
                    var photo = e.NewPhotos[i];
                    tilePhotos.Add(photo);
                }

                LiveTileUpdateService.Instance.StartNewRequests(tilePhotos);
            });
        }