[evolution-data-server/camel-gobject: 67/67] Merge branch 'master' into camel-gobject.



commit 8626dd31f8d20d4a608465319a8d5ca6d9953ea6
Merge: 63ffa6a f9a83a2
Author: Matthew Barnes <mbarnes redhat com>
Date:   Sun Dec 27 00:09:15 2009 -0500

    Merge branch 'master' into camel-gobject.

 NEWS                                               |  100 ++
 addressbook/backends/ldap/e-book-backend-ldap.c    |   48 +-
 addressbook/libebook/Makefile.am                   |    6 +-
 addressbook/libebook/e-book.c                      |   75 +-
 addressbook/libebook/e-error.h                     |    8 +-
 addressbook/libedata-book/Makefile.am              |    1 +
 addressbook/libedata-book/e-data-book-factory.c    |   19 +-
 addressbook/libedata-book/e-data-book.c            |   62 +-
 calendar/backends/caldav/e-cal-backend-caldav.c    |   96 +-
 .../backends/contacts/e-cal-backend-contacts.c     |   27 -
 calendar/backends/file/e-cal-backend-file.c        |   45 -
 calendar/backends/google/e-cal-backend-google.c    |   49 -
 .../groupwise/e-cal-backend-groupwise-utils.c      |   11 +-
 .../backends/groupwise/e-cal-backend-groupwise.c   |   54 +-
 calendar/backends/http/e-cal-backend-http.c        |  119 +-
 calendar/backends/weather/e-cal-backend-weather.c  |  124 +-
 calendar/libecal/e-cal-util.c                      |    5 +-
 calendar/libecal/e-cal-util.h                      |    1 +
 calendar/libecal/e-cal-view.c                      |    2 +-
 calendar/libecal/e-cal.c                           |   45 +
 calendar/libecal/e-cal.h                           |    2 +
 calendar/libedata-cal/Makefile.am                  |    1 +
 calendar/libedata-cal/e-cal-backend-file-store.c   |    6 +-
 calendar/libedata-cal/e-cal-backend-sync.c         |  108 ++-
 calendar/libedata-cal/e-cal-backend-sync.h         |    5 +-
 calendar/libedata-cal/e-cal-backend.c              |   17 +
 calendar/libedata-cal/e-cal-backend.h              |    2 +
 calendar/libedata-cal/e-data-cal-factory.c         |   18 +-
 calendar/libedata-cal/e-data-cal.c                 |   27 +-
 calendar/libedata-cal/e-data-cal.h                 |    1 +
 calendar/libedata-cal/e-data-cal.xml               |    5 +
 camel/camel-db.c                                   |   18 +-
 camel/camel-folder-summary.c                       |   52 +-
 camel/camel-folder-summary.h                       |    2 +
 camel/camel-gpg-context.c                          |   71 +-
 camel/camel-mime-message.c                         |   15 +-
 camel/camel-mime-part.c                            |   19 +-
 camel/camel-mime-part.h                            |    1 +
 camel/camel-msgport.h                              |    2 +
 camel/camel-net-utils.c                            |   34 +-
 camel/camel-smime-context.c                        |    6 +-
 camel/camel-stream-vfs.c                           |   65 +-
 camel/camel-tcp-stream-ssl.c                       |    6 +
 camel/camel-tcp-stream-ssl.h                       |    3 +
 camel/camel-vee-folder.c                           |   55 +-
 camel/camel-vee-summary.c                          |    5 +-
 camel/providers/groupwise/camel-groupwise-folder.c |   48 +-
 camel/providers/imap/camel-imap-folder.c           |   11 +-
 camel/providers/imapx/camel-imapx-folder.c         |  128 ++-
 camel/providers/imapx/camel-imapx-folder.h         |    9 +-
 camel/providers/imapx/camel-imapx-server.c         |  854 +++++++++----
 camel/providers/imapx/camel-imapx-server.h         |    6 +-
 camel/providers/imapx/camel-imapx-store-summary.c  |   10 +-
 camel/providers/imapx/camel-imapx-store.c          |  346 ++++--
 camel/providers/imapx/camel-imapx-store.h          |    5 +-
 camel/providers/imapx/camel-imapx-stream.c         |    3 +-
 camel/providers/imapx/camel-imapx-tokenise.h       |   79 +-
 camel/providers/imapx/camel-imapx-tokens.txt       |    3 +-
 camel/providers/imapx/camel-imapx-utils.c          |  236 +++--
 camel/providers/imapx/camel-imapx-utils.h          |   10 +-
 camel/providers/imapx/test-imapx.c                 |    7 +-
 configure.ac                                       |    4 +-
 .../addressbook/libebook/libebook-sections.txt     |    1 +
 .../addressbook/libebook/tmpl/e-book.sgml          |    9 +
 docs/reference/camel/camel-sections.txt            |    2 +
 docs/reference/camel/tmpl/camel-block-file.sgml    |    4 +
 .../reference/camel/tmpl/camel-cipher-context.sgml |    1 +
 docs/reference/camel/tmpl/camel-data-wrapper.sgml  |    3 +
 docs/reference/camel/tmpl/camel-file-utils.sgml    |    4 +
 .../reference/camel/tmpl/camel-folder-summary.sgml |   10 +
 docs/reference/camel/tmpl/camel-http-stream.sgml   |    1 +
 docs/reference/camel/tmpl/camel-index.sgml         |    6 +-
 docs/reference/camel/tmpl/camel-mime-parser.sgml   |    1 +
 docs/reference/camel/tmpl/camel-mime-part.sgml     |    5 +-
 docs/reference/camel/tmpl/camel-msgport.sgml       |    1 +
 docs/reference/camel/tmpl/camel-nntp-stream.sgml   |    3 +
 .../camel/tmpl/camel-partition-table.sgml          |   13 +
 .../camel/tmpl/camel-seekable-stream.sgml          |    2 +
 docs/reference/camel/tmpl/camel-stream-buffer.sgml |    2 +
 docs/reference/camel/tmpl/camel-stream-fs.sgml     |    2 +
 docs/reference/camel/tmpl/camel-stream.sgml        |   19 +-
 .../reference/camel/tmpl/camel-tcp-stream-ssl.sgml |    9 +
 docs/reference/camel/tmpl/camel-tcp-stream.sgml    |    1 +
 docs/reference/camel/tmpl/camel-text-index.sgml    |    2 +
 docs/reference/camel/tmpl/camel-unused.sgml        |   10 +
 libedataserver/e-proxy.c                           |   13 +-
 libedataserver/e-time-utils.c                      |   14 +-
 libedataserverui/Makefile.am                       |    2 +
 libedataserverui/e-passwords.c                     |   13 +-
 libedataserverui/e-source-selector.c               |    8 +
 po/es.po                                           |  263 ++--
 po/et.po                                           |  109 +-
 po/nb.po                                           |  345 +++---
 po/ro.po                                           | 1337 +++++++-------------
 po/sl.po                                           |  283 +++--
 95 files changed, 3293 insertions(+), 2407 deletions(-)
---
diff --cc addressbook/libebook/Makefile.am
index 2210723,2210723..0bf19c8
--- a/addressbook/libebook/Makefile.am
+++ b/addressbook/libebook/Makefile.am
@@@ -14,7 -14,7 +14,8 @@@ libebook_1_2_la_CPPFLAGS = 
  	-I$(top_srcdir)/addressbook			\
  	-I$(top_builddir)/addressbook			\
  	-I$(top_builddir)/addressbook/libebook		\
--        $(EVOLUTION_ADDRESSBOOK_CFLAGS)
++	$(EVOLUTION_ADDRESSBOOK_CFLAGS)			\
++	$(CAMEL_CFLAGS)
  
  libebook_1_2_la_SOURCES =				\
  	$(MARSHAL_GENERATED)				\
@@@ -34,7 -34,7 +35,8 @@@
  libebook_1_2_la_LIBADD =					\
  	$(top_builddir)/camel/libcamel-1.2.la			\
  	$(top_builddir)/libedataserver/libedataserver-1.2.la    \
--	$(EVOLUTION_ADDRESSBOOK_LIBS)
++	$(EVOLUTION_ADDRESSBOOK_LIBS)				\
++	$(CAMEL_LIBS)
  
  libebook_1_2_la_LDFLAGS = 							\
  	-version-info $(LIBEBOOK_CURRENT):$(LIBEBOOK_REVISION):$(LIBEBOOK_AGE) $(NO_UNDEFINED)
