[evolution-data-server] Merge some cleanup bits from camel-gobject.



commit c1730ba391e0c0658d6eb85bdcd1f10113ddcf3e
Author: Matthew Barnes <mbarnes redhat com>
Date:   Wed Apr 14 17:50:23 2010 -0400

    Merge some cleanup bits from camel-gobject.

 camel/camel-disco-folder.c   |  394 +++++-----
 camel/camel-disco-folder.h   |    2 +
 camel/camel-disco-store.c    |  314 ++++----
 camel/camel-disco-store.h    |    2 +
 camel/camel-folder-summary.c |    1 -
 camel/camel-folder.c         | 1899 ++++++++++++++++++++++--------------------
 camel/camel-store-summary.c  |  893 +++++++++++---------
 camel/camel-store-summary.h  |    2 +
 camel/camel-store.c          |  762 +++++++++---------
 camel/camel-store.h          |    2 +
 10 files changed, 2255 insertions(+), 2016 deletions(-)
---
diff --git a/camel/camel-disco-folder.c b/camel/camel-disco-folder.c
index 9ed5502..cde2232 100644
--- a/camel/camel-disco-folder.c
+++ b/camel/camel-disco-folder.c
@@ -25,7 +25,6 @@
 #include <config.h>
 #endif
 
-#include <glib.h>
 #include <glib/gi18n-lib.h>
 
 #include "camel-disco-folder.h"
@@ -33,9 +32,6 @@
 #include "camel-exception.h"
 #include "camel-session.h"
 
-#define CF_CLASS(o) (CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS (o)))
-#define CDF_CLASS(o) (CAMEL_DISCO_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS (o)))
-
 static CamelFolderClass *parent_class = NULL;
 static GSList *disco_folder_properties;
 
@@ -43,52 +39,9 @@ static CamelProperty disco_property_list[] = {
 	{ CAMEL_DISCO_FOLDER_OFFLINE_SYNC, "offline_sync", N_("Copy folder content locally for offline operation") },
 };
 
-static gint disco_getv(CamelObject *object, CamelException *ex, CamelArgGetV *args);
-static gint disco_setv(CamelObject *object, CamelException *ex, CamelArgV *args);
-
-static void disco_refresh_info (CamelFolder *folder, CamelException *ex);
-static void disco_refresh_info_online (CamelFolder *folder, CamelException *ex);
-static void disco_sync (CamelFolder *folder, gboolean expunge, CamelException *ex);
+/* Forward Declarations */
 static void disco_expunge (CamelFolder *folder, CamelException *ex);
 
-static void disco_append_message (CamelFolder *folder, CamelMimeMessage *message,
-				  const CamelMessageInfo *info, gchar **appended_uid, CamelException *ex);
-static void disco_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
-					CamelFolder *destination,
-					GPtrArray **transferred_uids,
-					gboolean delete_originals,
-					CamelException *ex);
-
-static void disco_cache_message       (CamelDiscoFolder *disco_folder,
-				       const gchar *uid, CamelException *ex);
-static void disco_prepare_for_offline (CamelDiscoFolder *disco_folder,
-				       const gchar *expression,
-				       CamelException *ex);
-
-static void
-camel_disco_folder_class_init (CamelDiscoFolderClass *camel_disco_folder_class)
-{
-	CamelFolderClass *camel_folder_class = CAMEL_FOLDER_CLASS (camel_disco_folder_class);
-
-	parent_class = CAMEL_FOLDER_CLASS (camel_type_get_global_classfuncs (camel_folder_get_type ()));
-
-	((CamelObjectClass *)camel_folder_class)->getv = disco_getv;
-	((CamelObjectClass *)camel_folder_class)->setv = disco_setv;
-
-	/* virtual method definition */
-	camel_disco_folder_class->cache_message = disco_cache_message;
-	camel_disco_folder_class->prepare_for_offline = disco_prepare_for_offline;
-	camel_disco_folder_class->refresh_info_online = disco_refresh_info_online;
-
-	/* virtual method overload */
-	camel_folder_class->refresh_info = disco_refresh_info;
-	camel_folder_class->sync = disco_sync;
-	camel_folder_class->expunge = disco_expunge;
-
-	camel_folder_class->append_message = disco_append_message;
-	camel_folder_class->transfer_messages_to = disco_transfer_messages_to;
-}
-
 struct _cdf_sync_msg {
 	CamelSessionThreadMsg msg;
 
@@ -154,37 +107,10 @@ cdf_folder_changed(CamelFolder *folder, CamelFolderChangeInfo *changes, gpointer
 	}
 }
 
-static void
-camel_disco_folder_init(CamelDiscoFolder *folder)
-{
-	camel_object_hook_event(folder, "folder_changed", (CamelObjectEventHookFunc)cdf_folder_changed, NULL);
-}
-
-CamelType
-camel_disco_folder_get_type (void)
-{
-	static CamelType camel_disco_folder_type = CAMEL_INVALID_TYPE;
-	gint i;
-
-	if (camel_disco_folder_type == CAMEL_INVALID_TYPE) {
-		camel_disco_folder_type = camel_type_register (
-			CAMEL_FOLDER_TYPE, "CamelDiscoFolder",
-			sizeof (CamelDiscoFolder),
-			sizeof (CamelDiscoFolderClass),
-			(CamelObjectClassInitFunc)camel_disco_folder_class_init, NULL,
-			(CamelObjectInitFunc)camel_disco_folder_init, NULL);
-
-		for (i = 0; i < G_N_ELEMENTS (disco_property_list); i++) {
-			disco_property_list[i].description = _(disco_property_list[i].description);
-			disco_folder_properties = g_slist_prepend(disco_folder_properties, &disco_property_list[i]);
-		}
-	}
-
-	return camel_disco_folder_type;
-}
-
 static gint
-disco_getv(CamelObject *object, CamelException *ex, CamelArgGetV *args)
+disco_getv (CamelObject *object,
+            CamelException *ex,
+            CamelArgGetV *args)
 {
 	gint i, count=0;
 	guint32 tag;
@@ -223,7 +149,9 @@ disco_getv(CamelObject *object, CamelException *ex, CamelArgGetV *args)
 }
 
 static gint
-disco_setv(CamelObject *object, CamelException *ex, CamelArgV *args)
+disco_setv (CamelObject *object,
+            CamelException *ex,
+            CamelArgV *args)
 {
 	gint save = 0;
 	gint i;
@@ -255,23 +183,25 @@ disco_setv(CamelObject *object, CamelException *ex, CamelArgV *args)
 }
 
 static void
-disco_refresh_info_online(CamelFolder *folder, CamelException *ex)
+disco_refresh_info (CamelFolder *folder,
+                    CamelException *ex)
 {
-	/* NOOP */;
-}
+	CamelDiscoFolderClass *disco_folder_class;
 
-static void
-disco_refresh_info (CamelFolder *folder, CamelException *ex)
-{
 	if (camel_disco_store_status (CAMEL_DISCO_STORE (folder->parent_store)) != CAMEL_DISCO_STORE_ONLINE)
 		return;
-	CDF_CLASS (folder)->refresh_info_online (folder, ex);
+
+	disco_folder_class = CAMEL_DISCO_FOLDER_GET_CLASS (folder);
+
+	disco_folder_class->refresh_info_online (folder, ex);
 }
 
 static void
-disco_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
+disco_sync (CamelFolder *folder,
+            gboolean expunge,
+            CamelException *ex)
 {
-	void (*sync)(CamelFolder *, CamelException *) = NULL;
+	CamelDiscoFolderClass *disco_folder_class;
 
 	if (expunge) {
 		disco_expunge (folder, ex);
@@ -281,61 +211,61 @@ disco_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
 
 	camel_object_state_write(folder);
 
+	disco_folder_class = CAMEL_DISCO_FOLDER_GET_CLASS (folder);
+
 	switch (camel_disco_store_status (CAMEL_DISCO_STORE (folder->parent_store))) {
 	case CAMEL_DISCO_STORE_ONLINE:
-		sync = CDF_CLASS (folder)->sync_online;
-		break;
+		disco_folder_class->sync_online (folder, ex);
+		return;
 
 	case CAMEL_DISCO_STORE_OFFLINE:
-		sync = CDF_CLASS (folder)->sync_offline;
-		break;
+		disco_folder_class->sync_offline (folder, ex);
+		return;
 
 	case CAMEL_DISCO_STORE_RESYNCING:
-		sync = CDF_CLASS (folder)->sync_resyncing;
-		break;
+		disco_folder_class->sync_resyncing (folder, ex);
+		return;
 	}
 
-	if (sync) {
-		sync(folder, ex);
-	} else {
-		g_warning("Class '%s' doesn't implement CamelDiscoFolder:sync methods",
-			  ((CamelObject *)folder)->klass->name);
-	}
+	g_warn_if_reached ();
 }
 
 static void
-disco_expunge_uids (CamelFolder *folder, GPtrArray *uids, CamelException *ex)
+disco_expunge_uids (CamelFolder *folder,
+                    GPtrArray *uids,
+                    CamelException *ex)
 {
 	CamelDiscoStore *disco = CAMEL_DISCO_STORE (folder->parent_store);
-	void (*expunge_uids)(CamelFolder *, GPtrArray *, CamelException *) = NULL;
+	CamelDiscoFolderClass *disco_folder_class;
 
 	if (uids->len == 0)
 		return;
 
+	disco_folder_class = CAMEL_DISCO_FOLDER_GET_CLASS (folder);
+
 	switch (camel_disco_store_status (disco)) {
 	case CAMEL_DISCO_STORE_ONLINE:
-		expunge_uids = CDF_CLASS (folder)->expunge_uids_online;
-		break;
+		disco_folder_class->expunge_uids_online (
+			folder, uids, ex);
+		return;
 
 	case CAMEL_DISCO_STORE_OFFLINE:
-		expunge_uids = CDF_CLASS (folder)->expunge_uids_offline;
-		break;
+		disco_folder_class->expunge_uids_offline (
+			folder, uids, ex);
+		return;
 
 	case CAMEL_DISCO_STORE_RESYNCING:
-		expunge_uids = CDF_CLASS (folder)->expunge_uids_resyncing;
-		break;
+		disco_folder_class->expunge_uids_resyncing (
+			folder, uids, ex);
+		return;
 	}
 
-	if (expunge_uids) {
-		expunge_uids(folder, uids, ex);
-	} else {
-		g_warning("Class '%s' doesn't implement CamelDiscoFolder:expunge_uids methods",
-			  ((CamelObject *)folder)->klass->name);
-	}
+	g_warn_if_reached ();
 }
 
 static void
-disco_expunge (CamelFolder *folder, CamelException *ex)
+disco_expunge (CamelFolder *folder,
+               CamelException *ex)
 {
 	GPtrArray *uids;
 	gint i;
@@ -359,104 +289,77 @@ disco_expunge (CamelFolder *folder, CamelException *ex)
 }
 
 static void
-disco_append_message (CamelFolder *folder, CamelMimeMessage *message,
-		      const CamelMessageInfo *info, gchar **appended_uid,
-		      CamelException *ex)
+disco_append_message (CamelFolder *folder,
+                      CamelMimeMessage *message,
+                      const CamelMessageInfo *info,
+                      gchar **appended_uid,
+                      CamelException *ex)
 {
 	CamelDiscoStore *disco = CAMEL_DISCO_STORE (folder->parent_store);
+	CamelDiscoFolderClass *disco_folder_class;
+
+	disco_folder_class = CAMEL_DISCO_FOLDER_GET_CLASS (folder);
 
 	switch (camel_disco_store_status (disco)) {
 	case CAMEL_DISCO_STORE_ONLINE:
-		CDF_CLASS (folder)->append_online (folder, message, info,
-						   appended_uid, ex);
-		break;
+		disco_folder_class->append_online (
+			folder, message, info, appended_uid, ex);
+		return;
 
 	case CAMEL_DISCO_STORE_OFFLINE:
-		CDF_CLASS (folder)->append_offline (folder, message, info,
-						    appended_uid, ex);
-		break;
+		disco_folder_class->append_offline (
+			folder, message, info, appended_uid, ex);
+		return;
 
 	case CAMEL_DISCO_STORE_RESYNCING:
-		CDF_CLASS (folder)->append_resyncing (folder, message, info,
-						      appended_uid, ex);
-		break;
+		disco_folder_class->append_resyncing (
+			folder, message, info, appended_uid, ex);
+		return;
 	}
+
+	g_warn_if_reached ();
 }
 
 static void
-disco_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
-			    CamelFolder *dest, GPtrArray **transferred_uids,
-			    gboolean delete_originals, CamelException *ex)
+disco_transfer_messages_to (CamelFolder *source,
+                            GPtrArray *uids,
+                            CamelFolder *dest,
+                            GPtrArray **transferred_uids,
+                            gboolean delete_originals,
+                            CamelException *ex)
 {
 	CamelDiscoStore *disco = CAMEL_DISCO_STORE (source->parent_store);
+	CamelDiscoFolderClass *disco_folder_class;
+
+	disco_folder_class = CAMEL_DISCO_FOLDER_GET_CLASS (source);
 
 	switch (camel_disco_store_status (disco)) {
 	case CAMEL_DISCO_STORE_ONLINE:
-		CDF_CLASS (source)->transfer_online (source, uids,
-						     dest, transferred_uids,
-						     delete_originals, ex);
-		break;
+		disco_folder_class->transfer_online (
+			source, uids, dest, transferred_uids,
+			delete_originals, ex);
+		return;
 
 	case CAMEL_DISCO_STORE_OFFLINE:
-		CDF_CLASS (source)->transfer_offline (source, uids,
-						      dest, transferred_uids,
-						      delete_originals, ex);
-		break;
+		disco_folder_class->transfer_offline (
+			source, uids, dest, transferred_uids,
+			delete_originals, ex);
+		return;
 
 	case CAMEL_DISCO_STORE_RESYNCING:
-		CDF_CLASS (source)->transfer_resyncing (source, uids,
-							dest, transferred_uids,
-							delete_originals, ex);
-		break;
+		disco_folder_class->transfer_resyncing (
+			source, uids, dest, transferred_uids,
+			delete_originals, ex);
+		return;
 	}
-}
 
-/**
- * camel_disco_folder_expunge_uids:
- * @folder: a (disconnectable) folder
- * @uids: array of UIDs to expunge
- * @ex: a CamelException
- *
- * This expunges the messages in @uids from @folder. It should take
- * whatever steps are needed to avoid expunging any other messages,
- * although in some cases it may not be possible to avoid expunging
- * messages that are marked deleted by another client at the same time
- * as the expunge_uids call is running.
- **/
-void
-camel_disco_folder_expunge_uids (CamelFolder *folder, GPtrArray *uids,
-				 CamelException *ex)
-{
-	disco_expunge_uids (folder, uids, ex);
-}
-
-static void
-disco_cache_message (CamelDiscoFolder *disco_folder, const gchar *uid,
-		     CamelException *ex)
-{
-	g_warning ("CamelDiscoFolder::cache_message not implemented for '%s'",
-		   camel_type_to_name (CAMEL_OBJECT_GET_TYPE (disco_folder)));
-}
-
-/**
- * camel_disco_folder_cache_message:
- * @disco_folder: the folder
- * @uid: the UID of the message to cache
- * @ex: a CamelException
- *
- * Requests that @disco_folder cache message @uid to disk.
- **/
-void
-camel_disco_folder_cache_message (CamelDiscoFolder *disco_folder,
-				  const gchar *uid, CamelException *ex)
-{
-	CDF_CLASS (disco_folder)->cache_message (disco_folder, uid, ex);
+	g_warn_if_reached ();
 }
 
 static void
 disco_prepare_for_offline (CamelDiscoFolder *disco_folder,
-			   const gchar *expression,
-			   CamelException *ex)
+                           const gchar *expression,
+                           CamelException *ex)
 {
 	CamelFolder *folder = CAMEL_FOLDER (disco_folder);
 	GPtrArray *uids;
@@ -491,6 +394,116 @@ disco_prepare_for_offline (CamelDiscoFolder *disco_folder,
 	camel_operation_end(NULL);
 }
 
+static void
+disco_refresh_info_online (CamelFolder *folder,
+                           CamelException *ex)
+{
+	/* NOOP */;
+}
+
+static void
+camel_disco_folder_class_init (CamelDiscoFolderClass *class)
+{
+	CamelObjectClass *camel_object_class;
+	CamelFolderClass *folder_class;
+	gint ii;
+
+	parent_class = CAMEL_FOLDER_CLASS (camel_type_get_global_classfuncs (camel_folder_get_type ()));
+
+	camel_object_class = CAMEL_OBJECT_CLASS (class);
+	camel_object_class->getv = disco_getv;
+	camel_object_class->setv = disco_setv;
+
+	folder_class = CAMEL_FOLDER_CLASS (class);
+	folder_class->refresh_info = disco_refresh_info;
+	folder_class->sync = disco_sync;
+	folder_class->expunge = disco_expunge;
+	folder_class->append_message = disco_append_message;
+	folder_class->transfer_messages_to = disco_transfer_messages_to;
+
+	class->prepare_for_offline = disco_prepare_for_offline;
+	class->refresh_info_online = disco_refresh_info_online;
+
+	for (ii = 0; ii < G_N_ELEMENTS (disco_property_list); ii++) {
+		disco_property_list[ii].description =
+			_(disco_property_list[ii].description);
+		disco_folder_properties = g_slist_prepend (
+			disco_folder_properties, &disco_property_list[ii]);
+	}
+}
+
+static void
+camel_disco_folder_init (CamelDiscoFolder *disco_folder)
+{
+	camel_object_hook_event (
+		disco_folder, "folder_changed",
+		(CamelObjectEventHookFunc) cdf_folder_changed, NULL);
+}
+
+CamelType
+camel_disco_folder_get_type (void)
+{
+	static CamelType camel_disco_folder_type = CAMEL_INVALID_TYPE;
+
+	if (camel_disco_folder_type == CAMEL_INVALID_TYPE) {
+		camel_disco_folder_type = camel_type_register (
+			CAMEL_FOLDER_TYPE, "CamelDiscoFolder",
+			sizeof (CamelDiscoFolder),
+			sizeof (CamelDiscoFolderClass),
+			(CamelObjectClassInitFunc)camel_disco_folder_class_init, NULL,
+			(CamelObjectInitFunc)camel_disco_folder_init, NULL);
+	}
+
+	return camel_disco_folder_type;
+}
+
+/**
+ * camel_disco_folder_expunge_uids:
+ * @folder: a (disconnectable) folder
+ * @uids: array of UIDs to expunge
+ * @ex: a CamelException
+ *
+ * This expunges the messages in @uids from @folder. It should take
+ * whatever steps are needed to avoid expunging any other messages,
+ * although in some cases it may not be possible to avoid expunging
+ * messages that are marked deleted by another client at the same time
+ * as the expunge_uids call is running.
+ **/
+void
+camel_disco_folder_expunge_uids (CamelFolder *folder,
+                                 GPtrArray *uids,
+                                 CamelException *ex)
+{
+	g_return_if_fail (CAMEL_IS_DISCO_FOLDER (folder));
+	g_return_if_fail (uids != NULL);
+
+	disco_expunge_uids (folder, uids, ex);
+}
+
+/**
+ * camel_disco_folder_cache_message:
+ * @disco_folder: the folder
+ * @uid: the UID of the message to cache
+ * @ex: a CamelException
+ *
+ * Requests that @disco_folder cache message @uid to disk.
+ **/
+void
+camel_disco_folder_cache_message (CamelDiscoFolder *disco_folder,
+                                  const gchar *uid,
+                                  CamelException *ex)
+{
+	CamelDiscoFolderClass *class;
+
+	g_return_if_fail (CAMEL_IS_DISCO_FOLDER (disco_folder));
+	g_return_if_fail (uid != NULL);
+
+	class = CAMEL_DISCO_FOLDER_GET_CLASS (disco_folder);
+	g_return_if_fail (class->cache_message != NULL);
+
+	class->cache_message (disco_folder, uid, ex);
+}
+
 /**
  * camel_disco_folder_prepare_for_offline:
  * @disco_folder: the folder
@@ -504,10 +517,15 @@ disco_prepare_for_offline (CamelDiscoFolder *disco_folder,
  **/
 void
 camel_disco_folder_prepare_for_offline (CamelDiscoFolder *disco_folder,
-					const gchar *expression,
-					CamelException *ex)
+                                        const gchar *expression,
+                                        CamelException *ex)
 {
+	CamelDiscoFolderClass *class;
+
 	g_return_if_fail (CAMEL_IS_DISCO_FOLDER (disco_folder));
 
-	CDF_CLASS (disco_folder)->prepare_for_offline (disco_folder, expression, ex);
+	class = CAMEL_DISCO_FOLDER_GET_CLASS (disco_folder);
+	g_return_if_fail (class->prepare_for_offline != NULL);
+
+	class->prepare_for_offline (disco_folder, expression, ex);
 }
diff --git a/camel/camel-disco-folder.h b/camel/camel-disco-folder.h
index 98f9672..7bd8fce 100644
--- a/camel/camel-disco-folder.h
+++ b/camel/camel-disco-folder.h
@@ -36,6 +36,8 @@
 #define CAMEL_DISCO_FOLDER(obj)     (CAMEL_CHECK_CAST((obj), CAMEL_DISCO_FOLDER_TYPE, CamelDiscoFolder))
 #define CAMEL_DISCO_FOLDER_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_DISCO_FOLDER_TYPE, CamelDiscoFolderClass))
 #define CAMEL_IS_DISCO_FOLDER(o)    (CAMEL_CHECK_TYPE((o), CAMEL_DISCO_FOLDER_TYPE))
+#define CAMEL_DISCO_FOLDER_GET_CLASS(obj) \
+	((CamelDiscoFolderClass *) CAMEL_OBJECT_GET_CLASS (obj))
 
 G_BEGIN_DECLS
 
diff --git a/camel/camel-disco-store.c b/camel/camel-disco-store.c
index 8b49c54..7510d6b 100644
--- a/camel/camel-disco-store.c
+++ b/camel/camel-disco-store.c
@@ -26,7 +26,6 @@
 #include <config.h>
 #endif
 
-#include <glib.h>
 #include <glib/gi18n-lib.h>
 
 #include "camel-disco-diary.h"
@@ -37,96 +36,14 @@
 
 #define d(x)
 
-#define CDS_CLASS(o) (CAMEL_DISCO_STORE_CLASS (CAMEL_OBJECT_GET_CLASS (o)))
-
 static CamelStoreClass *parent_class = NULL;
 
-static void disco_construct (CamelService *service, CamelSession *session,
-			     CamelProvider *provider, CamelURL *url,
-			     CamelException *ex);
-static gboolean disco_connect (CamelService *service, CamelException *ex);
-static void disco_cancel_connect (CamelService *service);
-static gboolean disco_disconnect (CamelService *service, gboolean clean, CamelException *ex);
-static CamelFolder *disco_get_folder (CamelStore *store, const gchar *name,
-				      guint32 flags, CamelException *ex);
-static CamelFolderInfo *disco_get_folder_info (CamelStore *store,
-					       const gchar *top, guint32 flags,
-					       CamelException *ex);
-static void set_status (CamelDiscoStore *disco_store,
-			CamelDiscoStoreStatus status,
-			CamelException *ex);
-static gboolean can_work_offline (CamelDiscoStore *disco_store);
-
-static gint disco_setv (CamelObject *object, CamelException *ex, CamelArgV *args);
-static gint disco_getv (CamelObject *object, CamelException *ex, CamelArgGetV *args);
-
 static void
