private void HandlePixbufLoaded(FSpot.PixbufCache Cache, FSpot.PixbufCache.CacheEntry entry)
        {
            Gdk.Pixbuf result = entry.ShallowCopyPixbuf();
            int        order  = (int)entry.Data;

            if (result == null)
            {
                return;
            }

            // We have to do the scaling here rather than on load because we need to preserve the
            // Pixbuf option iformation to verify the thumbnail validity later
            int width, height;

            PixbufUtils.Fit(result, ThumbnailWidth, ThumbnailHeight, false, out width, out height);
            if (result.Width > width && result.Height > height)
            {
                //  Log.Debug ("scaling");
                Gdk.Pixbuf temp = PixbufUtils.ScaleDown(result, width, height);
                result.Dispose();
                result = temp;
            }
            else if (result.Width < ThumbnailWidth && result.Height < ThumbnailHeight)
            {
                // FIXME this is a workaround to handle images whose actual size is smaller than
                // the thumbnail size, it needs to be fixed at a different level.
                Gdk.Pixbuf temp = new Gdk.Pixbuf(Gdk.Colorspace.Rgb, true, 8, ThumbnailWidth, ThumbnailHeight);
                temp.Fill(0x00000000);
                result.CopyArea(0, 0,
                                result.Width, result.Height,
                                temp,
                                (temp.Width - result.Width) / 2,
                                temp.Height - result.Height);

                result.Dispose();
                result = temp;
            }

            Cache.Update(entry, result);
            InvalidateCell(order);
        }
        // FIXME Cache the GCs?
        protected virtual void DrawPhoto(int cell_num, Rectangle cell_area, Rectangle expose_area, bool selected, bool focussed)
        {
            if (!cell_area.Intersect(expose_area, out expose_area))
            {
                return;
            }

            IPhoto photo = Collection [cell_num];

            FSpot.PixbufCache.CacheEntry entry = Cache.Lookup(photo.DefaultVersion.Uri);
            if (entry == null)
            {
                Cache.Request(photo.DefaultVersion.Uri, cell_num, ThumbnailWidth, ThumbnailHeight);
            }
            else
            {
                entry.Data = cell_num;
            }

            StateType cell_state = selected ? (HasFocus ? StateType.Selected : StateType.Active) : State;

            if (cell_state != State)
            {
                Style.PaintBox(Style, BinWindow, cell_state,
                               ShadowType.Out, expose_area, this, "IconView",
                               cell_area.X, cell_area.Y,
                               cell_area.Width - 1, cell_area.Height - 1);
            }

            Gdk.Rectangle focus = Gdk.Rectangle.Inflate(cell_area, -3, -3);

            if (HasFocus && focussed)
            {
                Style.PaintFocus(Style, BinWindow,
                                 cell_state, expose_area,
                                 this, null,
                                 focus.X, focus.Y,
                                 focus.Width, focus.Height);
            }

            Gdk.Rectangle region       = Gdk.Rectangle.Zero;
            Gdk.Rectangle image_bounds = Gdk.Rectangle.Inflate(cell_area, -CELL_BORDER_WIDTH, -CELL_BORDER_WIDTH);
            int           expansion    = ThrobExpansion(cell_num, selected);

            Gdk.Pixbuf thumbnail = null;
            if (entry != null)
            {
                thumbnail = entry.ShallowCopyPixbuf();
            }

            Gdk.Rectangle draw = Gdk.Rectangle.Zero;
            if (Gdk.Rectangle.Inflate(image_bounds, expansion + 1, expansion + 1).Intersect(expose_area, out image_bounds) && thumbnail != null)
            {
                PixbufUtils.Fit(thumbnail, ThumbnailWidth, ThumbnailHeight,
                                true, out region.Width, out region.Height);

                region.X = (int)(cell_area.X + (cell_area.Width - region.Width) / 2);
                region.Y = (int)cell_area.Y + ThumbnailHeight - region.Height + CELL_BORDER_WIDTH;

                if (Math.Abs(region.Width - thumbnail.Width) > 1 &&
                    Math.Abs(region.Height - thumbnail.Height) > 1)
                {
                    Cache.Reload(entry, cell_num, thumbnail.Width, thumbnail.Height);
                }

                region = Gdk.Rectangle.Inflate(region, expansion, expansion);
                Pixbuf temp_thumbnail;
                region.Width  = System.Math.Max(1, region.Width);
                region.Height = System.Math.Max(1, region.Height);

                if (Math.Abs(region.Width - thumbnail.Width) > 1 &&
                    Math.Abs(region.Height - thumbnail.Height) > 1)
                {
                    if (region.Width < thumbnail.Width && region.Height < thumbnail.Height)
                    {
                        /*
                         * temp_thumbnail = PixbufUtils.ScaleDown (thumbnail,
                         *      region.Width, region.Height);
                         */
                        temp_thumbnail = thumbnail.ScaleSimple(region.Width, region.Height,
                                                               InterpType.Bilinear);


                        lock (entry) {
                            if (entry.Reload && expansion == 0 && !entry.IsDisposed)
                            {
                                entry.SetPixbufExtended(temp_thumbnail.ShallowCopy(), false);
                                entry.Reload = true;
                            }
                        }
                    }
                    else
                    {
                        temp_thumbnail = thumbnail.ScaleSimple(region.Width, region.Height,
                                                               InterpType.Bilinear);
                    }
                }
                else
                {
                    temp_thumbnail = thumbnail;
                }

                // FIXME There seems to be a rounding issue between the
                // scaled thumbnail sizes, we avoid this for now by using
                // the actual thumnail sizes here.
                region.Width  = temp_thumbnail.Width;
                region.Height = temp_thumbnail.Height;

                draw = Gdk.Rectangle.Inflate(region, 1, 1);

                if (!temp_thumbnail.HasAlpha)
                {
                    Style.PaintShadow(Style, BinWindow, cell_state,
                                      ShadowType.Out, expose_area, this,
                                      "IconView",
                                      draw.X, draw.Y,
                                      draw.Width, draw.Height);
                }

                if (region.Intersect(expose_area, out draw))
                {
                    Cms.Profile screen_profile;
                    if (FSpot.ColorManagement.Profiles.TryGetValue(Preferences.Get <string> (Preferences.COLOR_MANAGEMENT_DISPLAY_PROFILE), out screen_profile))
                    {
                        Pixbuf t = temp_thumbnail.Copy();
                        temp_thumbnail.Dispose();
                        temp_thumbnail = t;
                        FSpot.ColorManagement.ApplyProfile(temp_thumbnail, screen_profile);
                    }
                    temp_thumbnail.RenderToDrawable(BinWindow, Style.WhiteGC,
                                                    draw.X - region.X,
                                                    draw.Y - region.Y,
                                                    draw.X, draw.Y,
                                                    draw.Width, draw.Height,
                                                    RgbDither.None,
                                                    draw.X, draw.Y);
                }

                if (temp_thumbnail != thumbnail)
                {
                    temp_thumbnail.Dispose();
                }
            }

            if (thumbnail != null)
            {
                thumbnail.Dispose();
            }

            // Render Decorations
            if (DisplayRatings && region.X == draw.X && region.X != 0)
            {
                rating_renderer.Render(BinWindow, this, region, expose_area, cell_state, photo);
            }

            // Render Captions
            Rectangle caption_area = Rectangle.Zero;

            caption_area.Y     = cell_area.Y + CELL_BORDER_WIDTH + ThumbnailHeight + CAPTION_PADDING;
            caption_area.X     = cell_area.X + CELL_BORDER_WIDTH;
            caption_area.Width = cell_area.Width - 2 * CELL_BORDER_WIDTH;

            if (DisplayDates)
            {
                caption_area.Height = date_renderer.GetHeight(this, ThumbnailWidth);
                date_renderer.Render(BinWindow, this, caption_area, expose_area, cell_state, photo);

                caption_area.Y += caption_area.Height;
            }

            if (DisplayFilenames)
            {
                caption_area.Height = filename_renderer.GetHeight(this, ThumbnailWidth);
                filename_renderer.Render(BinWindow, this, caption_area, expose_area, cell_state, photo);

                caption_area.Y += caption_area.Height;
            }

            if (DisplayTags)
            {
                caption_area.Height = tag_renderer.GetHeight(this, ThumbnailWidth);
                tag_renderer.Render(BinWindow, this, caption_area, expose_area, cell_state, photo);

                caption_area.Y += caption_area.Height;
            }
        }