diff --cc camel/camel-db.c
index aa7b109,b3b1191..22a6dac
--- a/camel/camel-db.c
+++ b/camel/camel-db.c
@@@ -1095,9 -1019,9 +1095,9 @@@ camel_db_get_folder_preview (CamelDB *d
  	 gint ret;
  	 GHashTable *hash = g_hash_table_new (g_str_hash, g_str_equal);
  
- 	 sel_query = sqlite3_mprintf("SELECT uid, preview FROM '%s_preview'", folder_name);
+ 	 sel_query = sqlite3_mprintf("SELECT uid, preview FROM '%q_preview'", folder_name);
  
 -	 ret = camel_db_select (db, sel_query, read_preview_callback, hash, ex);
 +	 ret = camel_db_select (db, sel_query, read_preview_callback, hash, error);
  	 sqlite3_free (sel_query);
  
  	 if (!g_hash_table_size (hash) || ret != 0) {
@@@ -1118,9 -1038,9 +1118,9 @@@ camel_db_write_preview_record (CamelDB 
  	gchar *query;
  	gint ret;
  
- 	query = sqlite3_mprintf("INSERT OR REPLACE INTO '%s_preview' VALUES(%Q,%Q)", folder_name, uid, msg);
+ 	query = sqlite3_mprintf("INSERT OR REPLACE INTO '%q_preview' VALUES(%Q,%Q)", folder_name, uid, msg);
  
 -	ret = camel_db_add_to_transaction (db, query, ex);
 +	ret = camel_db_add_to_transaction (db, query, error);
  	sqlite3_free (query);
  
  	return ret;
@@@ -1232,16 -1140,16 +1232,16 @@@ camel_db_create_message_info_table (Cam
  
  	/* README: It is possible to compress all system flags into a single column and use just as userflags but that makes querying for other applications difficult an d bloats the parsing code. Instead, it is better to bloat the tables. Sqlite should have some optimizations for sparse columns etc. */
  	table_creation_query = sqlite3_mprintf ("CREATE TABLE IF NOT EXISTS %Q (  uid TEXT PRIMARY KEY , flags INTEGER , msg_type INTEGER , read INTEGER , deleted INTEGER , replied INTEGER , important INTEGER , junk INTEGER , attachment INTEGER , dirty INTEGER , size INTEGER , dsent NUMERIC , dreceived NUMERIC , subject TEXT , mail_from TEXT , mail_to TEXT , mail_cc TEXT , mlist TEXT , followup_flag TEXT , followup_completed_on TEXT , followup_due_by TEXT , part TEXT , labels TEXT , usertags TEXT , cinfo TEXT , bdata TEXT, created TEXT, modified TEXT)", folder_name);
 -	ret = camel_db_add_to_transaction (cdb, table_creation_query, ex);
 +	ret = camel_db_add_to_transaction (cdb, table_creation_query, error);
  	sqlite3_free (table_creation_query);
  
- 	table_creation_query = sqlite3_mprintf ("CREATE TABLE IF NOT EXISTS '%s_bodystructure' (  uid TEXT PRIMARY KEY , bodystructure TEXT )", folder_name);
+ 	table_creation_query = sqlite3_mprintf ("CREATE TABLE IF NOT EXISTS '%q_bodystructure' (  uid TEXT PRIMARY KEY , bodystructure TEXT )", folder_name);
 -	ret = camel_db_add_to_transaction (cdb, table_creation_query, ex);
 +	ret = camel_db_add_to_transaction (cdb, table_creation_query, error);
  	sqlite3_free (table_creation_query);
  
  	/* Create message preview table. */
- 	table_creation_query = sqlite3_mprintf ("CREATE TABLE IF NOT EXISTS '%s_preview' (  uid TEXT PRIMARY KEY , preview TEXT)", folder_name);
+ 	table_creation_query = sqlite3_mprintf ("CREATE TABLE IF NOT EXISTS '%q_preview' (  uid TEXT PRIMARY KEY , preview TEXT)", folder_name);
 -	ret = camel_db_add_to_transaction (cdb, table_creation_query, ex);
 +	ret = camel_db_add_to_transaction (cdb, table_creation_query, error);
  	sqlite3_free (table_creation_query);
  
  	/* FIXME: sqlize folder_name before you create the index */
@@@ -1253,8 -1161,8 +1253,8 @@@
  
  	/* INDEX on preview */
  	safe_index = g_strdup_printf("SINDEX-%s-preview", folder_name);
- 	table_creation_query = sqlite3_mprintf ("CREATE INDEX IF NOT EXISTS %Q ON '%s_preview' (uid, preview)", safe_index, folder_name);
+ 	table_creation_query = sqlite3_mprintf ("CREATE INDEX IF NOT EXISTS %Q ON '%q_preview' (uid, preview)", safe_index, folder_name);
 -	ret = camel_db_add_to_transaction (cdb, table_creation_query, ex);
 +	ret = camel_db_add_to_transaction (cdb, table_creation_query, error);
  	g_free (safe_index);
  	sqlite3_free (table_creation_query);
  
@@@ -1503,9 -1403,9 +1503,9 @@@ write_mir (CamelDB *cdb
  	sqlite3_free (ins_query);
  
  	if (ret == 0) {
- 		ins_query = sqlite3_mprintf ("INSERT OR REPLACE INTO '%s_bodystructure' VALUES (%Q, %Q )",
+ 		ins_query = sqlite3_mprintf ("INSERT OR REPLACE INTO '%q_bodystructure' VALUES (%Q, %Q )",
  				folder_name, record->uid, record->bodystructure);
 -		ret = camel_db_add_to_transaction (cdb, ins_query, ex);
 +		ret = camel_db_add_to_transaction (cdb, ins_query, error);
  		sqlite3_free (ins_query);
  	}
  
@@@ -1705,18 -1568,18 +1705,18 @@@ camel_db_delete_uid (CamelDB *cdb
  	gchar *tab;
  	gint ret;
  
 -	camel_db_begin_transaction (cdb, ex);
 +	camel_db_begin_transaction (cdb, error);
  
 -	ret = camel_db_create_deleted_table (cdb, ex);
 +	ret = camel_db_create_deleted_table (cdb, error);
  
  	tab = sqlite3_mprintf ("INSERT OR REPLACE INTO Deletes (uid, mailbox, time) SELECT uid, %Q, strftime(\"%%s\", 'now') FROM %Q WHERE uid = %Q", folder, folder, uid);
 -	ret = camel_db_add_to_transaction (cdb, tab, ex);
 +	ret = camel_db_add_to_transaction (cdb, tab, error);
  	sqlite3_free (tab);
  
 -	ret = camel_db_trim_deleted_table (cdb, ex);
 +	ret = camel_db_trim_deleted_table (cdb, error);
  
- 	tab = sqlite3_mprintf ("DELETE FROM '%s_bodystructure' WHERE uid = %Q", folder, uid);
+ 	tab = sqlite3_mprintf ("DELETE FROM '%q_bodystructure' WHERE uid = %Q", folder, uid);
 -	ret = camel_db_add_to_transaction (cdb, tab, ex);
 +	ret = camel_db_add_to_transaction (cdb, tab, error);
  	sqlite3_free (tab);
  
  	tab = sqlite3_mprintf ("DELETE FROM %Q WHERE uid = %Q", folder, uid);
@@@ -1841,23 -1690,23 +1841,23 @@@ camel_db_clear_folder_summary (CamelDB 
  
  	folders_del = sqlite3_mprintf ("DELETE FROM folders WHERE folder_name = %Q", folder);
  	msginfo_del = sqlite3_mprintf ("DELETE FROM %Q ", folder);
- 	bstruct_del = sqlite3_mprintf ("DELETE FROM '%s_bodystructure' ", folder);
+ 	bstruct_del = sqlite3_mprintf ("DELETE FROM '%q_bodystructure' ", folder);
  
 -	camel_db_begin_transaction (cdb, ex);
 +	camel_db_begin_transaction (cdb, error);
  
 -	ret = camel_db_create_deleted_table (cdb, ex);
 +	ret = camel_db_create_deleted_table (cdb, error);
  
  	tab = sqlite3_mprintf ("INSERT OR REPLACE INTO Deletes (uid, mailbox, time) SELECT uid, %Q, strftime(\"%%s\", 'now') FROM %Q", folder, folder);
 -	ret = camel_db_add_to_transaction (cdb, tab, ex);
 +	ret = camel_db_add_to_transaction (cdb, tab, error);
  	sqlite3_free (tab);
  
 -	ret = camel_db_trim_deleted_table (cdb, ex);
 +	ret = camel_db_trim_deleted_table (cdb, error);
  
 -	camel_db_add_to_transaction (cdb, msginfo_del, ex);
 -	camel_db_add_to_transaction (cdb, folders_del, ex);
 -	camel_db_add_to_transaction (cdb, bstruct_del, ex);
 +	camel_db_add_to_transaction (cdb, msginfo_del, error);
 +	camel_db_add_to_transaction (cdb, folders_del, error);
 +	camel_db_add_to_transaction (cdb, bstruct_del, error);
  
 -	ret = camel_db_end_transaction (cdb, ex);
 +	ret = camel_db_end_transaction (cdb, error);
  
  	sqlite3_free (folders_del);
  	sqlite3_free (msginfo_del);
@@@ -1890,14 -1737,14 +1890,14 @@@ camel_db_delete_folder (CamelDB *cdb
  	sqlite3_free (del);
  
  	del = sqlite3_mprintf ("DROP TABLE %Q ", folder);
 -	ret = camel_db_add_to_transaction (cdb, del, ex);
 +	ret = camel_db_add_to_transaction (cdb, del, error);
  	sqlite3_free (del);
  
- 	del = sqlite3_mprintf ("DROP TABLE '%s_bodystructure' ", folder);
+ 	del = sqlite3_mprintf ("DROP TABLE '%q_bodystructure' ", folder);
 -	ret = camel_db_add_to_transaction (cdb, del, ex);
 +	ret = camel_db_add_to_transaction (cdb, del, error);
  	sqlite3_free (del);
  
 -	ret = camel_db_end_transaction (cdb, ex);
 +	ret = camel_db_end_transaction (cdb, error);
  
  	CAMEL_DB_RELEASE_SQLITE_MEMORY;
  	return ret;
diff --cc camel/camel-folder-summary.c
index 17ebd64,47fc5e6..39e4ee3
--- a/camel/camel-folder-summary.c
+++ b/camel/camel-folder-summary.c
@@@ -5092,9 -4978,62 +5092,9 @@@ camel_message_info_dump (CamelMessageIn
  	printf("From: %s\n", camel_message_info_from(mi));
  	printf("UID: %s\n", camel_message_info_uid(mi));
  	printf("Flags: %04x\n", camel_message_info_flags(mi));
- 	/*camel_content_info_dump(mi->content, 0);*/
+ 	camel_content_info_dump(((CamelMessageInfoBase *) mi)->content, 0);
  }
  
 -static void
 -camel_folder_summary_class_init (CamelFolderSummaryClass *klass)
 -{
 -	camel_folder_summary_parent = camel_type_get_global_classfuncs (camel_object_get_type ());
 -
 -	klass->summary_header_load = summary_header_load;
 -	klass->summary_header_save = summary_header_save;
 -
 -	klass->summary_header_from_db = summary_header_from_db;
 -	klass->summary_header_to_db = summary_header_to_db;
 -	klass->message_info_from_db = message_info_from_db;
 -	klass->message_info_to_db = message_info_to_db;
 -	klass->content_info_from_db = content_info_from_db;
 -	klass->content_info_to_db = content_info_to_db;
 -
 -	klass->message_info_new_from_header  = message_info_new_from_header;
 -	klass->message_info_new_from_parser = message_info_new_from_parser;
 -	klass->message_info_new_from_message = message_info_new_from_message;
 -	klass->message_info_load = message_info_load;
 -	klass->message_info_save = message_info_save;
 -	klass->meta_message_info_save = meta_message_info_save;
 -	klass->message_info_free = message_info_free;
 -	klass->message_info_clone = message_info_clone;
 -	klass->message_info_from_uid = message_info_from_uid;
 -
 -	klass->content_info_new_from_header  = content_info_new_from_header;
 -	klass->content_info_new_from_parser = content_info_new_from_parser;
 -	klass->content_info_new_from_message = content_info_new_from_message;
 -	klass->content_info_load = content_info_load;
 -	klass->content_info_save = content_info_save;
 -	klass->content_info_free = content_info_free;
 -
 -	klass->next_uid_string = next_uid_string;
 -
 -	klass->info_ptr = info_ptr;
 -	klass->info_uint32 = info_uint32;
 -	klass->info_time = info_time;
 -	klass->info_user_flag = info_user_flag;
 -	klass->info_user_tag = info_user_tag;
 -
 -#if 0
 -	klass->info_set_string = info_set_string;
 -	klass->info_set_uint32 = info_set_uint32;
 -	klass->info_set_time = info_set_time;
 -	klass->info_set_ptr = info_set_ptr;
 -#endif
 -	klass->info_set_user_flag = info_set_user_flag;
 -	klass->info_set_user_tag = info_set_user_tag;
 -
 -	klass->info_set_flags = info_set_flags;
 -
 -}
 -
  /* Utils */
  void
  camel_folder_summary_set_need_preview (CamelFolderSummary *summary, gboolean preview)
@@@ -5105,6 -5044,56 +5105,56 @@@
  gboolean
  camel_folder_summary_get_need_preview (CamelFolderSummary *summary)
  {
 -	return _PRIVATE(summary)->need_preview;
 +	return CAMEL_FOLDER_SUMMARY_GET_PRIVATE(summary)->need_preview;
  }
  
+ static gboolean
+ compare_strings (const gchar *str1, const gchar *str2)
+ {
+ 	if (str1 && str2 && !g_ascii_strcasecmp (str1, str2))
+ 		return TRUE;
+ 	else if (!str1 && !str2)
+ 		return TRUE;
+ 	else
+ 		return FALSE;
+ }
+ 
+ static gboolean
+ match_content_type (CamelContentType *info_ctype, CamelContentType *ctype)
+ {
+ 	const gchar *name1, *name2;
+ 
+ 	if (!compare_strings (info_ctype->type, ctype->type))
+ 		return FALSE;
+ 	if (!compare_strings (info_ctype->subtype, ctype->subtype))
+ 		return FALSE;
+ 
+ 	name1 = camel_content_type_param (info_ctype, "name");
+ 	name2 = camel_content_type_param (ctype, "name");
+ 	if (!compare_strings (name1, name2))
+ 		return FALSE;
+ 
+ 	return TRUE;
+ }
+ 
+ CamelMessageContentInfo *
+ camel_folder_summary_guess_content_info (CamelMessageInfo *mi, CamelContentType *ctype)
+ {
+ 	CamelMessageInfoBase *bmi = (CamelMessageInfoBase *) mi;
+ 	CamelMessageContentInfo *ci = bmi->content;
+ 
+ 	while (ci) {
+ 		CamelMessageContentInfo *child = ci;
+ 
+ 		do {
+ 			if (match_content_type (child->type, ctype))
+ 				return child;
+ 
+ 			child = child->next;
+ 		} while (child != NULL);
+ 
+ 		ci = ci->childs;
+ 	}
+ 
+ 	return NULL;
+ }
diff --cc camel/camel-gpg-context.c
index ce2d747,0bec14a..46f2a66
--- a/camel/camel-gpg-context.c
+++ b/camel/camel-gpg-context.c
@@@ -431,13 -458,16 +434,16 @@@ gpg_ctx_free (struct _GpgCtx *gpg
  	}
  
  	if (gpg->istream)
 -		camel_object_unref (gpg->istream);
 +		g_object_unref (gpg->istream);
  
  	if (gpg->ostream)
 -		camel_object_unref (gpg->ostream);
 +		g_object_unref (gpg->ostream);
  
 -	camel_object_unref (gpg->diagnostics);
 +	g_object_unref (gpg->diagnostics);
  
+ 	if (gpg->signers)
+ 		g_string_free (gpg->signers, TRUE);
+ 
  	g_free (gpg);
  }
  
@@@ -1391,10 -1403,10 +1427,10 @@@ gpg_sign (CamelCipherContext *context
  	camel_data_wrapper_set_mime_type_field(dw, ct);
  	camel_content_type_unref(ct);
  
 -	camel_medium_set_content_object((CamelMedium *)sigpart, dw);
 -	camel_object_unref(dw);
 +	camel_medium_set_content ((CamelMedium *)sigpart, dw);
 +	g_object_unref (dw);
  
- 	camel_mime_part_set_description(sigpart, _("This is a digitally signed message part"));
+ 	camel_mime_part_set_description(sigpart, "This is a digitally signed message part");
  
  	mps = camel_multipart_signed_new();
  	ct = camel_content_type_new("multipart", "signed");
@@@ -1455,12 -1465,36 +1491,39 @@@ swrite (CamelMimePart *sigpart
  	return template;
  }
  
+ static void
+ add_signers (CamelCipherValidity *validity, const GString *signers)
+ {
+ 	CamelInternetAddress *address;
+ 	gint i, count;
+ 
+ 	g_return_if_fail (validity != NULL);
+ 
+ 	if (!signers || !signers->str || !*signers->str)
+ 		return;
+ 
+ 	address = camel_internet_address_new ();
+ 	g_return_if_fail (address != NULL);
+ 
+ 	count = camel_address_decode (CAMEL_ADDRESS (address), signers->str);
+ 	for (i = 0; i < count; i++) {
+ 		const gchar *name = NULL, *email = NULL;
+ 
+ 		if (!camel_internet_address_get (address, i, &name, &email))
+ 			break;
+ 
+ 		camel_cipher_validity_add_certinfo (validity, CAMEL_CIPHER_VALIDITY_SIGN, name, email);
+ 	}
+ 
 -	camel_object_unref (address);
++	g_object_unref (address);
+ }
+ 
  static CamelCipherValidity *
 -gpg_verify (CamelCipherContext *context, CamelMimePart *ipart, CamelException *ex)
 +gpg_verify (CamelCipherContext *context,
 +            CamelMimePart *ipart,
 +            GError **error)
  {
 +	CamelCipherContextClass *class;
  	CamelCipherValidity *validity;
  	const gchar *diagnostics = NULL;
  	struct _GpgCtx *gpg = NULL;
@@@ -1702,9 -1717,9 +1767,9 @@@ gpg_encrypt (CamelCipherContext *contex
  		goto fail;
  	}
  
- 	/* FIXME: move tihs to a common routine */
+ 	/* FIXME: move this to a common routine */
  	while (!gpg_ctx_op_complete(gpg)) {
 -		if (gpg_ctx_op_step (gpg, ex) == -1)
 +		if (gpg_ctx_op_step (gpg, error) == -1)
  			goto fail;
  	}
  
@@@ -1909,7 -1910,12 +1974,9 @@@ gpg_decrypt (CamelCipherContext *contex
  			} else {
  				valid->sign.status = CAMEL_CIPHER_VALIDITY_SIGN_BAD;
  			}
+ 
+ 			add_signers (valid, gpg->signers);
  		}
 -	} else {
 -		camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
 -				     _("Unable to parse message content"));
  	}
  
   fail:
diff --cc camel/camel-mime-part.c
index 2e5ed96,37f8522..3acdb7f
--- a/camel/camel-mime-part.c
+++ b/camel/camel-mime-part.c
@@@ -984,6 -446,23 +984,23 @@@ camel_mime_part_get_disposition (CamelM
  		return NULL;
  }
  
+ /**
+  * camel_mime_part_get_content_disposition:
+  * @mime_part: a #CamelMimePart object
+  *
+  * Get the disposition of the MIME part as a structure.
+  * Returned pointer is owned by #mime_part.
+  *
+  * Returns: the disposition structure
+  **/
+ const CamelContentDisposition *
+ camel_mime_part_get_content_disposition (CamelMimePart *mime_part)
+ {
+ 	g_return_val_if_fail (mime_part != NULL, NULL);
+ 
 -	return mime_part->disposition;
++	return mime_part->priv->disposition;
+ }
+ 
  /* **** Content-Disposition: filename="xxx" */
  
  /**
diff --cc camel/camel-net-utils.c
index 9e77d08,d447e41..2578e36
--- a/camel/camel-net-utils.c
+++ b/camel/camel-net-utils.c
@@@ -495,24 -492,17 +495,23 @@@ cs_waitinfo (gpointer (worker)(gpointer
  #endif
  						   ) {
  			if (status == -1)
 -				camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, "%s: %s", error,
 +				g_set_error (
 +					error, G_FILE_ERROR,
 +					g_file_error_from_errno (errno),
 +					"%s: %s", errmsg,
  #ifndef G_OS_WIN32
 -						     g_strerror(errno)
 +					g_strerror (errno)
  #else
 -						     g_win32_error_message (WSAGetLastError ())
 +					g_win32_error_message (WSAGetLastError ())
  #endif
 -						     );
 +					);
  			else
 -				camel_exception_setv(ex, CAMEL_EXCEPTION_USER_CANCEL, _("Canceled"));
 +				g_set_error (
 +					error, CAMEL_ERROR,
 +					CAMEL_ERROR_USER_CANCEL,
 +					_("Canceled"));
  
  			/* We cancel so if the thread impl is decent it causes immediate exit.
- 			   We detach so we dont need to wait for it to exit if it isn't.
  			   We check the reply port incase we had a reply in the mean time, which we free later */
  			d(printf("Canceling lookup thread and leaving it\n"));
  			msg->cancelled = 1;
@@@ -715,15 -697,11 +715,13 @@@ camel_getaddrinfo (const gchar *name
  	msg->hostbuflen = 1024;
  	msg->hostbufmem = g_malloc(msg->hostbuflen);
  #endif
 -	if (cs_waitinfo(cs_getaddrinfo, msg, _("Host lookup failed"), ex) == 0) {
 +	if (cs_waitinfo(cs_getaddrinfo, msg, _("Host lookup failed"), error) == 0) {
  		if (msg->result != 0) {
 -			camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Host lookup failed: %s: %s"),
 -					      name, gai_strerror (msg->result));
 +			g_set_error (
 +				error, CAMEL_ERROR, CAMEL_ERROR_SYSTEM,
 +				_("Host lookup failed: %s: %s"),
 +				name, gai_strerror (msg->result));
  		}
- 
- 		cs_freeinfo(msg);
  	} else
  		res = NULL;
  
diff --cc camel/camel-smime-context.c
index ca0a387,a8f3b4a..f24361e
--- a/camel/camel-smime-context.c
+++ b/camel/camel-smime-context.c
@@@ -320,14 -439,12 +320,14 @@@ sm_signing_cmsmessage (CamelSMIMEContex
  	NSSCMSSignerInfo *signerinfo;
  	CERTCertificate *cert= NULL, *ekpcert = NULL;
  
 -	if ((cert = CERT_FindUserCertByUsage(p->certdb,
 +	if ((cert = CERT_FindUserCertByUsage (p->certdb,
  					     (gchar *)nick,
  					     certUsageEmailSigner,
- 					     PR_FALSE,
+ 					     PR_TRUE,
  					     NULL)) == NULL) {
 -		camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot find certificate for '%s'"), nick);
 +		g_set_error (
 +			error, CAMEL_ERROR, CAMEL_ERROR_SYSTEM,
 +			_("Cannot find certificate for '%s'"), nick);
  		return NULL;
  	}
  
@@@ -387,14 -504,11 +387,14 @@@
  
  		if (p->encrypt_key) {
  			/* encrypt key has its own nick */
 -			if ((ekpcert = CERT_FindUserCertByUsage(
 +			if ((ekpcert = CERT_FindUserCertByUsage (
  				     p->certdb,
  				     p->encrypt_key,
- 				     certUsageEmailRecipient, PR_FALSE, NULL)) == NULL) {
+ 				     certUsageEmailRecipient, PR_TRUE, NULL)) == NULL) {
 -				camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, _("Encryption certificate for '%s' does not exist"), p->encrypt_key);
 +				g_set_error (
 +					error, CAMEL_ERROR, CAMEL_ERROR_SYSTEM,
 +					_("Encryption certificate for '%s' does not exist"),
 +					p->encrypt_key);
  				goto fail;
  			}
  			enccert = ekpcert;
@@@ -403,12 -517,10 +403,12 @@@
  			enccert = cert;
  		} else {
  			/* encrypt key uses same nick */
 -			if ((ekpcert = CERT_FindUserCertByUsage(
 +			if ((ekpcert = CERT_FindUserCertByUsage (
  				     p->certdb, (gchar *)nick,
- 				     certUsageEmailRecipient, PR_FALSE, NULL)) == NULL) {
+ 				     certUsageEmailRecipient, PR_TRUE, NULL)) == NULL) {
 -				camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, _("Encryption certificate for '%s' does not exist"), nick);
 +				g_set_error (
 +					error, CAMEL_ERROR, CAMEL_ERROR_SYSTEM,
 +					_("Encryption certificate for '%s' does not exist"), nick);
  				goto fail;
  			}
  			enccert = ekpcert;
diff --cc camel/camel-stream-vfs.c
index adaa0e9,b735638..483b575
--- a/camel/camel-stream-vfs.c
+++ b/camel/camel-stream-vfs.c
@@@ -35,152 -36,64 +35,133 @@@
  #include "camel-private.h"
  #include "camel-stream-vfs.h"
  
 -static CamelStreamClass *parent_class = NULL;
 +static gpointer parent_class;
  
 -/* Returns the class for a CamelStreamVFS */
 -#define CSVFS_CLASS(so) CAMEL_STREAM_VFS_CLASS (CAMEL_OBJECT_GET_CLASS(so))
 +static void
 +stream_vfs_dispose (GObject *object)
 +{
 +	CamelStreamVFS *stream = CAMEL_STREAM_VFS (object);
 +
 +	if (stream->stream != NULL) {
 +		g_object_unref (stream->stream);
 +		stream->stream = NULL;
 +	}
  
 -static gssize stream_read   (CamelStream *stream, gchar *buffer, gsize n);
 -static gssize stream_write  (CamelStream *stream, const gchar *buffer, gsize n);
 -static gint stream_flush  (CamelStream *stream);
 -static gint stream_close  (CamelStream *stream);
 +	/* Chain up to parent's dispose() method. */
 +	G_OBJECT_CLASS (parent_class)->dispose (object);
 +}
  
 -static void
 -camel_stream_vfs_class_init (CamelStreamVFSClass *camel_stream_vfs_class)
 +static gssize
 +stream_vfs_read (CamelStream *stream,
 +                 gchar *buffer,
 +                 gsize n,
 +                 GError **error)
  {
- 	gssize nread;
 -	CamelStreamClass *camel_stream_class =
 -		CAMEL_STREAM_CLASS (camel_stream_vfs_class);
 +	CamelStreamVFS *stream_vfs = CAMEL_STREAM_VFS (stream);
- 
- 	g_return_val_if_fail (G_IS_INPUT_STREAM (stream_vfs->stream), 0);
++	gssize nread;
  
 -	parent_class = CAMEL_STREAM_CLASS (camel_type_get_global_classfuncs (camel_stream_get_type ()));
 +	nread = g_input_stream_read (
 +		G_INPUT_STREAM (stream_vfs->stream),
 +		buffer, n, NULL, error);
 +
 +	if (nread <= 0)
 +		stream->eos = TRUE;
  
 -	/* virtual method overload */
 -	camel_stream_class->read = stream_read;
 -	camel_stream_class->write = stream_write;
 -	camel_stream_class->flush = stream_flush;
 -	camel_stream_class->close = stream_close;
 +	return nread;
  }
  
 -static void
 -camel_stream_vfs_init (gpointer object, gpointer klass)
 +static gssize
 +stream_vfs_write (CamelStream *stream,
 +                  const gchar *buffer,
-                   gsize n)
++                  gsize n,
++                  GError **error)
  {
 -	CamelStreamVFS *stream = CAMEL_STREAM_VFS (object);
 +	gboolean success;
 +	gsize bytes_written;
- 	GError *error = NULL;
 +	CamelStreamVFS *stream_vfs = CAMEL_STREAM_VFS (stream);
  
- 	g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream_vfs->stream), 0);
 -	stream->stream = NULL;
++	success = g_output_stream_write_all (
++		G_OUTPUT_STREAM (stream_vfs->stream),
++		buffer, n, &bytes_written, NULL, error);
 +
- 	success = g_output_stream_write_all (G_OUTPUT_STREAM (stream_vfs->stream), buffer, n, &bytes_written, NULL, &error);
- 
- 	if (error) {
- 		g_warning ("%s", error->message);
- 		g_error_free (error);
- 	}
 +	return success ? bytes_written : -1;
  }
  
 -static void
 -camel_stream_vfs_finalize (CamelObject *object)
 +static gint
- stream_vfs_flush (CamelStream *stream)
++stream_vfs_flush (CamelStream *stream,
++                  GError **error)
  {
 -	CamelStreamVFS *stream_vfs = CAMEL_STREAM_VFS (object);
 +	CamelStreamVFS *stream_vfs = CAMEL_STREAM_VFS (stream);
- 	GError *error = NULL;
- 
- 	g_return_val_if_fail (CAMEL_IS_STREAM_VFS (stream) && stream_vfs != NULL, -1);
- 	g_return_val_if_fail (stream_vfs->stream != NULL, -1);
- 	g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream_vfs->stream), -1);
- 
- 	g_output_stream_flush (G_OUTPUT_STREAM (stream_vfs->stream), NULL, &error);
++	gboolean success;
  
- 	if (error) {
- 		g_warning ("%s", error->message);
- 		g_error_free (error);
- 		return -1;
- 	}
 -	if (stream_vfs->stream)
 -		g_object_unref (stream_vfs->stream);
++	success = g_output_stream_flush (
++		G_OUTPUT_STREAM (stream_vfs->stream), NULL, error);
 +
- 	return 0;
++	return success ? 0 : -1;
  }
  
 -CamelType
 -camel_stream_vfs_get_type (void)
 +static gint
- stream_vfs_close (CamelStream *stream)
++stream_vfs_close (CamelStream *stream,
++                  GError **error)
  {
 -	static CamelType camel_stream_vfs_type = CAMEL_INVALID_TYPE;
 -
 -	if (camel_stream_vfs_type == CAMEL_INVALID_TYPE) {
 -		camel_stream_vfs_type = camel_type_register (camel_stream_get_type (), "CamelStreamVFS",
 -							    sizeof (CamelStreamVFS),
 -							    sizeof (CamelStreamVFSClass),
 -							    (CamelObjectClassInitFunc) camel_stream_vfs_class_init,
 -							    NULL,
 -							    (CamelObjectInitFunc) camel_stream_vfs_init,
 -							    (CamelObjectFinalizeFunc) camel_stream_vfs_finalize);
 +	CamelStreamVFS *stream_vfs = CAMEL_STREAM_VFS (stream);
- 	GError *error = NULL;
- 
- 	g_return_val_if_fail (CAMEL_IS_STREAM_VFS (stream) && stream_vfs != NULL, -1);
- 	g_return_val_if_fail (stream_vfs->stream != NULL, -1);
- 	g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream_vfs->stream) || G_IS_INPUT_STREAM (stream_vfs->stream), -1);
++	gboolean success;
 +
 +	if (G_IS_OUTPUT_STREAM (stream_vfs->stream))
- 		g_output_stream_close (G_OUTPUT_STREAM (stream_vfs->stream), NULL, &error);
++		success = g_output_stream_close (
++			G_OUTPUT_STREAM (stream_vfs->stream), NULL, error);
 +	else
- 		g_input_stream_close (G_INPUT_STREAM (stream_vfs->stream), NULL, &error);
++		success = g_input_stream_close (
++			G_INPUT_STREAM (stream_vfs->stream), NULL, error);
 +
- 	if (error) {
- 		g_warning ("%s", error->message);
- 		g_error_free (error);
- 		return -1;
++	if (success) {
++		g_object_unref (stream_vfs->stream);
++		stream_vfs->stream = NULL;
  	}
  
- 	g_object_unref (stream_vfs->stream);
- 	stream_vfs->stream = NULL;
- 
- 	return 0;
 -	return camel_stream_vfs_type;
++	return success ? 0 : -1;
 +}
 +
 +static void
 +stream_vfs_class_init (CamelStreamVFSClass *class)
 +{
 +	GObjectClass *object_class;
 +	CamelStreamClass *stream_class;
 +
 +	parent_class = g_type_class_peek_parent (class);
 +
 +	object_class = G_OBJECT_CLASS (class);
 +	object_class->dispose = stream_vfs_dispose;
 +
 +	stream_class = CAMEL_STREAM_CLASS (class);
 +	stream_class->read = stream_vfs_read;
 +	stream_class->write = stream_vfs_write;
 +	stream_class->flush = stream_vfs_flush;
 +	stream_class->close = stream_vfs_close;
 +}
 +
 +static void
 +stream_vfs_init (CamelStreamVFS *stream)
 +{
 +	stream->stream = NULL;
 +}
 +
 +GType
 +camel_stream_vfs_get_type (void)
 +{
 +	static GType type = G_TYPE_INVALID;
 +
 +	if (G_UNLIKELY (type == G_TYPE_INVALID))
 +		type = g_type_register_static_simple (
 +			CAMEL_TYPE_STREAM,
 +			"CamelStreamVFS",
 +			sizeof (CamelStreamVFSClass),
 +			(GClassInitFunc) stream_vfs_class_init,
 +			sizeof (CamelStreamVFS),
 +			(GInstanceInitFunc) stream_vfs_init,
 +			0);
 +
 +	return type;
  }
  
  /**
diff --cc camel/camel-tcp-stream-ssl.h
index 88b3a1e,f4060a3..a35e913
--- a/camel/camel-tcp-stream-ssl.h
+++ b/camel/camel-tcp-stream-ssl.h
@@@ -28,25 -24,12 +28,26 @@@
  #define CAMEL_TCP_STREAM_SSL_H
  
  #include <camel/camel-tcp-stream.h>
+ #include <prio.h>
  
 -#define CAMEL_TCP_STREAM_SSL_TYPE     (camel_tcp_stream_ssl_get_type ())
 -#define CAMEL_TCP_STREAM_SSL(obj)     (CAMEL_CHECK_CAST((obj), CAMEL_TCP_STREAM_SSL_TYPE, CamelTcpStreamSSL))
 -#define CAMEL_TCP_STREAM_SSL_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_TCP_STREAM_SSL_TYPE, CamelTcpStreamSSLClass))
 -#define CAMEL_IS_TCP_STREAM_SSL(o)    (CAMEL_CHECK_TYPE((o), CAMEL_TCP_STREAM_SSL_TYPE))
 +/* Standard GObject macros */
 +#define CAMEL_TYPE_TCP_STREAM_SSL \
 +	(camel_tcp_stream_ssl_get_type ())
 +#define CAMEL_TCP_STREAM_SSL(obj) \
 +	(G_TYPE_CHECK_INSTANCE_CAST \
 +	((obj), CAMEL_TYPE_TCP_STREAM_SSL, CamelTcpStreamSSL))
 +#define CAMEL_TCP_STREAM_SSL_CLASS(cls) \
 +	(G_TYPE_CHECK_CLASS_CAST \
 +	((cls), CAMEL_TYPE_TCP_STREAM_SSL, CamelTcpStreamSSLClass))
 +#define CAMEL_IS_TCP_STREAM_SSL(obj) \
 +	(G_TYPE_CHECK_INSTANCE_TYPE \
 +	((obj), CAMEL_TYPE_TCP_STREAM_SSL))
 +#define CAMEL_IS_TCP_STREAM_SSL_CLASS(cls) \
 +	(G_TYPE_CHECK_CLASS_TYPE \
 +	((cls), CAMEL_TYPE_TCP_STREAM_SSL))
 +#define CAMEL_TCP_STREAM_SSL_GET_CLASS(obj) \
 +	(G_TYPE_INSTANCE_GET_CLASS \
 +	((obj), CAMEL_TYPE_TCP_STREAM_SSL, CamelTcpStreamSSLClass))
  
  #define CAMEL_TCP_STREAM_SSL_ENABLE_SSL2   (1 << 0)
  #define CAMEL_TCP_STREAM_SSL_ENABLE_SSL3   (1 << 1)
diff --cc camel/camel-vee-folder.c
index d93a211,903fa98..d04c015
--- a/camel/camel-vee-folder.c
+++ b/camel/camel-vee-folder.c
@@@ -40,608 -42,437 +40,630 @@@
  #include "camel-vee-summary.h"
  #include "camel-string-utils.h"
  #include "camel-vee-folder.h"
+ #include "camel-vtrash-folder.h"
  
  #define d(x)
 -#define dd(x) (camel_debug("vfolder")?(x):0)
 +#define dd(x) (camel_debug ("vfolder")?(x):0)
  
 -#define _PRIVATE(o) (((CamelVeeFolder *)(o))->priv)
 +#define CAMEL_VEE_FOLDER_GET_PRIVATE(obj) \
 +	(G_TYPE_INSTANCE_GET_PRIVATE \
 +	((obj), CAMEL_TYPE_VEE_FOLDER, CamelVeeFolderPrivate))
  
 -#if 0
 -static void vee_refresh_info(CamelFolder *folder, CamelException *ex);
 +struct _update_data {
 +	CamelFolder *source;
 +	CamelVeeFolder *vee_folder;
 +	gchar hash[8];
 +	CamelVeeFolder *folder_unmatched;
 +	GHashTable *unmatched_uids;
 +	gboolean rebuilt, correlating;
 +};
  
 -static void vee_sync (CamelFolder *folder, gboolean expunge, CamelException *ex);
 -static void vee_expunge (CamelFolder *folder, CamelException *ex);
 +static gpointer parent_class;
  
 -static void vee_freeze(CamelFolder *folder);
 -static void vee_thaw(CamelFolder *folder);
 +struct _folder_changed_msg {
 +	CamelSessionThreadMsg msg;
 +	CamelFolderChangeInfo *changes;
 +	CamelFolder *sub;
 +	CamelVeeFolder *vee_folder;
 +};
  
 -static CamelMimeMessage *vee_get_message (CamelFolder *folder, const gchar *uid, CamelException *ex);
 -static void vee_append_message(CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, gchar **appended_uid, CamelException *ex);
 -static void vee_transfer_messages_to(CamelFolder *source, GPtrArray *uids, CamelFolder *dest, GPtrArray **transferred_uids, gboolean delete_originals, CamelException *ex);
 +/* must be called with summary_lock held */
 +static CamelVeeMessageInfo *
 +vee_folder_add_uid (CamelVeeFolder *vf,
 +                    CamelFolder *f,
 +                    const gchar *inuid,
 +                    const gchar hash[8])
 +{
 +	CamelVeeMessageInfo *mi = NULL;
  
 -static guint32 vee_count_by_expression(CamelFolder *folder, const gchar *expression, CamelException *ex);
 -static GPtrArray *vee_search_by_expression(CamelFolder *folder, const gchar *expression, CamelException *ex);
 -static GPtrArray *vee_search_by_uids(CamelFolder *folder, const gchar *expression, GPtrArray *uids, CamelException *ex);
 +	mi = camel_vee_summary_add ((CamelVeeSummary *)((CamelFolder *)vf)->summary, f->summary, (gchar *)inuid, hash);
 +	return mi;
 +}
  
 -static void vee_rename(CamelFolder *folder, const gchar *new);
 -#endif
++/* same as vee_folder_add_uid, only returns whether uid was added or not */
++static gboolean
++vee_folder_add_uid_test (CamelVeeFolder *vf, CamelFolder *f, const gchar *inid, const gchar hash[8])
++{
++	CamelVeeMessageInfo *mi;
+ 
 -static void camel_vee_folder_class_init (CamelVeeFolderClass *klass);
 -static void camel_vee_folder_init       (CamelVeeFolder *obj);
 -static void camel_vee_folder_finalise   (CamelObject *obj);
++	mi = vee_folder_add_uid (vf, f, inid, hash);
+ 
 -static gint vee_rebuild_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException *ex);
 -static void vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source);
++	if (mi != NULL)
++		camel_message_info_free ((CamelMessageInfo *) mi);
+ 
 -static void folder_changed(CamelFolder *sub, CamelFolderChangeInfo *changes, CamelVeeFolder *vf);
 -static void subfolder_deleted(CamelFolder *f, gpointer event_data, CamelVeeFolder *vf);
 -static void folder_renamed(CamelFolder *f, const gchar *old, CamelVeeFolder *vf);
++	return mi != NULL;
++}
+ 
 -static CamelFolderClass *camel_vee_folder_parent;
 +/* A "correlating" expression has the property that whether a message matches
 + * depends on the other messages being searched.  folder_changed_change on a
 + * vfolder with a correlating expression may not make all the necessary updates,
 + * so the query is redone on the entire changed source folder the next time
 + * the vfolder is opened.
 + *
 + * The only current example of a correlating expression is one that uses
 + * "match-threads". */
 +static gboolean
 +expression_is_correlating (const gchar *expr)
 +{
 +	/* XXX: Actually parse the expression to avoid triggering on
 +	 * "match-threads" in the text the user is searching for! */
 +	return (strstr (expr, "match-threads") != NULL);
 +}
  
 -CamelType
 -camel_vee_folder_get_type (void)
 +/* Hold all these with summary lock and unmatched summary lock held */
 +static void
 +folder_changed_add_uid (CamelFolder *sub, const gchar *uid, const gchar hash[8], CamelVeeFolder *vf, gboolean use_db)
  {
 -	static CamelType type = CAMEL_INVALID_TYPE;
 +	CamelFolder *folder = (CamelFolder *)vf;
 +	CamelVeeMessageInfo *vinfo;
 +	const gchar *vuid;
 +	gchar *oldkey;
 +	gpointer oldval;
 +	gint n;
 +	CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
 +	GHashTable *unmatched_uids = vf->parent_vee_store ? vf->parent_vee_store->unmatched_uids : NULL;
 +
 +	vinfo = vee_folder_add_uid (vf, sub, uid, hash);
 +	if (vinfo == NULL)
 +		return;
  
- 	vuid = camel_message_info_uid (vinfo);
 -	if (type == CAMEL_INVALID_TYPE) {
 -		type = camel_type_register (camel_folder_get_type (), "CamelVeeFolder",
 -					    sizeof (CamelVeeFolder),
 -					    sizeof (CamelVeeFolderClass),
 -					    (CamelObjectClassInitFunc) camel_vee_folder_class_init,
 -					    NULL,
 -					    (CamelObjectInitFunc) camel_vee_folder_init,
 -					    (CamelObjectFinalizeFunc) camel_vee_folder_finalise);
++	vuid = camel_pstring_strdup (camel_message_info_uid (vinfo));
++	camel_message_info_free ((CamelMessageInfo *) vinfo);
 +	if (use_db) {
- 		camel_db_add_to_vfolder_transaction (folder->parent_store->cdb_w, folder->full_name, (gchar *)vuid, NULL);
++		camel_db_add_to_vfolder_transaction (folder->parent_store->cdb_w, folder->full_name, (gchar *) vuid, NULL);
 +	}
 +	camel_folder_change_info_add_uid (vf->changes,  vuid);
 +	if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !CAMEL_IS_VEE_FOLDER (sub) && folder_unmatched != NULL) {
 +		if (g_hash_table_lookup_extended (unmatched_uids, vuid, (gpointer *)&oldkey, &oldval)) {
 +			n = GPOINTER_TO_INT (oldval);
 +			g_hash_table_insert (unmatched_uids, oldkey, GINT_TO_POINTER (n+1));
 +		} else {
 +			g_hash_table_insert (unmatched_uids, g_strdup (vuid), GINT_TO_POINTER (1));
 +		}
 +		vinfo = (CamelVeeMessageInfo *)camel_folder_get_message_info ((CamelFolder *)folder_unmatched, vuid);
 +		if (vinfo) {
 +			camel_folder_change_info_remove_uid (folder_unmatched->changes, vuid);
 +			camel_db_delete_uid_from_vfolder_transaction (folder->parent_store->cdb_w, ((CamelFolder *)folder_unmatched)->full_name, vuid, NULL);
 +			camel_folder_summary_remove_uid_fast (((CamelFolder *)folder_unmatched)->summary, vuid);
 +			camel_folder_free_message_info ((CamelFolder *)folder_unmatched, (CamelMessageInfo *)vinfo);
 +		}
  	}
+ 
 -	return type;
++	camel_pstring_free (vuid);
  }
  
 -void
 -camel_vee_folder_construct (CamelVeeFolder *vf, CamelStore *parent_store, const gchar *full, const gchar *name, guint32 flags)
 +static void
 +folder_changed_remove_uid (CamelFolder *sub, const gchar *uid, const gchar hash[8], gint keep, CamelVeeFolder *vf, gboolean use_db)
  {
  	CamelFolder *folder = (CamelFolder *)vf;
 +	gchar *vuid, *oldkey;
 +	gpointer oldval;
 +	gint n;
 +	CamelVeeMessageInfo *vinfo;
 +	CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
 +	GHashTable *unmatched_uids = vf->parent_vee_store ? vf->parent_vee_store->unmatched_uids : NULL;
  
 -	vf->flags = flags;
 -	camel_folder_construct(folder, parent_store, full, name);
 +	vuid = alloca (strlen (uid)+9);
 +	memcpy (vuid, hash, 8);
 +	strcpy (vuid+8, uid);
  
 -	folder->summary = camel_vee_summary_new(folder);
 +	camel_folder_change_info_remove_uid (vf->changes, vuid);
 +	if (use_db)
 +		camel_db_delete_uid_from_vfolder_transaction (
 +			folder->parent_store->cdb_w,
 +			folder->full_name, vuid, NULL);
 +	camel_folder_summary_remove_uid_fast (folder->summary, vuid);
  
 -	if (CAMEL_IS_VEE_STORE(parent_store))
 -		vf->parent_vee_store = (CamelVeeStore *)parent_store;
 +	if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !CAMEL_IS_VEE_FOLDER (sub) && folder_unmatched != NULL) {
 +		if (keep) {
 +			if (g_hash_table_lookup_extended (unmatched_uids, vuid, (gpointer *)&oldkey, &oldval)) {
 +				n = GPOINTER_TO_INT (oldval);
 +				if (n == 1) {
 +					g_hash_table_remove (unmatched_uids, oldkey);
- 					if (vee_folder_add_uid (folder_unmatched, sub, uid, hash))
++					if (vee_folder_add_uid_test (folder_unmatched, sub, uid, hash))
 +						camel_folder_change_info_add_uid (folder_unmatched->changes, oldkey);
 +					g_free (oldkey);
 +				} else {
 +					g_hash_table_insert (unmatched_uids, oldkey, GINT_TO_POINTER (n-1));
 +				}
 +			} else {
- 				if (vee_folder_add_uid (folder_unmatched, sub, uid, hash))
++				if (vee_folder_add_uid_test (folder_unmatched, sub, uid, hash))
 +					camel_folder_change_info_add_uid (folder_unmatched->changes, oldkey);
 +			}
 +		} else {
 +			if (g_hash_table_lookup_extended (unmatched_uids, vuid, (gpointer *)&oldkey, &oldval)) {
 +				g_hash_table_remove (unmatched_uids, oldkey);
 +				g_free (oldkey);
 +			}
 +
 +			vinfo = (CamelVeeMessageInfo *)camel_folder_get_message_info ((CamelFolder *)folder_unmatched, vuid);
 +			if (vinfo) {
 +				camel_folder_change_info_remove_uid (folder_unmatched->changes, vuid);
 +				camel_db_delete_uid_from_vfolder_transaction (folder->parent_store->cdb_w, ((CamelFolder *)folder_unmatched)->full_name, vuid, NULL);
 +				camel_folder_summary_remove_uid_fast (((CamelFolder *)folder_unmatched)->summary, vuid);
 +				camel_folder_free_message_info ((CamelFolder *)folder_unmatched, (CamelMessageInfo *)vinfo);
 +			}
 +		}
 +	}
  }
  
 -/**
 - * camel_vee_folder_new:
 - * @parent_store: the parent CamelVeeStore
 - * @full: the full path to the vfolder.
 - * @flags: flags of some kind
 - *
 - * Create a new CamelVeeFolder object.
 - *
 - * Return value: A new CamelVeeFolder widget.
 - **/
 -CamelFolder *
 -camel_vee_folder_new(CamelStore *parent_store, const gchar *full, guint32 flags)
 +static void
 +folder_changed_change_uid (CamelFolder *sub, const gchar *uid, const gchar hash[8], CamelVeeFolder *vf, gboolean use_db)
  {
 -	CamelVeeFolder *vf;
 -	gchar *tmp;
 +	gchar *vuid;
 +	CamelVeeMessageInfo *vinfo, *uinfo = NULL;
 +	CamelMessageInfo *info;
 +	CamelFolder *folder = (CamelFolder *)vf;
 +	CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
  
 -	if (CAMEL_IS_VEE_STORE(parent_store) && strcmp(full, CAMEL_UNMATCHED_NAME) == 0) {
 -		vf = ((CamelVeeStore *)parent_store)->folder_unmatched;
 -		camel_object_ref(vf);
 -	} else {
 -		const gchar *name = strrchr(full, '/');
 +	vuid = alloca (strlen (uid)+9);
 +	memcpy (vuid, hash, 8);
 +	strcpy (vuid+8, uid);
  
 -		if (name == NULL)
 -			name = full;
 -		else
 -			name++;
 -		vf = (CamelVeeFolder *)camel_object_new(camel_vee_folder_get_type());
 -		camel_vee_folder_construct(vf, parent_store, full, name, flags);
 -	}
 +	vinfo = (CamelVeeMessageInfo *)camel_folder_summary_uid (folder->summary, vuid);
 +	if (folder_unmatched != NULL)
 +		uinfo = (CamelVeeMessageInfo *)camel_folder_summary_uid (((CamelFolder *)folder_unmatched)->summary, vuid);
 +	if (vinfo || uinfo) {
 +		info = camel_folder_get_message_info (sub, uid);
 +		if (info) {
 +			if (vinfo) {
 +				camel_folder_change_info_change_uid (vf->changes, vuid);
 +				camel_message_info_free ((CamelMessageInfo *)vinfo);
 +			}
  
 -	d(printf("returning folder %s %p, count = %d\n", full, vf, camel_folder_get_message_count((CamelFolder *)vf)));
 +			if (uinfo) {
 +				camel_folder_change_info_change_uid (folder_unmatched->changes, vuid);
 +				camel_message_info_free ((CamelMessageInfo *)uinfo);
 +			}
  
 -	if (vf) {
 -		tmp = g_strdup_printf("%s/%s.cmeta", ((CamelService *)parent_store)->url->path, full);
 -		camel_object_set(vf, NULL, CAMEL_OBJECT_STATE_FILE, tmp, NULL);
 -		g_free(tmp);
 -		if (camel_object_state_read(vf) == -1) {
 -			/* setup defaults: we have none currently */
 +			camel_folder_free_message_info (sub, info);
 +		} else {
 +			if (vinfo) {
 +				folder_changed_remove_uid (sub, uid, hash, FALSE, vf, use_db);
 +				camel_message_info_free ((CamelMessageInfo *)vinfo);
 +			}
 +			if (uinfo)
 +				camel_message_info_free ((CamelMessageInfo *)uinfo);
  		}
  	}
 -	return (CamelFolder *)vf;
  }
  
 -void
 -camel_vee_folder_set_expression(CamelVeeFolder *vf, const gchar *query)
 -{
 -	((CamelVeeFolderClass *)((CamelObject *)vf)->klass)->set_expression(vf, query);
 -}
 -
 -/**
 - * camel_vee_folder_add_folder:
 - * @vf: Virtual Folder object
 - * @sub: source CamelFolder to add to @vf
 - *
 - * Adds @sub as a source folder to @vf.
 - **/
 -void
 -camel_vee_folder_add_folder(CamelVeeFolder *vf, CamelFolder *sub)
 +static void
 +folder_changed_change (CamelSession *session, CamelSessionThreadMsg *msg)
  {
 -	struct _CamelVeeFolderPrivate *p = _PRIVATE(vf);
 -	gint i;
 +	struct _folder_changed_msg *m = (struct _folder_changed_msg *)msg;
 +	CamelFolder *sub = m->sub;
 +	CamelFolder *folder = (CamelFolder *)m->vee_folder;
 +	CamelVeeFolder *vf = m->vee_folder;
 +	CamelFolderChangeInfo *changes = m->changes;
 +	gchar *vuid = NULL, hash[8];
 +	const gchar *uid;
 +	CamelVeeMessageInfo *vinfo;
 +	gint i, vuidlen = 0;
 +	CamelFolderChangeInfo *vf_changes = NULL, *unmatched_changes = NULL;
 +	GPtrArray *matches_added = NULL, /* newly added, that match */
 +		*matches_changed = NULL, /* newly changed, that now match */
 +		*newchanged = NULL,
 +		*changed;
 +	GPtrArray *always_changed = NULL;
 +	GHashTable *matches_hash;
  	CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
 +	GHashTable *unmatched_uids = vf->parent_vee_store ? vf->parent_vee_store->unmatched_uids : NULL;
 +	GPtrArray *present = NULL;
  
 -	if (vf == (CamelVeeFolder *)sub) {
 -		g_warning("Adding a virtual folder to itself as source, ignored");
 +	/* See vee_folder_rebuild_folder. */
 +	gboolean correlating = expression_is_correlating (vf->expression);
 +
 +	/* Check the folder hasn't beem removed while we weren't watching */
 +	CAMEL_VEE_FOLDER_LOCK (vf, subfolder_lock);
 +	if (g_list_find (CAMEL_VEE_FOLDER_GET_PRIVATE (vf)->folders, sub) == NULL) {
 +		CAMEL_VEE_FOLDER_UNLOCK (vf, subfolder_lock);
  		return;
  	}
  
 -	CAMEL_VEE_FOLDER_LOCK(vf, subfolder_lock);
 -
 -	/* for normal vfolders we want only unique ones, for unmatched we want them all recorded */
 -	if (g_list_find(p->folders, sub) == NULL) {
 -		camel_object_ref((CamelObject *)sub);
 -		p->folders = g_list_append(p->folders, sub);
 -
 -		CAMEL_FOLDER_LOCK(vf, change_lock);
 +	camel_vee_folder_hash_folder (sub, hash);
  
 -		/* update the freeze state of 'sub' to match our freeze state */
 -		for (i = 0; i < ((CamelFolder *)vf)->priv->frozen; i++)
 -			camel_folder_freeze(sub);
 +	/* Lookup anything before we lock anything, to avoid deadlock with build_folder */
  
 -		CAMEL_FOLDER_UNLOCK(vf, change_lock);
 +	/* Find newly added that match */
 +	if (changes->uid_added->len > 0) {
 +		dd (printf (" Searching for added matches '%s'\n", vf->expression));
 +		matches_added = camel_folder_search_by_uids (sub, vf->expression, changes->uid_added, NULL);
  	}
 -	if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !CAMEL_IS_VEE_FOLDER(sub) && folder_unmatched != NULL) {
 -		struct _CamelVeeFolderPrivate *up = _PRIVATE(folder_unmatched);
 -		camel_object_ref((CamelObject *)sub);
 -		up->folders = g_list_append(up->folders, sub);
  
 -		CAMEL_FOLDER_LOCK(folder_unmatched, change_lock);
 -
 -		/* update the freeze state of 'sub' to match Unmatched's freeze state */
 -		for (i = 0; i < ((CamelFolder *)folder_unmatched)->priv->frozen; i++)
 -			camel_folder_freeze(sub);
 -
 -		CAMEL_FOLDER_UNLOCK(folder_unmatched, change_lock);
 -	}
 +	/* TODO:
 +	   In this code around here, we can work out if the search will affect the changes
 +	   we had, and only re-search against them if they might have */
  
 -	CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock);
 +	/* Search for changed items that newly match, but only if we dont have them */
 +	changed = changes->uid_changed;
 +	if (changed->len > 0) {
 +		dd (printf (" Searching for changed matches '%s'\n", vf->expression));
  
 -	d(printf("camel_vee_folder_add_folder(%s, %s)\n", ((CamelFolder *)vf)->full_name, sub->full_name));
 +		if ((vf->flags & CAMEL_STORE_VEE_FOLDER_AUTO) == 0) {
 +			newchanged = g_ptr_array_new ();
 +			always_changed = g_ptr_array_new ();
 +			for (i=0;i<changed->len;i++) {
 +				uid = changed->pdata[i];
 +				if (strlen (uid)+9 > vuidlen) {
 +					vuidlen = strlen (uid)+64;
 +					vuid = g_realloc (vuid, vuidlen);
 +				}
 +				memcpy (vuid, hash, 8);
 +				strcpy (vuid+8, uid);
 +				vinfo = (CamelVeeMessageInfo *)camel_folder_summary_uid (folder->summary, vuid);
 +				if (vinfo == NULL) {
 +					g_ptr_array_add (newchanged, (gchar *)uid);
 +				} else {
 +					g_ptr_array_add (always_changed, (gchar *)uid);
 +					camel_message_info_free ((CamelMessageInfo *)vinfo);
 +				}
 +			}
 +			changed = newchanged;
 +		}
  
 -	camel_object_hook_event((CamelObject *)sub, "folder_changed", (CamelObjectEventHookFunc)folder_changed, vf);
 -	camel_object_hook_event((CamelObject *)sub, "deleted", (CamelObjectEventHookFunc)subfolder_deleted, vf);
 -	camel_object_hook_event((CamelObject *)sub, "renamed", (CamelObjectEventHookFunc)folder_renamed, vf);
 +		if (changed->len)
 +			matches_changed = camel_folder_search_by_uids (sub, vf->expression, changed, NULL);
 +		if (always_changed && always_changed->len)
 +			present = camel_folder_search_by_uids (sub, vf->expression, always_changed, NULL);
 +	}
  
 -	((CamelVeeFolderClass *)((CamelObject *)vf)->klass)->add_folder(vf, sub);
 +	CAMEL_VEE_FOLDER_LOCK (vf, summary_lock);
  
 -}
 +	if (folder_unmatched != NULL)
 +		CAMEL_VEE_FOLDER_LOCK (folder_unmatched, summary_lock);
  
 -/**
 - * camel_vee_folder_remove_folder:
 - * @vf: Virtual Folder object
 - * @sub: source CamelFolder to remove from @vf
 - *
 - * Removed the source folder, @sub, from the virtual folder, @vf.
 - **/
 -void
 +	if (matches_changed || matches_added || changes->uid_removed->len||present)
 +		camel_db_begin_transaction (folder->parent_store->cdb_w, NULL);
  
 -camel_vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *sub)
 -{
 -	struct _CamelVeeFolderPrivate *p = _PRIVATE(vf);
 -	gint i;
 -	CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
 +	dd (printf ("Vfolder '%s' subfolder changed '%s'\n", folder->full_name, sub->full_name));
 +	dd (printf (" changed %u added %u removed %u\n", changes->uid_changed->len, changes->uid_added->len, changes->uid_removed->len));
  
 -	CAMEL_VEE_FOLDER_LOCK(vf, subfolder_lock);
 +	/* Always remove removed uid's, in any case */
 +	for (i=0;i<changes->uid_removed->len;i++) {
 +		dd (printf ("  removing uid '%s'\n", (gchar *)changes->uid_removed->pdata[i]));
 +		folder_changed_remove_uid (sub, changes->uid_removed->pdata[i], hash, FALSE, vf, !correlating);
 +	}
  
 -	CAMEL_VEE_FOLDER_LOCK(vf, changed_lock);
 -	p->folders_changed = g_list_remove(p->folders_changed, sub);
 -	CAMEL_VEE_FOLDER_UNLOCK(vf, changed_lock);
 +	/* Add any newly matched or to unmatched folder if they dont */
 +	if (matches_added) {
 +		matches_hash = g_hash_table_new (g_str_hash, g_str_equal);
 +		for (i=0;i<matches_added->len;i++) {
 +			dd (printf (" %s", (gchar *)matches_added->pdata[i]));
 +			g_hash_table_insert (matches_hash, matches_added->pdata[i], matches_added->pdata[i]);
 +		}
 +		for (i=0;i<changes->uid_added->len;i++) {
 +			uid = changes->uid_added->pdata[i];
 +			if (g_hash_table_lookup (matches_hash, uid)) {
 +				dd (printf ("  adding uid '%s' [newly matched]\n", (gchar *)uid));
 +				folder_changed_add_uid (sub, uid, hash, vf, !correlating);
 +			} else if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0) {
 +				if (strlen (uid)+9 > vuidlen) {
 +					vuidlen = strlen (uid)+64;
 +					vuid = g_realloc (vuid, vuidlen);
 +				}
 +				memcpy (vuid, hash, 8);
 +				strcpy (vuid+8, uid);
  
 -	if (g_list_find(p->folders, sub) == NULL) {
 -		CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock);
 -		return;
 +				if (!CAMEL_IS_VEE_FOLDER (sub) && folder_unmatched != NULL && g_hash_table_lookup (unmatched_uids, vuid) == NULL) {
 +					dd (printf ("  adding uid '%s' to Unmatched [newly unmatched]\n", (gchar *)uid));
 +					vinfo = (CamelVeeMessageInfo *)camel_folder_get_message_info ((CamelFolder *)folder_unmatched, vuid);
 +					if (vinfo == NULL) {
- 						if (vee_folder_add_uid (folder_unmatched, sub, uid, hash))
++						if (vee_folder_add_uid_test (folder_unmatched, sub, uid, hash))
 +							camel_folder_change_info_add_uid (folder_unmatched->changes, vuid);
 +					} else {
 +						camel_folder_free_message_info ((CamelFolder *)folder_unmatched, (CamelMessageInfo *)vinfo);
 +					}
 +				}
 +			}
 +		}
 +		g_hash_table_destroy (matches_hash);
  	}
  
 -	camel_object_unhook_event((CamelObject *)sub, "folder_changed", (CamelObjectEventHookFunc) folder_changed, vf);
 -	camel_object_unhook_event((CamelObject *)sub, "deleted", (CamelObjectEventHookFunc) subfolder_deleted, vf);
 -	camel_object_unhook_event((CamelObject *)sub, "renamed", (CamelObjectEventHookFunc) folder_renamed, vf);
 -
 -	p->folders = g_list_remove(p->folders, sub);
 +	/* Change any newly changed */
 +	if (always_changed) {
 +		if (correlating) {
 +			/* Messages may be pulled in by the correlation even if
 +			 * they do not match the expression individually, so it
 +			 * would be wrong to preemptively remove anything here.
 +			 * vee_folder_rebuild_folder will make any necessary removals
 +			 * when it re-queries the entire source folder. */
 +			for (i=0;i<always_changed->len;i++)
 +				folder_changed_change_uid (sub, always_changed->pdata[i], hash, vf, !correlating);
 +		} else {
 +			GHashTable *ht_present = g_hash_table_new (g_str_hash, g_str_equal);
  
 -	/* undo the freeze state that we have imposed on this source folder */
 -	CAMEL_FOLDER_LOCK(vf, change_lock);
 -	for (i = 0; i < ((CamelFolder *)vf)->priv->frozen; i++)
 -		camel_folder_thaw(sub);
 -	CAMEL_FOLDER_UNLOCK(vf, change_lock);
 +			for (i=0;present && i<present->len;i++) {
 +				folder_changed_change_uid (sub, present->pdata[i], hash, vf, !correlating);
 +				g_hash_table_insert (ht_present, present->pdata[i], present->pdata[i]);
 +			}
  
 -	CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock);
 +			for (i=0; i<always_changed->len; i++) {
 +				if (!present || !g_hash_table_lookup (ht_present, always_changed->pdata[i]))
 +					/* XXX: IIUC, these messages haven't been deleted from the
 +					 * source folder, so shouldn't "keep" be set to TRUE? */
 +					folder_changed_remove_uid (sub, always_changed->pdata[i], hash, TRUE, vf, !correlating);
 +			}
  
 -	if (folder_unmatched != NULL) {
 -		struct _CamelVeeFolderPrivate *up = _PRIVATE(folder_unmatched);
 +			g_hash_table_destroy (ht_present);
 +		}
 +		g_ptr_array_free (always_changed, TRUE);
 +	}
  
 -		CAMEL_VEE_FOLDER_LOCK(folder_unmatched, subfolder_lock);
 -		/* if folder deleted, then blow it away from unmatched always, and remove all refs to it */
 -		if (sub->folder_flags & CAMEL_FOLDER_HAS_BEEN_DELETED) {
 -			while (g_list_find(up->folders, sub)) {
 -				up->folders = g_list_remove(up->folders, sub);
 -				camel_object_unref((CamelObject *)sub);
 +	/* Change/add/remove any changed */
 +	if (changes->uid_changed->len) {
 +		/* If we are auto-updating, then re-check changed uids still match */
 +		dd (printf (" Vfolder %supdate\nuids match:", (vf->flags & CAMEL_STORE_VEE_FOLDER_AUTO)?"auto-":""));
 +		matches_hash = g_hash_table_new (g_str_hash, g_str_equal);
 +		for (i=0;matches_changed && i<matches_changed->len;i++) {
 +			dd (printf (" %s", (gchar *)matches_changed->pdata[i]));
 +			g_hash_table_insert (matches_hash, matches_changed->pdata[i], matches_changed->pdata[i]);
 +		}
 +		dd (printf ("\n"));
  
 -				/* undo the freeze state that Unmatched has imposed on this source folder */
 -				CAMEL_FOLDER_LOCK(folder_unmatched, change_lock);
 -				for (i = 0; i < ((CamelFolder *)folder_unmatched)->priv->frozen; i++)
 -					camel_folder_thaw(sub);
 -				CAMEL_FOLDER_UNLOCK(folder_unmatched, change_lock);
 +		for (i=0;i<changed->len;i++) {
 +			uid = changed->pdata[i];
 +			if (strlen (uid)+9 > vuidlen) {
 +				vuidlen = strlen (uid)+64;
 +				vuid = g_realloc (vuid, vuidlen);
  			}
 -		} else if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0) {
 -			if (g_list_find(up->folders, sub) != NULL) {
 -				up->folders = g_list_remove(up->folders, sub);
 -				camel_object_unref((CamelObject *)sub);
 -
 -				/* undo the freeze state that Unmatched has imposed on this source folder */
 -				CAMEL_FOLDER_LOCK(folder_unmatched, change_lock);
 -				for (i = 0; i < ((CamelFolder *)folder_unmatched)->priv->frozen; i++)
 -					camel_folder_thaw(sub);
 -				CAMEL_FOLDER_UNLOCK(folder_unmatched, change_lock);
 +			memcpy (vuid, hash, 8);
 +			strcpy (vuid+8, uid);
 +			vinfo = (CamelVeeMessageInfo *)camel_folder_summary_uid (folder->summary, vuid);
 +			if (vinfo == NULL) {
 +				if (g_hash_table_lookup (matches_hash, uid)) {
 +					/* A uid we dont have, but now it matches, add it */
 +					dd (printf ("  adding uid '%s' [newly matched]\n", uid));
 +					folder_changed_add_uid (sub, uid, hash, vf, !correlating);
 +				} else {
 +					/* A uid we still don't have, just change it (for unmatched) */
 +					folder_changed_change_uid (sub, uid, hash, vf, !correlating);
 +				}
 +			} else {
 +				if ((vf->flags & CAMEL_STORE_VEE_FOLDER_AUTO) == 0
 +				    || g_hash_table_lookup (matches_hash, uid)) {
 +					/* still match, or we're not auto-updating, change event, (if it changed) */
 +					dd (printf ("  changing uid '%s' [still matches]\n", uid));
 +					folder_changed_change_uid (sub, uid, hash, vf, !correlating);
 +				} else {
 +					/* No longer matches, remove it, but keep it in unmatched (potentially) */
 +					dd (printf ("  removing uid '%s' [did match]\n", uid));
 +					folder_changed_remove_uid (sub, uid, hash, TRUE, vf, !correlating);
 +				}
 +				camel_message_info_free ((CamelMessageInfo *)vinfo);
  			}
  		}
 -		CAMEL_VEE_FOLDER_UNLOCK(folder_unmatched, subfolder_lock);
 +		g_hash_table_destroy (matches_hash);
 +	} else {
 +		/* stuff didn't match but it changed - check unmatched folder for changes */
 +		for (i=0;i<changed->len;i++)
 +			folder_changed_change_uid (sub, changed->pdata[i], hash, vf, !correlating);
  	}
  
 -	((CamelVeeFolderClass *)((CamelObject *)vf)->klass)->remove_folder(vf, sub);
 +	if (folder_unmatched != NULL) {
 +		if (camel_folder_change_info_changed (folder_unmatched->changes)) {
 +			unmatched_changes = folder_unmatched->changes;
 +			folder_unmatched->changes = camel_folder_change_info_new ();
 +		}
  
 -	if (CAMEL_IS_VEE_FOLDER(sub))
 -		return;
 +		CAMEL_VEE_FOLDER_UNLOCK (folder_unmatched, summary_lock);
 +	}
  
 -	camel_object_unref((CamelObject *)sub);
 -}
 +	if (camel_folder_change_info_changed (vf->changes)) {
 +		vf_changes = vf->changes;
 +		vf->changes = camel_folder_change_info_new ();
 +	}
  
 -/**
 - * camel_vee_folder_rebuild_folder:
 - * @vf: Virtual Folder object
 - * @sub: source CamelFolder to add to @vf
 - * @ex: Exception.
 - *
 - * Rebuild the folder @sub, if it should be.
 - **/
 -gint
 -camel_vee_folder_rebuild_folder(CamelVeeFolder *vf, CamelFolder *sub, CamelException *ex)
 -{
 -	return ((CamelVeeFolderClass *)((CamelObject *)vf)->klass)->rebuild_folder(vf, sub, ex);
 -}
 +	if (matches_changed || matches_added || changes->uid_removed->len || present)
 +		camel_db_end_transaction (folder->parent_store->cdb_w, NULL);
 +	CAMEL_VEE_FOLDER_UNLOCK (vf, summary_lock);
  
 -static void
 -remove_folders(CamelFolder *folder, CamelFolder *foldercopy, CamelVeeFolder *vf)
 -{
 -	camel_vee_folder_remove_folder(vf, folder);
 -	camel_object_unref((CamelObject *)folder);
 -}
 +	/* Cleanup stuff on our folder */
 +	if (matches_added)
 +		camel_folder_search_free (sub, matches_added);
 +	if (present)
 +		camel_folder_search_free (sub, present);
  
 -/**
 - * camel_vee_folder_set_folders:
 - * @vf:
 - * @folders:
 - *
 - * Set the whole list of folder sources on a vee folder.
 - **/
 -void
 -camel_vee_folder_set_folders(CamelVeeFolder *vf, GList *folders)
 -{
 -	struct _CamelVeeFolderPrivate *p = _PRIVATE(vf);
 -	GHashTable *remove = g_hash_table_new(NULL, NULL);
 -	GList *l;
 -	CamelFolder *folder;
 +	if (matches_changed)
 +		camel_folder_search_free (sub, matches_changed);
  
 -	/* setup a table of all folders we have currently */
 -	CAMEL_VEE_FOLDER_LOCK(vf, subfolder_lock);
 -	l = p->folders;
 -	while (l) {
 -		g_hash_table_insert(remove, l->data, l->data);
 -		camel_object_ref((CamelObject *)l->data);
 -		l = l->next;
 +	CAMEL_VEE_FOLDER_UNLOCK (vf, subfolder_lock);
 +
 +	/* cleanup the rest */
 +	if (newchanged)
 +		g_ptr_array_free (newchanged, TRUE);
 +
 +	g_free (vuid);
 +
 +	if (unmatched_changes) {
 +		camel_object_trigger_event ((CamelObject *)folder_unmatched, "folder_changed", unmatched_changes);
 +		camel_folder_change_info_free (unmatched_changes);
  	}
 -	CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock);
  
 -	/* if we already have the folder, ignore it, otherwise add it */
 -	l = folders;
 -	while (l) {
 -		if ((folder = g_hash_table_lookup(remove, l->data))) {
 -			g_hash_table_remove(remove, folder);
 -			camel_object_unref((CamelObject *)folder);
 -		} else {
 -			camel_vee_folder_add_folder(vf, l->data);
 -		}
 -		l = l->next;
 +	/* Add to folders_changed if we need to call vee_folder_rebuild_folder, which
 +	 * could be the case for two reasons:
 +	 * - We changed the vfolder and it is not auto-updating.  Need to re-sync.
 +	 * - Vfolder is correlating.  Changes to non-matching source messages
 +	 *   won't be processed here and won't show up in vf_changes but may
 +	 *   still affect the vfolder contents (e.g., non-matching messages
 +	 *   added to a matching thread), so we re-run the query on the whole
 +	 *   source folder.  (For match-threads, it may be enough to do this if
 +	 *   changes->uid_added->len > 0, but I'm not completely sure and I'd
 +	 *   rather be safe than sorry.)
 +	 */
 +	if ((vf_changes && (vf->flags & CAMEL_STORE_VEE_FOLDER_AUTO) == 0) || correlating) {
 +		CAMEL_VEE_FOLDER_LOCK (vf, changed_lock);
 +		if (g_list_find (vf->priv->folders_changed, sub) == NULL)
 +			vf->priv->folders_changed = g_list_prepend (vf->priv->folders_changed, sub);
 +		CAMEL_VEE_FOLDER_UNLOCK (vf, changed_lock);
  	}
  
 -	/* then remove any we still have */
 -	g_hash_table_foreach(remove, (GHFunc)remove_folders, vf);
 -	g_hash_table_destroy(remove);
 +	if (vf_changes) {
 +		camel_object_trigger_event ((CamelObject *)vf, "folder_changed", vf_changes);
 +		camel_folder_change_info_free (vf_changes);
 +	}
  }
  
 -/**
 - * camel_vee_folder_hash_folder:
 - * @folder:
 - * @:
 - *
 - * Create a hash string representing the folder name, which should be
 - * unique, and remain static for a given folder.
 - **/
 -void
 -camel_vee_folder_hash_folder(CamelFolder *folder, gchar buffer[8])
 +static void
 +subfolder_renamed_update (CamelVeeFolder *vf, CamelFolder *sub, gchar hash[8])
  {
 -	GChecksum *checksum;
 -	guint8 *digest;
 -	gsize length;
 -	gint state = 0, save = 0;
 -	gchar *tmp;
 -	gint i;
 +	gint count, i;
 +	CamelFolderChangeInfo *changes = NULL;
 +	CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
 +	GHashTable *unmatched_uids = vf->parent_vee_store ? vf->parent_vee_store->unmatched_uids : NULL;
 +	CamelFolderSummary *ssummary = sub->summary;
  
 -	length = g_checksum_type_get_length (G_CHECKSUM_MD5);
 -	digest = g_alloca (length);
 +	CAMEL_VEE_FOLDER_LOCK (vf, summary_lock);
  
 -	checksum = g_checksum_new (G_CHECKSUM_MD5);
 -	tmp = camel_service_get_url((CamelService *)folder->parent_store);
 -	g_checksum_update (checksum, (guchar *) tmp, -1);
 -	g_free (tmp);
 -	tmp = folder->full_name;
 -	g_checksum_update (checksum, (guchar *) tmp, -1);
 -	g_checksum_get_digest (checksum, digest, &length);
 -	g_checksum_free (checksum);
 +	count = camel_folder_summary_count (((CamelFolder *)vf)->summary);
 +	for (i=0;i<count;i++) {
 +		CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index (((CamelFolder *)vf)->summary, i);
 +		CamelVeeMessageInfo *vinfo;
  
 -	g_base64_encode_step (digest, 6, FALSE, buffer, &state, &save);
 -	g_base64_encode_close (FALSE, buffer, &state, &save);
 +		if (mi == NULL)
 +			continue;
  
 -	for (i=0;i<8;i++) {
 -		if (buffer[i] == '+')
 -			buffer[i] = '.';
 -		if (buffer[i] == '/')
 -			buffer[i] = '_';
 -	}
 -}
 +		if (mi->summary == ssummary) {
 +			gchar *uid = (gchar *)camel_message_info_uid (mi);
 +			gchar *oldkey;
 +			gpointer oldval;
  
 -/**
 - * camel_vee_folder_get_location:
 - * @vf:
 - * @vinfo:
 - * @realuid: if not NULL, set to the uid of the real message, must be
 - * g_free'd by caller.
 - *
 - * Find the real folder (and uid)
 - *
 - * Return value:
 - **/
 -CamelFolder *
 -camel_vee_folder_get_location(CamelVeeFolder *vf, const CamelVeeMessageInfo *vinfo, gchar **realuid)
 -{
 -	CamelFolder *folder;
 +			camel_folder_change_info_remove_uid (vf->changes, uid);
 +			camel_folder_summary_remove (((CamelFolder *)vf)->summary, (CamelMessageInfo *)mi);
  
 -	folder = vinfo->summary->folder;
 +			/* works since we always append on the end */
 +			i--;
 +			count--;
  
 -	/* locking?  yes?  no?  although the vfolderinfo is valid when obtained
 -	   the folder in it might not necessarily be so ...? */
 -	if (CAMEL_IS_VEE_FOLDER(folder)) {
 -		CamelFolder *res;
 -		const CamelVeeMessageInfo *vfinfo;
 +			vinfo = vee_folder_add_uid (vf, sub, uid+8, hash);
 +			if (vinfo) {
 +				camel_folder_change_info_add_uid (vf->changes, camel_message_info_uid (vinfo));
  
 -		vfinfo = (CamelVeeMessageInfo *)camel_folder_get_message_info(folder, camel_message_info_uid(vinfo)+8);
 -		res = camel_vee_folder_get_location((CamelVeeFolder *)folder, vfinfo, realuid);
 -		camel_folder_free_message_info(folder, (CamelMessageInfo *)vfinfo);
 -		return res;
 -	} else {
 -		if (realuid)
 -			*realuid = g_strdup(camel_message_info_uid(vinfo)+8);
 +				/* check unmatched uid's table for any matches */
 +				if (vf == folder_unmatched
 +				    && g_hash_table_lookup_extended (unmatched_uids, uid, (gpointer *)&oldkey, &oldval)) {
 +					g_hash_table_remove (unmatched_uids, oldkey);
 +					g_hash_table_insert (unmatched_uids, g_strdup (camel_message_info_uid (vinfo)), oldval);
 +					g_free (oldkey);
 +				}
+ 
 -		return folder;
++				camel_message_info_free ((CamelMessageInfo *) vinfo);
 +			}
 +		}
 +
 +		camel_message_info_free ((CamelMessageInfo *)mi);
 +	}
 +
 +	if (camel_folder_change_info_changed (vf->changes)) {
 +		changes = vf->changes;
 +		vf->changes = camel_folder_change_info_new ();
 +	}
 +
 +	CAMEL_VEE_FOLDER_UNLOCK (vf, summary_lock);
 +
 +	if (changes) {
 +		camel_object_trigger_event ((CamelObject *)vf, "folder_changed", changes);
 +		camel_folder_change_info_free (changes);
  	}
  }
  
 -static void vee_refresh_info(CamelFolder *folder, CamelException *ex)
 +static void
 +folder_changed_free (CamelSession *session, CamelSessionThreadMsg *msg)
  {
 -	CamelVeeFolder *vf = (CamelVeeFolder *)folder;
 -	struct _CamelVeeFolderPrivate *p = _PRIVATE(vf);
 -	GList *node, *list;
 +	struct _folder_changed_msg *m = (struct _folder_changed_msg *)msg;
  
 -	CAMEL_VEE_FOLDER_LOCK(vf, changed_lock);
 -	list = p->folders_changed;
 -	p->folders_changed = NULL;
 -	CAMEL_VEE_FOLDER_UNLOCK(vf, changed_lock);
 +	camel_folder_change_info_free (m->changes);
 +	g_object_unref (m->vee_folder);
 +	g_object_unref (m->sub);
 +}
  
 -	node = list;
 -	while (node) {
 -		CamelFolder *f = node->data;
 +static CamelSessionThreadOps folder_changed_ops = {
 +	folder_changed_change,
 +	folder_changed_free,
 +};
  
 -		if (camel_vee_folder_rebuild_folder(vf, f, ex) == -1)
 -			break;
 +static gint
 +vee_folder_rebuild_folder (CamelVeeFolder *vee_folder,
 +                           CamelFolder *source,
 +                           GError **error);
  
 -		node = node->next;
 -	}
 +static void
 +unmatched_check_uid (gchar *uidin, gpointer value, struct _update_data *u)
 +{
 +	gchar *uid;
 +	gint n;
  
 -	g_list_free(list);
 +	uid = alloca (strlen (uidin)+9);
 +	memcpy (uid, u->hash, 8);
 +	strcpy (uid+8, uidin);
 +	n = GPOINTER_TO_INT (g_hash_table_lookup (u->unmatched_uids, uid));
 +	if (n == 0) {
- 		if (vee_folder_add_uid (u->folder_unmatched, u->source, uidin, u->hash))
++		if (vee_folder_add_uid_test (u->folder_unmatched, u->source, uidin, u->hash))
 +			camel_folder_change_info_add_uid (u->folder_unmatched->changes, uid);
 +	} else {
 +		CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_uid (((CamelFolder *)u->folder_unmatched)->summary, uid);
 +		if (mi) {
 +			camel_db_delete_uid_from_vfolder_transaction (((CamelFolder *)u->folder_unmatched)->parent_store->cdb_w, ((CamelFolder *)u->folder_unmatched)->full_name, uid, NULL);
 +			camel_folder_summary_remove_uid_fast (((CamelFolder *)u->folder_unmatched)->summary, uid);
 +			camel_folder_change_info_remove_uid (u->folder_unmatched->changes, uid);
 +			camel_message_info_free ((CamelMessageInfo *)mi);
 +		}
 +	}
  }
  
 -static guint32
 -count_folder (CamelFolder *f, gchar *expr, CamelException *ex)
 +static void
 +folder_added_uid (gchar *uidin, gpointer value, struct _update_data *u)
  {
 -	return camel_folder_count_by_expression(f, expr, ex);
 +	CamelVeeMessageInfo *mi;
 +	gchar *oldkey;
 +	gpointer oldval;
 +	gint n;
 +
- 	if ((mi = vee_folder_add_uid (u->vee_folder, u->source, uidin, u->hash))) {
++	if ((mi = vee_folder_add_uid (u->vee_folder, u->source, uidin, u->hash)) != NULL) {
 +		camel_folder_change_info_add_uid (u->vee_folder->changes, camel_message_info_uid (mi));
 +		/* FIXME[disk-summary] Handle exceptions */
 +		/* FIXME[disk-summary] Make all these as transactions, just
 +		 * testing atm */
 +		if (u->rebuilt && !u->correlating) {
 +			camel_db_add_to_vfolder_transaction (((CamelFolder *) u->vee_folder)->parent_store->cdb_w, ((CamelFolder *) u->vee_folder)->full_name, (gchar *) camel_message_info_uid (mi), NULL);
 +		}
 +		if (!CAMEL_IS_VEE_FOLDER (u->source) && u->unmatched_uids != NULL) {
 +			if (g_hash_table_lookup_extended (u->unmatched_uids, camel_message_info_uid (mi), (gpointer *)&oldkey, &oldval)) {
 +				n = GPOINTER_TO_INT (oldval);
 +				g_hash_table_insert (u->unmatched_uids, oldkey, GINT_TO_POINTER (n+1));
 +			} else {
 +				g_hash_table_insert (u->unmatched_uids, g_strdup (camel_message_info_uid (mi)), GINT_TO_POINTER (1));
 +			}
 +		}
++
++		camel_message_info_free ((CamelMessageInfo *) mi);
 +	}
  }
 +
  static gint
 -count_result (CamelFolderSummary *summary, const gchar *query, CamelException *ex)
 +count_result (CamelFolderSummary *summary,
 +              const gchar *query,
 +              GError **error)
  {
  	CamelFolder *folder = summary->folder;
  	CamelVeeFolder *vf = (CamelVeeFolder *)folder;
@@@ -723,441 -553,11 +745,439 @@@ summary_header_to_db (CamelFolderSummar
  }
  
  static void
 -vee_sync(CamelFolder *folder, gboolean expunge, CamelException *ex)
 +folder_changed (CamelFolder *sub,
 +                CamelFolderChangeInfo *changes,
 +                CamelVeeFolder *vee_folder)
 +{
 +	CamelVeeFolderClass *class;
 +
 +	class = CAMEL_VEE_FOLDER_GET_CLASS (vee_folder);
 +	class->folder_changed (vee_folder, sub, changes);
 +}
 +
 +/* track vanishing folders */
 +static void
 +subfolder_deleted (CamelFolder *folder,
 +                   gpointer event_data,
 +                   CamelVeeFolder *vee_folder)
 +{
 +	camel_vee_folder_remove_folder (vee_folder, folder);
 +}
 +
 +static void
 +folder_renamed (CamelFolder *sub,
 +                const gchar *old,
 +                CamelVeeFolder *vee_folder)
 +{
 +	CamelVeeFolderClass *class;
 +
 +	class = CAMEL_VEE_FOLDER_GET_CLASS (vee_folder);
 +	class->folder_renamed (vee_folder, sub, old);
 +}
 +
 +static void
 +vee_folder_stop_folder (CamelVeeFolder *vf, CamelFolder *sub)
 +{
 +	CamelVeeFolderPrivate *p = CAMEL_VEE_FOLDER_GET_PRIVATE (vf);
 +	gint i;
 +	CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
 +
 +	CAMEL_VEE_FOLDER_LOCK (vf, subfolder_lock);
 +
 +	CAMEL_VEE_FOLDER_LOCK (vf, changed_lock);
 +	p->folders_changed = g_list_remove (p->folders_changed, sub);
 +	CAMEL_VEE_FOLDER_UNLOCK (vf, changed_lock);
 +
 +	if (g_list_find (p->folders, sub) == NULL) {
 +		CAMEL_VEE_FOLDER_UNLOCK (vf, subfolder_lock);
 +		return;
 +	}
 +
 +	camel_object_unhook_event ((CamelObject *)sub, "folder_changed", (CamelObjectEventHookFunc) folder_changed, vf);
 +	camel_object_unhook_event ((CamelObject *)sub, "deleted", (CamelObjectEventHookFunc) subfolder_deleted, vf);
 +	camel_object_unhook_event ((CamelObject *)sub, "renamed", (CamelObjectEventHookFunc) folder_renamed, vf);
 +
 +	p->folders = g_list_remove (p->folders, sub);
 +
 +	/* undo the freeze state that we have imposed on this source folder */
 +	CAMEL_FOLDER_LOCK (vf, change_lock);
 +	for (i = 0; i < ((CamelFolder *)vf)->priv->frozen; i++)
 +		camel_folder_thaw (sub);
 +	CAMEL_FOLDER_UNLOCK (vf, change_lock);
 +
 +	CAMEL_VEE_FOLDER_UNLOCK (vf, subfolder_lock);
 +
 +	if (folder_unmatched != NULL) {
 +		CamelVeeFolderPrivate *up = CAMEL_VEE_FOLDER_GET_PRIVATE (folder_unmatched);
 +
 +		CAMEL_VEE_FOLDER_LOCK (folder_unmatched, subfolder_lock);
 +		/* if folder deleted, then blow it away from unmatched always, and remove all refs to it */
 +		if (sub->folder_flags & CAMEL_FOLDER_HAS_BEEN_DELETED) {
 +			while (g_list_find (up->folders, sub)) {
 +				up->folders = g_list_remove (up->folders, sub);
 +				g_object_unref (sub);
 +
 +				/* undo the freeze state that Unmatched has imposed on this source folder */
 +				CAMEL_FOLDER_LOCK (folder_unmatched, change_lock);
 +				for (i = 0; i < ((CamelFolder *)folder_unmatched)->priv->frozen; i++)
 +					camel_folder_thaw (sub);
 +				CAMEL_FOLDER_UNLOCK (folder_unmatched, change_lock);
 +			}
 +		} else if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0) {
 +			if (g_list_find (up->folders, sub) != NULL) {
 +				up->folders = g_list_remove (up->folders, sub);
 +				g_object_unref (sub);
 +
 +				/* undo the freeze state that Unmatched has imposed on this source folder */
 +				CAMEL_FOLDER_LOCK (folder_unmatched, change_lock);
 +				for (i = 0; i < ((CamelFolder *)folder_unmatched)->priv->frozen; i++)
 +					camel_folder_thaw (sub);
 +				CAMEL_FOLDER_UNLOCK (folder_unmatched, change_lock);
 +			}
 +		}
 +		CAMEL_VEE_FOLDER_UNLOCK (folder_unmatched, subfolder_lock);
 +	}
 +
 +	if (CAMEL_IS_VEE_FOLDER (sub))
 +		return;
 +
 +	g_object_unref (sub);
 +}
 +
 +static void
 +vee_folder_remove_folder_helper (CamelVeeFolder *vf, CamelFolder *source)
 +{
 +	gint i, count, n, still = FALSE, start, last;
 +	gchar *oldkey;
 +	CamelFolder *folder = (CamelFolder *)vf;
 +	gchar hash[8];
 +	CamelFolderChangeInfo *vf_changes = NULL, *unmatched_changes = NULL;
 +	gpointer oldval;
 +	CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
 +	GHashTable *unmatched_uids = vf->parent_vee_store ? vf->parent_vee_store->unmatched_uids : NULL;
 +	CamelFolderSummary *ssummary = source->summary;
 +	gint killun = FALSE;
 +
 +	if (vf == folder_unmatched)
 +		return;
 +
 +	if ((source->folder_flags & CAMEL_FOLDER_HAS_BEEN_DELETED))
 +		killun = TRUE;
 +
 +	CAMEL_VEE_FOLDER_LOCK (vf, summary_lock);
 +
 +	if (folder_unmatched != NULL) {
 +		/* check if this folder is still to be part of unmatched */
 +		if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !killun) {
 +			CAMEL_VEE_FOLDER_LOCK (folder_unmatched, subfolder_lock);
 +			still = g_list_find (CAMEL_VEE_FOLDER_GET_PRIVATE (folder_unmatched)->folders, source) != NULL;
 +			CAMEL_VEE_FOLDER_UNLOCK (folder_unmatched, subfolder_lock);
 +			camel_vee_folder_hash_folder (source, hash);
 +		}
 +
 +		CAMEL_VEE_FOLDER_LOCK (folder_unmatched, summary_lock);
 +
 +		/* See if we just blow all uid's from this folder away from unmatched, regardless */
 +		if (killun) {
 +			start = -1;
 +			last = -1;
 +			count = camel_folder_summary_count (((CamelFolder *)folder_unmatched)->summary);
 +			for (i=0;i<count;i++) {
 +				CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index (((CamelFolder *)folder_unmatched)->summary, i);
 +
 +				if (mi) {
 +					if (mi->summary == ssummary) {
 +						camel_folder_change_info_remove_uid (folder_unmatched->changes, camel_message_info_uid (mi));
 +						if (last == -1) {
 +							last = start = i;
 +						} else if (last+1 == i) {
 +							last = i;
 +						} else {
 +							camel_folder_summary_remove_range (((CamelFolder *)folder_unmatched)->summary, start, last);
 +							i -= (last-start)+1;
 +							start = last = i;
 +						}
 +					}
 +					camel_message_info_free ((CamelMessageInfo *)mi);
 +				}
 +			}
 +			if (last != -1)
 +				camel_folder_summary_remove_range (((CamelFolder *)folder_unmatched)->summary, start, last);
 +		}
 +	}
 +
 +	/*FIXME: This can be optimized a lot like, searching for UID in the summary uids */
 +	start = -1;
 +	last = -1;
 +	count = camel_folder_summary_count (folder->summary);
 +	for (i=0;i<count;i++) {
 +		CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index (folder->summary, i);
 +		if (mi) {
 +			if (mi->summary == ssummary) {
 +				const gchar *uid = camel_message_info_uid (mi);
 +
 +				camel_folder_change_info_remove_uid (vf->changes, uid);
 +
 +				if (last == -1) {
 +					last = start = i;
 +				} else if (last+1 == i) {
 +					last = i;
 +				} else {
 +					camel_folder_summary_remove_range (folder->summary, start, last);
 +					i -= (last-start)+1;
 +					start = last = i;
 +				}
 +				if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && folder_unmatched != NULL) {
 +					if (still) {
 +						if (g_hash_table_lookup_extended (unmatched_uids, uid, (gpointer *)&oldkey, &oldval)) {
 +							n = GPOINTER_TO_INT (oldval);
 +							if (n == 1) {
- 								CamelMessageInfo *tinfo;
 +								g_hash_table_remove (unmatched_uids, oldkey);
- 								if ((tinfo = (CamelMessageInfo *) vee_folder_add_uid (folder_unmatched, source, oldkey+8, hash)) != NULL) {
- 									camel_message_info_free (tinfo);
++								if (vee_folder_add_uid_test (folder_unmatched, source, oldkey+8, hash)) {
 +									camel_folder_change_info_add_uid (folder_unmatched->changes, oldkey);
 +								}
 +								g_free (oldkey);
 +							} else {
 +								g_hash_table_insert (unmatched_uids, oldkey, GINT_TO_POINTER (n-1));
 +							}
 +						}
 +					} else {
 +						if (g_hash_table_lookup_extended (unmatched_uids, camel_message_info_uid (mi), (gpointer *)&oldkey, &oldval)) {
 +							g_hash_table_remove (unmatched_uids, oldkey);
 +							g_free (oldkey);
 +						}
 +					}
 +				}
 +			}
 +			camel_message_info_free ((CamelMessageInfo *)mi);
 +		}
 +	}
 +
 +	if (last != -1)
 +		camel_folder_summary_remove_range (folder->summary, start, last);
 +
 +	if (folder_unmatched) {
 +		if (camel_folder_change_info_changed (folder_unmatched->changes)) {
 +			unmatched_changes = folder_unmatched->changes;
 +			folder_unmatched->changes = camel_folder_change_info_new ();
 +		}
 +
 +		CAMEL_VEE_FOLDER_UNLOCK (folder_unmatched, summary_lock);
 +	}
 +
 +	if (camel_folder_change_info_changed (vf->changes)) {
 +		vf_changes = vf->changes;
 +		vf->changes = camel_folder_change_info_new ();
 +	}
 +
 +	CAMEL_VEE_FOLDER_UNLOCK (vf, summary_lock);
 +
 +	if (unmatched_changes) {
 +		camel_object_trigger_event ((CamelObject *)folder_unmatched, "folder_changed", unmatched_changes);
 +		camel_folder_change_info_free (unmatched_changes);
 +	}
 +
 +	if (vf_changes) {
 +		camel_object_trigger_event ((CamelObject *)vf, "folder_changed", vf_changes);
 +		camel_folder_change_info_free (vf_changes);
 +	}
 +}
 +
 +static void
 +vee_folder_finalize (GObject *object)
 +{
 +	CamelVeeFolder *vf;
 +	CamelVeeFolder *folder_unmatched;
 +	GList *node;
 +	CamelFIRecord * record;
 +
 +	vf = CAMEL_VEE_FOLDER (object);
 +	vf->priv->destroyed = TRUE;
 +
 +	if (vf->parent_vee_store != NULL)
 +		folder_unmatched = vf->parent_vee_store->folder_unmatched;
 +	else
 +		folder_unmatched = NULL;
 +
 +	/* Save the counts to DB */
 +	if (!vf->deleted) {
 +		record = summary_header_to_db (((CamelFolder *)vf)->summary, NULL);
 +		camel_db_write_folder_info_record (((CamelFolder *) vf)->parent_store->cdb_w, record, NULL);
 +		g_free (record);
 +	}
 +
 +	/* This may invoke sub-classes with partially destroyed state, they must deal with this */
 +	if (vf == folder_unmatched) {
 +		for (node = vf->priv->folders;node;node = g_list_next (node))
 +			g_object_unref (node->data);
 +	} else {
 +		/* FIXME[disk-summary] See if it is really reqd */
 +		camel_folder_freeze ((CamelFolder *)vf);
 +		while (vf->priv->folders) {
 +			CamelFolder *f = vf->priv->folders->data;
 +			vee_folder_stop_folder (vf, f);
 +		}
 +		camel_folder_thaw ((CamelFolder *)vf);
 +	}
 +
 +	g_free (vf->expression);
 +
 +	g_list_free (vf->priv->folders);
 +	g_list_free (vf->priv->folders_changed);
 +
 +	camel_folder_change_info_free (vf->changes);
 +	g_object_unref (vf->search);
 +
 +	g_mutex_free (vf->priv->summary_lock);
 +	g_mutex_free (vf->priv->subfolder_lock);
 +	g_mutex_free (vf->priv->changed_lock);
 +	g_hash_table_destroy (vf->hashes);
 +
 +	/* Chain up to parent's finalize () method. */
 +	G_OBJECT_CLASS (parent_class)->finalize (object);
 +}
 +
 +/* This entire code will be useless, since we sync the counts always. */
 +static gint
 +vee_folder_getv (CamelObject *object,
 +                 GError **error,
 +                 CamelArgGetV *args)
 +{
 +	CamelFolder *folder = (CamelFolder *)object;
 +	CamelVeeFolder *vf = (CamelVeeFolder *)folder;
 +	gint i;
 +	guint32 tag;
 +	gint unread = -1, deleted = 0, junked = 0, visible = 0, count = -1, junked_not_deleted = -1;
 +
 +	for (i=0;i<args->argc;i++) {
 +		CamelArgGet *arg = &args->argv[i];
 +
 +		tag = arg->tag;
 +
 +		/* NB: this is a copy of camel-folder.c with the unread count logic altered.
 +		   makes sure its still atomically calculated */
 +		switch (tag & CAMEL_ARG_TAG) {
 +		case CAMEL_FOLDER_ARG_UNREAD:
 +		case CAMEL_FOLDER_ARG_DELETED:
 +		case CAMEL_FOLDER_ARG_JUNKED:
 +		case CAMEL_FOLDER_ARG_JUNKED_NOT_DELETED:
 +		case CAMEL_FOLDER_ARG_VISIBLE:
 +
 +			if (vf->expression && vf->priv->unread_vfolder == -1)
 +				camel_vee_summary_load_check_unread_vfolder ((CamelVeeSummary *)folder->summary);
 +
 +			/* This is so we can get the values atomically, and also so we can calculate them only once */
 +			if (unread == -1) {
 +				gint j;
 +				CamelMessageInfoBase *info;
 +				CamelVeeMessageInfo *vinfo;
 +
 +				unread = deleted = visible = junked = junked_not_deleted = 0;
 +				count = camel_folder_summary_count (folder->summary);
 +				for (j=0; j<count; j++) {
 +					if ((info = (CamelMessageInfoBase *) camel_folder_summary_index (folder->summary, j))) {
 +						guint32 flags;
 +
 +						vinfo = (CamelVeeMessageInfo *) info;
 +						flags = vinfo->old_flags; /* ? vinfo->old_flags : camel_message_info_flags (info); */
 +
 +						if ((flags & (CAMEL_MESSAGE_SEEN)) == 0)
 +							unread++;
 +						if (flags & CAMEL_MESSAGE_DELETED)
 +							deleted++;
 +						if (flags & CAMEL_MESSAGE_JUNK) {
 +							junked++;
 +								if (! (flags & CAMEL_MESSAGE_DELETED))
 +									junked_not_deleted++;
 +						}
 +						if ((flags & (CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_JUNK)) == 0)
 +							visible++;
 +						camel_message_info_free (info);
 +					}
 +				}
 +			}
 +
 +			switch (tag & CAMEL_ARG_TAG) {
 +			case CAMEL_FOLDER_ARG_UNREAD:
 +				if (vf->priv->unread_vfolder == 1)
 +					count = unread == -1 ? 0 : unread - junked_not_deleted;
 +				else
 +					count = unread == -1 ? 0 : unread;
 +				break;
 +			case CAMEL_FOLDER_ARG_DELETED:
 +				count = deleted == -1 ? 0 : deleted;
 +				break;
 +			case CAMEL_FOLDER_ARG_JUNKED:
 +				count = junked == -1 ? 0 : junked;
 +				break;
 +			case CAMEL_FOLDER_ARG_JUNKED_NOT_DELETED:
 +				count = junked_not_deleted == -1 ? 0 : junked_not_deleted;
 +				break;
 +			case CAMEL_FOLDER_ARG_VISIBLE:
 +				if (vf->priv->unread_vfolder == 1)
 +					count = unread == -1 ? 0 : unread - junked_not_deleted;
 +				else
 +					count = visible == -1 ? 0 : visible;
 +
 +				break;
 +			}
 +			folder->summary->unread_count = unread == -1 ? 0 : unread;
 +			folder->summary->deleted_count = deleted == -1 ? 0 : deleted;
 +			junked = folder->summary->junk_count = junked == -1 ? 0 : junked;
 +			folder->summary->junk_not_deleted_count = junked_not_deleted == -1 ? 0 : junked_not_deleted;
 +			folder->summary->visible_count = visible == -1 ? 0 : visible;
 +			*arg->ca_int = count;
 +			break;
 +		default:
 +			continue;
 +		}
 +
 +		arg->tag = (tag & CAMEL_ARG_TYPE) | CAMEL_ARG_IGNORE;
 +	}
 +
 +	return ((CamelObjectClass *)parent_class)->getv (object, error, args);
 +}
 +
 +static gboolean
 +vee_folder_refresh_info (CamelFolder *folder,
 +                         GError **error)
 +{
 +	CamelVeeFolder *vf = (CamelVeeFolder *)folder;
 +	CamelVeeFolderPrivate *p = CAMEL_VEE_FOLDER_GET_PRIVATE (vf);
 +	GList *node, *list;
 +	gboolean success = TRUE;
 +
 +	CAMEL_VEE_FOLDER_LOCK (vf, changed_lock);
 +	list = p->folders_changed;
 +	p->folders_changed = NULL;
 +	CAMEL_VEE_FOLDER_UNLOCK (vf, changed_lock);
 +
 +	node = list;
 +	while (node) {
 +		CamelFolder *f = node->data;
 +
 +		if (camel_vee_folder_rebuild_folder (vf, f, error) == -1) {
 +			success = FALSE;
 +			break;
 +		}
 +
 +		node = node->next;
 +	}
 +
 +	g_list_free (list);
 +
 +	return success;
 +}
 +
 +static gboolean
 +vee_folder_sync (CamelFolder *folder,
 +                 gboolean expunge,
 +                 GError **error)
  {
  	CamelVeeFolder *vf = (CamelVeeFolder *)folder;
 -	struct _CamelVeeFolderPrivate *p = _PRIVATE(vf);
 +	CamelVeeFolderPrivate *p = CAMEL_VEE_FOLDER_GET_PRIVATE (vf);
  	GList *node;
 +	GError *local_error = NULL;
  
  	if (((CamelVeeSummary *)folder->summary)->fake_visible_count)
  		folder->summary->visible_count = ((CamelVeeSummary *)folder->summary)->fake_visible_count;
@@@ -1578,26 -1067,39 +1598,33 @@@ vee_folder_add_folder (CamelVeeFolder *
  }
  
  static void
 -folder_added_uid(gchar *uidin, gpointer value, struct _update_data *u)
 +vee_folder_remove_folder (CamelVeeFolder *vee_folder,
 +                          CamelFolder *sub)
  {
 -	CamelVeeMessageInfo *mi;
 -	gchar *oldkey;
 -	gpointer oldval;
 -	gint n;
 +	gchar *shash, hash[8];
++	CamelVeeFolder *folder_unmatched = vee_folder->parent_vee_store ? vee_folder->parent_vee_store->folder_unmatched : NULL;
  
 -	if ((mi = vee_folder_add_uid (u->vf, u->source, uidin, u->hash)) != NULL) {
 -		camel_folder_change_info_add_uid(u->vf->changes, camel_message_info_uid(mi));
 -		/* FIXME[disk-summary] Handle exceptions */
 -		/* FIXME[disk-summary] Make all these as transactions, just
 -		 * testing atm */
 -		if (u->rebuilt && !u->correlating) {
 -			CamelException ex = CAMEL_EXCEPTION_INITIALISER;
 -			camel_db_add_to_vfolder_transaction (((CamelFolder *) u->vf)->parent_store->cdb_w, ((CamelFolder *) u->vf)->full_name, camel_message_info_uid(mi), &ex);
 -			camel_exception_clear (&ex);
 -		}
 -		if (!CAMEL_IS_VEE_FOLDER(u->source) && u->unmatched_uids != NULL) {
 -			if (g_hash_table_lookup_extended(u->unmatched_uids, camel_message_info_uid(mi), (gpointer *)&oldkey, &oldval)) {
 -				n = GPOINTER_TO_INT (oldval);
 -				g_hash_table_insert(u->unmatched_uids, oldkey, GINT_TO_POINTER(n+1));
 -			} else {
 -				g_hash_table_insert(u->unmatched_uids, g_strdup(camel_message_info_uid(mi)), GINT_TO_POINTER(1));
 -			}
 -		}
 +	camel_vee_folder_hash_folder (sub, hash);
 +	vee_folder_remove_folder_helper (vee_folder, sub);
 +	shash = g_strdup_printf (
 +		"%c%c%c%c%c%c%c%c",
 +		hash[0], hash[1], hash[2], hash[3],
 +		hash[4], hash[5], hash[6], hash[7]);
- 	if (g_hash_table_lookup (vee_folder->hashes, shash))
++	if (g_hash_table_lookup (vee_folder->hashes, shash)) {
 +		g_hash_table_remove (vee_folder->hashes, shash);
++	}
+ 
 -		camel_message_info_free ((CamelMessageInfo *) mi);
++	if (folder_unmatched && g_hash_table_lookup (folder_unmatched->hashes, shash)) {
++		g_hash_table_remove (folder_unmatched->hashes, shash);
+ 	}
++
 +	g_free (shash);
  }
  
 -/* build query contents for a single folder */
  static gint
 -vee_rebuild_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException *ex)
 +vee_folder_rebuild_folder (CamelVeeFolder *vee_folder,
 +                           CamelFolder *source,
 +                           GError **error)
  {
  	GPtrArray *match, *all;
  	GHashTable *allhash, *matchhash, *fullhash;
@@@ -1612,22 -1114,26 +1639,26 @@@
  	gboolean rebuilded = FALSE;
  	gchar *shash;
  
 -	/* Since the source of a correlating vfolder has to be requeried in
 +	/* Since the source of a correlating vee_folderolder has to be requeried in
  	 * full every time it changes, caching the results in the db is not
  	 * worth the effort.  Thus, DB use is conditioned on !correlating. */
 -	gboolean correlating = expression_is_correlating(vf->expression);
 +	gboolean correlating = expression_is_correlating (vee_folder->expression);
  
 -	if (vf == folder_unmatched)
 +	if (vee_folder == folder_unmatched)
  		return 0;
  
 -	camel_vee_folder_hash_folder(source, u.hash);
 -	shash = g_strdup_printf("%c%c%c%c%c%c%c%c", u.hash[0], u.hash[1], u.hash[2], u.hash[3], u.hash[4], u.hash[5], u.hash[6], u.hash[7]);
 -	if (!g_hash_table_lookup (vf->hashes, shash)) {
 -		g_hash_table_insert (vf->hashes, g_strdup(shash), source->summary);
 +	camel_vee_folder_hash_folder (source, u.hash);
 +	shash = g_strdup_printf ("%c%c%c%c%c%c%c%c", u.hash[0], u.hash[1], u.hash[2], u.hash[3], u.hash[4], u.hash[5], u.hash[6], u.hash[7]);
- 	if (!g_hash_table_lookup (vee_folder->hashes, shash))
++	if (!g_hash_table_lookup (vee_folder->hashes, shash)) {
 +		g_hash_table_insert (vee_folder->hashes, g_strdup (shash), source->summary);
+ 	}
+ 	if (folder_unmatched && !g_hash_table_lookup (folder_unmatched->hashes, shash)) {
+ 		g_hash_table_insert (folder_unmatched->hashes, g_strdup (shash), source->summary);
+ 	}
  
  	/* if we have no expression, or its been cleared, then act as if no matches */
 -	if (vf->expression == NULL) {
 -		match = g_ptr_array_new();
 +	if (vee_folder->expression == NULL) {
 +		match = g_ptr_array_new ();
  	} else {
  		if (!correlating) {
  			/* Load the folder results from the DB. */
diff --cc camel/camel-vee-summary.c
index fac3801,20e88f8..d3c909d
--- a/camel/camel-vee-summary.c
+++ b/camel/camel-vee-summary.c
@@@ -487,9 -498,10 +485,10 @@@ camel_vee_summary_add(CamelVeeSummary *
  		g_free (vuid);
  		if (!mi->summary) {
  			mi->summary = summary;
 -			camel_object_ref(summary);
 +			g_object_ref (summary);
  		}
  
+ 		camel_message_info_ref (mi);
  		return mi;
  	}
  
diff --cc camel/providers/groupwise/camel-groupwise-folder.c
index 5e5ee80,61d6dff..07677dc
--- a/camel/providers/groupwise/camel-groupwise-folder.c
+++ b/camel/providers/groupwise/camel-groupwise-folder.c
@@@ -92,11 -94,12 +92,12 @@@ static void gw_update_all_items ( Camel
  static void groupwise_populate_details_from_item (CamelMimeMessage *msg, EGwItem *item);
  static void groupwise_populate_msg_body_from_item (EGwConnection *cnc, CamelMultipart *multipart, EGwItem *item, gchar *body);
  static void groupwise_msg_set_recipient_list (CamelMimeMessage *msg, EGwItem *item);
 -static void gw_update_cache ( CamelFolder *folder, GList *item_list, CamelException *ex, gboolean uid_flag);
 -static CamelMimeMessage *groupwise_folder_item_to_msg ( CamelFolder *folder, EGwItem *item, CamelException *ex );
 -static gchar * groupwise_get_filename (CamelFolder *folder, const gchar *uid, CamelException *ex);
 +static void gw_update_cache ( CamelFolder *folder, GList *item_list, GError **error, gboolean uid_flag);
 +static CamelMimeMessage *groupwise_folder_item_to_msg ( CamelFolder *folder, EGwItem *item, GError **error );
 +static gchar * groupwise_get_filename (CamelFolder *folder, const gchar *uid, GError **error);
  static const gchar *get_from_from_org (EGwItemOrganizer *org);
 -static void groupwise_refresh_folder(CamelFolder *folder, CamelException *ex);
 -static void groupwise_sync (CamelFolder *folder, gboolean expunge, CamelMessageInfo *update_single, CamelException *ex);
 +static void groupwise_refresh_folder(CamelFolder *folder, GError **error);
++static gboolean groupwise_sync (CamelFolder *folder, gboolean expunge, CamelMessageInfo *update_single, GError **error);
  
  #define d(x)
  
@@@ -706,9 -689,44 +707,39 @@@ sync_flags (CamelFolder *folder, GList 
  	}
  }
  
+ static gboolean
+ groupwise_set_message_flags (CamelFolder *folder, const gchar *uid, guint32 flags, guint32 set)
+ {
+ 	CamelMessageInfo *info;
+ 	gint res;
+ 	const gchar *sync_immediately;
+ 
+ 	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);
+ 
+ 	sync_immediately = g_getenv ("GW_SYNC_IMMEDIATE");
+ 
 -	if (sync_immediately) {
 -		CamelException ex;
 -
 -		camel_exception_init (&ex);
 -		groupwise_sync (folder, FALSE, info, &ex);
 -		camel_exception_clear (&ex);
 -	}
++	if (sync_immediately)
++		groupwise_sync (folder, FALSE, info, NULL);
+ 
+ 	camel_message_info_free (info);
+ 	return res;
+ }
+ 
 -static void
 -groupwise_sync_all (CamelFolder *folder, gboolean expunge, CamelException *ex)
++static gboolean
++groupwise_sync_all (CamelFolder *folder, gboolean expunge, GError **error)
+ {
 -	groupwise_sync (folder, expunge, NULL, ex);
++	return groupwise_sync (folder, expunge, NULL, error);
+ }
+ 
  /* This may need to be reorganized. */
 -static void
 -groupwise_sync (CamelFolder *folder, gboolean expunge, CamelMessageInfo *update_single, CamelException *ex)
 +static gboolean
- groupwise_sync (CamelFolder *folder, gboolean expunge, GError **error)
++groupwise_sync (CamelFolder *folder, gboolean expunge, CamelMessageInfo *update_single, GError **error)
  {
  	CamelGroupwiseStore *gw_store = CAMEL_GROUPWISE_STORE (folder->parent_store);
  	CamelGroupwiseFolder *gw_folder = CAMEL_GROUPWISE_FOLDER (folder);
@@@ -1272,7 -1296,7 +1311,7 @@@ groupwise_refresh_folder(CamelFolder *f
  
  	/* Sync-up the (un)read changes before getting updates,
  	so that the getFolderList will reflect the most recent changes too */
- 	/*groupwise_sync (folder, FALSE, ex);*/
 -	groupwise_sync_all (folder, FALSE, ex);
++	groupwise_sync_all (folder, FALSE, error);
  
  	if (((CamelOfflineStore *) gw_store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
  		g_warning ("In offline mode. Cannot refresh!!!\n");
@@@ -2775,43 -2776,10 +2814,44 @@@ groupwise_folder_dispose (GObject *obje
  }
  
  static void
 -camel_groupwise_folder_init (gpointer object, gpointer klass)
 +groupwise_folder_class_init (CamelGroupwiseFolderClass *class)
  {
 -	CamelGroupwiseFolder *gw_folder = CAMEL_GROUPWISE_FOLDER (object);
 -	CamelFolder *folder = CAMEL_FOLDER (object);
 +	GObjectClass *object_class;
 +	CamelObjectClass *camel_object_class;
 +	CamelFolderClass *folder_class;
 +
 +	parent_class = g_type_class_peek_parent (class);
 +	g_type_class_add_private (class, sizeof (CamelGroupwiseFolderPrivate));
 +
 +	object_class = G_OBJECT_CLASS (class);
 +	object_class->dispose = groupwise_folder_dispose;
 +
 +	camel_object_class = CAMEL_OBJECT_CLASS (class);
 +	camel_object_class->getv = gw_getv;
 +
 +	folder_class = CAMEL_FOLDER_CLASS (class);
 +	folder_class->get_message = groupwise_folder_get_message;
 +	folder_class->rename = groupwise_folder_rename;
 +	folder_class->search_by_expression = groupwise_folder_search_by_expression;
 +	folder_class->count_by_expression = groupwise_folder_count_by_expression;
 +	folder_class->cmp_uids = groupwise_cmp_uids;
 +	folder_class->search_by_uids = groupwise_folder_search_by_uids;
 +	folder_class->search_free = groupwise_folder_search_free;
 +	folder_class->append_message = groupwise_append_message;
 +	folder_class->refresh_info = groupwise_refresh_info;
- 	folder_class->sync = groupwise_sync;
++	folder_class->sync = groupwise_sync_all;
++	folder_class->set_message_flags = groupwise_set_message_flags;
 +	folder_class->expunge = groupwise_expunge;
 +	folder_class->transfer_messages_to = groupwise_transfer_messages_to;
 +	folder_class->get_filename = groupwise_get_filename;
 +}
 +
 +static void
 +groupwise_folder_init (CamelGroupwiseFolder *gw_folder)
 +{
 +	CamelFolder *folder = CAMEL_FOLDER (gw_folder);
 +
 +	gw_folder->priv = CAMEL_GROUPWISE_FOLDER_GET_PRIVATE (gw_folder);
  
  	folder->permanent_flags = CAMEL_MESSAGE_ANSWERED | CAMEL_MESSAGE_DELETED |
  		CAMEL_MESSAGE_DRAFT | CAMEL_MESSAGE_FLAGGED | CAMEL_MESSAGE_SEEN;
diff --cc camel/providers/imapx/camel-imapx-folder.c
index 0ff98a6,a96f77d..bf05fcb
--- a/camel/providers/imapx/camel-imapx-folder.c
+++ b/camel/providers/imapx/camel-imapx-folder.c
@@@ -93,19 -111,26 +110,26 @@@ camel_imapx_folder_close(CamelIMAPXFold
  #endif
  
  static void
 -imapx_refresh_info (CamelFolder *folder, CamelException *ex)
 +imapx_refresh_info (CamelFolder *folder, GError **error)
  {
- 	CamelIMAPXStore *is = (CamelIMAPXStore *)folder->parent_store;
+ 	CamelIMAPXStore *istore = (CamelIMAPXStore *)folder->parent_store;
  
- 	if (is->server)
- 		camel_imapx_server_refresh_info(is->server, folder, ex);
+ 	if (CAMEL_OFFLINE_STORE (istore)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
+ 		return;
+ 
+ 	if (istore->server) {
+ 		camel_imapx_server_connect (istore->server, 1);
+ 
+ 		camel_imapx_server_refresh_info(istore->server, folder, ex);
+ 	}
  
  }
  
  static void
 -imapx_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
 +imapx_sync (CamelFolder *folder, gboolean expunge, GError **error)
  {
  	CamelIMAPXStore *is = (CamelIMAPXStore *)folder->parent_store;
+ 	GPtrArray *changed_uids;
  
  	/* Sync twice - make sure deleted flags are written out,
  	   then sync again incase expunge changed anything */
diff --cc camel/providers/imapx/camel-imapx-server.c
index 93e21c6,16a0c4c..ce3eedc
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@@ -935,9 -938,43 +938,43 @@@ imapx_expunged(CamelIMAPXServer *imap
  	g_array_set_size(imap->expunged, 0); */
  }
  
+ static void
+ update_summary (CamelFolderSummary *summary, CamelMessageInfoBase *info)
+ {
+ 	gint unread=0, deleted=0, junk=0;
+ 	guint32 flags = info->flags;
+ 
+ 	if (!(flags & CAMEL_MESSAGE_SEEN))
+ 		unread = 1;
+ 
+ 	if (flags & CAMEL_MESSAGE_DELETED)
+ 		deleted = 1;
+ 
+ 	if (flags & CAMEL_MESSAGE_JUNK)
+ 		junk = 1;
+ 
+ 	if (summary) {
+ 
+ 		if (unread)
+ 			summary->unread_count += unread;
+ 		if (deleted)
+ 			summary->deleted_count += deleted;
+ 		if (junk)
+ 			summary->junk_count += junk;
+ 		if (junk && !deleted)
+ 			summary->junk_not_deleted_count += junk;
+ 		summary->visible_count++;
+ 		if (junk ||  deleted)
+ 			summary->visible_count -= junk ? junk : deleted;
+ 
+ 		summary->saved_count++;
+ 		camel_folder_summary_touch(summary);
+ 	}
+ }
+ 
  /* handle any untagged responses */
  static gint
 -imapx_untagged(CamelIMAPXServer *imap, CamelException *ex)
 +imapx_untagged(CamelIMAPXServer *imap, GError **error)
  {
  	guint id, len;
  	guchar *token, *p, c;
@@@ -1256,15 -1326,18 +1326,18 @@@ imapx_continuation(CamelIMAPXServer *im
  
  /* handle a completion line */
  static gint
 -imapx_completion(CamelIMAPXServer *imap, guchar *token, gint len, CamelException *ex)
 +imapx_completion(CamelIMAPXServer *imap, guchar *token, gint len, GError **error)
  {
- 	CamelIMAPXCommand * volatile ic;
+ 	CamelIMAPXCommand *ic;
  	guint tag;
  
- 	if (token[0] != imap->tagprefix)
- 		camel_exception_throw(1, "Server sent unexpected response: %s", token);
+ 	if (token[0] != imap->tagprefix) {
+ 		camel_exception_setv (ex, 1, "Server sent unexpected response: %s", token);
  
- 	tag = strtoul(token+1, NULL, 10);
+ 		return -1;
+ 	}
+ 
+ 	tag = strtoul( (const gchar *)token+1, NULL, 10);
  
  	QUEUE_LOCK(imap);
  	if ((ic = imapx_find_command_tag(imap, tag)) == NULL) {
@@@ -2612,10 -2941,10 +2941,10 @@@ getmsgs(gpointer d
  	pthread_mutex_unlock(&lock);
  
  	return NULL;
- }
+ } */
  
  void
 -camel_imapx_server_refresh_info(CamelIMAPXServer *is, CamelFolder *folder, CamelException *ex)
 +camel_imapx_server_refresh_info(CamelIMAPXServer *is, CamelFolder *folder, GError **error)
  {
  	CamelIMAPXJob *job;
  
diff --cc camel/providers/imapx/camel-imapx-server.h
index 3b3649c,7d7579c..8a4622d
--- a/camel/providers/imapx/camel-imapx-server.h
+++ b/camel/providers/imapx/camel-imapx-server.h
@@@ -94,15 -98,15 +98,15 @@@ struct _CamelIMAPXServerClass 
  CamelType               camel_imapx_server_get_type     (void);
  CamelIMAPXServer *camel_imapx_server_new(struct _CamelStore *store, struct _CamelURL *url);
  
- void camel_imapx_server_connect(CamelIMAPXServer *is, gint state);
+ gboolean camel_imapx_server_connect(CamelIMAPXServer *is, gint state);
  
 -GPtrArray *camel_imapx_server_list(CamelIMAPXServer *is, const gchar *top, guint32 flags, CamelException *ex);
 +GPtrArray *camel_imapx_server_list(CamelIMAPXServer *is, const gchar *top, guint32 flags, GError **error);
  
 -void camel_imapx_server_refresh_info(CamelIMAPXServer *is, CamelFolder *folder, struct _CamelException *ex);
 -void camel_imapx_server_sync_changes(CamelIMAPXServer *is, CamelFolder *folder, GPtrArray *infos, CamelException *ex);
 -void camel_imapx_server_expunge(CamelIMAPXServer *is, CamelFolder *folder, CamelException *ex);
 +void camel_imapx_server_refresh_info(CamelIMAPXServer *is, CamelFolder *folder, struct _GError **error);
 +void camel_imapx_server_sync_changes(CamelIMAPXServer *is, CamelFolder *folder, GPtrArray *infos, GError **error);
 +void camel_imapx_server_expunge(CamelIMAPXServer *is, CamelFolder *folder, GError **error);
  
 -CamelStream *camel_imapx_server_get_message(CamelIMAPXServer *is, CamelFolder *folder, const gchar *uid, struct _CamelException *ex);
 -void camel_imapx_server_append_message(CamelIMAPXServer *is, CamelFolder *folder, struct _CamelMimeMessage *message, const struct _CamelMessageInfo *mi, CamelException *ex);
 +CamelStream *camel_imapx_server_get_message(CamelIMAPXServer *is, CamelFolder *folder, const gchar *uid, struct _GError **error);
 +void camel_imapx_server_append_message(CamelIMAPXServer *is, CamelFolder *folder, struct _CamelMimeMessage *message, const struct _CamelMessageInfo *mi, GError **error);
  
  #endif /* ! _CAMEL_IMAPX_SERVER_H */
diff --cc camel/providers/imapx/camel-imapx-store.c
index 0d0d670,7162cc9..9224b79
--- a/camel/providers/imapx/camel-imapx-store.c
+++ b/camel/providers/imapx/camel-imapx-store.c
@@@ -83,9 -84,9 +83,9 @@@ imapx_name_equal(gconstpointer a, gcons
  	return g_str_equal(aname, bname);
  }
  
 -static void imap_construct(CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, CamelException *ex)
 +static void imap_construct(CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, GError **error)
  {
- 	gchar *base, *summary;
+ 	gchar *summary;
  	CamelIMAPXStore *store = (CamelIMAPXStore *)service;
  
  	CAMEL_SERVICE_CLASS (parent_class)->construct (service, session, provider, url, ex);
@@@ -246,9 -249,8 +248,8 @@@ get_folder_offline (CamelStore *store, 
  }
  
  static CamelFolder *
 -imap_get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, CamelException *ex)
 +imap_get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError **error)
  {
- 	CamelIMAPXStore *istore = (CamelIMAPXStore *)store;
  	CamelFolder *folder;
  
  	folder = get_folder_offline(store, folder_name, flags, ex);
diff --cc camel/providers/imapx/camel-imapx-utils.c
index 78b0c4a,792a79f..4526e07
--- a/camel/providers/imapx/camel-imapx-utils.c
+++ b/camel/providers/imapx/camel-imapx-utils.c
@@@ -152,12 -211,13 +211,13 @@@ struct 
  };
  
  struct _capability_info *
 -imap_parse_capability(CamelIMAPXStream *stream, CamelException *ex)
 +imap_parse_capability(CamelIMAPXStream *stream, GError **error)
  {
- 	gint tok, len, i;
- 	guchar *token, *p, c, *temp;
+ 	gint tok, i;
+ 	guint len;
+ 	guchar *token, *p, c;
  	gboolean free_token = FALSE;
- 	struct _capability_info * volatile cinfo;
+ 	struct _capability_info * cinfo;
  
  	cinfo = g_malloc0(sizeof(*cinfo));
  
@@@ -443,10 -505,12 +505,12 @@@ imap_free_body(struct _CamelMessageCont
  }
  
  void
 -imap_parse_param_list(CamelIMAPXStream *is, struct _camel_header_param **plist, CamelException *ex)
 +imap_parse_param_list(CamelIMAPXStream *is, struct _camel_header_param **plist, GError **error)
  {
- 	gint tok, len;
- 	guchar *token, *param;
+ 	gint tok;
+ 	guint len;
+ 	guchar *token;
+ 	gchar *param;
  
  	p(printf("body_fld_param\n"));
  
@@@ -469,9 -533,10 +533,10 @@@
  }
  
  struct _CamelContentDisposition *
 -imap_parse_ext_optional(CamelIMAPXStream *is, CamelException *ex)
 +imap_parse_ext_optional(CamelIMAPXStream *is, GError **error)
  {
- 	gint tok, len;
+ 	gint tok;
+ 	guint len;
  	guchar *token;
  	struct _CamelContentDisposition *dinfo = NULL;
  
@@@ -555,9 -620,10 +620,10 @@@
  }
  
  struct _CamelMessageContentInfo *
 -imap_parse_body_fields(CamelIMAPXStream *is, CamelException *ex)
 +imap_parse_body_fields(CamelIMAPXStream *is, GError **error)
  {
- 	guchar *token, *type;
+ 	guchar *token;
+ 	gchar  *type;
  	struct _CamelMessageContentInfo *cinfo;
  
  	/* body_fields     ::= body_fld_param SPACE body_fld_id SPACE
@@@ -613,11 -679,13 +679,13 @@@ error
  }
  
  struct _camel_header_address *
 -imap_parse_address_list(CamelIMAPXStream *is, CamelException *ex)
 +imap_parse_address_list(CamelIMAPXStream *is, GError **error)
  /* throws PARSE,IO exception */
  {
- 	gint tok, len;
- 	guchar *token, *host, *mbox;
+ 	gint tok;
+ 	guint len;
+ 	guchar *token, *host;
+ 	gchar *mbox;
  	struct _camel_header_address *list = NULL;
  
  	/* "(" 1*address ")" / nil */
@@@ -690,9 -758,10 +758,10 @@@
  }
  
  struct _CamelMessageInfo *
 -imap_parse_envelope(CamelIMAPXStream *is, CamelException *ex)
 +imap_parse_envelope(CamelIMAPXStream *is, GError **error)
  {
- 	gint tok, len;
+ 	gint tok;
+ 	guint len;
  	guchar *token;
  	struct _camel_header_address *addr, *addr_from;
  	gchar *addrstr;
@@@ -800,14 -869,15 +869,15 @@@
  }
  
  struct _CamelMessageContentInfo *
 -imap_parse_body(CamelIMAPXStream *is, CamelException *ex)
 +imap_parse_body(CamelIMAPXStream *is, GError **error)
  {
- 	gint tok, len;
+ 	gint tok;
+ 	guint len;
  	guchar *token;
- 	struct _CamelMessageContentInfo * volatile cinfo = NULL;
+ 	struct _CamelMessageContentInfo * cinfo = NULL;
  	struct _CamelMessageContentInfo *subinfo, *last;
- 	struct _CamelContentDisposition * volatile dinfo = NULL;
- 	struct _CamelMessageInfo * volatile minfo = NULL;
+ 	struct _CamelContentDisposition * dinfo = NULL;
+ 	struct _CamelMessageInfo * minfo = NULL;
  
  	/* body            ::= "(" body_type_1part / body_type_mpart ")" */
  
@@@ -955,9 -1026,10 +1026,10 @@@
  }
  
  gchar *
 -imap_parse_section(CamelIMAPXStream *is, CamelException *ex)
 +imap_parse_section(CamelIMAPXStream *is, GError **error)
  {
- 	gint tok, len;
+ 	gint tok;
+ 	guint len;
  	guchar *token;
  	gchar * section = NULL;
  
@@@ -1098,9 -1168,10 +1168,10 @@@ imap_dump_fetch(struct _fetch_info *fin
  }
  
  struct _fetch_info *
 -imap_parse_fetch(CamelIMAPXStream *is, CamelException *ex)
 +imap_parse_fetch(CamelIMAPXStream *is, GError **error)
  {
- 	gint tok, len;
+ 	gint tok;
+ 	guint len;
  	guchar *token, *p, c;
  	struct _fetch_info *finfo;
  
@@@ -1201,9 -1272,10 +1272,10 @@@
  /* rfc 2060 section 7.1 Status Responses */
  /* shoudl this start after [ or before the [? token_unget anyone? */
  struct _status_info *
 -imap_parse_status(CamelIMAPXStream *is, CamelException *ex)
 +imap_parse_status(CamelIMAPXStream *is, GError **error)
  {
- 	gint tok, len;
+ 	gint tok;
+ 	guint len;
  	guchar *token;
  	struct _status_info *sinfo;
  
@@@ -1340,12 -1412,13 +1412,13 @@@ static struct 
  };
  
  struct _list_info *
 -imap_parse_list(CamelIMAPXStream *is, CamelException *ex)
 +imap_parse_list(CamelIMAPXStream *is, GError **error)
  /* throws io, parse */
  {
- 	gint tok, len, i;
+ 	gint tok, i;
+ 	guint len;
  	guchar *token, *p, c;
- 	struct _list_info * volatile linfo;
+ 	struct _list_info * linfo;
  
  	linfo = g_malloc0(sizeof(*linfo));
  
diff --cc camel/providers/imapx/test-imapx.c
index 4ea1d6f,2f139d7..0162517
--- a/camel/providers/imapx/test-imapx.c
+++ b/camel/providers/imapx/test-imapx.c
@@@ -8,9 -8,10 +8,10 @@@ gin
  main (gint argc, gchar *argv [])
  {
  	CamelSession *session;
 -	CamelException *ex;
 +	GError **error;
  	gchar *uri = NULL;
  	CamelService *service;
+ 	CamelFolder *folder;
  
  	if (argc != 2) {
  		printf ("Pass the account url argument \n");
diff --cc docs/reference/camel/tmpl/camel-block-file.sgml
index cf08d27,454f9d4..1858aa5
--- a/docs/reference/camel/tmpl/camel-block-file.sgml
+++ b/docs/reference/camel/tmpl/camel-block-file.sgml
@@@ -103,6 -116,6 +103,7 @@@ CamelKeyFil
  @flags: 
  @version: 
  @block_size: 
++ error: 
  @Returns: 
  
  
@@@ -131,6 -144,6 +132,7 @@@
  </para>
  
  @bs: 
++ error: 
  @Returns: 
  
  
@@@ -141,6 -154,6 +143,7 @@@
  
  @bs: 
  @id: 
++ error: 
  @Returns: 
  
  
@@@ -151,6 -164,6 +154,7 @@@
  
  @bs: 
  @id: 
++ error: 
  @Returns: 
  
  
diff --cc docs/reference/camel/tmpl/camel-cipher-context.sgml
index 65842c9,318fedb..9040a62
--- a/docs/reference/camel/tmpl/camel-cipher-context.sgml
+++ b/docs/reference/camel/tmpl/camel-cipher-context.sgml
@@@ -323,6 -324,6 +323,7 @@@ CamelCipherContex
  @part: 
  @flags: 
  @ostream: 
++ error: 
  @Returns: 
  
  
diff --cc docs/reference/camel/tmpl/camel-data-wrapper.sgml
index 11144cc,6a941a7..830d13a
--- a/docs/reference/camel/tmpl/camel-data-wrapper.sgml
+++ b/docs/reference/camel/tmpl/camel-data-wrapper.sgml
@@@ -38,6 -44,6 +38,7 @@@ CamelDataWrappe
  
  @data_wrapper: 
  @stream: 
++ error: 
  @Returns: 
  
  
@@@ -48,6 -54,6 +49,7 @@@
  
  @data_wrapper: 
  @stream: 
++ error: 
  @Returns: 
  
  
@@@ -94,6 -100,6 +96,7 @@@
  
  @data_wrapper: 
  @stream: 
++ error: 
  @Returns: 
  
  
diff --cc docs/reference/camel/tmpl/camel-file-utils.sgml
index 85c7221,85c7221..f38bf88
--- a/docs/reference/camel/tmpl/camel-file-utils.sgml
+++ b/docs/reference/camel/tmpl/camel-file-utils.sgml
@@@ -183,6 -183,6 +183,7 @@@ camel-file-util
  @fd: 
  @buf: 
  @n: 
++ error: 
  @Returns: 
  
  
@@@ -194,6 -194,6 +195,7 @@@
  @fd: 
  @buf: 
  @n: 
++ error: 
  @Returns: 
  
  
@@@ -205,6 -205,6 +207,7 @@@
  @fd: 
  @buf: 
  @n: 
++ error: 
  @Returns: 
  
  
@@@ -216,6 -216,6 +219,7 @@@
  @fd: 
  @buf: 
  @n: 
++ error: 
  @Returns: 
  
  
diff --cc docs/reference/camel/tmpl/camel-http-stream.sgml
index 2885970,1ef6d79..14c6ec4
--- a/docs/reference/camel/tmpl/camel-http-stream.sgml
+++ b/docs/reference/camel/tmpl/camel-http-stream.sgml
@@@ -84,6 -98,6 +84,7 @@@ CamelHttpStrea
  </para>
  
  @http_stream: 
++ error: 
  @Returns: 
  
  
diff --cc docs/reference/camel/tmpl/camel-index.sgml
index 16292e3,a3488fe..dd9b519
--- a/docs/reference/camel/tmpl/camel-index.sgml
+++ b/docs/reference/camel/tmpl/camel-index.sgml
@@@ -125,7 -142,7 +125,7 @@@ CamelInde
  
  </para>
  
-- Param1: 
++ index: 
  @path: 
  @flags: 
  
@@@ -135,7 -152,7 +135,7 @@@
  
  </para>
  
-- Param1: 
++ index: 
  @path: 
  @Returns: 
  
@@@ -156,6 -173,6 +156,7 @@@
  </para>
  
  @idx: 
++ error: 
  @Returns: 
  
  
@@@ -165,6 -182,6 +166,7 @@@
  </para>
  
  @idx: 
++ error: 
  @Returns: 
  
  
diff --cc docs/reference/camel/tmpl/camel-mime-parser.sgml
index d31c7bf,18a207c..b8b6703
--- a/docs/reference/camel/tmpl/camel-mime-parser.sgml
+++ b/docs/reference/camel/tmpl/camel-mime-parser.sgml
@@@ -79,6 -81,6 +79,7 @@@ CamelMimeParse
  
  @m: 
  @stream: 
++ error: 
  @Returns: 
  
  
diff --cc docs/reference/camel/tmpl/camel-mime-part.sgml
index 570c2b2,d916d64..d04089c
--- a/docs/reference/camel/tmpl/camel-mime-part.sgml
+++ b/docs/reference/camel/tmpl/camel-mime-part.sgml
@@@ -229,6 -209,6 +229,7 @@@ CamelMimePar
  
  @mime_part: 
  @parser: 
++ error: 
  @Returns: 
  
  
@@@ -257,8 -237,8 +258,10 @@@
  
  </para>
  
-- Param1: 
++ mime_part: 
  @mp: 
++ error: 
++ Returns: 
  
  
  <!-- ##### FUNCTION camel_mime_message_build_preview ##### -->
diff --cc docs/reference/camel/tmpl/camel-nntp-stream.sgml
index 840db5b,840db5b..699e505
--- a/docs/reference/camel/tmpl/camel-nntp-stream.sgml
+++ b/docs/reference/camel/tmpl/camel-nntp-stream.sgml
@@@ -68,6 -68,6 +68,7 @@@ CamelNNTPStrea
  @is: 
  @data: 
  @len: 
++ error: 
  @Returns: 
  
  
@@@ -79,6 -79,6 +80,7 @@@
  @is: 
  @start: 
  @len: 
++ error: 
  @Returns: 
  
  
@@@ -90,6 -90,6 +92,7 @@@
  @is: 
  @start: 
  @len: 
++ error: 
  @Returns: 
  
  
diff --cc docs/reference/camel/tmpl/camel-partition-table.sgml
index 8f600d7,b9eaafc..c282caf
--- a/docs/reference/camel/tmpl/camel-partition-table.sgml
+++ b/docs/reference/camel/tmpl/camel-partition-table.sgml
@@@ -64,6 -71,6 +64,7 @@@ CamelKeyTabl
  
  @bs: 
  @root: 
++ error: 
  @Returns: 
  
  
@@@ -84,6 -91,6 +85,7 @@@
  @cpi: 
  @key: 
  @keyid: 
++ error: 
  @Returns: 
  
  
@@@ -94,6 -101,6 +96,7 @@@
  
  @cpi: 
  @key: 
++ error: 
  @Returns: 
  
  
@@@ -104,6 -111,6 +107,8 @@@
  
  @cpi: 
  @key: 
++ error: 
++ Returns: 
  
  
  <!-- ##### STRUCT CamelKeyBlock ##### -->
@@@ -150,6 -163,6 +155,7 @@@
  
  @bs: 
  @root: 
++ error: 
  @Returns: 
  
  
@@@ -171,6 -184,6 +177,7 @@@
  @key: 
  @data: 
  @flags: 
++ error: 
  @Returns: 
  
  
@@@ -182,6 -195,6 +189,8 @@@
  @ki: 
  @keyid: 
  @data: 
++ error: 
++ Returns: 
  
  
  <!-- ##### FUNCTION camel_key_table_set_flags ##### -->
@@@ -193,6 -206,6 +202,8 @@@
  @keyid: 
  @flags: 
  @set: 
++ error: 
++ Returns: 
  
  
  <!-- ##### FUNCTION camel_key_table_lookup ##### -->
@@@ -204,6 -217,6 +215,7 @@@
  @keyid: 
  @key: 
  @flags: 
++ error: 
  @Returns: 
  
  
@@@ -217,6 -230,6 +229,7 @@@
  @keyp: 
  @flagsp: 
  @datap: 
++ error: 
  @Returns: 
  
  
diff --cc docs/reference/camel/tmpl/camel-seekable-stream.sgml
index b12cddb,7cee441..cac69e6
--- a/docs/reference/camel/tmpl/camel-seekable-stream.sgml
+++ b/docs/reference/camel/tmpl/camel-seekable-stream.sgml
@@@ -47,6 -51,6 +47,7 @@@ CamelSeekableStrea
  @stream: 
  @offset: 
  @policy: 
++ error: 
  @Returns: 
  
  
@@@ -67,6 -71,6 +68,7 @@@
  @stream: 
  @start: 
  @end: 
++ error: 
  @Returns: 
  
  
diff --cc docs/reference/camel/tmpl/camel-stream-buffer.sgml
index 35348b7,b4b17c0..1be69a6
--- a/docs/reference/camel/tmpl/camel-stream-buffer.sgml
+++ b/docs/reference/camel/tmpl/camel-stream-buffer.sgml
@@@ -64,6 -74,6 +64,7 @@@ CamelStreamBuffe
  @sbf: 
  @buf: 
  @max: 
++ error: 
  @Returns: 
  
  
@@@ -73,6 -83,6 +74,7 @@@
  </para>
  
  @sbf: 
++ error: 
  @Returns: 
  
  
diff --cc docs/reference/camel/tmpl/camel-stream-fs.sgml
index 8947ca6,50b07a0..ee13f8c
--- a/docs/reference/camel/tmpl/camel-stream-fs.sgml
+++ b/docs/reference/camel/tmpl/camel-stream-fs.sgml
@@@ -31,6 -33,6 +31,7 @@@ CamelStreamF
  @name: 
  @flags: 
  @mode: 
++ error: 
  @Returns: 
  
  
@@@ -44,6 -46,6 +45,7 @@@
  @mode: 
  @start: 
  @end: 
++ error: 
  @Returns: 
  
  
diff --cc docs/reference/camel/tmpl/camel-stream.sgml
index 109f381,62b03ee..135a8fe
--- a/docs/reference/camel/tmpl/camel-stream.sgml
+++ b/docs/reference/camel/tmpl/camel-stream.sgml
@@@ -31,6 -33,6 +31,7 @@@ CamelStrea
  @stream: 
  @buffer: 
  @n: 
++ error: 
  @Returns: 
  
  
@@@ -42,6 -44,6 +43,7 @@@
  @stream: 
  @buffer: 
  @n: 
++ error: 
  @Returns: 
  
  
@@@ -51,6 -53,6 +53,7 @@@
  </para>
  
  @stream: 
++ error: 
  @Returns: 
  
  
@@@ -60,6 -62,6 +63,7 @@@
  </para>
  
  @stream: 
++ error: 
  @Returns: 
  
  
@@@ -78,6 -80,6 +82,7 @@@
  </para>
  
  @stream: 
++ error: 
  @Returns: 
  
  
@@@ -88,6 -90,6 +93,7 @@@
  
  @stream: 
  @string: 
++ error: 
  @Returns: 
  
  
@@@ -97,22 -99,22 +103,12 @@@
  </para>
  
  @stream: 
++ error: 
  @fmt: 
  @Varargs: 
  @Returns: 
  
  
--<!-- ##### FUNCTION camel_stream_vprintf ##### -->
--<para>
--
--</para>
--
-- stream: 
-- fmt: 
-- ap: 
-- Returns: 
--
--
  <!-- ##### FUNCTION camel_stream_write_to_stream ##### -->
  <para>
  
@@@ -120,6 -122,6 +116,7 @@@
  
  @stream: 
  @output_stream: 
++ error: 
  @Returns: 
  
  
diff --cc docs/reference/camel/tmpl/camel-tcp-stream.sgml
index 4ddafee,3ef788c..4625f13
--- a/docs/reference/camel/tmpl/camel-tcp-stream.sgml
+++ b/docs/reference/camel/tmpl/camel-tcp-stream.sgml
@@@ -66,6 -67,6 +66,7 @@@ CamelTcpStrea
  
  @stream: 
  @host: 
++ error: 
  @Returns: 
  
  
diff --cc docs/reference/camel/tmpl/camel-text-index.sgml
index ab4bb90,faa0037..cf8891b
--- a/docs/reference/camel/tmpl/camel-text-index.sgml
+++ b/docs/reference/camel/tmpl/camel-text-index.sgml
@@@ -58,6 -66,6 +58,7 @@@ CamelTextInde
  
  @path: 
  @flags: 
++ error: 
  @Returns: 
  
  
@@@ -67,6 -75,6 +68,7 @@@
  </para>
  
  @path: 
++ error: 
  @Returns: 
  
  
diff --cc docs/reference/camel/tmpl/camel-unused.sgml
index 4a9ee9d,f578a14..2305d45
--- a/docs/reference/camel/tmpl/camel-unused.sgml
+++ b/docs/reference/camel/tmpl/camel-unused.sgml
@@@ -1364,6 -703,6 +1364,16 @@@ camel-type
  @handle: 
  @Returns: 
  
++<!-- ##### FUNCTION camel_stream_vprintf ##### -->
++<para>
++
++</para>
++
++ stream: 
++ fmt: 
++ ap: 
++ Returns: 
++
  <!-- ##### FUNCTION camel_text_index_get_type ##### -->
  <para>
  



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