Index: camel/providers/nntp/camel-nntp-folder.c
===================================================================
--- camel/providers/nntp/camel-nntp-folder.c	(revision 9848)
+++ camel/providers/nntp/camel-nntp-folder.c	(working copy)
@@ -123,6 +123,25 @@
         return ((CamelFolderClass *) folder_class)->set_message_flags (folder, uid, flags, set);
 }
 
+static char*
+nntp_get_filename (CamelFolder *folder, const char *uid, CamelException *ex)
+{
+	CamelNNTPStore *nntp_store = (CamelNNTPStore *) folder->parent_store;
+	char *article, *msgid;
+
+	article = alloca(strlen(uid)+1);
+	strcpy(article, uid);
+	msgid = strchr (article, ',');
+	if (msgid == NULL) {
+		camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
+				      _("Internal error: UID in invalid format: %s"), uid);
+		return NULL;
+	}
+	*msgid++ = 0;
+
+	return camel_data_cache_get_filename (nntp_store->cache, "cache", msgid, ex);
+}
+
 static CamelStream *
 nntp_folder_download_message (CamelNNTPFolder *nntp_folder, const char *id, const char *msgid, CamelException *ex)
 {
@@ -483,6 +502,7 @@
 	camel_folder_class->count_by_expression = nntp_folder_count_by_expression;
 	camel_folder_class->search_by_uids = nntp_folder_search_by_uids;
 	camel_folder_class->search_free = nntp_folder_search_free;
+	camel_folder_class->get_filename = nntp_get_filename;
 }
 
 CamelType
Index: camel/providers/pop3/camel-pop3-folder.c
===================================================================
--- camel/providers/pop3/camel-pop3-folder.c	(revision 9848)
+++ camel/providers/pop3/camel-pop3-folder.c	(working copy)
@@ -54,6 +54,7 @@
 static GPtrArray *pop3_get_uids (CamelFolder *folder);
 static CamelMimeMessage *pop3_get_message (CamelFolder *folder, const char *uid, CamelException *ex);
 static gboolean pop3_set_message_flags (CamelFolder *folder, const char *uid, guint32 flags, guint32 set);
+static char* pop3_get_filename (CamelFolder *folder, const char *uid, CamelException *ex);
 
 static void
 camel_pop3_folder_class_init (CamelPOP3FolderClass *camel_pop3_folder_class)
@@ -69,7 +70,8 @@
 	camel_folder_class->get_message_count = pop3_get_message_count;
 	camel_folder_class->get_uids = pop3_get_uids;
 	camel_folder_class->free_uids = camel_folder_free_shallow;
-	
+	camel_folder_class->get_filename = pop3_get_filename;
+
 	camel_folder_class->get_message = pop3_get_message;
 	camel_folder_class->set_message_flags = pop3_set_message_flags;
 }
@@ -515,6 +517,23 @@
 	fi->stream = NULL;
 }
 
