diff --git a/src/camel/camel-folder-summary.c b/src/camel/camel-folder-summary.c
index f265011d4..fc989fc5c 100644
--- a/src/camel/camel-folder-summary.c
+++ b/src/camel/camel-folder-summary.c
@@ -55,6 +55,7 @@
 #include "camel-vee-folder.h"
 #include "camel-vtrash-folder.h"
 #include "camel-mime-part-utils.h"
+#include "camel-weak-ref-group.h"
 
 #define CAMEL_FOLDER_SUMMARY_GET_PRIVATE(obj) \
 	(G_TYPE_INSTANCE_GET_PRIVATE \
@@ -248,6 +249,8 @@ folder_summary_finalize (GObject *object)
 	g_rec_mutex_clear (&priv->summary_lock);
 	g_rec_mutex_clear (&priv->filter_lock);
 
+	camel_weak_ref_group_claim_summary_finalize (summary);
+
 	/* Chain up to parent's finalize() method. */
 	G_OBJECT_CLASS (camel_folder_summary_parent_class)->finalize (object);
 }
@@ -1204,7 +1207,7 @@ camel_folder_summary_check_uid (CamelFolderSummary *summary,
 
 	camel_folder_summary_lock (summary);
 
-	ret = g_hash_table_lookup_extended (summary->priv->uids, uid, NULL, NULL);
+	ret = g_hash_table_contains (summary->priv->uids, uid);
 
 	camel_folder_summary_unlock (summary);
 
@@ -1316,7 +1319,7 @@ camel_folder_summary_get_hash (CamelFolderSummary *summary)
  * @uid: a message UID to look for
  *
  * Returns: (nullable) (transfer full): a #CamelMessageInfo for the given @uid,
- *    if it's currently loaded in memoru, or %NULL otherwise. Unref the non-NULL
+ *    if it's currently loaded in memory, or %NULL otherwise. Unref the non-NULL
  *    info with g_object_unref() when done with it.
  *
  * Since: 2.26
@@ -1329,11 +1332,15 @@ camel_folder_summary_peek_loaded (CamelFolderSummary *summary,
 
 	g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), NULL);
 
+	camel_folder_summary_lock (summary);
+
 	info = g_hash_table_lookup (summary->priv->loaded_infos, uid);
 
 	if (info)
 		g_object_ref (info);
 
+	camel_folder_summary_unlock (summary);
+
 	return info;
 }
 
@@ -2010,35 +2017,36 @@ camel_read_mir_callback (gpointer ref,
 	return ret;
 }
 