-camel_disco_store_class_init (CamelDiscoStoreClass *camel_disco_store_class)
-{
-	CamelObjectClass *camel_object_class =
-		CAMEL_OBJECT_CLASS (camel_disco_store_class);
-	CamelServiceClass *camel_service_class =
-		CAMEL_SERVICE_CLASS (camel_disco_store_class);
-	CamelStoreClass *camel_store_class =
-		CAMEL_STORE_CLASS (camel_disco_store_class);
-
-	parent_class = CAMEL_STORE_CLASS (camel_type_get_global_classfuncs (camel_store_get_type ()));
-
-	/* virtual method definition */
-	camel_disco_store_class->set_status = set_status;
-	camel_disco_store_class->can_work_offline = can_work_offline;
-
-	/* virtual method overload */
-	camel_object_class->setv = disco_setv;
-	camel_object_class->getv = disco_getv;
-
-	camel_service_class->construct = disco_construct;
-	camel_service_class->connect = disco_connect;
-	camel_service_class->disconnect = disco_disconnect;
-	camel_service_class->cancel_connect = disco_cancel_connect;
-
-	camel_store_class->get_folder = disco_get_folder;
-	camel_store_class->get_folder_info = disco_get_folder_info;
-}
-
-CamelType
-camel_disco_store_get_type (void)
-{
-	static CamelType camel_disco_store_type = CAMEL_INVALID_TYPE;
-
-	if (camel_disco_store_type == CAMEL_INVALID_TYPE) {
-		camel_disco_store_type = camel_type_register (
-			CAMEL_STORE_TYPE,
-			"CamelDiscoStore",
-			sizeof (CamelDiscoStore),
-			sizeof (CamelDiscoStoreClass),
-			(CamelObjectClassInitFunc) camel_disco_store_class_init,
-			NULL,
-			NULL,
-			NULL);
-	}
-
-	return camel_disco_store_type;
-}
-
-static gint
-disco_setv (CamelObject *object, CamelException *ex, CamelArgV *args)
-{
-	/* CamelDiscoStore doesn't currently have anything to set */
-	return CAMEL_OBJECT_CLASS (parent_class)->setv (object, ex, args);
-}
-
-static gint
-disco_getv (CamelObject *object, CamelException *ex, CamelArgGetV *args)
-{
-	/* CamelDiscoStore doesn't currently have anything to get */
-	return CAMEL_OBJECT_CLASS (parent_class)->getv (object, ex, args);
-}
-
-static void
-disco_construct (CamelService *service, CamelSession *session,
-		 CamelProvider *provider, CamelURL *url,
-		 CamelException *ex)
+disco_store_construct (CamelService *service,
+                       CamelSession *session,
+                       CamelProvider *provider,
+                       CamelURL *url,
+                       CamelException *ex)
 {
 	CamelDiscoStore *disco = CAMEL_DISCO_STORE (service);
 
@@ -139,7 +56,8 @@ disco_construct (CamelService *service, CamelSession *session,
 }
 
 static gboolean
-disco_connect (CamelService *service, CamelException *ex)
+disco_store_connect (CamelService *service,
+                     CamelException *ex)
 {
 	CamelDiscoStore *store = CAMEL_DISCO_STORE (service);
 	CamelDiscoStoreStatus status;
@@ -158,7 +76,7 @@ disco_connect (CamelService *service, CamelException *ex)
 	switch (status) {
 	case CAMEL_DISCO_STORE_ONLINE:
 	case CAMEL_DISCO_STORE_RESYNCING:
-		if (!CDS_CLASS (service)->connect_online (service, ex))
+		if (!CAMEL_DISCO_STORE_GET_CLASS (service)->connect_online (service, ex))
 			return FALSE;
 
 		if (!store->diary)
@@ -183,37 +101,29 @@ disco_connect (CamelService *service, CamelException *ex)
 		return camel_service_connect (service, ex);
 
 	case CAMEL_DISCO_STORE_OFFLINE:
-		return CDS_CLASS (service)->connect_offline (service, ex);
+		return CAMEL_DISCO_STORE_GET_CLASS (service)->connect_offline (service, ex);
 	}
 
 	g_assert_not_reached ();
 	return FALSE;
 }
 
-static void
-disco_cancel_connect (CamelService *service)
-{
-	CamelDiscoStore *store = CAMEL_DISCO_STORE (service);
-
-	/* Fall back */
-	store->status = CAMEL_DISCO_STORE_OFFLINE;
-	CAMEL_SERVICE_CLASS (parent_class)->cancel_connect (service);
-}
-
 static gboolean
-disco_disconnect (CamelService *service, gboolean clean, CamelException *ex)
+disco_store_disconnect (CamelService *service,
+                        gboolean clean,
+                        CamelException *ex)
 {
 	CamelDiscoStore *store = CAMEL_DISCO_STORE (service);
 
 	switch (camel_disco_store_status (store)) {
 	case CAMEL_DISCO_STORE_ONLINE:
 	case CAMEL_DISCO_STORE_RESYNCING:
-		if (!CDS_CLASS (service)->disconnect_online (service, clean, ex))
+		if (!CAMEL_DISCO_STORE_GET_CLASS (service)->disconnect_online (service, clean, ex))
 			return FALSE;
 		break;
 
 	case CAMEL_DISCO_STORE_OFFLINE:
-		if (!CDS_CLASS (service)->disconnect_offline (service, clean, ex))
+		if (!CAMEL_DISCO_STORE_GET_CLASS (service)->disconnect_offline (service, clean, ex))
 			return FALSE;
 		break;
 
@@ -222,36 +132,61 @@ disco_disconnect (CamelService *service, gboolean clean, CamelException *ex)
 	return CAMEL_SERVICE_CLASS (parent_class)->disconnect (service, clean, ex);
 }
 
+static void
+disco_store_cancel_connect (CamelService *service)
+{
+	CamelDiscoStore *store = CAMEL_DISCO_STORE (service);
+
+	/* Fall back */
+	store->status = CAMEL_DISCO_STORE_OFFLINE;
+	CAMEL_SERVICE_CLASS (parent_class)->cancel_connect (service);
+}
+
 static CamelFolder *
-disco_get_folder (CamelStore *store, const gchar *name,
-		  guint32 flags, CamelException *ex)
+disco_store_get_folder (CamelStore *store,
+                        const gchar *name,
+                        guint32 flags,
+                        CamelException *ex)
 {
 	CamelDiscoStore *disco_store = CAMEL_DISCO_STORE (store);
+	CamelDiscoStoreClass *class;
+
+	class = CAMEL_DISCO_STORE_GET_CLASS (disco_store);
+	g_return_val_if_fail (class->get_folder_online != NULL, NULL);
+	g_return_val_if_fail (class->get_folder_offline != NULL, NULL);
+	g_return_val_if_fail (class->get_folder_resyncing != NULL, NULL);
 
 	switch (camel_disco_store_status (disco_store)) {
 	case CAMEL_DISCO_STORE_ONLINE:
-		return CDS_CLASS (store)->get_folder_online (store, name, flags, ex);
+		return class->get_folder_online (store, name, flags, ex);
 
 	case CAMEL_DISCO_STORE_OFFLINE:
-		return CDS_CLASS (store)->get_folder_offline (store, name, flags, ex);
+		return class->get_folder_offline (store, name, flags, ex);
 
 	case CAMEL_DISCO_STORE_RESYNCING:
-		return CDS_CLASS (store)->get_folder_resyncing (store, name, flags, ex);
+		return class->get_folder_resyncing (store, name, flags, ex);
 	}
 
-	g_assert_not_reached ();
-	return NULL;
+	g_return_val_if_reached (NULL);
 }
 
 static CamelFolderInfo *
-disco_get_folder_info (CamelStore *store, const gchar *top,
-		       guint32 flags, CamelException *ex)
+disco_store_get_folder_info (CamelStore *store,
+                             const gchar *top,
+                             guint32 flags,
+                             CamelException *ex)
 {
 	CamelDiscoStore *disco_store = CAMEL_DISCO_STORE (store);
+	CamelDiscoStoreClass *class;
+
+	class = CAMEL_DISCO_STORE_GET_CLASS (disco_store);
+	g_return_val_if_fail (class->get_folder_info_online != NULL, NULL);
+	g_return_val_if_fail (class->get_folder_info_offline != NULL, NULL);
+	g_return_val_if_fail (class->get_folder_info_resyncing != NULL, NULL);
 
 	switch (camel_disco_store_status (disco_store)) {
 	case CAMEL_DISCO_STORE_ONLINE:
-		return CDS_CLASS (store)->get_folder_info_online (store, top, flags, ex);
+		return class->get_folder_info_online (store, top, flags, ex);
 
 	case CAMEL_DISCO_STORE_OFFLINE:
 		/* Can't edit subscriptions while offline */
@@ -261,38 +196,19 @@ disco_get_folder_info (CamelStore *store, const gchar *top,
 			return NULL;
 		}
 
-		return CDS_CLASS (store)->get_folder_info_offline (store, top, flags, ex);
+		return class->get_folder_info_offline (store, top, flags, ex);
 
 	case CAMEL_DISCO_STORE_RESYNCING:
-		return CDS_CLASS (store)->get_folder_info_resyncing (store, top, flags, ex);
+		return class->get_folder_info_resyncing (store, top, flags, ex);
 	}
 
-	g_assert_not_reached ();
-	return NULL;
-}
-
-/**
- * camel_disco_store_status:
- * @store: a disconnectable store
- *
- * Returns: the current online/offline status of @store.
- **/
-CamelDiscoStoreStatus
-camel_disco_store_status (CamelDiscoStore *store)
-{
-	CamelService *service = CAMEL_SERVICE (store);
-
-	g_return_val_if_fail (CAMEL_IS_DISCO_STORE (store), CAMEL_DISCO_STORE_ONLINE);
-
-	if (store->status != CAMEL_DISCO_STORE_OFFLINE
-	    && !camel_session_is_online (service->session))
-		store->status = CAMEL_DISCO_STORE_OFFLINE;
-
-	return store->status;
+	g_return_val_if_reached (NULL);
 }
 
 static void
-set_status(CamelDiscoStore *disco_store, CamelDiscoStoreStatus status, CamelException *ex)
+disco_store_set_status (CamelDiscoStore *disco_store,
+                        CamelDiscoStoreStatus status,
+                        CamelException *ex)
 {
 	CamelException x;
 	CamelService *service = CAMEL_SERVICE (disco_store);
@@ -340,6 +256,67 @@ set_status(CamelDiscoStore *disco_store, CamelDiscoStoreStatus status, CamelExce
 	camel_service_connect (CAMEL_SERVICE (disco_store), ex);
 }
 
+static void
+camel_disco_store_class_init (CamelDiscoStoreClass *class)
+{
+	CamelServiceClass *service_class;
+	CamelStoreClass *store_class;
+
+	parent_class = CAMEL_STORE_CLASS (camel_type_get_global_classfuncs (camel_store_get_type ()));
+
+	service_class = CAMEL_SERVICE_CLASS (class);
+	service_class->construct = disco_store_construct;
+	service_class->connect = disco_store_connect;
+	service_class->disconnect = disco_store_disconnect;
+	service_class->cancel_connect = disco_store_cancel_connect;
+
+	store_class = CAMEL_STORE_CLASS (class);
+	store_class->get_folder = disco_store_get_folder;
+	store_class->get_folder_info = disco_store_get_folder_info;
+
+	class->set_status = disco_store_set_status;
+}
+
+CamelType
+camel_disco_store_get_type (void)
+{
+	static CamelType camel_disco_store_type = CAMEL_INVALID_TYPE;
+
+	if (camel_disco_store_type == CAMEL_INVALID_TYPE) {
+		camel_disco_store_type = camel_type_register (
+			CAMEL_STORE_TYPE,
+			"CamelDiscoStore",
+			sizeof (CamelDiscoStore),
+			sizeof (CamelDiscoStoreClass),
+			(CamelObjectClassInitFunc) camel_disco_store_class_init,
+			NULL,
+			NULL,
+			NULL);
+	}
+
+	return camel_disco_store_type;
+}
+
+/**
+ * camel_disco_store_status:
+ * @store: a disconnectable store
+ *
+ * Returns: the current online/offline status of @store.
+ **/
+CamelDiscoStoreStatus
+camel_disco_store_status (CamelDiscoStore *store)
+{
+	CamelService *service = CAMEL_SERVICE (store);
+
+	g_return_val_if_fail (CAMEL_IS_DISCO_STORE (store), CAMEL_DISCO_STORE_ONLINE);
+
+	if (store->status != CAMEL_DISCO_STORE_OFFLINE
+	    && !camel_session_is_online (service->session))
+		store->status = CAMEL_DISCO_STORE_OFFLINE;
+
+	return store->status;
+}
+
 /**
  * camel_disco_store_set_status:
  * @store: a disconnectable store
@@ -351,20 +328,17 @@ set_status(CamelDiscoStore *disco_store, CamelDiscoStoreStatus status, CamelExce
  **/
 void
 camel_disco_store_set_status (CamelDiscoStore *store,
-			      CamelDiscoStoreStatus status,
-			      CamelException *ex)
+                              CamelDiscoStoreStatus status,
+                              CamelException *ex)
 {
-	d(printf("disco store set status: %s\n", status == CAMEL_DISCO_STORE_ONLINE?"online":"offline"));
+	CamelDiscoStoreClass *class;
 
-	CDS_CLASS (store)->set_status (store, status, ex);
-}
+	g_return_if_fail (CAMEL_IS_DISCO_STORE (store));
 
-static gboolean
-can_work_offline (CamelDiscoStore *disco_store)
-{
-	g_warning ("CamelDiscoStore::can_work_offline not implemented for '%s'",
-		   camel_type_to_name (CAMEL_OBJECT_GET_TYPE (disco_store)));
-	return FALSE;
+	class = CAMEL_DISCO_STORE_GET_CLASS (store);
+	g_return_if_fail (class->set_status != NULL);
+
+	class->set_status (store, status, ex);
 }
 
 /**
@@ -377,7 +351,14 @@ can_work_offline (CamelDiscoStore *disco_store)
 gboolean
 camel_disco_store_can_work_offline (CamelDiscoStore *store)
 {
-	return CDS_CLASS (store)->can_work_offline (store);
+	CamelDiscoStoreClass *class;
+
+	g_return_val_if_fail (CAMEL_IS_DISCO_STORE (store), FALSE);
+
+	class = CAMEL_DISCO_STORE_GET_CLASS (store);
+	g_return_val_if_fail (class->can_work_offline != NULL, FALSE);
+
+	return class->can_work_offline (store);
 }
 
 /**
@@ -392,29 +373,36 @@ camel_disco_store_can_work_offline (CamelDiscoStore *store)
  * Returns: whether or not @store is online.
  **/
 gboolean
-camel_disco_store_check_online (CamelDiscoStore *store, CamelException *ex)
+camel_disco_store_check_online (CamelDiscoStore *store,
+                                CamelException *ex)
 {
-	if (camel_disco_store_status (store) != CAMEL_DISCO_STORE_ONLINE) {
-		camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
-				     _("You must be working online to "
-				       "complete this operation"));
-		return FALSE;
-	}
+	g_return_val_if_fail (CAMEL_IS_DISCO_STORE (store), FALSE);
+
+	if (camel_disco_store_status (store) == CAMEL_DISCO_STORE_ONLINE)
+		return TRUE;
+
+	camel_exception_set (
+		ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+		_("You must be working online to complete this operation"));
 
-	return TRUE;
+	return FALSE;
 }
 
 void
-camel_disco_store_prepare_for_offline(CamelDiscoStore *disco_store, CamelException *ex)
+camel_disco_store_prepare_for_offline (CamelDiscoStore *disco_store,
+                                       CamelException *ex)
 {
 	CamelException x;
-	CamelService *service = CAMEL_SERVICE (disco_store);
-	gboolean network_state = camel_session_get_network_state (service->session);
+	CamelService *service;
+
+	g_return_if_fail (CAMEL_IS_DISCO_STORE (disco_store));
+
+	service = CAMEL_SERVICE (disco_store);
 
 	camel_exception_init(&x);
 	/* Sync the folder fully if we've been told to sync online for this store or this folder */
 
-	if (network_state) {
+	if (camel_session_get_network_state (service->session)) {
 		if (disco_store->status == CAMEL_DISCO_STORE_ONLINE) {
 			if (((CamelStore *)disco_store)->folders) {
 				GPtrArray *folders;
diff --git a/camel/camel-disco-store.h b/camel/camel-disco-store.h
index d1bb131..8c5adff 100644
--- a/camel/camel-disco-store.h
+++ b/camel/camel-disco-store.h
@@ -36,6 +36,8 @@
 #define CAMEL_DISCO_STORE(obj)     (CAMEL_CHECK_CAST((obj), CAMEL_DISCO_STORE_TYPE, CamelDiscoStore))
 #define CAMEL_DISCO_STORE_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_DISCO_STORE_TYPE, CamelDiscoStoreClass))
 #define CAMEL_IS_DISCO_STORE(o)    (CAMEL_CHECK_TYPE((o), CAMEL_DISCO_STORE_TYPE))
+#define CAMEL_DISCO_STORE_GET_CLASS(obj) \
+	((CamelDiscoStoreClass *) CAMEL_OBJECT_GET_CLASS (obj))
 
 G_BEGIN_DECLS
 
diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c
index e91304b..5429a0f 100644
--- a/camel/camel-folder-summary.c
+++ b/camel/camel-folder-summary.c
@@ -4489,7 +4489,6 @@ camel_message_info_new (CamelFolderSummary *s)
 		CAMEL_SUMMARY_UNLOCK(s, alloc_lock);
 	} else {
 		info = g_slice_alloc0 (sizeof(CamelMessageInfoBase));
-
 	}
 
 	info->refcount = 1;
diff --git a/camel/camel-folder.c b/camel/camel-folder.c
index f1d592c..848787c 100644
--- a/camel/camel-folder.c
+++ b/camel/camel-folder.c
@@ -28,7 +28,6 @@
 
 #include <string.h>
 
-#include <glib.h>
 #include <glib/gi18n-lib.h>
 
 #include "camel-db.h"
@@ -50,151 +49,62 @@
 
 static CamelObjectClass *parent_class = NULL;
 
-static void camel_folder_finalize (CamelObject *object);
+/* Forward Declarations */
+static gboolean folder_changed (CamelObject *object, gpointer event_data);
 
-static void refresh_info (CamelFolder *folder, CamelException *ex);
-
-static void folder_sync (CamelFolder *folder, gboolean expunge,
-			 CamelException *ex);
-
-static const gchar *get_name (CamelFolder *folder);
-static const gchar *get_full_name (CamelFolder *folder);
-static CamelStore *get_parent_store   (CamelFolder *folder);
-
-static guint32 get_permanent_flags (CamelFolder *folder);
-static guint32 get_message_flags (CamelFolder *folder, const gchar *uid);
-static gboolean set_message_flags (CamelFolder *folder, const gchar *uid, guint32 flags, guint32 set);
-static gboolean get_message_user_flag (CamelFolder *folder, const gchar *uid, const gchar *name);
-static void set_message_user_flag (CamelFolder *folder, const gchar *uid, const gchar *name, gboolean value);
-static const gchar *get_message_user_tag (CamelFolder *folder, const gchar *uid, const gchar *name);
-static void set_message_user_tag (CamelFolder *folder, const gchar *uid, const gchar *name, const gchar *value);
-
-static gint get_message_count (CamelFolder *folder);
-
-static void expunge             (CamelFolder *folder,
-				 CamelException *ex);
-static gint folder_getv (CamelObject *object, CamelException *ex, CamelArgGetV *args);
-static void folder_free (CamelObject *o, guint32 tag, gpointer val);
-
-static void append_message (CamelFolder *folder, CamelMimeMessage *message,
-			    const CamelMessageInfo *info, gchar **appended_uid,
-			    CamelException *ex);
-
-static GPtrArray        *get_uids            (CamelFolder *folder);
-static GPtrArray	*get_uncached_uids   (CamelFolder *, GPtrArray * uids, CamelException *);
-static void              free_uids           (CamelFolder *folder,
-					      GPtrArray *array);
-static gint cmp_uids (CamelFolder *folder, const gchar *uid1, const gchar *uid2);
-static void              sort_uids           (CamelFolder *folder,
-					      GPtrArray *uids);
-static GPtrArray        *get_summary         (CamelFolder *folder);
-static void              free_summary        (CamelFolder *folder,
-					      GPtrArray *array);
-
-static CamelMimeMessage *get_message         (CamelFolder *folder, const gchar *uid, CamelException *ex);
-
-static CamelMessageInfo *get_message_info    (CamelFolder *folder, const gchar *uid);
-static void		 free_message_info   (CamelFolder *folder, CamelMessageInfo *info);
-static void		 ref_message_info    (CamelFolder *folder, CamelMessageInfo *info);
-
-static GPtrArray      *search_by_expression  (CamelFolder *folder, const gchar *exp, CamelException *ex);
-static guint32	       count_by_expression  (CamelFolder *folder, const gchar *exp, CamelException *ex);
-
-static GPtrArray      *search_by_uids	     (CamelFolder *folder, const gchar *exp, GPtrArray *uids, CamelException *ex);
-static void            search_free           (CamelFolder * folder, GPtrArray *result);
-
-static void            transfer_messages_to  (CamelFolder *source, GPtrArray *uids, CamelFolder *dest,
-					      GPtrArray **transferred_uids, gboolean delete_originals, CamelException *ex);
-
-static void            delete                (CamelFolder *folder);
-static void            folder_rename         (CamelFolder *folder, const gchar *new);
-
-static void            freeze                (CamelFolder *folder);
-static void            thaw                  (CamelFolder *folder);
-static gboolean        is_frozen             (CamelFolder *folder);
-
-static gboolean        folder_changed        (CamelObject *object,
-					      gpointer event_data);
+static gint
+cmp_array_uids (gconstpointer a,
+                gconstpointer b,
+                gpointer user_data)
+{
+	const gchar *uid1 = *(const gchar **) a;
+	const gchar *uid2 = *(const gchar **) b;
+	CamelFolder *folder = user_data;
 
-static gchar *           get_filename          (CamelFolder *folder,
-					      const gchar *uid,
-					      CamelException *ex);
+	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), 0);
 
-static CamelFolderQuotaInfo *get_quota_info  (CamelFolder *folder);
+	return camel_folder_cmp_uids (folder, uid1, uid2);
+}
 
 static void
-camel_folder_class_init (CamelFolderClass *camel_folder_class)
+folder_transfer_message_to (CamelFolder *source,
+                            const gchar *uid,
+                            CamelFolder *dest,
+                            gchar **transferred_uid,
+                            gboolean delete_original,
+                            CamelException *ex)
 {
-	CamelObjectClass *camel_object_class = CAMEL_OBJECT_CLASS (camel_folder_class);
+	CamelMimeMessage *msg;
+	CamelMessageInfo *minfo, *info;
 
-	parent_class = camel_type_get_global_classfuncs (camel_object_get_type ());
+	/* Default implementation. */
 
-	/* virtual method definition */
-	camel_folder_class->sync = folder_sync;
-	camel_folder_class->refresh_info = refresh_info;
-	camel_folder_class->get_name = get_name;
-	camel_folder_class->get_full_name = get_full_name;
-	camel_folder_class->get_parent_store = get_parent_store;
-	camel_folder_class->expunge = expunge;
-	camel_folder_class->get_message_count = get_message_count;
-	camel_folder_class->append_message = append_message;
-	camel_folder_class->get_permanent_flags = get_permanent_flags;
-	camel_folder_class->get_message_flags = get_message_flags;
-	camel_folder_class->set_message_flags = set_message_flags;
-	camel_folder_class->get_message_user_flag = get_message_user_flag;
-	camel_folder_class->set_message_user_flag = set_message_user_flag;
-	camel_folder_class->get_message_user_tag = get_message_user_tag;
-	camel_folder_class->set_message_user_tag = set_message_user_tag;
-	camel_folder_class->get_message = get_message;
-	camel_folder_class->get_uids = get_uids;
-	camel_folder_class->get_uncached_uids = get_uncached_uids;
-	camel_folder_class->free_uids = free_uids;
-	camel_folder_class->cmp_uids = cmp_uids;
-	camel_folder_class->sort_uids = sort_uids;
-	camel_folder_class->get_summary = get_summary;
-	camel_folder_class->free_summary = free_summary;
-	camel_folder_class->search_by_expression = search_by_expression;
-	camel_folder_class->count_by_expression = count_by_expression;
-	camel_folder_class->search_by_uids = search_by_uids;
-	camel_folder_class->search_free = search_free;
-	camel_folder_class->get_message_info = get_message_info;
-	camel_folder_class->ref_message_info = ref_message_info;
-	camel_folder_class->free_message_info = free_message_info;
-	camel_folder_class->transfer_messages_to = transfer_messages_to;
-	camel_folder_class->delete = delete;
-	camel_folder_class->rename = folder_rename;
-	camel_folder_class->freeze = freeze;
-	camel_folder_class->sync_message = NULL;
-	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;
-	camel_object_class->free = folder_free;
+	msg = camel_folder_get_message (source, uid, ex);
+	if (!msg)
+		return;
 
-	/* events */
-	camel_object_class_add_event (camel_object_class, "folder_changed", folder_changed);
-	camel_object_class_add_event (camel_object_class, "deleted", NULL);
-	camel_object_class_add_event (camel_object_class, "renamed", NULL);
-}
+	/* if its deleted we poke the flags, so we need to copy the messageinfo */
+	if ((source->folder_flags & CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY)
+			&& (minfo = camel_folder_get_message_info (source, uid))) {
+		info = camel_message_info_clone (minfo);
+		camel_folder_free_message_info (source, minfo);
+	} else
+		info = camel_message_info_new_from_header (NULL, ((CamelMimePart *)msg)->headers);
 
-static void
-camel_folder_init (gpointer object, gpointer klass)
-{
-	CamelFolder *folder = object;
+	/* we don't want to retain the deleted flag */
+	camel_message_info_set_flags (info, CAMEL_MESSAGE_DELETED, 0);
 
-	folder->priv = g_malloc0 (sizeof (*folder->priv));
-	folder->priv->frozen = 0;
-	folder->priv->changed_frozen = camel_folder_change_info_new ();
-	folder->priv->skip_folder_lock = FALSE;
-	g_static_rec_mutex_init (&folder->priv->lock);
-	g_static_mutex_init (&folder->priv->change_lock);
+	camel_folder_append_message (dest, msg, info, transferred_uid, ex);
+	camel_object_unref (msg);
+
+	if (delete_original && !camel_exception_is_set (ex))
+		camel_folder_set_message_flags (source, uid, CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN, ~0);
+
+	camel_message_info_free (info);
 }
 
 static void
-camel_folder_finalize (CamelObject *object)
+folder_finalize (CamelObject *object)
 {
 	CamelFolder *camel_folder = CAMEL_FOLDER (object);
 	struct _CamelFolderPrivate *p = camel_folder->priv;
@@ -219,138 +129,10 @@ camel_folder_finalize (CamelObject *object)
 	g_free (p);
 }
 
-/**
- * camel_folder_set_lock_async:
- * @folder: a #CamelFolder
- * @skip_folder_lock:
- *
- * FIXME Document me!
- *
- * Since: 2.30
- **/
-void
-camel_folder_set_lock_async (CamelFolder *folder, gboolean skip_folder_lock)
-{
-	folder->priv->skip_folder_lock = skip_folder_lock;
-}
-
-CamelType
-camel_folder_get_type (void)
-{
-	static CamelType camel_folder_type = CAMEL_INVALID_TYPE;
-
-	if (camel_folder_type == CAMEL_INVALID_TYPE)	{
-		camel_folder_type = camel_type_register (CAMEL_TYPE_OBJECT, "CamelFolder",
-							 sizeof (CamelFolder),
-							 sizeof (CamelFolderClass),
-							 (CamelObjectClassInitFunc) camel_folder_class_init,
-							 NULL,
-							 (CamelObjectInitFunc) camel_folder_init,
-							 (CamelObjectFinalizeFunc) camel_folder_finalize );
-	}
-
-	return camel_folder_type;
-}
-
-static gchar *
-get_filename (CamelFolder *folder, const gchar *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");
-}
-
-/**
- * camel_folder_get_filename:
- *
- * Since: 2.26
- **/
-gchar *
-camel_folder_get_filename (CamelFolder *folder, const gchar *uid, CamelException *ex)
-{
-	return CAMEL_FOLDER_GET_CLASS (folder)->get_filename (folder, uid, ex);
-}
-
-/**
- * camel_folder_construct:
- * @folder: a #CamelFolder object to construct
- * @parent_store: parent #CamelStore object of the folder
- * @full_name: full name of the folder
- * @name: short name of the folder
- *
- * Initalizes the folder by setting the parent store and name.
- **/
-void
-camel_folder_construct (CamelFolder *folder, CamelStore *parent_store,
-			const gchar *full_name, const gchar *name)
-{
-	g_return_if_fail (CAMEL_IS_FOLDER (folder));
-	g_return_if_fail (CAMEL_IS_STORE (parent_store));
-	g_return_if_fail (folder->parent_store == NULL);
-	g_return_if_fail (folder->name == NULL);
-
-	folder->parent_store = parent_store;
-	if (parent_store)
-		camel_object_ref (parent_store);
-
-	folder->name = g_strdup (name);
-	folder->full_name = g_strdup (full_name);
-}
-
-static void
-folder_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
-{
-	w (g_warning ("CamelFolder::sync not implemented for '%s'",
-		     camel_type_to_name (CAMEL_OBJECT_GET_TYPE (folder))));
-}
-
-/**
- * camel_folder_sync:
- * @folder: a #CamelFolder object
- * @expunge: whether or not to expunge deleted messages
- * @ex: a #CamelException
- *
- * Sync changes made to a folder to its backing store, possibly
- * expunging deleted messages as well.
- **/
-void
-camel_folder_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
-{
-	g_return_if_fail (CAMEL_IS_FOLDER (folder));
-
-	CAMEL_FOLDER_REC_LOCK (folder, lock);
-
-	if (!(folder->folder_flags & CAMEL_FOLDER_HAS_BEEN_DELETED))
-		CAMEL_FOLDER_GET_CLASS (folder)->sync (folder, expunge, ex);
-
-	CAMEL_FOLDER_REC_UNLOCK (folder, lock);
-}
-
-static void
-refresh_info (CamelFolder *folder, CamelException *ex)
-{
-	/* No op */
-}
-
-/**
- * camel_folder_refresh_info:
- * @folder: a #CamelFolder object
- * @ex: a #CamelException
- *
- * Updates a folder's summary to be in sync with its backing store.
- **/
-void
-camel_folder_refresh_info (CamelFolder *folder, CamelException *ex)
-{
-	g_return_if_fail (CAMEL_IS_FOLDER (folder));
-
-	CAMEL_FOLDER_REC_LOCK (folder, lock);
-	CAMEL_FOLDER_GET_CLASS (folder)->refresh_info (folder, ex);
-	CAMEL_FOLDER_REC_UNLOCK (folder, lock);
-}
-
 static gint
-folder_getv (CamelObject *object, CamelException *ex, CamelArgGetV *args)
+folder_getv (CamelObject *object,
+             CamelException *ex,
+             CamelArgGetV *args)
 {
 	CamelFolder *folder = (CamelFolder *)object;
 	gint i;
@@ -476,7 +258,7 @@ folder_getv (CamelObject *object, CamelException *ex, CamelArgGetV *args)
 			}
 			*arg->ca_ptr = array;*/
 			/* WTH this is reqd ?, let it crash to find out who uses this */
-			g_assert (0);
+			g_assert_not_reached ();
 			break; }
 		case CAMEL_FOLDER_ARG_INFO_ARRAY:
 			*arg->ca_ptr = camel_folder_summary_array (folder->summary);
@@ -495,9 +277,11 @@ folder_getv (CamelObject *object, CamelException *ex, CamelArgGetV *args)
 }
 
 static void
-folder_free (CamelObject *o, guint32 tag, gpointer val)
+folder_free (CamelObject *object,
+             guint32 tag,
+             gpointer val)
 {
-	CamelFolder *folder = (CamelFolder *)o;
+	CamelFolder *folder = (CamelFolder *)object;
 
 	switch (tag & CAMEL_ARG_TAG) {
 	case CAMEL_FOLDER_ARG_UID_ARRAY: {
@@ -515,19 +299,600 @@ folder_free (CamelObject *o, guint32 tag, gpointer val)
 		g_slist_free (val);
 		break;
 	default:
-		parent_class->free (o, tag, val);
+		parent_class->free (object, tag, val);
 	}
 }
 
+static void
+folder_refresh_info (CamelFolder *folder,
+                     CamelException *ex)
+{
+	/* No op */
+}
+
 static const gchar *
-get_name (CamelFolder *folder)
+folder_get_name (CamelFolder *folder)
 {
 	return folder->name;
 }
 
+static const gchar *
+folder_get_full_name (CamelFolder *folder)
+{
+	return folder->full_name;
+}
+
+static CamelStore *
+folder_get_parent_store (CamelFolder * folder)
+{
+	return folder->parent_store;
+}
+
+static gint
+folder_get_message_count (CamelFolder *folder)
+{
+	g_return_val_if_fail (folder->summary != NULL, -1);
+
+	return camel_folder_summary_count (folder->summary);
+}
+
+static guint32
+folder_get_permanent_flags (CamelFolder *folder)
+{
+	return folder->permanent_flags;
+}
+
+static guint32
+folder_get_message_flags (CamelFolder *folder,
+                          const gchar *uid)
+{
+	CamelMessageInfo *info;
+	guint32 flags;
+
+	g_return_val_if_fail (folder->summary != NULL, 0);
+
+	info = camel_folder_summary_uid (folder->summary, uid);
+	if (info == NULL)
+		return 0;
+
+	flags = camel_message_info_flags (info);
+	camel_message_info_free (info);
+
+	return flags;
+}
+
+static gboolean
+folder_set_message_flags (CamelFolder *folder,
+                          const gchar *uid,
+                          guint32 flags,
+                          guint32 set)
+{
+	CamelMessageInfo *info;
+	gint res;
+
+	g_return_val_if_fail (folder->summary != NULL, FALSE);
+
+	info = camel_folder_summary_uid (folder->summary, uid);
+	if (info == NULL)
+		return FALSE;
+
+	res = camel_message_info_set_flags (info, flags, set);
+	camel_message_info_free (info);
+
+	return res;
+}
+
+static gboolean
+folder_get_message_user_flag (CamelFolder *folder,
+                              const gchar *uid,
+                              const gchar *name)
+{
+	CamelMessageInfo *info;
+	gboolean ret;
+
+	g_return_val_if_fail (folder->summary != NULL, FALSE);
+
+	info = camel_folder_summary_uid (folder->summary, uid);
+	if (info == NULL)
+		return FALSE;
+
+	ret = camel_message_info_user_flag (info, name);
+	camel_message_info_free (info);
+
+	return ret;
+}
+
+static void
+folder_set_message_user_flag (CamelFolder *folder,
+                              const gchar *uid,
+                              const gchar *name,
+                              gboolean value)
+{
+	CamelMessageInfo *info;
+
+	g_return_if_fail (folder->summary != NULL);
+
+	info = camel_folder_summary_uid (folder->summary, uid);
+	if (info == NULL)
+		return;
+
+	camel_message_info_set_user_flag (info, name, value);
+	camel_message_info_free (info);
+}
+
+static const gchar *
+folder_get_message_user_tag (CamelFolder *folder,
+                             const gchar *uid,
+                             const gchar *name)
+{
+	CamelMessageInfo *info;
+	const gchar *ret;
+
+	g_return_val_if_fail (folder->summary != NULL, NULL);
+
+	info = camel_folder_summary_uid (folder->summary, uid);
+	if (info == NULL)
+		return NULL;
+
+	ret = camel_message_info_user_tag (info, name);
+	camel_message_info_free (info);
+
+	return ret;
+}
+
+static void
+folder_set_message_user_tag (CamelFolder *folder,
+                             const gchar *uid,
+                             const gchar *name,
+                             const gchar *value)
+{
+	CamelMessageInfo *info;
+
+	g_return_if_fail (folder->summary != NULL);
+
+	info = camel_folder_summary_uid (folder->summary, uid);
+	if (info == NULL)
+		return;
+
+	camel_message_info_set_user_tag (info, name, value);
+	camel_message_info_free (info);
+}
+
+static GPtrArray *
+folder_get_uids (CamelFolder *folder)
+{
+	g_return_val_if_fail (folder->summary != NULL, NULL);
+
+	return camel_folder_summary_array (folder->summary);
+}
+
+static GPtrArray *
+folder_get_uncached_uids (CamelFolder *folder,
+                          GPtrArray * uids,
+                          CamelException *ex)
+{
+	GPtrArray *result;
+	gint i;
+
+	result = g_ptr_array_new ();
+
+	g_ptr_array_set_size (result, uids->len);
+	for (i = 0; i < uids->len; i++)
+		result->pdata[i] =
+			(gpointer) camel_pstring_strdup (uids->pdata[i]);
+
+	return result;
+}
+
+static void
+folder_free_uids (CamelFolder *folder,
+                  GPtrArray *array)
+{
+	gint i;
+
+	for (i=0; i<array->len; i++)
+		camel_pstring_free (array->pdata[i]);
+	g_ptr_array_free (array, TRUE);
+}
+
+static gint
+folder_cmp_uids (CamelFolder *folder,
+                 const gchar *uid1,
+                 const gchar *uid2)
+{
+	g_return_val_if_fail (uid1 != NULL, 0);
+	g_return_val_if_fail (uid2 != NULL, 0);
+
+	return strtoul (uid1, NULL, 10) - strtoul (uid2, NULL, 10);
+}
+
+static void
+folder_sort_uids (CamelFolder *folder,
+                  GPtrArray *uids)
+{
+	g_qsort_with_data (
+		uids->pdata, uids->len,
+		sizeof (gpointer), cmp_array_uids, folder);
+}
+
+static GPtrArray *
+folder_get_summary (CamelFolder *folder)
+{
+	g_return_val_if_fail (folder->summary != NULL, NULL);
+
+	return camel_folder_summary_array (folder->summary);
+}
+
+static void
+folder_free_summary (CamelFolder *folder,
+                     GPtrArray *summary)
+{
+	g_ptr_array_foreach (summary, (GFunc) camel_pstring_free, NULL);
+	g_ptr_array_free (summary, TRUE);
+}
+
+static void
+folder_search_free (CamelFolder *folder,
+                    GPtrArray *result)
+{
+	gint i;
+
+	for (i = 0; i < result->len; i++)
+		camel_pstring_free (g_ptr_array_index (result, i));
+	g_ptr_array_free (result, TRUE);
+}
+
+static CamelMessageInfo *
+folder_get_message_info (CamelFolder *folder,
+                         const gchar *uid)
+{
+	g_return_val_if_fail (folder->summary != NULL, NULL);
+
+	return camel_folder_summary_uid (folder->summary, uid);
+}
+
+static void
+folder_ref_message_info (CamelFolder *folder,
+                         CamelMessageInfo *info)
+{
+	g_return_if_fail (folder->summary != NULL);
+
+	camel_message_info_ref (info);
+}
+
+static void
+folder_free_message_info (CamelFolder *folder,
+                          CamelMessageInfo *info)
+{
+	g_return_if_fail (folder->summary != NULL);
+
+	camel_message_info_free (info);
+}
+
+static void
+folder_transfer_messages_to (CamelFolder *source,
+                             GPtrArray *uids,
+                             CamelFolder *dest,
+                             GPtrArray **transferred_uids,
+                             gboolean delete_originals,
+                             CamelException *ex)
+{
+	CamelException local;
+	gchar **ret_uid = NULL;
+	gint i;
+
+	if (transferred_uids) {
+		*transferred_uids = g_ptr_array_new ();
+		g_ptr_array_set_size (*transferred_uids, uids->len);
+	}
+
+	camel_exception_init (&local);
+	if (ex == NULL)
+		ex = &local;
+
+	if (delete_originals)
+		camel_operation_start (NULL, _("Moving messages"));
+	else
+		camel_operation_start (NULL, _("Copying messages"));
+
+	if (uids->len > 1) {
+		camel_folder_freeze (dest);
+		if (delete_originals)
+			camel_folder_freeze (source);
+	}
+	for (i = 0; i < uids->len && !camel_exception_is_set (ex); i++) {
+		if (transferred_uids)
+			ret_uid = (gchar **)&((*transferred_uids)->pdata[i]);
+		folder_transfer_message_to (
+			source, uids->pdata[i], dest,
+			ret_uid, delete_originals, ex);
+		camel_operation_progress (NULL, i * 100 / uids->len);
+	}
+	if (uids->len > 1) {
+		camel_folder_thaw (dest);
+		if (delete_originals)
+			camel_folder_thaw (source);
+	}
+
+	camel_operation_end (NULL);
+	camel_exception_clear (&local);
+}
+
+static void
+folder_delete (CamelFolder *folder)
+{
+	if (folder->summary)
+		camel_folder_summary_clear (folder->summary);
+}
+
+static void
+folder_rename (CamelFolder *folder,
+               const gchar *new)
+{
+	gchar *tmp;
+
+	d (printf ("CamelFolder:rename ('%s')\n", new));
+
+	g_free (folder->full_name);
+	folder->full_name = g_strdup (new);
+	g_free (folder->name);
+	tmp = strrchr (new, '/');
+	folder->name = g_strdup (tmp?tmp+1:new);
+}
+
+static void
+folder_freeze (CamelFolder *folder)
+{
+	g_return_if_fail (folder->priv->frozen >= 0);
+
+	CAMEL_FOLDER_LOCK (folder, change_lock);
+
+	folder->priv->frozen++;
+
+	d (printf ("freeze (%p '%s') = %d\n", folder, folder->full_name, folder->priv->frozen));
+	CAMEL_FOLDER_UNLOCK (folder, change_lock);
+}
+
+static void
+folder_thaw (CamelFolder * folder)
+{
+	CamelFolderChangeInfo *info = NULL;
+
+	g_return_if_fail (folder->priv->frozen > 0);
+
+	CAMEL_FOLDER_LOCK (folder, change_lock);
+
+	folder->priv->frozen--;
+
+	d (printf ("thaw (%p '%s') = %d\n", folder, folder->full_name, folder->priv->frozen));
+
+	if (folder->priv->frozen == 0
+	    && camel_folder_change_info_changed (folder->priv->changed_frozen)) {
+		info = folder->priv->changed_frozen;
+		folder->priv->changed_frozen = camel_folder_change_info_new ();
+	}
+
+	CAMEL_FOLDER_UNLOCK (folder, change_lock);
+
+	if (info) {
+		camel_object_trigger_event (folder, "folder_changed", info);
+		camel_folder_change_info_free (info);
+	}
+}
+
+static gboolean
+folder_is_frozen (CamelFolder *folder)
+{
+	return folder->priv->frozen != 0;
+}
+
+static CamelFolderQuotaInfo *
+folder_get_quota_info (CamelFolder *folder)
+{
+	return NULL;
+}
+
+static void
+camel_folder_class_init (CamelFolderClass *class)
+{
+	CamelObjectClass *camel_object_class;
+
+	parent_class = camel_type_get_global_classfuncs (camel_object_get_type ());
+
+	camel_object_class = CAMEL_OBJECT_CLASS (class);
+	camel_object_class->getv = folder_getv;
+	camel_object_class->free = folder_free;
+
+	class->refresh_info = folder_refresh_info;
+	class->get_name = folder_get_name;
+	class->get_full_name = folder_get_full_name;
+	class->get_parent_store = folder_get_parent_store;
+	class->get_message_count = folder_get_message_count;
+	class->get_permanent_flags = folder_get_permanent_flags;
+	class->get_message_flags = folder_get_message_flags;
+	class->set_message_flags = folder_set_message_flags;
+	class->get_message_user_flag = folder_get_message_user_flag;
+	class->set_message_user_flag = folder_set_message_user_flag;
+	class->get_message_user_tag = folder_get_message_user_tag;
+	class->set_message_user_tag = folder_set_message_user_tag;
+	class->get_uids = folder_get_uids;
+	class->get_uncached_uids = folder_get_uncached_uids;
+	class->free_uids = folder_free_uids;
+	class->cmp_uids = folder_cmp_uids;
+	class->sort_uids = folder_sort_uids;
+	class->get_summary = folder_get_summary;
+	class->free_summary = folder_free_summary;
+	class->search_free = folder_search_free;
+	class->get_message_info = folder_get_message_info;
+	class->ref_message_info = folder_ref_message_info;
+	class->free_message_info = folder_free_message_info;
+	class->transfer_messages_to = folder_transfer_messages_to;
+	class->delete = folder_delete;
+	class->rename = folder_rename;
+	class->freeze = folder_freeze;
+	class->thaw = folder_thaw;
+	class->is_frozen = folder_is_frozen;
+	class->get_quota_info = folder_get_quota_info;
+
+	camel_object_class_add_event (
+		camel_object_class, "folder_changed", folder_changed);
+	camel_object_class_add_event (
+		camel_object_class, "deleted", NULL);
+	camel_object_class_add_event (
+		camel_object_class, "renamed", NULL);
+}
+
+static void
+camel_folder_init (CamelFolder *folder)
+{
+	folder->priv = g_malloc0 (sizeof (*folder->priv));
+	folder->priv->frozen = 0;
+	folder->priv->changed_frozen = camel_folder_change_info_new ();
+
+	g_static_rec_mutex_init (&folder->priv->lock);
+	g_static_mutex_init (&folder->priv->change_lock);
+}
+
+CamelType
+camel_folder_get_type (void)
+{
+	static CamelType camel_folder_type = CAMEL_INVALID_TYPE;
+
+	if (camel_folder_type == CAMEL_INVALID_TYPE)	{
+		camel_folder_type = camel_type_register (CAMEL_TYPE_OBJECT, "CamelFolder",
+							 sizeof (CamelFolder),
+							 sizeof (CamelFolderClass),
+							 (CamelObjectClassInitFunc) camel_folder_class_init,
+							 NULL,
+							 (CamelObjectInitFunc) camel_folder_init,
+							 (CamelObjectFinalizeFunc) folder_finalize );
+	}
+
+	return camel_folder_type;
+}
+
+/**
+ * camel_folder_set_lock_async:
+ * @folder: a #CamelFolder
+ * @skip_folder_lock:
+ *
+ * FIXME Document me!
+ *
+ * Since: 2.30
+ **/
+void
+camel_folder_set_lock_async (CamelFolder *folder,
+                             gboolean skip_folder_lock)
+{
+	g_return_if_fail (CAMEL_IS_FOLDER (folder));
+
+	folder->priv->skip_folder_lock = skip_folder_lock;
+}
+
+/**
+ * camel_folder_get_filename:
+ *
+ * Since: 2.26
+ **/
+gchar *
+camel_folder_get_filename (CamelFolder *folder,
+                           const gchar *uid,
+                           CamelException *ex)
+{
+	CamelFolderClass *class;
+
+	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL);
+	g_return_val_if_fail (uid != NULL, NULL);
+
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_val_if_fail (class->get_filename != NULL, NULL);
+
+	return class->get_filename (folder, uid, ex);
+}
+
+/**
+ * camel_folder_construct:
+ * @folder: a #CamelFolder to construct
+ * @parent_store: parent #CamelStore object of the folder
+ * @full_name: full name of the folder
+ * @name: short name of the folder
+ *
+ * Initalizes the folder by setting the parent store and name.
+ **/
+void
+camel_folder_construct (CamelFolder *folder,
+                        CamelStore *parent_store,
+                        const gchar *full_name,
+                        const gchar *name)
+{
+	g_return_if_fail (CAMEL_IS_FOLDER (folder));
+	g_return_if_fail (CAMEL_IS_STORE (parent_store));
+	g_return_if_fail (folder->parent_store == NULL);
+	g_return_if_fail (folder->name == NULL);
+
+	folder->parent_store = parent_store;
+	if (parent_store)
+		camel_object_ref (parent_store);
+
+	folder->name = g_strdup (name);
+	folder->full_name = g_strdup (full_name);
+}
+
+/**
+ * camel_folder_sync:
+ * @folder: a #CamelFolder
+ * @expunge: whether or not to expunge deleted messages
+ * @ex: a #CamelException
+ *
+ * Sync changes made to a folder to its backing store, possibly
+ * expunging deleted messages as well.
+ **/
+void
+camel_folder_sync (CamelFolder *folder,
+                   gboolean expunge,
+                   CamelException *ex)
+{
+	CamelFolderClass *class;
+
+	g_return_if_fail (CAMEL_IS_FOLDER (folder));
+
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_if_fail (class->sync != NULL);
+
+	CAMEL_FOLDER_REC_LOCK (folder, lock);
+
+	if (!(folder->folder_flags & CAMEL_FOLDER_HAS_BEEN_DELETED))
+		class->sync (folder, expunge, ex);
+
+	CAMEL_FOLDER_REC_UNLOCK (folder, lock);
+}
+
+/**
+ * camel_folder_refresh_info:
+ * @folder: a #CamelFolder
+ * @ex: a #CamelException
+ *
+ * Updates a folder's summary to be in sync with its backing store.
+ **/
+void
+camel_folder_refresh_info (CamelFolder *folder,
+                           CamelException *ex)
+{
+	CamelFolderClass *class;
+
+	g_return_if_fail (CAMEL_IS_FOLDER (folder));
+
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_if_fail (class->refresh_info != NULL);
+
+	CAMEL_FOLDER_REC_LOCK (folder, lock);
+	class->refresh_info (folder, ex);
+	CAMEL_FOLDER_REC_UNLOCK (folder, lock);
+}
+
 /**
  * camel_folder_get_name:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  *
  * Get the (short) name of the folder. The fully qualified name
  * can be obtained with the #camel_folder_get_full_name method.
@@ -537,20 +902,19 @@ get_name (CamelFolder *folder)
 const gchar *
 camel_folder_get_name (CamelFolder *folder)
 {
+	CamelFolderClass *class;
+
 	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL);
 
-	return CAMEL_FOLDER_GET_CLASS (folder)->get_name (folder);
-}
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_val_if_fail (class->get_name != NULL, NULL);
 
-static const gchar *
-get_full_name (CamelFolder *folder)
-{
-	return folder->full_name;
+	return class->get_name (folder);
 }
 
 /**
  * camel_folder_get_full_name:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  *
  * Get the full name of the folder.
  *
@@ -559,87 +923,83 @@ get_full_name (CamelFolder *folder)
 const gchar *
 camel_folder_get_full_name (CamelFolder *folder)
 {
+	CamelFolderClass *class;
+
 	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL);
 
-	return CAMEL_FOLDER_GET_CLASS (folder)->get_full_name (folder);
-}
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_val_if_fail (class->get_full_name != NULL, NULL);
 
-static CamelStore *
-get_parent_store (CamelFolder * folder)
-{
-	return folder->parent_store;
+	return class->get_full_name (folder);
 }
 
 /**
  * camel_folder_get_parent_store:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  *
  * Returns: the parent #CamelStore of the folder
  **/
 CamelStore *
 camel_folder_get_parent_store (CamelFolder *folder)
 {
+	CamelFolderClass *class;
+
 	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL);
 
-	return CAMEL_FOLDER_GET_CLASS (folder)->get_parent_store (folder);
-}
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_val_if_fail (class->get_parent_store != NULL, NULL);
 
