diff -pru dillo/src/cache.c dillo.dicache-new/src/cache.c
--- dillo/src/cache.c	Tue Oct 16 14:43:40 2001
+++ dillo.dicache-new/src/cache.c	Fri Nov  2 16:43:40 2001
@@ -236,7 +236,7 @@ gint Cache_entry_remove_raw(CacheData_t 
       !g_slist_find_custom(ClientQueue, url, Cache_client_url_cmp), 0);
 
    /* remove from dicache */
-   a_Dicache_remove(entry->Url, -1);
+   a_Dicache_invalidate_entry(url);
 
    /* remove from cache */
    a_Url_free((DilloUrl *)entry->Url);
@@ -386,9 +386,9 @@ gint a_Cache_open_url(void *web, CA_Call
       /* This is a verbatim request */
       ClientKey = Cache_open_url(Web, Call, CbData);
 
-   } else if ( (DicEntry = a_Dicache_get_entry(Url)) != NULL ) {
+   } else if ( (DicEntry = a_Dicache_get_entry(Url)) && 
+	       (entry = Cache_entry_search(Url)) ) {
       /* We have it in the Dicache! */
-      entry = Cache_entry_search(Url);
       ClientKey = Cache_client_enqueue(entry->Url, Web, Call, CbData);
       Cache_delayed_process_queue(entry);
 
diff -pru dillo/src/dicache.c dillo.dicache-new/src/dicache.c
--- dillo/src/dicache.c	Fri Oct 19 14:19:42 2001
+++ dillo.dicache-new/src/dicache.c	Mon Nov  5 11:00:44 2001
@@ -9,141 +9,214 @@
  * (at your option) any later version.
  */
 
-
+#include <glib.h>           /* GHashTable functions */
 #include <gtk/gtk.h>
 #include <sys/time.h>       /* for libc5 compatibility */
 #include <string.h>         /* for memset */
 #include <stdio.h>
-#include "IO/IO.h"
 
-#include "list.h"
 #include "image.h"
-#include "dillo.h"
 #include "web.h"
 #include "dicache.h"
 #include "cache.h"
 #include "interface.h"
 
+typedef struct _DICacheHashEntry DICacheHashEntry;
+
+struct _DICacheHashEntry {
+   gint valid;
+   DilloUrl *url;       /* "Key" of this hash entry */
+   DICacheEntry* next;  /* pointer to the first dicache entry in this list */
+};
 
-static DICacheEntry **dicache;
-static gint dicache_size;
-static gint dicache_size_max;
+static GHashTable *dicache_hash;
 
 static gint dicache_size_total; /* invariant: dicache_size_total is
                                  * the sum of the image sizes of all
                                  * cache lines in dicache. */
-static gint dicache_counter;
+
+/* 
+ * Determine if two hash entries are equal (used by GHashTable)
+ */
+gint Dicache_hash_entry_equal(gconstpointer v1, gconstpointer v2)
+{
+   return (!a_Url_cmp((DilloUrl *)v1, (DilloUrl *)v2));
+}
+
+/*
+ * Determine the hash value given the key (used by GHashTable)
+ */
+guint Dicache_url_hash(gconstpointer key)
+{
+   return g_str_hash(URL_STR(((DilloUrl *)key)));
+}
 
 /*
  * Initialize dicache data
  */
 void a_Dicache_init(void)
 {
-   dicache_size = 0;
-   dicache_size_max = 16;
-   dicache = g_new(DICacheEntry *, dicache_size_max);
-
+   dicache_hash = g_hash_table_new(Dicache_url_hash, Dicache_hash_entry_equal);
    dicache_size_total = 0;
-   dicache_counter = 0;
 }
 
 /*
- * Create and initialize a new cache entry with safe values
+ * Create, initialize and add a new cache entry to the hash
  */
-DICacheEntry *Dicache_entry_new(const DilloUrl *Url)
+DICacheEntry *a_Dicache_add_entry(const DilloUrl *Url)
 {
-   static gint DicKey = 0;
    DICacheEntry *entry;
-
-   if ( ++DicKey < 0 ) DicKey = 1;
+   DICacheHashEntry *hash_entry;
 
    entry = g_new(DICacheEntry, 1);
-   entry->Key = DicKey;
-   entry->url = a_Url_dup(Url);
    entry->width = 0;
    entry->height = 0;
    entry->type = DILLO_IMG_TYPE_NOTSET;
    entry->cmap = NULL;
    entry->ImageBuffer = NULL;
+   entry->RefCount = 1;
 
    entry->TotalSize = 0;
    entry->Y = 0;
    entry->BitVec = NULL;
    entry->State = DIC_Empty;
 
-   return entry;
-}
+   entry->next = NULL;
+   if ( (hash_entry = g_hash_table_lookup(dicache_hash, Url))) {
+      /* this URL is already in the hash, add entry at the END of the list */
+      DICacheEntry *ptr = hash_entry->next;
+     
+      hash_entry->valid = 1;
+      while (ptr->next) ptr = ptr->next;
+      ptr->next = entry;
+      entry->version = ptr->version+1;
+      entry->url = hash_entry->url;
+   }
+   else { /* no hash entry yet, so create one */
+      DICacheHashEntry *hash_entry = g_new(DICacheHashEntry, 1);
 
-/*
- * Add an entry to the dicache
- */
-DICacheEntry *a_Dicache_add_entry(const DilloUrl *Url)
-{
-   /* Allocate memory */
-   a_List_add(dicache, dicache_size, sizeof(*dicache), dicache_size_max);
-   dicache[dicache_size] = Dicache_entry_new(Url);
-   dicache_size++;
-   return dicache[dicache_size - 1];
+      hash_entry->url = a_Url_dup(Url);
+      entry->url = hash_entry->url;
+      hash_entry->next = entry;
+      hash_entry->valid = 1;
+      g_hash_table_insert(dicache_hash, hash_entry->url, hash_entry);
+   }
+
+   return entry;
 }
 
 /*
- * Search an entry in the dicache (given the Url)
- * Return value: a pointer to the entry if found; NULL otherwise.
+ * Search an entry in the dicache (given the Url).
+ * Return value: a pointer to the entry of the _newest_ (i.e. highest) 
+ *               version if found; NULL otherwise.
  */
 DICacheEntry *a_Dicache_get_entry(const DilloUrl *Url)
 {
-   gint i;
+   DICacheHashEntry *hash_entry = g_hash_table_lookup(dicache_hash, Url);
+   DICacheEntry *entry;
 
-   for (i = dicache_size - 1; i >= 0; i--) {
-      if ( !a_Url_cmp(Url, dicache[i]->url) )
-         return dicache[i];
-   }
-   return NULL;
+   if (!hash_entry || !hash_entry->valid)
+      return NULL;
+
+   entry = hash_entry->next;
+   while (entry && entry->next) entry = entry->next;
+
+   return entry;
 }
 
 /*
- * Search an entry in the dicache (given the DicEntryKey)
+ * Search a particular version of an URL in the Dicache.
  * Return value: a pointer to the entry if found; NULL otherwise.
  */
-DICacheEntry *a_Dicache_get_entry_by_key(gint Key)
+DICacheEntry *Dicache_get_entry_version(const DilloUrl *Url, gint version) 
 {
-   gint i;
+   DICacheHashEntry *hash_entry = g_hash_table_lookup(dicache_hash, Url);
+   DICacheEntry *entry = hash_entry ? hash_entry->next : NULL;
+   
+   while (entry && entry->version != version) 
+      entry = entry->next;
 
-   for (i = dicache_size - 1; i >= 0; i--) {
-      if ( dicache[i]->Key == Key )
-         return dicache[i];
-   }
-   return NULL;
+   return entry;
 }
 
 /*
- * Remove a dicache entry (Using Url or DicKey as primary Key)
+ * Actually free a dicache entry, given the URL and the version number.
  */
-void a_Dicache_remove(const DilloUrl *Url, gint DicKey)
+void Dicache_remove(const DilloUrl *Url, gint version)
 {
-   gint i;
-   DICacheEntry *entry = NULL;
+   DICacheHashEntry *hash_entry = g_hash_table_lookup(dicache_hash, Url);
+   DICacheEntry *entry = hash_entry ? hash_entry->next : NULL, *prev = entry;
 
-   for (i = 0; i < dicache_size; ++i) {
-      entry = dicache[i];
-      if ( (Url && !a_Url_cmp(Url, entry->url)) || DicKey == entry->Key )
-         break;
+   while (entry && (entry->version != version) ) {
+      prev = entry;
+      entry = entry->next;
    }
 
-   if ( i < dicache_size ) {
+   if ( entry ) {
       /* Eliminate this dicache entry */
-      a_Url_free(entry->url);
       g_free(entry->cmap);
       if (entry->ImageBuffer) {
          g_free(entry->ImageBuffer);
          dicache_size_total -= entry->TotalSize;
       }
       a_Bitvec_free(entry->BitVec);
+
+      if (hash_entry->next == entry) {
+	 if (!entry->next) {
+	    /* last entry with this URL. Remove the hash entry as well */
+	    g_hash_table_remove(dicache_hash, hash_entry->url);
+	    a_Url_free(hash_entry->url);
+	    g_free(hash_entry);
+	 }
+	 else
+	    hash_entry->next = entry->next;
+      } 
+      else
+	 prev->next = entry->next;
       g_free(entry);
-      dicache[i] = dicache[--dicache_size];
    }
 }
 
+/*
+ * Unrefs the counter of a dicache entry, and _if_ no DwImage is acessing 
+ * this buffer _and_ there is a higher version of this image, then we call 
+ * Dicache_free to do the dirty job.
+ */
+void a_Dicache_unref(const DilloUrl *Url, gint version)
+{
+   DICacheEntry *entry = NULL;
+
+   if ( (entry = Dicache_get_entry_version(Url, version)) )
+      if (--entry->RefCount == 0 && entry->next)
+         Dicache_remove(Url, version);
+}
+
+/*
+ * Refs the counter of a dicache entry.
+ */
+
+DICacheEntry* a_Dicache_ref(const DilloUrl *Url, gint version)
+{
+   DICacheEntry *entry;
+
+   if ( (entry = Dicache_get_entry_version(Url, version)) )
+      ++entry->RefCount;
+
+   return entry;
+}
+
+/*
+ * Invalidate this entry. This is used for the reloading mechanism.
+ * Can't erase current versions, but a_Dicache_get_entry must return NULL.
+ */
+void a_Dicache_invalidate_entry(const DilloUrl *Url)
+{
+   DICacheHashEntry *hash_entry = g_hash_table_lookup(dicache_hash, Url);
+
+   if (hash_entry) hash_entry->valid = 0;
+}
+
+
 // -------------------------------------------------------------------------
 
 /*
@@ -162,8 +235,9 @@ void a_Dicache_callback(int Op, CacheCli
    if ( Op == CA_Send ) {
       if ( Image->height == 0 && DicEntry->State >= DIC_SetParms ) {
          /* Set parms */
-         a_Image_set_parms(Image, DicEntry->ImageBuffer,
-                           DicEntry->width, DicEntry->height, DicEntry->type);
+         a_Image_set_parms(Image, DicEntry->ImageBuffer, DicEntry->url,
+			   DicEntry->version, DicEntry->width, DicEntry->height,
+			   DicEntry->type);
       }
       if ( DicEntry->State == DIC_Write ) {
 
@@ -186,7 +260,7 @@ void a_Dicache_callback(int Op, CacheCli
  * Set image's width, height & type
  * (By now, we'll use the image information despite the html tags --Jcid)
  */
-void a_Dicache_set_parms(gint DicEntryKey, DilloImage *Image,
+void a_Dicache_set_parms(DilloUrl *url, gint version, DilloImage *Image,
                          gint width, gint height, DilloImgType type)
 {
    DICacheEntry *DicEntry;
@@ -194,7 +268,7 @@ void a_Dicache_set_parms(gint DicEntryKe
 
    g_return_if_fail ( Image != NULL && width && height );
    /* Find the DicEntry for this Image */
-   DicEntry = a_Dicache_get_entry_by_key(DicEntryKey);
+   DicEntry = Dicache_get_entry_version(url, version);
    g_return_if_fail ( DicEntry != NULL );
 
    /* Initialize the DicEntry */
@@ -206,20 +280,23 @@ void a_Dicache_set_parms(gint DicEntryKe
    DicEntry->BitVec = a_Bitvec_new(height);
    DicEntry->State = DIC_SetParms;
 
+   dicache_size_total += Size;
+
    /* For giggles, make the background of the undrawn parts interesting */
    memset(DicEntry->ImageBuffer, 0xdd, DicEntry->TotalSize);
 
    /* Allocate and initialize this image */
-   a_Image_set_parms(Image, DicEntry->ImageBuffer, width, height, type);
+   a_Image_set_parms(Image, DicEntry->ImageBuffer, url, version, 
+		     width, height, type);
 }
 
 /*
  * Implement the set_cmap method for the Image
  */
-void a_Dicache_set_cmap(gint DicKey, DilloImage *Image,
-                        const guchar *cmap, gint num_colors, gint bg_index)
+void a_Dicache_set_cmap(DilloUrl *url, gint version, DilloImage *Image, 
+			const guchar *cmap, gint num_colors, gint bg_index)
 {
-   DICacheEntry *DicEntry = a_Dicache_get_entry_by_key(DicKey);
+   DICacheEntry *DicEntry = Dicache_get_entry_version(url, version);
 
    g_return_if_fail ( DicEntry != NULL );
 
@@ -242,13 +319,13 @@ void a_Dicache_set_cmap(gint DicKey, Dil
  * Y  : row number
  * x  : horizontal offset? (always zero)
  */
-void a_Dicache_write(DilloImage *Image, gint DicKey,
+void a_Dicache_write(DilloImage *Image, DilloUrl *url, gint version,
                      const guchar *buf, gint x, gint Y)
 {
    DICacheEntry *DicEntry;
 
    g_return_if_fail ( Image != NULL );
-   DicEntry = a_Dicache_get_entry_by_key(DicKey);
+   DicEntry = Dicache_get_entry_version(url, version);
    g_return_if_fail ( DicEntry != NULL );
    g_return_if_fail ( DicEntry->width > 0 && DicEntry->height > 0 );
 
@@ -261,10 +338,10 @@ void a_Dicache_write(DilloImage *Image, 
 /*
  * Implement the close method of the decoding process
  */
-void a_Dicache_close(gint DicKey, CacheClient_t *Client)
+void a_Dicache_close(DilloUrl *url, gint version, CacheClient_t *Client)
 {
    DilloWeb *Web = Client->Web;
-   DICacheEntry *DicEntry = a_Dicache_get_entry_by_key(DicKey);
+   DICacheEntry *DicEntry = Dicache_get_entry_version(url, version);
 
    g_return_if_fail ( DicEntry != NULL );
 
@@ -279,6 +356,24 @@ void a_Dicache_close(gint DicKey, CacheC
 
 // -------------------------------------------------------------------------
 
+gboolean Dicache_remove_hash_entry(gpointer key, gpointer value, gpointer user_data)
+{
+   DICacheHashEntry *hash_entry = (DICacheHashEntry *)value;
+   DICacheEntry *entry = hash_entry->next;
+   
+   /* Eliminate this (last) dicache entry */
+   g_free(entry->cmap);
+   if (entry->ImageBuffer) {
+      g_free(entry->ImageBuffer);
+      dicache_size_total -= entry->TotalSize;
+   }
+   a_Bitvec_free(entry->BitVec);
+   a_Url_free(hash_entry->url);
+   g_free(hash_entry);
+
+   return TRUE;
+}
+
 /*
  * Deallocate memory used by dicache module
  * (Call this one at exit time)
@@ -286,8 +381,7 @@ void a_Dicache_close(gint DicKey, CacheC
 void a_Dicache_freeall(void)
 {
    /* Remove every dicache entry */
-   while ( dicache_size )
-      a_Dicache_remove(NULL, dicache[0]->Key);
-   /* Remove the dicache list */
-   g_free(dicache);
+   g_hash_table_foreach_remove(dicache_hash, (GHRFunc)Dicache_remove_hash_entry, NULL);
+   /* Remove the dicache hash */
+   g_hash_table_destroy(dicache_hash);
 }
diff -pru dillo/src/dicache.h dillo.dicache-new/src/dicache.h
--- dillo/src/dicache.h	Wed May 23 19:18:03 2001
+++ dillo.dicache-new/src/dicache.h	Fri Nov  2 17:01:29 2001
@@ -18,7 +18,6 @@ typedef enum {
 typedef struct _DICacheEntry DICacheEntry;
 
 struct _DICacheEntry {
-   gint Key;               /* A primary Key for this entry */
    DilloUrl *url;          /* Image URL for this entry */
    gint width, height;     /* As taken from image data */
    DilloImgType type;      /* Image type */
@@ -28,26 +27,32 @@ struct _DICacheEntry {
    gint Y;                 /* Current decoding row */
    bitvec_t *BitVec;       /* Bit vector for decoded rows */
    DicEntryState State;    /* Current status for this entry */
+   gint RefCount;          /* Reference Counter */
+   gint version;           /* Version number, used for different 
+			      versions of the same URL image */
+
+   DICacheEntry *next;     /* Link to the next "newer" version */
 };
 
 
 void a_Dicache_init (void);
 
 DICacheEntry *a_Dicache_get_entry(const DilloUrl *Url);
-DICacheEntry *a_Dicache_get_entry_by_key(gint Key);
 DICacheEntry *a_Dicache_add_entry(const DilloUrl *Url);
 
 void a_Dicache_callback(gint Op, CacheClient_t *Client);
 
-void a_Dicache_set_parms(gint DicEntryKey, DilloImage *Image,
+void a_Dicache_set_parms(DilloUrl *url, gint version, DilloImage *Image,
                          gint width, gint height, DilloImgType type);
-void a_Dicache_set_cmap(gint DicKey, DilloImage *Image,
+void a_Dicache_set_cmap(DilloUrl *url, gint version, DilloImage *Image,
                         const guchar *cmap, gint num_colors, gint bg_index);
-void a_Dicache_write(DilloImage *Image, gint DicKey,
+void a_Dicache_write(DilloImage *Image, DilloUrl *url, gint version,
                      const guchar *buf, gint x, gint Y);
-void a_Dicache_close(gint DicKey, CacheClient_t *Client);
+void a_Dicache_close(DilloUrl *url, gint version, CacheClient_t *Client);
 
+void a_Dicache_invalidate_entry(const DilloUrl *Url);
+DICacheEntry* a_Dicache_ref(const DilloUrl *Url, gint version);
+void a_Dicache_unref(const DilloUrl *Url, gint version);
 void a_Dicache_freeall(void);
-void a_Dicache_remove(const DilloUrl *Url, gint DicKey);
 
 #endif /* __DILLODICACHE_H__ */
diff -pru dillo/src/dw_image.c dillo.dicache-new/src/dw_image.c
--- dillo/src/dw_image.c	Mon Nov  5 15:58:33 2001
+++ dillo.dicache-new/src/dw_image.c	Mon Nov  5 16:16:06 2001
@@ -15,6 +15,7 @@
 #include "prefs.h"
 #include "dw_marshal.h"
 #include "list.h"
+#include "dicache.h"
 #include <gdk/gdk.h>
 #include <gtk/gtk.h>
 #include <stdio.h>
@@ -127,6 +128,7 @@ DwWidget* a_Dw_image_new (DwImageType ty
  */
 static void Dw_image_init (DwImage *image)
 {
+   image->url = NULL;
    image->width = 0;
    image->height = 0;
    image->buffer = NULL;
@@ -211,6 +213,8 @@ static void Dw_image_destroy (GtkObject 
       g_free (image->scaled_buffer);
    if (image->usemap_url)
       a_Url_free(image->usemap_url);
+   if (image->url)
+      a_Dicache_unref(image->url, image->version);
 
    (* GTK_OBJECT_CLASS(parent_class)->destroy) (object);
 }
@@ -498,9 +502,12 @@ void a_Dw_image_draw_row(DwImage *image,
 /*
  * Set the widget buffer to reference the dicache entry buffer
  */
-void a_Dw_image_set_buffer(DwImage *image, guchar *ImageBuffer)
+void a_Dw_image_set_buffer(DwImage *image, guchar *ImageBuffer, 
+			   DilloUrl *url, gint version)
 {
    image->buffer = ImageBuffer;
+   image->url = url;
+   image->version = version;
 
    if (image->width > 0 && image->height > 0)
       /* if a_Dw_image_set_size has been called before */
diff -pru dillo/src/dw_image.h dillo.dicache-new/src/dw_image.h
--- dillo/src/dw_image.h	Thu May 31 10:14:08 2001
+++ dillo.dicache-new/src/dw_image.h	Fri Oct 26 14:04:53 2001
@@ -32,6 +32,8 @@ struct _DwImage
 {  
    DwWidget widget;
 
+   DilloUrl *url;
+   gint version;
    DwImageType type;
    guchar *buffer;
    gint width;
@@ -124,7 +126,8 @@ DwWidget* a_Dw_image_new  (DwImageType t
 void a_Dw_image_size (DwImage *image, gint width, gint height);
 void a_Dw_image_draw_row(DwImage *image,
                          gint Width, gint Height, gint x, gint y);
-void a_Dw_image_set_buffer(DwImage *image, guchar *ImageBuffer);
+void a_Dw_image_set_buffer(DwImage *image, guchar *ImageBuffer, 
+			   DilloUrl *url, gint version);
 
 void a_Dw_image_set_ismap (DwImage *image);
 void a_Dw_image_set_usemap (DwImage *image,  DwImageMapList *map_list,
diff -pru dillo/src/gif.c dillo.dicache-new/src/gif.c
--- dillo/src/gif.c	Tue Sep  4 16:03:38 2001
+++ dillo.dicache-new/src/gif.c	Fri Nov  2 17:02:12 2001
@@ -83,7 +83,8 @@
 
 typedef struct _DilloGif {
    DilloImage *Image;
-   gint DicEntryKey;
+   DilloUrl *url;
+   gint version;
 
    gint state;
    size_t Start_Ofs;
@@ -146,7 +147,7 @@ static void Gif_write(DilloGif *gif, voi
 static void Gif_close(DilloGif *gif, CacheClient_t *Client);
 static size_t Gif_process_bytes(DilloGif *gif, const guchar *buf,
                                 size_t bufsize, void *Buf);
-static DilloGif *Gif_new(DilloImage *Image, gint DicEntryKey);
+static DilloGif *Gif_new(DilloImage *Image, DilloUrl *url, gint version);
 void Gif_callback(int Op, CacheClient_t *Client);
 
 
@@ -173,10 +174,11 @@ DwWidget *a_Gif_image(const char *Type, 
       DicEntry = a_Dicache_add_entry(web->url);
 
       /* ... and let the decoder feed it! */
-      *Data = Gif_new(web->Image, DicEntry->Key);
+      *Data = Gif_new(web->Image, DicEntry->url, DicEntry->version);
       *Call = (CA_Callback_t) Gif_callback;
    } else {
       /* Let's feed our client from the dicache */
+      a_Dicache_ref(DicEntry->url, DicEntry->version);
       *Data = web->Image;
       *Call = (CA_Callback_t) a_Dicache_callback;
    }
@@ -186,12 +188,13 @@ DwWidget *a_Gif_image(const char *Type, 
 /*
  * Create a new gif structure for decoding a gif into a RGB buffer
  */
-static DilloGif *Gif_new(DilloImage *Image, gint DicEntryKey)
+static DilloGif *Gif_new(DilloImage *Image, DilloUrl *url, gint version)
 {
    DilloGif *gif = g_malloc(sizeof(DilloGif));
 
    gif->Image = Image;
-   gif->DicEntryKey = DicEntryKey;
+   gif->url = url;
+   gif->version = version;
 
    gif->Flags = 0;
    gif->state = 0;
@@ -261,7 +264,7 @@ static void Gif_close(DilloGif *gif, Cac
    g_print("destroy gif %x\n", gif);
 #endif
 
-   a_Dicache_close(gif->DicEntryKey, Client);
+   a_Dicache_close(gif->url, gif->version, Client);
 
    if (gif->linebuf != NULL)
       g_free(gif->linebuf);
@@ -420,7 +423,7 @@ static void Gif_lwz_init(DilloGif *gif)
  */
 static void Gif_emit_line(DilloGif *gif, const guchar *linebuf)
 {
-   a_Dicache_write(gif->Image, gif->DicEntryKey, linebuf, 0, gif->y);
+   a_Dicache_write(gif->Image, gif->url, gif->version, linebuf, 0, gif->y);
    if (gif->Flags & INTERLACE) {
       switch (gif->pass) {
       case 0:
@@ -864,7 +867,7 @@ static size_t Gif_do_img_desc(DilloGif *
    gif->Height  = LM_to_uint(buf[6], buf[7]);
    gif->linebuf = g_malloc(gif->Width);
 
-   a_Dicache_set_parms(gif->DicEntryKey, gif->Image, 
+   a_Dicache_set_parms(gif->url, gif->version, gif->Image,
                        gif->Width, gif->Height, DILLO_IMG_TYPE_INDEXED);
 
    Flags = buf[8];
@@ -895,7 +898,7 @@ static size_t Gif_do_img_desc(DilloGif *
    gif->spill_line_index = 0;
    gif->state = 3;              /*Process the lzw data next */
    if (gif->Image && gif->ColorMap_ofs) {
-      a_Dicache_set_cmap(gif->DicEntryKey, gif->Image,
+      a_Dicache_set_cmap(gif->url, gif->version, gif->Image,
                          (guchar *) Buf + gif->ColorMap_ofs,
                          256 /* gif->NumColors */, gif->transparent);
    }
diff -pru dillo/src/image.c dillo.dicache-new/src/image.c
--- dillo/src/image.c	Tue Sep  4 16:03:38 2001
+++ dillo.dicache-new/src/image.c	Thu Oct 25 17:49:35 2001
@@ -110,11 +110,12 @@ static guchar *
 /*
  * Set initial parameters of the image
  */
-void a_Image_set_parms(DilloImage *Image, guchar *EntryBuf,
-                       guint width, guint height, DilloImgType type)
+void a_Image_set_parms(DilloImage *Image, guchar *EntryBuf, DilloUrl *url,
+		       gint version, guint width, guint height, 
+		       DilloImgType type)
 {
    if ( !Image->dw->buffer )
-      a_Dw_image_set_buffer(Image->dw, EntryBuf);
+      a_Dw_image_set_buffer(Image->dw, EntryBuf, url, version);
    if ( !Image->BitVec )
       Image->BitVec = a_Bitvec_new(height);
    Image->in_type = type;
diff -pru dillo/src/image.h dillo.dicache-new/src/image.h
--- dillo/src/image.h	Tue Sep  4 16:03:38 2001
+++ dillo.dicache-new/src/image.h	Thu Oct 25 17:48:54 2001
@@ -12,10 +12,10 @@
 typedef struct _DilloImage DilloImage;
 
 typedef enum {
-  DILLO_IMG_TYPE_INDEXED,
-  DILLO_IMG_TYPE_RGB,
-  DILLO_IMG_TYPE_GRAY,
-  DILLO_IMG_TYPE_NOTSET    /* Initial value */
+   DILLO_IMG_TYPE_INDEXED,
+   DILLO_IMG_TYPE_RGB,
+   DILLO_IMG_TYPE_GRAY,
+   DILLO_IMG_TYPE_NOTSET    /* Initial value */
 } DilloImgType;
 
 /* These will reflect the Image's "state" */
@@ -29,21 +29,21 @@ typedef enum {
 } ImageState;
 
 struct _DilloImage {
-  DwImage *dw;
-
-  /* Parameters as told by image data */
-  guint width;
-  guint height;
-
-  const guchar *cmap;     /* Color map (only for indexed) */
-  DilloImgType in_type;   /* Image Type */
-  gint32 bg_color;        /* Background color */
-
-  gint ProcessedBytes;    /* Amount of bytes already decoded */
-  bitvec_t *BitVec;       /* Bit vector for decoded rows */
-  ImageState State;
-
-  gint RefCount;          /* Reference counter */
+   DwImage *dw;
+   
+   /* Parameters as told by image data */
+   guint width;
+   guint height;
+   
+   const guchar *cmap;     /* Color map (only for indexed) */
+   DilloImgType in_type;   /* Image Type */
+   gint32 bg_color;        /* Background color */
+   
+   gint ProcessedBytes;    /* Amount of bytes already decoded */
+   bitvec_t *BitVec;       /* Bit vector for decoded rows */
+   ImageState State;
+   
+   gint RefCount;          /* Reference counter */
 };
 
 
@@ -55,8 +55,9 @@ DilloImage *a_Image_new(gint width, gint
 void a_Image_ref(DilloImage *Image);
 void a_Image_unref(DilloImage *Image);
 
-void a_Image_set_parms(DilloImage *Image, guchar *EntryBuf,
-                       guint width, guint height, DilloImgType type);
+void a_Image_set_parms(DilloImage *Image, guchar *EntryBuf, DilloUrl *url,
+		       gint version, guint width, guint height, 
+		       DilloImgType type);
 void a_Image_set_cmap(DilloImage *Image, const guchar *cmap);
 void a_Image_write(DilloImage *Image, const guchar *buf, guint y, gint decode);
 void a_Image_close(DilloImage *Image);
diff -pru dillo/src/jpeg.c dillo.dicache-new/src/jpeg.c
--- dillo/src/jpeg.c	Tue Sep  4 16:03:38 2001
+++ dillo.dicache-new/src/jpeg.c	Fri Nov  2 17:02:01 2001
@@ -46,14 +46,15 @@ typedef struct {
 } my_source_mgr;
 
 struct my_error_mgr {
-     struct jpeg_error_mgr pub;    /* "public" fields */
-     jmp_buf setjmp_buffer;        /* for return to caller */
+   struct jpeg_error_mgr pub;    /* "public" fields */
+   jmp_buf setjmp_buffer;        /* for return to caller */
 };
 typedef struct my_error_mgr * my_error_ptr;
 
 typedef struct DilloJpeg {
    DilloImage *Image;
-   gint DicEntryKey;
+   DilloUrl *url;
+   gint version;
 
    my_source_mgr Src;
 
@@ -70,7 +71,7 @@ typedef struct DilloJpeg {
 /*
  * Forward declarations
  */
-static DilloJpeg *Jpeg_new(DilloImage *Image, gint DicEntryKey);
+static DilloJpeg *Jpeg_new(DilloImage *Image, DilloUrl *url, gint version);
 void Jpeg_callback(int Op, CacheClient_t *Client);
 static void Jpeg_write(DilloJpeg *jpeg, void *Buf, guint BufSize);
 static void Jpeg_close(DilloJpeg *jpeg, CacheClient_t *Client);
@@ -109,10 +110,11 @@ DwWidget *a_Jpeg_image(const char *Type,
       DicEntry = a_Dicache_add_entry(web->url);
 
       /* ... and let the decoder feed it! */
-      *Data = Jpeg_new(web->Image, DicEntry->Key);
+      *Data = Jpeg_new(web->Image, DicEntry->url, DicEntry->version);
       *Call = (CA_Callback_t) Jpeg_callback;
    } else {
       /* Let's feed our client from the dicache */
+      a_Dicache_ref(DicEntry->url, DicEntry->version);
       *Data = web->Image;
       *Call = (CA_Callback_t) a_Dicache_callback;
    }
@@ -124,11 +126,13 @@ DwWidget *a_Jpeg_image(const char *Type,
  */
 static void Jpeg_close(DilloJpeg *jpeg, CacheClient_t *Client)
 {
-   a_Dicache_close(jpeg->DicEntryKey, Client);
+   a_Dicache_close(jpeg->url, jpeg->version, Client);
 
    if (jpeg->state != DILLO_JPEG_DONE) {
       jpeg_destroy_decompress(&(jpeg->cinfo));
    }
+   /*   if (jpeg->url)
+	a_Url_free(jpeg->url); */
    g_free(jpeg);
 }
 
@@ -149,14 +153,14 @@ static boolean fill_input_buffer(j_decom
       g_print("fill_input_buffer: %d bytes in buffer\n", cinfo->src->bytes_in_buffer);
 #endif
       jpeg->Start_Ofs = (gulong) jpeg->cinfo.src->next_input_byte -
-          (gulong) jpeg->Data;
+	 (gulong) jpeg->Data;
 #endif
       if (jpeg->Skip) {
          jpeg->Start_Ofs = jpeg->NewStart + jpeg->Skip - 1;
          jpeg->Skip = 0;
       } else {
          jpeg->Start_Ofs = (gulong) jpeg->cinfo.src->next_input_byte -
-                           (gulong) jpeg->Data;
+	    (gulong) jpeg->Data;
       }
       return FALSE;
 #if 0
@@ -191,13 +195,14 @@ static void term_source(j_decompress_ptr
 {
 }
 
-static DilloJpeg *Jpeg_new(DilloImage *Image, gint DicEntryKey)
+static DilloJpeg *Jpeg_new(DilloImage *Image, DilloUrl *url, gint version)
 {
    my_source_mgr *src;
    DilloJpeg *jpeg = g_malloc(sizeof(*jpeg));
 
    jpeg->Image = Image;
-   jpeg->DicEntryKey = DicEntryKey;
+   jpeg->url = url;
+   jpeg->version = version;
 
    jpeg->state = DILLO_JPEG_INIT;
    jpeg->Start_Ofs = 0;
@@ -276,7 +281,7 @@ static void Jpeg_write(DilloJpeg *jpeg, 
          else
             g_print("jpeg: can't handle %d component images\n",
                     jpeg->cinfo.num_components);
-         a_Dicache_set_parms(jpeg->DicEntryKey, jpeg->Image,
+         a_Dicache_set_parms(jpeg->url, jpeg->version, jpeg->Image,
                              jpeg->cinfo.image_width,
                              jpeg->cinfo.image_height,
                              type);
@@ -300,7 +305,8 @@ static void Jpeg_write(DilloJpeg *jpeg, 
          num_read = jpeg_read_scanlines(&(jpeg->cinfo), array, 1);
          if (num_read == 0)
             break;
-         a_Dicache_write(jpeg->Image, jpeg->DicEntryKey, linebuf, 0, jpeg->y);
+         a_Dicache_write(jpeg->Image, jpeg->url, jpeg->version, 
+			 linebuf, 0, jpeg->y);
 
          jpeg->y++;
       }
diff -pru dillo/src/png.c dillo.dicache-new/src/png.c
--- dillo/src/png.c	Tue Sep  4 16:03:38 2001
+++ dillo.dicache-new/src/png.c	Fri Nov  2 17:01:50 2001
@@ -60,7 +60,8 @@ static char *prog_state_name[] =
 typedef
 struct _DilloPng {
    DilloImage *Image;           /* Image meta data */
-   gint DicEntryKey;            /* Primary Key for the dicache */
+   DilloUrl *url;               /* Primary Key for the dicache */
+   gint version;                /* Secondary Key for the dicache */
 
    double display_exponent;     /* gamma correction */
    gulong width;                /* png image width */
@@ -196,7 +197,7 @@ Png_datainfo_callback(png_structp png_pt
    png->linebuf = g_malloc(3 * png->width);
 
    /* Initialize the dicache-entry here */
-   a_Dicache_set_parms(png->DicEntryKey, png->Image,
+   a_Dicache_set_parms(png->url, png->version, png->Image,
                        png->width, png->height, DILLO_IMG_TYPE_RGB);
 }
 
@@ -220,7 +221,7 @@ static void
 
    switch (png->channels) {
    case 3:
-      a_Dicache_write(png->Image, png->DicEntryKey,
+      a_Dicache_write(png->Image, png->url, png->version,
                       png->image_data + (row_num * png->rowbytes), 0, row_num);
       break;
    case 4:
@@ -257,7 +258,7 @@ static void
               data++;
            }
         }
-        a_Dicache_write(png->Image, png->DicEntryKey, png->linebuf, 0, row_num);
+        a_Dicache_write(png->Image, png->url, png->version, png->linebuf, 0, row_num);
         break;
      }
    default:
@@ -309,7 +310,7 @@ void Png_callback(int Op, CacheClient_t 
 
    if ( Op ) {
       /* finished - free up the resources for this image */
-      a_Dicache_close(png->DicEntryKey, Client);
+      a_Dicache_close(png->url, png->version, Client);
       if (png->image_data != NULL)
          g_free(png->image_data);
       if (png->row_pointers != NULL)
@@ -395,12 +396,13 @@ void Png_callback(int Op, CacheClient_t 
 /*
  * Create the image state data that must be kept between calls
  */
-static DilloPng *Png_new(DilloImage *Image, gint DicEntryKey)
+static DilloPng *Png_new(DilloImage *Image, DilloUrl *url, gint version)
 {
    DilloPng *png = g_malloc(sizeof(DilloPng));
 
    png->Image = Image;
-   png->DicEntryKey = DicEntryKey;
+   png->url = url;
+   png->version = version;
    png->state = IS_init;
    png->error = 0;
    png->ipbuf = NULL;
@@ -450,10 +452,11 @@ DwWidget *a_Png_image(const char *Type, 
       DicEntry = a_Dicache_add_entry(web->url);
 
       /* ... and let the decoder feed it! */
-      *Data = Png_new(web->Image, DicEntry->Key);
+      *Data = Png_new(web->Image, DicEntry->url, DicEntry->version);
       *Call = (CA_Callback_t) Png_callback;
    } else {
       /* Let's feed our client from the dicache */
+      a_Dicache_ref(DicEntry->url, DicEntry->version);
       *Data = web->Image;
       *Call = (CA_Callback_t) a_Dicache_callback;
    }