+static char*
+pop3_get_filename (CamelFolder *folder, const char *uid, CamelException *ex)
+{
+	CamelPOP3Folder *pop3_folder = (CamelPOP3Folder *)folder;
+	CamelPOP3Store *pop3_store = (CamelPOP3Store *)((CamelFolder *)pop3_folder)->parent_store;
+	CamelPOP3FolderInfo *fi;
+
+	fi = g_hash_table_lookup(pop3_folder->uids_uid, uid);
+	if (fi == NULL) {
+		camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID,
+				      _("No message with UID %s"), uid);
+		return NULL;
+	}
+
+	return camel_data_cache_get_filename (pop3_store->cache, "cache", fi->uid, NULL);
+}
+
 static CamelMimeMessage *
 pop3_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
 {
Index: camel/providers/groupwise/camel-groupwise-folder.c
===================================================================
--- camel/providers/groupwise/camel-groupwise-folder.c	(revision 9848)
+++ camel/providers/groupwise/camel-groupwise-folder.c	(working copy)
@@ -89,6 +89,7 @@
 static void groupwise_msg_set_recipient_list (CamelMimeMessage *msg, EGwItem *item);
 static void gw_update_cache ( CamelFolder *folder, GList *item_list, CamelException *ex, gboolean uid_flag);
 static CamelMimeMessage *groupwise_folder_item_to_msg ( CamelFolder *folder, EGwItem *item, CamelException *ex );
+static char* groupwise_get_filename (CamelFolder *folder, const char *uid, CamelException *ex);
 
 
 #define d(x)  
@@ -96,6 +97,15 @@
 const char * GET_ITEM_VIEW_WITH_CACHE = "peek default recipient threading attachments subject status priority startDate created delivered size recurrenceKey message notification";
 const char * GET_ITEM_VIEW_WITHOUT_CACHE = "peek default recipient threading hasAttachment subject status priority startDate created delivered size recurrenceKey";
 
+static char* 
+groupwise_get_filename (CamelFolder *folder, const char *uid, CamelException *ex)
+{
+	CamelGroupwiseFolder *gw_folder = CAMEL_GROUPWISE_FOLDER(folder);
+
+	return camel_data_cache_get_filename (gw_folder->cache, "cache", uid, ex);
+}
+
+
 static CamelMimeMessage *
 groupwise_folder_get_message( CamelFolder *folder, const char *uid, CamelException *ex )
 {
@@ -2485,6 +2495,7 @@
 	camel_folder_class->sync = groupwise_sync;
 	camel_folder_class->expunge = groupwise_expunge;
 	camel_folder_class->transfer_messages_to = groupwise_transfer_messages_to;
+	camel_folder_class->get_filename = groupwise_get_filename;
 }
 
 static void
Index: camel/providers/imap/camel-imap-folder.c
===================================================================
--- camel/providers/imap/camel-imap-folder.c	(revision 9848)
+++ camel/providers/imap/camel-imap-folder.c	(working copy)
@@ -102,6 +102,7 @@
 static void imap_expunge (CamelFolder *folder, CamelException *ex);
 //static void imap_cache_message (CamelDiscoFolder *disco_folder, const char *uid, CamelException *ex);
 static void imap_rename (CamelFolder *folder, const char *new);
+static char* imap_get_filename (CamelFolder *folder, const char *uid, CamelException *ex);
 
 /* message manipulation */
 static CamelMimeMessage *imap_get_message (CamelFolder *folder, const gchar *uid,
@@ -167,6 +168,7 @@
 	camel_folder_class->sync= imap_sync;
 	camel_folder_class->append_message = imap_append_online;
 	camel_folder_class->transfer_messages_to = imap_transfer_online;
+	camel_folder_class->get_filename = imap_get_filename;
 }
 
 static void
@@ -446,6 +448,14 @@
 	g_free(imap_folder->priv);
 }
 
+static char*
+imap_get_filename (CamelFolder *folder, const char *uid, CamelException *ex)
+{
+	CamelImapFolder *imap_folder = (CamelImapFolder*) folder;
+
+	return camel_imap_message_cache_get_filename (imap_folder->cache, uid, "", ex);
+}
+
 static int
 imap_getv(CamelObject *object, CamelException *ex, CamelArgGetV *args)
 {
Index: camel/providers/imap/camel-imap-message-cache.c
===================================================================
--- camel/providers/imap/camel-imap-message-cache.c	(revision 9848)
+++ camel/providers/imap/camel-imap-message-cache.c	(working copy)
@@ -438,7 +438,36 @@
 	}
 }
 