-static void
-expunge (CamelFolder *folder, CamelException *ex)
-{
-	w (g_warning ("CamelFolder::expunge not implemented for '%s'",
-		     camel_type_to_name (CAMEL_OBJECT_GET_TYPE (folder))));
+	return class->get_parent_store (folder);
 }
 
 /**
  * camel_folder_expunge:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  * @ex: a #CamelException
  *
  * Delete messages which have been marked as "DELETED"
  **/
 void
-camel_folder_expunge (CamelFolder *folder, CamelException *ex)
+camel_folder_expunge (CamelFolder *folder,
+                      CamelException *ex)
 {
+	CamelFolderClass *class;
+
 	g_return_if_fail (CAMEL_IS_FOLDER (folder));
 
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_if_fail (class->expunge != NULL);
+
 	CAMEL_FOLDER_REC_LOCK (folder, lock);
 
 	if (!(folder->folder_flags & CAMEL_FOLDER_HAS_BEEN_DELETED))
-		CAMEL_FOLDER_GET_CLASS (folder)->expunge (folder, ex);
+		class->expunge (folder, ex);
 
 	CAMEL_FOLDER_REC_UNLOCK (folder, lock);
 }
 
-static gint
-get_message_count (CamelFolder *folder)
-{
-	g_return_val_if_fail (folder->summary != NULL, -1);
-
-	return camel_folder_summary_count (folder->summary);
-}
-
 /**
  * camel_folder_get_message_count:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  *
  * Returns: the number of messages in the folder, or %-1 if unknown
  **/
 gint
 camel_folder_get_message_count (CamelFolder *folder)
 {
-	gint ret;
+	CamelFolderClass *class;
 
 	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), -1);
 
-	ret = CAMEL_FOLDER_GET_CLASS (folder)->get_message_count (folder);
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_val_if_fail (class->get_message_count != NULL, -1);
 
-	return ret;
+	return class->get_message_count (folder);
 }
 
 /**
  * camel_folder_get_unread_message_count:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  *
  * DEPRECATED: use #camel_object_get instead.
  *
@@ -660,7 +1020,7 @@ camel_folder_get_unread_message_count (CamelFolder *folder)
 
 /**
  * camel_folder_get_deleted_message_count:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  *
  * Returns: the number of deleted messages in the folder, or %-1 if
  * unknown
@@ -677,25 +1037,9 @@ camel_folder_get_deleted_message_count (CamelFolder *folder)
 	return count;
 }
 
-static void
-append_message (CamelFolder *folder, CamelMimeMessage *message,
-		const CamelMessageInfo *info, gchar **appended_uid,
-		CamelException *ex)
-{
-	camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID,
-			      _("Unsupported operation: append message: for %s"),
-			      camel_type_to_name (CAMEL_OBJECT_GET_TYPE (folder)));
-
-	w (g_warning ("CamelFolder::append_message not implemented for '%s'",
-		     camel_type_to_name (CAMEL_OBJECT_GET_TYPE (folder))));
-
-	return;
-
-}
-
 /**
  * camel_folder_append_message:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  * @message: a #CamelMimeMessage object
  * @info: a #CamelMessageInfo with additional flags/etc to set on
  * new message, or %NULL
@@ -707,26 +1051,29 @@ append_message (CamelFolder *folder, CamelMimeMessage *message,
  * are used. If @info is %NULL, no flags or tags will be set.
  **/
 void
-camel_folder_append_message (CamelFolder *folder, CamelMimeMessage *message,
-			     const CamelMessageInfo *info, gchar **appended_uid,
-			     CamelException *ex)
+camel_folder_append_message (CamelFolder *folder,
+                             CamelMimeMessage *message,
+                             const CamelMessageInfo *info,
+                             gchar **appended_uid,
+                             CamelException *ex)
 {
+	CamelFolderClass *class;
+
 	g_return_if_fail (CAMEL_IS_FOLDER (folder));
+	g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message));
+	g_return_if_fail (info != NULL);
+
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_if_fail (class->append_message != NULL);
 
 	CAMEL_FOLDER_REC_LOCK (folder, lock);
-	CAMEL_FOLDER_GET_CLASS (folder)->append_message (folder, message, info, appended_uid, ex);
+	class->append_message (folder, message, info, appended_uid, ex);
 	CAMEL_FOLDER_REC_UNLOCK (folder, lock);
 }
 
-static guint32
-get_permanent_flags (CamelFolder *folder)
-{
-	return folder->permanent_flags;
-}
-
 /**
  * camel_folder_get_permanent_flags:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  *
  * Returns: the set of #CamelMessageFlags that can be permanently
  * stored on a message between sessions. If it includes
@@ -735,32 +1082,19 @@ get_permanent_flags (CamelFolder *folder)
 guint32
 camel_folder_get_permanent_flags (CamelFolder *folder)
 {
-	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), 0);
+	CamelFolderClass *class;
 
-	return CAMEL_FOLDER_GET_CLASS (folder)->get_permanent_flags (folder);
-}
-
-static guint32
-get_message_flags (CamelFolder *folder, const gchar *uid)
-{
-	CamelMessageInfo *info;
-	guint32 flags;
-
-	g_return_val_if_fail (folder->summary != NULL, 0);
-
-	info = camel_folder_summary_uid (folder->summary, uid);
-	if (info == NULL)
-		return 0;
+	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), 0);
 
-	flags = camel_message_info_flags (info);
-	camel_message_info_free (info);
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_val_if_fail (class->get_permanent_flags != NULL, 0);
 
-	return flags;
+	return class->get_permanent_flags (folder);
 }
 
 /**
  * camel_folder_get_message_flags:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  * @uid: the UID of a message in @folder
  *
  * Deprecated: Use #camel_folder_get_message_info instead.
@@ -769,38 +1103,23 @@ get_message_flags (CamelFolder *folder, const gchar *uid)
  * message.
  **/
 guint32
-camel_folder_get_message_flags (CamelFolder *folder, const gchar *uid)
+camel_folder_get_message_flags (CamelFolder *folder,
+                                const gchar *uid)
 {
-	guint32 ret;
+	CamelFolderClass *class;
 
 	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), 0);
+	g_return_val_if_fail (uid != NULL, 0);
 
-	ret = CAMEL_FOLDER_GET_CLASS (folder)->get_message_flags (folder, uid);
-
-	return ret;
-}
-
-static gboolean
-set_message_flags (CamelFolder *folder, const gchar *uid, guint32 flags, guint32 set)
-{
-	CamelMessageInfo *info;
-	gint res;
-
-	g_return_val_if_fail (folder->summary != NULL, FALSE);
-
-	info = camel_folder_summary_uid (folder->summary, uid);
-	if (info == NULL)
-		return FALSE;
-
-	res = camel_message_info_set_flags (info, flags, set);
-	camel_message_info_free (info);
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_val_if_fail (class->get_message_flags != NULL, 0);
 
-	return res;
+	return class->get_message_flags (folder, uid);
 }
 
 /**
  * camel_folder_set_message_flags:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  * @uid: the UID of a message in @folder
  * @flags: a set of #CamelMessageFlag values to set
  * @set: the mask of values in @flags to use.
@@ -818,39 +1137,30 @@ set_message_flags (CamelFolder *folder, const gchar *uid, guint32 flags, guint32
  * Returns: %TRUE if the flags were changed or %FALSE otherwise
  **/
 gboolean
-camel_folder_set_message_flags (CamelFolder *folder, const gchar *uid, guint32 flags, guint32 set)
+camel_folder_set_message_flags (CamelFolder *folder,
+                                const gchar *uid,
+                                guint32 flags,
+                                guint32 set)
 {
+	CamelFolderClass *class;
+
 	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
+	g_return_val_if_fail (uid != NULL, FALSE);
+
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_val_if_fail (class->set_message_flags != NULL, FALSE);
 
 	if ((flags & (CAMEL_MESSAGE_JUNK|CAMEL_MESSAGE_JUNK_LEARN)) == CAMEL_MESSAGE_JUNK) {
 		flags |= CAMEL_MESSAGE_JUNK_LEARN;
 		set &= ~CAMEL_MESSAGE_JUNK_LEARN;
 	}
 
-	return CAMEL_FOLDER_GET_CLASS (folder)->set_message_flags (folder, uid, flags, set);
-}
-
-static gboolean
-get_message_user_flag (CamelFolder *folder, const gchar *uid, const gchar *name)
-{
-	CamelMessageInfo *info;
-	gboolean ret;
-
-	g_return_val_if_fail (folder->summary != NULL, FALSE);
-
-	info = camel_folder_summary_uid (folder->summary, uid);
-	if (info == NULL)
-		return FALSE;
-
-	ret = camel_message_info_user_flag (info, name);
-	camel_message_info_free (info);
-
-	return ret;
+	return class->set_message_flags (folder, uid, flags, set);
 }
 
 /**
  * camel_folder_get_message_user_flag:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  * @uid: the UID of a message in @folder
  * @name: the name of a user flag
  *
@@ -861,36 +1171,25 @@ get_message_user_flag (CamelFolder *folder, const gchar *uid, const gchar *name)
  * %FALSE otherwise
  **/
 gboolean
-camel_folder_get_message_user_flag (CamelFolder *folder, const gchar *uid,
-				    const gchar *name)
+camel_folder_get_message_user_flag (CamelFolder *folder,
+                                    const gchar *uid,
+                                    const gchar *name)
 {
-	gboolean ret;
+	CamelFolderClass *class;
 
 	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), 0);
+	g_return_val_if_fail (uid != NULL, 0);
+	g_return_val_if_fail (name != NULL, 0);
 
-	ret = CAMEL_FOLDER_GET_CLASS (folder)->get_message_user_flag (folder, uid, name);
-
-	return ret;
-}
-
-static void
-set_message_user_flag (CamelFolder *folder, const gchar *uid, const gchar *name, gboolean value)
-{
-	CamelMessageInfo *info;
-
-	g_return_if_fail (folder->summary != NULL);
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_val_if_fail (class->get_message_user_flag != NULL, 0);
 
-	info = camel_folder_summary_uid (folder->summary, uid);
-	if (info == NULL)
-		return;
-
-	camel_message_info_set_user_flag (info, name, value);
-	camel_message_info_free (info);
+	return class->get_message_user_flag (folder, uid, name);
 }
 
 /**
  * camel_folder_set_message_user_flag:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  * @uid: the UID of a message in @folder
  * @name: the name of the user flag to set
  * @value: the value to set it to
@@ -903,35 +1202,26 @@ set_message_user_flag (CamelFolder *folder, const gchar *uid, const gchar *name,
  * folder or store is closed. See #camel_folder_get_permanent_flags)
  **/
 void
-camel_folder_set_message_user_flag (CamelFolder *folder, const gchar *uid,
-				    const gchar *name, gboolean value)
-{
-	g_return_if_fail (CAMEL_IS_FOLDER (folder));
-
-	CAMEL_FOLDER_GET_CLASS (folder)->set_message_user_flag (folder, uid, name, value);
-}
-
-static const gchar *
-get_message_user_tag (CamelFolder *folder, const gchar *uid, const gchar *name)
+camel_folder_set_message_user_flag (CamelFolder *folder,
+                                    const gchar *uid,
+                                    const gchar *name,
+                                    gboolean value)
 {
-	CamelMessageInfo *info;
-	const gchar *ret;
-
-	g_return_val_if_fail (folder->summary != NULL, NULL);
+	CamelFolderClass *class;
 
-	info = camel_folder_summary_uid (folder->summary, uid);
-	if (info == NULL)
-		return NULL;
+	g_return_if_fail (CAMEL_IS_FOLDER (folder));
+	g_return_if_fail (uid != NULL);
+	g_return_if_fail (name != NULL);
 
-	ret = camel_message_info_user_tag (info, name);
-	camel_message_info_free (info);
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_if_fail (class->set_message_user_flag != NULL);
 
-	return ret;
+	class->set_message_user_flag (folder, uid, name, value);
 }
 
 /**
  * camel_folder_get_message_user_tag:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  * @uid: the UID of a message in @folder
  * @name: the name of a user tag
  *
@@ -941,36 +1231,26 @@ get_message_user_tag (CamelFolder *folder, const gchar *uid, const gchar *name)
  * Returns: the value of the user tag
  **/
 const gchar *
-camel_folder_get_message_user_tag (CamelFolder *folder, const gchar *uid,  const gchar *name)
+camel_folder_get_message_user_tag (CamelFolder *folder,
+                                   const gchar *uid,
+                                   const gchar *name)
 {
-	const gchar *ret;
+	CamelFolderClass *class;
 
 	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL);
+	g_return_val_if_fail (uid != NULL, NULL);
+	g_return_val_if_fail (name != NULL, NULL);
 