+typedef struct _SaveData {
+	CamelFolderSummary *summary;
+	const gchar *full_name;
+	CamelDB *cdb;
+	GError **out_error;
+} SaveData;
+
 static void
 save_to_db_cb (gpointer key,
                gpointer value,
-               gpointer data)
+               gpointer user_data)
 {
 	CamelMessageInfo *mi = value;
 	CamelFolderSummary *summary;
-	CamelStore *parent_store;
-	const gchar *full_name;
-	CamelDB *cdb;
 	CamelMIRecord *mir;
 	GString *bdata_str;
-	GError **error = data;
+	SaveData *dt = user_data;
 
-	if (!camel_message_info_get_dirty (mi))
-		return;
+	g_return_if_fail (dt != NULL);
 
 	summary = camel_message_info_ref_summary (mi);
-	if (!summary)
-		return;
-
-	full_name = camel_folder_get_full_name (summary->priv->folder);
-	parent_store = camel_folder_get_parent_store (summary->priv->folder);
-	if (!parent_store) {
-		g_clear_object (&summary);
-		return;
+	if (!summary) {
+		g_warning ("%s: Summary of message info '%s : %s' is NULL, but expected %p", G_STRFUNC, dt->full_name, camel_message_info_get_subject (mi), dt->summary);
+	} else if (summary != dt->summary) {
+		g_warning ("%s: Summary of message info '%s : %s' (%p) doesn't match expected (%p)", G_STRFUNC, dt->full_name, camel_message_info_get_subject (mi), summary, dt->summary);
 	}
+	g_clear_object (&summary);
 
-	cdb = camel_store_get_db (parent_store);
+	if (!camel_message_info_get_dirty (mi))
+		return;
 
 	mir = g_new0 (CamelMIRecord, 1);
 	bdata_str = g_string_new (NULL);
@@ -2047,7 +2055,6 @@ save_to_db_cb (gpointer key,
 		g_warning ("Failed to save message info: %s\n", camel_message_info_get_uid (mi));
 		g_string_free (bdata_str, TRUE);
 		camel_db_camel_mir_free (mir);
-		g_clear_object (&summary);
 		return;
 	}
 
@@ -2055,9 +2062,8 @@ save_to_db_cb (gpointer key,
 	mir->bdata = g_string_free (bdata_str, FALSE);
 	bdata_str = NULL;
 
-	if (camel_db_write_message_info_record (cdb, full_name, mir, error) != 0) {
+	if (camel_db_write_message_info_record (dt->cdb, dt->full_name, mir, dt->out_error) != 0) {
 		camel_db_camel_mir_free (mir);
-		g_clear_object (&summary);
 		return;
 	}
 
@@ -2067,7 +2073,6 @@ save_to_db_cb (gpointer key,
 	camel_message_info_set_dirty (mi, FALSE);
 
 	camel_db_camel_mir_free (mir);
-	g_clear_object (&summary);
 }
 
 static gint
@@ -2077,6 +2082,7 @@ save_message_infos_to_db (CamelFolderSummary *summary,
 	CamelStore *parent_store;
 	CamelDB *cdb;
 	const gchar *full_name;
+	SaveData dt;
 
 	if (is_in_memory_summary (summary))
 		return 0;
@@ -2093,9 +2099,14 @@ save_message_infos_to_db (CamelFolderSummary *summary,
 
 	camel_folder_summary_lock (summary);
 
+	dt.summary = summary;
+	dt.full_name = full_name;
+	dt.cdb = cdb;
+	dt.out_error = error;
+
 	/* Push MessageInfo-es */
 	camel_db_begin_transaction (cdb, NULL);
-	g_hash_table_foreach (summary->priv->loaded_infos, save_to_db_cb, error);
+	g_hash_table_foreach (summary->priv->loaded_infos, save_to_db_cb, &dt);
 	camel_db_end_transaction (cdb, NULL);
 
 	camel_folder_summary_unlock (summary);
@@ -2373,16 +2384,20 @@ summary_assign_uid (CamelFolderSummary *summary,
  *
  * Adds a new @info record to the summary. If the @force_keep_uid is %FALSE,
  * then a new uid is automatically re-assigned by calling
- * camel_folder_summary_next_uid_string(). It's an error to to use
- * @force_keep_uid whe nthe @info has none set.
+ * camel_folder_summary_next_uid_string(). It's an error to use
+ * @force_keep_uid when the @info has none set.
  *
- * The @summary adds its own reference to @info, if needed.
+ * The @summary adds its own reference to @info, if needed, and any
+ * previously loaded info is replaced with the new one.
  **/
 void
 camel_folder_summary_add (CamelFolderSummary *summary,
                           CamelMessageInfo *info,
 			  gboolean force_keep_uid)
 {
+	CamelFolderSummary *info_summary;
+	CamelMessageInfo *loaded_info;
+
 	g_return_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary));
 
 	if (!info)
@@ -2416,9 +2431,34 @@ camel_folder_summary_add (CamelFolderSummary *summary,
 		(gpointer) camel_pstring_strdup (camel_message_info_get_uid (info)),
 		GUINT_TO_POINTER (camel_message_info_get_flags (info)));
 
+	loaded_info = g_hash_table_lookup (summary->priv->loaded_infos, camel_message_info_get_uid (info));
+	if (loaded_info) {
+		printf ("     %s: %p: adding info:%p which is already there as:%p\n", __FUNCTION__, summary, info, loaded_info);
+		/* Dirty hack, to have CamelWeakRefGroup properly cleared,
+		   when the message info leaks due to ref/unref imbalance. */
+		_camel_message_info_unset_summary (loaded_info);
+
+		g_clear_object (&loaded_info);
+	}
+
 	/* Summary always holds a ref for the loaded infos */
 	g_hash_table_insert (summary->priv->loaded_infos, (gpointer) camel_message_info_get_uid (info), g_object_ref (info));
 
+	info_summary = camel_message_info_ref_summary (info);
+	if (info_summary != summary) {
+		GString *bt;
+
+		bt = camel_debug_get_backtrace ();
+		if (bt) {
+			printf ("%s: adding info '%s' with summary %p to summary %p:\n%s\n\n", __FUNCTION__, camel_message_info_get_subject (info), info_summary, summary, bt->str);
+			g_string_free (bt, TRUE);
+		} else {
+			printf ("%s: adding info '%s' with summary %p to summary %p (no backtrace)\n", __FUNCTION__, camel_message_info_get_subject (info), info_summary, summary);
+		}
+		fflush (stdout);
+	}
+	g_clear_object (&info_summary);
+
 	camel_folder_summary_touch (summary);
 
 	camel_folder_summary_unlock (summary);
@@ -2679,12 +2719,7 @@ camel_folder_summary_remove (CamelFolderSummary *summary,
 	g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), FALSE);
 	g_return_val_if_fail (info != NULL, FALSE);
 
-	if (camel_folder_summary_remove_uid (summary, camel_message_info_get_uid (info))) {
-		g_clear_object (&info);
-		return TRUE;
-	}
-
-	return FALSE;
+	return camel_folder_summary_remove_uid (summary, camel_message_info_get_uid (info));
 }
 
 /**
@@ -2701,6 +2736,7 @@ camel_folder_summary_remove_uid (CamelFolderSummary *summary,
                                  const gchar *uid)
 {
 	gpointer ptr_uid = NULL, ptr_flags = NULL;
+	CamelMessageInfo *mi;
 	CamelStore *parent_store;
 	const gchar *full_name;
 	const gchar *uid_copy;
@@ -2719,8 +2755,18 @@ camel_folder_summary_remove_uid (CamelFolderSummary *summary,
 
 	uid_copy = camel_pstring_strdup (uid);
 	g_hash_table_remove (summary->priv->uids, uid_copy);
+
+	mi = g_hash_table_lookup (summary->priv->loaded_infos, uid_copy);
 	g_hash_table_remove (summary->priv->loaded_infos, uid_copy);
 
+	if (mi) {
+		/* Dirty hack, to have CamelWeakRefGroup properly cleared,
+		   when the message info leaks due to ref/unref imbalance. */
+		_camel_message_info_unset_summary (mi);
+
+		g_clear_object (&mi);
+	}
+
 	if (!is_in_memory_summary (summary)) {
 		full_name = camel_folder_get_full_name (summary->priv->folder);
 		parent_store = camel_folder_get_parent_store (summary->priv->folder);
@@ -2774,8 +2820,13 @@ camel_folder_summary_remove_uids (CamelFolderSummary *summary,
 			mi = g_hash_table_lookup (summary->priv->loaded_infos, uid_copy);
 			g_hash_table_remove (summary->priv->loaded_infos, uid_copy);
 
-			if (mi)
+			if (mi) {
+				/* Dirty hack, to have CamelWeakRefGroup properly cleared,
+				   when the message info leaks due to ref/unref imbalance. */
+				_camel_message_info_unset_summary (mi);
 				g_clear_object (&mi);
+			}
+
 			camel_pstring_free (uid_copy);
 		}
 	}
@@ -2895,6 +2946,33 @@ message_info_new_from_headers (CamelFolderSummary *summary,
 	digest = g_alloca (length);
 
 	mi = camel_message_info_new (summary);
+	{
+		CamelFolderSummary *info_summary;
+
+		info_summary = camel_message_info_ref_summary (mi);
+		if (info_summary != summary) {
+			CamelMessageInfo *nfo;
+			GString *bt;
+
+			bt = camel_debug_get_backtrace ();
+			printf ("%s: new mesage info has summary %p, while it is supposed to have %p (%s/refs:%d)\n", __FUNCTION__, info_summary, summary, summary ? G_OBJECT_TYPE_NAME (summary) : "none", summary ? ((GObject *) summary)->ref_count : -1);
+			if (bt) {
+				printf ("%s\n", bt->str);
+				g_string_free (bt, TRUE);
+			}
+			nfo = camel_message_info_new (summary);
+
+			g_clear_object (&info_summary);
+			info_summary = camel_message_info_ref_summary (nfo);
+			if (info_summary == summary)
+				printf ("   %s: second time okay\n", __FUNCTION__);
+			else
+				printf ("   %s: neither second time, got %p, expected %p\n", __FUNCTION__, info_summary, summary);
+			fflush (stdout);
+			g_clear_object (&nfo);
+		}
+		g_clear_object (&info_summary);
+	}
 
 	camel_message_info_set_abort_notifications (mi, TRUE);
 
diff --git a/src/camel/camel-vee-summary.c b/src/camel/camel-vee-summary.c
index e89ee4881..80626e8af 100644
--- a/src/camel/camel-vee-summary.c
+++ b/src/camel/camel-vee-summary.c
@@ -303,7 +303,6 @@ camel_vee_summary_remove (CamelVeeSummary *summary,
                           const gchar *vuid,
                           CamelFolder *subfolder)
 {
-	CamelMessageInfo *mi;
 	GHashTable *vuids;
 
 	g_return_if_fail (CAMEL_IS_VEE_SUMMARY (summary));
@@ -319,17 +318,8 @@ camel_vee_summary_remove (CamelVeeSummary *summary,
 			g_hash_table_remove (summary->priv->vuids_by_subfolder, subfolder);
 	}
 
-	mi = camel_folder_summary_peek_loaded (CAMEL_FOLDER_SUMMARY (summary), vuid);
-
 	camel_folder_summary_remove_uid (CAMEL_FOLDER_SUMMARY (summary), vuid);
 
-	if (mi) {
-		/* unref twice, the first for camel_folder_summary_peek_loaded(),
-		 * the second to actually free the mi */
-		g_object_unref (mi);
-		g_clear_object (&mi);
-	}
-
 	camel_folder_summary_unlock (CAMEL_FOLDER_SUMMARY (summary));
 }
 
diff --git a/src/camel/camel-weak-ref-group.c b/src/camel/camel-weak-ref-group.c
index 3cd8e199b..9bdb128de 100644
--- a/src/camel/camel-weak-ref-group.c
+++ b/src/camel/camel-weak-ref-group.c
@@ -29,6 +29,10 @@
 #include "evolution-data-server-config.h"
 
 #include <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "camel-debug.h"
 
 #include "camel-weak-ref-group.h"
 
@@ -144,6 +148,49 @@ camel_weak_ref_group_unref (CamelWeakRefGroup *group)
 	}
 }
 
+void
+camel_weak_ref_group_claim_summary_finalize (gpointer summary)
+{
+	G_LOCK (groups);
+
+	if (groups && g_hash_table_lookup (groups, summary)) {
+		GString *bt;
+
+		bt = camel_debug_get_backtrace ();
+		printf ("%s: summary gone:%p, while still in the weak ref groups\n%s%s", __FUNCTION__, summary, bt ? bt->str : "", bt ? "\n" : "");
+		if (bt)
+			g_string_free (bt, TRUE);
+	}
+
+	G_UNLOCK (groups);
+}
+
+static void
+dump_left_groups (void)
+{
+	G_LOCK (groups);
+
+	if (!groups) {
+		printf ("%s: no groups left\n", __FUNCTION__);
+	} else {
+		GHashTableIter iter;
+		gpointer key, value;
+
+		printf ("%s: there left %d groups\n", __FUNCTION__, g_hash_table_size (groups));
+		g_hash_table_iter_init (&iter, groups);
+		while (g_hash_table_iter_next (&iter, &key, &value)) {
+			ObjectData *od = value;
+			GObject *xxx;
+
+			xxx = g_weak_ref_get (&od->weakref);
+			printf ("   obj:%p use_count:%ld in-ref:%p\n", key, od->use_count, xxx);
+			g_clear_object (&xxx);
+		}
+	}
+
+	G_UNLOCK (groups);
+}
+
 /**
  * camel_weak_ref_group_set:
  * @group: a #CamelWeakRefGroup
@@ -173,10 +220,16 @@ camel_weak_ref_group_set (CamelWeakRefGroup *group,
 
 			if (od) {
 				od->use_count--;
-				if (!od->use_count)
+				if (!od->use_count) {
 					g_hash_table_remove (groups, group->object);
+				}
 			}
 		} else if (!groups) {
+			static gboolean has_at_exit = FALSE;
+			if (!has_at_exit) {
+				has_at_exit = TRUE;
+				atexit (dump_left_groups);
+			}
 			groups = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, object_data_free);
 		}
 
diff --git a/src/camel/camel-weak-ref-group.h b/src/camel/camel-weak-ref-group.h
index 811d20ccc..7dded372e 100644
--- a/src/camel/camel-weak-ref-group.h
+++ b/src/camel/camel-weak-ref-group.h
@@ -41,6 +41,8 @@ void		camel_weak_ref_group_set	(CamelWeakRefGroup *group,
 						 gpointer object);
 gpointer	camel_weak_ref_group_get	(CamelWeakRefGroup *group);
 
+void		camel_weak_ref_group_claim_summary_finalize (gpointer summary);
+
 G_END_DECLS
 
 #endif /* CAMEL_WEAK_REF_GROUP_H */
diff --git a/src/camel/providers/imapx/camel-imapx-server.c b/src/camel/providers/imapx/camel-imapx-server.c
index fe2358a5b..aa705bd58 100644
--- a/src/camel/providers/imapx/camel-imapx-server.c
+++ b/src/camel/providers/imapx/camel-imapx-server.c
@@ -1339,6 +1339,20 @@ imapx_untagged_fetch (CamelIMAPXServer *is,
 			CamelNamedFlags *server_user_flags;
 			gboolean free_user_flags = FALSE;
 
+			{
+				CamelFolderSummary *zumm;
+
+				zumm = camel_message_info_ref_summary (mi);
+				if (!zumm) {
+					zumm = camel_folder_get_folder_summary (folder);
+					printf ("%s: no summary set for mi '%s' constructed from parser of folder %p (%s, refs:%d), which has summary %p (%d) fetch_changes_folder:%p\n",
+						__FUNCTION__, camel_message_info_get_subject (mi), folder, camel_folder_get_full_name (folder), ((GObject *) folder)->ref_count,
+						zumm, zumm ? ((GObject *) zumm)->ref_count : -1, is->priv->fetch_changes_folder);
+				} else {
+					g_object_unref (zumm);
+				}
+			}
+
 			camel_message_info_set_abort_notifications (mi, TRUE);
 
 			camel_message_info_set_uid (mi, finfo->uid);