+/**
+ * camel_imap_message_cache_get_filename:
+ * @cache: the cache
+ * @uid: the UID of the data to get
+ * @part_spec: the part_spec of the data to get
+ * @ex: exception
+ *
+ * Return value: the filename of a cache item
+ **/
+char*
+camel_imap_message_cache_get_filename (CamelImapMessageCache *cache,
+				       const char *uid,
+				       const char *part_spec,
+				       CamelException *ex)
+{
+	char *path;
+	
+	if (uid[0] == 0)
+		return NULL;
+	
+#ifdef G_OS_WIN32
+	/* See comment in insert_setup() */
+	if (!*part_spec)
+		part_spec = "~";
+#endif
+	path = g_strdup_printf ("%s/%s.%s", cache->path, uid, part_spec);
 
+	return path;
+}
+
 /**
  * camel_imap_message_cache_get:
  * @cache: the cache
Index: camel/providers/imap/camel-imap-message-cache.h
===================================================================
--- camel/providers/imap/camel-imap-message-cache.h	(revision 9848)
+++ camel/providers/imap/camel-imap-message-cache.h	(working copy)
@@ -86,6 +86,11 @@
 					      const char *part_spec,
 					      CamelException *ex);
 
+char*       camel_imap_message_cache_get_filename (CamelImapMessageCache *cache,
+					      const char *uid,
+					      const char *part_spec,
+					      CamelException *ex);
+
 void         camel_imap_message_cache_remove (CamelImapMessageCache *cache,
 					      const char *uid);
 
Index: camel/providers/imap4/camel-imap4-folder.c
===================================================================
--- camel/providers/imap4/camel-imap4-folder.c	(revision 9848)
+++ camel/providers/imap4/camel-imap4-folder.c	(working copy)
@@ -78,8 +78,8 @@
 static GPtrArray *imap4_search_by_expression (CamelFolder *folder, const char *expr, CamelException *ex);
 static GPtrArray *imap4_search_by_uids (CamelFolder *folder, const char *expr, GPtrArray *uids, CamelException *ex);
 static void imap4_search_free (CamelFolder *folder, GPtrArray *uids);
+static char* imap4_get_filename (CamelFolder *folder, const char *uid, CamelException *ex);
 
-
 static CamelOfflineFolderClass *parent_class = NULL;
 
 
@@ -139,6 +139,7 @@
 	folder_class->search_by_expression = imap4_search_by_expression;
 	folder_class->search_by_uids = imap4_search_by_uids;
 	folder_class->search_free = imap4_search_free;
+	folder_class->get_filename = imap4_get_filename;
 }
 
 static void
@@ -170,6 +171,14 @@
 	g_free (folder->cachedir);
 }
 
+static char*
+imap4_get_filename (CamelFolder *folder, const char *uid, CamelException *ex)
+{
+	CamelIMAP4Folder *imap4_folder = (CamelIMAP4Folder *) folder;
+
+	return camel_data_cache_get_filename (imap4_folder->cache, "cache", uid, ex);
+}
+
 static int
 imap4_getv (CamelObject *object, CamelException *ex, CamelArgGetV *args)
 {
Index: camel/providers/local/camel-mbox-folder.c
===================================================================
--- camel/providers/local/camel-mbox-folder.c	(revision 9848)
+++ camel/providers/local/camel-mbox-folder.c	(working copy)
@@ -31,6 +31,7 @@
 #include <unistd.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <inttypes.h>
 
 #include <glib.h>
 #include <glib/gi18n-lib.h>
@@ -67,6 +68,7 @@
 static void mbox_append_message(CamelFolder *folder, CamelMimeMessage * message, const CamelMessageInfo * info,	char **appended_uid, CamelException *ex);
 static CamelMimeMessage *mbox_get_message(CamelFolder *folder, const gchar * uid, CamelException *ex);
 static CamelLocalSummary *mbox_create_summary(CamelLocalFolder *lf, const char *path, const char *folder, CamelIndex *index);
+static char* mbox_get_filename (CamelFolder *folder, const char *uid, CamelException *ex);
 
 static void mbox_finalise(CamelObject * object);
 
@@ -83,6 +85,7 @@
 	/* virtual method overload */
 	camel_folder_class->append_message = mbox_append_message;
 	camel_folder_class->get_message = mbox_get_message;
+	camel_folder_class->get_filename = mbox_get_filename;
 
 	lclass->create_summary = mbox_create_summary;
 	lclass->lock = mbox_lock;
@@ -315,6 +318,54 @@
 	}
 }
 