-	/* FIXME: should duplicate string */
-	ret = CAMEL_FOLDER_GET_CLASS (folder)->get_message_user_tag (folder, uid, name);
-
-	return ret;
-}
-
-static void
-set_message_user_tag (CamelFolder *folder, const gchar *uid, const gchar *name, const gchar *value)
-{
-	CamelMessageInfo *info;
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_val_if_fail (class->get_message_user_tag != NULL, NULL);
 
-	g_return_if_fail (folder->summary != NULL);
-
-	info = camel_folder_summary_uid (folder->summary, uid);
-	if (info == NULL)
-		return;
-
-	camel_message_info_set_user_tag (info, name, value);
-	camel_message_info_free (info);
+	/* FIXME: should duplicate string */
+	return class->get_message_user_tag (folder, uid, name);
 }
 
 /**
  * camel_folder_set_message_user_tag:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  * @uid: the UID of a message in @folder
  * @name: the name of the user tag to set
  * @value: the value to set it to
@@ -983,24 +1263,26 @@ set_message_user_tag (CamelFolder *folder, const gchar *uid, const gchar *name,
  * folder or store is closed. See #camel_folder_get_permanent_flags)
  **/
 void
-camel_folder_set_message_user_tag (CamelFolder *folder, const gchar *uid, const gchar *name, const gchar *value)
+camel_folder_set_message_user_tag (CamelFolder *folder,
+                                   const gchar *uid,
+                                   const gchar *name,
+                                   const gchar *value)
 {
-	g_return_if_fail (CAMEL_IS_FOLDER (folder));
+	CamelFolderClass *class;
 
-	CAMEL_FOLDER_GET_CLASS (folder)->set_message_user_tag (folder, uid, name, value);
-}
+	g_return_if_fail (CAMEL_IS_FOLDER (folder));
+	g_return_if_fail (uid != NULL);
+	g_return_if_fail (name != NULL);
 
-static CamelMessageInfo *
-get_message_info (CamelFolder *folder, const gchar *uid)
-{
-	g_return_val_if_fail (folder->summary != NULL, NULL);
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_if_fail (class->set_message_user_tag != NULL);
 
-	return camel_folder_summary_uid (folder->summary, uid);
+	class->set_message_user_tag (folder, uid, name, value);
 }
 
 /**
  * camel_folder_get_message_info:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  * @uid: the uid of a message
  *
  * Retrieve the #CamelMessageInfo for the specified @uid.  This return
@@ -1010,54 +1292,46 @@ get_message_info (CamelFolder *folder, const gchar *uid)
  * if the uid does not exist
  **/
 CamelMessageInfo *
-camel_folder_get_message_info (CamelFolder *folder, const gchar *uid)
+camel_folder_get_message_info (CamelFolder *folder,
+                               const gchar *uid)
 {
-	CamelMessageInfo *ret;
+	CamelFolderClass *class;
 
 	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL);
 	g_return_val_if_fail (uid != NULL, NULL);
 
-	ret = CAMEL_FOLDER_GET_CLASS (folder)->get_message_info (folder, uid);
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_val_if_fail (class->get_message_info != NULL, NULL);
 
-	return ret;
-}
-
-static void
-free_message_info (CamelFolder *folder, CamelMessageInfo *info)
-{
-	g_return_if_fail (folder->summary != NULL);
-
-	camel_message_info_free (info);
+	return class->get_message_info (folder, uid);
 }
 
 /**
  * camel_folder_free_message_info:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  * @info: a #CamelMessageInfo
  *
  * Free (unref) a #CamelMessageInfo, previously obtained with
  * #camel_folder_get_message_info.
  **/
 void
-camel_folder_free_message_info (CamelFolder *folder, CamelMessageInfo *info)
+camel_folder_free_message_info (CamelFolder *folder,
+                                CamelMessageInfo *info)
 {
+	CamelFolderClass *class;
+
 	g_return_if_fail (CAMEL_IS_FOLDER (folder));
 	g_return_if_fail (info != NULL);
 
-	CAMEL_FOLDER_GET_CLASS (folder)->free_message_info (folder, info);
-}
-
-static void
-ref_message_info (CamelFolder *folder, CamelMessageInfo *info)
-{
-	g_return_if_fail (folder->summary != NULL);
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_if_fail (class->free_message_info != NULL);
 
-	camel_message_info_ref (info);
+	class->free_message_info (folder, info);
 }
 
 /**
  * camel_folder_ref_message_info:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  * @info: a #CamelMessageInfo
  *
  * DEPRECATED: Use #camel_message_info_ref directly.
@@ -1066,18 +1340,24 @@ ref_message_info (CamelFolder *folder, CamelMessageInfo *info)
  * #camel_folder_get_message_info.
  **/
 void
-camel_folder_ref_message_info (CamelFolder *folder, CamelMessageInfo *info)
+camel_folder_ref_message_info (CamelFolder *folder,
+                               CamelMessageInfo *info)
 {
+	CamelFolderClass *class;
+
 	g_return_if_fail (CAMEL_IS_FOLDER (folder));
 	g_return_if_fail (info != NULL);
 
-	CAMEL_FOLDER_GET_CLASS (folder)->ref_message_info (folder, info);
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_if_fail (class->ref_message_info != NULL);
+
+	class->ref_message_info (folder, info);
 }
 
 /* TODO: is this function required anyway? */
 /**
  * camel_folder_has_summary_capability:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  *
  * Get whether or not the folder has a summary.
  *
@@ -1093,18 +1373,9 @@ camel_folder_has_summary_capability (CamelFolder *folder)
 
 /* UIDs stuff */
 
-static CamelMimeMessage *
-get_message (CamelFolder *folder, const gchar *uid, CamelException *ex)
-{
-	w (g_warning ("CamelFolder::get_message not implemented for '%s'",
-		     camel_type_to_name (CAMEL_OBJECT_GET_TYPE (folder))));
-
-	return NULL;
-}
-
 /**
  * camel_folder_get_message:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  * @uid: the UID
  * @ex: a #CamelException
  *
@@ -1113,15 +1384,22 @@ get_message (CamelFolder *folder, const gchar *uid, CamelException *ex)
  * Returns: a #CamelMimeMessage corresponding to @uid
  **/
 CamelMimeMessage *
-camel_folder_get_message (CamelFolder *folder, const gchar *uid, CamelException *ex)
+camel_folder_get_message (CamelFolder *folder,
+                          const gchar *uid,
+                          CamelException *ex)
 {
+	CamelFolderClass *class;
 	CamelMimeMessage *ret;
 
 	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL);
+	g_return_val_if_fail (uid != NULL, NULL);
+
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_val_if_fail (class->get_message != NULL, NULL);
 
 	CAMEL_FOLDER_REC_LOCK (folder, lock);
 
-	ret = CAMEL_FOLDER_GET_CLASS (folder)->get_message (folder, uid, ex);
+	ret = class->get_message (folder, uid, ex);
 
 	CAMEL_FOLDER_REC_UNLOCK (folder, lock);
 
@@ -1136,7 +1414,7 @@ camel_folder_get_message (CamelFolder *folder, const gchar *uid, CamelException
 
 /**
  * camel_folder_sync_message:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  * @uid: the UID
  * @ex: a #CamelException
  *
@@ -1146,34 +1424,37 @@ camel_folder_get_message (CamelFolder *folder, const gchar *uid, CamelException
  * Since: 2.26
  **/
 void
-camel_folder_sync_message (CamelFolder *folder, const gchar *uid, CamelException *ex)
+camel_folder_sync_message (CamelFolder *folder,
+                           const gchar *uid,
+                           CamelException *ex)
 {
+	CamelFolderClass *class;
+
 	g_return_if_fail (CAMEL_IS_FOLDER (folder));
+	g_return_if_fail (uid != NULL);
+
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_if_fail (class->get_message != NULL);
+
 	CAMEL_FOLDER_REC_LOCK (folder, lock);
 
 	/* Use the sync_message method if the class implements it. */
-	if (CAMEL_FOLDER_GET_CLASS (folder)->sync_message)
-		CAMEL_FOLDER_GET_CLASS (folder)->sync_message (folder, uid, ex);
+	if (class->sync_message != NULL)
+		class->sync_message (folder, uid, ex);
 	else {
 		CamelMimeMessage *message;
-		message = CAMEL_FOLDER_GET_CLASS (folder)->get_message (folder, uid, ex);
-		if (message)
+
+		message = class->get_message (folder, uid, ex);
+		if (message != NULL)
 			  camel_object_unref (message);
 	}
-	CAMEL_FOLDER_REC_UNLOCK (folder, lock);
-}
-
-static GPtrArray *
-get_uids (CamelFolder *folder)
-{
-	g_return_val_if_fail (folder->summary != NULL, g_ptr_array_new ());
 
-	return camel_folder_summary_array (folder->summary);
+	CAMEL_FOLDER_REC_UNLOCK (folder, lock);
 }
 
 /**
  * camel_folder_get_uids:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  *
  * Get the list of UIDs available in a folder. This routine is useful
  * for finding what messages are available when the folder does not
@@ -1186,60 +1467,41 @@ get_uids (CamelFolder *folder)
 GPtrArray *
 camel_folder_get_uids (CamelFolder *folder)
 {
-	GPtrArray *ret;
+	CamelFolderClass *class;
 
 	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL);
 
-	ret = CAMEL_FOLDER_GET_CLASS (folder)->get_uids (folder);
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_val_if_fail (class->get_uids != NULL, NULL);
 
-	return ret;
-}
-
-static void
-free_uids (CamelFolder *folder, GPtrArray *array)
-{
-	gint i;
-
-	for (i=0; i<array->len; i++)
-		camel_pstring_free (array->pdata[i]);
-	g_ptr_array_free (array, TRUE);
+	return class->get_uids (folder);
 }
 
 /**
  * camel_folder_free_uids:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  * @array: the array of uids to free
  *
  * Frees the array of UIDs returned by #camel_folder_get_uids.
  **/
 void
-camel_folder_free_uids (CamelFolder *folder, GPtrArray *array)
+camel_folder_free_uids (CamelFolder *folder,
+                        GPtrArray *array)
 {
-	g_return_if_fail (CAMEL_IS_FOLDER (folder));
-
-	CAMEL_FOLDER_GET_CLASS (folder)->free_uids (folder, array);
-}
+	CamelFolderClass *class;
 
-/**
- * Default: return the uids we are given.
- */
-static GPtrArray *
-get_uncached_uids (CamelFolder *folder, GPtrArray * uids, CamelException *ex)
-{
-	GPtrArray *result;
-	gint i;
+	g_return_if_fail (CAMEL_IS_FOLDER (folder));
+	g_return_if_fail (array != NULL);
 
-	result = g_ptr_array_new ();
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_if_fail (class->free_uids != NULL);
 
-	g_ptr_array_set_size (result, uids->len);
-	for (i = 0; i < uids->len; i++)
-	    result->pdata[i] = (gchar *)camel_pstring_strdup (uids->pdata[i]);
-	return result;
+	class->free_uids (folder, array);
 }
 
 /**
  * camel_folder_get_uncached_uids:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  * @uids: the array of uids to filter down to uncached ones.
  *
  * Returns the known-uncached uids from a list of uids. It may return uids
@@ -1250,24 +1512,24 @@ get_uncached_uids (CamelFolder *folder, GPtrArray * uids, CamelException *ex)
  * Since: 2.26
  **/
 GPtrArray *
-camel_folder_get_uncached_uids (CamelFolder *folder, GPtrArray * uids, CamelException *ex)
+camel_folder_get_uncached_uids (CamelFolder *folder,
+                                GPtrArray * uids,
+                                CamelException *ex)
 {
+	CamelFolderClass *class;
+
 	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL);
-	return CAMEL_FOLDER_GET_CLASS (folder)->get_uncached_uids (folder, uids, ex);
-}
+	g_return_val_if_fail (uids != NULL, NULL);
 
-static gint
-cmp_uids (CamelFolder *folder, const gchar *uid1, const gchar *uid2)
-{
-	g_return_val_if_fail (uid1 != NULL, 0);
-	g_return_val_if_fail (uid2 != NULL, 0);
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_val_if_fail (class->get_uncached_uids != NULL, NULL);
 
-	return strtoul (uid1, NULL, 10) - strtoul (uid2, NULL, 10);
+	return class->get_uncached_uids (folder, uids, ex);
 }
 
 /**
  * camel_folder_cmp_uids:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  * @uid1: The first uid.
  * @uid2: the second uid.
  *
@@ -1279,36 +1541,25 @@ cmp_uids (CamelFolder *folder, const gchar *uid1, const gchar *uid2)
  * Since: 2.28
  **/
 gint
-camel_folder_cmp_uids (CamelFolder *folder, const gchar *uid1, const gchar *uid2)
+camel_folder_cmp_uids (CamelFolder *folder,
+                       const gchar *uid1,
+                       const gchar *uid2)
 {
+	CamelFolderClass *class;
+
 	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), 0);
 	g_return_val_if_fail (uid1 != NULL, 0);
 	g_return_val_if_fail (uid2 != NULL, 0);
 
-	return CAMEL_FOLDER_GET_CLASS (folder)->cmp_uids (folder, uid1, uid2);
-}
-
-static gint
-cmp_array_uids (gconstpointer a, gconstpointer b, gpointer user_data)
-{
-	const gchar *uid1 = *(const gchar **) a;
-	const gchar *uid2 = *(const gchar **) b;
-	CamelFolder *folder = user_data;
-
-	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), 0);
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_val_if_fail (class->cmp_uids != NULL, 0);
 
-	return camel_folder_cmp_uids (folder, uid1, uid2);
-}
-
-static void
-sort_uids (CamelFolder *folder, GPtrArray *uids)
-{
-	g_qsort_with_data (uids->pdata, uids->len, sizeof (gpointer), cmp_array_uids, folder);
+	return class->cmp_uids (folder, uid1, uid2);
 }
 
 /**
  * camel_folder_sort_uids:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  * @uids: array of uids
  *
  * Sorts the array of UIDs.
@@ -1316,24 +1567,23 @@ sort_uids (CamelFolder *folder, GPtrArray *uids)
  * Since: 2.24
  **/
 void
-camel_folder_sort_uids (CamelFolder *folder, GPtrArray *uids)
+camel_folder_sort_uids (CamelFolder *folder,
+                        GPtrArray *uids)
 {
-	g_return_if_fail (CAMEL_IS_FOLDER (folder));
+	CamelFolderClass *class;
 
-	CAMEL_FOLDER_GET_CLASS (folder)->sort_uids (folder, uids);
-}
+	g_return_if_fail (CAMEL_IS_FOLDER (folder));
+	g_return_if_fail (uids != NULL);
 
-static GPtrArray *
-get_summary (CamelFolder *folder)
-{
-	g_assert (folder->summary != NULL);
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_if_fail (class->sort_uids != NULL);
 
-	return camel_folder_summary_array (folder->summary);
+	class->sort_uids (folder, uids);
 }
 
 /**
  * camel_folder_get_summary:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  *
  * This returns the summary information for the folder. This array
  * should not be modified, and must be freed with
@@ -1344,38 +1594,41 @@ get_summary (CamelFolder *folder)
 GPtrArray *
 camel_folder_get_summary (CamelFolder *folder)
 {
-	GPtrArray *ret;
+	CamelFolderClass *class;
 
 	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL);
 
-	ret = CAMEL_FOLDER_GET_CLASS (folder)->get_summary (folder);
-
-	return ret;
-}
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_val_if_fail (class->get_summary != NULL, NULL);
 
-static void
-free_summary (CamelFolder *folder, GPtrArray *summary)
-{
-	g_ptr_array_foreach (summary, (GFunc) camel_pstring_free, NULL);
-	g_ptr_array_free (summary, TRUE);
+	return class->get_summary (folder);
 }
 
 /**
  * camel_folder_free_summary:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  * @array: the summary array to free
  *
  * Frees the summary array returned by #camel_folder_get_summary.
  **/
 void
-camel_folder_free_summary (CamelFolder *folder, GPtrArray *array)
+camel_folder_free_summary (CamelFolder *folder,
+                           GPtrArray *array)
 {
-	CAMEL_FOLDER_GET_CLASS (folder)->free_summary (folder, array);
+	CamelFolderClass *class;
+
+	g_return_if_fail (CAMEL_IS_FOLDER (folder));
+	g_return_if_fail (array != NULL);
+
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_if_fail (class->free_summary != NULL);
+
+	class->free_summary (folder, array);
 }
 
 /**
  * camel_folder_has_search_capability:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  *
  * Checks if a folder supports searching.
  *
@@ -1389,23 +1642,9 @@ camel_folder_has_search_capability (CamelFolder *folder)
 	return folder->folder_flags & CAMEL_FOLDER_HAS_SEARCH_CAPABILITY;
 }
 
-static GPtrArray *
-search_by_expression (CamelFolder *folder, const gchar *expression,
-		      CamelException *ex)
-{
-	camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID,
-			      _("Unsupported operation: search by expression: for %s"),
-			      camel_type_to_name (CAMEL_OBJECT_GET_TYPE (folder)));
-
-	w (g_warning ("CamelFolder::search_by_expression not implemented for "
-		     "'%s'", camel_type_to_name (CAMEL_OBJECT_GET_TYPE (folder))));
-
-	return NULL;
-}
-
 /**
  * camel_folder_search_by_expression:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  * @expr: a search expression
  * @ex: a #CamelException
  *
@@ -1415,38 +1654,26 @@ search_by_expression (CamelFolder *folder, const gchar *expression,
  * free the list and each of the elements when it is done.
  **/
 GPtrArray *
-camel_folder_search_by_expression (CamelFolder *folder, const gchar *expression,
-				   CamelException *ex)
+camel_folder_search_by_expression (CamelFolder *folder,
+                                   const gchar *expression,
+                                   CamelException *ex)
 {
-	GPtrArray *ret;
+	CamelFolderClass *class;
 
 	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL);
 	g_return_val_if_fail (folder->folder_flags & CAMEL_FOLDER_HAS_SEARCH_CAPABILITY, NULL);
 
-	/* NOTE: that it is upto the callee to lock */
-
-	ret = CAMEL_FOLDER_GET_CLASS (folder)->search_by_expression (folder, expression, ex);
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_val_if_fail (class->search_by_expression != NULL, NULL);
 
-	return ret;
-}
-
-static guint32
-count_by_expression (CamelFolder *folder, const gchar *expression,
-		      CamelException *ex)
-{
-	camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID,
-			      _("Unsupported operation: count by expression: for %s"),
-			      camel_type_to_name (CAMEL_OBJECT_GET_TYPE (folder)));
-
-	w (g_warning ("CamelFolder::count_by_expression not implemented for "
-		     "'%s'", camel_type_to_name (CAMEL_OBJECT_GET_TYPE (folder))));
+	/* NOTE: that it is upto the callee to lock */
 
-	return 0;
+	return class->search_by_expression (folder, expression, ex);
 }
 
 /**
  * camel_folder_count_by_expression:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  * @expr: a search expression
  * @ex: a #CamelException
  *
@@ -1457,37 +1684,26 @@ count_by_expression (CamelFolder *folder, const gchar *expression,
  * Since: 2.26
  **/
 guint32
-camel_folder_count_by_expression (CamelFolder *folder, const gchar *expression,
-				   CamelException *ex)
+camel_folder_count_by_expression (CamelFolder *folder,
+                                  const gchar *expression,
+                                  CamelException *ex)
 {
-	guint32 ret;
+	CamelFolderClass *class;
 
 	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), 0);
 	g_return_val_if_fail (folder->folder_flags & CAMEL_FOLDER_HAS_SEARCH_CAPABILITY, 0);
 
-	/* NOTE: that it is upto the callee to lock */
-
-	ret = CAMEL_FOLDER_GET_CLASS (folder)->count_by_expression (folder, expression, ex);
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_val_if_fail (class->count_by_expression != NULL, 0);
 
-	return ret;
-}
-
-static GPtrArray *
-search_by_uids (CamelFolder *folder, const gchar *exp, GPtrArray *uids, CamelException *ex)
-{
-	camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID,
-			      _("Unsupported operation: search by UIDs: for %s"),
-			      camel_type_to_name (CAMEL_OBJECT_GET_TYPE (folder)));
-
-	w (g_warning ("CamelFolder::search_by_expression not implemented for "
-		     "'%s'", camel_type_to_name (CAMEL_OBJECT_GET_TYPE (folder))));
+	/* NOTE: that it is upto the callee to lock */
 
-	return NULL;
+	return class->count_by_expression (folder, expression, ex);
 }
 
 /**
  * camel_folder_search_by_uids:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  * @expr: search expression
  * @uids: array of uid's to match against.
  * @ex: a #CamelException
@@ -1498,118 +1714,47 @@ search_by_uids (CamelFolder *folder, const gchar *exp, GPtrArray *uids, CamelExc
  * free the list and each of the elements when it is done.
  **/
 GPtrArray *
-camel_folder_search_by_uids (CamelFolder *folder, const gchar *expr, GPtrArray *uids, CamelException *ex)
+camel_folder_search_by_uids (CamelFolder *folder,
+                             const gchar *expr,
+                             GPtrArray *uids,
+                             CamelException *ex)
 {
-	GPtrArray *ret;
+	CamelFolderClass *class;
 
 	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL);
 	g_return_val_if_fail (folder->folder_flags & CAMEL_FOLDER_HAS_SEARCH_CAPABILITY, NULL);
 
-	/* NOTE: that it is upto the callee to lock */
-
-	ret = CAMEL_FOLDER_GET_CLASS (folder)->search_by_uids (folder, expr, uids, ex);
-
-	return ret;
-}
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_val_if_fail (class->search_by_uids != NULL, NULL);
 
-static void
-search_free (CamelFolder *folder, GPtrArray *result)
-{
-	gint i;
+	/* NOTE: that it is upto the callee to lock */
 
-	for (i = 0; i < result->len; i++)
-		camel_pstring_free (g_ptr_array_index (result, i));
-	g_ptr_array_free (result, TRUE);
+	return class->search_by_uids (folder, expr, uids, ex);
 }
 
 /**
  * camel_folder_search_free:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  * @result: search results to free
  *
  * Free the result of a search as gotten by #camel_folder_search or
  * #camel_folder_search_by_uids.
  **/
 void
-camel_folder_search_free (CamelFolder *folder, GPtrArray *result)
+camel_folder_search_free (CamelFolder *folder,
+                          GPtrArray *result)
 {
-	g_return_if_fail (CAMEL_IS_FOLDER (folder));
-
-	/* NOTE: upto the callee to lock */
-	CAMEL_FOLDER_GET_CLASS (folder)->search_free (folder, result);
-}
-
-static void
-transfer_message_to (CamelFolder *source, const gchar *uid, CamelFolder *dest,
-		     gchar **transferred_uid, gboolean delete_original,
-		     CamelException *ex)
-{
-	CamelMimeMessage *msg;
-	CamelMessageInfo *minfo, *info;
-
-	/* Default implementation. */
+	CamelFolderClass *class;
 
-	msg = camel_folder_get_message (source, uid, ex);
-	if (!msg)
-		return;
-
-	/* if its deleted we poke the flags, so we need to copy the messageinfo */
-	if ((source->folder_flags & CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY)
-			&& (minfo = camel_folder_get_message_info (source, uid))) {
-		info = camel_message_info_clone (minfo);
-		camel_folder_free_message_info (source, minfo);
-	} else
-		info = camel_message_info_new_from_header (NULL, ((CamelMimePart *)msg)->headers);
-
-	/* we don't want to retain the deleted flag */
-	camel_message_info_set_flags (info, CAMEL_MESSAGE_DELETED, 0);
-
-	camel_folder_append_message (dest, msg, info, transferred_uid, ex);
-	camel_object_unref (msg);
-
-	if (delete_original && !camel_exception_is_set (ex))
-		camel_folder_set_message_flags (source, uid, CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN, ~0);
-
-	camel_message_info_free (info);
-}
-
-static void
-transfer_messages_to (CamelFolder *source, GPtrArray *uids, CamelFolder *dest, GPtrArray **transferred_uids, gboolean delete_originals, CamelException *ex)
-{
-	CamelException local;
-	gchar **ret_uid = NULL;
-	gint i;
-
-	if (transferred_uids) {
-		*transferred_uids = g_ptr_array_new ();
-		g_ptr_array_set_size (*transferred_uids, uids->len);
-	}
-
-	camel_exception_init (&local);
-	if (ex == NULL)
-		ex = &local;
+	g_return_if_fail (CAMEL_IS_FOLDER (folder));
+	g_return_if_fail (result != NULL);
 
-	camel_operation_start (NULL, delete_originals ? _("Moving messages") : _("Copying messages"));
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_if_fail (class->search_free != NULL);
 
-	if (uids->len > 1) {
-		camel_folder_freeze (dest);
-		if (delete_originals)
-			camel_folder_freeze (source);
-	}
-	for (i = 0; i < uids->len && !camel_exception_is_set (ex); i++) {
-		if (transferred_uids)
-			ret_uid = (gchar **)&((*transferred_uids)->pdata[i]);
-		transfer_message_to (source, uids->pdata[i], dest, ret_uid, delete_originals, ex);
-		camel_operation_progress (NULL, i * 100 / uids->len);
-	}
-	if (uids->len > 1) {
-		camel_folder_thaw (dest);
-		if (delete_originals)
-			camel_folder_thaw (source);
-	}
+	/* NOTE: upto the callee to lock */
 
-	camel_operation_end (NULL);
-	camel_exception_clear (&local);
+	class->search_free (folder, result);
 }
 
 /**
@@ -1627,10 +1772,15 @@ transfer_messages_to (CamelFolder *source, GPtrArray *uids, CamelFolder *dest, G
  * more efficient than using #camel_folder_append_message.
  **/
 void
