diff --git a/camel/camel-db.c b/camel/camel-db.c
index 73834f0..1be6cd7 100644
--- a/camel/camel-db.c
+++ b/camel/camel-db.c
@@ -561,6 +561,51 @@ camel_db_delete_uid_from_vfolder_transaction (CamelDB *db, char *folder_name, ch
 	return ret;
 }
 
+struct _db_data_uids_flags {
+	GPtrArray *uids;
+	GPtrArray *flags;
+};
+static int
+read_uids_flags_callback (void *ref, int ncol, char ** cols, char ** name)
+{
+	struct _db_data_uids_flags *data= (struct _db_data_uids_flags *) ref;
+	 
+	int i;
+	for (i = 0; i < ncol; ++i) {
+		if (!strcmp (name [i], "uid"))
+			g_ptr_array_add (data->uids, (char *) (camel_pstring_strdup(cols [i])));
+		else if (!strcmp (name [i], "flags"))
+			g_ptr_array_add (data->flags, GUINT_TO_POINTER(strtoul (cols [i], NULL, 10)));
+	}
+	 
+	 return 0;
+}
+
+int
+camel_db_get_folder_uids_flags (CamelDB *db, char *folder_name, char *sort_by, char *collate, GPtrArray *summary, GHashTable *table, CamelException *ex)
+{
+	 GPtrArray *uids = summary;
+	 GPtrArray *flags = g_ptr_array_new ();
+	 char *sel_query;
+	 int ret;
+	 struct _db_data_uids_flags data;
+	 int i;
+	
+	 data.uids = uids;
+	 data.flags = flags;
+
+
+	 sel_query = sqlite3_mprintf("SELECT uid,flags FROM %Q%s%s%s%s", folder_name, sort_by ? " order by " : "", sort_by ? sort_by: "", (sort_by && collate) ? " collate " : "", (sort_by && collate) ? collate : "");	 
+
+	 ret = camel_db_select (db, sel_query, read_uids_flags_callback, &data, ex);
+	 sqlite3_free (sel_query);
+
+	 for (i=0; i<uids->len; i++) {
+		 g_hash_table_insert (table, uids->pdata[i], flags->pdata[i]);
+	 }
+	 return ret;
+}
+
 static int
 read_uids_callback (void *ref, int ncol, char ** cols, char ** name)
 {
diff --git a/camel/camel-db.h b/camel/camel-db.h
index 56bb113..fa6d57c 100644
--- a/camel/camel-db.h
+++ b/camel/camel-db.h
@@ -156,6 +156,7 @@ int camel_db_add_to_vfolder (CamelDB *db, char *folder_name, char *vuid, CamelEx
 int camel_db_add_to_vfolder_transaction (CamelDB *db, char *folder_name, char *vuid, CamelException *ex);
 
 int camel_db_get_folder_uids (CamelDB *db, char *folder_name, char *sort_by, char *collate, GPtrArray *array, CamelException *ex);
+int camel_db_get_folder_uids_flags (CamelDB *db, char *folder_name, char *sort_by, char *collate, GPtrArray *summary, GHashTable *table, CamelException *ex);
 
 GPtrArray * camel_db_get_folder_junk_uids (CamelDB *db, char *folder_name, CamelException *ex);
 GPtrArray * camel_db_get_folder_deleted_uids (CamelDB *db, char *folder_name, CamelException *ex);
diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c
index 7a9c3d5..5c7b6d2 100644
--- a/camel/camel-folder-summary.c
+++ b/camel/camel-folder-summary.c
@@ -67,6 +67,7 @@
 
 /* Make 5 minutes as default cache drop */
 #define SUMMARY_CACHE_DROP 300
+#define dd(x) if (camel_debug("sync")) x
 
 static pthread_mutex_t info_lock = PTHREAD_MUTEX_INITIALIZER;
 
@@ -154,6 +155,7 @@ camel_folder_summary_init (CamelFolderSummary *s)
 
 	s->message_info_size = sizeof(CamelMessageInfoBase);
 	s->content_info_size = sizeof(CamelMessageContentInfo);
+	s->flag_cache = g_hash_table_new (g_str_hash, g_str_equal);
 
 	s->message_info_chunks = NULL;
 	s->content_info_chunks = NULL;
@@ -823,12 +825,13 @@ remove_cache (CamelSession *session, CamelSessionThreadMsg *msg)
 	CamelFolderSummary *s = m->summary;
 
 	CAMEL_DB_RELEASE_SQLITE_MEMORY;
-	
+	camel_folder_sync (s->folder, FALSE, NULL);
+
 	if (time(NULL) - s->cache_load_time < SUMMARY_CACHE_DROP)
 		return;
 	
-	d(printf("removing cache for  %s %d %p\n", s->folder ? s->folder->full_name : s->summary_path, g_hash_table_size (s->loaded_infos), s->loaded_infos));
-	#warning "hack. fix it"
+	dd(printf("removing cache for  %s %d %p\n", s->folder ? s->folder->full_name : s->summary_path, g_hash_table_size (s->loaded_infos), s->loaded_infos));
+
 	CAMEL_SUMMARY_LOCK (s, summary_lock);
 	g_hash_table_foreach_remove  (s->loaded_infos, (GHRFunc) remove_item, s);
 	CAMEL_SUMMARY_UNLOCK (s, summary_lock);
@@ -948,7 +951,7 @@ camel_folder_summary_load_from_db (CamelFolderSummary *s, CamelException *ex)
 	folder_name = s->folder->full_name;
 	cdb = s->folder->parent_store->cdb_r;
 
-	ret = camel_db_get_folder_uids (cdb, folder_name, (char *)s->sort_by, (char *)s->collate, s->uids, ex);
+	ret = camel_db_get_folder_uids_flags (cdb, folder_name, (char *)s->sort_by, (char *)s->collate, s->uids, s->flag_cache, ex);
 	/* camel_folder_summary_dump (s); */
 
 #if 0
@@ -1378,7 +1381,7 @@ camel_folder_summary_save_to_db (CamelFolderSummary *s, CamelException *ex)
 	if (!count) 
 		return camel_folder_summary_header_save_to_db (s, ex);
 
-	d(printf("Saving %d/%d dirty records of %s\n", count, g_hash_table_size (s->loaded_infos), s->folder->full_name));
+	dd(printf("Saving %d/%d dirty records of %s\n", count, g_hash_table_size (s->loaded_infos), s->folder->full_name));
 
 	camel_db_begin_transaction (cdb, ex);
 
diff --git a/camel/camel-folder-summary.h b/camel/camel-folder-summary.h
index eb3c9f8..7ee3d0f 100644
--- a/camel/camel-folder-summary.h
+++ b/camel/camel-folder-summary.h
@@ -250,8 +250,9 @@ struct _CamelFolderSummary {
 	const char *collate;
 	const char *sort_by;
 
+	GHashTable *flag_cache;
 	/* Future ABI expansion */
-	gpointer later[4];
+	gpointer later[3];
 };
 
 struct _CamelMIRecord;
diff --git a/camel/camel-vee-folder.c b/camel/camel-vee-folder.c
index b26bbe2..c38a86b 100644
--- a/camel/camel-vee-folder.c
+++ b/camel/camel-vee-folder.c
@@ -2017,13 +2017,14 @@ summary_reloaded(CamelObject *o, void *event_data, void *data)
 		camel_object_unhook_event((CamelObject *)o, "summary_reloaded", (CamelObjectEventHookFunc) summary_reloaded, data);
 	}
 	
+	/*
 	m = camel_session_thread_msg_new(session, &folder_flags_ops, sizeof(*m));
 	m->sub = summary->folder;
 	camel_object_ref((CamelObject *)summary->folder);
 	m->vf = vf;
 	camel_object_ref((CamelObject *)vf);
 	camel_session_thread_queue(session, &m->msg, 0);
-	
+	*/
 }
 
 /* vfolder base implementaitons */