+static char* 
+mbox_get_filename (CamelFolder *folder, const char *uid, CamelException *ex)
+{
+	CamelLocalFolder *lf = (CamelLocalFolder *)folder;
+	CamelMboxMessageInfo *info;
+	off_t frompos;
+	char *filename = NULL;
+
+	d(printf("Getting message %s\n", uid));
+
+	/* lock the folder first, burn if we can't, need write lock for summary check */
+	if (camel_local_folder_lock(lf, CAMEL_LOCK_WRITE, ex) == -1)
+		return NULL;
+
+	/* check for new messages always */
+	if (camel_local_summary_check((CamelLocalSummary *)folder->summary, lf->changes, ex) == -1) {
+		camel_local_folder_unlock(lf);
+		return NULL;
+	}
+	
+	/* get the message summary info */
+	info = (CamelMboxMessageInfo *) camel_folder_summary_uid(folder->summary, uid);
+
+	if (info == NULL) {
+		camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID,
+				     _("Cannot get message: %s from folder %s\n  %s"),
+				     uid, lf->folder_path, _("No such message"));
+		goto fail;
+	}
+
+	if (info->frompos == -1) {
+		camel_message_info_free((CamelMessageInfo *)info);
+		goto fail;
+	}
+
+	frompos = info->frompos;
+	camel_message_info_free((CamelMessageInfo *)info);
+
+
+	filename = g_strdup_printf ("%s%s!%" PRId64, lf->folder_path, G_DIR_SEPARATOR_S, (long long) frompos);
+
+fail:
+	/* and unlock now we're finished with it */
+	camel_local_folder_unlock(lf);
+
+	return filename;
+}
+
 static CamelMimeMessage *
 mbox_get_message(CamelFolder *folder, const gchar * uid, CamelException *ex)
 {
Index: camel/providers/local/camel-maildir-folder.c
===================================================================
--- camel/providers/local/camel-maildir-folder.c	(revision 9848)
+++ camel/providers/local/camel-maildir-folder.c	(working copy)
@@ -56,6 +56,7 @@
 
 static void maildir_append_message(CamelFolder * folder, CamelMimeMessage * message, const CamelMessageInfo *info, char **appended_uid, CamelException * ex);
 static CamelMimeMessage *maildir_get_message(CamelFolder * folder, const gchar * uid, CamelException * ex);
+static char* maildir_get_filename (CamelFolder *folder, const char *uid, CamelException *ex);
 
 static void maildir_finalize(CamelObject * object);
 
@@ -102,6 +103,7 @@
 
 	camel_folder_class->append_message = maildir_append_message;
 	camel_folder_class->get_message = maildir_get_message;
+	camel_folder_class->get_filename = maildir_get_filename;
 
 	lclass->create_summary = maildir_create_summary;
 }
@@ -232,6 +234,28 @@
 	g_free (dest);
 }
 
+static char* 
+maildir_get_filename (CamelFolder *folder, const char *uid, CamelException *ex)
+{
+	CamelLocalFolder *lf = (CamelLocalFolder *)folder;
+	CamelMaildirMessageInfo *mdi;
+	CamelMessageInfo *info;
+
+	/* get the message summary info */
+	if ((info = camel_folder_summary_uid(folder->summary, uid)) == NULL) {
+		camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID,
+				     _("Cannot get message: %s from folder %s\n  %s"),
+				     uid, lf->folder_path, _("No such message"));
+		return NULL;
+	}
+
+	mdi = (CamelMaildirMessageInfo *)info;
+
+	/* what do we do if the message flags (and :info data) changes?  filename mismatch - need to recheck I guess */
+	return g_strdup_printf("%s/cur/%s", lf->folder_path, camel_maildir_info_filename(mdi));
+}
+
+
 static CamelMimeMessage *
 maildir_get_message(CamelFolder * folder, const gchar * uid, CamelException * ex)
 {
Index: camel/providers/local/camel-mh-folder.c
===================================================================
--- camel/providers/local/camel-mh-folder.c	(revision 9848)
+++ camel/providers/local/camel-mh-folder.c	(working copy)
@@ -55,6 +55,7 @@
 
 static void mh_append_message(CamelFolder * folder, CamelMimeMessage * message, const CamelMessageInfo *info, char **appended_uid, CamelException * ex);
 static CamelMimeMessage *mh_get_message(CamelFolder * folder, const gchar * uid, CamelException * ex);
+static char* mh_get_filename (CamelFolder *folder, const char *uid, CamelException *ex);
 
 static void mh_finalize(CamelObject * object);
 
@@ -70,6 +71,7 @@
 	/* virtual method overload */
 	camel_folder_class->append_message = mh_append_message;
 	camel_folder_class->get_message = mh_get_message;
+	camel_folder_class->get_filename = mh_get_filename;
 
 	lclass->create_summary = mh_create_summary;
 }
@@ -187,6 +189,14 @@
 	g_free (name);
 }
 