-camel_folder_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
-				   CamelFolder *dest, GPtrArray **transferred_uids,
-				   gboolean delete_originals, CamelException *ex)
+camel_folder_transfer_messages_to (CamelFolder *source,
+                                   GPtrArray *uids,
+                                   CamelFolder *dest,
+                                   GPtrArray **transferred_uids,
+                                   gboolean delete_originals,
+                                   CamelException *ex)
 {
+	CamelFolderClass *class;
+
 	g_return_if_fail (CAMEL_IS_FOLDER (source));
 	g_return_if_fail (CAMEL_IS_FOLDER (dest));
 	g_return_if_fail (uids != NULL);
@@ -1642,34 +1792,36 @@ camel_folder_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
 
 	if (source->parent_store == dest->parent_store) {
 		/* If either folder is a vtrash, we need to use the
-		 * vtrash transfer method.
-		 */
+		 * vtrash transfer method. */
 		if (CAMEL_IS_VTRASH_FOLDER (dest))
-			CAMEL_FOLDER_GET_CLASS (dest)->transfer_messages_to (source, uids, dest, transferred_uids, delete_originals, ex);
+			class = CAMEL_FOLDER_GET_CLASS (dest);
 		else
-			CAMEL_FOLDER_GET_CLASS (source)->transfer_messages_to (source, uids, dest, transferred_uids, delete_originals, ex);
+			class = CAMEL_FOLDER_GET_CLASS (source);
+		class->transfer_messages_to (
+			source, uids, dest, transferred_uids,
+			delete_originals, ex);
 	} else
-		transfer_messages_to (source, uids, dest, transferred_uids, delete_originals, ex);
-}
-
-static void
-delete (CamelFolder *folder)
-{
-	if (folder->summary)
-		camel_folder_summary_clear (folder->summary);
+		folder_transfer_messages_to (
+			source, uids, dest, transferred_uids,
+			delete_originals, ex);
 }
 
 /**
  * camel_folder_delete:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  *
  * Marks a folder object as deleted and performs any required cleanup.
  **/
 void
 camel_folder_delete (CamelFolder *folder)
 {
+	CamelFolderClass *class;
+
 	g_return_if_fail (CAMEL_IS_FOLDER (folder));
 
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_if_fail (class->delete != NULL);
+
 	CAMEL_FOLDER_REC_LOCK (folder, lock);
 	if (folder->folder_flags & CAMEL_FOLDER_HAS_BEEN_DELETED) {
 		CAMEL_FOLDER_REC_UNLOCK (folder, lock);
@@ -1678,7 +1830,7 @@ camel_folder_delete (CamelFolder *folder)
 
 	folder->folder_flags |= CAMEL_FOLDER_HAS_BEEN_DELETED;
 
-	CAMEL_FOLDER_GET_CLASS (folder)->delete (folder);
+	class->delete (folder);
 
 	CAMEL_FOLDER_REC_UNLOCK (folder, lock);
 
@@ -1688,23 +1840,9 @@ camel_folder_delete (CamelFolder *folder)
 	camel_object_trigger_event (folder, "deleted", NULL);
 }
 
-static void
-folder_rename (CamelFolder *folder, const gchar *new)
-{
-	gchar *tmp;
-
-	d (printf ("CamelFolder:rename ('%s')\n", new));
-
-	g_free (folder->full_name);
-	folder->full_name = g_strdup (new);
-	g_free (folder->name);
-	tmp = strrchr (new, '/');
-	folder->name = g_strdup (tmp?tmp+1:new);
-}
-
 /**
  * camel_folder_rename:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  * @new: new name for the folder
  *
  * Mark an active folder object as renamed.
@@ -1713,29 +1851,25 @@ folder_rename (CamelFolder *folder, const gchar *new)
  * is performed on the folder.
  **/
 void
-camel_folder_rename (CamelFolder *folder, const gchar *new)
+camel_folder_rename (CamelFolder *folder,
+                     const gchar *new)
 {
+	CamelFolderClass *class;
 	gchar *old;
 
+	g_return_if_fail (CAMEL_IS_FOLDER (folder));
+	g_return_if_fail (new != NULL);
+
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_if_fail (class->rename != NULL);
+
 	old = g_strdup (folder->full_name);
 
-	CAMEL_FOLDER_GET_CLASS (folder)->rename (folder, new);
+	class->rename (folder, new);
 	camel_db_rename_folder (folder->parent_store->cdb_w, old, new, NULL);
 	camel_object_trigger_event (folder, "renamed", old);
-	g_free (old);
-}
-
-static void
-freeze (CamelFolder *folder)
-{
-	CAMEL_FOLDER_LOCK (folder, change_lock);
 
-	g_assert (folder->priv->frozen >= 0);
-
-	folder->priv->frozen++;
-
-	d (printf ("freeze (%p '%s') = %d\n", folder, folder->full_name, folder->priv->frozen));
-	CAMEL_FOLDER_UNLOCK (folder, change_lock);
+	g_free (old);
 }
 
 /**
@@ -1748,43 +1882,21 @@ freeze (CamelFolder *folder)
  * be emitted.
  **/
 void
-camel_folder_freeze (CamelFolder * folder)
-{
-	g_return_if_fail (CAMEL_IS_FOLDER (folder));
-
-	CAMEL_FOLDER_GET_CLASS (folder)->freeze (folder);
-}
-
-static void
-thaw (CamelFolder * folder)
+camel_folder_freeze (CamelFolder *folder)
 {
-	CamelFolderChangeInfo *info = NULL;
-
-	CAMEL_FOLDER_LOCK (folder, change_lock);
+	CamelFolderClass *class;
 
-	g_assert (folder->priv->frozen > 0);
-
-	folder->priv->frozen--;
-
-	d (printf ("thaw (%p '%s') = %d\n", folder, folder->full_name, folder->priv->frozen));
-
-	if (folder->priv->frozen == 0
-	    && camel_folder_change_info_changed (folder->priv->changed_frozen)) {
-		info = folder->priv->changed_frozen;
-		folder->priv->changed_frozen = camel_folder_change_info_new ();
-	}
+	g_return_if_fail (CAMEL_IS_FOLDER (folder));
 
-	CAMEL_FOLDER_UNLOCK (folder, change_lock);
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_if_fail (class->freeze != NULL);
 
-	if (info) {
-		camel_object_trigger_event (folder, "folder_changed", info);
-		camel_folder_change_info_free (info);
-	}
+	class->freeze (folder);
 }
 
 /**
  * camel_folder_thaw:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  *
  * Thaws the folder and emits any pending folder_changed
  * signals.
@@ -1792,52 +1904,55 @@ thaw (CamelFolder * folder)
 void
 camel_folder_thaw (CamelFolder *folder)
 {
+	CamelFolderClass *class;
+
 	g_return_if_fail (CAMEL_IS_FOLDER (folder));
 	g_return_if_fail (folder->priv->frozen != 0);
 
-	CAMEL_FOLDER_GET_CLASS (folder)->thaw (folder);
-}
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_if_fail (class->thaw != NULL);
 
-static gboolean
-is_frozen (CamelFolder *folder)
-{
-	return folder->priv->frozen != 0;
+	class->thaw (folder);
 }
 
 /**
  * camel_folder_is_frozen:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  *
  * Returns: whether or not the folder is frozen
  **/
 gboolean
 camel_folder_is_frozen (CamelFolder *folder)
 {
+	CamelFolderClass *class;
+
 	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
 
-	return CAMEL_FOLDER_GET_CLASS (folder)->is_frozen (folder);
-}
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_val_if_fail (class->is_frozen != NULL, FALSE);
 
-static CamelFolderQuotaInfo *
-get_quota_info (CamelFolder *folder)
-{
-	return NULL;
+	return class->is_frozen (folder);
 }
 
 /**
  * camel_folder_get_quota_info:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  *
- * Returns: list of known quota (s) for the folder.
+ * Returns: list of known quota(s) for the folder.
  *
  * Since: 2.24
  **/
 CamelFolderQuotaInfo *
 camel_folder_get_quota_info (CamelFolder *folder)
 {
+	CamelFolderClass *class;
+
 	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL);
 
-	return CAMEL_FOLDER_GET_CLASS (folder)->get_quota_info (folder);
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_val_if_fail (class->get_quota_info != NULL, NULL);
+
+	return class->get_quota_info (folder);
 }
 
 /**
@@ -1852,7 +1967,9 @@ camel_folder_get_quota_info (CamelFolder *folder)
  * Since: 2.24
  **/
 CamelFolderQuotaInfo *