@@ -2098,6 +2099,94 @@ vee_set_expression(CamelVeeFolder *vf, const char *query)
 	CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock);
 }
 
+/* This entire code will be useless, since we sync the counts always. */
+static int
+vf_getv(CamelObject *object, CamelException *ex, CamelArgGetV *args)
+{
+	CamelFolder *folder = (CamelFolder *)object;
+	int i;
+	guint32 tag;
+	int unread = -1, deleted = 0, junked = 0, visible = 0, count = -1, junked_not_deleted = -1;
+
+	for (i=0;i<args->argc;i++) {
+		CamelArgGet *arg = &args->argv[i];
+
+		tag = arg->tag;
+
+		/* NB: this is a copy of camel-folder.c with the unread count logic altered.
+		   makes sure its still atomically calculated */
+		switch (tag & CAMEL_ARG_TAG) {
+		case CAMEL_FOLDER_ARG_UNREAD:
+		case CAMEL_FOLDER_ARG_DELETED:
+		case CAMEL_FOLDER_ARG_JUNKED:
+		case CAMEL_FOLDER_ARG_JUNKED_NOT_DELETED:	
+		case CAMEL_FOLDER_ARG_VISIBLE:
+			
+			/* This is so we can get the values atomically, and also so we can calculate them only once */
+			if (unread == -1) {
+				int j;
+				CamelMessageInfoBase *info;
+				CamelVeeMessageInfo *vinfo;
+
+				unread = deleted = visible = junked = junked_not_deleted = 0;
+				count = camel_folder_summary_count(folder->summary);
+				for (j=0; j<count; j++) {
+					if ((info = (CamelMessageInfoBase *) camel_folder_summary_index(folder->summary, j))) {
+						guint32 flags;
+
+						vinfo = (CamelVeeMessageInfo *) info;
+						flags = vinfo->old_flags;// ? vinfo->old_flags : camel_message_info_flags(info);
+
+						if ((flags & (CAMEL_MESSAGE_SEEN)) == 0)
+							unread++;
+						if (flags & CAMEL_MESSAGE_DELETED)
+							deleted++;
+						if (flags & CAMEL_MESSAGE_JUNK) {
+							junked++;
+								if (! (flags & CAMEL_MESSAGE_DELETED))
+									junked_not_deleted++;						
+						}
+						if ((flags & (CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_JUNK)) == 0)
+							visible++;
+						camel_message_info_free(info);
+					}
+				}
+			}
+
+			switch (tag & CAMEL_ARG_TAG) {
+			case CAMEL_FOLDER_ARG_UNREAD:
+				count = unread == -1 ? 0 : unread;
+				break;
+			case CAMEL_FOLDER_ARG_DELETED:
+				count = deleted == -1 ? 0 : deleted;
+				break;
+			case CAMEL_FOLDER_ARG_JUNKED:
+				count = junked == -1 ? 0 : junked;
+				break;
+			case CAMEL_FOLDER_ARG_JUNKED_NOT_DELETED:
+				count = junked_not_deleted == -1 ? 0 : junked_not_deleted;
+				break;				
+			case CAMEL_FOLDER_ARG_VISIBLE:
+				count = visible == -1 ? 0 : visible;
+				break;
+			}
+			folder->summary->unread_count = unread == -1 ? 0 : unread;
+			folder->summary->deleted_count = deleted == -1 ? 0 : deleted;
+			junked = folder->summary->junk_count = junked == -1 ? 0 : junked;
+			folder->summary->junk_not_deleted_count = junked_not_deleted == -1 ? 0 : junked_not_deleted;
+			folder->summary->visible_count = visible == -1 ? 0 : visible;			
+			*arg->ca_int = count;
+			break;
+		default:
+			continue;
+		}
+
+		arg->tag = (tag & CAMEL_ARG_TYPE) | CAMEL_ARG_IGNORE;
+	}
+
+	return ((CamelObjectClass *)camel_vee_folder_parent)->getv(object, ex, args);
+}
+
 static void
 camel_vee_folder_class_init (CamelVeeFolderClass *klass)
 {
@@ -2105,6 +2194,8 @@ camel_vee_folder_class_init (CamelVeeFolderClass *klass)
 
 	camel_vee_folder_parent = CAMEL_FOLDER_CLASS(camel_type_get_global_classfuncs (camel_folder_get_type ()));
 
+	((CamelObjectClass *)klass)->getv = vf_getv; 
+
 	folder_class->refresh_info = vee_refresh_info;
 	folder_class->sync = vee_sync;
 	folder_class->expunge = vee_expunge;
diff --git a/camel/camel-vee-summary.c b/camel/camel-vee-summary.c
index 56916ef..281a423 100644
--- a/camel/camel-vee-summary.c
+++ b/camel/camel-vee-summary.c
@@ -176,20 +176,33 @@ vee_info_set_flags(CamelMessageInfo *mi, guint32 flags, guint32 set)
 {
 	int res = FALSE;
 	CamelVeeFolder *vf = (CamelVeeFolder *)mi->summary->folder;
-	const char *exp = g_getenv("CAMEL_VFOLDER_UNREAD_EXP");
+	static char *exp = NULL;
+	static only_once = FALSE;
 	gboolean hacked_unread_folder = FALSE;
+	char *meta = NULL;
 
 	/* HACK: Ugliest of all hacks. Its virtually not possible now
 	 * to maintain counts and the non matching uids of unread vfolder here.
 	 * So, I hardcode unread vfolder expression and hack it. */
+	if (!only_once) {
+		exp =  g_getenv("CAMEL_VFOLDER_UNREAD_EXP") ? g_strcompress(g_getenv("CAMEL_VFOLDER_UNREAD_EXP")) : NULL;
+		only_once = TRUE;
+	}
+
 	if (!exp || !*exp)
-		exp = unread_str;
+		exp = g_strcompress(unread_str);
+
 	if (camel_debug("vfolderexp"))
 		printf("Expression for vfolder '%s' is '%s'\n", mi->summary->folder->full_name, g_strescape(vf->expression, ""));
 
 	if (strstr(exp, vf->expression) &&  (vf->flags & CAMEL_STORE_VEE_FOLDER_SPECIAL) == 0)
 		hacked_unread_folder = TRUE;
 
+	meta = camel_object_meta_get (mi->summary->folder, "vfolder:unread");
+	if (!hacked_unread_folder && meta && strcmp (meta, "true") == 0)
+		hacked_unread_folder = TRUE;
+	g_free(meta);
+
 	if (mi->uid) {
 		guint32 old_visible, old_unread, old_deleted, old_junked, old_junked_not_deleted;
 		guint32 visible, unread, deleted, junked, junked_not_deleted;
@@ -440,6 +453,7 @@ camel_vee_summary_add(CamelVeeSummary *s, CamelFolderSummary *summary, const cha
 
 	mi = (CamelVeeMessageInfo *)camel_message_info_new(&s->summary);
 	mi->summary = summary;
+	mi->old_flags = GPOINTER_TO_UINT(g_hash_table_lookup (summary->flag_cache, uid));
 	/* We would do lazy loading of flags, when the folders are loaded to memory through folder_reloaded signal */
 	camel_object_ref (summary);
 	mi->info.uid = (char *) camel_pstring_strdup (vuid);
diff --git a/camel/camel-vtrash-folder.c b/camel/camel-vtrash-folder.c
index 80f63b0..aa75c2e 100644
--- a/camel/camel-vtrash-folder.c
+++ b/camel/camel-vtrash-folder.c
@@ -151,7 +151,7 @@ vtrash_getv(CamelObject *object, CamelException *ex, CamelArgGetV *args)
 						guint32 flags;
 
 						vinfo = (CamelVeeMessageInfo *) info;
-						flags = vinfo->old_flags ? vinfo->old_flags : camel_message_info_flags(info);
+						flags = vinfo->old_flags;// ? vinfo->old_flags : camel_message_info_flags(info);
 
 						if ((flags & (CAMEL_MESSAGE_SEEN)) == 0)
 							unread++;
