diff --git a/camel/camel-disco-folder.c b/camel/camel-disco-folder.c
index cde2232..263504f 100644
--- a/camel/camel-disco-folder.c
+++ b/camel/camel-disco-folder.c
@@ -273,6 +273,7 @@ disco_expunge (CamelFolder *folder,
 	CamelMessageInfo *info;
 
 	uids = g_ptr_array_new ();
+	camel_folder_summary_prepare_fetch_all (folder->summary, ex);
 	count = camel_folder_summary_count (folder->summary);
 	for (i = 0; i < count; i++) {
 		info = camel_folder_summary_index (folder->summary, i);
diff --git a/camel/camel-folder-search.c b/camel/camel-folder-search.c
index 94c18a6..be49b7c 100644
--- a/camel/camel-folder-search.c
+++ b/camel/camel-folder-search.c
@@ -851,8 +851,8 @@ search_match_all(struct _ESExp *f, gint argc, struct _ESExpTerm **argv, CamelFol
 
 	v = search->summary_set?search->summary_set:search->summary;
 
-	if (v->len > g_hash_table_size (search->folder->summary->loaded_infos) && !CAMEL_IS_VEE_FOLDER (search->folder)) {
-		camel_folder_summary_reload_from_db (search->folder->summary, search->priv->ex);
+	if (!CAMEL_IS_VEE_FOLDER (search->folder)) {
+		camel_folder_summary_prepare_fetch_all (search->folder->summary, search->priv->ex);
 	}
 
 	for (i=0;i<v->len;i++) {
diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c
index aeb38bd..961cb1f 100644
--- a/camel/camel-folder-summary.c
+++ b/camel/camel-folder-summary.c
@@ -60,7 +60,7 @@
 #include "camel-win32.h"
 
 /* Make 5 minutes as default cache drop */
-#define SUMMARY_CACHE_DROP 300 
+#define SUMMARY_CACHE_DROP 300
 #define dd(x) if (camel_debug("sync")) x
 
 struct _CamelFolderSummaryPrivate {
@@ -77,11 +77,11 @@ struct _CamelFolderSummaryPrivate {
 
 	struct _CamelIndex *index;
 
-	GMutex *summary_lock;	/* for the summary hashtable/array */
-	GMutex *io_lock;	/* load/save lock, for access to saved_count, etc */
-	GMutex *filter_lock;	/* for accessing any of the filtering/indexing stuff, since we share them */
-	GMutex *alloc_lock;	/* for setting up and using allocators */
-	GMutex *ref_lock;	/* for reffing/unreffing messageinfo's ALWAYS obtain before summary_lock */
+	GStaticRecMutex summary_lock;	/* for the summary hashtable/array */
+	GStaticRecMutex io_lock;	/* load/save lock, for access to saved_count, etc */
+	GStaticRecMutex filter_lock;	/* for accessing any of the filtering/indexing stuff, since we share them */
+	GStaticRecMutex alloc_lock;	/* for setting up and using allocators */
+	GStaticRecMutex ref_lock;	/* for reffing/unreffing messageinfo's ALWAYS obtain before summary_lock */
 	GHashTable *flag_cache;
 
 	gboolean need_preview;
@@ -121,6 +121,8 @@ struct _node {
 	struct _node *next;
 };
 
+static void cfs_schedule_info_release_timer (CamelFolderSummary *s);
+
 static struct _node *my_list_append(struct _node **list, struct _node *n);
 static gint my_list_size(struct _node **list);
 
@@ -185,11 +187,11 @@ camel_folder_summary_init (CamelFolderSummary *s)
 	s->uids = g_ptr_array_new ();
 	s->loaded_infos = g_hash_table_new (g_str_hash, g_str_equal);
 
-	p->summary_lock = g_mutex_new();
-	p->io_lock = g_mutex_new();
-	p->filter_lock = g_mutex_new();
-	p->alloc_lock = g_mutex_new();
-	p->ref_lock = g_mutex_new();
+	g_static_rec_mutex_init (&p->summary_lock);
+	g_static_rec_mutex_init (&p->io_lock);
+	g_static_rec_mutex_init (&p->filter_lock);
+	g_static_rec_mutex_init (&p->alloc_lock);
+	g_static_rec_mutex_init (&p->ref_lock);
 
 	s->meta_summary = g_malloc0(sizeof(CamelFolderMetaSummary));
 
@@ -249,11 +251,11 @@ camel_folder_summary_finalize (CamelObject *obj)
 	g_free(s->meta_summary->path);
 	g_free(s->meta_summary);
 
-	g_mutex_free(p->summary_lock);
-	g_mutex_free(p->io_lock);
-	g_mutex_free(p->filter_lock);
-	g_mutex_free(p->alloc_lock);
-	g_mutex_free(p->ref_lock);
+	g_static_rec_mutex_free (&p->summary_lock);
+	g_static_rec_mutex_free (&p->io_lock);
+	g_static_rec_mutex_free (&p->filter_lock);
+	g_static_rec_mutex_free (&p->alloc_lock);
+	g_static_rec_mutex_free (&p->ref_lock);
 
 	g_free(p);
 }
@@ -583,20 +585,19 @@ message_info_from_uid (CamelFolderSummary *s, const gchar *uid)
 		folder_name = s->folder->full_name;
 		cdb = s->folder->parent_store->cdb_r;
 
-		camel_folder_summary_unlock (s, CFS_SUMMARY_LOCK);
-
 		data.summary = s;
-		data.double_ref = TRUE;
+		data.double_ref = FALSE;
 		data.add = FALSE;
 
 		ret = camel_db_read_message_info_record_with_uid (cdb, folder_name, uid, &data, camel_read_mir_callback, &ex);
 		if (ret != 0) {
+			camel_folder_summary_unlock (s, CFS_SUMMARY_LOCK);
+			if (camel_exception_is_set (&ex))
+				g_warning ("%s: Failed read '%s' in '%s' from db: %s (0x%x)", G_STRFUNC, uid, folder_name, camel_exception_get_description (&ex), camel_exception_get_id (&ex));
 			camel_exception_clear (&ex);
 			return NULL;
 		}
 
-		camel_folder_summary_lock (s, CFS_SUMMARY_LOCK);
-
 		/* We would have double reffed at camel_read_mir_callback */
 		info = g_hash_table_lookup (s->loaded_infos, uid);
 
@@ -609,6 +610,8 @@ message_info_from_uid (CamelFolderSummary *s, const gchar *uid)
 			camel_exception_clear (&ex);
 			g_free (errmsg);
 		}
+
+		cfs_schedule_info_release_timer (s);
 	}
 
 	if (info)
@@ -833,16 +836,19 @@ remove_cache (CamelSession *session, CamelSessionThreadMsg *msg)
 	CamelFolderSummary *s = m->summary;
 	CamelException ex;
 	GSList *to_free_list = NULL, *l;
+	gboolean skip_remove;
+
+	skip_remove = time(NULL) - s->cache_load_time < SUMMARY_CACHE_DROP;
 
 	CAMEL_DB_RELEASE_SQLITE_MEMORY;
 	camel_exception_init (&ex);
 	camel_folder_sync (s->folder, FALSE, &ex);
 	camel_exception_clear (&ex);
 
-	if (time(NULL) - s->cache_load_time < SUMMARY_CACHE_DROP)
+	if (skip_remove)
 		return;
 
-	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), (gpointer) s->loaded_infos));
+	dd(printf("removing cache for  %s %d %p ", s->folder ? s->folder->full_name : s->summary_path, g_hash_table_size (s->loaded_infos), (gpointer) s->loaded_infos));
 	/* FIXME[disk-summary] hack. fix it */
 	camel_folder_summary_lock (s, CFS_SUMMARY_LOCK);
 
@@ -856,8 +862,8 @@ remove_cache (CamelSession *session, CamelSessionThreadMsg *msg)
 		camel_message_info_free (l->data);
 	g_slist_free (to_free_list);
 
+	dd(printf("   done .. now %d\n", g_hash_table_size (s->loaded_infos)));
 	camel_folder_summary_unlock (s, CFS_SUMMARY_LOCK);
-	dd(printf("done .. now %d\n",g_hash_table_size (s->loaded_infos)));
 
 	s->cache_load_time = time(NULL);
 }