-camel_folder_quota_info_new (const gchar *name, guint64 used, guint64 total)
+camel_folder_quota_info_new (const gchar *name,
+                             guint64 used,
+                             guint64 total)
 {
 	CamelFolderQuotaInfo *info;
 
@@ -2150,7 +2267,7 @@ folder_changed (CamelObject *obj, gpointer event_data)
 
 /**
  * camel_folder_free_nop:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  * @array: an array of uids or #CamelMessageInfo
  *
  * "Frees" the provided array by doing nothing. Used by #CamelFolder
@@ -2158,14 +2275,15 @@ folder_changed (CamelObject *obj, gpointer event_data)
  * the returned array is "static" information and should not be freed.
  **/
 void
-camel_folder_free_nop (CamelFolder *folder, GPtrArray *array)
+camel_folder_free_nop (CamelFolder *folder,
+                       GPtrArray *array)
 {
 	;
 }
 
 /**
  * camel_folder_free_shallow:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  * @array: an array of uids or #CamelMessageInfo
  *
  * Frees the provided array but not its contents. Used by #CamelFolder
@@ -2174,14 +2292,15 @@ camel_folder_free_nop (CamelFolder *folder, GPtrArray *array)
  * "static" information.
  **/
 void
-camel_folder_free_shallow (CamelFolder *folder, GPtrArray *array)
+camel_folder_free_shallow (CamelFolder *folder,
+                           GPtrArray *array)
 {
 	g_ptr_array_free (array, TRUE);
 }
 
 /**
  * camel_folder_free_deep:
- * @folder: a #CamelFolder object
+ * @folder: a #CamelFolder
  * @array: an array of uids
  *
  * Frees the provided array and its contents. Used by #CamelFolder
@@ -2189,10 +2308,13 @@ camel_folder_free_shallow (CamelFolder *folder, GPtrArray *array)
  * information was created explicitly by the corresponding get_ call.
  **/
 void
-camel_folder_free_deep (CamelFolder *folder, GPtrArray *array)
+camel_folder_free_deep (CamelFolder *folder,
+                        GPtrArray *array)
 {
 	gint i;
 
+	g_return_if_fail (array != NULL);
+
 	for (i = 0; i < array->len; i++)
 		g_free (array->pdata[i]);
 	g_ptr_array_free (array, TRUE);
@@ -2235,11 +2357,13 @@ camel_folder_change_info_new (void)
  * Add a source uid for generating a changeset.
  **/
 void
-camel_folder_change_info_add_source (CamelFolderChangeInfo *info, const gchar *uid)
+camel_folder_change_info_add_source (CamelFolderChangeInfo *info,
+                                     const gchar *uid)
 {
 	struct _CamelFolderChangeInfoPrivate *p;
 
-	g_assert (info != NULL);
+	g_return_if_fail (info != NULL);
+	g_return_if_fail (uid != NULL);
 
 	p = info->priv;
 
@@ -2258,13 +2382,14 @@ camel_folder_change_info_add_source (CamelFolderChangeInfo *info, const gchar *u
  * Add a list of source uid's for generating a changeset.
  **/
 void
-camel_folder_change_info_add_source_list (CamelFolderChangeInfo *info, const GPtrArray *list)
+camel_folder_change_info_add_source_list (CamelFolderChangeInfo *info,
+                                          const GPtrArray *list)
 {
 	struct _CamelFolderChangeInfoPrivate *p;
 	gint i;
 
-	g_assert (info != NULL);
-	g_assert (list != NULL);
+	g_return_if_fail (info != NULL);
+	g_return_if_fail (list != NULL);
 
 	p = info->priv;
 
@@ -2287,13 +2412,15 @@ camel_folder_change_info_add_source_list (CamelFolderChangeInfo *info, const GPt
  * Add a uid from the updated list, used to generate a changeset diff.
  **/
 void
-camel_folder_change_info_add_update (CamelFolderChangeInfo *info, const gchar *uid)
+camel_folder_change_info_add_update (CamelFolderChangeInfo *info,
+                                     const gchar *uid)
 {
 	struct _CamelFolderChangeInfoPrivate *p;
 	gchar *key;
 	gint value;
 
-	g_assert (info != NULL);
+	g_return_if_fail (info != NULL);
+	g_return_if_fail (uid != NULL);
 
 	p = info->priv;
 
@@ -2317,12 +2444,13 @@ camel_folder_change_info_add_update (CamelFolderChangeInfo *info, const gchar *u
  * Add a list of uid's from the updated list.
  **/
 void
-camel_folder_change_info_add_update_list (CamelFolderChangeInfo *info, const GPtrArray *list)
+camel_folder_change_info_add_update_list (CamelFolderChangeInfo *info,
+                                          const GPtrArray *list)
 {
 	gint i;
 
-	g_assert (info != NULL);
-	g_assert (list != NULL);
+	g_return_if_fail (info != NULL);
+	g_return_if_fail (list != NULL);
 
 	for (i=0;i<list->len;i++)
 		camel_folder_change_info_add_update (info, list->pdata[i]);
@@ -2362,7 +2490,7 @@ camel_folder_change_info_build_diff (CamelFolderChangeInfo *info)
 {
 	struct _CamelFolderChangeInfoPrivate *p;
 
-	g_assert (info != NULL);
+	g_return_if_fail (info != NULL);
 
 	p = info->priv;
 
@@ -2423,10 +2551,11 @@ change_info_cat (CamelFolderChangeInfo *info, GPtrArray *source, void (*add)(Cam
  * too.
  **/
 void
-camel_folder_change_info_cat (CamelFolderChangeInfo *info, CamelFolderChangeInfo *source)
+camel_folder_change_info_cat (CamelFolderChangeInfo *info,
+                              CamelFolderChangeInfo *source)
 {
-	g_assert (info != NULL);
-	g_assert (source != NULL);
+	g_return_if_fail (info != NULL);
+	g_return_if_fail (source != NULL);
 
 	change_info_cat (info, source->uid_added, camel_folder_change_info_add_uid);
 	change_info_cat (info, source->uid_removed, camel_folder_change_info_remove_uid);
@@ -2443,13 +2572,15 @@ camel_folder_change_info_cat (CamelFolderChangeInfo *info, CamelFolderChangeInfo
  * Add a new uid to the changeinfo.
  **/
 void
-camel_folder_change_info_add_uid (CamelFolderChangeInfo *info, const gchar *uid)
+camel_folder_change_info_add_uid (CamelFolderChangeInfo *info,
+                                  const gchar *uid)
 {
 	struct _CamelFolderChangeInfoPrivate *p;
 	GPtrArray *olduids;
 	gchar *olduid;
 
-	g_assert (info != NULL);
+	g_return_if_fail (info != NULL);
+	g_return_if_fail (uid != NULL);
 
 	p = info->priv;
 
@@ -2477,13 +2608,15 @@ camel_folder_change_info_add_uid (CamelFolderChangeInfo *info, const gchar *uid)
  * Add a uid to the removed uid list.
  **/
 void
-camel_folder_change_info_remove_uid (CamelFolderChangeInfo *info, const gchar *uid)
+camel_folder_change_info_remove_uid (CamelFolderChangeInfo *info,
+                                     const gchar *uid)
 {
 	struct _CamelFolderChangeInfoPrivate *p;
 	GPtrArray *olduids;
 	gchar *olduid;
 
-	g_assert (info != NULL);
+	g_return_if_fail (info != NULL);
+	g_return_if_fail (uid != NULL);
 
 	p = info->priv;
 
@@ -2510,13 +2643,15 @@ camel_folder_change_info_remove_uid (CamelFolderChangeInfo *info, const gchar *u
  * Add a uid to the changed uid list.
  **/
 void
-camel_folder_change_info_change_uid (CamelFolderChangeInfo *info, const gchar *uid)
+camel_folder_change_info_change_uid (CamelFolderChangeInfo *info,
+                                     const gchar *uid)
 {
 	struct _CamelFolderChangeInfoPrivate *p;
 	GPtrArray *olduids;
 	gchar *olduid;
 
-	g_assert (info != NULL);
+	g_return_if_fail (info != NULL);
+	g_return_if_fail (uid != NULL);
 
 	p = info->priv;
 
@@ -2540,9 +2675,11 @@ camel_folder_change_info_change_uid (CamelFolderChangeInfo *info, const gchar *u
  * filtering
  **/
 void
-camel_folder_change_info_recent_uid (CamelFolderChangeInfo *info, const gchar *uid)
+camel_folder_change_info_recent_uid (CamelFolderChangeInfo *info,
+                                     const gchar *uid)
 {
-	g_assert (info != NULL);
+	g_return_if_fail (info != NULL);
+	g_return_if_fail (uid != NULL);
 
 	change_info_recent_uid (info, uid);
 	change_info_filter_uid (info, uid);
@@ -2560,7 +2697,7 @@ camel_folder_change_info_recent_uid (CamelFolderChangeInfo *info, const gchar *u
 gboolean
 camel_folder_change_info_changed (CamelFolderChangeInfo *info)
 {
-	g_assert (info != NULL);
+	g_return_val_if_fail (info != NULL, FALSE);
 
 	return (info->uid_added->len || info->uid_removed->len || info->uid_changed->len || info->uid_recent->len);
 }
@@ -2577,7 +2714,7 @@ camel_folder_change_info_clear (CamelFolderChangeInfo *info)
 {
 	struct _CamelFolderChangeInfoPrivate *p;
 
-	g_assert (info != NULL);
+	g_return_if_fail (info != NULL);
 
 	p = info->priv;
 
@@ -2606,7 +2743,7 @@ camel_folder_change_info_free (CamelFolderChangeInfo *info)
 {
 	struct _CamelFolderChangeInfoPrivate *p;
 
-	g_assert (info != NULL);
+	g_return_if_fail (info != NULL);
 
 	p = info->priv;
 
diff --git a/camel/camel-store-summary.c b/camel/camel-store-summary.c
index 746ba6c..f6c27e0 100644
--- a/camel/camel-store-summary.c
+++ b/camel/camel-store-summary.c
@@ -32,7 +32,6 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 
-#include <glib.h>
 #include <glib/gstdio.h>
 
 #include <libedataserver/e-memory.h>
@@ -52,90 +51,278 @@
 /* current version */
 #define CAMEL_STORE_SUMMARY_VERSION (2)
 
-#define _PRIVATE(o) (((CamelStoreSummary *)(o))->priv)
+#define CAMEL_STORE_SUMMARY_GET_PRIVATE(o) (((CamelStoreSummary *)(o))->priv)
 
-static gint summary_header_load (CamelStoreSummary *, FILE *);
-static gint summary_header_save (CamelStoreSummary *, FILE *);
+static CamelObjectClass *camel_store_summary_parent;
 
-static CamelStoreInfo * store_info_new (CamelStoreSummary *, const gchar *);
-static CamelStoreInfo * store_info_load (CamelStoreSummary *, FILE *);
-static gint		 store_info_save (CamelStoreSummary *, FILE *, CamelStoreInfo *);
-static void		 store_info_free (CamelStoreSummary *, CamelStoreInfo *);
+static void
+store_summary_finalize (CamelStoreSummary *summary)
+{
+	camel_store_summary_clear (summary);
+	g_ptr_array_free (summary->folders, TRUE);
+	g_hash_table_destroy (summary->folders_path);
 
-static const gchar *store_info_string (CamelStoreSummary *, const CamelStoreInfo *, gint);
-static void store_info_set_string (CamelStoreSummary *, CamelStoreInfo *, int, const gchar *);
+	g_free (summary->summary_path);
 
-static void camel_store_summary_class_init (CamelStoreSummaryClass *klass);
-static void camel_store_summary_init       (CamelStoreSummary *obj);
-static void camel_store_summary_finalize   (CamelObject *obj);
+	if (summary->store_info_chunks != NULL)
+		e_memchunk_destroy (summary->store_info_chunks);
 
-static CamelObjectClass *camel_store_summary_parent;
+	g_mutex_free (summary->priv->summary_lock);
+	g_mutex_free (summary->priv->io_lock);
+	g_mutex_free (summary->priv->alloc_lock);
+	g_mutex_free (summary->priv->ref_lock);
 
-static void
-camel_store_summary_class_init (CamelStoreSummaryClass *klass)
+	g_free (summary->priv);
+}
+
+static gint
+store_summary_summary_header_load (CamelStoreSummary *summary,
+                                   FILE *in)
 {
-	camel_store_summary_parent = camel_type_get_global_classfuncs (camel_object_get_type ());
+	gint32 version, flags, count;
+	time_t time;
+
+	fseek (in, 0, SEEK_SET);
+
+	io (printf ("Loading header\n"));
+
+	if (camel_file_util_decode_fixed_int32 (in, &version) == -1
+	    || camel_file_util_decode_fixed_int32 (in, &flags) == -1
+	    || camel_file_util_decode_time_t (in, &time) == -1
+	    || camel_file_util_decode_fixed_int32 (in, &count) == -1) {
+		return -1;
+	}
+
+	summary->flags = flags;
+	summary->time = time;
+	summary->count = count;
+	summary->version = version;
 
-	klass->summary_header_load = summary_header_load;
-	klass->summary_header_save = summary_header_save;
+	if (version < CAMEL_STORE_SUMMARY_VERSION_0) {
+		g_warning ("Store summary header version too low");
+		return -1;
+	}
+
+	return 0;
+}
+
+static gint
+store_summary_summary_header_save (CamelStoreSummary *summary,
+                                   FILE *out)
+{
+	fseek (out, 0, SEEK_SET);
+
+	io (printf ("Savining header\n"));
+
+	/* always write latest version */
+	camel_file_util_encode_fixed_int32 (out, CAMEL_STORE_SUMMARY_VERSION);
+	camel_file_util_encode_fixed_int32 (out, summary->flags);
+	camel_file_util_encode_time_t (out, summary->time);
+
+	return camel_file_util_encode_fixed_int32 (
+		out, camel_store_summary_count (summary));
+}
+
+static CamelStoreInfo *
+store_summary_store_info_new (CamelStoreSummary *summary,
+                              const gchar *path)
+{
+	CamelStoreInfo *info;
+
+	info = camel_store_summary_info_new (summary);
+
+	info->path = g_strdup (path);
+	info->unread = CAMEL_STORE_INFO_FOLDER_UNKNOWN;
+	info->total = CAMEL_STORE_INFO_FOLDER_UNKNOWN;
+
+	return info;
+}
+
+static CamelStoreInfo *
+store_summary_store_info_load (CamelStoreSummary *summary,
+                               FILE *in)
+{
+	CamelStoreInfo *info;
+
+	info = camel_store_summary_info_new (summary);
+
+	io (printf ("Loading folder info\n"));
+
+	camel_file_util_decode_string (in, &info->path);
+	camel_file_util_decode_uint32 (in, &info->flags);
+	camel_file_util_decode_uint32 (in, &info->unread);
+	camel_file_util_decode_uint32 (in, &info->total);
+
+	/* Ok, brown paper bag bug - prior to version 2 of the file, flags are
+	   stored using the bit number, not the bit. Try to recover as best we can */
+	if (summary->version < CAMEL_STORE_SUMMARY_VERSION_2) {
+		guint32 flags = 0;
+
+		if (info->flags & 1)
+			flags |= CAMEL_STORE_INFO_FOLDER_NOSELECT;
+		if (info->flags & 2)
+			flags |= CAMEL_STORE_INFO_FOLDER_READONLY;
+		if (info->flags & 3)
+			flags |= CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
+		if (info->flags & 4)
+			flags |= CAMEL_STORE_INFO_FOLDER_FLAGGED;
+
+		info->flags = flags;
+	}
+
+	if (!ferror (in))
+		return info;
+
+	camel_store_summary_info_free (summary, info);
+
+	return NULL;
+}
+
+static gint
+store_summary_store_info_save (CamelStoreSummary *summary,
+                               FILE *out,
+                               CamelStoreInfo *info)
+{
+	io (printf ("Saving folder info\n"));
 
-	klass->store_info_new  = store_info_new;
-	klass->store_info_load = store_info_load;
-	klass->store_info_save = store_info_save;
-	klass->store_info_free = store_info_free;
+	camel_file_util_encode_string (
+		out, camel_store_info_path (summary, info));
+	camel_file_util_encode_uint32 (out, info->flags);
+	camel_file_util_encode_uint32 (out, info->unread);
+	camel_file_util_encode_uint32 (out, info->total);
 
-	klass->store_info_string = store_info_string;
-	klass->store_info_set_string = store_info_set_string;
+	return ferror (out);
 }
 
 static void
-camel_store_summary_init (CamelStoreSummary *s)
+store_summary_store_info_free (CamelStoreSummary *summary,
+                               CamelStoreInfo *info)
 {
-	struct _CamelStoreSummaryPrivate *p;
+	g_free (info->path);
+	g_free (info->uri);
+	g_slice_free1 (summary->store_info_size, info);
+}
 
-	p = _PRIVATE (s) = g_malloc0 (sizeof (*p));
+static const gchar *
+store_summary_store_info_string (CamelStoreSummary *summary,
+                                 const CamelStoreInfo *info,
+                                 gint type)
+{
+	const gchar *p;
 
-	s->store_info_size = sizeof (CamelStoreInfo);
+	/* FIXME: Locks? */
 
-	s->store_info_chunks = NULL;
+	g_assert (info != NULL);
 
-	s->version = CAMEL_STORE_SUMMARY_VERSION;
-	s->flags = 0;
-	s->count = 0;
-	s->time = 0;
+	switch (type) {
+	case CAMEL_STORE_INFO_PATH:
+		return info->path;
+	case CAMEL_STORE_INFO_NAME:
+		p = strrchr (info->path, '/');
+		if (p)
+			return p+1;
+		else
+			return info->path;
+	case CAMEL_STORE_INFO_URI:
+		if (info->uri == NULL) {
+			CamelURL *uri;
 
-	s->folders = g_ptr_array_new ();
-	s->folders_path = g_hash_table_new (g_str_hash, g_str_equal);
+			uri = camel_url_new_with_base (summary->uri_base, info->path);
+			((CamelStoreInfo *)info)->uri = camel_url_to_string (uri, 0);
+			camel_url_free (uri);
+		}
+		return info->uri;
+	}
 
-	p->summary_lock = g_mutex_new ();
-	p->io_lock = g_mutex_new ();
-	p->alloc_lock = g_mutex_new ();
-	p->ref_lock = g_mutex_new ();
+	return "";
 }
 
 static void
-camel_store_summary_finalize (CamelObject *obj)
+store_summary_store_info_set_string (CamelStoreSummary *summary,
+                                     CamelStoreInfo *info,
+                                     gint type,
+                                     const gchar *str)
 {
-	struct _CamelStoreSummaryPrivate *p;
-	CamelStoreSummary *s = (CamelStoreSummary *)obj;
+	const gchar *p;
+	gchar *v;
+	gint len;
 
-	p = _PRIVATE (obj);
+	g_assert (info != NULL);
 
-	camel_store_summary_clear (s);
-	g_ptr_array_free (s->folders, TRUE);
-	g_hash_table_destroy (s->folders_path);
+	switch (type) {
+	case CAMEL_STORE_INFO_PATH:
+		CAMEL_STORE_SUMMARY_LOCK (summary, summary_lock);
+		g_hash_table_remove (summary->folders_path, (gchar *)camel_store_info_path (summary, info));
+		g_free (info->path);
+		g_free (info->uri);
+		info->uri = NULL;
+		info->path = g_strdup (str);
+		g_hash_table_insert (summary->folders_path, (gchar *)camel_store_info_path (summary, info), info);
+		summary->flags |= CAMEL_STORE_SUMMARY_DIRTY;
+		CAMEL_STORE_SUMMARY_UNLOCK (summary, summary_lock);
+		break;
+	case CAMEL_STORE_INFO_NAME:
+		CAMEL_STORE_SUMMARY_LOCK (summary, summary_lock);
+		g_hash_table_remove (summary->folders_path, (gchar *)camel_store_info_path (summary, info));
+		p = strrchr (info->path, '/');
+		if (p) {
+			len = p-info->path+1;
+			v = g_malloc (len+strlen (str)+1);
+			memcpy (v, info->path, len);
+			strcpy (v+len, str);
+		} else {
+			v = g_strdup (str);
+		}
+		g_free (info->path);
+		info->path = v;
+		g_free (info->uri);
+		info->uri = NULL;
+		g_hash_table_insert (summary->folders_path, (gchar *)camel_store_info_path (summary, info), info);
+		CAMEL_STORE_SUMMARY_UNLOCK (summary, summary_lock);
+		break;
+	case CAMEL_STORE_INFO_URI:
+		g_warning ("Cannot set store info uri, aborting");
+		abort ();
+		break;
+	}
+}
+
+static void
+camel_store_summary_class_init (CamelStoreSummaryClass *class)
+{
+	camel_store_summary_parent = camel_type_get_global_classfuncs (camel_object_get_type ());
+
+	class->summary_header_load = store_summary_summary_header_load;
+	class->summary_header_save = store_summary_summary_header_save;
+	class->store_info_new  = store_summary_store_info_new;
+	class->store_info_load = store_summary_store_info_load;
+	class->store_info_save = store_summary_store_info_save;
+	class->store_info_free = store_summary_store_info_free;
+	class->store_info_string = store_summary_store_info_string;
+	class->store_info_set_string = store_summary_store_info_set_string;
+}
+
+static void
+camel_store_summary_init (CamelStoreSummary *summary)
+{
+	summary->priv = g_new0 (CamelStoreSummaryPrivate, 1);
 
-	g_free (s->summary_path);
+	summary->store_info_size = sizeof (CamelStoreInfo);
 
-	if (s->store_info_chunks)
-		e_memchunk_destroy (s->store_info_chunks);
+	summary->store_info_chunks = NULL;
 
-	g_mutex_free (p->summary_lock);
-	g_mutex_free (p->io_lock);
-	g_mutex_free (p->alloc_lock);
-	g_mutex_free (p->ref_lock);
+	summary->version = CAMEL_STORE_SUMMARY_VERSION;
+	summary->flags = 0;
+	summary->count = 0;
+	summary->time = 0;
 
-	g_free (p);
+	summary->folders = g_ptr_array_new ();
+	summary->folders_path = g_hash_table_new (g_str_hash, g_str_equal);
+
+	summary->priv->summary_lock = g_mutex_new ();
+	summary->priv->io_lock = g_mutex_new ();
+	summary->priv->alloc_lock = g_mutex_new ();
+	summary->priv->ref_lock = g_mutex_new ();
 }
 
 CamelType
@@ -150,7 +337,7 @@ camel_store_summary_get_type (void)
 					    (CamelObjectClassInitFunc) camel_store_summary_class_init,
 					    NULL,
 					    (CamelObjectInitFunc) camel_store_summary_init,
-					    (CamelObjectFinalizeFunc) camel_store_summary_finalize);
+					    (CamelObjectFinalizeFunc) store_summary_finalize);
 	}
 
 	return type;
@@ -166,7 +353,7 @@ camel_store_summary_get_type (void)
 CamelStoreSummary *
 camel_store_summary_new (void)
 {
-	CamelStoreSummary *new = CAMEL_STORE_SUMMARY ( camel_object_new (camel_store_summary_get_type ()));	return new;
+	return CAMEL_STORE_SUMMARY (camel_object_new (camel_store_summary_get_type ()));
 }
 
 /**
@@ -177,14 +364,17 @@ camel_store_summary_new (void)
  * Set the filename where the summary will be loaded to/saved from.
  **/
 void
-camel_store_summary_set_filename (CamelStoreSummary *s, const gchar *name)
+camel_store_summary_set_filename (CamelStoreSummary *summary,
+                                  const gchar *name)
 {
-	CAMEL_STORE_SUMMARY_LOCK (s, summary_lock);
+	g_return_if_fail (CAMEL_IS_STORE_SUMMARY (summary));
+
+	CAMEL_STORE_SUMMARY_LOCK (summary, summary_lock);
 
-	g_free (s->summary_path);
-	s->summary_path = g_strdup (name);
+	g_free (summary->summary_path);
+	summary->summary_path = g_strdup (name);
 
-	CAMEL_STORE_SUMMARY_UNLOCK (s, summary_lock);
+	CAMEL_STORE_SUMMARY_UNLOCK (summary, summary_lock);
 }
 
 /**
@@ -195,15 +385,18 @@ camel_store_summary_set_filename (CamelStoreSummary *s, const gchar *name)
  * Sets the base URI for the summary.
  **/
 void
-camel_store_summary_set_uri_base (CamelStoreSummary *s, CamelURL *base)
+camel_store_summary_set_uri_base (CamelStoreSummary *summary,
+                                  CamelURL *base)
 {
-	CAMEL_STORE_SUMMARY_LOCK (s, summary_lock);
+	g_return_if_fail (CAMEL_IS_STORE_SUMMARY (summary));
+
+	CAMEL_STORE_SUMMARY_LOCK (summary, summary_lock);
 
-	if (s->uri_base)
-		camel_url_free (s->uri_base);
-	s->uri_base = camel_url_new_with_base (base, "");
+	if (summary->uri_base)
+		camel_url_free (summary->uri_base);
+	summary->uri_base = camel_url_new_with_base (base, "");
 
-	CAMEL_STORE_SUMMARY_UNLOCK (s, summary_lock);
+	CAMEL_STORE_SUMMARY_UNLOCK (summary, summary_lock);
 }
 
 /**
@@ -215,9 +408,11 @@ camel_store_summary_set_uri_base (CamelStoreSummary *s, CamelURL *base)
  * Returns: the number of items gint he summary.
  **/
 gint
-camel_store_summary_count (CamelStoreSummary *s)
+camel_store_summary_count (CamelStoreSummary *summary)
 {
-	return s->folders->len;
+	g_return_val_if_fail (CAMEL_IS_STORE_SUMMARY (summary), -1);
+
+	return summary->folders->len;
 }
 
 /**
@@ -235,22 +430,25 @@ camel_store_summary_count (CamelStoreSummary *s)
  * Returns: the summary item, or %NULL if @index is out of range
  **/
 CamelStoreInfo *
-camel_store_summary_index (CamelStoreSummary *s, gint i)
+camel_store_summary_index (CamelStoreSummary *summary,
+                           gint i)
 {
 	CamelStoreInfo *info = NULL;
 
-	CAMEL_STORE_SUMMARY_LOCK (s, ref_lock);
-	CAMEL_STORE_SUMMARY_LOCK (s, summary_lock);
+	g_return_val_if_fail (CAMEL_IS_STORE_SUMMARY (summary), NULL);
+
+	CAMEL_STORE_SUMMARY_LOCK (summary, ref_lock);
+	CAMEL_STORE_SUMMARY_LOCK (summary, summary_lock);
 
-	if (i<s->folders->len)
-		info = g_ptr_array_index (s->folders, i);
+	if (i < summary->folders->len)
+		info = g_ptr_array_index (summary->folders, i);
 
-	CAMEL_STORE_SUMMARY_UNLOCK (s, summary_lock);
+	CAMEL_STORE_SUMMARY_UNLOCK (summary, summary_lock);
 
 	if (info)
 		info->refcount++;
 
-	CAMEL_STORE_SUMMARY_UNLOCK (s, ref_lock);
+	CAMEL_STORE_SUMMARY_UNLOCK (summary, ref_lock);
 
 	return info;
 }
@@ -267,23 +465,26 @@ camel_store_summary_index (CamelStoreSummary *s, gint i)
  * Returns: the summary array
  **/
 GPtrArray *
-camel_store_summary_array (CamelStoreSummary *s)
+camel_store_summary_array (CamelStoreSummary *summary)
 {
 	CamelStoreInfo *info;
-	GPtrArray *res = g_ptr_array_new ();
+	GPtrArray *res;
 	gint i;
 
-	CAMEL_STORE_SUMMARY_LOCK (s, ref_lock);
-	CAMEL_STORE_SUMMARY_LOCK (s, summary_lock);
+	g_return_val_if_fail (CAMEL_IS_STORE_SUMMARY (summary), NULL);
 
-	g_ptr_array_set_size (res, s->folders->len);
-	for (i=0;i<s->folders->len;i++) {
-		info = res->pdata[i] = g_ptr_array_index (s->folders, i);
+	CAMEL_STORE_SUMMARY_LOCK (summary, ref_lock);
+	CAMEL_STORE_SUMMARY_LOCK (summary, summary_lock);
+
+	res = g_ptr_array_new ();
+	g_ptr_array_set_size (res, summary->folders->len);
+	for (i=0; i < summary->folders->len; i++) {
+		info = res->pdata[i] = g_ptr_array_index (summary->folders, i);
 		info->refcount++;
 	}
 
-	CAMEL_STORE_SUMMARY_UNLOCK (s, summary_lock);
-	CAMEL_STORE_SUMMARY_UNLOCK (s, ref_lock);
+	CAMEL_STORE_SUMMARY_UNLOCK (summary, summary_lock);
+	CAMEL_STORE_SUMMARY_UNLOCK (summary, ref_lock);
 
 	return res;
 }
@@ -296,12 +497,16 @@ camel_store_summary_array (CamelStoreSummary *s)
  * Free the folder summary array.
  **/
 void
-camel_store_summary_array_free (CamelStoreSummary *s, GPtrArray *array)
+camel_store_summary_array_free (CamelStoreSummary *summary,
+                                GPtrArray *array)
 {
 	gint i;
 
-	for (i=0;i<array->len;i++)
-		camel_store_summary_info_free (s, array->pdata[i]);
+	g_return_if_fail (CAMEL_IS_STORE_SUMMARY (summary));
+	g_return_if_fail (array != NULL);
+
+	for (i=0; i < array->len; i++)
+		camel_store_summary_info_free (summary, array->pdata[i]);
 
 	g_ptr_array_free (array, TRUE);
 }
@@ -322,21 +527,25 @@ camel_store_summary_array_free (CamelStoreSummary *s, GPtrArray *array)
  * available
  **/
 CamelStoreInfo *
-camel_store_summary_path (CamelStoreSummary *s, const gchar *path)
+camel_store_summary_path (CamelStoreSummary *summary,
+                          const gchar *path)
 {
 	CamelStoreInfo *info;
 
-	CAMEL_STORE_SUMMARY_LOCK (s, ref_lock);
-	CAMEL_STORE_SUMMARY_LOCK (s, summary_lock);
+	g_return_val_if_fail (CAMEL_IS_STORE_SUMMARY (summary), NULL);
+	g_return_val_if_fail (path != NULL, NULL);
+
+	CAMEL_STORE_SUMMARY_LOCK (summary, ref_lock);
+	CAMEL_STORE_SUMMARY_LOCK (summary, summary_lock);
 
-	info = g_hash_table_lookup (s->folders_path, path);
+	info = g_hash_table_lookup (summary->folders_path, path);
 
-	CAMEL_STORE_SUMMARY_UNLOCK (s, summary_lock);
+	CAMEL_STORE_SUMMARY_UNLOCK (summary, summary_lock);
 
 	if (info)
 		info->refcount++;
 
-	CAMEL_STORE_SUMMARY_UNLOCK (s, ref_lock);
+	CAMEL_STORE_SUMMARY_UNLOCK (summary, ref_lock);
 
 	return info;
 }
@@ -350,47 +559,52 @@ camel_store_summary_path (CamelStoreSummary *s, const gchar *path)
  * Returns: %0 on success or %-1 on fail
  **/
 gint
-camel_store_summary_load (CamelStoreSummary *s)
+camel_store_summary_load (CamelStoreSummary *summary)
 {
+	CamelStoreSummaryClass *class;
+	CamelStoreInfo *info;
 	FILE *in;
 	gint i;
-	CamelStoreInfo *info;
 
-	g_assert (s->summary_path);
+	g_return_val_if_fail (CAMEL_IS_STORE_SUMMARY (summary), -1);
+	g_return_val_if_fail (summary->summary_path != NULL, -1);
+
+	class = CAMEL_STORE_SUMMARY_GET_CLASS (summary);
+	g_return_val_if_fail (class->store_info_load != NULL, -1);
 
-	in = g_fopen (s->summary_path, "rb");
+	in = g_fopen (summary->summary_path, "rb");
 	if (in == NULL)
 		return -1;
 
-	CAMEL_STORE_SUMMARY_LOCK (s, io_lock);
-	if ( ((CamelStoreSummaryClass *)(CAMEL_OBJECT_GET_CLASS (s)))->summary_header_load (s, in) == -1)
+	CAMEL_STORE_SUMMARY_LOCK (summary, io_lock);
+	if (class->summary_header_load (summary, in) == -1)
 		goto error;
 
 	/* now read in each message ... */
-	for (i=0;i<s->count;i++) {
-		info = ((CamelStoreSummaryClass *)(CAMEL_OBJECT_GET_CLASS (s)))->store_info_load (s, in);
+	for (i = 0; i < summary->count; i++) {
+		info = class->store_info_load (summary, in);
 
 		if (info == NULL)
 			goto error;
 
-		camel_store_summary_add (s, info);
+		camel_store_summary_add (summary, info);
 	}
 
-	CAMEL_STORE_SUMMARY_UNLOCK (s, io_lock);
+	CAMEL_STORE_SUMMARY_UNLOCK (summary, io_lock);
 
 	if (fclose (in) != 0)
 		return -1;
 
-	s->flags &= ~CAMEL_STORE_SUMMARY_DIRTY;
+	summary->flags &= ~CAMEL_STORE_SUMMARY_DIRTY;
 
 	return 0;
 
 error:
 	i = ferror (in);
 	g_warning ("Cannot load summary file: %s", g_strerror (ferror (in)));
-	CAMEL_STORE_SUMMARY_UNLOCK (s, io_lock);
+	CAMEL_STORE_SUMMARY_UNLOCK (summary, io_lock);
 	fclose (in);
-	s->flags |= ~CAMEL_STORE_SUMMARY_DIRTY;
+	summary->flags |= ~CAMEL_STORE_SUMMARY_DIRTY;
 	errno = i;
 
 	return -1;
@@ -406,24 +620,29 @@ error:
  * Returns: %0 on succes or %-1 on fail
  **/
 gint
-camel_store_summary_save (CamelStoreSummary *s)
+camel_store_summary_save (CamelStoreSummary *summary)
 {
+	CamelStoreSummaryClass *class;
+	CamelStoreInfo *info;
 	FILE *out;
 	gint fd;
 	gint i;
 	guint32 count;
-	CamelStoreInfo *info;
 
-	g_assert (s->summary_path);
+	g_return_val_if_fail (CAMEL_IS_STORE_SUMMARY (summary), -1);
+	g_return_val_if_fail (summary->summary_path != NULL, -1);
+
+	class = CAMEL_STORE_SUMMARY_GET_CLASS (summary);
+	g_return_val_if_fail (class->summary_header_save != NULL, -1);
 
 	io (printf ("** saving summary\n"));
 
-	if ((s->flags & CAMEL_STORE_SUMMARY_DIRTY) == 0) {
+	if ((summary->flags & CAMEL_STORE_SUMMARY_DIRTY) == 0) {
 		io (printf ("**  summary clean no save\n"));
 		return 0;
 	}
 
-	fd = g_open (s->summary_path, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0600);
+	fd = g_open (summary->summary_path, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0600);
 	if (fd == -1) {
 		io (printf ("**  open error: %s\n", g_strerror (errno)));
 		return -1;
@@ -440,12 +659,12 @@ camel_store_summary_save (CamelStoreSummary *s)
 
 	io (printf ("saving header\n"));
 
-	CAMEL_STORE_SUMMARY_LOCK (s, io_lock);
+	CAMEL_STORE_SUMMARY_LOCK (summary, io_lock);
 
-	if ( ((CamelStoreSummaryClass *)(CAMEL_OBJECT_GET_CLASS (s)))->summary_header_save (s, out) == -1) {
+	if (class->summary_header_save (summary, out) == -1) {
 		i = errno;
 		fclose (out);
-		CAMEL_STORE_SUMMARY_UNLOCK (s, io_lock);
+		CAMEL_STORE_SUMMARY_UNLOCK (summary, io_lock);
 		errno = i;
 		return -1;
 	}
@@ -454,13 +673,13 @@ camel_store_summary_save (CamelStoreSummary *s)
 
 	/* FIXME: Locking? */
 
-	count = s->folders->len;
-	for (i=0;i<count;i++) {
-		info = s->folders->pdata[i];
-		((CamelStoreSummaryClass *)(CAMEL_OBJECT_GET_CLASS (s)))->store_info_save (s, out, info);
+	count = summary->folders->len;
+	for (i=0; i < count; i++) {
+		info = summary->folders->pdata[i];
+		class->store_info_save (summary, out, info);
 	}
 
-	CAMEL_STORE_SUMMARY_UNLOCK (s, io_lock);
+	CAMEL_STORE_SUMMARY_UNLOCK (summary, io_lock);
 
 	if (fflush (out) != 0 || fsync (fileno (out)) == -1) {
 		i = errno;
@@ -472,7 +691,7 @@ camel_store_summary_save (CamelStoreSummary *s)
 	if (fclose (out) != 0)
 		return -1;
 
-	s->flags &= ~CAMEL_STORE_SUMMARY_DIRTY;
+	summary->flags &= ~CAMEL_STORE_SUMMARY_DIRTY;
 	return 0;
 }
 
@@ -487,23 +706,28 @@ camel_store_summary_save (CamelStoreSummary *s)
  * Returns: %0 on success or %-1 on fail
  **/
 gint
-camel_store_summary_header_load (CamelStoreSummary *s)
+camel_store_summary_header_load (CamelStoreSummary *summary)
 {
+	CamelStoreSummaryClass *class;
 	FILE *in;
 	gint ret;
 
-	g_assert (s->summary_path);
+	g_return_val_if_fail (CAMEL_IS_STORE_SUMMARY (summary), -1);
+	g_return_val_if_fail (summary->summary_path != NULL, -1);
 
-	in = g_fopen (s->summary_path, "rb");
+	class = CAMEL_STORE_SUMMARY_GET_CLASS (summary);
+	g_return_val_if_fail (class->summary_header_load != NULL, -1);
+
+	in = g_fopen (summary->summary_path, "rb");
 	if (in == NULL)
 		return -1;
 
-	CAMEL_STORE_SUMMARY_LOCK (s, io_lock);
-	ret = ((CamelStoreSummaryClass *)(CAMEL_OBJECT_GET_CLASS (s)))->summary_header_load (s, in);
-	CAMEL_STORE_SUMMARY_UNLOCK (s, io_lock);
+	CAMEL_STORE_SUMMARY_LOCK (summary, io_lock);
+	ret = class->summary_header_load (summary, in);
+	CAMEL_STORE_SUMMARY_UNLOCK (summary, io_lock);
 
 	fclose (in);
-	s->flags &= ~CAMEL_STORE_SUMMARY_DIRTY;
+	summary->flags &= ~CAMEL_STORE_SUMMARY_DIRTY;
 	return ret;
 }
 
@@ -521,23 +745,26 @@ camel_store_summary_header_load (CamelStoreSummary *s)
  * class.  And MUST NOT be allocated directly using malloc.
  **/
 void
-camel_store_summary_add (CamelStoreSummary *s, CamelStoreInfo *info)
+camel_store_summary_add (CamelStoreSummary *summary,
+                         CamelStoreInfo *info)
 {
+	g_return_if_fail (CAMEL_IS_STORE_SUMMARY (summary));
+
 	if (info == NULL)
 		return;
 
-	if (camel_store_info_path (s, info) == NULL) {
+	if (camel_store_info_path (summary, info) == NULL) {
 		g_warning ("Trying to add a folder info with missing required path name\n");
 		return;
 	}
 
-	CAMEL_STORE_SUMMARY_LOCK (s, summary_lock);
+	CAMEL_STORE_SUMMARY_LOCK (summary, summary_lock);
 
-	g_ptr_array_add (s->folders, info);
-	g_hash_table_insert (s->folders_path, (gchar *)camel_store_info_path (s, info), info);
-	s->flags |= CAMEL_STORE_SUMMARY_DIRTY;
+	g_ptr_array_add (summary->folders, info);
+	g_hash_table_insert (summary->folders_path, (gchar *)camel_store_info_path (summary, info), info);
+	summary->flags |= CAMEL_STORE_SUMMARY_DIRTY;
 
-	CAMEL_STORE_SUMMARY_UNLOCK (s, summary_lock);
+	CAMEL_STORE_SUMMARY_UNLOCK (summary, summary_lock);
 }
 
 /**
@@ -550,24 +777,28 @@ camel_store_summary_add (CamelStoreSummary *s, CamelStoreInfo *info)
  * Returns: the newly added record
  **/
 CamelStoreInfo *
-camel_store_summary_add_from_path (CamelStoreSummary *s, const gchar *path)
+camel_store_summary_add_from_path (CamelStoreSummary *summary,
+                                   const gchar *path)
 {
 	CamelStoreInfo *info;
 
-	CAMEL_STORE_SUMMARY_LOCK (s, summary_lock);
+	g_return_val_if_fail (CAMEL_IS_STORE_SUMMARY (summary), NULL);
+	g_return_val_if_fail (path != NULL, NULL);
 
-	info = g_hash_table_lookup (s->folders_path, path);
+	CAMEL_STORE_SUMMARY_LOCK (summary, summary_lock);
+
+	info = g_hash_table_lookup (summary->folders_path, path);
 	if (info != NULL) {
 		g_warning ("Trying to add folder '%s' to summary that already has it", path);
 		info = NULL;
 	} else {
-		info = camel_store_summary_info_new_from_path (s, path);
-		g_ptr_array_add (s->folders, info);
-		g_hash_table_insert (s->folders_path, (gchar *)camel_store_info_path (s, info), info);
-		s->flags |= CAMEL_STORE_SUMMARY_DIRTY;
+		info = camel_store_summary_info_new_from_path (summary, path);
+		g_ptr_array_add (summary->folders, info);
+		g_hash_table_insert (summary->folders_path, (gchar *)camel_store_info_path (summary, info), info);
+		summary->flags |= CAMEL_STORE_SUMMARY_DIRTY;
 	}
 
-	CAMEL_STORE_SUMMARY_UNLOCK (s, summary_lock);
+	CAMEL_STORE_SUMMARY_UNLOCK (summary, summary_lock);
 
 	return info;
 }
@@ -586,9 +817,17 @@ camel_store_summary_add_from_path (CamelStoreSummary *s, const gchar *path)
  * Returns: the #CamelStoreInfo associated with @path
  **/
 CamelStoreInfo *
-camel_store_summary_info_new_from_path (CamelStoreSummary *s, const gchar *path)
+camel_store_summary_info_new_from_path (CamelStoreSummary *summary,
+                                        const gchar *path)
 {
-	return ((CamelStoreSummaryClass *)(CAMEL_OBJECT_GET_CLASS (s)))->store_info_new (s, path);
+	CamelStoreSummaryClass *class;
+
+	g_return_val_if_fail (CAMEL_IS_STORE_SUMMARY (summary), NULL);
+
+	class = CAMEL_STORE_SUMMARY_GET_CLASS (summary);
+	g_return_val_if_fail (class->store_info_new != NULL, NULL);
+
+	return class->store_info_new (summary, path);
 }
 
 /**
@@ -599,24 +838,28 @@ camel_store_summary_info_new_from_path (CamelStoreSummary *s, const gchar *path)
  * Unref and potentially free @info, and all associated memory.
  **/
 void
-camel_store_summary_info_free (CamelStoreSummary *s, CamelStoreInfo *info)
+camel_store_summary_info_free (CamelStoreSummary *summary,
+                               CamelStoreInfo *info)
 {
-	g_assert (info);
-	g_assert (s);
+	CamelStoreSummaryClass *class;
+
+	g_return_if_fail (CAMEL_IS_STORE_SUMMARY (summary));
+	g_return_if_fail (info != NULL && info->refcount >= 1);
 
-	CAMEL_STORE_SUMMARY_LOCK (s, ref_lock);
+	class = CAMEL_STORE_SUMMARY_GET_CLASS (summary);
+	g_return_if_fail (class->store_info_free != NULL);
 
-	g_assert (info->refcount >= 1);
+	CAMEL_STORE_SUMMARY_LOCK (summary, ref_lock);
 
 	info->refcount--;
 	if (info->refcount > 0) {
-		CAMEL_STORE_SUMMARY_UNLOCK (s, ref_lock);
+		CAMEL_STORE_SUMMARY_UNLOCK (summary, ref_lock);
 		return;
 	}
 
-	CAMEL_STORE_SUMMARY_UNLOCK (s, ref_lock);
+	CAMEL_STORE_SUMMARY_UNLOCK (summary, ref_lock);
 
-	((CamelStoreSummaryClass *)(CAMEL_OBJECT_GET_CLASS (s)))->store_info_free (s, info);
+	class->store_info_free (summary, info);
 }
 
 /**
@@ -627,15 +870,15 @@ camel_store_summary_info_free (CamelStoreSummary *s, CamelStoreInfo *info)
  * Add an extra reference to @info.
  **/
 void
-camel_store_summary_info_ref (CamelStoreSummary *s, CamelStoreInfo *info)
+camel_store_summary_info_ref (CamelStoreSummary *summary,
+                              CamelStoreInfo *info)
 {
-	g_assert (info);
-	g_assert (s);
+	g_return_if_fail (CAMEL_IS_STORE_SUMMARY (summary));
+	g_return_if_fail (info != NULL && info->refcount >= 1);
 
-	CAMEL_STORE_SUMMARY_LOCK (s, ref_lock);
-	g_assert (info->refcount >= 1);
+	CAMEL_STORE_SUMMARY_LOCK (summary, ref_lock);
 	info->refcount++;
-	CAMEL_STORE_SUMMARY_UNLOCK (s, ref_lock);
+	CAMEL_STORE_SUMMARY_UNLOCK (summary, ref_lock);
 }
 
 /**
@@ -646,11 +889,13 @@ camel_store_summary_info_ref (CamelStoreSummary *s, CamelStoreInfo *info)
  * written back to disk.
  **/
 void
-camel_store_summary_touch (CamelStoreSummary *s)
+camel_store_summary_touch (CamelStoreSummary *summary)
 {
-	CAMEL_STORE_SUMMARY_LOCK (s, summary_lock);
-	s->flags |= CAMEL_STORE_SUMMARY_DIRTY;
-	CAMEL_STORE_SUMMARY_UNLOCK (s, summary_lock);
+	g_return_if_fail (CAMEL_IS_STORE_SUMMARY (summary));
+
+	CAMEL_STORE_SUMMARY_LOCK (summary, summary_lock);
+	summary->flags |= CAMEL_STORE_SUMMARY_DIRTY;
+	CAMEL_STORE_SUMMARY_UNLOCK (summary, summary_lock);
 }
 
 /**
@@ -660,24 +905,26 @@ camel_store_summary_touch (CamelStoreSummary *s)
  * Empty the summary contents.
  **/
 void
-camel_store_summary_clear (CamelStoreSummary *s)
+camel_store_summary_clear (CamelStoreSummary *summary)
 {
 	gint i;
 
-	CAMEL_STORE_SUMMARY_LOCK (s, summary_lock);
-	if (camel_store_summary_count (s) == 0) {
-		CAMEL_STORE_SUMMARY_UNLOCK (s, summary_lock);
+	g_return_if_fail (CAMEL_IS_STORE_SUMMARY (summary));
+
+	CAMEL_STORE_SUMMARY_LOCK (summary, summary_lock);
+	if (camel_store_summary_count (summary) == 0) {
+		CAMEL_STORE_SUMMARY_UNLOCK (summary, summary_lock);
 		return;
 	}
 
-	for (i=0;i<s->folders->len;i++)
-		camel_store_summary_info_free (s, s->folders->pdata[i]);
+	for (i=0; i < summary->folders->len; i++)
+		camel_store_summary_info_free (summary, summary->folders->pdata[i]);
 
-	g_ptr_array_set_size (s->folders, 0);
-	g_hash_table_destroy (s->folders_path);
-	s->folders_path = g_hash_table_new (g_str_hash, g_str_equal);
-	s->flags |= CAMEL_STORE_SUMMARY_DIRTY;
-	CAMEL_STORE_SUMMARY_UNLOCK (s, summary_lock);
+	g_ptr_array_set_size (summary->folders, 0);
+	g_hash_table_destroy (summary->folders_path);
+	summary->folders_path = g_hash_table_new (g_str_hash, g_str_equal);
+	summary->flags |= CAMEL_STORE_SUMMARY_DIRTY;
+	CAMEL_STORE_SUMMARY_UNLOCK (summary, summary_lock);
 }
 
 /**
@@ -688,15 +935,19 @@ camel_store_summary_clear (CamelStoreSummary *s)
  * Remove a specific @info record from the summary.
  **/
 void
-camel_store_summary_remove (CamelStoreSummary *s, CamelStoreInfo *info)
+camel_store_summary_remove (CamelStoreSummary *summary,
+                            CamelStoreInfo *info)
 {
-	CAMEL_STORE_SUMMARY_LOCK (s, summary_lock);
-	g_hash_table_remove (s->folders_path, camel_store_info_path (s, info));
-	g_ptr_array_remove (s->folders, info);
-	s->flags |= CAMEL_STORE_SUMMARY_DIRTY;
-	CAMEL_STORE_SUMMARY_UNLOCK (s, summary_lock);
+	g_return_if_fail (CAMEL_IS_STORE_SUMMARY (summary));
+	g_return_if_fail (info != NULL);
+
+	CAMEL_STORE_SUMMARY_LOCK (summary, summary_lock);
+	g_hash_table_remove (summary->folders_path, camel_store_info_path (summary, info));
+	g_ptr_array_remove (summary->folders, info);
+	summary->flags |= CAMEL_STORE_SUMMARY_DIRTY;
+	CAMEL_STORE_SUMMARY_UNLOCK (summary, summary_lock);
 
-	camel_store_summary_info_free (s, info);
+	camel_store_summary_info_free (summary, info);
 }
 
 /**
@@ -707,23 +958,27 @@ camel_store_summary_remove (CamelStoreSummary *s, CamelStoreInfo *info)
  * Remove a specific info record from the summary, by @path.
  **/
 void
-camel_store_summary_remove_path (CamelStoreSummary *s, const gchar *path)
+camel_store_summary_remove_path (CamelStoreSummary *summary,
+                                 const gchar *path)
 {
-        CamelStoreInfo *oldinfo;
-        gchar *oldpath;
+	CamelStoreInfo *oldinfo;
+	gchar *oldpath;
+
+	g_return_if_fail (CAMEL_IS_STORE_SUMMARY (summary));
+	g_return_if_fail (path != NULL);
 
-	CAMEL_STORE_SUMMARY_LOCK (s, ref_lock);
-	CAMEL_STORE_SUMMARY_LOCK (s, summary_lock);
-        if (g_hash_table_lookup_extended (s->folders_path, path, (gpointer)&oldpath, (gpointer)&oldinfo)) {
+	CAMEL_STORE_SUMMARY_LOCK (summary, ref_lock);
+	CAMEL_STORE_SUMMARY_LOCK (summary, summary_lock);
+        if (g_hash_table_lookup_extended (summary->folders_path, path, (gpointer)&oldpath, (gpointer)&oldinfo)) {
 		/* make sure it doesn't vanish while we're removing it */
 		oldinfo->refcount++;
-		CAMEL_STORE_SUMMARY_UNLOCK (s, summary_lock);
-		CAMEL_STORE_SUMMARY_UNLOCK (s, ref_lock);
-		camel_store_summary_remove (s, oldinfo);
-		camel_store_summary_info_free (s, oldinfo);
+		CAMEL_STORE_SUMMARY_UNLOCK (summary, summary_lock);
+		CAMEL_STORE_SUMMARY_UNLOCK (summary, ref_lock);
+		camel_store_summary_remove (summary, oldinfo);
+		camel_store_summary_info_free (summary, oldinfo);
         } else {
-		CAMEL_STORE_SUMMARY_UNLOCK (s, summary_lock);
-		CAMEL_STORE_SUMMARY_UNLOCK (s, ref_lock);
+		CAMEL_STORE_SUMMARY_UNLOCK (summary, summary_lock);
+		CAMEL_STORE_SUMMARY_UNLOCK (summary, ref_lock);
 	}
 }
 
@@ -735,65 +990,24 @@ camel_store_summary_remove_path (CamelStoreSummary *s, const gchar *path)
  * Remove a specific info record from the summary, by index.
  **/
 void
-camel_store_summary_remove_index (CamelStoreSummary *s, gint index)
+camel_store_summary_remove_index (CamelStoreSummary *summary,
+                                  gint index)
 {
-	CAMEL_STORE_SUMMARY_LOCK (s, summary_lock);
-	if (index < s->folders->len) {
-		CamelStoreInfo *info = s->folders->pdata[index];
+	g_return_if_fail (CAMEL_IS_STORE_SUMMARY (summary));
 
-		g_hash_table_remove (s->folders_path, camel_store_info_path (s, info));
-		g_ptr_array_remove_index (s->folders, index);
-		s->flags |= CAMEL_STORE_SUMMARY_DIRTY;
+	CAMEL_STORE_SUMMARY_LOCK (summary, summary_lock);
+	if (index < summary->folders->len) {
+		CamelStoreInfo *info = summary->folders->pdata[index];
 
-		CAMEL_STORE_SUMMARY_UNLOCK (s, summary_lock);
-		camel_store_summary_info_free (s, info);
-	} else {
-		CAMEL_STORE_SUMMARY_UNLOCK (s, summary_lock);
-	}
-}
+		g_hash_table_remove (summary->folders_path, camel_store_info_path (summary, info));
+		g_ptr_array_remove_index (summary->folders, index);
+		summary->flags |= CAMEL_STORE_SUMMARY_DIRTY;
 
-static gint
-summary_header_load (CamelStoreSummary *s, FILE *in)
-{
-	gint32 version, flags, count;
-	time_t time;
-
-	fseek (in, 0, SEEK_SET);
-
-	io (printf ("Loading header\n"));
-
-	if (camel_file_util_decode_fixed_int32 (in, &version) == -1
-	    || camel_file_util_decode_fixed_int32 (in, &flags) == -1
-	    || camel_file_util_decode_time_t (in, &time) == -1
-	    || camel_file_util_decode_fixed_int32 (in, &count) == -1) {
-		return -1;
-	}
-
-	s->flags = flags;
-	s->time = time;
-	s->count = count;
-	s->version = version;
-
-	if (version < CAMEL_STORE_SUMMARY_VERSION_0) {
-		g_warning ("Store summary header version too low");
-		return -1;
+		CAMEL_STORE_SUMMARY_UNLOCK (summary, summary_lock);
+		camel_store_summary_info_free (summary, info);
+	} else {
+		CAMEL_STORE_SUMMARY_UNLOCK (summary, summary_lock);
 	}
-
-	return 0;
-}
-
-static gint
-summary_header_save (CamelStoreSummary *s, FILE *out)
-{
-	fseek (out, 0, SEEK_SET);
-
-	io (printf ("Savining header\n"));
-
-	/* always write latest version */
-	camel_file_util_encode_fixed_int32 (out, CAMEL_STORE_SUMMARY_VERSION);
-	camel_file_util_encode_fixed_int32 (out, s->flags);
-	camel_file_util_encode_time_t (out, s->time);
-	return camel_file_util_encode_fixed_int32 (out, camel_store_summary_count (s));
 }
 
 /**
@@ -806,12 +1020,15 @@ summary_header_save (CamelStoreSummary *s, FILE *out)
  * Returns: the newly allocated #CamelStoreInfo
  **/
 CamelStoreInfo *
-camel_store_summary_info_new (CamelStoreSummary *s)
+camel_store_summary_info_new (CamelStoreSummary *summary)
 {
 	CamelStoreInfo *info;
 
-	info = g_slice_alloc0 (s->store_info_size);
+	g_return_val_if_fail (CAMEL_IS_STORE_SUMMARY (summary), NULL);
+
+	info = g_slice_alloc0 (summary->store_info_size);
 	info->refcount = 1;
+
 	return info;
 }
 
@@ -826,9 +1043,19 @@ camel_store_summary_info_new (CamelStoreSummary *s)
  * Returns: the string value
  **/
 const gchar *
-camel_store_info_string (CamelStoreSummary *s, const CamelStoreInfo *info, gint type)
+camel_store_info_string (CamelStoreSummary *summary,
+                         const CamelStoreInfo *info,
+                         gint type)
 {
-	return ((CamelStoreSummaryClass *)(CAMEL_OBJECT_GET_CLASS (s)))->store_info_string (s, info, type);
+	CamelStoreSummaryClass *class;
+
+	g_return_val_if_fail (CAMEL_IS_STORE_SUMMARY (summary), NULL);
+	g_return_val_if_fail (info != NULL, NULL);
+
+	class = CAMEL_STORE_SUMMARY_GET_CLASS (summary);
+	g_return_val_if_fail (class->store_info_string != NULL, NULL);
+
+	return class->store_info_string (summary, info, type);
 }
 
 /**
@@ -841,160 +1068,18 @@ camel_store_info_string (CamelStoreSummary *s, const CamelStoreInfo *info, gint
  * Set a specific string on the @info.
  **/
 void
-camel_store_info_set_string (CamelStoreSummary *s, CamelStoreInfo *info, gint type, const gchar *value)
-{
-	((CamelStoreSummaryClass *)(CAMEL_OBJECT_GET_CLASS (s)))->store_info_set_string (s, info, type, value);
-}
-
-static CamelStoreInfo *
-store_info_new (CamelStoreSummary *s, const gchar *f)
-{
-	CamelStoreInfo *info;
-
-	info = camel_store_summary_info_new (s);
-
-	info->path = g_strdup (f);
-	info->unread = CAMEL_STORE_INFO_FOLDER_UNKNOWN;
-	info->total = CAMEL_STORE_INFO_FOLDER_UNKNOWN;
-
-	return info;
-}
-
-static CamelStoreInfo *
-store_info_load (CamelStoreSummary *s, FILE *in)
+camel_store_info_set_string (CamelStoreSummary *summary,
+                             CamelStoreInfo *info,
+                             gint type,
+                             const gchar *value)
 {
-	CamelStoreInfo *info;
-
-	info = camel_store_summary_info_new (s);
+	CamelStoreSummaryClass *class;
 
-	io (printf ("Loading folder info\n"));
-
-	camel_file_util_decode_string (in, &info->path);
-	camel_file_util_decode_uint32 (in, &info->flags);
-	camel_file_util_decode_uint32 (in, &info->unread);
-	camel_file_util_decode_uint32 (in, &info->total);
-
-	/* Ok, brown paper bag bug - prior to version 2 of the file, flags are
-	   stored using the bit number, not the bit. Try to recover as best we can */
-	if (s->version < CAMEL_STORE_SUMMARY_VERSION_2) {
-		guint32 flags = 0;
-
-		if (info->flags & 1)
-			flags |= CAMEL_STORE_INFO_FOLDER_NOSELECT;
-		if (info->flags & 2)
-			flags |= CAMEL_STORE_INFO_FOLDER_READONLY;
-		if (info->flags & 3)
-			flags |= CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
-		if (info->flags & 4)
-			flags |= CAMEL_STORE_INFO_FOLDER_FLAGGED;
+	g_return_if_fail (CAMEL_IS_STORE_SUMMARY (summary));
+	g_return_if_fail (info != NULL);
 
-		info->flags = flags;
-	}
+	class = CAMEL_STORE_SUMMARY_GET_CLASS (summary);
+	g_return_if_fail (class->store_info_set_string != NULL);
 
-	if (!ferror (in))
-		return info;
-
-	camel_store_summary_info_free (s, info);
-
-	return NULL;
-}
-
-static gint
-store_info_save (CamelStoreSummary *s, FILE *out, CamelStoreInfo *info)
-{
-	io (printf ("Saving folder info\n"));
-
-	camel_file_util_encode_string (out, camel_store_info_path (s, info));
-	camel_file_util_encode_uint32 (out, info->flags);
-	camel_file_util_encode_uint32 (out, info->unread);
-	camel_file_util_encode_uint32 (out, info->total);
-
-	return ferror (out);
-}
-
-static void
-store_info_free (CamelStoreSummary *s, CamelStoreInfo *info)
-{
-	g_free (info->path);
-	g_free (info->uri);
-	g_slice_free1 (s->store_info_size, info);
-}
-
-static const gchar *
-store_info_string (CamelStoreSummary *s, const CamelStoreInfo *info, gint type)
-{
-	const gchar *p;
-
-	/* FIXME: Locks? */
-
-	g_assert (info != NULL);
-
-	switch (type) {
-	case CAMEL_STORE_INFO_PATH:
-		return info->path;
-	case CAMEL_STORE_INFO_NAME:
-		p = strrchr (info->path, '/');
-		if (p)
-			return p+1;
-		else
-			return info->path;
-	case CAMEL_STORE_INFO_URI:
-		if (info->uri == NULL) {
-			CamelURL *uri;
-
-			uri = camel_url_new_with_base (s->uri_base, info->path);
-			((CamelStoreInfo *)info)->uri = camel_url_to_string (uri, 0);
-			camel_url_free (uri);
-		}
-		return info->uri;
-	}
-
-	return "";
-}
-
-static void
-store_info_set_string (CamelStoreSummary *s, CamelStoreInfo *info, gint type, const gchar *str)
-{
-	const gchar *p;
-	gchar *v;
-	gint len;
-
-	g_assert (info != NULL);
-
-	switch (type) {
-	case CAMEL_STORE_INFO_PATH:
-		CAMEL_STORE_SUMMARY_LOCK (s, summary_lock);
-		g_hash_table_remove (s->folders_path, (gchar *)camel_store_info_path (s, info));
-		g_free (info->path);
-		g_free (info->uri);
-		info->uri = NULL;
-		info->path = g_strdup (str);
-		g_hash_table_insert (s->folders_path, (gchar *)camel_store_info_path (s, info), info);
-		s->flags |= CAMEL_STORE_SUMMARY_DIRTY;
-		CAMEL_STORE_SUMMARY_UNLOCK (s, summary_lock);
-		break;
-	case CAMEL_STORE_INFO_NAME:
-		CAMEL_STORE_SUMMARY_LOCK (s, summary_lock);
-		g_hash_table_remove (s->folders_path, (gchar *)camel_store_info_path (s, info));
-		p = strrchr (info->path, '/');
-		if (p) {
-			len = p-info->path+1;
-			v = g_malloc (len+strlen (str)+1);
-			memcpy (v, info->path, len);
-			strcpy (v+len, str);
-		} else {
-			v = g_strdup (str);
-		}
-		g_free (info->path);
-		info->path = v;
-		g_free (info->uri);
-		info->uri = NULL;
-		g_hash_table_insert (s->folders_path, (gchar *)camel_store_info_path (s, info), info);
-		CAMEL_STORE_SUMMARY_UNLOCK (s, summary_lock);
-		break;
-	case CAMEL_STORE_INFO_URI:
-		g_warning ("Cannot set store info uri, aborting");
-		abort ();
-		break;
-	}
+	class->store_info_set_string (summary, info, type, value);
 }
diff --git a/camel/camel-store-summary.h b/camel/camel-store-summary.h
index 11eb8ca..fdfa05d 100644
--- a/camel/camel-store-summary.h
+++ b/camel/camel-store-summary.h
@@ -35,6 +35,8 @@
 #define CAMEL_STORE_SUMMARY(obj)         CAMEL_CHECK_CAST (obj, camel_store_summary_get_type (), CamelStoreSummary)
 #define CAMEL_STORE_SUMMARY_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_store_summary_get_type (), CamelStoreSummaryClass)
 #define CAMEL_IS_STORE_SUMMARY(obj)      CAMEL_CHECK_TYPE (obj, camel_store_summary_get_type ())
+#define CAMEL_STORE_SUMMARY_GET_CLASS(obj) \
+	((CamelStoreSummaryClass *) CAMEL_OBJECT_GET_CLASS (obj))
 
 G_BEGIN_DECLS
 
diff --git a/camel/camel-store.c b/camel/camel-store.c
index 4ca6c6a..619ec52 100644
--- a/camel/camel-store.c
+++ b/camel/camel-store.c
@@ -31,7 +31,6 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 
-#include <glib.h>
 #include <glib/gi18n-lib.h>
 
 #include "camel-db.h"
@@ -46,126 +45,53 @@
 #define d(x)
 #define w(x)
 
-static CamelServiceClass *parent_class = NULL;
-
-/* Returns the class for a CamelStore */
-#define CS_CLASS(so) ((CamelStoreClass *)((CamelObject *)(so))->klass)
-
-static CamelFolder *get_folder (CamelStore *store, const gchar *folder_name,
-				guint32 flags, CamelException *ex);
-static CamelFolder *get_inbox (CamelStore *store, CamelException *ex);
-
-static CamelFolder *get_trash (CamelStore *store, CamelException *ex);
-static CamelFolder *get_junk (CamelStore *store, CamelException *ex);
-
-static CamelFolderInfo *create_folder (CamelStore *store,
-				       const gchar *parent_name,
-				       const gchar *folder_name,
-				       CamelException *ex);
-static void delete_folder (CamelStore *store, const gchar *folder_name,
-			   CamelException *ex);
-static void rename_folder (CamelStore *store, const gchar *old_name,
-			   const gchar *new_name, CamelException *ex);
-
-static void store_sync (CamelStore *store, gint expunge, CamelException *ex);
-static CamelFolderInfo *get_folder_info (CamelStore *store, const gchar *top,
-					 guint32 flags, CamelException *ex);
-static void free_folder_info (CamelStore *store, CamelFolderInfo *tree);
-
-static gboolean folder_subscribed (CamelStore *store, const gchar *folder_name);
-static void subscribe_folder (CamelStore *store, const gchar *folder_name, CamelException *ex);
-static void unsubscribe_folder (CamelStore *store, const gchar *folder_name, CamelException *ex);
-
-static void noop (CamelStore *store, CamelException *ex);
-
-static gboolean can_refresh_folder (CamelStore *store, CamelFolderInfo *info, CamelException *ex);
-
-static void construct (CamelService *service, CamelSession *session,
-		       CamelProvider *provider, CamelURL *url,
-		       CamelException *ex);
-
-static gint store_setv (CamelObject *object, CamelException *ex, CamelArgV *args);
-static gint store_getv (CamelObject *object, CamelException *ex, CamelArgGetV *args);
+static gpointer camel_store_parent_class;
 
+/**
+ * ignore_no_such_table_exception:
+ * Clears the exception 'ex' when it's the 'no such table' exception.
+ **/
 static void
-camel_store_class_init (CamelStoreClass *camel_store_class)
+ignore_no_such_table_exception (CamelException *ex)
 {
-	CamelObjectClass *camel_object_class = CAMEL_OBJECT_CLASS (camel_store_class);
-	CamelServiceClass *camel_service_class = CAMEL_SERVICE_CLASS(camel_store_class);
-
-	parent_class = CAMEL_SERVICE_CLASS (camel_type_get_global_classfuncs (camel_service_get_type ()));
-
-	/* virtual method definition */
-	camel_store_class->hash_folder_name = g_str_hash;
-	camel_store_class->compare_folder_name = g_str_equal;
-	camel_store_class->get_folder = get_folder;
-	camel_store_class->get_inbox = get_inbox;
-	camel_store_class->get_trash = get_trash;
-	camel_store_class->get_junk = get_junk;
-	camel_store_class->create_folder = create_folder;
-	camel_store_class->delete_folder = delete_folder;
-	camel_store_class->rename_folder = rename_folder;
-	camel_store_class->sync = store_sync;
-	camel_store_class->get_folder_info = get_folder_info;
-	camel_store_class->free_folder_info = free_folder_info;
-	camel_store_class->folder_subscribed = folder_subscribed;
-	camel_store_class->subscribe_folder = subscribe_folder;
-	camel_store_class->unsubscribe_folder = unsubscribe_folder;
-	camel_store_class->noop = noop;
-	camel_store_class->can_refresh_folder = can_refresh_folder;
-
-	/* virtual method overload */
-	camel_service_class->construct = construct;
-
-	camel_object_class->setv = store_setv;
-	camel_object_class->getv = store_getv;
-
-	camel_object_class_add_event(camel_object_class, "folder_opened", NULL);
-	camel_object_class_add_event(camel_object_class, "folder_created", NULL);
-	camel_object_class_add_event(camel_object_class, "folder_deleted", NULL);
-	camel_object_class_add_event(camel_object_class, "folder_renamed", NULL);
-	camel_object_class_add_event(camel_object_class, "folder_subscribed", NULL);
-	camel_object_class_add_event(camel_object_class, "folder_unsubscribed", NULL);
+	if (ex && camel_exception_is_set (ex) && g_ascii_strncasecmp (camel_exception_get_description (ex), "no such table", 13) == 0)
+		camel_exception_clear (ex);
 }
 
-static void
-camel_store_init (gpointer o)
+static CamelFolder *
+store_get_special (CamelStore *store,
+                   camel_vtrash_folder_t type)
 {
-	CamelStore *store = o;
-	CamelStoreClass *store_class = (CamelStoreClass *)CAMEL_OBJECT_GET_CLASS (o);
-
-	if (store_class->hash_folder_name) {
-		store->folders = camel_object_bag_new(store_class->hash_folder_name,
-						      store_class->compare_folder_name,
-						      (CamelCopyFunc)g_strdup, g_free);
-	} else
-		store->folders = NULL;
+	CamelFolder *folder;
+	GPtrArray *folders;
+	gint i;
 
-	/* set vtrash and vjunk on by default */
-	store->flags = CAMEL_STORE_VTRASH | CAMEL_STORE_VJUNK;
-	store->mode = CAMEL_STORE_READ|CAMEL_STORE_WRITE;
+	folder = camel_vtrash_folder_new(store, type);
+	folders = camel_object_bag_list(store->folders);
+	for (i=0;i<folders->len;i++) {
+		if (!CAMEL_IS_VTRASH_FOLDER(folders->pdata[i]))
+			camel_vee_folder_add_folder((CamelVeeFolder *)folder, (CamelFolder *)folders->pdata[i]);
+		camel_object_unref (folders->pdata[i]);
+	}
+	g_ptr_array_free(folders, TRUE);
 
-	store->priv = g_malloc0 (sizeof (*store->priv));
-	g_static_rec_mutex_init (&store->priv->folder_lock);
+	return folder;
 }
 
 static void
-camel_store_finalize (CamelObject *object)
+store_finalize (CamelStore *store)
 {
-	CamelStore *store = CAMEL_STORE (object);
-
-	d(printf ("\ncamel_store_finalize called \n"));
-	if (store->folders)
-		camel_object_bag_destroy(store->folders);
+	if (store->folders != NULL)
+		camel_object_bag_destroy (store->folders);
 
 	g_static_rec_mutex_free (&store->priv->folder_lock);
 
-	if (store->cdb_r) {
+	if (store->cdb_r != NULL) {
 		camel_db_close (store->cdb_r);
 		store->cdb_r = NULL;
 	}
 
-	if (store->cdb_w) {
+	if (store->cdb_w != NULL) {
 		camel_db_close (store->cdb_w);
 		store->cdb_w = NULL;
 	}
@@ -173,47 +99,20 @@ camel_store_finalize (CamelObject *object)
 	g_free (store->priv);
 }
 
-CamelType
-camel_store_get_type (void)
-{
-	static CamelType camel_store_type = CAMEL_INVALID_TYPE;
-
-	if (camel_store_type == CAMEL_INVALID_TYPE) {
-		camel_store_type = camel_type_register (CAMEL_SERVICE_TYPE, "CamelStore",
-							sizeof (CamelStore),
-							sizeof (CamelStoreClass),
-							(CamelObjectClassInitFunc) camel_store_class_init,
-							NULL,
-							(CamelObjectInitFunc) camel_store_init,
-							(CamelObjectFinalizeFunc) camel_store_finalize );
-	}
-
-	return camel_store_type;
-}
-
-static gint
-store_setv (CamelObject *object, CamelException *ex, CamelArgV *args)
-{
-	/* CamelStore doesn't currently have anything to set */
-	return CAMEL_OBJECT_CLASS (parent_class)->setv (object, ex, args);
-}
-
-static gint
-store_getv (CamelObject *object, CamelException *ex, CamelArgGetV *args)
-{
-	/* CamelStore doesn't currently have anything to get */
-	return CAMEL_OBJECT_CLASS (parent_class)->getv (object, ex, args);
-}
-
 static void
-construct (CamelService *service, CamelSession *session,
-	   CamelProvider *provider, CamelURL *url,
-	   CamelException *ex)
+store_construct (CamelService *service,
+                 CamelSession *session,
+                 CamelProvider *provider,
+                 CamelURL *url,
+                 CamelException *ex)
 {
+	CamelServiceClass *service_class;
 	CamelStore *store = CAMEL_STORE(service);
 	gchar *store_db_path, *store_path = NULL;
 
-	parent_class->construct(service, session, provider, url, ex);
+	/* Chain up to parent's construct() method. */
+	service_class = CAMEL_SERVICE_CLASS (camel_store_parent_class);
+	service_class->construct(service, session, provider, url, ex);
 	if (camel_exception_is_set (ex))
 		return;
 
@@ -274,15 +173,144 @@ construct (CamelService *service, CamelSession *session,
 }
 
 static CamelFolder *
-get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, CamelException *ex)
+store_get_inbox (CamelStore *store,
+                 CamelException *ex)
+{
+	CamelStoreClass *class;
+
+	/* Assume the inbox's name is "inbox" and open with default flags. */
+	class = CAMEL_STORE_GET_CLASS (store);
+	return class->get_folder (store, "inbox", 0, ex);
+}
+
+static CamelFolder *
+store_get_trash (CamelStore *store,
+                 CamelException *ex)
+{
+	return store_get_special (store, CAMEL_VTRASH_FOLDER_TRASH);
+}
+
+static CamelFolder *
+store_get_junk (CamelStore *store,
+                CamelException *ex)
+{
+	return store_get_special (store, CAMEL_VTRASH_FOLDER_JUNK);
+}
+
+static void
+store_sync (CamelStore *store,
+            gint expunge,
+            CamelException *ex)
 {
-	w(g_warning ("CamelStore::get_folder not implemented for '%s'",
-		     camel_type_to_name (CAMEL_OBJECT_GET_TYPE (store))));
+	GPtrArray *folders;
+	CamelFolder *folder;
+	CamelException x;
+	gint i;
+
+	if (store->folders == NULL)
+		return;
+
+	/* We don't sync any vFolders, that is used to update certain
+	 * vfolder queries mainly, and we're really only interested in
+	 * storing/expunging the physical mails. */
+	camel_exception_init(&x);
+	folders = camel_object_bag_list(store->folders);
+	for (i=0;i<folders->len;i++) {
+		folder = folders->pdata[i];
+		if (!CAMEL_IS_VEE_FOLDER(folder)
+		    && !camel_exception_is_set(&x)) {
+			camel_folder_sync(folder, expunge, &x);
+			ignore_no_such_table_exception (&x);
+		} else if (CAMEL_IS_VEE_FOLDER(folder))
+			camel_vee_folder_sync_headers(folder, NULL); /* Literally don't care of vfolder exceptions */
+		camel_object_unref (folder);
+	}
+	camel_exception_xfer(ex, &x);
+
+	g_ptr_array_free (folders, TRUE);
+}
 
-	camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_INVALID,
-			      _("Cannot get folder: Invalid operation on this store"));
+static void
+store_noop (CamelStore *store,
+            CamelException *ex)
+{
+	/* no-op */
+}
 
-	return NULL;
+static gboolean
+store_can_refresh_folder (CamelStore *store,
+                          CamelFolderInfo *info,
+                          CamelException *ex)
+{
+	return ((info->flags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_INBOX);
+}
+
+static void
+camel_store_class_init (CamelStoreClass *class)
+{
+	CamelObjectClass *camel_object_class;
+	CamelServiceClass *service_class;
+
+	camel_store_parent_class = CAMEL_SERVICE_CLASS (camel_type_get_global_classfuncs (camel_service_get_type ()));
+
+	service_class = CAMEL_SERVICE_CLASS (class);
+	service_class->construct = store_construct;
+
+	class->hash_folder_name = g_str_hash;
+	class->compare_folder_name = g_str_equal;
+	class->get_inbox = store_get_inbox;
+	class->get_trash = store_get_trash;
+	class->get_junk = store_get_junk;
+	class->sync = store_sync;
+	class->noop = store_noop;
+	class->can_refresh_folder = store_can_refresh_folder;
+
+	camel_object_class = CAMEL_OBJECT_CLASS (class);
+	camel_object_class_add_event(camel_object_class, "folder_opened", NULL);
+	camel_object_class_add_event(camel_object_class, "folder_created", NULL);
+	camel_object_class_add_event(camel_object_class, "folder_deleted", NULL);
+	camel_object_class_add_event(camel_object_class, "folder_renamed", NULL);
+	camel_object_class_add_event(camel_object_class, "folder_subscribed", NULL);
+	camel_object_class_add_event(camel_object_class, "folder_unsubscribed", NULL);
+}
+
+static void
+camel_store_init (CamelStore *store)
+{
+	CamelStoreClass *store_class = CAMEL_STORE_GET_CLASS (store);
+
+	if (store_class->hash_folder_name) {
+		store->folders = camel_object_bag_new (
+			store_class->hash_folder_name,
+			store_class->compare_folder_name,
+			(CamelCopyFunc) g_strdup, g_free);
+	} else
+		store->folders = NULL;
+
+	/* set vtrash and vjunk on by default */
+	store->flags = CAMEL_STORE_VTRASH | CAMEL_STORE_VJUNK;
+	store->mode = CAMEL_STORE_READ | CAMEL_STORE_WRITE;
+
+	store->priv = g_malloc0 (sizeof (*store->priv));
+	g_static_rec_mutex_init (&store->priv->folder_lock);
+}
+
+CamelType
+camel_store_get_type (void)
+{
+	static CamelType camel_store_type = CAMEL_INVALID_TYPE;
+
+	if (camel_store_type == CAMEL_INVALID_TYPE) {
+		camel_store_type = camel_type_register (CAMEL_SERVICE_TYPE, "CamelStore",
+							sizeof (CamelStore),
+							sizeof (CamelStoreClass),
+							(CamelObjectClassInitFunc) camel_store_class_init,
+							NULL,
+							(CamelObjectInitFunc) camel_store_init,
+							(CamelObjectFinalizeFunc) store_finalize );
+	}
+
+	return camel_store_type;
 }
 
 /**
@@ -297,13 +325,19 @@ get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, CamelExc
  * Returns: the folder corresponding to the path @folder_name or %NULL.
  **/
 CamelFolder *
-camel_store_get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, CamelException *ex)
+camel_store_get_folder (CamelStore *store,
+                        const gchar *folder_name,
+                        guint32 flags,
+                        CamelException *ex)
 {
+	CamelStoreClass *class;
 	CamelFolder *folder = NULL;
 
 	g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
 	g_return_val_if_fail (folder_name != NULL, NULL);
 
+	class = CAMEL_STORE_GET_CLASS (store);
+
 	/* O_EXCL doesn't make sense if we aren't requesting to also create the folder if it doesn't exist */
 	if (!(flags & CAMEL_STORE_FOLDER_CREATE))
 		flags &= ~CAMEL_STORE_FOLDER_EXCL;
@@ -312,9 +346,10 @@ camel_store_get_folder (CamelStore *store, const gchar *folder_name, guint32 fla
 		/* Try cache first. */
 		folder = camel_object_bag_reserve(store->folders, folder_name);
 		if (folder && (flags & CAMEL_STORE_FOLDER_EXCL)) {
-			camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
-					      _("Cannot create folder '%s': folder exists"),
-					      folder_name);
+			camel_exception_setv (
+				ex, CAMEL_EXCEPTION_SYSTEM,
+				_("Cannot create folder '%s': folder exists"),
+				folder_name);
                         camel_object_bag_abort (store->folders, folder_name);
 			camel_object_unref (folder);
 			return NULL;
@@ -338,11 +373,11 @@ camel_store_get_folder (CamelStore *store, const gchar *folder_name, guint32 fla
 		}
 
 		if ((store->flags & CAMEL_STORE_VTRASH) && strcmp(folder_name, CAMEL_VTRASH_NAME) == 0) {
-			folder = CS_CLASS(store)->get_trash(store, ex);
+			folder = class->get_trash(store, ex);
 		} else if ((store->flags & CAMEL_STORE_VJUNK) && strcmp(folder_name, CAMEL_VJUNK_NAME) == 0) {
-			folder = CS_CLASS(store)->get_junk(store, ex);
+			folder = class->get_junk(store, ex);
 		} else {
-			folder = CS_CLASS (store)->get_folder(store, folder_name, flags, ex);
+			folder = class->get_folder(store, folder_name, flags, ex);
 			if (folder) {
 				CamelVeeFolder *vfolder;
 
@@ -384,19 +419,6 @@ camel_store_get_folder (CamelStore *store, const gchar *folder_name, guint32 fla
 	return folder;
 }
 
-static CamelFolderInfo *
-create_folder (CamelStore *store, const gchar *parent_name,
-	       const gchar *folder_name, CamelException *ex)
-{
-	w(g_warning ("CamelStore::create_folder not implemented for '%s'",
-		     camel_type_to_name (CAMEL_OBJECT_GET_TYPE (store))));
-
-	camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_INVALID,
-			      _("Cannot create folder: Invalid operation on this store"));
-
-	return NULL;
-}
-
 /**
  * camel_store_create_folder:
  * @store: a #CamelStore object
@@ -411,21 +433,32 @@ create_folder (CamelStore *store, const gchar *parent_name,
  * free with #camel_store_free_folder_info, or %NULL.
  **/
 CamelFolderInfo *
-camel_store_create_folder (CamelStore *store, const gchar *parent_name,
-			   const gchar *folder_name, CamelException *ex)
+camel_store_create_folder (CamelStore *store,
+                           const gchar *parent_name,
+                           const gchar *folder_name,
+                           CamelException *ex)
 {
+	CamelStoreClass *class;
 	CamelFolderInfo *fi;
 
+	g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
+	g_return_val_if_fail (folder_name != NULL, NULL);
+
+	class = CAMEL_STORE_GET_CLASS (store);
+	g_return_val_if_fail (class->create_folder != NULL, NULL);
+
 	if ((parent_name == NULL || parent_name[0] == 0)
 	    && (((store->flags & CAMEL_STORE_VTRASH) && strcmp(folder_name, CAMEL_VTRASH_NAME) == 0)
 		|| ((store->flags & CAMEL_STORE_VJUNK) && strcmp(folder_name, CAMEL_VJUNK_NAME) == 0))) {
-		camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_INVALID,
-				     _("Cannot create folder: %s: folder exists"), folder_name);
+		camel_exception_setv (
+			ex, CAMEL_EXCEPTION_STORE_INVALID,
+			_("Cannot create folder: %s: folder exists"),
+			folder_name);
 		return NULL;
 	}
 
 	CAMEL_STORE_LOCK(store, folder_lock);
-	fi = CS_CLASS (store)->create_folder (store, parent_name, folder_name, ex);
+	fi = class->create_folder (store, parent_name, folder_name, ex);
 	CAMEL_STORE_UNLOCK(store, folder_lock);
 
 	return fi;
@@ -460,13 +493,6 @@ cs_delete_cached_folder(CamelStore *store, const gchar *folder_name)
 	}
 }
 
-static void
-delete_folder (CamelStore *store, const gchar *folder_name, CamelException *ex)
-{
-	w(g_warning ("CamelStore::delete_folder not implemented for '%s'",
-		     camel_type_to_name (CAMEL_OBJECT_GET_TYPE (store))));
-}
-
 /**
  * camel_store_delete_folder:
  * @store: a #CamelStore object
@@ -476,15 +502,26 @@ delete_folder (CamelStore *store, const gchar *folder_name, CamelException *ex)
  * Deletes the named folder. The folder must be empty.
  **/
 void
-camel_store_delete_folder (CamelStore *store, const gchar *folder_name, CamelException *ex)
+camel_store_delete_folder (CamelStore *store,
+                           const gchar *folder_name,
+                           CamelException *ex)
 {
+	CamelStoreClass *class;
 	CamelException local;
 
+	g_return_if_fail (CAMEL_IS_STORE (store));
+	g_return_if_fail (folder_name != NULL);
+
+	class = CAMEL_STORE_GET_CLASS (store);
+	g_return_if_fail (class->delete_folder != NULL);
+
 	/* TODO: should probably be a parameter/bit on the storeinfo */
 	if (((store->flags & CAMEL_STORE_VTRASH) && strcmp(folder_name, CAMEL_VTRASH_NAME) == 0)
 	    || ((store->flags & CAMEL_STORE_VJUNK) && strcmp(folder_name, CAMEL_VJUNK_NAME) == 0)) {
-		camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
-				     _("Cannot delete folder: %s: Invalid operation"), folder_name);
+		camel_exception_setv (
+			ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
+			_("Cannot delete folder: %s: Invalid operation"),
+			folder_name);
 		return;
 	}
 
@@ -492,7 +529,7 @@ camel_store_delete_folder (CamelStore *store, const gchar *folder_name, CamelExc
 
 	CAMEL_STORE_LOCK(store, folder_lock);
 
-	CS_CLASS(store)->delete_folder(store, folder_name, &local);
+	class->delete_folder(store, folder_name, &local);
 
 	/* ignore 'no such table' errors */
 	if (camel_exception_is_set (&local) && camel_exception_get_description (&local) &&
@@ -501,21 +538,12 @@ camel_store_delete_folder (CamelStore *store, const gchar *folder_name, CamelExc
 
 	if (!camel_exception_is_set(&local))
 		cs_delete_cached_folder(store, folder_name);
-	else {
+	else
 		camel_exception_xfer(ex, &local);
-		printf("excep: %s\n", camel_exception_get_description (ex));
-	}
 
 	CAMEL_STORE_UNLOCK(store, folder_lock);
 }
 
-static void
-rename_folder (CamelStore *store, const gchar *old_name, const gchar *new_name, CamelException *ex)
-{
-	w(g_warning ("CamelStore::rename_folder not implemented for '%s'",
-		     camel_type_to_name (CAMEL_OBJECT_GET_TYPE (store))));
-}
-
 /**
  * camel_store_rename_folder:
  * @store: a #CamelStore object
@@ -526,22 +554,33 @@ rename_folder (CamelStore *store, const gchar *old_name, const gchar *new_name,
  * Rename a named folder to a new name.
  **/
 void
-camel_store_rename_folder (CamelStore *store, const gchar *old_namein, const gchar *new_name, CamelException *ex)
+camel_store_rename_folder (CamelStore *store,
+                           const gchar *old_namein,
+                           const gchar *new_name,
+                           CamelException *ex)
 {
+	CamelStoreClass *class;
 	CamelFolder *folder;
 	gint i, oldlen, namelen;
 	GPtrArray *folders = NULL;
 	gchar *old_name;
 
-	d(printf("store rename folder %s '%s' '%s'\n", ((CamelService *)store)->url->protocol, old_name, new_name));
+	g_return_if_fail (CAMEL_IS_STORE (store));
+	g_return_if_fail (old_namein != NULL);
+	g_return_if_fail (new_name != NULL);
+
+	class = CAMEL_STORE_GET_CLASS (store);
+	g_return_if_fail (class->rename_folder != NULL);
 
 	if (strcmp(old_namein, new_name) == 0)
 		return;
 
 	if (((store->flags & CAMEL_STORE_VTRASH) && strcmp(old_namein, CAMEL_VTRASH_NAME) == 0)
 	    || ((store->flags & CAMEL_STORE_VJUNK) && strcmp(old_namein, CAMEL_VJUNK_NAME) == 0)) {
-		camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
-				     _("Cannot rename folder: %s: Invalid operation"), old_namein);
+		camel_exception_setv (
+			ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
+			_("Cannot rename folder: %s: Invalid operation"),
+			old_namein);
 		return;
 	}
 
@@ -574,7 +613,7 @@ camel_store_rename_folder (CamelStore *store, const gchar *old_namein, const gch
 	}
 
 	/* Now try the real rename (will emit renamed event) */
-	CS_CLASS (store)->rename_folder (store, old_name, new_name, ex);
+	class->rename_folder (store, old_name, new_name, ex);
 
 	/* If it worked, update all open folders/unlock them */
 	if (folders) {
@@ -601,10 +640,10 @@ camel_store_rename_folder (CamelStore *store, const gchar *old_namein, const gch
 				flags |= CAMEL_STORE_FOLDER_INFO_SUBSCRIBED;
 
 			reninfo.old_base = (gchar *)old_name;
-			reninfo.new = ((CamelStoreClass *)((CamelObject *)store)->klass)->get_folder_info(store, new_name, flags, ex);
+			reninfo.new = class->get_folder_info(store, new_name, flags, ex);
 			if (reninfo.new != NULL) {
 				camel_object_trigger_event (store, "folder_renamed", &reninfo);
-				((CamelStoreClass *)((CamelObject *)store)->klass)->free_folder_info(store, reninfo.new);
+				class->free_folder_info(store, reninfo.new);
 			}
 		} else {
 			/* Failed, just unlock our folders for re-use */
@@ -622,15 +661,6 @@ camel_store_rename_folder (CamelStore *store, const gchar *old_namein, const gch
 	g_free(old_name);
 }
 
-static CamelFolder *
-get_inbox (CamelStore *store, CamelException *ex)
-{
-	/* Default: assume the inbox's name is "inbox"
-	 * and open with default flags.
-	 */
-	return CS_CLASS (store)->get_folder (store, "inbox", 0, ex);
-}
-
 /**
  * camel_store_get_inbox:
  * @store: a #CamelStore object
@@ -640,48 +670,24 @@ get_inbox (CamelStore *store, CamelException *ex)
  * or %NULL if no such folder exists.
  **/
 CamelFolder *
-camel_store_get_inbox (CamelStore *store, CamelException *ex)
+camel_store_get_inbox (CamelStore *store,
+                       CamelException *ex)
 {
+	CamelStoreClass *class;
 	CamelFolder *folder;
 
-	CAMEL_STORE_LOCK(store, folder_lock);
-	folder = CS_CLASS (store)->get_inbox (store, ex);
-	CAMEL_STORE_UNLOCK(store, folder_lock);
+	g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
 
-	return folder;
-}
+	class = CAMEL_STORE_GET_CLASS (store);
+	g_return_val_if_fail (class->get_inbox != NULL, NULL);
 
-static CamelFolder *
-get_special(CamelStore *store, camel_vtrash_folder_t type)
-{
-	CamelFolder *folder;
-	GPtrArray *folders;
-	gint i;
-
-	folder = camel_vtrash_folder_new(store, type);
-	folders = camel_object_bag_list(store->folders);
-	for (i=0;i<folders->len;i++) {
-		if (!CAMEL_IS_VTRASH_FOLDER(folders->pdata[i]))
-			camel_vee_folder_add_folder((CamelVeeFolder *)folder, (CamelFolder *)folders->pdata[i]);
-		camel_object_unref (folders->pdata[i]);
-	}
-	g_ptr_array_free(folders, TRUE);
+	CAMEL_STORE_LOCK (store, folder_lock);
+	folder = class->get_inbox (store, ex);
+	CAMEL_STORE_UNLOCK (store, folder_lock);
 
 	return folder;
 }
 
-static CamelFolder *
-get_trash(CamelStore *store, CamelException *ex)
-{
-	return get_special(store, CAMEL_VTRASH_FOLDER_TRASH);
-}
-
-static CamelFolder *
-get_junk(CamelStore *store, CamelException *ex)
-{
-	return get_special(store, CAMEL_VTRASH_FOLDER_JUNK);
-}
-
 /**
  * camel_store_get_trash:
  * @store: a #CamelStore object
@@ -691,12 +697,21 @@ get_junk(CamelStore *store, CamelException *ex)
  * %NULL if no such folder exists.
  **/
 CamelFolder *
-camel_store_get_trash (CamelStore *store, CamelException *ex)
+camel_store_get_trash (CamelStore *store,
+                       CamelException *ex)
 {
-	if ((store->flags & CAMEL_STORE_VTRASH) == 0)
-		return CS_CLASS(store)->get_trash(store, ex);
-	else
-		return camel_store_get_folder(store, CAMEL_VTRASH_NAME, 0, ex);
+	g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
+
+	if ((store->flags & CAMEL_STORE_VTRASH) == 0) {
+		CamelStoreClass *class;
+
+		class = CAMEL_STORE_GET_CLASS (store);
+		g_return_val_if_fail (class->get_trash != NULL, NULL);
+
+		return class->get_trash (store, ex);
+	}
+
+	return camel_store_get_folder (store, CAMEL_VTRASH_NAME, 0, ex);
 }
 
 /**
@@ -708,51 +723,21 @@ camel_store_get_trash (CamelStore *store, CamelException *ex)
  * %NULL if no such folder exists.
  **/
 CamelFolder *
-camel_store_get_junk (CamelStore *store, CamelException *ex)
+camel_store_get_junk (CamelStore *store,
+                      CamelException *ex)
 {
-	if ((store->flags & CAMEL_STORE_VJUNK) == 0)
-		return CS_CLASS(store)->get_junk(store, ex);
-	else
-		return camel_store_get_folder(store, CAMEL_VJUNK_NAME, 0, ex);
-}
+	g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
 
-/**
- * ignore_no_such_table_exception:
- * Clears the exception 'ex' when it's the 'no such table' exception.
- **/
-static void
-ignore_no_such_table_exception (CamelException *ex)
-{
-	if (ex && camel_exception_is_set (ex) && g_ascii_strncasecmp (camel_exception_get_description (ex), "no such table", 13) == 0)
-		camel_exception_clear (ex);
-}
+	if ((store->flags & CAMEL_STORE_VJUNK) == 0) {
+		CamelStoreClass *class;
 
-static void
-store_sync (CamelStore *store, gint expunge, CamelException *ex)
-{
-	if (store->folders) {
-		GPtrArray *folders;
-		CamelFolder *folder;
-		CamelException x;
-		gint i;
-
-		/* we don't sync any vFolders, that is used to update certain vfolder queries mainly,
-		   and we're really only interested in storing/expunging the physical mails */
-		camel_exception_init(&x);
-		folders = camel_object_bag_list(store->folders);
-		for (i=0;i<folders->len;i++) {
-			folder = folders->pdata[i];
-			if (!CAMEL_IS_VEE_FOLDER(folder)
-			    && !camel_exception_is_set(&x)) {
-				camel_folder_sync(folder, expunge, &x);
-				ignore_no_such_table_exception (&x);
-			} else if (CAMEL_IS_VEE_FOLDER(folder))
-				camel_vee_folder_sync_headers(folder, NULL); /* Literally don't care of vfolder exceptions */
-			camel_object_unref (folder);
-		}
-		camel_exception_xfer(ex, &x);
-		g_ptr_array_free(folders, TRUE);
+		class = CAMEL_STORE_GET_CLASS (store);
+		g_return_val_if_fail (class->get_junk != NULL, NULL);
+
+		return class->get_junk (store, ex);
 	}
+
+	return camel_store_get_folder (store, CAMEL_VJUNK_NAME, 0, ex);
 }
 
 /**
@@ -765,24 +750,27 @@ store_sync (CamelStore *store, gint expunge, CamelException *ex)
  * folders with the real store.
  **/
 void
-camel_store_sync(CamelStore *store, gint expunge, CamelException *ex)
+camel_store_sync (CamelStore *store,
+                  gint expunge,
+                  CamelException *ex)
 {
+	CamelStoreClass *class;
+
 	g_return_if_fail (CAMEL_IS_STORE (store));
 
-	CS_CLASS(store)->sync(store, expunge, ex);
-}
+	class = CAMEL_STORE_GET_CLASS (store);
+	g_return_if_fail (class->sync != NULL);
 
-static CamelFolderInfo *
-get_folder_info (CamelStore *store, const gchar *top, guint32 flags, CamelException *ex)
-{
-	w(g_warning ("CamelStore::get_folder_info not implemented for '%s'",
-		     camel_type_to_name (CAMEL_OBJECT_GET_TYPE (store))));
-
-	return NULL;
+	class->sync (store, expunge, ex);
 }
 
 static void
-add_special_info (CamelStore *store, CamelFolderInfo *info, const gchar *name, const gchar *translated, gboolean unread_count, guint32 flags)
+add_special_info (CamelStore *store,
+                  CamelFolderInfo *info,
+                  const gchar *name,
+                  const gchar *translated,
+                  gboolean unread_count,
+                  guint32 flags)
 {
 	CamelFolderInfo *fi, *vinfo, *parent;
 	gchar *uri, *path;
@@ -839,7 +827,7 @@ add_special_info (CamelStore *store, CamelFolderInfo *info, const gchar *name, c
 }
 
 static void
-dump_fi(CamelFolderInfo *fi, gint depth)
+dump_fi (CamelFolderInfo *fi, gint depth)
 {
 	gchar *s;
 
@@ -886,13 +874,20 @@ dump_fi(CamelFolderInfo *fi, gint depth)
  * #camel_store_free_folder_info, or %NULL.
  **/
 CamelFolderInfo *
-camel_store_get_folder_info(CamelStore *store, const gchar *top, guint32 flags, CamelException *ex)
+camel_store_get_folder_info (CamelStore *store,
+                             const gchar *top,
+                             guint32 flags,
+                             CamelException *ex)
 {
+	CamelStoreClass *class;
 	CamelFolderInfo *info;
 
 	g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
 
-	info = CS_CLASS (store)->get_folder_info (store, top, flags, ex);
+	class = CAMEL_STORE_GET_CLASS (store);
+	g_return_val_if_fail (class->get_folder_info != NULL, NULL);
+
+	info = class->get_folder_info (store, top, flags, ex);
 
 	if (info && (top == NULL || *top == '\0') && (flags & CAMEL_STORE_FOLDER_INFO_NO_VIRTUAL) == 0) {
 		if (info->uri && (store->flags & CAMEL_STORE_VTRASH))
@@ -914,13 +909,6 @@ camel_store_get_folder_info(CamelStore *store, const gchar *top, guint32 flags,
 	return info;
 }
 
-static void
-free_folder_info (CamelStore *store, CamelFolderInfo *fi)
-{
-	w(g_warning ("CamelStore::free_folder_info not implemented for '%s'",
-		     camel_type_to_name (CAMEL_OBJECT_GET_TYPE (store))));
-}
-
 /**
  * camel_store_free_folder_info:
  * @store: a #CamelStore object
@@ -930,14 +918,20 @@ free_folder_info (CamelStore *store, CamelFolderInfo *fi)
  * nothing is done, the routine simply returns.
  **/
 void
-camel_store_free_folder_info (CamelStore *store, CamelFolderInfo *fi)
+camel_store_free_folder_info (CamelStore *store,
+                              CamelFolderInfo *fi)
 {
+	CamelStoreClass *class;
+
 	g_return_if_fail (CAMEL_IS_STORE (store));
 
-	if (!fi)
+	if (fi == NULL)
 		return;
 
-	CS_CLASS (store)->free_folder_info (store, fi);
+	class = CAMEL_STORE_GET_CLASS (store);
+	g_return_if_fail (class->free_folder_info != NULL);
+
+	class->free_folder_info (store, fi);
 }
 
 /**
@@ -949,7 +943,8 @@ camel_store_free_folder_info (CamelStore *store, CamelFolderInfo *fi)
  * of the data.
  **/
 void
-camel_store_free_folder_info_full (CamelStore *store, CamelFolderInfo *fi)
+camel_store_free_folder_info_full (CamelStore *store,
+                                   CamelFolderInfo *fi)
 {
 	camel_folder_info_free (fi);
 }
@@ -962,7 +957,8 @@ camel_store_free_folder_info_full (CamelStore *store, CamelFolderInfo *fi)
  * An implementation for #CamelStore::free_folder_info. Does nothing.
  **/
 void
-camel_store_free_folder_info_nop (CamelStore *store, CamelFolderInfo *fi)
+camel_store_free_folder_info_nop (CamelStore *store,
+                                  CamelFolderInfo *fi)
 {
 	;
 }
@@ -976,7 +972,7 @@ camel_store_free_folder_info_nop (CamelStore *store, CamelFolderInfo *fi)
 void
 camel_folder_info_free (CamelFolderInfo *fi)
 {
-	if (fi) {
+	if (fi != NULL) {
 		camel_folder_info_free (fi->next);
 		camel_folder_info_free (fi->child);
 		g_free (fi->name);
@@ -1000,7 +996,8 @@ camel_folder_info_new (void)
 }
 
 static gint
-folder_info_cmp (gconstpointer ap, gconstpointer bp)
+folder_info_cmp (gconstpointer ap,
+                 gconstpointer bp)
 {
 	const CamelFolderInfo *a = ((CamelFolderInfo **)ap)[0];
 	const CamelFolderInfo *b = ((CamelFolderInfo **)bp)[0];
@@ -1030,8 +1027,10 @@ folder_info_cmp (gconstpointer ap, gconstpointer bp)
  * Returns: the top level of the tree of linked folder info.
  **/
 CamelFolderInfo *
-camel_folder_info_build (GPtrArray *folders, const gchar *namespace,
-			 gchar separator, gboolean short_names)
+camel_folder_info_build (GPtrArray *folders,
+                         const gchar *namespace,
+                         gchar separator,
+                         gboolean short_names)
 {
 	CamelFolderInfo *fi, *pfi, *top = NULL, *tail = NULL;
 	GHashTable *hash;
@@ -1133,7 +1132,8 @@ camel_folder_info_build (GPtrArray *folders, const gchar *namespace,
 }
 
 static CamelFolderInfo *
-folder_info_clone_rec(CamelFolderInfo *fi, CamelFolderInfo *parent)
+folder_info_clone_rec (CamelFolderInfo *fi,
+                       CamelFolderInfo *parent)
 {
 	CamelFolderInfo *info;
 
@@ -1167,7 +1167,7 @@ folder_info_clone_rec(CamelFolderInfo *fi, CamelFolderInfo *parent)
  * Returns: the cloned #CamelFolderInfo tree.
  **/
 CamelFolderInfo *
-camel_folder_info_clone(CamelFolderInfo *fi)
+camel_folder_info_clone (CamelFolderInfo *fi)
 {
 	if (fi == NULL)
 		return NULL;
@@ -1186,16 +1186,9 @@ camel_folder_info_clone(CamelFolderInfo *fi)
 gboolean
 camel_store_supports_subscriptions (CamelStore *store)
 {
-	return (store->flags & CAMEL_STORE_SUBSCRIPTIONS);
-}
-
-static gboolean
-folder_subscribed(CamelStore *store, const gchar *folder_name)
-{
-	w(g_warning ("CamelStore::folder_subscribed not implemented for '%s'",
-		     camel_type_to_name (CAMEL_OBJECT_GET_TYPE (store))));
+	g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
 
-	return FALSE;
+	return (store->flags & CAMEL_STORE_SUBSCRIPTIONS);
 }
 
 /**
@@ -1208,29 +1201,26 @@ folder_subscribed(CamelStore *store, const gchar *folder_name)
  * Returns: %TRUE if the folder has been subscribed to or %FALSE otherwise
  **/
 gboolean
-camel_store_folder_subscribed(CamelStore *store, const gchar *folder_name)
+camel_store_folder_subscribed (CamelStore *store,
+                               const gchar *folder_name)
 {
+	CamelStoreClass *class;
 	gboolean ret;
 
 	g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
+	g_return_val_if_fail (folder_name != NULL, FALSE);
 	g_return_val_if_fail (store->flags & CAMEL_STORE_SUBSCRIPTIONS, FALSE);
 
-	CAMEL_STORE_LOCK(store, folder_lock);
-
-	ret = CS_CLASS (store)->folder_subscribed (store, folder_name);
+	class = CAMEL_STORE_GET_CLASS (store);
+	g_return_val_if_fail (class->folder_subscribed != NULL, FALSE);
 
-	CAMEL_STORE_UNLOCK(store, folder_lock);
+	CAMEL_STORE_LOCK (store, folder_lock);
+	ret = class->folder_subscribed (store, folder_name);
+	CAMEL_STORE_UNLOCK (store, folder_lock);
 
 	return ret;
 }
 
-static void
-subscribe_folder(CamelStore *store, const gchar *folder_name, CamelException *ex)
-{
-	w(g_warning ("CamelStore::subscribe_folder not implemented for '%s'",
-		     camel_type_to_name (CAMEL_OBJECT_GET_TYPE (store))));
-}
-
 /**
  * camel_store_subscribe_folder:
  * @store: a #CamelStore object
@@ -1240,23 +1230,22 @@ subscribe_folder(CamelStore *store, const gchar *folder_name, CamelException *ex
  * Subscribe to the folder described by @folder_name.
  **/
 void
-camel_store_subscribe_folder(CamelStore *store, const gchar *folder_name, CamelException *ex)
+camel_store_subscribe_folder (CamelStore *store,
+                              const gchar *folder_name,
+                              CamelException *ex)
 {
+	CamelStoreClass *class;
+
 	g_return_if_fail (CAMEL_IS_STORE (store));
+	g_return_if_fail (folder_name != NULL);
 	g_return_if_fail (store->flags & CAMEL_STORE_SUBSCRIPTIONS);
 
-	CAMEL_STORE_LOCK(store, folder_lock);
-
-	CS_CLASS (store)->subscribe_folder (store, folder_name, ex);
+	class = CAMEL_STORE_GET_CLASS (store);
+	g_return_if_fail (class->subscribe_folder != NULL);
 
-	CAMEL_STORE_UNLOCK(store, folder_lock);
-}
-
-static void
-unsubscribe_folder(CamelStore *store, const gchar *folder_name, CamelException *ex)
-{
-	w(g_warning ("CamelStore::unsubscribe_folder not implemented for '%s'",
-		     camel_type_to_name (CAMEL_OBJECT_GET_TYPE (store))));
+	CAMEL_STORE_LOCK (store, folder_lock);
+	class->subscribe_folder (store, folder_name, ex);
+	CAMEL_STORE_UNLOCK (store, folder_lock);
 }
 
 /**
@@ -1268,32 +1257,32 @@ unsubscribe_folder(CamelStore *store, const gchar *folder_name, CamelException *
  * Unsubscribe from the folder described by @folder_name.
  **/
 void
-camel_store_unsubscribe_folder(CamelStore *store, const gchar *folder_name, CamelException *ex)
+camel_store_unsubscribe_folder (CamelStore *store,
+                                const gchar *folder_name,
+                                CamelException *ex)
 {
+	CamelStoreClass *class;
 	CamelException local;
 
 	g_return_if_fail (CAMEL_IS_STORE (store));
+	g_return_if_fail (folder_name != NULL);
 	g_return_if_fail (store->flags & CAMEL_STORE_SUBSCRIPTIONS);
 
-	camel_exception_init(&local);
+	class = CAMEL_STORE_GET_CLASS (store);
+	g_return_if_fail (class->unsubscribe_folder != NULL);
 
-	CAMEL_STORE_LOCK(store, folder_lock);
+	camel_exception_init (&local);
 
-	CS_CLASS (store)->unsubscribe_folder (store, folder_name, ex);
+	CAMEL_STORE_LOCK (store, folder_lock);
 
-	if (!camel_exception_is_set(&local))
-		cs_delete_cached_folder(store, folder_name);
-	else
-		camel_exception_xfer(ex, &local);
+	class->unsubscribe_folder (store, folder_name, ex);
 
-	CAMEL_STORE_UNLOCK(store, folder_lock);
-}
+	if (!camel_exception_is_set (&local))
+		cs_delete_cached_folder (store, folder_name);
+	else
+		camel_exception_xfer (ex, &local);
 
-static void
-noop (CamelStore *store, CamelException *ex)
-{
-	/* no-op */
-	;
+	CAMEL_STORE_UNLOCK (store, folder_lock);
 }
 
 /**
@@ -1304,9 +1293,17 @@ noop (CamelStore *store, CamelException *ex)
  * Pings @store so that its connection doesn't timeout.
  **/
 void
-camel_store_noop (CamelStore *store, CamelException *ex)
+camel_store_noop (CamelStore *store,
+                  CamelException *ex)
 {
-	CS_CLASS (store)->noop (store, ex);
+	CamelStoreClass *class;
+
+	g_return_if_fail (CAMEL_IS_STORE (store));
+
+	class = CAMEL_STORE_GET_CLASS (store);
+	g_return_if_fail (class->noop != NULL);
+
+	class->noop (store, ex);
 }
 
 /**
@@ -1315,13 +1312,16 @@ camel_store_noop (CamelStore *store, CamelException *ex)
  * @uri0: a folder uri
  * @uri1: another folder uri
  *
- * Compares 2 folder uris to check that they are equal.
+ * Compares two folder uris to check that they are equal.
  *
  * Returns: %TRUE if they are equal or %FALSE otherwise
  **/
 gint
-camel_store_folder_uri_equal (CamelStore *store, const gchar *uri0, const gchar *uri1)
+camel_store_folder_uri_equal (CamelStore *store,
+                              const gchar *uri0,
+                              const gchar *uri1)
 {
+	CamelStoreClass *class;
 	CamelProvider *provider;
 	CamelURL *url0, *url1;
 	gint equal;
@@ -1329,6 +1329,9 @@ camel_store_folder_uri_equal (CamelStore *store, const gchar *uri0, const gchar
 	g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
 	g_return_val_if_fail (uri0 && uri1, FALSE);
 
+	class = CAMEL_STORE_GET_CLASS (store);
+	g_return_val_if_fail (class->compare_folder_name != NULL, FALSE);
+
 	provider = ((CamelService *) store)->provider;
 
 	if (!(url0 = camel_url_new (uri0, NULL)))
@@ -1356,7 +1359,7 @@ camel_store_folder_uri_equal (CamelStore *store, const gchar *uri0, const gchar
 		if (name1 == NULL)
 			g_warning("URI is badly formed, missing folder name: %s", uri1);
 
-		equal = name0 && name1 && CS_CLASS (store)->compare_folder_name (name0, name1);
+		equal = name0 && name1 && class->compare_folder_name (name0, name1);
 	}
 
 	camel_url_free (url0);
@@ -1365,12 +1368,6 @@ camel_store_folder_uri_equal (CamelStore *store, const gchar *uri0, const gchar
 	return equal;
 }
 
-static gboolean
-can_refresh_folder (CamelStore *store, CamelFolderInfo *info, CamelException *ex)
-{
-	return ((info->flags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_INBOX);
-}
-
 /**
  * camel_store_can_refresh_folder
  * @store: a #CamelStore
@@ -1387,10 +1384,17 @@ can_refresh_folder (CamelStore *store, CamelFolderInfo *info, CamelException *ex
  * Since: 2.22
  **/
 gboolean
-camel_store_can_refresh_folder (CamelStore *store, CamelFolderInfo *info, CamelException *ex)
+camel_store_can_refresh_folder (CamelStore *store,
+                                CamelFolderInfo *info,
+                                CamelException *ex)
 {
-	g_return_val_if_fail (store != NULL, FALSE);
+	CamelStoreClass *class;
+
+	g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
 	g_return_val_if_fail (info != NULL, FALSE);
 
-	return CS_CLASS (store)->can_refresh_folder (store, info, ex);
+	class = CAMEL_STORE_GET_CLASS (store);
+	g_return_val_if_fail (class->can_refresh_folder != NULL, FALSE);
+
+	return class->can_refresh_folder (store, info, ex);
 }
diff --git a/camel/camel-store.h b/camel/camel-store.h
index a19ede0..da4cf6b 100644
--- a/camel/camel-store.h
+++ b/camel/camel-store.h
@@ -41,6 +41,8 @@
 #define CAMEL_STORE(obj)     (CAMEL_CHECK_CAST((obj), CAMEL_STORE_TYPE, CamelStore))
 #define CAMEL_STORE_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_STORE_TYPE, CamelStoreClass))
 #define CAMEL_IS_STORE(o)    (CAMEL_CHECK_TYPE((o), CAMEL_STORE_TYPE))
+#define CAMEL_STORE_GET_CLASS(obj) \
+	((CamelStoreClass *) CAMEL_OBJECT_GET_CLASS (obj))
 
 G_BEGIN_DECLS
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]