+static char* mh_get_filename (CamelFolder *folder, const char *uid, CamelException *ex)
+{
+	CamelLocalFolder *lf = (CamelLocalFolder *)folder;
+
+	return g_strdup_printf("%s/%s", lf->folder_path, uid);
+}
+
+
 static CamelMimeMessage *mh_get_message(CamelFolder * folder, const gchar * uid, CamelException * ex)
 {
 	CamelLocalFolder *lf = (CamelLocalFolder *)folder;
Index: camel/camel-folder.c
===================================================================
--- camel/camel-folder.c	(revision 9848)
+++ camel/camel-folder.c	(working copy)
@@ -121,6 +121,10 @@
 static gboolean        folder_changed        (CamelObject *object,
 					      gpointer event_data);
 
+static char*           get_filename          (CamelFolder *folder, 
+					      const char *uid, 
+					      CamelException *ex);
+
 static CamelFolderQuotaInfo *get_quota_info  (CamelFolder *folder);
 
 static void
@@ -166,6 +170,7 @@
 	camel_folder_class->thaw = thaw;
 	camel_folder_class->is_frozen = is_frozen;
 	camel_folder_class->get_quota_info = get_quota_info;
+	camel_folder_class->get_filename = get_filename;
 
 	/* virtual method overload */
 	camel_object_class->getv = folder_getv;
@@ -233,7 +238,20 @@
 	return camel_folder_type;
 }
 
+static char*
+get_filename (CamelFolder *folder, const char *uid, CamelException *ex)
+{
+	w(g_warning ("CamelFolder::get_filename not implemented for '%s'",
+		     camel_type_to_name (CAMEL_OBJECT_GET_TYPE (folder))));
+	return g_strdup ("/dev/null");
+}
 
+char *
+camel_folder_get_filename (CamelFolder *folder, const char *uid, CamelException *ex)
+{
+	return CF_CLASS (folder)->get_filename (folder, uid, ex);
+}
+
 /**
  * camel_folder_construct:
  * @folder: a #CamelFolder object to construct
Index: camel/camel-folder.h
===================================================================
--- camel/camel-folder.h	(revision 9848)
+++ camel/camel-folder.h	(working copy)
@@ -211,6 +211,7 @@
 	
 	CamelFolderQuotaInfo * (*get_quota_info) (CamelFolder *folder);
 	guint32	(*count_by_expression) (CamelFolder *, const char *, CamelException *);
+	char * (*get_filename) (CamelFolder *, const char *uid, CamelException *);
 } CamelFolderClass;
 
 /* Standard Camel function */
@@ -353,6 +354,8 @@
 void camel_folder_free_shallow (CamelFolder *folder, GPtrArray *array);
 void camel_folder_free_deep    (CamelFolder *folder, GPtrArray *array);
 
+char * camel_folder_get_filename (CamelFolder *folder, const char *uid, CamelException *ex);
+
 /* update functions for change info */
 CamelFolderChangeInfo *	camel_folder_change_info_new		(void);
 void			camel_folder_change_info_clear		(CamelFolderChangeInfo *info);
Index: camel/camel-data-cache.c
===================================================================
--- camel/camel-data-cache.c	(revision 9848)
+++ camel/camel-data-cache.c	(working copy)
@@ -350,7 +350,29 @@
 	return stream;
 }
 
+
 /**
+ * camel_data_cache_get_filename:
+ * @cdc: A #CamelDataCache
+ * @path: Path to the (sub) cache the item exists in.
+ * @key: Key for the cache item.
+ * @ex: 
+ * 
+ * Lookup the filename for an item in the cache
+ * 
+ * Return value: The filename for a cache item
+ **/
+gchar *
+camel_data_cache_get_filename (CamelDataCache *cdc, const char *path, const char *key, CamelException *ex)
+{
+	char *real;
+
+	real = data_cache_path(cdc, FALSE, path, key);
+
+	return real;
+}
+
+/**
  * camel_data_cache_remove:
  * @cdc: A #CamelDataCache
  * @path: 
Index: camel/camel-data-cache.h
===================================================================
--- camel/camel-data-cache.h	(revision 9848)
+++ camel/camel-data-cache.h	(working copy)
@@ -85,6 +85,9 @@
 int             camel_data_cache_clear(CamelDataCache *cache,
 				       const char *path, CamelException *ex);
 
+gchar *         camel_data_cache_get_filename(CamelDataCache *cdc, 
+					      const char *path, const char *key, CamelException *ex);
+
 /* Standard Camel function */
 CamelType camel_data_cache_get_type (void);
 