@@ -898,13 +904,30 @@ cfs_try_release_memory (CamelFolderSummary *s)
 	return TRUE;
 }
 
-/**
- * camel_folder_summary_cache_size:
- *
- * Since: 2.24
- **/
-gint
-camel_folder_summary_cache_size (CamelFolderSummary *s)
+static void
+cfs_schedule_info_release_timer (CamelFolderSummary *s)
+{
+	g_return_if_fail (CAMEL_IS_FOLDER_SUMMARY (s));
+
+	if (!s->timeout_handle) {
+		static gboolean know_can_do = FALSE, can_do = TRUE;
+
+		if (!know_can_do) {
+			can_do = !g_getenv ("CAMEL_FREE_INFOS");
+			know_can_do = TRUE;
+		}
+
+		/* FIXME[disk-summary] LRU please and not timeouts */
+		if (can_do)
+			s->timeout_handle = g_timeout_add_seconds (SUMMARY_CACHE_DROP, (GSourceFunc) cfs_try_release_memory, s);
+	}
+
+	/* update also cache load time to the actual, to not release something just loaded */
+	s->cache_load_time = time (NULL);
+}
+
+static gint
+cfs_cache_size (CamelFolderSummary *s)
 {
 	/* FIXME[disk-summary] this is a timely hack. fix it well */
 	if (!CAMEL_IS_VEE_FOLDER(s->folder))
@@ -1009,13 +1032,8 @@ static CamelSessionThreadOps preview_update_ops = {
 
 /* end */
 
-/**
- * camel_folder_summary_reload_from_db:
- *
- * Since: 2.24
- **/
-gint
-camel_folder_summary_reload_from_db (CamelFolderSummary *s, CamelException *ex)
+static gint
+cfs_reload_from_db (CamelFolderSummary *s, CamelException *ex)
 {
 	CamelDB *cdb;
 	gchar *folder_name;
@@ -1035,10 +1053,7 @@ camel_folder_summary_reload_from_db (CamelFolderSummary *s, CamelException *ex)
 	data.add = FALSE;
 	ret = camel_db_read_message_info_records (cdb, folder_name, (gpointer)&data, camel_read_mir_callback, NULL);
 
-	s->cache_load_time = time (NULL);
-        /* FIXME[disk-summary] LRU please and not timeouts */
-	if (!g_getenv("CAMEL_FREE_INFOS") && !s->timeout_handle)
-		s->timeout_handle = g_timeout_add_seconds (SUMMARY_CACHE_DROP, (GSourceFunc) cfs_try_release_memory, s);
+	cfs_schedule_info_release_timer (s);
 
 	if (CAMEL_FOLDER_SUMMARY_GET_PRIVATE(s)->need_preview) {
 		struct _preview_update_msg *m;
@@ -1066,29 +1081,30 @@ camel_folder_summary_add_preview (CamelFolderSummary *s, CamelMessageInfo *info)
 }
 
 /**
- * camel_folder_summary_ensure_infos_loaded:
+ * camel_folder_summary_prepare_fetch_all:
  * @s: #CamelFolderSummary object
- * @at_least: How many infos already loaded are considered fine to not reload all of them.
- *    Use -1 to force reload of all of them if not in memory yet.
  * @ex: #CamelException object.
  *
- * Loads all infos into memory, if they are not yet.
+ * Loads all infos into memory, if they are not yet and ensures
+ * they will not be freed in next couple minutes.
  *
- * Since: 2.28
+ * Since: 2.31
  **/
 void
-camel_folder_summary_ensure_infos_loaded (CamelFolderSummary *s, gint at_least, CamelException *ex)
+camel_folder_summary_prepare_fetch_all (CamelFolderSummary *s, CamelException *ex)
 {
 	guint loaded, known;
 
 	g_return_if_fail (s != NULL);
 
-	loaded = camel_folder_summary_cache_size (s);
+	loaded = cfs_cache_size (s);
 	known = camel_folder_summary_count (s);
 
-	if ((at_least == -1 && known != loaded) || at_least > loaded) {
-		camel_folder_summary_reload_from_db (s, ex);
-	}
+	if (known - loaded > 50)
+		cfs_reload_from_db (s, ex);
+
+	/* update also cache load time, even when not loaded anything */
+	s->cache_load_time = time (NULL);
 }
 
 #if 0
@@ -2480,7 +2496,7 @@ camel_folder_summary_remove_uid(CamelFolderSummary *s, const gchar *uid)
 		camel_folder_summary_lock (s, CFS_REF_LOCK);
 		if (g_hash_table_lookup_extended(s->loaded_infos, uid, (gpointer)&olduid, (gpointer)&oldinfo)) {
 				/* make sure it doesn't vanish while we're removing it */
-				oldinfo->refcount++;
+				camel_message_info_ref (oldinfo);
 				camel_folder_summary_unlock (s, CFS_REF_LOCK);
 				camel_folder_summary_unlock (s, CFS_SUMMARY_LOCK);
 				camel_folder_summary_remove(s, oldinfo);
@@ -2518,7 +2534,7 @@ camel_folder_summary_remove_uid_fast (CamelFolderSummary *s, const gchar *uid)
 		camel_folder_summary_lock (s, CFS_REF_LOCK);
 		if (g_hash_table_lookup_extended(s->loaded_infos, uid, (gpointer)&olduid, (gpointer)&oldinfo)) {
 				/* make sure it doesn't vanish while we're removing it */
-				oldinfo->refcount++;
+				camel_message_info_ref (oldinfo);
 				camel_folder_summary_unlock (s, CFS_REF_LOCK);
 				g_hash_table_remove (s->loaded_infos, olduid);
 				summary_remove_uid (s, olduid);
@@ -5223,19 +5239,19 @@ camel_folder_summary_lock (CamelFolderSummary *summary, CamelFolderSummaryLock l
 
 	switch (lock) {
 	case CFS_SUMMARY_LOCK:
-		g_mutex_lock (summary->priv->summary_lock);
+		g_static_rec_mutex_lock (&summary->priv->summary_lock);
 		break;
 	case CFS_IO_LOCK:
-		g_mutex_lock (summary->priv->io_lock);
+		g_static_rec_mutex_lock (&summary->priv->io_lock);
 		break;
 	case CFS_FILTER_LOCK:
-		g_mutex_lock (summary->priv->filter_lock);
+		g_static_rec_mutex_lock (&summary->priv->filter_lock);
 		break;
 	case CFS_ALLOC_LOCK:
-		g_mutex_lock (summary->priv->alloc_lock);
+		g_static_rec_mutex_lock (&summary->priv->alloc_lock);
 		break;
 	case CFS_REF_LOCK:
-		g_mutex_lock (summary->priv->ref_lock);
+		g_static_rec_mutex_lock (&summary->priv->ref_lock);
 		break;
 	default:
 		g_return_if_reached ();
@@ -5260,19 +5276,19 @@ camel_folder_summary_unlock (CamelFolderSummary *summary, CamelFolderSummaryLock
 
 	switch (lock) {
 	case CFS_SUMMARY_LOCK:
-		g_mutex_unlock (summary->priv->summary_lock);
+		g_static_rec_mutex_unlock (&summary->priv->summary_lock);
 		break;
 	case CFS_IO_LOCK:
-		g_mutex_unlock (summary->priv->io_lock);
+		g_static_rec_mutex_unlock (&summary->priv->io_lock);
 		break;
 	case CFS_FILTER_LOCK:
-		g_mutex_unlock (summary->priv->filter_lock);
+		g_static_rec_mutex_unlock (&summary->priv->filter_lock);
 		break;
 	case CFS_ALLOC_LOCK:
-		g_mutex_unlock (summary->priv->alloc_lock);
+		g_static_rec_mutex_unlock (&summary->priv->alloc_lock);
 		break;
 	case CFS_REF_LOCK:
-		g_mutex_unlock (summary->priv->ref_lock);
+		g_static_rec_mutex_unlock (&summary->priv->ref_lock);
 		break;
 	default:
 		g_return_if_reached ();
diff --git a/camel/camel-folder-summary.h b/camel/camel-folder-summary.h
index 887b345..db62038 100644
--- a/camel/camel-folder-summary.h
+++ b/camel/camel-folder-summary.h
@@ -374,12 +374,8 @@ CamelMessageInfo * camel_folder_summary_peek_info (CamelFolderSummary *s, const
 
 /* Get only the uids of dirty/changed things to sync to server/db */
 GPtrArray * camel_folder_summary_get_changed (CamelFolderSummary *s);
-/* Gets the size of loaded mi's */
-gint camel_folder_summary_cache_size (CamelFolderSummary *s);
 /* reload the summary at any required point if required */
-gint camel_folder_summary_reload_from_db (CamelFolderSummary *s, CamelException *ex);
-/* ensures all CamelMessagesInfos loaded in memory */
-void camel_folder_summary_ensure_infos_loaded (CamelFolderSummary *s, gint at_least, CamelException *ex);
+void camel_folder_summary_prepare_fetch_all (CamelFolderSummary *s, CamelException *ex);
 /* insert mi to summary */
 void camel_folder_summary_insert (CamelFolderSummary *s, CamelMessageInfo *info, gboolean load);
 
diff --git a/camel/camel-folder-thread.c b/camel/camel-folder-thread.c
index 07c7e5f..4bac800 100644
--- a/camel/camel-folder-thread.c
+++ b/camel/camel-folder-thread.c
@@ -607,10 +607,9 @@ camel_folder_thread_messages_new (CamelFolder *folder, GPtrArray *uids, gboolean
 	thread->node_chunks = e_memchunk_new(32, sizeof(CamelFolderThreadNode));
 	thread->folder = camel_object_ref (folder);
 
+	camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
 	fsummary = camel_folder_summary_array (folder->summary);
 	thread->summary = summary = g_ptr_array_new();
-	if (fsummary->len - camel_folder_summary_cache_size (folder->summary) > 50)
-		camel_folder_summary_reload_from_db (folder->summary, NULL);
 
 	/* prefer given order from the summary order */
 	if (!uids)
diff --git a/camel/camel-vee-folder.c b/camel/camel-vee-folder.c
index 6a7a62c..59b447d 100644
--- a/camel/camel-vee-folder.c
+++ b/camel/camel-vee-folder.c
@@ -618,8 +618,9 @@ vee_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
 		/* Cleanup Junk/Trash uids */
 		GSList *del = NULL;
 		gint i, count;
-		count = folder->summary->uids->len;
 
+		camel_folder_summary_prepare_fetch_all (folder->summary, ex);
+		count = camel_folder_summary_count (folder->summary);
 		for (i=0; i < count; i++) {
 			CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index (folder->summary, i);
 			if (mi->old_flags & CAMEL_MESSAGE_DELETED) {
@@ -938,6 +939,7 @@ vee_folder_remove_folder (CamelVeeFolder *vf, CamelFolder *source)
 		if (killun) {
 			start = -1;
 			last = -1;
+			camel_folder_summary_prepare_fetch_all (((CamelFolder *)folder_unmatched)->summary, NULL);
 			count = camel_folder_summary_count (((CamelFolder *)folder_unmatched)->summary);
 			for (i=0;i<count;i++) {
 				CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index (((CamelFolder *)folder_unmatched)->summary, i);
@@ -966,6 +968,7 @@ vee_folder_remove_folder (CamelVeeFolder *vf, CamelFolder *source)
 	/*FIXME: This can be optimized a lot like, searching for UID in the summary uids */
 	start = -1;
 	last = -1;
+	camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
 	count = camel_folder_summary_count (folder->summary);
 	for (i=0;i<count;i++) {
 		CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index (folder->summary, i);
@@ -1207,6 +1210,7 @@ vee_rebuild_folder (CamelVeeFolder *vf, CamelFolder *source, CamelException *ex)
 	   current source) */
 	start = -1;
 	last = -1;
+	camel_folder_summary_prepare_fetch_all (folder->summary, ex);
 	count = camel_folder_summary_count (folder->summary);
 	for (i=0;i<count;i++) {
 		CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index (folder->summary, i);
@@ -1828,6 +1832,7 @@ subfolder_renamed_update (CamelVeeFolder *vf, CamelFolder *sub, gchar hash[8])
 
 	camel_vee_folder_lock (vf, CVF_SUMMARY_LOCK);
 
+	camel_folder_summary_prepare_fetch_all (((CamelFolder *)vf)->summary, NULL);
 	count = camel_folder_summary_count (((CamelFolder *)vf)->summary);
 	for (i=0;i<count;i++) {
 		CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index (((CamelFolder *)vf)->summary, i);
@@ -2071,6 +2076,7 @@ vf_getv (CamelObject *object, CamelException *ex, CamelArgGetV *args)
 				CamelVeeMessageInfo *vinfo;
 
 				unread = deleted = visible = junked = junked_not_deleted = 0;
+				camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
 				count = camel_folder_summary_count (folder->summary);
 				for (j=0; j<count; j++) {
 					if ((info = (CamelMessageInfoBase *) camel_folder_summary_index (folder->summary, j))) {
diff --git a/camel/camel-vtrash-folder.c b/camel/camel-vtrash-folder.c
index 7dbdece..9c063e9 100644
--- a/camel/camel-vtrash-folder.c
+++ b/camel/camel-vtrash-folder.c
@@ -111,6 +111,7 @@ vtrash_folder_getv (CamelObject *object,
 				CamelVeeMessageInfo *vinfo;
 
 				unread = deleted = visible = junked = junked_not_deleted = 0;
+				camel_folder_summary_prepare_fetch_all (folder->summary, ex);
 				count = camel_folder_summary_count(folder->summary);
 				for (j=0; j<count; j++) {
 					if ((info = (CamelMessageInfoBase *) camel_folder_summary_index(folder->summary, j))) {
diff --git a/camel/providers/groupwise/camel-groupwise-folder.c b/camel/providers/groupwise/camel-groupwise-folder.c
index 0bae726..4759678 100644
--- a/camel/providers/groupwise/camel-groupwise-folder.c
+++ b/camel/providers/groupwise/camel-groupwise-folder.c
@@ -767,6 +767,7 @@ groupwise_sync (CamelFolder *folder, gboolean expunge, CamelMessageInfo *update_
 		return;
 
 	changes = camel_folder_change_info_new ();
+	camel_folder_summary_prepare_fetch_all (folder->summary, ex);
 	count = camel_folder_summary_count (folder->summary);
 	CAMEL_GROUPWISE_FOLDER_REC_LOCK (folder, cache_lock);
 	for (i=0; i < count; i++) {
@@ -2690,6 +2691,7 @@ groupwise_expunge (CamelFolder *folder, CamelException *ex)
 
 	container_id =  g_strdup (camel_groupwise_store_container_id_lookup (groupwise_store, folder->full_name));
 
+	camel_folder_summary_prepare_fetch_all (folder->summary, ex);
 	max = camel_folder_summary_count (folder->summary);
 	for (i = 0; i < max; i++) {
 		info = camel_folder_summary_index (folder->summary, i);
diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c
index 29ab68d..1f7da37 100644
--- a/camel/providers/imap/camel-imap-folder.c
+++ b/camel/providers/imap/camel-imap-folder.c
@@ -969,8 +969,7 @@ imap_rescan (CamelFolder *folder, gint exists, CamelException *ex)
 	 */
 	removed = g_array_new (FALSE, FALSE, sizeof (gint));
 
-	if (summary_len - camel_folder_summary_cache_size (folder->summary) > 50)
-		camel_folder_summary_reload_from_db (folder->summary, ex);
+	camel_folder_summary_prepare_fetch_all (folder->summary, ex);
 
 	for (i = 0, j = 0; i < summary_len && new[j].uid; i++) {
 		gboolean changed = FALSE;
@@ -1426,6 +1425,7 @@ imap_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
 		/* Make sure we're connected before issuing commands */
 		if (!camel_imap_store_connected(store, ex)) {
 			g_free(set);
+			camel_message_info_free(info);
 			break;
 		}
 
diff --git a/camel/providers/local/camel-maildir-folder.c b/camel/providers/local/camel-maildir-folder.c
index 57974b1..c938a1a 100644
--- a/camel/providers/local/camel-maildir-folder.c
+++ b/camel/providers/local/camel-maildir-folder.c
@@ -251,6 +251,7 @@ maildir_get_filename (CamelFolder *folder, const gchar *uid, CamelException *ex)
 	CamelLocalFolder *lf = (CamelLocalFolder *)folder;
 	CamelMaildirMessageInfo *mdi;
 	CamelMessageInfo *info;
+	gchar *res;
 
 	/* get the message summary info */
 	if ((info = camel_folder_summary_uid(folder->summary, uid)) == NULL) {
@@ -262,7 +263,11 @@ maildir_get_filename (CamelFolder *folder, const gchar *uid, CamelException *ex)
 	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));
+	res = g_strdup_printf("%s/cur/%s", lf->folder_path, camel_maildir_info_filename (mdi));
+
+	camel_message_info_free (info);
+
+	return res;
 }
 
 static CamelMimeMessage *
@@ -340,6 +345,9 @@ maildir_cmp_uids (CamelFolder *folder, const gchar *uid1, const gchar *uid2)
 	tma = camel_message_info_date_received (a);
 	tmb = camel_message_info_date_received (b);
 
+	camel_message_info_free (a);
+	camel_message_info_free (b);
+
 	return tma < tmb ? -1 : tma == tmb ? 0 : 1;
 }
 
@@ -354,7 +362,7 @@ maildir_sort_uids (CamelFolder *folder, GPtrArray *uids)
 
 		camel_exception_init (&ex);
 
-		camel_folder_summary_ensure_infos_loaded (folder->summary, uids->len, &ex);
+		camel_folder_summary_prepare_fetch_all (folder->summary, &ex);
 
 		if (camel_exception_is_set (&ex))
 			g_warning ("%s: %s", G_STRFUNC, camel_exception_get_description (&ex));
diff --git a/camel/providers/local/camel-maildir-summary.c b/camel/providers/local/camel-maildir-summary.c
index 4854f51..35904ca 100644
--- a/camel/providers/local/camel-maildir-summary.c
+++ b/camel/providers/local/camel-maildir-summary.c
@@ -549,11 +549,8 @@ maildir_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changes, Ca
 
 	/* keeps track of all uid's that have not been processed */
 	left = g_hash_table_new(g_str_hash, g_str_equal);
+	camel_folder_summary_prepare_fetch_all (s, ex);
 	count = camel_folder_summary_count (s);
-	if (count != camel_folder_summary_cache_size (s)) {
-		camel_folder_summary_reload_from_db (s, ex);
-		count = camel_folder_summary_count (s);
-	}
 	forceindex = count == 0;
 	for (i=0;i<count;i++) {
 		info = camel_folder_summary_index((CamelFolderSummary *)cls, i);
@@ -713,6 +710,7 @@ maildir_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChange
 
 	camel_operation_start(NULL, _("Storing folder"));
 
+	camel_folder_summary_prepare_fetch_all ((CamelFolderSummary *)cls, ex);
 	count = camel_folder_summary_count((CamelFolderSummary *)cls);
 	for (i=count-1;i>=0;i--) {
 		camel_operation_progress(NULL, (count-i)*100/count);
diff --git a/camel/providers/local/camel-mbox-folder.c b/camel/providers/local/camel-mbox-folder.c
index 6102f63..ed93b4b 100644
--- a/camel/providers/local/camel-mbox-folder.c
+++ b/camel/providers/local/camel-mbox-folder.c
@@ -486,6 +486,7 @@ static gint
 mbox_cmp_uids (CamelFolder *folder, const gchar *uid1, const gchar *uid2)
 {
 	CamelMboxMessageInfo *a, *b;
+	gint res;
 
 	g_return_val_if_fail (folder != NULL, 0);
 	g_return_val_if_fail (folder->summary != NULL, 0);
@@ -496,7 +497,12 @@ mbox_cmp_uids (CamelFolder *folder, const gchar *uid1, const gchar *uid2)
 	g_return_val_if_fail (a != NULL, 0);
 	g_return_val_if_fail (b != NULL, 0);
 
-	return a->frompos < b->frompos ? -1 : a->frompos == b->frompos ? 0 : 1;
+	res = a->frompos < b->frompos ? -1 : a->frompos == b->frompos ? 0 : 1;
+
+	camel_message_info_free ((CamelMessageInfo *)a);
+	camel_message_info_free ((CamelMessageInfo *)b);
+
+	return res;
 }
 
 static void
@@ -510,7 +516,7 @@ mbox_sort_uids (CamelFolder *folder, GPtrArray *uids)
 
 		camel_exception_init (&ex);
 
-		camel_folder_summary_ensure_infos_loaded (folder->summary, uids->len, &ex);
+		camel_folder_summary_prepare_fetch_all (folder->summary, &ex);
 
 		if (camel_exception_is_set (&ex))
 			g_warning ("%s: %s", G_STRFUNC, camel_exception_get_description (&ex));
diff --git a/camel/providers/local/camel-mbox-summary.c b/camel/providers/local/camel-mbox-summary.c
index c5d9860..5cc6dd1 100644
--- a/camel/providers/local/camel-mbox-summary.c
+++ b/camel/providers/local/camel-mbox-summary.c
@@ -548,9 +548,8 @@ summary_update(CamelLocalSummary *cls, off_t offset, CamelFolderChangeInfo *chan
 	/* we mark messages as to whether we've seen them or not.
 	   If we're not starting from the start, we must be starting
 	   from the old end, so everything must be treated as new */
+	camel_folder_summary_prepare_fetch_all (s, ex);
 	count = camel_folder_summary_count(s);
-	if (count != camel_folder_summary_cache_size(s)) /* It makes sense to load summary, if it isn't there. */
-		camel_folder_summary_reload_from_db (s, ex);
 	for (i=0;i<count;i++) {
 		mi = (CamelMboxMessageInfo *)camel_folder_summary_index(s, i);
 		if (offset == 0)
@@ -658,6 +657,7 @@ mbox_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changes, Camel
 	if (st.st_size == 0) {
 		/* empty?  No need to scan at all */
 		d(printf("Empty mbox, clearing summary\n"));
+		camel_folder_summary_prepare_fetch_all (s, ex);
 		count= camel_folder_summary_count(s);
 		for (i=0;i<count;i++) {
 			CamelMessageInfo *info = camel_folder_summary_index(s, i);
@@ -1081,6 +1081,7 @@ camel_mbox_summary_sync_mbox(CamelMboxSummary *cls, guint32 flags, CamelFolderCh
 	camel_mime_parser_scan_pre_from(mp, TRUE);
 	camel_mime_parser_init_with_fd(mp, fd);
 
+	camel_folder_summary_prepare_fetch_all (s, ex);
 	count = camel_folder_summary_count(s);
 	for (i = 0; i < count; i++) {
 		gint pc = (i + 1) * 100 / count;
diff --git a/camel/providers/local/camel-mh-summary.c b/camel/providers/local/camel-mh-summary.c
index 27c87de..53d856d 100644
--- a/camel/providers/local/camel-mh-summary.c
+++ b/camel/providers/local/camel-mh-summary.c
@@ -239,6 +239,7 @@ mh_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, Came
 
 	/* keeps track of all uid's that have not been processed */
 	left = g_hash_table_new(g_str_hash, g_str_equal);
+	camel_folder_summary_prepare_fetch_all ((CamelFolderSummary *)cls, ex);
 	count = camel_folder_summary_count((CamelFolderSummary *)cls);
 	forceindex = count == 0;
 	for (i=0;i<count;i++) {
@@ -306,6 +307,7 @@ mh_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo
 
 	/* FIXME: need to update/honour .mh_sequences or whatever it is */
 
+	camel_folder_summary_prepare_fetch_all ((CamelFolderSummary *)cls, ex);
 	count = camel_folder_summary_count((CamelFolderSummary *)cls);
 	for (i=count-1;i>=0;i--) {
 		info = (CamelLocalMessageInfo *)camel_folder_summary_index((CamelFolderSummary *)cls, i);
diff --git a/camel/providers/local/camel-spool-summary.c b/camel/providers/local/camel-spool-summary.c
index a0325fc..48a432d 100644
--- a/camel/providers/local/camel-spool-summary.c
+++ b/camel/providers/local/camel-spool-summary.c
@@ -310,6 +310,7 @@ spool_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, C
 
 	/* check to see if we need to copy/update the file; missing xev headers prompt this */
 	work = FALSE;
+	camel_folder_summary_prepare_fetch_all (s, ex);
 	count = camel_folder_summary_count(s);
 	for (i=0;!work && i<count; i++) {
 		CamelMboxMessageInfo *info = (CamelMboxMessageInfo *)camel_folder_summary_index(s, i);
diff --git a/camel/providers/nntp/camel-nntp-folder.c b/camel/providers/nntp/camel-nntp-folder.c
index 91e961c..a3d29eb 100644
--- a/camel/providers/nntp/camel-nntp-folder.c
+++ b/camel/providers/nntp/camel-nntp-folder.c
@@ -84,19 +84,52 @@ nntp_folder_refresh_info_online (CamelFolder *folder, CamelException *ex)
 }
 
 static void
-nntp_folder_sync_online (CamelFolder *folder, CamelException *ex)
+unset_flagged_flag (const gchar *uid, CamelFolderSummary *summary)
 {
+	CamelMessageInfo *info;
+
+	info = camel_folder_summary_uid (summary, uid);
+	if (info) {
+		CamelMessageInfoBase *base = (CamelMessageInfoBase *) info;
+
+		if ((base->flags & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0) {
+			base->flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED;
+			base->dirty = TRUE;
+		}
+
+		camel_message_info_free (info);
+	}
+}
+
+static void
+nntp_folder_sync (CamelFolder *folder, CamelException *ex)
+{
+	GPtrArray *changed;
+
 	camel_service_lock (CAMEL_SERVICE (folder->parent_store), CS_REC_CONNECT_LOCK);
-	camel_folder_summary_save_to_db (folder->summary, ex);
+
+	changed = camel_folder_summary_get_changed (folder->summary);
+	if (changed) {
+		g_ptr_array_foreach (changed, (GFunc) unset_flagged_flag, folder->summary);
+		g_ptr_array_foreach (changed, (GFunc) camel_pstring_free, NULL);
+		g_ptr_array_free (changed, TRUE);
+		camel_folder_summary_touch (folder->summary);
+	}
+ 	camel_folder_summary_save_to_db (folder->summary, ex);
+
 	camel_service_unlock (CAMEL_SERVICE (folder->parent_store), CS_REC_CONNECT_LOCK);
 }
 
 static void
+nntp_folder_sync_online (CamelFolder *folder, CamelException *ex)
+{
+	nntp_folder_sync (folder, ex);
+}
+
+static void
 nntp_folder_sync_offline (CamelFolder *folder, CamelException *ex)
 {
-	camel_service_lock (CAMEL_SERVICE (folder->parent_store), CS_REC_CONNECT_LOCK);
-	camel_folder_summary_save_to_db (folder->summary, ex);
-	camel_service_unlock (CAMEL_SERVICE (folder->parent_store), CS_REC_CONNECT_LOCK);
+	nntp_folder_sync (folder, ex);
 }
 
 static gboolean
