diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/broken-date-parser.c ./broken-date-parser.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/broken-date-parser.c	2007-05-12 09:58:58.000000000 +0200
+++ ./broken-date-parser.c	2007-05-12 10:01:18.000000000 +0200
@@ -122,7 +122,7 @@
 	const unsigned char *start, *end;
 	unsigned int mask;
 	
-	start = date;
+	start = (const unsigned char *)date;
 	while (*start) {
 		/* kill leading whitespace */
 		while (*start && isspace ((int) *start))
@@ -195,7 +195,7 @@
 		return -1;
 	
 	for (wday = 0; wday < 7; wday++)
-		if (!g_ascii_strncasecmp (in, tm_days[wday], 3))
+		if (!g_ascii_strncasecmp ((const char *)in, tm_days[wday], 3))
 			return wday;
 	
 	return -1;  /* unknown week day */
@@ -223,7 +223,7 @@
 		return -1;
 	
 	for (i = 0; i < 12; i++)
-		if (!g_ascii_strncasecmp (in, tm_months[i], 3))
+		if (!g_ascii_strncasecmp ((const char*)in, tm_months[i], 3))
 			return i;
 	
 	return -1;  /* unknown month */
@@ -313,7 +313,7 @@
 				if (len != inlen)
 					continue;
 				
-				if (!strncmp (inptr, tz_offsets[t].name, len))
+				if (!strncmp ((const char*)inptr, tz_offsets[t].name, len))
 					return tz_offsets[t].offset;
 			}
 		}
Only in .: broken-date-parser.lo
Only in .: broken-date-parser.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-address.c ./camel-address.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-address.c	2007-04-20 13:25:00.000000000 +0200
+++ ./camel-address.c	2007-03-11 16:44:11.000000000 +0100
@@ -233,7 +233,7 @@
 void
 camel_address_remove (CamelAddress *addr, int index)
 {
-	g_return_if_fail(CAMEL_IS_ADDRESS(addr));
+	/* g_return_if_fail(CAMEL_IS_ADDRESS(addr)); */
 
 	if (index == -1) {
 		for (index = addr->addresses->len; index>-1; index--)
Only in .: camel-address.lo
Only in .: camel-address.o
Only in .: camel-arg.lo
Only in .: camel-arg.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-block-file.c ./camel-block-file.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-block-file.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-block-file.c	2007-05-12 10:01:18.000000000 +0200
@@ -564,7 +564,7 @@
 		bl = g_malloc0(sizeof(*bl));
 		bl->id = id;
 		if (lseek(bs->fd, id, SEEK_SET) == -1 ||
-		    camel_read (bs->fd, bl->data, CAMEL_BLOCK_SIZE) == -1) {
+		    camel_read (bs->fd, (char*)bl->data, CAMEL_BLOCK_SIZE) == -1) {
 			block_file_unuse(bs);
 			CAMEL_BLOCK_FILE_UNLOCK(bs, cache_lock);
 			g_free(bl);
Only in .: camel-block-file.lo
Only in .: camel-block-file.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel.c ./camel.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel.c	2007-05-12 10:01:18.000000000 +0200
@@ -81,7 +81,7 @@
 	if (initialised)
 		return 0;
 
-	bindtextdomain (GETTEXT_PACKAGE, EVOLUTION_LOCALEDIR);
+	bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
 	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
 
 	camel_debug_init();
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-certdb.c ./camel-certdb.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-certdb.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-certdb.c	2007-05-12 10:01:18.000000000 +0200
@@ -112,14 +112,11 @@
 	
 	certdb->cert_size = sizeof (CamelCert);
 	
-	certdb->cert_chunks = NULL;
-	
 	certdb->certs = g_ptr_array_new ();
 	certdb->cert_hash = g_hash_table_new (g_str_hash, g_str_equal);
 	
 	certdb->priv->db_lock = g_mutex_new ();
 	certdb->priv->io_lock = g_mutex_new ();
-	certdb->priv->alloc_lock = g_mutex_new ();
 	certdb->priv->ref_lock = g_mutex_new ();
 }
 
@@ -140,12 +137,8 @@
 	
 	g_free (certdb->filename);
 	
-	if (certdb->cert_chunks)
-		e_memchunk_destroy (certdb->cert_chunks);
-	
 	g_mutex_free (p->db_lock);
 	g_mutex_free (p->io_lock);
-	g_mutex_free (p->alloc_lock);
 	g_mutex_free (p->ref_lock);
 	
 	g_free (p);
@@ -478,10 +471,7 @@
 {
 	CamelCert *cert;
 	
-	if (certdb->cert_chunks)
-		cert = e_memchunk_alloc0 (certdb->cert_chunks);
-	else
-		cert = g_malloc0 (certdb->cert_size);
+	cert = g_slice_alloc0 (certdb->cert_size);
 	
 	cert->refcount = 1;
 	
@@ -491,17 +481,9 @@
 CamelCert *
 camel_certdb_cert_new (CamelCertDB *certdb)
 {
-	CamelCert *cert;
-	
 	g_return_val_if_fail (CAMEL_IS_CERTDB (certdb), NULL);
-	
-	CAMEL_CERTDB_LOCK (certdb, alloc_lock);
-	
-	cert = CAMEL_CERTDB_GET_CLASS (certdb)->cert_new (certdb);
-	
-	CAMEL_CERTDB_UNLOCK (certdb, alloc_lock);
-	
-	return cert;
+
+	return CAMEL_CERTDB_GET_CLASS (certdb)->cert_new (certdb);
 }
 
 void
@@ -536,10 +518,7 @@
 	
 	if (cert->refcount <= 1) {
 		CAMEL_CERTDB_GET_CLASS (certdb)->cert_free (certdb, cert);
-		if (certdb->cert_chunks)
-			e_memchunk_free (certdb->cert_chunks, cert);
-		else
-			g_free (cert);
+		g_slice_free1(certdb->cert_size, cert);
 	} else {
 		cert->refcount--;
 	}
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-certdb.h ./camel-certdb.h
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-certdb.h	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-certdb.h	2007-05-12 10:01:18.000000000 +0200
@@ -79,8 +79,6 @@
 	
 	guint32 cert_size;
 	
-	struct _EMemChunk *cert_chunks;
-	
 	GPtrArray *certs;
 	GHashTable *cert_hash;
 };
Only in .: camel-certdb.lo
Only in .: camel-certdb.o
Only in .: camel-charset-map.lo
Only in .: camel-charset-map.o
Only in .: camel-cipher-context.lo
Only in .: camel-cipher-context.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-data-cache.c ./camel-data-cache.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-data-cache.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-data-cache.c	2007-05-12 10:01:18.000000000 +0200
@@ -132,7 +132,7 @@
 {
 	CamelDataCache *cdc;
 
-	if (g_mkdir_with_parents (path, 0700) == -1) {
+	if (e_util_mkdir_hier (path, 0700) == -1) {
 		camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
 				     _("Unable to create cache path"));
 		return NULL;
@@ -227,6 +227,84 @@
 	g_dir_close(dir);
 }
 
+
+void 
+camel_data_cache_set_flags (CamelDataCache *cdc, const char *path, CamelMessageInfoBase *mi)
+{
+	char mystring [512];
+	guint32 hash;
+	hash = g_str_hash(mi->uid);
+	hash = (hash>>5)&CAMEL_DATA_CACHE_MASK;
+
+	snprintf (mystring, 512, "%s/%s/%02x/%s", cdc->path, path, hash, mi->uid);
+
+	if (g_file_test (mystring, G_FILE_TEST_IS_REGULAR))
+	{
+		mi->flags |= CAMEL_MESSAGE_CACHED;
+		snprintf (mystring, 512, "%s/%s/%02x/%s.ispartial", cdc->path, path, hash, mi->uid);
+		if (g_file_test (mystring, G_FILE_TEST_IS_REGULAR))
+			mi->flags |= CAMEL_MESSAGE_PARTIAL;
+		else
+			mi->flags &= ~CAMEL_MESSAGE_PARTIAL;
+	} else {
+		mi->flags &= ~CAMEL_MESSAGE_CACHED;
+		mi->flags &= ~CAMEL_MESSAGE_PARTIAL;
+	}
+}
+
+gboolean
+camel_data_cache_is_partial (CamelDataCache *cdc, const char *path,
+					      const char *uid)
+{
+	gboolean retval = FALSE;
+	gchar *mpath; char *dir;
+	guint32 hash;
+	hash = g_str_hash(uid);
+	hash = (hash>>5)&CAMEL_DATA_CACHE_MASK;
+	dir = alloca(strlen(cdc->path) + strlen(path) + 8);
+	sprintf(dir, "%s/%s/%02x", cdc->path, path, hash);
+
+	mpath = g_strdup_printf ("%s/%s.ispartial", dir, uid);
+
+	retval = g_file_test (mpath, G_FILE_TEST_IS_REGULAR);
+
+	g_free (mpath);
+
+	return retval;
+}
+
+
+void
+camel_data_cache_set_partial (CamelDataCache *cdc, const char *path,
+					      const char *uid, gboolean partial)
+{
+	int fd; char *dir;
+	gchar *mpath;
+	guint32 hash;
+	hash = g_str_hash(uid);
+	hash = (hash>>5)&CAMEL_DATA_CACHE_MASK;
+	dir = alloca(strlen(cdc->path) + strlen(path) + 8);
+	sprintf(dir, "%s/%s/%02x", cdc->path, path, hash);
+
+	mpath = g_strdup_printf ("%s/%s.ispartial", dir, uid);
+	
+	if (!partial)
+	{
+		if (g_file_test (mpath, G_FILE_TEST_IS_REGULAR))
+			g_unlink (mpath);
+	} else {
+		if (!g_file_test (mpath, G_FILE_TEST_IS_REGULAR))
+		{
+		    fd = g_open (mpath, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0600);
+		    if (fd) close (fd);
+		}
+	}
+
+	g_free (mpath);
+
+}
+
+
 /* Since we have to stat the directory anyway, we use this opportunity to
    lazily expire old data.
    If it is this directories 'turn', and we haven't done it for CYCLE_TIME seconds,
@@ -248,7 +326,7 @@
 	if (access (dir, F_OK) == -1) {
 #endif
 		if (create)
-			g_mkdir_with_parents (dir, 0700);
+			e_util_mkdir_hier (dir, 0700);
 	} else if (cdc->priv->expire_inc == hash
 		   && (cdc->expire_age != -1 || cdc->expire_access != -1)) {
 		time_t now;
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-data-cache.h ./camel-data-cache.h
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-data-cache.h	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-data-cache.h	2007-05-12 10:00:17.000000000 +0200
@@ -28,6 +28,7 @@
 
 #include <camel/camel-stream.h>
 #include <camel/camel-exception.h>
+#include <camel/camel-folder-summary.h>
 
 #define CAMEL_DATA_CACHE_TYPE     (camel_data_cache_get_type ())
 #define CAMEL_DATA_CACHE(obj)     (CAMEL_CHECK_CAST((obj), CAMEL_DATA_CACHE_TYPE, CamelFolder))
@@ -85,6 +86,15 @@
 int             camel_data_cache_clear(CamelDataCache *cache,
 				       const char *path, CamelException *ex);
 
+
+gboolean     camel_data_cache_is_partial (CamelDataCache *cache, const char *path,
+					      const char *uid);
+
+void         camel_data_cache_set_partial (CamelDataCache *cache, const char *path,
+					      const char *uid, gboolean partial);
+
+void camel_data_cache_set_flags (CamelDataCache *cdc, const char *path, CamelMessageInfoBase *mi);
+
 /* Standard Camel function */
 CamelType camel_data_cache_get_type (void);
 
Only in .: camel-data-cache.lo
Only in .: camel-data-cache.o
Only in .: camel-data-wrapper.lo
Only in .: camel-data-wrapper.o
Only in .: camel-debug.lo
Only in .: camel-debug.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-digest-folder.c ./camel-digest-folder.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-digest-folder.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-digest-folder.c	2007-05-12 10:01:18.000000000 +0200
@@ -53,7 +53,7 @@
 
 /* message manipulation */
 static CamelMimeMessage *digest_get_message (CamelFolder *folder, const gchar *uid,
-					     CamelException *ex);
+					     CamelFolderReceiveType type, gint param, CamelException *ex);
 static void digest_append_message (CamelFolder *folder, CamelMimeMessage *message,
 				   const CamelMessageInfo *info, char **appended_uid, CamelException *ex);
 static void digest_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
@@ -282,7 +282,7 @@
 }
 
 static CamelMimeMessage *
-digest_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
+digest_get_message (CamelFolder *folder, const char *uid, CamelFolderReceiveType type, gint param, CamelException *ex)
 {
 	CamelDigestFolder *digest = CAMEL_DIGEST_FOLDER (folder);
 	CamelDataWrapper *wrapper;
@@ -290,6 +290,9 @@
 	CamelMimePart *part;
 	char *subuid;
 	int id;
+
+	/* TNY TODO: Implement partial message retrieval if full==TRUE 
+	   (after figuring out what a digest folder does, of course) */
 	
 	part = CAMEL_MIME_PART (digest->priv->message);
 	wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (part));
Only in .: camel-digest-folder.lo
Only in .: camel-digest-folder.o
Only in .: camel-digest-store.lo
Only in .: camel-digest-store.o
Only in .: camel-digest-summary.lo
Only in .: camel-digest-summary.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-disco-diary.c ./camel-disco-diary.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-disco-diary.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-disco-diary.c	2007-05-12 10:01:18.000000000 +0200
@@ -285,7 +285,6 @@
 {
 	guint32 action;
 	off_t size;
-	double pc;
 
 	d(printf("disco diary replay\n"));
 
@@ -296,8 +295,7 @@
 
 	camel_operation_start (NULL, _("Resynchronizing with server"));
 	while (!camel_exception_is_set (ex)) {
-		pc = ftell (diary->file) / size;
-		camel_operation_progress (NULL, pc * 100);
+		camel_operation_progress (NULL, ftell (diary->file) , size);
 
 		if (camel_file_util_decode_uint32 (diary->file, &action) == -1)
 			break;
@@ -337,7 +335,8 @@
 				continue;
 			}
 
-			message = camel_folder_get_message (folder, uid, NULL);
+			/* TNY TODO Partial message retrieval exception */
+			message = camel_folder_get_message (folder, uid, CAMEL_FOLDER_RECEIVE_FULL, -1, NULL);
 			if (!message) {
 				/* The message was appended and then deleted. */
 				g_free (uid);
Only in .: camel-disco-diary.lo
Only in .: camel-disco-diary.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-disco-folder.c ./camel-disco-folder.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-disco-folder.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-disco-folder.c	2007-05-12 10:01:18.000000000 +0200
@@ -106,9 +106,8 @@
 
 	if (m->changes) {
 		for (i=0;i<m->changes->uid_added->len;i++) {
-			int pc = i * 100 / m->changes->uid_added->len;
-
-			camel_operation_progress(NULL, pc);
+			
+			camel_operation_progress(NULL, i, m->changes->uid_added->len);
 			camel_disco_folder_cache_message((CamelDiscoFolder *)m->folder,
 							 m->changes->uid_added->pdata[i],
 							 &mm->ex);
@@ -478,10 +477,9 @@
 	}
 
 	for (i = 0; i < uids->len; i++) {
-		int pc = i * 100 / uids->len;
-
+		
 		camel_disco_folder_cache_message (disco_folder, uids->pdata[i], ex);
-		camel_operation_progress(NULL, pc);
+		camel_operation_progress(NULL, i, uids->len);
 		if (camel_exception_is_set (ex))
 			break;
 	}
Only in .: camel-disco-folder.lo
Only in .: camel-disco-folder.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-disco-store.c ./camel-disco-store.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-disco-store.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-disco-store.c	2007-05-12 10:01:18.000000000 +0200
@@ -256,12 +256,12 @@
 		return CDS_CLASS (store)->get_folder_info_online (store, top, flags, ex);
 		
 	case CAMEL_DISCO_STORE_OFFLINE:
-		/* Can't edit subscriptions while offline */
+		/* Can't edit subscriptions while offline 
 		if ((store->flags & CAMEL_STORE_SUBSCRIPTIONS) &&
 		    !(flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED)) {
 			camel_disco_store_check_online (disco_store, ex);
 			return NULL;
-		}
+		}*/
 		
 		return CDS_CLASS (store)->get_folder_info_offline (store, top, flags, ex);
 		
Only in .: camel-disco-store.lo
Only in .: camel-disco-store.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-exception.c ./camel-exception.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-exception.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-exception.c	2007-05-12 10:01:18.000000000 +0200
@@ -39,16 +39,6 @@
 /* dont turn this off */
 #define w(x) x
 
-/* i dont know why gthread_mutex stuff even exists, this is easier */
-
-/* also, i'm not convinced mutexes are needed here.  But it
-   doesn't really hurt either */
-static pthread_mutex_t exception_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-#define CAMEL_EXCEPTION_LOCK(e) (pthread_mutex_lock(&exception_mutex))
-#define CAMEL_EXCEPTION_UNLOCK(e) (pthread_mutex_unlock(&exception_mutex))
-
-static EMemChunk *exception_chunks = NULL;
 
 /**
  * camel_exception_new: allocate a new exception object. 
@@ -62,19 +52,12 @@
 {
 	CamelException *ex;
 
-	CAMEL_EXCEPTION_LOCK(exception);
-
-	if (exception_chunks == NULL)
-		exception_chunks = e_memchunk_new(16, sizeof(CamelException));
-
-	ex = e_memchunk_alloc(exception_chunks);
+	ex = g_slice_new (CamelException);
 	ex->desc = NULL;
 
 	/* set the Exception Id to NULL */
 	ex->id = CAMEL_EXCEPTION_NONE;
 
-	CAMEL_EXCEPTION_UNLOCK(exception);
-
 	return ex;
 }
 
@@ -109,14 +92,10 @@
 	if (!exception)
 		return;
 
-	CAMEL_EXCEPTION_LOCK(exception);
-
 	if (exception->desc)
 		g_free (exception->desc);
 	exception->desc = NULL;
 	exception->id = CAMEL_EXCEPTION_NONE;
-
-	CAMEL_EXCEPTION_UNLOCK(exception);
 }
 
 /**
@@ -135,11 +114,7 @@
 	if (exception->desc)
 		g_free (exception->desc);
 
-	CAMEL_EXCEPTION_LOCK(exception);
-
-	e_memchunk_free(exception_chunks, exception);
-
-	CAMEL_EXCEPTION_UNLOCK(exception);
+	g_slice_free (CamelException, exception);
 }
 
 /**
@@ -161,20 +136,13 @@
 {
 	if (camel_debug("exception"))
 		printf("CamelException.set(%p, %u, '%s')\n", ex, id, desc);
-
 	if (!ex)
 		return;
-
-	CAMEL_EXCEPTION_LOCK(exception);
-
 	ex->id = id;
-
 	if (desc != ex->desc) {
 		g_free (ex->desc);
 		ex->desc = g_strdup (desc);
 	}
-
-	CAMEL_EXCEPTION_UNLOCK(exception);
 }
 
 /**
@@ -215,13 +183,9 @@
 		return;
 	}
 
-	CAMEL_EXCEPTION_LOCK(exception);
-
 	g_free(ex->desc);
 	ex->desc = desc;
 	ex->id = id;
-
-	CAMEL_EXCEPTION_UNLOCK(exception);
 }
 
 /**
@@ -248,8 +212,6 @@
 		return;
 	}
 
-	CAMEL_EXCEPTION_LOCK(exception);
-
 	if (ex_dst->desc)
 		g_free (ex_dst->desc);
 
@@ -258,8 +220,6 @@
 
 	ex_src->desc = NULL;
 	ex_src->id = CAMEL_EXCEPTION_NONE;
-
-	CAMEL_EXCEPTION_UNLOCK(exception);
 }
 
 /**
Only in .: camel-exception.lo
Only in .: camel-exception.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-file-utils.c ./camel-file-utils.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-file-utils.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-file-utils.c	2007-05-12 10:01:18.000000000 +0200
@@ -47,137 +47,120 @@
 #include "camel-operation.h"
 #include "camel-url.h"
 
-#define IO_TIMEOUT (60*4)
+#define IO_TIMEOUT (15*4)
+
 
 /**
- * camel_file_util_encode_uint32:
+ * camel_file_util_encode_fixed_int32:
  * @out: file to output to
  * @value: value to output
  * 
- * Utility function to save an uint32 to a file.
+ * Encode a gint32, performing no compression, but converting
+ * to network order.
  * 
  * Return value: 0 on success, -1 on error.
  **/
 int
-camel_file_util_encode_uint32 (FILE *out, guint32 value)
+camel_file_util_encode_fixed_int32 (FILE *out, gint32 value)
 {
-	int i;
+	guint32 save;
 
-	for (i = 28; i > 0; i -= 7) {
-		if (value >= (1 << i)) {
-			unsigned int c = (value >> i) & 0x7f;
-			if (fputc (c, out) == -1)
-				return -1;
-		}
-	}
-	return fputc (value | 0x80, out);
+	save = g_htonl (value);
+	if (fwrite (&save, sizeof (save), 1, out) != 1)
+		return -1;
+	return 0;
 }
 
 
 /**
- * camel_file_util_decode_uint32:
+ * camel_file_util_decode_fixed_int32:
  * @in: file to read from
  * @dest: pointer to a variable to store the value in
  * 
- * Retrieve an encoded uint32 from a file.
+ * Retrieve a gint32.
  * 
- * Return value: 0 on success, -1 on error.  @*dest will contain the
- * decoded value.
+ * Return value: 0 on success, -1 on error.
  **/
 int
-camel_file_util_decode_uint32 (FILE *in, guint32 *dest)
+camel_file_util_decode_fixed_int32 (FILE *in, gint32 *dest)
 {
-        guint32 value = 0;
-	int v;
+	guint32 save;
 
-        /* until we get the last byte, keep decoding 7 bits at a time */
-        while ( ((v = fgetc (in)) & 0x80) == 0 && v!=EOF) {
-                value |= v;
-                value <<= 7;
-        }
-	if (v == EOF) {
-		*dest = value >> 7;
+	if (fread (&save, sizeof (save), 1, in) == 1) {
+		*dest = g_ntohl (save);
+		return 0;
+	} else {
 		return -1;
 	}
-	*dest = value | (v & 0x7f);
-
-        return 0;
 }
 
 
 /**
- * camel_file_util_encode_fixed_int32:
+ * camel_file_util_encode_uint32:
  * @out: file to output to
  * @value: value to output
  * 
- * Encode a gint32, performing no compression, but converting
- * to network order.
+ * Utility function to save an uint32 to a file.
  * 
  * Return value: 0 on success, -1 on error.
  **/
 int
-camel_file_util_encode_fixed_int32 (FILE *out, gint32 value)
+camel_file_util_encode_uint32 (FILE *out, guint32 value)
 {
-	guint32 save;
-
-	save = g_htonl (value);
-	if (fwrite (&save, sizeof (save), 1, out) != 1)
-		return -1;
-	return 0;
+	return camel_file_util_encode_fixed_int32 (out, value);
 }
 
 
 /**
- * camel_file_util_decode_fixed_int32:
+ * camel_file_util_decode_uint32:
  * @in: file to read from
  * @dest: pointer to a variable to store the value in
  * 
- * Retrieve a gint32.
+ * Retrieve an encoded uint32 from a file.
  * 
- * Return value: 0 on success, -1 on error.
+ * Return value: 0 on success, -1 on error.  @*dest will contain the
+ * decoded value.
  **/
 int
-camel_file_util_decode_fixed_int32 (FILE *in, gint32 *dest)
+camel_file_util_decode_uint32 (FILE *in, guint32 *dest)
 {
-	guint32 save;
+	return camel_file_util_decode_fixed_int32 (in, (gint32*)dest);
+}
 
-	if (fread (&save, sizeof (save), 1, in) == 1) {
-		*dest = g_ntohl (save);
-		return 0;
-	} else {
-		return -1;
-	}
+
+unsigned char*
+camel_file_util_mmap_decode_uint32 (unsigned char *start, guint32 *dest, gboolean is_string)
+{
+	guint32 value = 0;
+	value = g_ntohl(get_unaligned_u32(start)); start += 4;
+	*dest = value;
+	return start;
+}
+
+
+/* This casting should be okay, because it also gets BOTH written and read from
+   the file using a 4 byte integer. */
+
+#define CFU_ENCODE_T(type)						  \
+int									  \
+camel_file_util_encode_##type(FILE *out, type value)			  \
+{									  \
+	return camel_file_util_encode_fixed_int32 (out, (guint32) value); \
 }
 
-#define CFU_ENCODE_T(type)						\
-int									\
-camel_file_util_encode_##type(FILE *out, type value)			\
-{									\
-	int i;								\
-									\
-	for (i = sizeof (type) - 1; i >= 0; i--) {			\
-		if (fputc((value >> (i * 8)) & 0xff, out) == -1)	\
-			return -1;					\
-	}								\
-	return 0;							\
-}
-
-#define CFU_DECODE_T(type)				\
-int							\
-camel_file_util_decode_##type(FILE *in, type *dest)	\
-{							\
-	type save = 0;					\
-	int i = sizeof(type) - 1;			\
-	int v = EOF;					\
-							\
-        while (i >= 0 && (v = fgetc (in)) != EOF) {	\
-		save |= ((type)v) << (i * 8);		\
-		i--;					\
-	}						\
-	*dest = save;					\
-	if (v == EOF)					\
-		return -1;				\
-	return 0;					\
+#define CFU_DECODE_T(type)						  \
+int									  \
+camel_file_util_decode_##type(FILE *in, type *dest)			  \
+{									  \
+	return camel_file_util_decode_fixed_int32 (in, (gint32*) dest);  \
+}
+
+
+#define MMAP_DECODE_T(type)						    \
+unsigned char*								    \
+camel_file_util_mmap_decode_##type(unsigned char *start, type *dest)	    \
+{									    \
+	return camel_file_util_mmap_decode_uint32 (start, (guint32*) dest, FALSE); \
 }
 
 
@@ -202,6 +185,7 @@
  * Return value: 0 on success, -1 on error.
  **/
 CFU_DECODE_T(time_t)
+MMAP_DECODE_T(time_t)
 
 /**
  * camel_file_util_encode_off_t:
@@ -225,6 +209,7 @@
  * Return value: 0 on success, -1 on failure.
  **/
 CFU_DECODE_T(off_t)
+MMAP_DECODE_T(off_t)
 
 /**
  * camel_file_util_encode_size_t:
@@ -248,6 +233,7 @@
  * Return value: 0 on success, -1 on failure.
  **/
 CFU_DECODE_T(size_t)
+MMAP_DECODE_T(size_t)
 
 
 /**
@@ -262,18 +248,31 @@
 int
 camel_file_util_encode_string (FILE *out, const char *str)
 {
-	register int len;
+	register int lena, len;
+
+	if (str == NULL) {
+		if (camel_file_util_encode_uint32 (out, 0) == -1)
+			return -1;
 
-	if (str == NULL)
-		return camel_file_util_encode_uint32 (out, 1);
-	
-	if ((len = strlen (str)) > 65536)
-		len = 65536;
-	
-	if (camel_file_util_encode_uint32 (out, len+1) == -1)
-		return -1;
-	if (len == 0 || fwrite (str, len, 1, out) == 1)
 		return 0;
+	}
+
+	lena = len = strlen (str) + 1;
+
+	if (lena % G_MEM_ALIGN)
+		lena += G_MEM_ALIGN - (lena % G_MEM_ALIGN);
+
+	if (camel_file_util_encode_uint32 (out, lena) == -1)
+		return -1;
+
+	if (fwrite (str, len, 1, out) == 1) {
+		if (lena > len) {
+			if (fwrite ("\0\0\0\0\0\0\0\0", lena-len, 1, out) == 1)
+				return 0;
+			else return -1;
+		} else return 0;
+	}
+
 	return -1;
 }
 
@@ -298,12 +297,6 @@
 		return -1;
 	}
 
-	len--;
-	if (len > 65536) {
-		*str = NULL;
-		return -1;
-	}
-
 	ret = g_malloc (len+1);
 	if (len > 0 && fread (ret, len, 1, in) != 1) {
 		g_free (ret);
@@ -313,6 +306,7 @@
 
 	ret[len] = 0;
 	*str = ret;
+
 	return 0;
 }
 
@@ -487,6 +481,46 @@
 	return nread;
 }
 
+ssize_t
+camel_read_nb (int fd, char *buf, size_t n)
+{
+	ssize_t nread;
+
+	int errnosav, flags, fdmax;
+	fd_set rdset;
+	
+	flags = fcntl (fd, F_GETFL);
+	fcntl (fd, F_SETFL, flags | O_NONBLOCK);
+	
+	do {
+		struct timeval tv;
+		int res;
+
+		FD_ZERO (&rdset);
+		FD_SET (fd, &rdset);
+		fdmax = fd + 1;
+		tv.tv_sec = 0;
+		tv.tv_usec = 0;
+		nread = -1;
+
+		res = select(fdmax, &rdset, 0, 0, &tv);
+		if (res == -1)
+			;
+		else if (res == 0)
+			errno = ETIMEDOUT;
+		else {
+			do {
+				nread = read (fd, buf, n);
+			} while (0 && (nread == -1 && errno == EINTR));
+		}
+	} while (0 && (nread == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)));
+
+	errnosav = errno;
+	fcntl (fd, F_SETFL, flags);
+	errno = errnosav;
+
+	return nread;
+}
 
 /**
  * camel_write:
@@ -543,7 +577,7 @@
 			FD_SET (fd, &wrset);
 			FD_SET (cancel_fd, &rdset);
 			tv.tv_sec = IO_TIMEOUT;
-			tv.tv_usec = 0;			
+			tv.tv_usec = 0;
 			w = -1;
 
 			res = select (fdmax, &rdset, &wrset, 0, &tv);
@@ -611,7 +645,7 @@
 	if (cancel_fd == -1) {
 		do {
 			nread = recv (fd, buf, n, 0);
-		} while (nread == SOCKET_ERROR && WSAGetLastError () == WSAEWOULDBLOCK);
+		} while ((nread == SOCKET_ERROR && WSAGetLastError () == WSAEWOULDBLOCK));
 	} else {
 		int fdmax;
 		fd_set rdset;
@@ -641,7 +675,64 @@
 			} else {				
 				nread = recv (fd, buf, n, 0);
 			}
-		} while (nread == -1 && WSAGetLastError () == WSAEWOULDBLOCK);
+		} while ((nread == -1 && WSAGetLastError () == WSAEWOULDBLOCK));
+	failed:
+		;
+	}
+	
+	return nread;
+#endif
+}
+
+ssize_t
+camel_read_socket_nb (int fd, char *buf, size_t n)
+{
+#ifndef G_OS_WIN32
+	return camel_read_nb (fd, buf, n);
+#else
+	ssize_t nread;
+	int cancel_fd;
+	
+	if (camel_operation_cancel_check (NULL)) {
+		errno = EINTR;
+		return -1;
+	}
+	cancel_fd = camel_operation_cancel_fd (NULL);
+
+	if (cancel_fd == -1) {
+		do {
+			nread = recv (fd, buf, n, 0);
+		} while (0&&(nread == SOCKET_ERROR && WSAGetLastError () == WSAEWOULDBLOCK));
+	} else {
+		int fdmax;
+		fd_set rdset;
+		u_long yes = 1;
+
+		ioctlsocket (fd, FIONBIO, &yes);
+		fdmax = MAX (fd, cancel_fd) + 1;
+		do {
+			struct timeval tv;
+			int res;
+
+			FD_ZERO (&rdset);
+			FD_SET (fd, &rdset);
+			FD_SET (cancel_fd, &rdset);
+			tv.tv_sec = IO_TIMEOUT;
+			tv.tv_usec = 0;
+			nread = -1;
+
+			res = select(fdmax, &rdset, 0, 0, &tv);
+			if (res == -1)
+				;
+			else if (res == 0)
+				errno = ETIMEDOUT;
+			else if (FD_ISSET (cancel_fd, &rdset)) {
+				errno = EINTR;
+				goto failed;
+			} else {				
+				nread = recv (fd, buf, n, 0);
+			}
+		} while (0&&(nread == -1 && WSAGetLastError () == WSAEWOULDBLOCK));
 	failed:
 		;
 	}
@@ -702,7 +793,7 @@
 			FD_SET (fd, &wrset);
 			FD_SET (cancel_fd, &rdset);
 			tv.tv_sec = IO_TIMEOUT;
-			tv.tv_usec = 0;			
+			tv.tv_usec = 0;
 			w = -1;
 
 			res = select (fdmax, &rdset, &wrset, 0, &tv);
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-file-utils.h ./camel-file-utils.h
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-file-utils.h	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-file-utils.h	2007-05-12 10:01:18.000000000 +0200
@@ -43,6 +43,7 @@
 int camel_file_util_decode_fixed_int32 (FILE *in, gint32 *);
 int camel_file_util_encode_uint32 (FILE *out, guint32);
 int camel_file_util_decode_uint32 (FILE *in, guint32 *);
+
 int camel_file_util_encode_time_t (FILE *out, time_t);
 int camel_file_util_decode_time_t (FILE *in, time_t *);
 int camel_file_util_encode_off_t (FILE *out, off_t);
@@ -55,6 +56,11 @@
 int camel_file_util_decode_fixed_string (FILE *in, char **str, size_t len);
 
 
+unsigned char* camel_file_util_mmap_decode_time_t(unsigned char *start, time_t *dest);
+unsigned char* camel_file_util_mmap_decode_off_t(unsigned char *start, off_t *dest);
+unsigned char* camel_file_util_mmap_decode_size_t(unsigned char *start, size_t *dest);
+unsigned char* camel_file_util_mmap_decode_uint32 (unsigned char *start, guint32 *dest, gboolean is_string);
+
 char *camel_file_util_safe_filename (const char *name);
 
 /* Code that intends to be portable to Win32 should use camel_read()
@@ -70,8 +76,15 @@
 ssize_t camel_read_socket (int fd, char *buf, size_t n);
 ssize_t camel_write_socket (int fd, const char *buf, size_t n);
 
+ssize_t camel_read_socket_nb (int fd, char *buf, size_t n);
+
 char *camel_file_util_savename(const char *filename);
 
+#define get_unaligned_u32(p) ((((unsigned char*)(p))[0]) | \
+	(((unsigned char*)(p))[1] << 8) | \
+	(((unsigned char*)(p))[2] << 16) | \
+	(((unsigned char*)(p))[3] << 24))
+
 G_END_DECLS
 
 #endif /* CAMEL_FILE_UTILS_H */
Only in .: camel-file-utils.lo
Only in .: camel-file-utils.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-filter-driver.c ./camel-filter-driver.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-filter-driver.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-filter-driver.c	2007-05-12 10:01:18.000000000 +0200
@@ -486,8 +486,9 @@
 				camel_folder_transfer_messages_to (p->source, uids, outbox, NULL, FALSE, p->ex);
 				g_ptr_array_free (uids, TRUE);
 			} else {
+				/* TNY TODO: Partial message retrieval exception */
 				if (p->message == NULL)
-					p->message = camel_folder_get_message (p->source, p->uid, p->ex);
+					p->message = camel_folder_get_message (p->source, p->uid, CAMEL_FOLDER_RECEIVE_FULL, -1, p->ex);
 				
 				if (!p->message)
 					continue;
@@ -539,8 +540,9 @@
 				camel_folder_transfer_messages_to (p->source, uids, outbox, NULL, last, p->ex);
 				g_ptr_array_free (uids, TRUE);
 			} else {
+				/* TNY TODO: Partial message retrieval exception */
 				if (p->message == NULL)
-					p->message = camel_folder_get_message (p->source, p->uid, p->ex);
+					p->message = camel_folder_get_message (p->source, p->uid, CAMEL_FOLDER_RECEIVE_FULL, -1, p->ex);
 				
 				if (!p->message)
 					continue;
@@ -724,7 +726,8 @@
 	
 	/* make sure we have the message... */
 	if (p->message == NULL) {
-		if (!(p->message = camel_folder_get_message (p->source, p->uid, p->ex)))
+		/* TNY TODO: Partial message retrieval exception */
+		if (!(p->message = camel_folder_get_message (p->source, p->uid, CAMEL_FOLDER_RECEIVE_FULL, -1, p->ex)))
 			return -1;
 	}
 	
@@ -1190,7 +1193,8 @@
 		}
 		
 		info = camel_message_info_new_from_header(NULL, ((CamelMimePart *)msg)->headers);
-		((CamelMessageInfoBase *)info)->size = camel_mime_parser_tell(mp) - last;
+		((CamelMessageInfoBase *)info)->size = ((camel_mime_parser_tell(mp) - last));
+
 		last = camel_mime_parser_tell(mp);
 		status = camel_filter_driver_filter_message (driver, msg, info, NULL, NULL, source_url, 
 							     original_source_url ? original_source_url : source_url, ex);
@@ -1342,7 +1346,8 @@
 		else
 			uid = camel_message_info_uid (p->info);
 		
-		message = camel_folder_get_message (p->source, uid, ex);
+		/* TNY TODO: Partial message retrieval exception */
+		message = camel_folder_get_message (p->source, uid, CAMEL_FOLDER_RECEIVE_FULL, -1, ex);
 	}
 	
 	if (source_url && message && camel_mime_message_get_source (message) == NULL)
@@ -1398,7 +1403,8 @@
 		if (message) {
 			camel_object_ref (message);
 		} else {
-			message = camel_folder_get_message (source, uid, ex);
+			/* TNY TODO: Partial message retrieval exception */
+			message = camel_folder_get_message (source, uid, CAMEL_FOLDER_RECEIVE_FULL, -1, ex);
 			if (!message)
 				return -1;
 		}
@@ -1506,7 +1512,8 @@
 			g_ptr_array_free (uids, TRUE);
 		} else {
 			if (p->message == NULL) {
-				p->message = camel_folder_get_message (source, uid, ex);
+				/* TNY TODO: Partial message retrieval exception */
+				p->message = camel_folder_get_message (source, uid, CAMEL_FOLDER_RECEIVE_FULL, -1, ex);
 				if (!p->message)
 					goto error;
 			}
Only in .: camel-filter-driver.lo
Only in .: camel-filter-driver.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-filter-search.c ./camel-filter-search.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-filter-search.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-filter-search.c	2007-05-12 10:00:17.000000000 +0200
@@ -153,7 +153,7 @@
 		/* shortcut: a match for "" against any header always matches */
 		for (i=1; i<argc && !matched; i++)
 			matched = argv[i]->type == ESEXP_RES_STRING && argv[i]->value.string[0] == 0;
-
+#if NON_TINYMAIL_FEATURES
 		if (g_ascii_strcasecmp(name, "x-camel-mlist") == 0) {
 			const char *list = camel_message_info_mlist(fms->info);
 
@@ -164,6 +164,7 @@
 				}
 			}
 		} else {
+#endif
 			CamelMimeMessage *message = camel_filter_search_get_message (fms, f);
 			struct _camel_header_raw *header;
 			const char *charset = NULL;
@@ -189,7 +190,9 @@
 					}
 				}
 			}
+#ifdef NON_TINYMAIL_FEATURES
 		}
+#endif
 	}
 	
 	r = e_sexp_result_new (f, ESEXP_RES_BOOL);
@@ -504,7 +507,8 @@
 	ESExpResult *r;
 	
 	r = e_sexp_result_new(f, ESEXP_RES_INT);
-	r->value.number = camel_message_info_size(fms->info) / 1024;
+
+	r->value.number = camel_message_info_size(fms->info);
 
 	return r;
 }
Only in .: camel-filter-search.lo
Only in .: camel-filter-search.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-folder.c ./camel-folder.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-folder.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-folder.c	2007-05-12 10:01:18.000000000 +0200
@@ -93,7 +93,7 @@
 static void              free_summary        (CamelFolder *folder,
 					      GPtrArray *array);
 
-static CamelMimeMessage *get_message         (CamelFolder *folder, const gchar *uid, CamelException *ex);
+static CamelMimeMessage *get_message         (CamelFolder *folder, const gchar *uid, CamelFolderReceiveType type, gint param, CamelException *ex);
 
 static CamelMessageInfo *get_message_info    (CamelFolder *folder, const char *uid);
 static void		 free_message_info   (CamelFolder *folder, CamelMessageInfo *info);
@@ -116,6 +116,18 @@
 static gboolean        folder_changed        (CamelObject *object,
 					      gpointer event_data);
 
+static void 
+folder_set_push_email (CamelFolder *folder, gboolean setting)
+{
+	return;
+}
+
+void 
+camel_folder_set_push_email (CamelFolder *folder, gboolean setting)
+{
+	CF_CLASS (folder)->set_push_email (folder, setting);
+}
+
 static void
 camel_folder_class_init (CamelFolderClass *camel_folder_class)
 {
@@ -124,6 +136,7 @@
 	parent_class = camel_type_get_global_classfuncs (camel_object_get_type ());
 
 	/* virtual method definition */
+	camel_folder_class->set_push_email = folder_set_push_email;
 	camel_folder_class->sync = folder_sync;
 	camel_folder_class->refresh_info = refresh_info;
 	camel_folder_class->get_name = get_name;
@@ -308,15 +321,17 @@
 	CamelFolder *folder = (CamelFolder *)object;
 	int i;
 	guint32 tag;
-	int unread = -1, deleted = 0, junked = 0, visible = 0, count = -1;
+	int unread = -1, deleted = 0, count = -1;
 
-	for (i=0;i<args->argc;i++) {
-		CamelArgGet *arg = &args->argv[i];
+	for (i=0; i < args->argc; i++) 
+	{
+	  CamelArgGet *arg = &args->argv[i];
 
-		tag = arg->tag;
+	  tag = arg->tag;
 
-		switch (tag & CAMEL_ARG_TAG) {
-			/* CamelObject args */
+	  switch (tag & CAMEL_ARG_TAG) 
+	  {
+		/* CamelObject args */
 		case CAMEL_OBJECT_ARG_DESCRIPTION:
 			if (folder->description == NULL)
 				folder->description = g_strdup_printf("%s", folder->full_name);
@@ -341,28 +356,30 @@
 			break;
 		case CAMEL_FOLDER_ARG_UNREAD:
 		case CAMEL_FOLDER_ARG_DELETED:
-		case CAMEL_FOLDER_ARG_JUNKED:
-		case CAMEL_FOLDER_ARG_VISIBLE:
-			/* This is so we can get the values atomically, and also so we can calculate them only once */
+
+			/* This is so we can get the values atomically, and also 
+			 * so we can calculate them only once */
+
 			if (unread == -1) {
 				int j;
 				CamelMessageInfo *info;
 
 				/* TODO: Locking? */
 				unread = 0;
-				count = camel_folder_summary_count(folder->summary);
-				for (j=0; j<count; j++) {
-					if ((info = camel_folder_summary_index(folder->summary, j))) {
-						guint32 flags = camel_message_info_flags(info);
+				count = camel_folder_summary_count (folder->summary);
+				for (j=0; j < count; j++) 
+				{
+					info = camel_folder_summary_index (folder->summary, j);
+					if (info) 
+					{
+						guint32 flags = camel_message_info_flags (info);
 
-						if ((flags & (CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_JUNK)) == 0)
-							unread++;
 						if (flags & CAMEL_MESSAGE_DELETED)
 							deleted++;
-						if (flags & CAMEL_MESSAGE_JUNK)
-							junked++;
-						if ((flags & (CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_JUNK)) == 0)
-							visible++;
+						else
+							if ((flags & CAMEL_MESSAGE_SEEN) == 0)
+								unread++;
+
 						camel_message_info_free(info);
 					}
 				}
@@ -375,12 +392,6 @@
 			case CAMEL_FOLDER_ARG_DELETED:
 				count = deleted;
 				break;
-			case CAMEL_FOLDER_ARG_JUNKED:
-				count = junked;
-				break;
-			case CAMEL_FOLDER_ARG_VISIBLE:
-				count = visible;
-				break;
 			}
 
 			*arg->ca_int = count;
@@ -409,9 +420,9 @@
 			break;
 		default:
 			continue;
-		}
+	  }
 
-		arg->tag = (tag & CAMEL_ARG_TYPE) | CAMEL_ARG_IGNORE;
+	  arg->tag = (tag & CAMEL_ARG_TYPE) | CAMEL_ARG_IGNORE;
 	}
 
 	return parent_class->getv(object, ex, args);
@@ -762,11 +773,6 @@
 {
 	g_return_val_if_fail(CAMEL_IS_FOLDER(folder), FALSE);
 
-	if ((flags & (CAMEL_MESSAGE_JUNK|CAMEL_MESSAGE_JUNK_LEARN)) == CAMEL_MESSAGE_JUNK) {
-		flags |= CAMEL_MESSAGE_JUNK_LEARN;
-		set &= ~CAMEL_MESSAGE_JUNK_LEARN;
-	}
-
 	return CF_CLASS(folder)->set_message_flags(folder, uid, flags, set);
 }
 
@@ -1043,7 +1049,7 @@
 /* UIDs stuff */
 
 static CamelMimeMessage *
-get_message (CamelFolder *folder, const char *uid, CamelException *ex)
+get_message (CamelFolder *folder, const char *uid, CamelFolderReceiveType type, gint param, CamelException *ex)
 {
 	w(g_warning ("CamelFolder::get_message not implemented for `%s'",
 		     camel_type_to_name (CAMEL_OBJECT_GET_TYPE (folder))));
@@ -1063,7 +1069,7 @@
  * Returns a #CamelMimeMessage corresponding to @uid
  **/
 CamelMimeMessage *
-camel_folder_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
+camel_folder_get_message (CamelFolder *folder, const char *uid, CamelFolderReceiveType type, gint param, CamelException *ex)
 {
 	CamelMimeMessage *ret;
 
@@ -1071,7 +1077,7 @@
 
 	CAMEL_FOLDER_REC_LOCK(folder, lock);
 
-	ret = CF_CLASS (folder)->get_message (folder, uid, ex);
+	ret = CF_CLASS (folder)->get_message (folder, uid, type, param, ex);
 
 	CAMEL_FOLDER_REC_UNLOCK(folder, lock);
 
@@ -1355,7 +1361,9 @@
 	
 	/* Default implementation. */
 	
-	msg = camel_folder_get_message(source, uid, ex);
+	/* TNY: Partial message retrieval exception (always transfer the full 
+		message, not just the body part) */
+	msg = camel_folder_get_message(source, uid, CAMEL_FOLDER_RECEIVE_FULL, -1, ex);
 	if (!msg)
 		return;
 
@@ -1406,7 +1414,7 @@
 		if (transferred_uids)
 			ret_uid = (char **)&((*transferred_uids)->pdata[i]);
 		transfer_message_to (source, uids->pdata[i], dest, ret_uid, delete_originals, ex);
-		camel_operation_progress(NULL, i * 100 / uids->len);
+		camel_operation_progress(NULL, i , uids->len);
 	}
 	if (uids->len > 1) {
 		camel_folder_thaw(dest);
@@ -1637,6 +1645,7 @@
 	CamelException ex;
 };
 
+#if 0
 static void
 filter_filter(CamelSession *session, CamelSessionThreadMsg *tmsg)
 {
@@ -1652,10 +1661,10 @@
 		camel_operation_start (NULL, _("Learning junk"));
 
 		for (i = 0; i < m->junk->len; i ++) {
-			CamelMimeMessage *msg = camel_folder_get_message(m->folder, m->junk->pdata[i], NULL);
-			int pc = 100 * i / m->junk->len;
+			/* TNY TODO: Partial message retrieval exception */
+			CamelMimeMessage *msg = camel_folder_get_message(m->folder, m->junk->pdata[i], CAMEL_FOLDER_RECEIVE_FULL, -1, NULL);
 			
-			camel_operation_progress(NULL, pc);
+			camel_operation_progress(NULL, i, m->junk->len);
 
 			if (msg) {
 				camel_junk_plugin_report_junk (csp, msg);
@@ -1668,10 +1677,10 @@
 	if (m->notjunk) {
 		camel_operation_start (NULL, _("Learning non-junk"));
 		for (i = 0; i < m->notjunk->len; i ++) {
-			CamelMimeMessage *msg = camel_folder_get_message(m->folder, m->notjunk->pdata[i], NULL);
-			int pc = 100 * i / m->notjunk->len;
-
-			camel_operation_progress(NULL, pc);
+			/* TNY TODO: Partial message retrieval exception */
+			CamelMimeMessage *msg = camel_folder_get_message(m->folder, m->notjunk->pdata[i], CAMEL_FOLDER_RECEIVE_FULL, -1, NULL);
+			
+			camel_operation_progress(NULL, i, m->notjunk->len);
 
 			if (msg) {
 				camel_junk_plugin_report_notjunk (csp, msg);
@@ -1702,9 +1711,8 @@
 
 		for (i=0;status == 0 && i<m->recents->len;i++) {
 			char *uid = m->recents->pdata[i];
-			int pc = 100 * i / m->recents->len;
 
-			camel_operation_progress(NULL, pc);
+			camel_operation_progress(NULL, i, m->recents->len);
 
 			info = camel_folder_get_message_info(m->folder, uid);
 			if (info == NULL) {
@@ -1745,11 +1753,8 @@
 	camel_folder_thaw(m->folder);
 	camel_object_unref(m->folder);
 }
+#endif
 
-static CamelSessionThreadOps filter_ops = {
-	filter_filter,
-	filter_free,
-};
 
 /* Event hooks that block emission when frozen */
 static gboolean
@@ -1759,8 +1764,6 @@
 	CamelFolderChangeInfo *changed = event_data;
 	CamelSession *session = ((CamelService *)folder->parent_store)->session;
 	CamelFilterDriver *driver = NULL;
-	GPtrArray *junk = NULL;
-	GPtrArray *notjunk = NULL;
 	GPtrArray *recents = NULL;
 	int i;
 
@@ -1784,56 +1787,17 @@
 	}
 	CAMEL_FOLDER_UNLOCK(folder, change_lock);
 
-	if (session->junk_plugin && changed->uid_changed->len) {
-		guint32 flags;
-
-		for (i = 0; i < changed->uid_changed->len; i ++) {
-			flags = camel_folder_get_message_flags (folder, changed->uid_changed->pdata [i]);
-			if (flags & CAMEL_MESSAGE_JUNK_LEARN) {
-				if (flags & CAMEL_MESSAGE_JUNK) {
-					if (!junk)
-						junk = g_ptr_array_new();
-					g_ptr_array_add (junk, g_strdup (changed->uid_changed->pdata [i]));
-				} else {
-					if (!notjunk)
-						notjunk = g_ptr_array_new();
-					g_ptr_array_add (notjunk, g_strdup (changed->uid_changed->pdata [i]));
-				}
-				/* reset junk learn flag so that we don't process it again*/ 
-				camel_folder_set_message_flags (folder, changed->uid_changed->pdata [i], CAMEL_MESSAGE_JUNK_LEARN, 0);
-			}
-		}
-	}
 
-	if ((folder->folder_flags & (CAMEL_FOLDER_FILTER_RECENT|CAMEL_FOLDER_FILTER_JUNK))
+	if ((folder->folder_flags & CAMEL_FOLDER_FILTER_RECENT)
 	    && changed->uid_recent->len > 0)
-		driver = camel_session_get_filter_driver(session,
-							 (folder->folder_flags & CAMEL_FOLDER_FILTER_RECENT) 
-							 ? "incoming":"junktest", NULL);
-		
+		driver = camel_session_get_filter_driver(session, "incoming", NULL);
+
 	if (driver) {
 		recents = g_ptr_array_new();
 		for (i=0;i<changed->uid_recent->len;i++)
 			g_ptr_array_add(recents, g_strdup(changed->uid_recent->pdata[i]));
 	}
 
-	if (driver || junk || notjunk) {
-		struct _folder_filter_msg *msg;
-
-		d(printf("* launching filter thread %d new mail, %d junk and %d not junk\n",
-			 recents?recents->len:0, junk?junk->len:0, notjunk?notjunk->len:0));
-
-		msg = camel_session_thread_msg_new(session, &filter_ops, sizeof(*msg));
-		msg->recents = recents;
-		msg->junk = junk;
-		msg->notjunk = notjunk;
-		msg->folder = folder;
-		camel_object_ref(folder);
-		camel_folder_freeze(folder);
-		msg->driver = driver;
-		camel_exception_init(&msg->ex);
-		camel_session_thread_queue(session, &msg->msg, 0);
-	}
 
 	return TRUE;
 }
@@ -2120,7 +2084,7 @@
 	struct _CamelFolderChangeInfoPrivate *p;
 	GPtrArray *olduids;
 	char *olduid;
-	
+
 	g_assert(info != NULL);
 	
 	p = info->priv;
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-folder.h ./camel-folder.h
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-folder.h	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-folder.h	2007-05-12 10:01:18.000000000 +0200
@@ -34,6 +34,16 @@
 #define CAMEL_FOLDER_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_FOLDER_TYPE, CamelFolderClass))
 #define CAMEL_IS_FOLDER(o)    (CAMEL_CHECK_TYPE((o), CAMEL_FOLDER_TYPE))
 
+
+typedef enum _CamelFolderReceiveType CamelFolderReceiveType;
+
+enum _CamelFolderReceiveType 
+{
+	CAMEL_FOLDER_RECEIVE_FULL = 1<<0,
+	CAMEL_FOLDER_RECEIVE_PARTIAL = 1<<1,
+	CAMEL_FOLDER_RECEIVE_SIZE_LIMITED = CAMEL_FOLDER_RECEIVE_PARTIAL<<2
+};
+
 G_BEGIN_DECLS
 
 typedef struct _CamelFolderChangeInfo CamelFolderChangeInfo;
@@ -47,8 +57,6 @@
 	CAMEL_FOLDER_ARG_TOTAL,
 	CAMEL_FOLDER_ARG_UNREAD, /* unread messages */
 	CAMEL_FOLDER_ARG_DELETED, /* deleted messages */
-	CAMEL_FOLDER_ARG_JUNKED, /* junked messages */
-	CAMEL_FOLDER_ARG_VISIBLE, /* visible !(deleted or junked) */
 	CAMEL_FOLDER_ARG_UID_ARRAY,
 	CAMEL_FOLDER_ARG_INFO_ARRAY,
 	CAMEL_FOLDER_ARG_PROPERTIES,
@@ -63,8 +71,6 @@
 	CAMEL_FOLDER_TOTAL = CAMEL_FOLDER_ARG_TOTAL | CAMEL_ARG_INT,
 	CAMEL_FOLDER_UNREAD = CAMEL_FOLDER_ARG_UNREAD | CAMEL_ARG_INT,
 	CAMEL_FOLDER_DELETED = CAMEL_FOLDER_ARG_DELETED | CAMEL_ARG_INT,
-	CAMEL_FOLDER_JUNKED = CAMEL_FOLDER_ARG_JUNKED | CAMEL_ARG_INT,
-	CAMEL_FOLDER_VISIBLE = CAMEL_FOLDER_ARG_VISIBLE | CAMEL_ARG_INT,
 
 	CAMEL_FOLDER_UID_ARRAY = CAMEL_FOLDER_ARG_UID_ARRAY | CAMEL_ARG_PTR,
 	CAMEL_FOLDER_INFO_ARRAY = CAMEL_FOLDER_ARG_INFO_ARRAY | CAMEL_ARG_PTR,
@@ -105,7 +111,9 @@
 #define CAMEL_FOLDER_HAS_BEEN_DELETED       (1<<3)
 #define CAMEL_FOLDER_IS_TRASH               (1<<4)
 #define CAMEL_FOLDER_IS_JUNK                (1<<5)
-#define CAMEL_FOLDER_FILTER_JUNK  	    (1<<6)
+#define CAMEL_FOLDER_FILTER_JUNK            (1<<6)
+#define CAMEL_FOLDER_IS_READONLY            (1<<7)
+#define CAMEL_FOLDER_HAS_PUSHEMAIL_CAPABILITY (1<<8)
 
 typedef struct {
 	CamelObjectClass parent_class;
@@ -156,7 +164,8 @@
 					  const char *value);
 
 	CamelMimeMessage * (*get_message)  (CamelFolder *folder, 
-					    const char *uid, 
+					    const char *uid, CamelFolderReceiveType type,
+					    gint param, 
 					    CamelException *ex);
 
 	GPtrArray * (*get_uids)       (CamelFolder *folder);
@@ -191,6 +200,8 @@
 	void     (*freeze)    (CamelFolder *folder);
 	void     (*thaw)      (CamelFolder *folder);
 	gboolean (*is_frozen) (CamelFolder *folder);
+	void (*set_push_email) (CamelFolder *folder, gboolean setting);
+
 } CamelFolderClass;
 
 /* Standard Camel function */
@@ -281,8 +292,8 @@
 
 /* uid based access operations */
 CamelMimeMessage * camel_folder_get_message           (CamelFolder *folder, 
-						       const char *uid, 
-						       CamelException *ex);
+						       const char *uid, CamelFolderReceiveType type,
+						       gint param, CamelException *ex);
 #define camel_folder_delete_message(folder, uid) \
 	camel_folder_set_message_flags (folder, uid, CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN)
 
@@ -343,6 +354,8 @@
 void			camel_folder_change_info_change_uid	(CamelFolderChangeInfo *info, const char *uid);
 void			camel_folder_change_info_recent_uid	(CamelFolderChangeInfo *info, const char *uid);
 
+void camel_folder_set_push_email (CamelFolder *folder, gboolean setting);
+
 G_END_DECLS
 
 #endif /* CAMEL_FOLDER_H */
Only in .: camel-folder.lo
Only in .: camel-folder.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-folder-search.c ./camel-folder-search.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-folder-search.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-folder-search.c	2007-05-12 10:01:18.000000000 +0200
@@ -880,10 +880,14 @@
 		} else if (!g_ascii_strcasecmp(headername, "cc")) {
 			header = camel_message_info_cc(search->current);
 			type = CAMEL_SEARCH_TYPE_ADDRESS;
-		} else if (!g_ascii_strcasecmp(headername, "x-camel-mlist")) {
+		} 
+#ifdef NON_TINYMAIL_FEATURES
+		else if (!g_ascii_strcasecmp(headername, "x-camel-mlist")) {
 			header = camel_message_info_mlist(search->current);
 			type = CAMEL_SEARCH_TYPE_MLIST;
-		} else {
+		} 
+#endif
+		else {
 			e_sexp_resultv_free(f, argc, argv);
 			e_sexp_fatal_error(f, _("Performing query on unknown header: %s"), headername);
 		}
@@ -898,7 +902,7 @@
 					truth = TRUE;
 				} else if (how == CAMEL_SEARCH_MATCH_CONTAINS) {
 					/* doesn't make sense to split words on anything but contains i.e. we can't have an ending match different words */
-					words = camel_search_words_split(argv[i]->value.string);
+					words = camel_search_words_split((const unsigned char*)argv[i]->value.string);
 					truth = TRUE;
 					for (j=0;j<words->len && truth;j++) {
 						truth = camel_search_header_match(header, words->words[j]->word, how, type, NULL);
@@ -1099,7 +1103,7 @@
 		camel_stream_write (CAMEL_STREAM (mem), "", 1);
 		for (i=0;i<words->len;i++) {
 			/* FIXME: This is horridly slow, and should use a real search algorithm */
-			if (camel_ustrstrcase(mem->buffer->data, words->words[i]->word) != NULL) {
+			if (camel_ustrstrcase((const char*)mem->buffer->data, words->words[i]->word) != NULL) {
 				*mask |= (1<<i);
 				/* shortcut a match */
 				if (*mask == (1<<(words->len))-1)
@@ -1121,7 +1125,8 @@
 	CamelException x = CAMEL_EXCEPTION_INITIALISER;
 	int truth;
 
-	msg = camel_folder_get_message(folder, uid, &x);
+	/* TNY TODO: Partial message retrieval exception */
+	msg = camel_folder_get_message(folder, uid, CAMEL_FOLDER_RECEIVE_FULL, -1, &x);
 	if (msg) {
 		mask = 0;
 		truth = match_words_1message((CamelDataWrapper *)msg, words, &mask);
@@ -1188,7 +1193,7 @@
 		} else {
 			for (i=0;i<argc && !truth;i++) {
 				if (argv[i]->type == ESEXP_RES_STRING) {
-					words = camel_search_words_split(argv[i]->value.string);
+					words = camel_search_words_split((const unsigned char*)argv[i]->value.string);
 					truth = TRUE;
 					if ((words->type & CAMEL_SEARCH_WORD_COMPLEX) == 0 && search->body_index) {
 						for (j=0;j<words->len && truth;j++)
@@ -1221,7 +1226,7 @@
 
 			for (i=0;i<argc;i++) {
 				if (argv[i]->type == ESEXP_RES_STRING) {
-					words = camel_search_words_split(argv[i]->value.string);
+					words = camel_search_words_split((const unsigned char*)argv[i]->value.string);
 					if ((words->type & CAMEL_SEARCH_WORD_COMPLEX) == 0 && search->body_index) {
 						matches = match_words_index(search, words, ex);
 					} else {
Only in .: camel-folder-search.lo
Only in .: camel-folder-search.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-folder-summary.c ./camel-folder-summary.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-folder-summary.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-folder-summary.c	2007-05-12 10:30:33.000000000 +0200
@@ -2,7 +2,13 @@
 /*
  *  Copyright (C) 2000-2003 Ximian Inc.
  *
- *  Authors: Michael Zucchi <notzed@ximian.com>
+ * This is the mmap version of camel-folder-summary.c which maps 
+ * the header data into memory in stead of fread()ing it. It uses
+ * the mmap() syscall for this.
+ *
+ *  Authors: 
+ *   Michael Zucchi <notzed@ximian.com>
+ *   Philip Van Hoof <pvanhoof@gnome.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of version 2 of the GNU Lesser General Public
@@ -40,6 +46,7 @@
 #include <libedataserver/e-memory.h>
 #include <libedataserver/md5-utils.h>
 
+
 #include "camel-file-utils.h"
 #include "camel-folder-summary.h"
 #include "camel-folder.h"
@@ -55,6 +62,17 @@
 #include "camel-stream-mem.h"
 #include "camel-stream-null.h"
 #include "camel-string-utils.h"
+#include "camel-disco-folder.h"
+
+
+
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <dirent.h>
+
+#include <glib.h>
+#include <glib/gprintf.h>
 
 static pthread_mutex_t info_lock = PTHREAD_MUTEX_INITIALIZER;
 
@@ -66,19 +84,20 @@
 /* this should probably be conditional on it existing */
 #define USE_BSEARCH
 
-#define d(x)
+#define d(x)	
 #define io(x)			/* io debug */
-#define w(x)
+#define w(x)	
 
 #if 0
 extern int strdup_count, malloc_count, free_count;
 #endif
 
-#define CAMEL_FOLDER_SUMMARY_VERSION (13)
+#define CAMEL_FOLDER_SUMMARY_VERSION (15)
 
 #define _PRIVATE(o) (((CamelFolderSummary *)(o))->priv)
 
-#define META_SUMMARY_SUFFIX_LEN 5 /* strlen("-meta") */
+static GStaticRecMutex global_lock = G_STATIC_REC_MUTEX_INIT;
+static GStaticMutex global_lock2 = G_STATIC_MUTEX_INIT;
 
 /* trivial lists, just because ... */
 struct _node {
@@ -88,23 +107,20 @@
 static struct _node *my_list_append(struct _node **list, struct _node *n);
 static int my_list_size(struct _node **list);
 
-static int summary_header_load(CamelFolderSummary *, FILE *);
-static int summary_header_save(CamelFolderSummary *, FILE *);
-static int summary_meta_header_load(CamelFolderSummary *, FILE *);
-static int summary_meta_header_save(CamelFolderSummary *, FILE *);
+static int summary_header_load(CamelFolderSummary *);
+static int summary_header_save(CamelFolderSummary *, FILE *out);
 
 static CamelMessageInfo * message_info_new_from_header(CamelFolderSummary *, struct _camel_header_raw *);
 static CamelMessageInfo * message_info_new_from_parser(CamelFolderSummary *, CamelMimeParser *);
 static CamelMessageInfo * message_info_new_from_message(CamelFolderSummary *s, CamelMimeMessage *msg);
-static CamelMessageInfo * message_info_load(CamelFolderSummary *, FILE *);
+static CamelMessageInfo * message_info_load(CamelFolderSummary *, gboolean *must_add);
 static int		  message_info_save(CamelFolderSummary *, FILE *, CamelMessageInfo *);
-static int		  meta_message_info_save(CamelFolderSummary *s, FILE *out_meta, FILE *out, CamelMessageInfo *info);
 static void		  message_info_free(CamelFolderSummary *, CamelMessageInfo *);
-
+static void destroy_possible_pstring_stuff (CamelFolderSummary *, CamelMessageInfo *, gboolean);
 static CamelMessageContentInfo * content_info_new_from_header(CamelFolderSummary *, struct _camel_header_raw *);
 static CamelMessageContentInfo * content_info_new_from_parser(CamelFolderSummary *, CamelMimeParser *);
 static CamelMessageContentInfo * content_info_new_from_message(CamelFolderSummary *s, CamelMimePart *mp);
-static CamelMessageContentInfo * content_info_load(CamelFolderSummary *, FILE *);
+static CamelMessageContentInfo * content_info_load(CamelFolderSummary *);
 static int		         content_info_save(CamelFolderSummary *, FILE *, CamelMessageContentInfo *);
 static void		         content_info_free(CamelFolderSummary *, CamelMessageContentInfo *);
 
@@ -117,22 +133,105 @@
 static void camel_folder_summary_init       (CamelFolderSummary *obj);
 static void camel_folder_summary_finalize   (CamelObject *obj);
 
+
+static void camel_folder_summary_mmap_add(CamelFolderSummary *s, CamelMessageInfo *info);
+static void camel_folder_summary_unload_mmap (CamelFolderSummary *s);
+
 static CamelObjectClass *camel_folder_summary_parent;
 
+
+void
+camel_message_info_clear_normal_flags (CamelMessageInfo *min)
+{
+
+	CamelMessageInfoBase *mi = (CamelMessageInfoBase*) min;
+
+	mi->flags &= ~CAMEL_MESSAGE_ANSWERED;
+	mi->flags &= ~CAMEL_MESSAGE_DELETED;
+	mi->flags &= ~CAMEL_MESSAGE_DRAFT;
+	mi->flags &= ~CAMEL_MESSAGE_FLAGGED;
+	mi->flags &= ~CAMEL_MESSAGE_SEEN;
+	mi->flags &= ~CAMEL_MESSAGE_ATTACHMENTS;
+	mi->flags &= ~CAMEL_MESSAGE_CACHED;
+	mi->flags &= ~CAMEL_MESSAGE_PARTIAL;
+	mi->flags &= ~CAMEL_MESSAGE_EXPUNGED;
+	mi->flags &= ~CAMEL_MESSAGE_HIGH_PRIORITY;
+	mi->flags &= ~CAMEL_MESSAGE_NORMAL_PRIORITY;
+	mi->flags &= ~CAMEL_MESSAGE_LOW_PRIORITY;
+
+	mi->flags &= ~CAMEL_MESSAGE_SECURE;
+	mi->flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED;
+}
+
+static CamelMessageInfo* 
+find_message_info_with_uid (CamelFolderSummary *s, const char *uid)
+{
+	CamelMessageInfo *retval = NULL;
+	guint i = 0;
+
+	if (uid == NULL || strlen (uid) <= 0)
+		return NULL;
+
+	g_mutex_lock (s->hash_lock);
+	if (s->uidhash != NULL)
+		retval = g_hash_table_lookup (s->uidhash, uid);
+	g_mutex_unlock (s->hash_lock);
+
+	if (retval == NULL)
+		for (i=0; G_LIKELY (i < s->messages->len) ; i++)
+		{
+			CamelMessageInfo *info = s->messages->pdata[i];
+
+			/* This can cause cache trashing */
+			if (G_UNLIKELY (info->uid[0] == uid[0]) && 
+			    G_UNLIKELY (!strcmp (info->uid, uid)))
+			{
+				retval = info;
+				break;
+			}
+		}
+
+	return retval;
+}
+
+int 
+camel_folder_summary_get_index_for (CamelFolderSummary *s, const char *uid) 
+{
+	int retval = -1, i;
+
+	if (uid == NULL || strlen (uid) == 0)
+		return -1;
+
+	for (i=0; G_LIKELY (i < s->messages->len) ; i++)
+	{
+		CamelMessageInfo *info = s->messages->pdata[i];
+
+		/* This can cause cache trashing */
+		if (G_UNLIKELY (info->uid[0] == uid[0]) && 
+		    G_UNLIKELY (!strcmp (info->uid, uid)))
+		{
+			retval = i;
+			break;
+		}
+	}
+
+	return retval;
+}
+
+static void do_nothing (CamelFolder *folder, CamelMessageInfoBase *mi) { }
+ 
 static void
 camel_folder_summary_init (CamelFolderSummary *s)
 {
 	struct _CamelFolderSummaryPrivate *p;
 
-	p = _PRIVATE(s) = g_malloc0(sizeof(*p));
+	p = _PRIVATE(s) = g_slice_alloc0 (sizeof (*p));
 
 	p->filter_charset = g_hash_table_new (camel_strcase_hash, camel_strcase_equal);
-
+	s->dump_lock = g_mutex_new ();
 	s->message_info_size = sizeof(CamelMessageInfoBase);
 	s->content_info_size = sizeof(CamelMessageContentInfo);
-
-	s->message_info_chunks = NULL;
-	s->content_info_chunks = NULL;
+	s->set_extra_flags_func = do_nothing;
 
 #if defined (DOESTRV) || defined (DOEPOOLV)
 	s->message_info_strings = CAMEL_MESSAGE_INFO_LAST;
@@ -142,30 +241,86 @@
 	s->flags = 0;
 	s->time = 0;
 	s->nextuid = 1;
+	s->in_reload = FALSE;
 
 	s->messages = g_ptr_array_new();
-	s->messages_uid = g_hash_table_new(g_str_hash, g_str_equal);
-	
+	s->expunged = g_ptr_array_new();
+	s->uidhash = NULL;
+	s->hash_lock = g_mutex_new ();
+
 	p->summary_lock = g_mutex_new();
 	p->io_lock = g_mutex_new();
 	p->filter_lock = g_mutex_new();
-	p->alloc_lock = g_mutex_new();
 	p->ref_lock = g_mutex_new();
+}
 
-	s->meta_summary = g_malloc0(sizeof(CamelFolderMetaSummary));
+void
+camel_folder_summary_prepare_hash (CamelFolderSummary *s)
+{
+	guint i = 0;
+
+	g_mutex_lock (s->hash_lock);
+
+	if (s->uidhash == NULL)
+	{
+		s->uidhash = g_hash_table_new_full (g_str_hash, g_str_equal, 
+			(GDestroyNotify)g_free, NULL);
 
-	/* Default is 20, any implementor having UIDs that has length
-	   exceeding 20, has to override this value 
-	*/
-	s->meta_summary->uid_len = 20;
+		for (i=0; G_LIKELY (i < s->messages->len) ; i++)
+		{
+			CamelMessageInfo *info = s->messages->pdata[i];
+			g_hash_table_insert(s->uidhash, g_strdup (info->uid), info);
+		}
+	}
+
+	g_mutex_unlock (s->hash_lock);
+
+}
+
+void
+camel_folder_summary_kill_hash (CamelFolderSummary *s)
+{
+	g_mutex_lock (s->hash_lock);
+	if (s->uidhash != NULL)
+		g_hash_table_destroy (s->uidhash);
+	s->uidhash = NULL;
+	g_mutex_unlock (s->hash_lock);
 }
 
+
 static void free_o_name(void *key, void *value, void *data)
 {
 	camel_object_unref((CamelObject *)value);
 	g_free(key);
 }
 
+static inline void
+foreach_msginfo (gpointer data, gpointer user_data)
+{
+	camel_message_info_free (data);
+	/* g_slice_free1 ((gint)user_data, data); */
+}
+
+static inline 
+gboolean always_true (gpointer key, gpointer value, gpointer gp)
+{
+	return TRUE;
+}
+
+static void 
+camel_folder_summary_unload_mmap (CamelFolderSummary *s)
+{
+	struct _CamelFolderSummaryPrivate *p;
+
+	p = _PRIVATE(s);
+
+	if (s->file)
+		g_mapped_file_free (s->file);
+	s->file = NULL;
+
+	return;
+}
+
 static void
 camel_folder_summary_finalize (CamelObject *obj)
 {
@@ -174,49 +329,51 @@
 
 	p = _PRIVATE(obj);
 
-	camel_folder_summary_clear(s);
+	g_mutex_lock (s->dump_lock);
+
+	g_ptr_array_foreach (s->messages, foreach_msginfo, (gpointer)s->message_info_size);
+	g_ptr_array_foreach (s->expunged, foreach_msginfo, (gpointer)s->message_info_size);
+
+	/* camel_folder_summary_clear(s); */
 	g_ptr_array_free(s->messages, TRUE);
-	g_hash_table_destroy(s->messages_uid);
+	g_ptr_array_free(s->expunged, TRUE);
 
-	g_hash_table_foreach(p->filter_charset, free_o_name, 0);
-	g_hash_table_destroy(p->filter_charset);
+	camel_folder_summary_unload_mmap (s);
 
-	g_free(s->summary_path);
+	g_mutex_unlock (s->dump_lock);
+	g_mutex_free (s->dump_lock);
 
-	if (s->message_info_chunks)
-		e_memchunk_destroy(s->message_info_chunks);
-	if (s->content_info_chunks)
-		e_memchunk_destroy(s->content_info_chunks);
+	g_hash_table_foreach(p->filter_charset, free_o_name, 0);
+	g_hash_table_destroy(p->filter_charset);
 
-	if (p->filter_index)
+	if (p->filter_index && CAMEL_IS_OBJECT (p->filter_index))
 		camel_object_unref((CamelObject *)p->filter_index);
-	if (p->filter_64)
+	if (p->filter_64 && CAMEL_IS_OBJECT (p->filter_64))
 		camel_object_unref((CamelObject *)p->filter_64);
-	if (p->filter_qp)
+	if (p->filter_qp && CAMEL_IS_OBJECT (p->filter_qp))
 		camel_object_unref((CamelObject *)p->filter_qp);
-	if (p->filter_uu)
+	if (p->filter_uu && CAMEL_IS_OBJECT (p->filter_uu))
 		camel_object_unref((CamelObject *)p->filter_uu);
-	if (p->filter_save)
+	if (p->filter_save && CAMEL_IS_OBJECT (p->filter_save))
 		camel_object_unref((CamelObject *)p->filter_save);
-	if (p->filter_html)
+	if (p->filter_html && CAMEL_IS_OBJECT (p->filter_html))
 		camel_object_unref((CamelObject *)p->filter_html);
-
-	if (p->filter_stream)
+	if (p->filter_stream && CAMEL_IS_OBJECT (p->filter_stream))
 		camel_object_unref((CamelObject *)p->filter_stream);
-	if (p->index)
-		camel_object_unref((CamelObject *)p->index);
 
-	/* Freeing memory occupied by meta-summary-header */
-	g_free(s->meta_summary->path);
-	g_free(s->meta_summary);
-	
+	g_free(s->summary_path);
+
+	if (s->uidhash != NULL)
+		g_hash_table_destroy (s->uidhash);
+	g_mutex_free(s->hash_lock);
+
 	g_mutex_free(p->summary_lock);
 	g_mutex_free(p->io_lock);
 	g_mutex_free(p->filter_lock);
-	g_mutex_free(p->alloc_lock);
 	g_mutex_free(p->ref_lock);
-	
-	g_free(p);
+
+
+	g_slice_free1 (sizeof (*p), p);
 }
 
 CamelType
@@ -250,9 +407,7 @@
 camel_folder_summary_new (struct _CamelFolder *folder)
 {
 	CamelFolderSummary *new = CAMEL_FOLDER_SUMMARY ( camel_object_new (camel_folder_summary_get_type ()));
-
 	new->folder = folder;
-
 	return new;
 }
 
@@ -272,35 +427,10 @@
 	g_free(s->summary_path);
 	s->summary_path = g_strdup(name);
 
-	g_free(s->meta_summary->path);
-	s->meta_summary->path = g_strconcat(name, "-meta", NULL);
-
 	CAMEL_SUMMARY_UNLOCK(s, summary_lock);
 }
 
 
-/**
- * camel_folder_summary_set_index:
- * @summary: a #CamelFolderSummary object
- * @index: a #CamelIndex
- * 
- * Set the index used to index body content.  If the index is %NULL, or
- * not set (the default), no indexing of body content will take place.
- *
- * Unlike earlier behaviour, build_content need not be set to perform indexing.
- **/
-void
-camel_folder_summary_set_index(CamelFolderSummary *s, CamelIndex *index)
-{
-	struct _CamelFolderSummaryPrivate *p = _PRIVATE(s);
-
-	if (p->index)
-		camel_object_unref((CamelObject *)p->index);
-
-	p->index = index;
-	if (index)
-		camel_object_ref((CamelObject *)index);
-}
 
 
 /**
@@ -441,7 +571,7 @@
 	CAMEL_SUMMARY_LOCK(s, summary_lock);
 	CAMEL_SUMMARY_LOCK(s, ref_lock);
 
-	info = g_hash_table_lookup(s->messages_uid, uid);
+	info = find_message_info_with_uid (s, uid);
 
 	if (info)
 		info->refcount++;
@@ -492,12 +622,7 @@
 void
 camel_folder_summary_set_uid(CamelFolderSummary *s, guint32 uid)
 {
-	/* TODO: sync to disk? */
-	CAMEL_SUMMARY_LOCK(s, summary_lock);
-
 	s->nextuid = MAX(s->nextuid, uid);
-
-	CAMEL_SUMMARY_UNLOCK(s, summary_lock);
 }
 
 
@@ -518,29 +643,38 @@
 
 /* loads the content descriptions, recursively */
 static CamelMessageContentInfo *
-perform_content_info_load(CamelFolderSummary *s, FILE *in)
+perform_content_info_load(CamelFolderSummary *s)
 {
 	int i;
 	guint32 count;
 	CamelMessageContentInfo *ci, *part;
+	unsigned char *ptrchr = s->filepos;
+
+	ci = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->content_info_load (s);
 
-	ci = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->content_info_load(s, in);
 	if (ci == NULL)
 		return NULL;
 
-	if (camel_file_util_decode_uint32(in, &count) == -1 || count > 500) {
-		camel_folder_summary_content_info_free(s, ci);
+	ptrchr = s->filepos;
+	ptrchr = camel_file_util_mmap_decode_uint32 ((unsigned char*)ptrchr, &count, FALSE);
+	s->filepos = ptrchr;
+
+	if (count > 500) 
+	{
+		camel_folder_summary_content_info_free (s, ci);
 		return NULL;
 	}
 
-	for (i=0;i<count;i++) {
-		part = perform_content_info_load(s, in);
-		if (part) {
+	for (i=0;i<count;i++) 
+	{
+		part = perform_content_info_load(s);
+		if (part) 
+		{
 			my_list_append((struct _node **)&ci->childs, (struct _node *)part);
 			part->parent = ci;
 		} else {
 			d(fprintf (stderr, "Summary file format messed up?"));
-			camel_folder_summary_content_info_free(s, ci);
+			camel_folder_summary_content_info_free (s, ci);
 			return NULL;
 		}
 	}
@@ -559,48 +693,77 @@
 int
 camel_folder_summary_load(CamelFolderSummary *s)
 {
-	FILE *in;
 	int i;
 	CamelMessageInfo *mi;
+	GError *err = NULL;
 
-	if (s->summary_path == NULL ||
-	    s->meta_summary->path == NULL)
-		return 0;
-
-	in = g_fopen(s->summary_path, "rb");
-	if (in == NULL)
+	if (s->summary_path == NULL || !g_file_test (s->summary_path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
 		return -1;
 
 	CAMEL_SUMMARY_LOCK(s, io_lock);
-	if ( ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->summary_header_load(s, in) == -1)
+
+	if (!s->file)
+	{
+		s->file = g_mapped_file_new (s->summary_path, FALSE, &err);
+		if (err != NULL)
+		{
+			g_critical ("Unable to mmap file: %s\n", err->message);
+			g_error_free (err);
+			goto error;
+		}
+	}
+
+	s->filepos = (unsigned char*) g_mapped_file_get_contents (s->file);
+
+	if ( ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->summary_header_load(s) == -1)
 		goto error;
 
+	if (s->messages && s->messages->len > s->saved_count)
+	{
+		int r, curlen = s->messages->len;
+		for (r = curlen - 1; r >= s->saved_count - 1; r--)
+		{ 
+			CamelMessageInfo *ri = g_ptr_array_index (s->messages, r);
+			if (ri)
+				camel_folder_summary_remove (s, ri);
+		}
+	}
+
 	/* now read in each message ... */
-	for (i=0;i<s->saved_count;i++) {
-		mi = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_load(s, in);
+	for (i=0; i < s->saved_count; i++) 
+	{
+		gboolean must_add = FALSE;
+		s->idx = i;
+
+		g_static_rec_mutex_lock (&global_lock);
+		mi = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_load(s, &must_add);
+		g_static_rec_mutex_unlock (&global_lock);
 
 		if (mi == NULL)
 			goto error;
 
-		/* FIXME: this should be done differently, how i don't know */
-		if (s->build_content) {
-			((CamelMessageInfoBase *)mi)->content = perform_content_info_load(s, in);
+		if (s->build_content) 
+		{
+			if (((CamelMessageInfoBase *)mi)->content != NULL)
+				camel_folder_summary_content_info_free(s, ((CamelMessageInfoBase *)mi)->content);
+
+			((CamelMessageInfoBase *)mi)->content = perform_content_info_load (s);
 			if (((CamelMessageInfoBase *)mi)->content == NULL) {
 				camel_message_info_free(mi);
 				goto error;
 			}
 		}
 
-		camel_folder_summary_add(s, mi);
+		if (must_add)
+			camel_folder_summary_mmap_add(s, mi);
 	}
 
+
 	CAMEL_SUMMARY_UNLOCK(s, io_lock);
-	
-	if (fclose (in) != 0)
-		return -1;
 
 	s->flags &= ~CAMEL_SUMMARY_DIRTY;
 
+
 	return 0;
 
 error:
@@ -608,12 +771,12 @@
 		g_warning ("Cannot load summary file: `%s': %s", s->summary_path, g_strerror (errno));
 	
 	CAMEL_SUMMARY_UNLOCK(s, io_lock);
-	fclose (in);
 	s->flags |= ~CAMEL_SUMMARY_DIRTY;
 
 	return -1;
 }
 
+
 /* saves the content descriptions, recursively */
 static int
 perform_content_info_save(CamelFolderSummary *s, FILE *out, CamelMessageContentInfo *ci)
@@ -650,53 +813,41 @@
 camel_folder_summary_save(CamelFolderSummary *s)
 {
 	FILE *out;
-	FILE *out_meta;
-	int fd, i, fd_meta;
+	int fd, i;
 	guint32 count;
 	CamelMessageInfo *mi;
 	char *path;
-	char *path_meta;
+	gboolean herr = FALSE;
+	gboolean hadhash;
+
+	g_mutex_lock (s->dump_lock);
+
+	hadhash = (s->uidhash != NULL);
 
 	g_assert(s->message_info_size >= sizeof(CamelMessageInfoBase));
 
-	if (s->summary_path == NULL 
-	    || s->meta_summary->path == NULL
-	    || (s->flags & CAMEL_SUMMARY_DIRTY) == 0)
-		return 0;
+	if (s->summary_path == NULL || (s->flags & CAMEL_SUMMARY_DIRTY) == 0) { 
+		g_mutex_unlock (s->dump_lock); 
+		return 0; 
+	}
 
 	path = alloca(strlen(s->summary_path)+4);
 	sprintf(path, "%s~", s->summary_path);
 	fd = g_open(path, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0600);
-	if (fd == -1)
-		return -1;
-	out = fdopen(fd, "wb");
-	if (out == NULL) {
-		i = errno;
-		g_unlink(path);
-		close(fd);
-		errno = i;
-		return -1;
+
+	if (fd == -1) { 
+	  g_mutex_unlock (s->dump_lock);
+	  return -1; 
 	}
 
-	/* Meta summary code */
-	/* This meta summary will be used by beagle in order to 
-	   quickly pass through the actual summary file, which 
-	   is quite time consuming otherwise.
-	*/
-	/* FIXME: Merge meta-summary and summary */
-	path_meta = alloca(strlen(s->meta_summary->path)+4);
-	sprintf(path_meta, "%s~", s->meta_summary->path);
-	fd_meta = g_open(path_meta, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0600);
-	if (fd_meta == -1)
-		return -1;
-	out_meta = fdopen(fd_meta, "wb");
-	if (out_meta == NULL) {
+	out = fdopen(fd, "wb");
+	if (out == NULL) 
+	{
 		i = errno;
 		g_unlink(path);
-		g_unlink(path_meta);
 		close(fd);
-		close(fd_meta);
 		errno = i;
+		g_mutex_unlock (s->dump_lock);
 		return -1;
 	}
 
@@ -705,40 +856,62 @@
 	CAMEL_SUMMARY_LOCK(s, io_lock);
 
 	if (((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->summary_header_save(s, out) == -1)
-		goto exception;
- 	
-	if (summary_meta_header_save(s, out_meta) == -1)
-		goto exception;
+		goto haerror;
 
 	/* now write out each message ... */
 	/* we check ferorr when done for i/o errors */
+
 	count = s->messages->len;
-	for (i = 0; i < count; i++) {
+
+	for (i = 0; i < count; i++) 
+	{
 		mi = s->messages->pdata[i];
-		if (((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS (s)))->meta_message_info_save (s, out_meta, out, mi) == -1)
-			goto exception;
-		
+
 		if (((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS (s)))->message_info_save (s, out, mi) == -1)
-			goto exception;
+		{
+			herr = TRUE;
+			goto haerror;
+		}
 
 		if (s->build_content) {
 			if (perform_content_info_save (s, out, ((CamelMessageInfoBase *)mi)->content) == -1)
-				goto exception;
+			{
+				herr = TRUE;
+				goto haerror;
+			}
 		}
 	}
-	
-	/* FIXME: Can't we use the above "fd" variables, instead of fileno()? */
+
 	if (fflush (out) != 0 || fsync (fileno (out)) == -1)
-		goto exception;
-	
-	if (fflush (out_meta) != 0 || fsync (fileno (out_meta)) == -1)
+		herr = TRUE;
+
+haerror:
+
+	if (s->build_content) 
+		for (i = 0; i < count; i++)
+		{
+			mi = s->messages->pdata[i];
+			if (((CamelMessageInfoBase *)mi)->content != NULL)
+				camel_folder_summary_content_info_free (s, ((CamelMessageInfoBase *)mi)->content); 
+			((CamelMessageInfoBase *)mi)->content = NULL;
+		}
+
+	CAMEL_SUMMARY_UNLOCK(s, io_lock);
+
+	if (herr) 
 		goto exception;
 
 	fclose (out);
-	fclose (out_meta);
+	s->in_reload = TRUE;
+
+	if (!hadhash)
+		camel_folder_summary_prepare_hash (s);
+
+	g_static_rec_mutex_lock (&global_lock);
+	g_static_mutex_lock (&global_lock2);
+
+	camel_folder_summary_unload_mmap (s);
 
-	CAMEL_SUMMARY_UNLOCK(s, io_lock);
-	
 #ifdef G_OS_WIN32
 	g_unlink(s->summary_path);
 #endif
@@ -746,32 +919,33 @@
 		i = errno;
 		g_unlink(path);
 		errno = i;
+		g_static_mutex_unlock (&global_lock2);
+		g_static_rec_mutex_unlock (&global_lock);
 		return -1;
 	}
+	camel_folder_summary_load (s);
+
+	g_static_mutex_unlock (&global_lock2);
+	g_static_rec_mutex_unlock (&global_lock);
+
+	if (!hadhash)
+		camel_folder_summary_kill_hash (s);
+
+	s->in_reload = FALSE;
 
-	if (g_rename(path_meta, s->meta_summary->path) == -1) {
-		i = errno;
-		g_unlink(path_meta);
-		errno = i;
-		return -1;
-	}
-	
 	s->flags &= ~CAMEL_SUMMARY_DIRTY;
+	g_mutex_unlock (s->dump_lock);
+
 	return 0;
-	
- exception:
-	
+
+exception:
+
 	i = errno;
-	
 	fclose (out);
-	fclose (out_meta);
-	
-	CAMEL_SUMMARY_UNLOCK(s, io_lock);
-	
 	g_unlink (path);
-	g_unlink (path_meta);
 	errno = i;
-	
+	g_mutex_unlock (s->dump_lock);
+
 	return -1;
 }
 
@@ -789,61 +963,66 @@
 int
 camel_folder_summary_header_load(CamelFolderSummary *s)
 {
-	FILE *in;
-	FILE *in_meta;
 	int ret;
+	GError *err = NULL;
 
-	if (s->summary_path == NULL ||
-	    s->meta_summary->path == NULL)
-		return 0;
-
-	in = g_fopen(s->summary_path, "rb");
-	if (in == NULL)
+	if (s->summary_path == NULL || !g_file_test (s->summary_path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
 		return -1;
 
-	in_meta = g_fopen(s->meta_summary->path, "rb");
-	if (in_meta == NULL) {
-		fclose(in);
-		return -1;
+	CAMEL_SUMMARY_LOCK(s, io_lock);
+
+	if (!s->file)
+	{
+		s->file = g_mapped_file_new (s->summary_path, FALSE, &err);
+		if (err != NULL)
+		{
+			g_critical ("Unable to mmap file: %s\n", err->message);
+			g_error_free (err);
+			return -1;
+		}
 	}
 
-	CAMEL_SUMMARY_LOCK(s, io_lock);
-	ret = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->summary_header_load(s, in);
-	ret = summary_meta_header_load(s, in_meta);
-	CAMEL_SUMMARY_UNLOCK(s, io_lock);
+	s->filepos = (unsigned char*) g_mapped_file_get_contents (s->file);
+
+	
+	ret = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->summary_header_load(s);
 	
-	fclose(in);
-	fclose(in_meta);
 	s->flags &= ~CAMEL_SUMMARY_DIRTY;
+	CAMEL_SUMMARY_UNLOCK(s, io_lock);
+
 	return ret;
 }
 
+
+
 static int
 summary_assign_uid(CamelFolderSummary *s, CamelMessageInfo *info)
 {
 	const char *uid;
 	CamelMessageInfo *mi;
+	CamelMessageInfoBase *bi = (CamelMessageInfoBase*)info;
 
-	uid = camel_message_info_uid(info);
+	uid = camel_message_info_uid (info);
 	if (uid == NULL || uid[0] == 0) {
-		g_free(info->uid);
 		uid = info->uid = camel_folder_summary_next_uid_string(s);
+		bi->flags |= CAMEL_MESSAGE_INFO_UID_NEEDS_FREE;
 	}
 
-	CAMEL_SUMMARY_LOCK(s, summary_lock);
-
-	while ((mi = g_hash_table_lookup(s->messages_uid, uid))) {
-		CAMEL_SUMMARY_UNLOCK(s, summary_lock);
-		if (mi == info)
+	while ((mi = find_message_info_with_uid (s, uid))) 
+	{
+		if (mi == info) 
 			return 0;
+
 		d(printf ("Trying to insert message with clashing uid (%s).  new uid re-assigned", camel_message_info_uid(info)));
-		g_free(info->uid);
+
+		if (bi->flags & CAMEL_MESSAGE_INFO_UID_NEEDS_FREE)
+			g_free(info->uid);
 		uid = info->uid = camel_folder_summary_next_uid_string(s);
+		bi->flags |= CAMEL_MESSAGE_INFO_UID_NEEDS_FREE;
+
 		camel_message_info_set_flags(info, CAMEL_MESSAGE_FOLDER_FLAGGED, CAMEL_MESSAGE_FOLDER_FLAGGED);
-		CAMEL_SUMMARY_LOCK(s, summary_lock);
 	}
 
-	CAMEL_SUMMARY_UNLOCK(s, summary_lock);
 
 	return 1;
 }
@@ -865,11 +1044,20 @@
 void
 camel_folder_summary_add(CamelFolderSummary *s, CamelMessageInfo *info)
 {
-	if (info == NULL)
+
+	g_mutex_lock (s->dump_lock);
+
+	if (info == NULL) 
+	{
+		g_mutex_unlock (s->dump_lock);
 		return;
+	}
 
 	if (summary_assign_uid(s, info) == 0)
+	{
+		g_mutex_unlock (s->dump_lock);
 		return;
+	}
 
 	CAMEL_SUMMARY_LOCK(s, summary_lock);
 
@@ -881,12 +1069,42 @@
 #endif
 
 	g_ptr_array_add(s->messages, info);
-	g_hash_table_insert(s->messages_uid, (char *)camel_message_info_uid(info), info);
+
+	g_mutex_lock (s->hash_lock);
+	if (s->uidhash != NULL)
+		g_hash_table_insert (s->uidhash, g_strdup (info->uid), info);
+	g_mutex_unlock (s->hash_lock);
+
 	s->flags |= CAMEL_SUMMARY_DIRTY;
 
 	CAMEL_SUMMARY_UNLOCK(s, summary_lock);
+
+	g_mutex_unlock (s->dump_lock);
 }
 
+static void
+camel_folder_summary_mmap_add(CamelFolderSummary *s, CamelMessageInfo *info)
+{
+	CAMEL_SUMMARY_LOCK(s, summary_lock);
+
+/* unnecessary for pooled vectors */
+#ifdef DOESTRV
+	/* this is vitally important, and also if this is ever modified, then
+	   the hash table needs to be resynced */
+	info->strings = e_strv_pack(info->strings);
+#endif
+
+	g_ptr_array_add(s->messages, info);
+
+	g_mutex_lock (s->hash_lock);
+	if (s->uidhash != NULL)
+		g_hash_table_insert (s->uidhash, g_strdup (info->uid), info);
+	g_mutex_unlock (s->hash_lock);
+
+	s->flags |= CAMEL_SUMMARY_DIRTY;
+
+	CAMEL_SUMMARY_UNLOCK(s, summary_lock);
+}
 
 /**
  * camel_folder_summary_add_from_header:
@@ -972,6 +1190,28 @@
 	return ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_new_from_header(s, h);
 }
 
+CamelMessageInfo *
+camel_folder_summary_info_new_from_header_with_uid (CamelFolderSummary *s, struct _camel_header_raw *h, const gchar *uid)
+{
+
+	CamelMessageInfo *mi;
+	CamelMessageInfoBase *bi;
+
+	if (s != NULL)
+		mi = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_new_from_header(s, h);
+	else 
+		mi = message_info_new_from_header(s, h);
+
+	bi = (CamelMessageInfoBase *)mi;
+
+	if (bi->uid && (bi->flags & CAMEL_MESSAGE_INFO_UID_NEEDS_FREE))
+		g_free (bi->uid);
+
+	((CamelMessageInfoBase *)mi)->uid = g_strdup (uid);
+	((CamelMessageInfoBase*)mi)->flags |= CAMEL_MESSAGE_INFO_UID_NEEDS_FREE;
+
+	return mi;
+}
 
 /**
  * camel_folder_summary_info_new_from_parser:
@@ -1000,45 +1240,15 @@
 	CamelMessageInfo *info = NULL;
 	char *buffer;
 	size_t len;
-	struct _CamelFolderSummaryPrivate *p = _PRIVATE(s);
 	off_t start;
-	CamelIndexName *name = NULL;
 
 	/* should this check the parser is in the right state, or assume it is?? */
 
 	start = camel_mime_parser_tell(mp);
 	if (camel_mime_parser_step(mp, &buffer, &len) != CAMEL_MIME_PARSER_STATE_EOF) {
 		info = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_new_from_parser(s, mp);
-
 		camel_mime_parser_unstep(mp);
-
-		/* assign a unique uid, this is slightly 'wrong' as we do not really
-		 * know if we are going to store this in the summary, but no matter */
-		if (p->index)
-			summary_assign_uid(s, info);
-
-		CAMEL_SUMMARY_LOCK(s, filter_lock);
-
-		if (p->index) {
-			if (p->filter_index == NULL)
-				p->filter_index = camel_mime_filter_index_new_index(p->index);
-			camel_index_delete_name(p->index, camel_message_info_uid(info));
-			name = camel_index_add_name(p->index, camel_message_info_uid(info));
-			camel_mime_filter_index_set_name(p->filter_index, name);
-		}
-
-		/* always scan the content info, even if we dont save it */
-		((CamelMessageInfoBase *)info)->content = summary_build_content_info(s, info, mp);
-
-		if (name && p->index) {
-			camel_index_write_name(p->index, name);
-			camel_object_unref((CamelObject *)name);
-			camel_mime_filter_index_set_name(p->filter_index, NULL);
-		}
-
-		CAMEL_SUMMARY_UNLOCK(s, filter_lock);
-
-		((CamelMessageInfoBase *)info)->size = camel_mime_parser_tell(mp) - start;
+		((CamelMessageInfoBase *)info)->size = ( (camel_mime_parser_tell(mp) - start) );
 	}
 	return info;
 }
@@ -1058,42 +1268,22 @@
 camel_folder_summary_info_new_from_message(CamelFolderSummary *s, CamelMimeMessage *msg)
 {
 	CamelMessageInfo *info;
-	struct _CamelFolderSummaryPrivate *p = _PRIVATE(s);
-	CamelIndexName *name = NULL;
 
-	info = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_new_from_message(s, msg);
+	if (s != NULL)
+	{
+		info = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_new_from_message(s, msg);
+	} else
+		info = message_info_new_from_message(s, msg);
 
-	/* assign a unique uid, this is slightly 'wrong' as we do not really
-	 * know if we are going to store this in the summary, but we need it set for indexing */
-	if (p->index)
-		summary_assign_uid(s, info);
-
-	CAMEL_SUMMARY_LOCK(s, filter_lock);
-
-	if (p->index) {
-		if (p->filter_index == NULL)
-			p->filter_index = camel_mime_filter_index_new_index(p->index);
-		camel_index_delete_name(p->index, camel_message_info_uid(info));
-		name = camel_index_add_name(p->index, camel_message_info_uid(info));
-		camel_mime_filter_index_set_name(p->filter_index, name);
 
-		if (p->filter_stream == NULL) {
-			CamelStream *null = camel_stream_null_new();
-
-			p->filter_stream = camel_stream_filter_new_with_stream(null);
-			camel_object_unref((CamelObject *)null);
-		}
-	}
+	if (s!=NULL)
+		CAMEL_SUMMARY_LOCK(s, filter_lock);
 
 	((CamelMessageInfoBase *)info)->content = summary_build_content_info_message(s, info, (CamelMimePart *)msg);
 
-	if (name) {
-		camel_index_write_name(p->index, name);
-		camel_object_unref((CamelObject *)name);
-		camel_mime_filter_index_set_name(p->filter_index, NULL);
-	}
 
-	CAMEL_SUMMARY_UNLOCK(s, filter_lock);
+	if (s!=NULL)
+		CAMEL_SUMMARY_UNLOCK(s, filter_lock);
 
 	return info;
 }
@@ -1112,7 +1302,12 @@
 	CamelMessageContentInfo *pw, *pn;
 
 	pw = ci->childs;
-	((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->content_info_free(s, ci);
+
+	if (s != NULL)
+		((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->content_info_free(s, ci);
+	else
+		content_info_free (NULL, ci);
+
 	while (pw) {
 		pn = pw->next;
 		camel_folder_summary_content_info_free(s, pw);
@@ -1131,9 +1326,7 @@
 void
 camel_folder_summary_touch(CamelFolderSummary *s)
 {
-	CAMEL_SUMMARY_LOCK(s, summary_lock);
 	s->flags |= CAMEL_SUMMARY_DIRTY;
-	CAMEL_SUMMARY_UNLOCK(s, summary_lock);
 }
 
 
@@ -1158,10 +1351,7 @@
 		camel_message_info_free(s->messages->pdata[i]);
 
 	g_ptr_array_set_size(s->messages, 0);
-	g_hash_table_destroy(s->messages_uid);
-	s->messages_uid = g_hash_table_new(g_str_hash, g_str_equal);
 	s->flags |= CAMEL_SUMMARY_DIRTY;
-	s->meta_summary->msg_expunged = TRUE;
 	CAMEL_SUMMARY_UNLOCK(s, summary_lock);
 }
 
@@ -1176,14 +1366,25 @@
 void
 camel_folder_summary_remove(CamelFolderSummary *s, CamelMessageInfo *info)
 {
-	CAMEL_SUMMARY_LOCK(s, summary_lock);
-	g_hash_table_remove(s->messages_uid, camel_message_info_uid(info));
-	g_ptr_array_remove(s->messages, info);
-	s->flags |= CAMEL_SUMMARY_DIRTY;
-	s->meta_summary->msg_expunged = TRUE;
-	CAMEL_SUMMARY_UNLOCK(s, summary_lock);
-	
-	camel_message_info_free(info);
+	g_mutex_lock (s->dump_lock);
+
+	if (((CamelMessageInfoBase*)info)->flags & CAMEL_MESSAGE_EXPUNGED)
+	{
+		CAMEL_SUMMARY_LOCK(s, summary_lock);
+		g_ptr_array_remove(s->messages, info);
+		g_ptr_array_add (s->expunged, info);
+		s->flags |= CAMEL_SUMMARY_DIRTY;
+		CAMEL_SUMMARY_UNLOCK(s, summary_lock);
+	} else {
+
+		CAMEL_SUMMARY_LOCK(s, summary_lock);
+		g_ptr_array_remove(s->messages, info);
+		s->flags |= CAMEL_SUMMARY_DIRTY;
+		CAMEL_SUMMARY_UNLOCK(s, summary_lock);
+		camel_message_info_free(info);
+	}
+
+	g_mutex_unlock (s->dump_lock);
 }
 
 
@@ -1197,19 +1398,22 @@
 void
 camel_folder_summary_remove_uid(CamelFolderSummary *s, const char *uid)
 {
-        CamelMessageInfo *oldinfo;
-        char *olduid;
+	CamelMessageInfo *oldinfo = NULL;
 
 	CAMEL_SUMMARY_LOCK(s, summary_lock);
 	CAMEL_SUMMARY_LOCK(s, ref_lock);
-        if (g_hash_table_lookup_extended(s->messages_uid, uid, (void *)&olduid, (void *)&oldinfo)) {
+
+	oldinfo = find_message_info_with_uid (s, uid);
+
+	if (oldinfo) 
+	{
 		/* make sure it doesn't vanish while we're removing it */
 		oldinfo->refcount++;
 		CAMEL_SUMMARY_UNLOCK(s, ref_lock);
 		CAMEL_SUMMARY_UNLOCK(s, summary_lock);
 		camel_folder_summary_remove(s, oldinfo);
 		camel_message_info_free(oldinfo);
-        } else {
+	} else {
 		CAMEL_SUMMARY_UNLOCK(s, ref_lock);
 		CAMEL_SUMMARY_UNLOCK(s, summary_lock);
 	}
@@ -1230,7 +1434,6 @@
 	if (index < s->messages->len) {
 		CamelMessageInfo *info = s->messages->pdata[index];
 
-		g_hash_table_remove(s->messages_uid, camel_message_info_uid(info));
 		g_ptr_array_remove_index(s->messages, index);
 		s->flags |= CAMEL_SUMMARY_DIRTY;
 
@@ -1256,6 +1459,7 @@
 	if (end < start)
 		return;
 
+	g_mutex_lock (s->dump_lock);
 	CAMEL_SUMMARY_LOCK(s, summary_lock);
 	if (start < s->messages->len) {
 		CamelMessageInfo **infos;
@@ -1264,13 +1468,6 @@
 		end = MIN(end+1, s->messages->len);
 		infos = g_malloc((end-start)*sizeof(infos[0]));
 
-		for (i=start;i<end;i++) {
-			CamelMessageInfo *info = s->messages->pdata[i];
-
-			infos[i-start] = info;
-			g_hash_table_remove(s->messages_uid, camel_message_info_uid(info));
-		}
-
 		memmove(s->messages->pdata+start, s->messages->pdata+end, (s->messages->len-end)*sizeof(s->messages->pdata[0]));
 		g_ptr_array_set_size(s->messages, s->messages->len - (end - start));
 		s->flags |= CAMEL_SUMMARY_DIRTY;
@@ -1283,6 +1480,8 @@
 	} else {
 		CAMEL_SUMMARY_UNLOCK(s, summary_lock);
 	}
+	
+	g_mutex_unlock (s->dump_lock);
 }
 
 /* should be sorted, for binary search */
@@ -1319,6 +1518,41 @@
 
 #define tokens_len (sizeof(tokens)/sizeof(tokens[0]))
 
+guint bytes;
+static gchar* 
+token_add (gchar *str)
+{
+	int i;
+
+	if (!str)
+		return NULL;
+
+	for (i=0; i<tokens_len; i++)
+		if (!strcmp (str, tokens[i]))
+		{
+			g_free (str);
+			return tokens[i];
+		}
+
+	return (gchar*) camel_pstring_add (str, FALSE);
+}
+
+
+static void
+token_free (gchar *token)
+{
+        gint i;
+
+	if (!token)
+		return;
+
+        for (i = 0; i < tokens_len; i ++)
+                if (tokens[i] == token)
+                        return;
+
+        camel_pstring_free (token);
+}
+
 /* baiscally ...
     0 = null
     1-tokens_len == tokens[id-1]
@@ -1379,12 +1613,26 @@
 		if (token != -1) {
 			return camel_file_util_encode_uint32(out, token+1);
 		} else {
-			if (camel_file_util_encode_uint32(out, len+32) == -1)
-				return -1;
-			if (fwrite(str, len, 1, out) != 1)
+			int lena;
+
+			lena = len = strlen (str) + 1;
+
+			if (lena % G_MEM_ALIGN)
+				lena += G_MEM_ALIGN - (lena % G_MEM_ALIGN);
+
+			if (camel_file_util_encode_uint32(out, lena+32) == -1)
 				return -1;
+
+			if (fwrite (str, len, 1, out) == 1) {
+				if (lena > len) {
+					if (fwrite ("\0\0\0\0\0\0\0\0", lena-len, 1, out) == 1)
+						return 0;
+					else return -1;
+				}
+			}
 		}
 	}
+
 	return 0;
 }
 
@@ -1399,24 +1647,22 @@
  * Returns %0 on success or %-1 on fail
  **/
 int
-camel_folder_summary_decode_token(FILE *in, char **str)
+camel_folder_summary_decode_token(CamelFolderSummary *s, char **str)
 {
 	char *ret;
 	guint32 len;
+	unsigned char *ptrchr = s->filepos;
 
 	io(printf("Decode token ...\n"));
-	
-	if (camel_file_util_decode_uint32(in, &len) == -1) {
-		io(printf ("Could not decode token from file"));
-		*str = NULL;
-		return -1;
-	}
+
+	ptrchr = camel_file_util_mmap_decode_uint32 ((unsigned char*)ptrchr, &len, FALSE);
 
 	if (len<32) {
+
 		if (len <= 0) {
 			ret = NULL;
 		} else if (len<= tokens_len) {
-			ret = g_strdup(tokens[len-1]);
+			ret = tokens[len-1];
 		} else {
 			io(printf ("Invalid token encountered: %d", len));
 			*str = NULL;
@@ -1427,17 +1673,17 @@
 		*str = NULL;
 		return -1;
 	} else {
+
 		len -= 32;
-		ret = g_malloc(len+1);
-		if (len > 0 && fread(ret, len, 1, in) != 1) {
-			g_free(ret);
-			*str = NULL;
-			return -1;
-		}
-		ret[len]=0;
+
+		if (len != 0)
+			ret = (char*)ptrchr;
+		else ret = NULL;
+
+		ptrchr += len;
 	}
 
-	io(printf("Token = '%s'\n", ret));
+	s->filepos = ptrchr;
 
 	*str = ret;
 	return 0;
@@ -1467,63 +1713,42 @@
 }
 
 static int
-summary_meta_header_load(CamelFolderSummary *s, FILE *in)
-{
-	if (!s->meta_summary->path)
-		return -1;
-
-	fseek(in, 0, SEEK_SET);
-
-	io(printf("Loading meta-header\n"));
-
-	if (camel_file_util_decode_uint32(in, &s->meta_summary->major) == -1
-	    || camel_file_util_decode_uint32(in, &s->meta_summary->minor) == -1
-	    || camel_file_util_decode_uint32(in, &s->meta_summary->uid_len) == -1) {
-		return -1;
-	}
-	
-	return 0;
-}
-
-static int
-summary_header_load(CamelFolderSummary *s, FILE *in)
+summary_header_load(CamelFolderSummary *s)
 {
-	if (!s->summary_path)
-		return -1;
+	s->version = g_ntohl(get_unaligned_u32(s->filepos)); 
+	s->filepos += 4;
 
-	fseek(in, 0, SEEK_SET);
+	io(printf("Loading header %d", (s->version&0xff)));
 
-	io(printf("Loading header\n"));
-
-	if (camel_file_util_decode_fixed_int32(in, &s->version) == -1)
-		return -1;
-
-	/* Legacy version check, before version 12 we have no upgrade knowledge */
+	/* Legacy version check, before version 13 we have no upgrade knowledge */
 	if ((s->version > 0xff) && (s->version & 0xff) < 12) {
 		io(printf ("Summary header version mismatch"));
 		errno = EINVAL;
 		return -1;
 	}
 
-	if (!(s->version < 0x100 && s->version >= 13))
-		io(printf("Loading legacy summary\n"));
-	else
-		io(printf("loading new-format summary\n"));
-
-	/* legacy version */
-	if (camel_file_util_decode_fixed_int32(in, &s->flags) == -1
-	    || camel_file_util_decode_fixed_int32(in, &s->nextuid) == -1
-	    || camel_file_util_decode_time_t(in, &s->time) == -1
-	    || camel_file_util_decode_fixed_int32(in, &s->saved_count) == -1) {
+	/* Check for MMAPable file */
+	if (s->version != CAMEL_FOLDER_SUMMARY_VERSION) {
+		errno = EINVAL;
 		return -1;
 	}
 
-	/* version 13 */
-	if (s->version < 0x100 && s->version >= 13
-	    && (camel_file_util_decode_fixed_int32(in, &s->unread_count) == -1
-		|| camel_file_util_decode_fixed_int32(in, &s->deleted_count) == -1
-		|| camel_file_util_decode_fixed_int32(in, &s->junk_count) == -1)) {
-		return -1;
+	s->flags = g_ntohl(get_unaligned_u32(s->filepos)); 
+	s->filepos += 4;
+	s->nextuid = g_ntohl(get_unaligned_u32(s->filepos)); 
+	s->filepos += 4;
+	s->time = (time_t)g_ntohl(get_unaligned_u32(s->filepos)); 
+	s->filepos += 4;
+	s->saved_count = g_ntohl(get_unaligned_u32(s->filepos)); 
+	s->filepos += 4;
+
+	if (s->version < 0x100 && s->version >= 13) {
+		s->unread_count = g_ntohl(get_unaligned_u32(s->filepos)); 
+		s->filepos += 4;
+		s->deleted_count = g_ntohl(get_unaligned_u32(s->filepos)); 
+		s->filepos += 4;
+		s->junk_count = g_ntohl(get_unaligned_u32(s->filepos)); 
+		s->filepos += 4;
 	}
 
 	return 0;
@@ -1557,8 +1782,6 @@
 			unread++;
 		if ((flags & CAMEL_MESSAGE_DELETED) != 0)
 			deleted++;
-		if ((flags & CAMEL_MESSAGE_JUNK) != 0)
-			junk++;
 
 		camel_message_info_free(info);
 	}
@@ -1570,25 +1793,6 @@
 	return camel_file_util_encode_fixed_int32(out, junk);
 }
 
-static int
-summary_meta_header_save(CamelFolderSummary *s, FILE *out_meta)
-{
-	fseek(out_meta, 0, SEEK_SET);
-
-	/* Save meta-summary header */
-	if (s->meta_summary->msg_expunged) {
-		s->meta_summary->msg_expunged = FALSE;
-		camel_file_util_encode_uint32(out_meta, ++s->meta_summary->major);
-		camel_file_util_encode_uint32(out_meta, (s->meta_summary->minor=0));
-	} else {
-		camel_file_util_encode_uint32(out_meta, s->meta_summary->major);
-		camel_file_util_encode_uint32(out_meta, ++s->meta_summary->minor);
-	}
-	camel_file_util_encode_uint32(out_meta, s->meta_summary->uid_len);
-
-	return ferror(out_meta);
-}
-
 /* are these even useful for anything??? */
 static CamelMessageInfo *
 message_info_new_from_parser(CamelFolderSummary *s, CamelMimeParser *mp)
@@ -1637,7 +1841,10 @@
 {
 	CamelMessageInfo *mi;
 
-	mi = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_new_from_header(s, ((CamelMimePart *)msg)->headers);
+	if (s != NULL)
+		mi = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_new_from_header(s, ((CamelMimePart *)msg)->headers);
+	else
+		mi = message_info_new_from_header(s, ((CamelMimePart *)msg)->headers);
 
 	return mi;
 }
@@ -1647,7 +1854,10 @@
 {
 	CamelMessageContentInfo *ci;
 
-	ci = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->content_info_new_from_header(s, mp->headers);
+	if (s != NULL)
+		ci = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->content_info_new_from_header(s, mp->headers);
+	else
+		ci = content_info_new_from_header(NULL, mp->headers);
 
 	return ci;
 }
@@ -1677,6 +1887,7 @@
 	const char *text;
 	
 	text = camel_header_raw_find (&h, name, NULL);
+
 	if (text) {
 		while (isspace ((unsigned) *text))
 			text++;
@@ -1686,9 +1897,44 @@
 	}
 }
 
+#ifndef _GNU_SOURCE
+static char *strcasestr(const char *haystack, const char *needle)
+{
+      const gchar *p = haystack;
+      gsize needle_len = strlen (needle);
+      gsize haystack_len;
+      const gchar *end;
+      gsize i;
+
+      if (needle_len == 0)
+	return (gchar *)haystack;
+
+      haystack_len = strlen (haystack);
+
+      if (haystack_len < needle_len)
+	return NULL;
 
+      end = haystack + haystack_len - needle_len;
+      while (*p && p <= end)
+	{
+	  for (i = 0; i < needle_len; i++)
+	    if (tolower (p[i]) != tolower (needle[i]))
+	      goto next;
+	  
+	  return (gchar *)p;
+	  
+	next:
+	  p++;
+	}
+      
+      return NULL;
+}
+#else
+char *strcasestr(const char *haystack, const char *needle);
+#endif
 /**
- * camel_folder_summary_content_info_new:
+ * 
+ :
  * @summary: a #CamelFolderSummary object
  * 
  * Allocate a new #CamelMessageContentInfo, suitable for adding
@@ -1699,16 +1945,9 @@
 CamelMessageContentInfo *
 camel_folder_summary_content_info_new(CamelFolderSummary *s)
 {
-	CamelMessageContentInfo *ci;
-
-	CAMEL_SUMMARY_LOCK(s, alloc_lock);
-	if (s->content_info_chunks == NULL)
-		s->content_info_chunks = e_memchunk_new(32, s->content_info_size);
-	ci = e_memchunk_alloc(s->content_info_chunks);
-	CAMEL_SUMMARY_UNLOCK(s, alloc_lock);
-
-	memset(ci, 0, s->content_info_size);
-	return ci;
+	if (s != NULL)
+		return g_slice_alloc0(s->content_info_size);
+	return g_slice_new0 (CamelMessageContentInfo);
 }
 
 static CamelMessageInfo *
@@ -1717,14 +1956,15 @@
 	CamelMessageInfoBase *mi;
 	const char *received;
 	guchar digest[16];
-	struct _camel_header_references *refs, *irt, *scan;
-	char *msgid;
-	int count;
-	char *subject, *from, *to, *cc, *mlist;
+	char *msgid, *r=NULL;
+	char *subject, *from, *to, *cc;
 	CamelContentType *ct = NULL;
 	const char *content, *charset = NULL;
+	const char *prio = NULL;
+	const char *attach = NULL;
 
 	mi = (CamelMessageInfoBase *)camel_message_info_new(s);
+	mi->flags |= CAMEL_MESSAGE_INFO_NEEDS_FREE;
 
 	if ((content = camel_header_raw_find(&h, "Content-Type", NULL))
 	     && (ct = camel_content_type_decode(content))
@@ -1738,191 +1978,295 @@
 	from = summary_format_address(h, "from", charset);
 	to = summary_format_address(h, "to", charset);
 	cc = summary_format_address(h, "cc", charset);
-	mlist = camel_header_raw_check_mailing_list(&h);
+
+	prio = camel_header_raw_find(&h, "X-Priority", NULL);
+	if (!prio)
+		prio = camel_header_raw_find(&h, "X-MSMail-Priority", NULL);
+
+	if (prio) 
+	{ 
+		if (strcasestr (prio, "high") != NULL)
+			mi->flags |= CAMEL_MESSAGE_HIGH_PRIORITY;
+		else if (strchr (prio, '1') != NULL)
+			mi->flags |= CAMEL_MESSAGE_HIGH_PRIORITY;
+		else if (strcasestr (prio, "normal") != NULL)
+			mi->flags |= CAMEL_MESSAGE_NORMAL_PRIORITY;
+		else if (strchr (prio, '2') != NULL)
+			mi->flags |= CAMEL_MESSAGE_NORMAL_PRIORITY;
+		else if (strcasestr (prio, "low") != NULL)
+			mi->flags |= CAMEL_MESSAGE_LOW_PRIORITY;
+		else if (strchr (prio, '3') != NULL)
+			mi->flags |= CAMEL_MESSAGE_LOW_PRIORITY;
+	} else 
+		mi->flags |= CAMEL_MESSAGE_NORMAL_PRIORITY;
+
+	attach = camel_header_raw_find(&h, "X-MS-Has-Attach", NULL);
+	if (attach)
+		if (strcasestr (attach, "yes") != NULL)
+			mi->flags |= CAMEL_MESSAGE_ATTACHMENTS;
+	/* else {
+		attach = camel_header_raw_find(&h, "Content-Type", NULL);
+		if (strcasestr (attach, "multi") != NULL)
+			mi->flags |= CAMEL_MESSAGE_ATTACHMENTS;
+	} */
+
 
 	if (ct)
 		camel_content_type_unref(ct);
-	
-	mi->subject = camel_pstring_add (subject, TRUE);
-	mi->from = camel_pstring_add (from, TRUE);
-	mi->to = camel_pstring_add (to, TRUE);
-	mi->cc = camel_pstring_add (cc, TRUE);
-	mi->mlist = camel_pstring_add (mlist, TRUE);
-	
-	mi->user_flags = NULL;
-	mi->user_tags = NULL;
+
+	if (subject)
+		mi->subject = camel_pstring_add (subject, TRUE);
+	else 
+		mi->subject = camel_pstring_add (g_strdup (""), TRUE);
+
+	if (from)
+		mi->from = camel_pstring_add (from, TRUE);
+	else 
+		mi->from = camel_pstring_add (g_strdup (""), TRUE);
+
+	if (to)
+		mi->to = camel_pstring_add (to, TRUE);
+	else 
+		mi->to = camel_pstring_add (g_strdup (""), TRUE);
+
+	if (cc)
+		mi->cc = camel_pstring_add (cc, TRUE);
+	else 
+		mi->cc = camel_pstring_add (g_strdup (""), TRUE);
+
 	mi->date_sent = camel_header_decode_date(camel_header_raw_find(&h, "date", NULL), NULL);
 	received = camel_header_raw_find(&h, "received", NULL);
+
 	if (received)
-		received = strrchr(received, ';');
-	if (received)
-		mi->date_received = camel_header_decode_date(received + 1, NULL);
-	else
+		r = strrchr(received, ';');
+	if (r)
+		mi->date_received = camel_header_decode_date(r + 1, NULL);
+
+	else if (received)
+		mi->date_received = camel_header_decode_date(received, NULL);
+	else 
 		mi->date_received = 0;
 
 	msgid = camel_header_msgid_decode(camel_header_raw_find(&h, "message-id", NULL));
-	if (msgid) {
+	if (msgid) 
+	{
 		md5_get_digest(msgid, strlen(msgid), digest);
 		memcpy(mi->message_id.id.hash, digest, sizeof(mi->message_id.id.hash));
 		g_free(msgid);
 	}
-	
-	/* decode our references and in-reply-to headers */
-	refs = camel_header_references_decode (camel_header_raw_find (&h, "references", NULL));
-	irt = camel_header_references_inreplyto_decode (camel_header_raw_find (&h, "in-reply-to", NULL));
-	if (refs || irt) {
-		if (irt) {
-			/* The References field is populated from the ``References'' and/or ``In-Reply-To''
-			   headers. If both headers exist, take the first thing in the In-Reply-To header
-			   that looks like a Message-ID, and append it to the References header. */
-			
-			if (refs)
-				irt->next = refs;
-			
-			refs = irt;
-		}
-		
-		count = camel_header_references_list_size(&refs);
-		mi->references = g_malloc(sizeof(*mi->references) + ((count-1) * sizeof(mi->references->references[0])));
-		count = 0;
-		scan = refs;
-		while (scan) {
-			md5_get_digest(scan->id, strlen(scan->id), digest);
-			memcpy(mi->references->references[count].id.hash, digest, sizeof(mi->message_id.id.hash));
-			count++;
-			scan = scan->next;
-		}
-		mi->references->size = count;
-		camel_header_references_list_clear(&refs);
-	}
+
 
 	return (CamelMessageInfo *)mi;
 }
 
+
 static CamelMessageInfo *
-message_info_load(CamelFolderSummary *s, FILE *in)
+message_info_load(CamelFolderSummary *s, gboolean *must_add)
 {
-	CamelMessageInfoBase *mi;
-	guint count;
-	int i;
-	char *subject, *from, *to, *cc, *mlist, *uid;
-
-	mi = (CamelMessageInfoBase *)camel_message_info_new(s);
+	CamelMessageInfoBase *mi = NULL;
+	guint count, len;
+	unsigned char *ptrchr = s->filepos;
+	unsigned int i;
+	gchar *theuid;
 
 	io(printf("Loading message info\n"));
 
-	camel_file_util_decode_string(in, &uid);
-	camel_file_util_decode_uint32(in, &mi->flags);
-	camel_file_util_decode_uint32(in, &mi->size);
-	camel_file_util_decode_time_t(in, &mi->date_sent);
-	camel_file_util_decode_time_t(in, &mi->date_received);
-	camel_file_util_decode_string(in, &subject);
-	camel_file_util_decode_string(in, &from);
-	camel_file_util_decode_string(in, &to);
-	camel_file_util_decode_string(in, &cc);
-	camel_file_util_decode_string(in, &mlist);
-	
-	mi->uid = uid;
-	mi->subject = camel_pstring_add (subject, TRUE);
-	mi->from = camel_pstring_add (from, TRUE);
-	mi->to = camel_pstring_add (to, TRUE);
-	mi->cc = camel_pstring_add (cc, TRUE);
-	mi->mlist = camel_pstring_add (mlist, TRUE);
-	
-	mi->content = NULL;
+	/* Try to find the original instance in case we are in reloading */
 
-	camel_file_util_decode_fixed_int32(in, &mi->message_id.id.part.hi);
-	camel_file_util_decode_fixed_int32(in, &mi->message_id.id.part.lo);
+	ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &len, TRUE);
+	if (len) 
+		theuid = (char*)ptrchr;
+	ptrchr += len;
+
+	if (!s->in_reload)
+	{
+		/* We are not reloading, so searching for recoverable 
+		 * CamelMessageInfo struct instances is avoidable */
+		mi = (CamelMessageInfoBase *) camel_message_info_new (s);
+		*must_add = TRUE;
+		mi->uid = theuid;
+	} else 
+	{
+		CAMEL_SUMMARY_LOCK(s, summary_lock);
 
-	if (camel_file_util_decode_uint32(in, &count) == -1 || count > 500)
-		goto error;
+		if (s->messages && s->idx >=0 && s->idx < s->messages->len)
+		{
+			CAMEL_SUMMARY_LOCK(s, ref_lock);
+
+			mi = (CamelMessageInfoBase *) s->messages->pdata[s->idx];
+			destroy_possible_pstring_stuff (s, (CamelMessageInfo*) mi, FALSE);
+			*must_add = FALSE;
+			if (mi->uid && (mi->flags & CAMEL_MESSAGE_INFO_UID_NEEDS_FREE))
+				g_free (mi->uid);
+			mi->uid = theuid;
+			CAMEL_SUMMARY_UNLOCK(s, ref_lock);
+		} else
+			printf ("Problem with %s. Can't find original instance (index=%d)\n", theuid, s->idx);
 
-	if (count > 0) {
-		mi->references = g_malloc(sizeof(*mi->references) + ((count-1) * sizeof(mi->references->references[0])));
-		mi->references->size = count;
-		for (i=0;i<count;i++) {
-			camel_file_util_decode_fixed_int32(in, &mi->references->references[i].id.part.hi);
-			camel_file_util_decode_fixed_int32(in, &mi->references->references[i].id.part.lo);
-		}
+		CAMEL_SUMMARY_UNLOCK(s, summary_lock);
 	}
 
-	if (camel_file_util_decode_uint32(in, &count) == -1 || count > 500)
-		goto error;
+	i = 0;
 
-	for (i=0;i<count;i++) {
-		char *name;
-		if (camel_file_util_decode_string(in, &name) == -1 || name == NULL)
-			goto error;
-		camel_flag_set(&mi->user_flags, name, TRUE);
-		g_free(name);
+	if (!mi)
+	{
+		mi = (CamelMessageInfoBase *) camel_message_info_new(s);
+		*must_add = TRUE;
+		mi->uid = theuid;
 	}
 
-	if (camel_file_util_decode_uint32(in, &count) == -1 || count > 500)
-		goto error;
+	ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &mi->size, FALSE);
+
+	ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &mi->flags, FALSE); 
+
+	mi->flags &= ~CAMEL_MESSAGE_INFO_NEEDS_FREE;
+	mi->flags &= ~CAMEL_MESSAGE_INFO_UID_NEEDS_FREE;
+	mi->flags &= ~CAMEL_MESSAGE_FREED;
+
+	s->set_extra_flags_func (s->folder, mi);
+
+	ptrchr = camel_file_util_mmap_decode_time_t (ptrchr, &mi->date_sent);
+	ptrchr = camel_file_util_mmap_decode_time_t (ptrchr, &mi->date_received);
+
+	ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &len, TRUE);
+
+	if (len) 
+		mi->subject = (const char*)ptrchr;
+
+	ptrchr += len;
+	ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &len, TRUE);
+
+	if (len) 
+		mi->from = (const char*)ptrchr;
+	
+	ptrchr += len;
 
+	ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &len, TRUE);
+
+	if (len) 
+		mi->to = (const char*)ptrchr;
+	ptrchr += len;
+
+	ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &len, TRUE);
+
+	if (len) 
+		mi->cc = (const char*)ptrchr;
+	ptrchr += len;
+
+	ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &len, TRUE);
+
+#ifdef NON_TINYMAIL_FEATURES
+	if (len) 
+		mi->mlist = (const char*)ptrchr;
+#endif
+
+	ptrchr += len;
+	s->filepos = ptrchr;
+
+/* #ifdef NON_TINYMAIL_FEATURES */
+	mi->message_id.id.part.hi = g_ntohl(get_unaligned_u32(s->filepos)); 
+	s->filepos += 4;
+	mi->message_id.id.part.lo = g_ntohl(get_unaligned_u32(s->filepos)); 
+	s->filepos += 4;
+/* #else 
+	s->filepos += 8; 
+#endif */
+
+	ptrchr = (unsigned char*) s->filepos;
+	ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &count, FALSE);
+
+#ifdef NON_TINYMAIL_FEATURES 
+	if (mi->references)
+		g_free (mi->references);
+	mi->references = g_malloc(sizeof(*mi->references) + ((count-1) * sizeof(mi->references->references[0])));
+	mi->references->size = count;
+#endif
+
+	s->filepos = ptrchr;
+
+#ifdef NON_TINYMAIL_FEATURES
 	for (i=0;i<count;i++) {
-		char *name, *value;
-		if (camel_file_util_decode_string(in, &name) == -1 || name == NULL
-		    || camel_file_util_decode_string(in, &value) == -1)
-			goto error;
-		camel_tag_set(&mi->user_tags, name, value);
-		g_free(name);
-		g_free(value);
+		mi->references->references[i].id.part.hi = g_ntohl(get_unaligned_u32(s->filepos)); 
+		s->filepos += 4;
+		mi->references->references[i].id.part.lo = g_ntohl(get_unaligned_u32(s->filepos));
+		s->filepos += 4;
 	}
+#else
+	s->filepos += (count * 8);
+#endif
 
-	if (!ferror(in))
-		return (CamelMessageInfo *)mi;
-
-error:
-	camel_message_info_free((CamelMessageInfo *)mi);
+	ptrchr = s->filepos;
+	ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &count, FALSE);
 
-	return NULL;
-}
+	for (i=0;i<count;i++) 
+	{
+		char *name = NULL;
+		ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &len, TRUE);
+		if (len) 
+			name = (char*) ptrchr;
+		ptrchr += len;
+	}
+
+	ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &count, FALSE);
+	if (!ptrchr) return NULL;
+
+	for (i=0;i<count;i++) 
+	{
+		char *name = NULL, *value = NULL;
+		ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &len, TRUE);
+		if (len) 
+			name = (char*)ptrchr;
+		ptrchr += len;
+		ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &len, TRUE);
+		if (len) 
+			value =(char*) ptrchr;
+		ptrchr += len;
+	}
 
-static int
-meta_message_info_save(CamelFolderSummary *s, FILE *out_meta, FILE *out, CamelMessageInfo *info)
-{
-	time_t timestamp;
-	off_t offset;
-	CamelMessageInfoBase *mi = (CamelMessageInfoBase *)info;
+	s->filepos = ptrchr;
 
-	time (&timestamp);
-	offset = ftell (out);
-	/* FIXME: errno check after ftell */
-	
-	camel_file_util_encode_time_t(out_meta, timestamp);
-	camel_file_util_encode_fixed_string(out_meta, camel_message_info_uid(mi), s->meta_summary->uid_len);
-	camel_file_util_encode_uint32(out_meta, mi->flags);
-	camel_file_util_encode_off_t(out_meta, offset);	
+	return (CamelMessageInfo *)mi;
 
-	return ferror(out);
 }
 
 static int
 message_info_save(CamelFolderSummary *s, FILE *out, CamelMessageInfo *info)
 {
 	guint32 count;
+#ifdef NON_TINYMAIL_FEATURES
 	CamelFlag *flag;
 	CamelTag *tag;
 	int i;
+#endif
 	CamelMessageInfoBase *mi = (CamelMessageInfoBase *)info;
 
+	/* if (mi->flags & CAMEL_MESSAGE_INFO_NEEDS_FREE)
+	       return -1; */
+
 	io(printf("Saving message info\n"));
 
 	camel_file_util_encode_string(out, camel_message_info_uid(mi));
-	camel_file_util_encode_uint32(out, mi->flags);
+
 	camel_file_util_encode_uint32(out, mi->size);
+	camel_file_util_encode_uint32(out, mi->flags);
+
 	camel_file_util_encode_time_t(out, mi->date_sent);
 	camel_file_util_encode_time_t(out, mi->date_received);
 	camel_file_util_encode_string(out, camel_message_info_subject(mi));
 	camel_file_util_encode_string(out, camel_message_info_from(mi));
 	camel_file_util_encode_string(out, camel_message_info_to(mi));
 	camel_file_util_encode_string(out, camel_message_info_cc(mi));
+
+#ifdef NON_TINYMAIL_FEATURES
 	camel_file_util_encode_string(out, camel_message_info_mlist(mi));
+#else
+	camel_file_util_encode_string(out, "");
+#endif
 
 	camel_file_util_encode_fixed_int32(out, mi->message_id.id.part.hi);
 	camel_file_util_encode_fixed_int32(out, mi->message_id.id.part.lo);
 
+#ifdef NON_TINYMAIL_FEATURES
 	if (mi->references) {
 		camel_file_util_encode_uint32(out, mi->references->size);
 		for (i=0;i<mi->references->size;i++) {
@@ -1930,47 +2274,115 @@
 			camel_file_util_encode_fixed_int32(out, mi->references->references[i].id.part.lo);
 		}
 	} else {
+#endif
 		camel_file_util_encode_uint32(out, 0);
-	}
 
+#ifdef NON_TINYMAIL_FEATURES
+	}
 	count = camel_flag_list_size(&mi->user_flags);
+#else
+	count = 0;
+#endif
+
 	camel_file_util_encode_uint32(out, count);
+
+#ifdef NON_TINYMAIL_FEATURES
 	flag = mi->user_flags;
 	while (flag) {
 		camel_file_util_encode_string(out, flag->name);
 		flag = flag->next;
 	}
+#endif
 
+#ifdef NON_TINYMAIL_FEATURES
 	count = camel_tag_list_size(&mi->user_tags);
+#else
+	count = 0;
+#endif
+
 	camel_file_util_encode_uint32(out, count);
+
+#ifdef NON_TINYMAIL_FEATURES
 	tag = mi->user_tags;
 	while (tag) {
 		camel_file_util_encode_string(out, tag->name);
 		camel_file_util_encode_string(out, tag->value);
 		tag = tag->next;
 	}
+#endif
 
 	return ferror(out);
 }
 
+#ifdef MEMDEBUG
+static int freed=0;
+#endif
+
+static void
+destroy_possible_pstring_stuff(CamelFolderSummary *s, CamelMessageInfo *info, gboolean freeuid)
+{
+	CamelMessageInfoBase *mi = (CamelMessageInfoBase *)info;
+
+#ifdef MEMDEBUG
+	printf ("Freeup %d, %s\n", freed++, (mi->flags & CAMEL_MESSAGE_INFO_NEEDS_FREE)?"YES":"NO");
+#endif
+
+	if (mi->flags & CAMEL_MESSAGE_INFO_NEEDS_FREE)
+	{
+		if (freeuid && (mi->flags & CAMEL_MESSAGE_INFO_UID_NEEDS_FREE))
+		{
+			g_free(mi->uid);
+			mi->flags &= ~CAMEL_MESSAGE_INFO_UID_NEEDS_FREE;
+		}
+
+		if (mi->subject)
+			camel_pstring_free(mi->subject);
+		if (mi->from)
+			camel_pstring_free(mi->from);
+		if (mi->to)
+			camel_pstring_free(mi->to);
+		if (mi->cc)
+			camel_pstring_free(mi->cc);
+
+#ifdef NON_TINYMAIL_FEATURES
+		if (mi->mlist)
+			camel_pstring_free(mi->mlist);
+		camel_flag_list_free(&mi->user_flags);
+		camel_tag_list_free(&mi->user_tags);
+#endif
+
+		mi->flags &= ~CAMEL_MESSAGE_INFO_NEEDS_FREE;
+
+	} else if (freeuid && (mi->flags & CAMEL_MESSAGE_INFO_UID_NEEDS_FREE))
+	{
+		g_free (mi->uid);
+		mi->flags &= ~CAMEL_MESSAGE_INFO_UID_NEEDS_FREE;
+	}
+#ifdef NON_TINYMAIL_FEATURES
+	g_free(mi->references);
+#endif
+
+	return;
+}
+
 static void
 message_info_free(CamelFolderSummary *s, CamelMessageInfo *info)
 {
 	CamelMessageInfoBase *mi = (CamelMessageInfoBase *)info;
 
-	g_free(mi->uid);
-	camel_pstring_free(mi->subject);
-	camel_pstring_free(mi->from);
-	camel_pstring_free(mi->to);
-	camel_pstring_free(mi->cc);
-	camel_pstring_free(mi->mlist);
-	g_free(mi->references);
-	camel_flag_list_free(&mi->user_flags);
-	camel_tag_list_free(&mi->user_tags);
+	destroy_possible_pstring_stuff (s, info, TRUE);
+
+	/* memset: Trash it, makes debugging more easy */
+
 	if (s)
-		e_memchunk_free(s->message_info_chunks, mi);
-	else
-		g_free(mi);
+	{
+		memset (info, 0, s->message_info_size);
+		g_slice_free1 (s->message_info_size, mi);
+	} else
+	{
+		memset (info, 0, sizeof (CamelMessageInfoBase));
+		g_slice_free (CamelMessageInfoBase, (CamelMessageInfoBase*) mi);
+	}
 }
 
 static CamelMessageContentInfo *
@@ -1980,75 +2392,75 @@
 	const char *charset;
 	
 	ci = camel_folder_summary_content_info_new (s);
+	ci->needs_free = TRUE;
 	
 	charset = e_iconv_locale_charset ();
-	ci->id = camel_header_msgid_decode (camel_header_raw_find (&h, "content-id", NULL));
-	ci->description = camel_header_decode_string (camel_header_raw_find (&h, "content-description", NULL), charset);
-	ci->encoding = camel_content_transfer_encoding_decode (camel_header_raw_find (&h, "content-transfer-encoding", NULL));
+
+	ci->id = token_add (camel_header_msgid_decode (camel_header_raw_find (&h, "content-id", NULL)));
+	ci->description = token_add (camel_header_decode_string (camel_header_raw_find (&h, "content-description", NULL), charset));
+	ci->encoding = token_add (camel_content_transfer_encoding_decode (camel_header_raw_find (&h, "content-transfer-encoding", NULL)));
 	ci->type = camel_content_type_decode(camel_header_raw_find(&h, "content-type", NULL));
 
 	return ci;
 }
 
 static CamelMessageContentInfo *
-content_info_load(CamelFolderSummary *s, FILE *in)
+content_info_load(CamelFolderSummary *s)
 {
 	CamelMessageContentInfo *ci;
 	char *type, *subtype;
 	guint32 count, i;
 	CamelContentType *ct;
+	unsigned char *ptrchr = s->filepos;
 
 	io(printf("Loading content info\n"));
 
 	ci = camel_folder_summary_content_info_new(s);
-	
-	camel_folder_summary_decode_token(in, &type);
-	camel_folder_summary_decode_token(in, &subtype);
+	ci->needs_free = FALSE;
+
+	camel_folder_summary_decode_token(s, &type);
+	camel_folder_summary_decode_token(s, &subtype);
+
 	ct = camel_content_type_new(type, subtype);
-	g_free(type);		/* can this be removed? */
-	g_free(subtype);
-	if (camel_file_util_decode_uint32(in, &count) == -1 || count > 500)
-		goto error;
-	
-	for (i=0;i<count;i++) {
+
+	ptrchr = s->filepos;
+	ptrchr = camel_file_util_mmap_decode_uint32 ((unsigned char*)ptrchr, &count, FALSE);
+	s->filepos = ptrchr;
+
+	for (i=0; i < count; i++) 
+	{
 		char *name, *value;
-		camel_folder_summary_decode_token(in, &name);
-		camel_folder_summary_decode_token(in, &value);
-		if (!(name && value))
-			goto error;
+		camel_folder_summary_decode_token(s, &name);
+		camel_folder_summary_decode_token(s, &value);
 		
-		camel_content_type_set_param(ct, name, value);
-		/* TODO: do this so we dont have to double alloc/free */
-		g_free(name);
-		g_free(value);
+		camel_content_type_set_param (ct, name, value);
 	}
-	ci->type = ct;
 
-	camel_folder_summary_decode_token(in, &ci->id);
-	camel_folder_summary_decode_token(in, &ci->description);
-	camel_folder_summary_decode_token(in, &ci->encoding);
+	ci->type = ct;
 
-	camel_file_util_decode_uint32(in, &ci->size);
+	camel_folder_summary_decode_token(s, &ci->id);
+	camel_folder_summary_decode_token(s, &ci->description);
+	camel_folder_summary_decode_token(s, &ci->encoding);
+
+	ptrchr = s->filepos;
+	ptrchr = camel_file_util_mmap_decode_uint32 ((unsigned char*)ptrchr, &ci->size, FALSE);
+	s->filepos = ptrchr;
 
 	ci->childs = NULL;
 
-	if (!ferror(in))
-		return ci;
-
- error:
-	camel_folder_summary_content_info_free(s, ci);
-	return NULL;
+	return ci;
 }
 
 static int
 content_info_save(CamelFolderSummary *s, FILE *out, CamelMessageContentInfo *ci)
 {
-	CamelContentType *ct;
+	CamelContentType *ct=NULL;
 	struct _camel_header_param *hp;
 
 	io(printf("Saving content info\n"));
 
 	ct = ci->type;
+
 	if (ct) {
 		camel_folder_summary_encode_token(out, ct->type);
 		camel_folder_summary_encode_token(out, ct->subtype);
@@ -2070,14 +2482,23 @@
 	return camel_file_util_encode_uint32(out, ci->size);
 }
 
+
 static void
 content_info_free(CamelFolderSummary *s, CamelMessageContentInfo *ci)
 {
 	camel_content_type_unref(ci->type);
-	g_free(ci->id);
-	g_free(ci->description);
-	g_free(ci->encoding);
-	e_memchunk_free(s->content_info_chunks, ci);
+
+	if (ci->needs_free) 
+	{
+		token_free (ci->id);
+		token_free (ci->description);
+		token_free (ci->encoding);
+	}
+
+	if (s != NULL)
+		g_slice_free1(s->content_info_size, ci);
+	else
+		g_slice_free (CamelMessageContentInfo, ci);
 }
 
 static char *
@@ -2102,8 +2523,6 @@
 	CamelMessageContentInfo *info = NULL;
 	CamelContentType *ct;
 	int enc_id = -1, chr_id = -1, html_id = -1, idx_id = -1;
-	struct _CamelFolderSummaryPrivate *p = _PRIVATE(s);
-	CamelMimeFilterCharset *mfc;
 	CamelMessageContentInfo *part;
 
 	d(printf("building content info\n"));
@@ -2119,6 +2538,8 @@
 		/* check content type for indexing, then read body */
 		ct = camel_mime_parser_content_type(mp);
 		/* update attachments flag as we go */
+
+
 		if (camel_content_type_is(ct, "application", "pgp-signature")
 #ifdef ENABLE_SMIME
 		    || camel_content_type_is(ct, "application", "x-pkcs7-signature")
@@ -2127,74 +2548,7 @@
 			)
 			camel_message_info_set_flags(msginfo, CAMEL_MESSAGE_SECURE, CAMEL_MESSAGE_SECURE);
 
-		if (p->index && camel_content_type_is(ct, "text", "*")) {
-			char *encoding;
-			const char *charset;
-
-			d(printf("generating index:\n"));
-			
-			encoding = camel_content_transfer_encoding_decode(camel_mime_parser_header(mp, "content-transfer-encoding", NULL));
-			if (encoding) {
-				if (!g_ascii_strcasecmp(encoding, "base64")) {
-					d(printf(" decoding base64\n"));
-					if (p->filter_64 == NULL)
-						p->filter_64 = camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_BASE64_DEC);
-					else
-						camel_mime_filter_reset((CamelMimeFilter *)p->filter_64);
-					enc_id = camel_mime_parser_filter_add(mp, (CamelMimeFilter *)p->filter_64);
-				} else if (!g_ascii_strcasecmp(encoding, "quoted-printable")) {
-					d(printf(" decoding quoted-printable\n"));
-					if (p->filter_qp == NULL)
-						p->filter_qp = camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_QP_DEC);
-					else
-						camel_mime_filter_reset((CamelMimeFilter *)p->filter_qp);
-					enc_id = camel_mime_parser_filter_add(mp, (CamelMimeFilter *)p->filter_qp);
-				} else if (!g_ascii_strcasecmp (encoding, "x-uuencode")) {
-					d(printf(" decoding x-uuencode\n"));
-					if (p->filter_uu == NULL)
-						p->filter_uu = camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_UU_DEC);
-					else
-						camel_mime_filter_reset((CamelMimeFilter *)p->filter_uu);
-					enc_id = camel_mime_parser_filter_add(mp, (CamelMimeFilter *)p->filter_uu);
-				} else {
-					d(printf(" ignoring encoding %s\n", encoding));
-				}
-				g_free(encoding);
-			}
-
-			charset = camel_content_type_param(ct, "charset");
-			if (charset!=NULL
-			    && !(g_ascii_strcasecmp(charset, "us-ascii")==0
-				 || g_ascii_strcasecmp(charset, "utf-8")==0)) {
-				d(printf(" Adding conversion filter from %s to UTF-8\n", charset));
-				mfc = g_hash_table_lookup(p->filter_charset, charset);
-				if (mfc == NULL) {
-					mfc = camel_mime_filter_charset_new_convert(charset, "UTF-8");
-					if (mfc)
-						g_hash_table_insert(p->filter_charset, g_strdup(charset), mfc);
-				} else {
-					camel_mime_filter_reset((CamelMimeFilter *)mfc);
-				}
-				if (mfc) {
-					chr_id = camel_mime_parser_filter_add(mp, (CamelMimeFilter *)mfc);
-				} else {
-					w(g_warning("Cannot convert '%s' to 'UTF-8', message index may be corrupt", charset));
-				}
-			}
 
-			/* we do charset conversions before this filter, which isn't strictly correct,
-			   but works in most cases */
-			if (camel_content_type_is(ct, "text", "html")) {
-				if (p->filter_html == NULL)
-					p->filter_html = camel_mime_filter_html_new();
-				else
-					camel_mime_filter_reset((CamelMimeFilter *)p->filter_html);
-				html_id = camel_mime_parser_filter_add(mp, (CamelMimeFilter *)p->filter_html);
-			}
-			
-			/* and this filter actually does the indexing */
-			idx_id = camel_mime_parser_filter_add(mp, (CamelMimeFilter *)p->filter_index);
-		}
 		/* and scan/index everything */
 		while (camel_mime_parser_step(mp, &buffer, &len) != CAMEL_MIME_PARSER_STATE_BODY_END)
 			;
@@ -2253,13 +2607,18 @@
 {
 	CamelDataWrapper *containee;
 	int parts, i;
-	struct _CamelFolderSummaryPrivate *p = _PRIVATE(s);
+	struct _CamelFolderSummaryPrivate *p;
 	CamelMessageContentInfo *info = NULL, *child;
 	CamelContentType *ct;
 
-	if (s->build_content)
+	if (s != NULL && s->build_content)
 		info = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->content_info_new_from_message(s, object);
-	
+	else
+		info = content_info_new_from_message(NULL, object);
+
+	if (s != NULL)
+		p = _PRIVATE(s);
+
 	containee = camel_medium_get_content_object(CAMEL_MEDIUM(object));
 
 	if (containee == NULL)
@@ -2304,7 +2663,7 @@
 			child->parent = info;
 			my_list_append((struct _node **)&info->childs, (struct _node *)child);
 		}
-	} else if (p->filter_stream
+	} else if (s != NULL && p->filter_stream
 		   && camel_content_type_is(ct, "text", "*")) {
 		int html_id = -1, idx_id = -1;
 
@@ -2649,7 +3008,6 @@
 	{ "flagged", CAMEL_MESSAGE_FLAGGED },
 	{ "seen", CAMEL_MESSAGE_SEEN },
 	{ "attachments", CAMEL_MESSAGE_ATTACHMENTS },
-	{ "junk", CAMEL_MESSAGE_JUNK },
 	{ "secure", CAMEL_MESSAGE_SECURE },
 	{ NULL, 0 }
 };
@@ -2707,15 +3065,12 @@
 {
 	CamelMessageInfo *info;
 
-	if (s) {
-		CAMEL_SUMMARY_LOCK(s, alloc_lock);
-		if (s->message_info_chunks == NULL)
-			s->message_info_chunks = e_memchunk_new(32, s->message_info_size);
-		info = e_memchunk_alloc0(s->message_info_chunks);
-		CAMEL_SUMMARY_UNLOCK(s, alloc_lock);
-	} else {
-		info = g_malloc0(sizeof(CamelMessageInfoBase));
-	}
+	if (s)
+		info = g_slice_alloc0(s->message_info_size);
+	else
+		info = (CamelMessageInfo *) g_slice_new0(CamelMessageInfoBase);
+
+	((CamelMessageInfoBase *)info)->flags = 0;
 
 	info->refcount = 1;
 	info->summary = s;
@@ -2748,6 +3103,16 @@
 	}
 }
 
+void *
+camel_message_info_new_uid (CamelFolderSummary *summary, const char *uid)
+{
+	CamelMessageInfoBase *mi = (CamelMessageInfoBase *)camel_message_info_new(summary);
+	mi->uid = g_strdup (uid);
+	mi->flags |= CAMEL_MESSAGE_INFO_NEEDS_FREE;
+	mi->flags |= CAMEL_MESSAGE_INFO_UID_NEEDS_FREE;
+	return mi;
+}
+
 
 /**
  * camel_message_info_new_from_header:
@@ -2780,6 +3145,8 @@
 {
 	CamelMessageInfo *mi = o;
 
+	/* camel_message_info_set_flags(mi, CAMEL_MESSAGE_FREED, CAMEL_MESSAGE_FREED); */
+
 	g_return_if_fail(mi != NULL);
 
 	if (mi->summary) {
@@ -2795,8 +3162,8 @@
 		CAMEL_SUMMARY_UNLOCK(mi->summary, ref_lock);
 
 		/* FIXME: this is kinda busted, should really be handled by message info free */
-		if (mi->summary->build_content
-		    && ((CamelMessageInfoBase *)mi)->content) {
+		if (/* mi->summary->build_content
+		    && */((CamelMessageInfoBase *)mi)->content) {
 			camel_folder_summary_content_info_free(mi->summary, ((CamelMessageInfoBase *)mi)->content);
 		}
 
@@ -2810,7 +3177,11 @@
 		}
 		GLOBAL_INFO_UNLOCK(info);
 
+		if (((CamelMessageInfoBase *)mi)->content)
+			camel_folder_summary_content_info_free(NULL, ((CamelMessageInfoBase *)mi)->content);
+
 		message_info_free(NULL, mi);
+
 	}
 }
 
@@ -2818,23 +3189,30 @@
 message_info_clone(CamelFolderSummary *s, const CamelMessageInfo *mi)
 {
 	CamelMessageInfoBase *to, *from = (CamelMessageInfoBase *)mi;
+#ifdef NON_TINYMAIL_FEATURES
 	CamelFlag *flag;
 	CamelTag *tag;
-
+#endif
 	to = (CamelMessageInfoBase *)camel_message_info_new(s);
 
 	to->flags = from->flags;
 	to->size = from->size;
+
 	to->date_sent = from->date_sent;
 	to->date_received = from->date_received;
 	to->refcount = 1;
 
 	/* NB: We don't clone the uid */
 
+	to->flags |= CAMEL_MESSAGE_INFO_NEEDS_FREE;
+	to->flags &= ~CAMEL_MESSAGE_INFO_UID_NEEDS_FREE;
+
 	to->subject = camel_pstring_strdup(from->subject);
 	to->from = camel_pstring_strdup(from->from);
 	to->to = camel_pstring_strdup(from->to);
 	to->cc = camel_pstring_strdup(from->cc);
+
+#ifdef NON_TINYMAIL_FEATURES
 	to->mlist = camel_pstring_strdup(from->mlist);
 	memcpy(&to->message_id, &from->message_id, sizeof(to->message_id));
 
@@ -2844,7 +3222,9 @@
 		to->references = g_malloc(len);
 		memcpy(to->references, from->references, len);
 	}
+#endif
 
+#ifdef NON_TINYMAIL_FEATURES
 	flag = from->user_flags;
 	while (flag) {
 		camel_flag_set(&to->user_flags, flag->name, TRUE);
@@ -2856,10 +3236,7 @@
 		camel_tag_set(&to->user_tags, tag->name, tag->value);
 		tag = tag->next;
 	}
-
-	if (from->content) {
-		/* FIXME: copy content-infos */
-	}
+#endif
 
 	return (CamelMessageInfo *)to;
 }
@@ -2878,75 +3255,113 @@
 {
 	const CamelMessageInfo *mi = o;
 
+	if (mi == NULL || mi->refcount <=0)
+		return NULL;
+
 	if (mi->summary)
 		return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->message_info_clone(mi->summary, mi);
 	else
 		return message_info_clone(NULL, mi);
 }
 
+
 static const void *
 info_ptr(const CamelMessageInfo *mi, int id)
 {
-	switch (id) {
-	case CAMEL_MESSAGE_INFO_SUBJECT:
-		return ((const CamelMessageInfoBase *)mi)->subject;
-	case CAMEL_MESSAGE_INFO_FROM:
-		return ((const CamelMessageInfoBase *)mi)->from;
-	case CAMEL_MESSAGE_INFO_TO:
-		return ((const CamelMessageInfoBase *)mi)->to;
-	case CAMEL_MESSAGE_INFO_CC:
-		return ((const CamelMessageInfoBase *)mi)->cc;
-	case CAMEL_MESSAGE_INFO_MLIST:
-		return ((const CamelMessageInfoBase *)mi)->mlist;
-	case CAMEL_MESSAGE_INFO_MESSAGE_ID:
-		return &((const CamelMessageInfoBase *)mi)->message_id;
-	case CAMEL_MESSAGE_INFO_REFERENCES:
-		return ((const CamelMessageInfoBase *)mi)->references;
-	case CAMEL_MESSAGE_INFO_USER_FLAGS:
-		return ((const CamelMessageInfoBase *)mi)->user_flags;
-	case CAMEL_MESSAGE_INFO_USER_TAGS:
-		return ((const CamelMessageInfoBase *)mi)->user_tags;
-	default:
-		abort();
+	const void *retval;
+
+	g_static_rec_mutex_lock (&global_lock);
+	g_static_mutex_lock (&global_lock2);
+
+	if (G_UNLIKELY (mi == NULL || mi->refcount <=0))
+		retval = "Invalid refcount";
+	if (G_UNLIKELY(((CamelMessageInfoBase*)mi)->flags & CAMEL_MESSAGE_FREED))
+		retval = "Invalid";
+	else switch (id) 
+	{
+		case CAMEL_MESSAGE_INFO_SUBJECT:
+			retval = ((const CamelMessageInfoBase *)mi)->subject;
+		break;
+		case CAMEL_MESSAGE_INFO_FROM:
+			retval = ((const CamelMessageInfoBase *)mi)->from;
+		break;
+		case CAMEL_MESSAGE_INFO_TO:
+			retval = ((const CamelMessageInfoBase *)mi)->to;
+		break;
+		case CAMEL_MESSAGE_INFO_CC:
+			retval = ((const CamelMessageInfoBase *)mi)->cc;
+		break;
+		case CAMEL_MESSAGE_INFO_MESSAGE_ID:
+			retval = &((const CamelMessageInfoBase *)mi)->message_id;
+		break;
 	}
+
+	g_static_mutex_unlock (&global_lock2);
+	g_static_rec_mutex_unlock (&global_lock);
+
+	return retval;
 }
 
 static guint32
 info_uint32(const CamelMessageInfo *mi, int id)
 {
-	switch (id) {
-	case CAMEL_MESSAGE_INFO_FLAGS:
-		return ((const CamelMessageInfoBase *)mi)->flags;
-	case CAMEL_MESSAGE_INFO_SIZE:
-		return ((const CamelMessageInfoBase *)mi)->size;
-	default:
-		abort();
+	guint32 retval;
+
+	g_static_rec_mutex_lock (&global_lock);
+
+	if (mi == NULL || mi->refcount <=0)
+		retval = 0;
+	else switch (id) 
+	{
+		case CAMEL_MESSAGE_INFO_FLAGS:
+			retval = ((const CamelMessageInfoBase *)mi)->flags;
+		break;
+		case CAMEL_MESSAGE_INFO_SIZE:
+			retval = ((const CamelMessageInfoBase *)mi)->size;
+		break;
 	}
+
+	g_static_rec_mutex_unlock (&global_lock);
+
+	return retval;
 }
 
 static time_t
 info_time(const CamelMessageInfo *mi, int id)
 {
-	switch (id) {
-	case CAMEL_MESSAGE_INFO_DATE_SENT:
-		return ((const CamelMessageInfoBase *)mi)->date_sent;
-	case CAMEL_MESSAGE_INFO_DATE_RECEIVED:
-		return ((const CamelMessageInfoBase *)mi)->date_received;
-	default:
-		abort();
+	time_t retval;
+
+	g_static_rec_mutex_lock (&global_lock);
+
+	if (mi == NULL || mi->refcount <=0)
+		retval = 0;
+	else switch (id) 
+	{
+		case CAMEL_MESSAGE_INFO_DATE_SENT:
+			retval = ((const CamelMessageInfoBase *)mi)->date_sent;
+		break;
+		case CAMEL_MESSAGE_INFO_DATE_RECEIVED:
+			retval = ((const CamelMessageInfoBase *)mi)->date_received;
+		break;
+		default:
+			abort();
 	}
+
+	g_static_rec_mutex_unlock (&global_lock);
+
+	return retval;
 }
 
 static gboolean
 info_user_flag(const CamelMessageInfo *mi, const char *id)
 {
-	return camel_flag_get(&((CamelMessageInfoBase *)mi)->user_flags, id);
+	return FALSE;
 }
 
 static const char *
 info_user_tag(const CamelMessageInfo *mi, const char *id)
 {
-	return camel_tag_get(&((CamelMessageInfoBase *)mi)->user_tags, id);
+	return NULL;
 }
 
 
@@ -2962,10 +3377,26 @@
 const void *
 camel_message_info_ptr(const CamelMessageInfo *mi, int id)
 {
-	if (mi->summary)
-		return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_ptr(mi, id);
+	const void * retval;
+
+	g_static_rec_mutex_lock (&global_lock);
+
+	if (mi==NULL || mi->refcount <= 0)
+		retval = NULL;
 	else
-		return info_ptr(mi, id);
+	{
+		if (mi->summary)
+			if (((CamelObject*)mi->summary)->ref_count > 0 && CAMEL_IS_FOLDER_SUMMARY (mi->summary))
+				retval = ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_ptr(mi, id);
+			else 
+				retval = NULL;
+		else
+			retval = info_ptr(mi, id);
+	}
+
+	g_static_rec_mutex_unlock (&global_lock);
+
+	return retval;
 }
 
 
@@ -2981,10 +3412,26 @@
 guint32
 camel_message_info_uint32(const CamelMessageInfo *mi, int id)
 {
-	if (mi->summary)
-		return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_uint32(mi, id);
+	guint32 retval;
+
+	g_static_rec_mutex_lock (&global_lock);
+
+	if (mi == NULL || mi->refcount <=0)
+		retval = 0;
 	else
-		return info_uint32(mi, id);
+	{
+		if (mi->summary)
+			if (CAMEL_IS_FOLDER_SUMMARY (mi->summary))
+				retval = ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_uint32(mi, id);
+			else
+				retval = 0;
+		else
+			retval = info_uint32(mi, id);
+	}
+
+	g_static_rec_mutex_unlock (&global_lock);
+
+	return retval;
 }
 
 
@@ -2998,12 +3445,28 @@
  * Returns the time_t data
  **/
 time_t
-camel_message_info_time(const CamelMessageInfo *mi, int id)
+camel_message_info_time (const CamelMessageInfo *mi, int id)
 {
-	if (mi->summary)
-		return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_time(mi, id);
-	else
-		return info_time(mi, id);
+	time_t retval;
+
+	g_static_rec_mutex_lock (&global_lock);
+
+	if (mi == NULL || mi->refcount <=0)
+		retval = 0;
+	else 
+	{
+		if (mi->summary)
+			if (CAMEL_IS_FOLDER_SUMMARY (mi->summary))
+				retval = ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_time(mi, id);
+			else 
+				retval = -1;
+		else
+			retval = info_time(mi, id);
+	}
+
+	g_static_rec_mutex_unlock (&global_lock);
+
+	return retval;
 }
 
 
@@ -3019,10 +3482,21 @@
 gboolean
 camel_message_info_user_flag(const CamelMessageInfo *mi, const char *id)
 {
+	gboolean retval;
+
+	g_static_rec_mutex_lock (&global_lock);
+
 	if (mi->summary)
-		return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_user_flag(mi, id);
+		if (CAMEL_IS_FOLDER_SUMMARY (mi->summary))
+			retval = ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_user_flag(mi, id);
+		else
+			retval = FALSE;
 	else
-		return info_user_flag(mi, id);
+		retval = info_user_flag(mi, id);
+
+	g_static_rec_mutex_unlock (&global_lock);
+
+	return retval;
 }
 
 
@@ -3038,16 +3512,27 @@
 const char *
 camel_message_info_user_tag(const CamelMessageInfo *mi, const char *id)
 {
+	const char * retval;
+
+	g_static_rec_mutex_lock (&global_lock);
+
 	if (mi->summary)
-		return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_user_tag(mi, id);
+		if (CAMEL_IS_FOLDER_SUMMARY (mi->summary))
+			retval = ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_user_tag(mi, id);
+		else
+			retval = NULL;
 	else
-		return info_user_tag(mi, id);
+		retval = info_user_tag(mi, id);
+
+	g_static_rec_mutex_unlock (&global_lock);
+
+	return retval;
 }
 
 static gboolean
 info_set_flags(CamelMessageInfo *info, guint32 flags, guint32 set)
 {
-	guint32 old;
+	guint16 old;
 	CamelMessageInfoBase *mi = (CamelMessageInfoBase *)info;
 
 	/* TODO: locking? */
@@ -3060,7 +3545,7 @@
 			camel_folder_summary_touch(mi->summary);
 	}
 
-	if (((old & ~CAMEL_MESSAGE_SYSTEM_MASK) == (mi->flags & ~CAMEL_MESSAGE_SYSTEM_MASK)) && !((set & CAMEL_MESSAGE_JUNK_LEARN) && !(set & CAMEL_MESSAGE_JUNK)))
+	if ((old & ~CAMEL_MESSAGE_SYSTEM_MASK) == (mi->flags & ~CAMEL_MESSAGE_SYSTEM_MASK))
 		return FALSE;
 
 	if (mi->summary && mi->summary->folder && mi->uid) {
@@ -3088,10 +3573,21 @@
 gboolean
 camel_message_info_set_flags(CamelMessageInfo *mi, guint32 flags, guint32 set)
 {
+	gboolean retval;
+
+	g_static_rec_mutex_lock (&global_lock);
+
 	if (mi->summary)
-		return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_set_flags(mi, flags, set);
+		if (CAMEL_IS_FOLDER_SUMMARY (mi->summary))
+			retval = ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_set_flags(mi, flags, set);
+		else
+			retval = FALSE;
 	else
-		return info_set_flags(mi, flags, set);
+		retval = info_set_flags(mi, flags, set);
+
+	g_static_rec_mutex_unlock (&global_lock);
+
+	return retval;
 }
 
 static gboolean
@@ -3100,7 +3596,11 @@
 	CamelMessageInfoBase *mi = (CamelMessageInfoBase *)info;
 	int res;
 
+	g_static_rec_mutex_lock (&global_lock);
+
+#ifdef NON_TINYMAIL_FEATURES
 	res = camel_flag_set(&mi->user_flags, name, value);
+#endif
 
 	/* TODO: check this item is still in the summary first */
 	if (mi->summary && res && mi->summary->folder && mi->uid) {
@@ -3113,6 +3613,8 @@
 		camel_folder_change_info_free(changes);
 	}
 
+	g_static_rec_mutex_unlock (&global_lock);
+
 	return res;
 }
 
@@ -3130,10 +3632,18 @@
 gboolean
 camel_message_info_set_user_flag(CamelMessageInfo *mi, const char *id, gboolean state)
 {
+	gboolean retval;
+
+	g_static_rec_mutex_lock (&global_lock);
+
 	if (mi->summary)
-		return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_set_user_flag(mi, id, state);
+		retval = ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_set_user_flag(mi, id, state);
 	else
-		return info_set_user_flag(mi, id, state);
+		retval = info_set_user_flag(mi, id, state);
+
+	g_static_rec_mutex_unlock (&global_lock);
+
+	return retval;
 }
 
 static gboolean
@@ -3142,7 +3652,11 @@
 	CamelMessageInfoBase *mi = (CamelMessageInfoBase *)info;
 	int res;
 
+	g_static_rec_mutex_lock (&global_lock);
+
+#ifdef NON_TINYMAIL_FEATURES
 	res = camel_tag_set(&mi->user_tags, name, value);
+#endif
 
 	if (mi->summary && res && mi->summary->folder && mi->uid) {
 		CamelFolderChangeInfo *changes = camel_folder_change_info_new();
@@ -3154,6 +3668,8 @@
 		camel_folder_change_info_free(changes);
 	}
 
+	g_static_rec_mutex_unlock (&global_lock);
+
 	return res;
 }
 
@@ -3171,10 +3687,18 @@
 gboolean
 camel_message_info_set_user_tag(CamelMessageInfo *mi, const char *id, const char *val)
 {
+	gboolean retval;
+
+	g_static_rec_mutex_lock (&global_lock);
+
 	if (mi->summary)
-		return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_set_user_tag(mi, id, val);
+		retval = ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_set_user_tag(mi, id, val);
 	else
-		return info_set_user_tag(mi, id, val);
+		retval = info_set_user_tag(mi, id, val);
+
+	g_static_rec_mutex_unlock (&global_lock);
+
+	return retval;
 }
 
 void
@@ -3217,7 +3741,9 @@
 	printf("Subject: %s\n", camel_message_info_subject(mi));
 	printf("To: %s\n", camel_message_info_to(mi));
 	printf("Cc: %s\n", camel_message_info_cc(mi));
+#ifdef NON_TINYMAIL_FEATURES
 	printf("mailing list: %s\n", camel_message_info_mlist(mi));
+#endif
 	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));
@@ -3238,7 +3764,6 @@
 	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;
 
Only in .: camel-folder-summary.c.rej
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-folder-summary.h ./camel-folder-summary.h
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-folder-summary.h	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-folder-summary.h	2007-05-12 10:31:09.000000000 +0200
@@ -22,11 +22,12 @@
 #ifndef _CAMEL_FOLDER_SUMMARY_H
 #define _CAMEL_FOLDER_SUMMARY_H
 
+
 #include <stdio.h>
 #include <time.h>
 #include <camel/camel-mime-parser.h>
 #include <camel/camel-object.h>
-#include <camel/camel-index.h>
+
 
 #define CAMEL_FOLDER_SUMMARY_TYPE         camel_folder_summary_get_type ()
 #define CAMEL_FOLDER_SUMMARY(obj)         CAMEL_CHECK_CAST (obj, camel_folder_summary_get_type (), CamelFolderSummary)
@@ -58,34 +59,32 @@
 	char *description;
 	char *encoding;		/* this should be an enum?? */
 	guint32 size;
+	gboolean needs_free;
 };
 
 /* system flag bits */
 typedef enum _CamelMessageFlags {
-	CAMEL_MESSAGE_ANSWERED = 1<<0,
-	CAMEL_MESSAGE_DELETED = 1<<1,
-	CAMEL_MESSAGE_DRAFT = 1<<2,
-	CAMEL_MESSAGE_FLAGGED = 1<<3,
-	CAMEL_MESSAGE_SEEN = 1<<4,
-	
-	/* these aren't really system flag bits, but are convenience flags */
-	CAMEL_MESSAGE_ATTACHMENTS = 1<<5,
-	CAMEL_MESSAGE_ANSWERED_ALL = 1<<6,
-	CAMEL_MESSAGE_JUNK = 1<<7,
-	CAMEL_MESSAGE_SECURE = 1<<8,
-	CAMEL_MESSAGE_USER_NOT_DELETABLE = 1<<9,
-	CAMEL_MESSAGE_HIDDEN = 1<<10,
-	
-	/* following flags are for the folder, and are not really permanent flags */
-	CAMEL_MESSAGE_FOLDER_FLAGGED = 1<<16, /* for use by the folder implementation */
+	CAMEL_MESSAGE_ANSWERED = 1<<0, /* used               TNY_HEADER_FLAG_ANSWERED    */
+	CAMEL_MESSAGE_DELETED = 1<<1, /* used                TNY_HEADER_FLAG_DELETED     */
+	CAMEL_MESSAGE_DRAFT = 1<<2, /* used                  TNY_HEADER_FLAG_DRAFT       */
+	CAMEL_MESSAGE_FLAGGED = 1<<3, /* used                TNY_HEADER_FLAG_FLAGGED     */
+	CAMEL_MESSAGE_SEEN = 1<<4, /* used                   TNY_HEADER_FLAG_SEEN        */
+	CAMEL_MESSAGE_ATTACHMENTS = 1<<5, /* used            TNY_HEADER_FLAG_ATTACHMENTS */
+	CAMEL_MESSAGE_CACHED = 1<<6, /* used                 TNY_HEADER_FLAG_CACHED      */
+	CAMEL_MESSAGE_PARTIAL = 1<<7, /* used                TNY_HEADER_FLAG_PARTIAL     */
+	CAMEL_MESSAGE_EXPUNGED = 1<<8, /* used               TNY_HEADER_FLAG_EXPUNGED    */
+	CAMEL_MESSAGE_HIGH_PRIORITY = 1<<9|1<<10, /* used    TNY_HEADER_FLAG_HIGH_PRIORITY    */
+	CAMEL_MESSAGE_NORMAL_PRIORITY = 0<<9|0<<10, /* used  TNY_HEADER_FLAG_NORMAL_PRIORITY    */
+	CAMEL_MESSAGE_LOW_PRIORITY = 0<<9|1<<10, /* used     TNY_HEADER_FLAG_LOW_PRIORITY    */
+
+	/* internally used */
+	CAMEL_MESSAGE_FOLDER_FLAGGED = 1<<12, /* internally used */
+	CAMEL_MESSAGE_INFO_NEEDS_FREE = 1<<13,/* internally used */
+	CAMEL_MESSAGE_INFO_UID_NEEDS_FREE = 1<<14, /* internally used */
+	CAMEL_MESSAGE_FREED = 1<<15,  /* internally used */
+	CAMEL_MESSAGE_USER = 1<<16,  /* free slot */
+	CAMEL_MESSAGE_SECURE = 1<<17, /* free slot */
 
-	/* flags after 1<<16 are used by camel providers,
-           if adding non permanent flags, add them to the end  */
-
-	CAMEL_MESSAGE_JUNK_LEARN = 1<<30, /* used when setting CAMEL_MESSAGE_JUNK flag
-					     to say that we request junk plugin
-					     to learn that message as junk/non junk */
-	CAMEL_MESSAGE_USER = 1<<31 /* supports user flags */
 } CamelMessageFlags;
 
 /* Changes to system flags will NOT trigger a folder changed event */
@@ -114,11 +113,6 @@
 	} id;
 } CamelSummaryMessageID;
 
-/* summary references is a fixed size array of references */
-typedef struct _CamelSummaryReferences {
-	int size;
-	CamelSummaryMessageID references[1];
-} CamelSummaryReferences;
 
 /* accessor id's */
 enum {
@@ -145,7 +139,6 @@
 /* information about a given message, use accessors */
 struct _CamelMessageInfo {
 	CamelFolderSummary *summary;
-
 	guint32 refcount;	/* ??? */
 	char *uid;
 };
@@ -153,48 +146,37 @@
 /* For classes wishing to do the provided i/o, or for anonymous users,
  * they must subclass or use this messageinfo structure */
 /* Otherwise they can do their own thing entirely */
-struct _CamelMessageInfoBase {
-	CamelFolderSummary *summary;
 
-	guint32 refcount;	/* ??? */
-	char *uid;
-
-	const char *subject;
-	const char *from;
-	const char *to;
-	const char *cc;
-	const char *mlist;
+/*                                          on x86_32 */
+struct _CamelMessageInfoBase 
+{
+	CamelFolderSummary *summary;       /* 4 bytes */
+	guint32 refcount;                  /* 4 bytes */
+	char *uid;                         /* 4 bytes */
+	const char *subject;               /* 4 bytes */
+	const char *from;                  /* 4 bytes */
+	const char *to;                    /* 4 bytes */
+	const char *cc;                    /* 4 bytes */
 
-	guint32 flags;
-	guint32 size;
-
-	time_t date_sent;
-	time_t date_received;
+	/* tree of content description - NULL if it is not available */
+	CamelMessageContentInfo *content;  /* 4 bytes */
+	CamelSummaryMessageID message_id;  /* 8 bytes */
 
-	CamelSummaryMessageID message_id;
-	CamelSummaryReferences *references;/* from parent to root */
+	guint32 flags;                     /* 4 bytes */
+	guint32 size;                      /* 4 bytes */
 
-	struct _CamelFlag *user_flags;
-	struct _CamelTag *user_tags;
+	time_t date_sent;                  /* 4 bytes */
+	time_t date_received;              /* 4 bytes */
 
-	/* tree of content description - NULL if it is not available */
-	CamelMessageContentInfo *content;
+                                          /* 56 bytes */
 };
 
-/* probably do this as well, removing CamelFolderChangeInfo and interfaces 
-typedef struct _CamelChangeInfo CamelChangeInfo;
-struct _CamelChangeInfo {
-	GPtrArray *added;
-	GPtrArray *removed;
-	GPtrArray *changed;
-	GPtrArray *recent;
-};
-*/
 
 typedef enum _CamelFolderSummaryFlags {
 	CAMEL_SUMMARY_DIRTY = 1<<0,
 } CamelFolderSummaryFlags;
 
+
 struct _CamelFolderSummary {
 	CamelObject parent;
 
@@ -214,32 +196,36 @@
 	guint32 message_info_size;
 	guint32 content_info_size;
 
-	/* memory allocators (setup automatically) */
-	struct _EMemChunk *message_info_chunks;
-	struct _EMemChunk *content_info_chunks;
-
 	char *summary_path;
 	gboolean build_content;	/* do we try and parse/index the content, or not? */
 
-	GPtrArray *messages;	/* CamelMessageInfo's */
-	GHashTable *messages_uid; /* CamelMessageInfo's by uid */
+	GPtrArray *messages, *expunged; /* CamelMessageInfo's */
+	GHashTable *uidhash;
 
 	struct _CamelFolder *folder; /* parent folder, for events */
 	struct _CamelFolderMetaSummary *meta_summary; /* Meta summary */
+
+	GMappedFile *file;
+	unsigned char *filepos;
+	GMutex *dump_lock, *hash_lock;
+	gboolean in_reload;
+	gint idx;
+
+	void (*set_extra_flags_func) (CamelFolder *folder, CamelMessageInfoBase *mi);
 };
 
 struct _CamelFolderSummaryClass {
 	CamelObjectClass parent_class;
 
 	/* load/save the global info */
-	int (*summary_header_load)(CamelFolderSummary *, FILE *);
+	int (*summary_header_load)(CamelFolderSummary *);
 	int (*summary_header_save)(CamelFolderSummary *, FILE *);
 
 	/* create/save/load an individual message info */
 	CamelMessageInfo * (*message_info_new_from_header)(CamelFolderSummary *, struct _camel_header_raw *);
 	CamelMessageInfo * (*message_info_new_from_parser)(CamelFolderSummary *, CamelMimeParser *);
 	CamelMessageInfo * (*message_info_new_from_message)(CamelFolderSummary *, CamelMimeMessage *);
-	CamelMessageInfo * (*message_info_load)(CamelFolderSummary *, FILE *);
+	CamelMessageInfo * (*message_info_load)(CamelFolderSummary *, gboolean *must_add);
  	int		   (*message_info_save)(CamelFolderSummary *, FILE *, CamelMessageInfo *);
 	int		   (*meta_message_info_save)(CamelFolderSummary *, FILE *, FILE *, CamelMessageInfo *);
 
@@ -250,7 +236,7 @@
 	CamelMessageContentInfo * (*content_info_new_from_header)(CamelFolderSummary *, struct _camel_header_raw *);
 	CamelMessageContentInfo * (*content_info_new_from_parser)(CamelFolderSummary *, CamelMimeParser *);
 	CamelMessageContentInfo * (*content_info_new_from_message)(CamelFolderSummary *, CamelMimePart *);
-	CamelMessageContentInfo * (*content_info_load)(CamelFolderSummary *, FILE *);
+	CamelMessageContentInfo * (*content_info_load)(CamelFolderSummary *);
 	int		          (*content_info_save)(CamelFolderSummary *, FILE *, CamelMessageContentInfo *);
 	void		          (*content_info_free)(CamelFolderSummary *, CamelMessageContentInfo *);
 
@@ -265,16 +251,10 @@
 	gboolean    (*info_user_flag)(const CamelMessageInfo *mi, const char *id);
 	const char *(*info_user_tag)(const CamelMessageInfo *mi, const char *id);
 
-	/* set accessors for the modifyable bits */
-#if 0
-	void (*info_set_ptr)(CamelMessageInfo *mi, int id, const void *val);
-	void (*info_set_uint32)(CamelMessageInfo *mi, int id, guint32 val);
-	void (*info_set_time)(CamelMessageInfo *mi, int id, time_t val);
-	void (*info_set_references)(CamelMessageInfo *mi, CamelSummaryReferences *);
-#endif
 	gboolean (*info_set_user_flag)(CamelMessageInfo *mi, const char *id, gboolean state);
 	gboolean (*info_set_user_tag)(CamelMessageInfo *mi, const char *id, const char *val);
 	gboolean (*info_set_flags)(CamelMessageInfo *mi, guint32 mask, guint32 set);
+
 };
 
 /* Meta-summary info */
@@ -289,8 +269,10 @@
 CamelType			 camel_folder_summary_get_type	(void);
 CamelFolderSummary      *camel_folder_summary_new	(struct _CamelFolder *folder);
 
+unsigned char*
+decode_uint32 (unsigned char *start, guint32 *dest, gboolean is_string);
+
 void camel_folder_summary_set_filename(CamelFolderSummary *summary, const char *filename);
-void camel_folder_summary_set_index(CamelFolderSummary *summary, CamelIndex *index);
 void camel_folder_summary_set_build_content(CamelFolderSummary *summary, gboolean state);
 
 guint32  camel_folder_summary_next_uid        (CamelFolderSummary *summary);
@@ -316,6 +298,7 @@
 CamelMessageInfo *camel_folder_summary_add_from_message(CamelFolderSummary *summary, CamelMimeMessage *message);
 
 /* Just build raw summary items */
+CamelMessageInfo *camel_folder_summary_info_new_from_header_with_uid (CamelFolderSummary *s, struct _camel_header_raw *h, const gchar *uid);
 CamelMessageInfo *camel_folder_summary_info_new_from_header(CamelFolderSummary *summary, struct _camel_header_raw *headers);
 CamelMessageInfo *camel_folder_summary_info_new_from_parser(CamelFolderSummary *summary, CamelMimeParser *parser);
 CamelMessageInfo *camel_folder_summary_info_new_from_message(CamelFolderSummary *summary, CamelMimeMessage *message);
@@ -341,7 +324,7 @@
 
 /* basically like strings, but certain keywords can be compressed and de-cased */
 int camel_folder_summary_encode_token(FILE *out, const char *str);
-int camel_folder_summary_decode_token(FILE *in, char **str);
+int camel_folder_summary_decode_token(CamelFolderSummary *s, char **str);
 
 /* message flag operations */
 gboolean	camel_flag_get(CamelFlag **list, const char *name);
@@ -363,6 +346,8 @@
 /* Summary may be null */
 /* Use anonymous pointers to avoid tons of cast crap */
 void *camel_message_info_new(CamelFolderSummary *summary);
+void *camel_message_info_new_uid (CamelFolderSummary *summary, const char *uid);
+
 void camel_message_info_ref(void *info);
 CamelMessageInfo *camel_message_info_new_from_header(CamelFolderSummary *summary, struct _camel_header_raw *header);
 void camel_message_info_free(void *info);
@@ -379,7 +364,6 @@
 #define camel_message_info_from(mi) ((const char *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_FROM))
 #define camel_message_info_to(mi) ((const char *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_TO))
 #define camel_message_info_cc(mi) ((const char *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_CC))
-#define camel_message_info_mlist(mi) ((const char *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_MLIST))
 
 #define camel_message_info_flags(mi) camel_message_info_uint32((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_FLAGS)
 #define camel_message_info_size(mi) camel_message_info_uint32((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_SIZE)
@@ -388,7 +372,6 @@
 #define camel_message_info_date_received(mi) camel_message_info_time((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_DATE_RECEIVED)
 
 #define camel_message_info_message_id(mi) ((const CamelSummaryMessageID *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_MESSAGE_ID))
-#define camel_message_info_references(mi) ((const CamelSummaryReferences *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_REFERENCES))
 #define camel_message_info_user_flags(mi) ((const CamelFlag *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_USER_FLAGS))
 #define camel_message_info_user_tags(mi) ((const CamelTag *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_USER_TAGS))
 
@@ -404,6 +387,13 @@
 
 void camel_message_info_dump (CamelMessageInfo *mi);
 
+void camel_folder_summary_prepare_hash (CamelFolderSummary *summary);
+void camel_folder_summary_kill_hash (CamelFolderSummary *summary);
+
+void camel_message_info_clear_normal_flags (CamelMessageInfo *min);
+int camel_folder_summary_get_index_for (CamelFolderSummary *s, const char *uid);
+
+
 G_END_DECLS
 
 #endif /* ! _CAMEL_FOLDER_SUMMARY_H */
Only in .: camel-folder-summary.h.rej
Only in .: camel-folder-summary.lo
Only in .: camel-folder-summary.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-folder-thread.c ./camel-folder-thread.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-folder-thread.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-folder-thread.c	2007-05-12 10:01:18.000000000 +0200
@@ -58,6 +58,7 @@
 	child->parent = node;
 }
 
+#if 0
 static void
 container_parent_child(CamelFolderThreadNode *parent, CamelFolderThreadNode *child)
 {
@@ -99,6 +100,8 @@
 
 	printf("DAMN, we shouldn't  be here!\n");
 }
+#endif
+
 
 static void
 prune_empty(CamelFolderThread *thread, CamelFolderThreadNode **cp)
@@ -118,8 +121,6 @@
 			if (c->child == NULL) {
 				d(printf("removing empty node\n"));
 				lastc->next = c->next;
-				m(memset(c, 0xfe, sizeof(*c)));
-				e_memchunk_free(thread->node_chunks, c);
 				continue;
 			}
 			if (c->parent || c->child->next==0) {
@@ -268,8 +269,6 @@
 					scan = scan->next;
 				scan->next = c->child;
 				clast->next = c->next;
-				m(memset(c, 0xee, sizeof(*c)));
-				e_memchunk_free(thread->node_chunks, c);
 				continue;
 			} if (c->message == NULL && container->message != NULL) {
 				d(printf("container is non-empty parent\n"));
@@ -296,7 +295,7 @@
 				remove_node(cp, container, &clast);
 				remove_node(cp, c, &clast);
 
-				scan = e_memchunk_alloc0(thread->node_chunks);
+				scan = camel_folder_thread_node_new(thread);
 
 				scan->root_subject = c->root_subject;
 				scan->re = c->re && container->re;
@@ -450,7 +449,9 @@
 	for (i=0;i<summary->len;i++) {
 		CamelMessageInfo *mi = summary->pdata[i];
 		const CamelSummaryMessageID *mid = camel_message_info_message_id(mi);
+#ifdef NON_TINYMAIL_FEATURES
 		const CamelSummaryReferences *references = camel_message_info_references(mi);
+#endif
 
 		if (mid->id.id) {
 			c = g_hash_table_lookup(id_table, mid);
@@ -459,22 +460,24 @@
 				/* if duplicate, just make out it is a no-id message,  but try and insert it
 				   into the right spot in the tree */
 				d(printf("doing: (duplicate message id)\n"));
-				c = e_memchunk_alloc0(thread->node_chunks);
+				c = camel_folder_thread_node_new(thread);
 				g_hash_table_insert(no_id_table, (void *)mi, c);
 			} else if (!c) {
 				d(printf("doing : %08x%08x (%s)\n", mid->id.part.hi, mid->id.part.lo, camel_message_info_subject(mi)));
-				c = e_memchunk_alloc0(thread->node_chunks);
+				c = camel_folder_thread_node_new(thread);
 				g_hash_table_insert(id_table, (void *)mid, c);
 			}
 		} else {
 			d(printf("doing : (no message id)\n"));
-			c = e_memchunk_alloc0(thread->node_chunks);
+			c = camel_folder_thread_node_new(thread);
 			g_hash_table_insert(no_id_table, (void *)mi, c);
 		}
 
 		c->message = mi;
 		c->order = i+1;
 		child = c;
+
+#ifdef NON_TINYMAIL_FEATURES
 		if (references) {
 			int j;
 
@@ -487,7 +490,7 @@
 				c = g_hash_table_lookup(id_table, &references->references[j]);
 				if (c == NULL) {
 					d(printf("not found\n"));
-					c = e_memchunk_alloc0(thread->node_chunks);
+					c = camel_folder_thread_node_new(thread);
 					g_hash_table_insert(id_table, (void *)&references->references[j], c);
 				}
 				if (c!=child)
@@ -495,6 +498,7 @@
 				child = c;
 			}
 		}
+#endif
 	}
 
 	d(printf("\n\n"));
@@ -547,8 +551,6 @@
 			/* and link the now 'real' node into the list */
 			newtop->next = child->next;
 			c = newtop;
-			m(memset(child, 0xde, sizeof(*child)));
-			e_memchunk_free(thread->node_chunks, child);
 		} else {
 			c = child;
 		}
@@ -607,7 +609,7 @@
 	thread->refcount = 1;
 	thread->subject = thread_subject;
 	thread->tree = NULL;
-	thread->node_chunks = e_memchunk_new(32, sizeof(CamelFolderThreadNode));
+	thread->mem_chain = NULL;
 	thread->folder = folder;
 	camel_object_ref((CamelObject *)folder);
 
@@ -682,9 +684,10 @@
 
 	g_hash_table_destroy(table);
 
+	g_slice_free_chain(CamelFolderThreadNode, thread->mem_chain, mem_chain);
+
 	thread->tree = NULL;
-	e_memchunk_destroy(thread->node_chunks);
-	thread->node_chunks = e_memchunk_new(32, sizeof(CamelFolderThreadNode));
+	thread->mem_chain = NULL;
 	thread_summary(thread, all);
 
 	g_ptr_array_free(thread->summary, TRUE);
@@ -719,7 +722,7 @@
 		g_ptr_array_free(thread->summary, TRUE);
 		camel_object_unref((CamelObject *)thread->folder);
 	}
-	e_memchunk_destroy(thread->node_chunks);
+	g_slice_free_chain(CamelFolderThreadNode, thread->mem_chain, mem_chain);
 	g_free(thread);
 }
 
@@ -750,7 +753,7 @@
 	thread = g_malloc(sizeof(*thread));
 	thread->refcount = 1;
 	thread->tree = NULL;
-	thread->node_chunks = e_memchunk_new(32, sizeof(CamelFolderThreadNode));
+	thread->mem_chain = NULL;
 	thread->folder = NULL;
 	thread->summary = NULL;
 
@@ -798,8 +801,9 @@
 	g_hash_table_destroy(table);
 
 	/* reset the tree, and rebuild fully */
+	g_slice_free_chain(CamelFolderThreadNode, thread->mem_chain, mem_chain);
 	thread->tree = NULL;
-	e_memchunk_empty(thread->node_chunks);
+	thread->mem_chain = NULL;
 	thread_summary(thread, all);
 }
 
@@ -836,7 +840,6 @@
 
 				rest = next->next;
 				node->next = child;
-				e_memchunk_free(thread->node_chunks, next);
 				next = child;
 				do {
 					lchild = child;
@@ -853,7 +856,6 @@
 				  node
 				  rest */
 				node->next = next->next;
-				e_memchunk_free(thread->node_chunks, next);
 				next = node->next;
 			}
 		} else {
@@ -878,3 +880,16 @@
 }
 
 #endif
+
+CamelFolderThreadNode *
+camel_folder_thread_node_new(CamelFolderThread *thread)
+{
+	CamelFolderThreadNode *node;
+
+	node = g_slice_new0(CamelFolderThreadNode);
+	node->mem_chain = thread->mem_chain;
+	thread->mem_chain = node;
+
+	return node;
+}
+
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-folder-thread.h ./camel-folder-thread.h
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-folder-thread.h	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-folder-thread.h	2007-05-12 10:01:18.000000000 +0200
@@ -28,6 +28,7 @@
 G_BEGIN_DECLS
 
 typedef struct _CamelFolderThreadNode {
+	struct _CamelFolderThreadNode *mem_chain;
 	struct _CamelFolderThreadNode *next, *parent, *child;
 	const CamelMessageInfo *message;
 	char *root_subject;	/* cached root equivalent subject */
@@ -40,7 +41,7 @@
 	guint32 subject   : 1;
 	
 	struct _CamelFolderThreadNode *tree;
-	struct _EMemChunk *node_chunks;
+	struct _CamelFolderThreadNode *mem_chain;
 	CamelFolder *folder;
 	GPtrArray *summary;
 } CamelFolderThread;
@@ -63,6 +64,8 @@
 /* debugging function only */
 int camel_folder_threaded_messages_dump(CamelFolderThreadNode *c);
 
+CamelFolderThreadNode *camel_folder_thread_node_new(CamelFolderThread *thread);
+
 G_END_DECLS
 
 #endif /* !_CAMEL_FOLDER_THREAD_H */
Only in .: camel-folder-thread.lo
Only in .: camel-folder-thread.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-gpg-context.c ./camel-gpg-context.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-gpg-context.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-gpg-context.c	2007-05-12 10:01:18.000000000 +0200
@@ -400,7 +400,7 @@
 		if (gpg->diagbuf->len == 0)
 			return NULL;
 		
-		g_byte_array_append (gpg->diagbuf, "", 1);
+		g_byte_array_append (gpg->diagbuf, (guchar*)"", 1);
 	}
 	
 	return (const char *) gpg->diagbuf->data;
@@ -747,23 +747,20 @@
 	if (camel_debug("gpg:status"))
 		printf ("status: %s\n", status);
 	
-	if (strncmp (status, "[GNUPG:] ", 9) != 0) {
-		char *message;
-		message = g_locale_to_utf8(status, -1, NULL, NULL, NULL);
+	if (strncmp ((char*)status, "[GNUPG:] ", 9) != 0) {
 		camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
 				      _("Unexpected GnuPG status message encountered:\n\n%s"),
-				      message);
-		g_free(message);
+				      status);
 		return -1;
 	}
 	
 	status += 9;
 	
-	if (!strncmp (status, "USERID_HINT ", 12)) {
+	if (!strncmp ((char*)status, "USERID_HINT ", 12)) {
 		char *hint, *user;
 		
 		status += 12;
-		status = next_token (status, &hint);
+		status = (const unsigned char *) next_token ((char*)status, &hint);
 		if (!hint) {
 			camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM,
 					     _("Failed to parse gpg userid hint."));
@@ -776,18 +773,18 @@
 			goto recycle;
 		}
 		
-		if (gpg->utf8 || !(user = g_locale_to_utf8 (status, -1, &nread, &nwritten, NULL)))
-			user = g_strdup (status);
+		if (gpg->utf8 || !(user = g_locale_to_utf8 ((gchar*)status, -1, &nread, &nwritten, NULL)))
+			user = g_strdup ((gchar*)status);
 		
 		g_strstrip (user);
 		
 		g_hash_table_insert (gpg->userid_hint, hint, user);
-	} else if (!strncmp (status, "NEED_PASSPHRASE ", 16)) {
+	} else if (!strncmp ((char*)status, "NEED_PASSPHRASE ", 16)) {
 		char *userid;
 		
 		status += 16;
 		
-		status = next_token (status, &userid);
+		status = (const unsigned char *) next_token ((char*)status, &userid);
 		if (!userid) {
 			camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM,
 					     _("Failed to parse gpg passphrase request."));
@@ -796,12 +793,12 @@
 		
 		g_free (gpg->need_id);
 		gpg->need_id = userid;
-	} else if (!strncmp (status, "NEED_PASSPHRASE_PIN ", 20)) {
+	} else if (!strncmp ((char*)status, "NEED_PASSPHRASE_PIN ", 20)) {
 		char *userid;
 		
 		status += 20;
 		
-		status = next_token (status, &userid);
+		status = (const unsigned char *)next_token ((char*)status, &userid);
 		if (!userid) {
 			camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM,
 					     _("Failed to parse gpg passphrase request."));
@@ -810,7 +807,7 @@
 		
 		g_free (gpg->need_id);
 		gpg->need_id = userid;
-	} else if (!strncmp (status, "GET_HIDDEN ", 11)) {
+	} else if (!strncmp ((char*)status, "GET_HIDDEN ", 11)) {
 		const char *name = NULL;
 		char *prompt, *passwd;
 		guint32 flags;
@@ -822,14 +819,14 @@
 		else if (!name)
 			name = "";
 		
-		if (!strncmp (status, "passphrase.pin.ask", 18)) {
+		if (!strncmp ((char*)status, "passphrase.pin.ask", 18)) {
 			prompt = g_strdup_printf (_("You need a PIN to unlock the key for your\n"
 						    "SmartCard: \"%s\""), name);
-		} else if (!strncmp (status, "passphrase.enter", 16)) {
+		} else if (!strncmp ((char*)status, "passphrase.enter", 16)) {
 			prompt = g_strdup_printf (_("You need a passphrase to unlock the key for\n"
 						    "user: \"%s\""), name);
 		} else {
-			next_token (status, &prompt);
+			next_token ((char*)status, &prompt);
 			camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
 					      _("Unexpected request from GnuPG for `%s'"), prompt);
 			g_free (prompt);
@@ -861,9 +858,9 @@
 		}
 		
 		g_free (prompt);
-	} else if (!strncmp (status, "GOOD_PASSPHRASE", 15)) {
+	} else if (!strncmp ((char*)status, "GOOD_PASSPHRASE", 15)) {
 		gpg->bad_passwds = 0;
-	} else if (!strncmp (status, "BAD_PASSPHRASE", 14)) {
+	} else if (!strncmp ((char*)status, "BAD_PASSPHRASE", 14)) {
 		gpg->bad_passwds++;
 		
 		camel_session_forget_password (gpg->session, NULL, NULL, gpg->need_id, ex);
@@ -873,16 +870,13 @@
 					     _("Failed to unlock secret key: 3 bad passphrases given."));
 			return -1;
 		}
-	} else if (!strncmp (status, "UNEXPECTED ", 11)) {
+	} else if (!strncmp ((char*)status, "UNEXPECTED ", 11)) {
 		/* this is an error */
-		char *message;
-		message = g_locale_to_utf8(status+11, -1, NULL, NULL, NULL);
 		camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
 				      _("Unexpected response from GnuPG: %s"),
-				      message);
-		g_free(message);
+				      status + 11);
 		return -1;
-	} else if (!strncmp (status, "NODATA", 6)) {
+	} else if (!strncmp ((char*)status, "NODATA", 6)) {
 		/* this is an error */
 		/* But we ignore it anyway, we should get other response codes to say why */
 		gpg->nodata = TRUE;
@@ -890,55 +884,55 @@
 		/* check to see if we are complete */
 		switch (gpg->mode) {
 		case GPG_CTX_MODE_SIGN:
-			if (!strncmp (status, "SIG_CREATED ", 12)) {
+			if (!strncmp ((char*)status, "SIG_CREATED ", 12)) {
 				/* FIXME: save this state? */
 			}
 			break;
 		case GPG_CTX_MODE_VERIFY:
-			if (!strncmp (status, "TRUST_", 6)) {
+			if (!strncmp ((char*)status, "TRUST_", 6)) {
 				status += 6;
-				if (!strncmp (status, "NEVER", 5)) {
+				if (!strncmp ((char*)status, "NEVER", 5)) {
 					gpg->trust = GPG_TRUST_NEVER;
-				} else if (!strncmp (status, "MARGINAL", 8)) {
+				} else if (!strncmp ((char*)status, "MARGINAL", 8)) {
 					gpg->trust = GPG_TRUST_MARGINAL;
-				} else if (!strncmp (status, "FULLY", 5)) {
+				} else if (!strncmp ((char*)status, "FULLY", 5)) {
 					gpg->trust = GPG_TRUST_FULLY;
-				} else if (!strncmp (status, "ULTIMATE", 8)) {
+				} else if (!strncmp ((char*)status, "ULTIMATE", 8)) {
 					gpg->trust = GPG_TRUST_ULTIMATE;
-				} else if (!strncmp (status, "UNDEFINED", 9)) {
+				} else if (!strncmp ((char*)status, "UNDEFINED", 9)) {
 					gpg->trust = GPG_TRUST_UNDEFINED;
 				}
-			} else if (!strncmp (status, "GOODSIG ", 8)) {
+			} else if (!strncmp ((char*)status, "GOODSIG ", 8)) {
 				gpg->goodsig = TRUE;
 				gpg->hadsig = TRUE;
-			} else if (!strncmp (status, "VALIDSIG ", 9)) {
+			} else if (!strncmp ((char*)status, "VALIDSIG ", 9)) {
 				gpg->validsig = TRUE;
-			} else if (!strncmp (status, "BADSIG ", 7)) {
+			} else if (!strncmp ((char*)status, "BADSIG ", 7)) {
 				gpg->badsig = FALSE;
 				gpg->hadsig = TRUE;
-			} else if (!strncmp (status, "ERRSIG ", 7)) {
+			} else if (!strncmp ((char*)status, "ERRSIG ", 7)) {
 				/* Note: NO_PUBKEY often comes after an ERRSIG */
 				gpg->errsig = FALSE;
 				gpg->hadsig = TRUE;
-			} else if (!strncmp (status, "NO_PUBKEY ", 10)) {
+			} else if (!strncmp ((char*)status, "NO_PUBKEY ", 10)) {
 				gpg->nopubkey = TRUE;
 			}
 			break;
 		case GPG_CTX_MODE_ENCRYPT:
-			if (!strncmp (status, "BEGIN_ENCRYPTION", 16)) {
+			if (!strncmp ((char*)status, "BEGIN_ENCRYPTION", 16)) {
 				/* nothing to do... but we know to expect data on stdout soon */
-			} else if (!strncmp (status, "END_ENCRYPTION", 14)) {
+			} else if (!strncmp ((char*)status, "END_ENCRYPTION", 14)) {
 				/* nothing to do, but we know the end is near? */
-			} else if (!strncmp (status, "NO_RECP", 7)) {
+			} else if (!strncmp ((char*)status, "NO_RECP", 7)) {
 				camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM,
 						     _("Failed to encrypt: No valid recipients specified."));
 				return -1;
 			}
 			break;
 		case GPG_CTX_MODE_DECRYPT:
-			if (!strncmp (status, "BEGIN_DECRYPTION", 16)) {
+			if (!strncmp ((char*)status, "BEGIN_DECRYPTION", 16)) {
 				/* nothing to do... but we know to expect data on stdout soon */
-			} else if (!strncmp (status, "END_DECRYPTION", 14)) {
+			} else if (!strncmp ((char*)status, "END_DECRYPTION", 14)) {
 				/* nothing to do, but we know the end is near? */
 			}
 			break;
Only in .: camel-gpg-context.lo
Only in .: camel-gpg-context.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel.h ./camel.h
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel.h	2007-05-12 09:58:58.000000000 +0200
+++ ./camel.h	2007-05-12 10:34:01.000000000 +0200
@@ -118,9 +118,9 @@
 #include <camel/camel-stream-filter.h>
 #include <camel/camel-stream-fs.h>
 #include <camel/camel-stream-mem.h>
+#include <camel/camel-stream-gzip.h>
 #include <camel/camel-stream-null.h>
 #include <camel/camel-stream-process.h>
-#include <camel/camel-stream-vfs.h>
 #include <camel/camel-string-utils.h>
 #include <camel/camel-tcp-stream.h>
 #include <camel/camel-tcp-stream-raw.h>
Only in .: camel.h.rej
Only in .: camel-html-parser.lo
Only in .: camel-html-parser.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-http-stream.c ./camel-http-stream.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-http-stream.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-http-stream.c	2007-05-12 10:01:18.000000000 +0200
@@ -268,7 +268,7 @@
 
 	/* parse the HTTP status code */
 	if (!g_ascii_strncasecmp (buffer, "HTTP/", 5)) {
-		token = http_next_token (buffer);
+		token = http_next_token ((const unsigned char *) buffer);
 		http->statuscode = camel_header_decode_int (&token);
 		return http->statuscode;
 	}
Only in .: camel-http-stream.lo
Only in .: camel-http-stream.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-i18n.h ./camel-i18n.h
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-i18n.h	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-i18n.h	2007-05-12 10:43:53.000000000 +0200
@@ -29,9 +29,9 @@
 
 #ifdef ENABLE_NLS
 #    include <libintl.h>
-#    ifdef CAMEL_EXPLICIT_TRANSLATION_DOMAIN
+#    ifdef TRANSDOM
 #        undef _
-#        define _(String) dgettext (CAMEL_EXPLICIT_TRANSLATION_DOMAIN, String)
+#        define _(String) dgettext (TRANSDOM, String)
 #    else 
 #        define _(String) gettext (String)
 #    endif
@@ -42,12 +42,20 @@
 #    endif
 #else
 /* Stubs that do something close enough.  */
-#    define textdomain(String) (String)
+#    define textdomain(String) (String
+#ifndef gettext
 #    define gettext(String) (String)
+#endif
+#ifndef dgettext
 #    define dgettext(Domain,Message) (Message)
+#endif
+#ifndef dcgettext
 #    define dcgettext(Domain,Message,Type) (Message)
+#endif
 #    define bindtextdomain(Domain,Directory) (Domain)
+#ifndef _
 #    define _(String) (String)
+#endif
 #    define N_(String) (String)
 #endif
 
Only in .: camel-index.lo
Only in .: camel-index.o
Only in .: camel-internet-address.lo
Only in .: camel-internet-address.o
Only in .: camel-junk-plugin.lo
Only in .: camel-junk-plugin.o
Only in .: camel-list-utils.lo
Only in .: camel-list-utils.o
Only in .: camel-lite-1.2.pc
Only in .: camel-lite.pc
Only in .: camel-lite.pc.in
Only in .: camel-lite-provider-1.2.pc
Only in .: camel-lite-provider.pc
Only in .: camel-lite-provider.pc.in
Only in .: camel.lo
Only in .: camel-lock-client.lo
Only in .: camel-lock-client.o
Only in .: camel-lock.lo
Only in .: camel-lock.o
Only in .: camel-medium.lo
Only in .: camel-medium.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-mime-filter-basic.c ./camel-mime-filter-basic.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-mime-filter-basic.c	2007-04-20 13:25:00.000000000 +0200
+++ ./camel-mime-filter-basic.c	2007-03-11 16:44:11.000000000 +0100
@@ -101,38 +101,38 @@
 	case CAMEL_MIME_FILTER_BASIC_BASE64_ENC:
 		/* wont go to more than 2x size (overly conservative) */
 		camel_mime_filter_set_size(mf, len*2+6, FALSE);
-		newlen = camel_base64_encode_close(in, len, TRUE, mf->outbuf, &f->state, &f->save);
+		newlen = camel_base64_encode_close((unsigned char *)in, len, TRUE, (unsigned char*)mf->outbuf, &f->state, &f->save);
 		g_assert(newlen <= len*2+6);
 		break;
 	case CAMEL_MIME_FILTER_BASIC_QP_ENC:
 		/* *4 is definetly more than needed ... */
 		camel_mime_filter_set_size(mf, len*4+4, FALSE);
-		newlen = camel_quoted_encode_close(in, len, mf->outbuf, &f->state, &f->save);
+		newlen = camel_quoted_encode_close((unsigned char *)in, len, (unsigned char*)mf->outbuf, &f->state, &f->save);
 		g_assert(newlen <= len*4+4);
 		break;
 	case CAMEL_MIME_FILTER_BASIC_UU_ENC:
 		/* won't go to more than 2 * (x + 2) + 62 */
 		camel_mime_filter_set_size (mf, (len + 2) * 2 + 62, FALSE);
-		newlen = camel_uuencode_close (in, len, mf->outbuf, f->uubuf, &f->state, &f->save);
+		newlen = camel_uuencode_close ((unsigned char *)in, len, (unsigned char*)mf->outbuf, f->uubuf, &f->state, (guint32*) &f->save);
 		g_assert (newlen <= (len + 2) * 2 + 62);
 		break;
 	case CAMEL_MIME_FILTER_BASIC_BASE64_DEC:
 		/* output can't possibly exceed the input size */
  		camel_mime_filter_set_size(mf, len, FALSE);
-		newlen = camel_base64_decode_step(in, len, mf->outbuf, &f->state, &f->save);
+		newlen = camel_base64_decode_step((unsigned char *)in, len, (unsigned char*)mf->outbuf, &f->state, (guint32*) &f->save);
 		g_assert(newlen <= len);
 		break;
 	case CAMEL_MIME_FILTER_BASIC_QP_DEC:
 		/* output can't possibly exceed the input size, well unless its not really qp, then +2 max */
 		camel_mime_filter_set_size(mf, len+2, FALSE);
-		newlen = camel_quoted_decode_step(in, len, mf->outbuf, &f->state, &f->save);
+		newlen = camel_quoted_decode_step((unsigned char *)in, len, (unsigned char*)mf->outbuf, &f->state, (gint*) &f->save);
 		g_assert(newlen <= len+2);
 		break;
 	case CAMEL_MIME_FILTER_BASIC_UU_DEC:
 		if ((f->state & CAMEL_UUDECODE_STATE_BEGIN) && !(f->state & CAMEL_UUDECODE_STATE_END)) {
 			/* "begin <mode> <filename>\n" has been found, so we can now start decoding */
 			camel_mime_filter_set_size (mf, len + 3, FALSE);
-			newlen = camel_uudecode_step (in, len, mf->outbuf, &f->state, &f->save);
+			newlen = camel_uudecode_step ((unsigned char *)in, len, (unsigned char*)mf->outbuf, &f->state, (guint32*) &f->save);
 		} else {
 			newlen = 0;
 		}
@@ -164,31 +164,31 @@
 	case CAMEL_MIME_FILTER_BASIC_BASE64_ENC:
 		/* wont go to more than 2x size (overly conservative) */
 		camel_mime_filter_set_size(mf, len*2+6, FALSE);
-		newlen = camel_base64_encode_step(in, len, TRUE, mf->outbuf, &f->state, &f->save);
+		newlen = camel_base64_encode_step((unsigned char *)in, len, TRUE,  (unsigned char*)mf->outbuf, &f->state, (gint*)&f->save);
 		g_assert(newlen <= len*2+6);
 		break;
 	case CAMEL_MIME_FILTER_BASIC_QP_ENC:
 		/* *4 is overly conservative, but will do */
 		camel_mime_filter_set_size(mf, len*4+4, FALSE);
-		newlen = camel_quoted_encode_step(in, len, mf->outbuf, &f->state, &f->save);
+		newlen = camel_quoted_encode_step((unsigned char *)in, len,  (unsigned char*)mf->outbuf, &f->state, (gint*)&f->save);
 		g_assert(newlen <= len*4+4);
 		break;
 	case CAMEL_MIME_FILTER_BASIC_UU_ENC:
 		/* won't go to more than 2 * (x + 2) + 62 */
 		camel_mime_filter_set_size (mf, (len + 2) * 2 + 62, FALSE);
-		newlen = camel_uuencode_step (in, len, mf->outbuf, f->uubuf, &f->state, &f->save);
+		newlen = camel_uuencode_step ((unsigned char *)in, len,  (unsigned char*)mf->outbuf, f->uubuf, &f->state, (guint32*)&f->save);
 		g_assert (newlen <= (len + 2) * 2 + 62);
 		break;
 	case CAMEL_MIME_FILTER_BASIC_BASE64_DEC:
 		/* output can't possibly exceed the input size */
 		camel_mime_filter_set_size(mf, len+3, FALSE);
-		newlen = camel_base64_decode_step(in, len, mf->outbuf, &f->state, &f->save);
+		newlen = camel_base64_decode_step((unsigned char *)in, len,  (unsigned char*)mf->outbuf, &f->state, (guint32*)&f->save);
 		g_assert(newlen <= len+3);
 		break;
 	case CAMEL_MIME_FILTER_BASIC_QP_DEC:
 		/* output can't possibly exceed the input size */
 		camel_mime_filter_set_size(mf, len + 2, FALSE);
-		newlen = camel_quoted_decode_step(in, len, mf->outbuf, &f->state, &f->save);
+		newlen = camel_quoted_decode_step((unsigned char *)in, len,  (unsigned char*)mf->outbuf, &f->state, (gint*)&f->save);
 		g_assert(newlen <= len + 2);
 		break;
 	case CAMEL_MIME_FILTER_BASIC_UU_DEC:
@@ -230,7 +230,7 @@
 		if ((f->state & CAMEL_UUDECODE_STATE_BEGIN) && !(f->state & CAMEL_UUDECODE_STATE_END)) {
 			/* "begin <mode> <filename>\n" has been found, so we can now start decoding */
 			camel_mime_filter_set_size (mf, len + 3, FALSE);
-			newlen = camel_uudecode_step (in, len, mf->outbuf, &f->state, &f->save);
+			newlen = camel_uudecode_step ((unsigned char*)in, len, (unsigned char*)mf->outbuf, &f->state, (guint32*)&f->save);
 		} else {
 			newlen = 0;
 		}
Only in .: camel-mime-filter-basic.lo
Only in .: camel-mime-filter-basic.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-mime-filter-bestenc.c ./camel-mime-filter-bestenc.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-mime-filter-bestenc.c	2007-04-20 13:25:00.000000000 +0200
+++ ./camel-mime-filter-bestenc.c	2007-03-11 16:44:11.000000000 +0100
@@ -102,7 +102,7 @@
 		f->startofline = FALSE;
 
 		/* See rfc2045 section 2 for definitions of 7bit/8bit/binary */
-		p = in;
+		p = (unsigned char *)in;
 		pend = p + len;
 		while (p<pend) {
 			c = *p++;
@@ -130,7 +130,7 @@
 					/* Check for "^From " lines */
 					if ((f->flags & CAMEL_BESTENC_NO_FROM) && !f->hadfrom) {
 						if (pend-p >= 5) {
-							f->hadfrom = strncmp(p, "From ", 5) == 0;
+							f->hadfrom = strncmp((char*)p, "From ", 5) == 0;
 						} else if (pend-p == 0) {
 							f->startofline = TRUE;
 						} else {
Only in .: camel-mime-filter-bestenc.lo
Only in .: camel-mime-filter-bestenc.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-mime-filter-canon.c ./camel-mime-filter-canon.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-mime-filter-canon.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-mime-filter-canon.c	2007-05-12 10:01:18.000000000 +0200
@@ -80,8 +80,8 @@
 	flags = ((CamelMimeFilterCanon *)f)->flags;
 
 	/* first, work out how much space we need */
-	inptr = in;
-	inend = in+len;
+	inptr = (unsigned char *)in;
+	inend = (const unsigned char *) (in+len);
 	while (inptr < inend)
 		if (*inptr++ == '\n')
 			lf++;
@@ -93,7 +93,7 @@
 	camel_mime_filter_set_size(f, len+lf*3+4, FALSE);
 
 	o = f->outbuf;
-	inptr = in;
+	inptr = (unsigned char *)in;
 	start = inptr;
 	starto = o;
 	while (inptr < inend) {
@@ -102,7 +102,7 @@
 		if (flags & CAMEL_MIME_FILTER_CANON_FROM && c == 'F') {
 			inptr++;
 			if (inptr < inend-4) {
-				if (strncmp(inptr, "rom ", 4) == 0) {
+				if (strncmp((char*)inptr, "rom ", 4) == 0) {
 					strcpy(o, "=46rom ");
 					inptr+=4;
 					o+= 7;
@@ -153,7 +153,7 @@
 	if (last) {
 		*outlen = o - f->outbuf;
 	} else {
-		camel_mime_filter_backup(f, start, inend - start);
+		camel_mime_filter_backup(f, (const char*)start, inend - start);
 		*outlen = starto - f->outbuf;
 	}
 
Only in .: camel-mime-filter-canon.lo
Only in .: camel-mime-filter-canon.o
Only in .: camel-mime-filter-charset.lo
Only in .: camel-mime-filter-charset.o
Only in .: camel-mime-filter-crlf.lo
Only in .: camel-mime-filter-crlf.o
Only in .: camel-mime-filter-enriched.lo
Only in .: camel-mime-filter-enriched.o
Only in .: camel-mime-filter-from.lo
Only in .: camel-mime-filter-from.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-mime-filter-gzip.c ./camel-mime-filter-gzip.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-mime-filter-gzip.c	2007-04-20 13:25:00.000000000 +0200
+++ ./camel-mime-filter-gzip.c	2007-03-11 16:44:11.000000000 +0100
@@ -185,18 +185,18 @@
 		
 		memcpy (filter->outbuf, priv->hdr.buf, 10);
 		
-		priv->stream->next_out = filter->outbuf + 10;
+		priv->stream->next_out = (Bytef *)filter->outbuf + 10;
 		priv->stream->avail_out = filter->outsize - 10;
 		
 		priv->state.zip.wrote_hdr = TRUE;
 	} else {
 		camel_mime_filter_set_size (filter, (len * 2) + 12, FALSE);
 		
-		priv->stream->next_out = filter->outbuf;
+		priv->stream->next_out = (Bytef *)filter->outbuf;
 		priv->stream->avail_out = filter->outsize;
 	}
 	
-	priv->stream->next_in = in;
+	priv->stream->next_in = (Bytef *)in;
 	priv->stream->avail_in = len;
 	
 	do {
@@ -210,7 +210,7 @@
 			n = filter->outsize - priv->stream->avail_out;
 			camel_mime_filter_set_size (filter, n + (priv->stream->avail_in * 2) + 12, TRUE);
 			priv->stream->avail_out = filter->outsize - n;
-			priv->stream->next_out = filter->outbuf + n;
+			priv->stream->next_out = (Bytef *)filter->outbuf + n;
 			
 			if (priv->stream->avail_in == 0) {
 				guint32 val;
@@ -229,13 +229,13 @@
 			}
 		} else {
 			if (priv->stream->avail_in > 0)
-				camel_mime_filter_backup (filter, priv->stream->next_in, priv->stream->avail_in);
+				camel_mime_filter_backup (filter, (const char *)priv->stream->next_in, priv->stream->avail_in);
 			
 			break;
 		}
 	} while (1);
 	
-	priv->crc32 = crc32 (priv->crc32, in, len - priv->stream->avail_in);
+	priv->crc32 = crc32 (priv->crc32, (unsigned char*)in, len - priv->stream->avail_in);
 	priv->isize += len - priv->stream->avail_in;
 	
 	*out = filter->outbuf;
@@ -346,10 +346,10 @@
 	
 	camel_mime_filter_set_size (filter, (len * 2) + 12, FALSE);
 	
-	priv->stream->next_in = in;
+	priv->stream->next_in = (Bytef *)in;
 	priv->stream->avail_in = len - 8;
 	
-	priv->stream->next_out = filter->outbuf;
+	priv->stream->next_out = (Bytef *)filter->outbuf;
 	priv->stream->avail_out = filter->outsize;
 	
 	do {
@@ -368,12 +368,12 @@
 			n = filter->outsize - priv->stream->avail_out;
 			camel_mime_filter_set_size (filter, n + (priv->stream->avail_in * 2) + 12, TRUE);
 			priv->stream->avail_out = filter->outsize - n;
-			priv->stream->next_out = filter->outbuf + n;
+			priv->stream->next_out = (Bytef *)filter->outbuf + n;
 		} else {
 			priv->stream->avail_in += 8;
 			
 			if (priv->stream->avail_in > 0)
-				camel_mime_filter_backup (filter, priv->stream->next_in, priv->stream->avail_in);
+				camel_mime_filter_backup (filter, (char*)priv->stream->next_in, priv->stream->avail_in);
 			
 			break;
 		}
Only in .: camel-mime-filter-gzip.lo
Only in .: camel-mime-filter-gzip.o
Only in .: camel-mime-filter-html.lo
Only in .: camel-mime-filter-html.o
Only in .: camel-mime-filter-index.lo
Only in .: camel-mime-filter-index.o
Only in .: camel-mime-filter-linewrap.lo
Only in .: camel-mime-filter-linewrap.o
Only in .: camel-mime-filter.lo
Only in .: camel-mime-filter.o
Only in .: camel-mime-filter-pgp.lo
Only in .: camel-mime-filter-pgp.o
Only in .: camel-mime-filter-save.lo
Only in .: camel-mime-filter-save.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-mime-filter-tohtml.c ./camel-mime-filter-tohtml.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-mime-filter-tohtml.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-mime-filter-tohtml.c	2007-05-12 10:00:17.000000000 +0200
@@ -60,10 +60,8 @@
 	{ CONVERT_WEB_URLS, { "nntp://",   "",        camel_url_web_start,      camel_url_web_end      } },
 	{ CONVERT_WEB_URLS, { "telnet://", "",        camel_url_web_start,      camel_url_web_end      } },
 	{ CONVERT_WEB_URLS, { "webcal://", "",        camel_url_web_start,      camel_url_web_end      } },
-	{ CONVERT_WEB_URLS, { "mailto:",   "",        camel_url_web_start,      camel_url_web_end      } },
-	{ CONVERT_WEB_URLS, { "callto:",   "",        camel_url_web_start,      camel_url_web_end      } },
-	{ CONVERT_WEB_URLS, { "h323:",     "",        camel_url_web_start,      camel_url_web_end      } },
-	{ CONVERT_WEB_URLS, { "sip:",      "",        camel_url_web_start,      camel_url_web_end      } },
+	{ CONVERT_WEB_URLS, { "callto://", "",        camel_url_web_start,      camel_url_web_end      } },
+	{ CONVERT_WEB_URLS, { "h323://",   "",        camel_url_web_start,      camel_url_web_end      } },
 	{ CONVERT_WEB_URLS, { "www.",      "http://", camel_url_web_start,      camel_url_web_end      } },
 	{ CONVERT_WEB_URLS, { "ftp.",      "ftp://",  camel_url_web_start,      camel_url_web_end      } },
 	{ CONVERT_ADDRSPEC, { "@",         "mailto:", camel_url_addrspec_start, camel_url_addrspec_end } },
Only in .: camel-mime-filter-tohtml.lo
Only in .: camel-mime-filter-tohtml.o
Only in .: camel-mime-filter-windows.lo
Only in .: camel-mime-filter-windows.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-mime-filter-yenc.c ./camel-mime-filter-yenc.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-mime-filter-yenc.c	2007-04-20 13:25:00.000000000 +0200
+++ ./camel-mime-filter-yenc.c	2007-03-11 16:44:11.000000000 +0100
@@ -95,7 +95,7 @@
 	case CAMEL_MIME_FILTER_YENC_DIRECTION_ENCODE:
 		/* won't go to more than 2 * (x + 2) + 62 */
 		camel_mime_filter_set_size (filter, (len + 2) * 2 + 62, FALSE);
-		newlen = camel_yencode_step (in, len, filter->outbuf, &yenc->state,
+		newlen = camel_yencode_step ((const unsigned char *)in, len, (unsigned char*)filter->outbuf, &yenc->state,
 					     &yenc->pcrc, &yenc->crc);
 		g_assert (newlen <= (len + 2) * 2 + 62);
 		break;
@@ -166,7 +166,7 @@
 		if ((yenc->state & CAMEL_MIME_YDECODE_STATE_DECODE) && !(yenc->state & CAMEL_MIME_YDECODE_STATE_END)) {
 			/* all yEnc headers have been found so we can now start decoding */
 			camel_mime_filter_set_size (filter, len + 3, FALSE);
-			newlen = camel_ydecode_step (in, len, filter->outbuf, &yenc->state, &yenc->pcrc, &yenc->crc);
+			newlen = camel_ydecode_step ((const unsigned char *)in, len, (unsigned char*)filter->outbuf, &yenc->state, &yenc->pcrc, &yenc->crc);
 			g_assert (newlen <= len + 3);
 		} else {
 			newlen = 0;
@@ -190,7 +190,7 @@
 	case CAMEL_MIME_FILTER_YENC_DIRECTION_ENCODE:
 		/* won't go to more than 2 * (x + 2) + 62 */
 		camel_mime_filter_set_size (filter, (len + 2) * 2 + 62, FALSE);
-		newlen = camel_yencode_close (in, len, filter->outbuf, &yenc->state,
+		newlen = camel_yencode_close ((const unsigned char *)in, len, (unsigned char*)filter->outbuf, &yenc->state,
 					       &yenc->pcrc, &yenc->crc);
 		g_assert (newlen <= (len + 2) * 2 + 62);
 		break;
@@ -198,7 +198,7 @@
 		if ((yenc->state & CAMEL_MIME_YDECODE_STATE_DECODE) && !(yenc->state & CAMEL_MIME_YDECODE_STATE_END)) {
 			/* all yEnc headers have been found so we can now start decoding */
 			camel_mime_filter_set_size (filter, len + 3, FALSE);
-			newlen = camel_ydecode_step (in, len, filter->outbuf, &yenc->state,
+			newlen = camel_ydecode_step ((const unsigned char *)in, len, (unsigned char*)filter->outbuf, &yenc->state,
 						      &yenc->pcrc, &yenc->crc);
 			g_assert (newlen <= len + 3);
 		} else {
Only in .: camel-mime-filter-yenc.lo
Only in .: camel-mime-filter-yenc.o
Only in .: camel-mime-message.lo
Only in .: camel-mime-message.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-mime-parser.c ./camel-mime-parser.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-mime-parser.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-mime-parser.c	2007-05-12 10:01:18.000000000 +0200
@@ -366,7 +366,7 @@
 		return NULL;
 
 	if (array->len == 0 || array->data[array->len-1] != '\0')
-		g_byte_array_append(array, "", 1);
+		g_byte_array_append(array, (guchar*)"", 1);
 
 	return (const char *) array->data;
 }
@@ -1039,7 +1039,7 @@
 		}
 
 		if (save)
-			g_byte_array_append(save, s->inptr, inptr-s->inptr);
+			g_byte_array_append(save, (guchar*)s->inptr, inptr-s->inptr);
 
 		s->inptr = inptr;
 
@@ -1712,11 +1712,11 @@
 					if (h->prestage > 0) {
 						if (h->posttext == NULL)
 							h->posttext = g_byte_array_new();
-						g_byte_array_append(h->posttext, *databuffer, *datalength);
+						g_byte_array_append(h->posttext, (guchar*) *databuffer, *datalength);
 					} else {
 						if (h->pretext == NULL)
 							h->pretext = g_byte_array_new();
-						g_byte_array_append(h->pretext, *databuffer, *datalength);
+						g_byte_array_append(h->pretext, (guchar*) *databuffer, *datalength);
 					}
 				}
 			} while (hb==h && *datalength>0);
Only in .: camel-mime-parser.lo
Only in .: camel-mime-parser.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-mime-part.c ./camel-mime-part.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-mime-part.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-mime-part.c	2007-05-12 10:01:18.000000000 +0200
@@ -341,7 +341,7 @@
 void
 camel_mime_part_set_description (CamelMimePart *mime_part, const char *description)
 {
-	char *text = camel_header_encode_string (description);
+	char *text = camel_header_encode_string ((const unsigned char*)description);
 	
 	camel_medium_set_header (CAMEL_MEDIUM (mime_part),
 				 "Content-Description", text);
Only in .: camel-mime-part.lo
Only in .: camel-mime-part.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-mime-part-utils.c ./camel-mime-part-utils.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-mime-part-utils.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-mime-part-utils.c	2007-05-12 10:01:18.000000000 +0200
@@ -68,7 +68,7 @@
 	buffer = g_byte_array_new ();
 	while (camel_mime_parser_step (mp, &buf, &len) != CAMEL_MIME_PARSER_STATE_BODY_END) {
 		d(printf("appending o/p data: %d: %.*s\n", len, len, buf));
-		g_byte_array_append (buffer, buf, len);
+		g_byte_array_append (buffer, (guchar*)buf, len);
 	}
 	
 	d(printf("message part kept in memory!\n"));
Only in .: camel-mime-part-utils.lo
Only in .: camel-mime-part-utils.o
Only in .: camel-mime-tables.c
Only in .: camel-mime-tables.lo
Only in .: camel-mime-tables.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-mime-utils.c ./camel-mime-utils.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-mime-utils.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-mime-utils.c	2007-05-12 10:01:12.000000000 +0200
@@ -358,7 +358,7 @@
 	
 	out = g_malloc (len * 4 / 3 + 5);
 	outlen = camel_base64_encode_close ((unsigned char *)data, len, FALSE,
-				      out, &state, &save);
+				      out, &state, (gint*)&save);
 	out[outlen] = '\0';
 	return (char *)out;
 }
@@ -1034,13 +1034,13 @@
 		decword = g_alloca (tmplen); /* this will always be more-than-enough room */
 		switch(toupper(inptr[0])) {
 		case 'Q':
-			inlen = quoted_decode(inptr+2, tmplen, decword);
+			inlen = quoted_decode((const unsigned char *)inptr+2, tmplen, (unsigned char*)decword);
 			break;
 		case 'B': {
 			int state = 0;
 			unsigned int save = 0;
 			
-			inlen = camel_base64_decode_step((char *)inptr+2, tmplen, decword, &state, &save);
+			inlen = camel_base64_decode_step((unsigned char *)inptr+2, tmplen, (unsigned char*)decword, &state, &save);
 			/* if state != 0 then error? */
 			break;
 		}
@@ -1332,7 +1332,7 @@
 			proclen = -1;
 			p = inptr;
 			i = 0;
-			while (p < (in+len) && convlen < (75 - strlen("=?utf-8?q?\?="))) {
+			while (p < (in+len) && convlen < (75 - strlen("=?utf-8?q\?\?="))) {
 				unsigned char c = *p++;
 
 				if (c >= 0xc0)
@@ -1345,7 +1345,7 @@
 				else
 					convlen += 3;
 			}
-			if (proclen >= 0 && proclen < i && convlen < (75 - strlen("=?utf-8?q?\?=")))
+			if (proclen >= 0 && proclen < i && convlen < (75 - strlen("=?utf-8?q\?\?=")))
 				proclen = i;
 			/* well, we probably have broken utf8, just copy it anyway what the heck */
 			if (proclen == -1) {
@@ -1382,7 +1382,7 @@
 			else
 				*out++ = ' ';
 			out += sprintf (out, "=?%s?Q?", type);
-			out += quoted_encode (buffer, enclen, out, safemask);
+			out += quoted_encode ((const unsigned char *)buffer, enclen,  (unsigned char*)out, safemask);
 			sprintf (out, "?=");
 			
 			d(printf("converted part = %s\n", ascii));
@@ -1416,7 +1416,7 @@
 	GString *out;
 	char *outstr;
 
-	g_return_val_if_fail (g_utf8_validate (in, -1, NULL), NULL);
+	g_return_val_if_fail (g_utf8_validate ((const gchar*)in, -1, NULL), NULL);
 	
 	if (in == NULL)
 		return NULL;
@@ -1428,7 +1428,7 @@
 		inptr++;
 	}
 	if (*inptr == '\0')
-		return g_strdup (in);
+		return g_strdup ((gchar*)in);
 	
 	/* This gets each word out of the input, and checks to see what charset
 	   can be used to encode it. */
@@ -1443,7 +1443,7 @@
 		const char *newinptr;
 		
 		newinptr = g_utf8_next_char (inptr);
-		c = g_utf8_get_char (inptr);
+		c = g_utf8_get_char ((char*)inptr);
 		if (newinptr == NULL || !g_unichar_validate (c)) {
 			w(g_warning ("Invalid UTF-8 sequence encountered (pos %d, char '%c'): %s",
 				     (inptr-in), inptr[0], in));
@@ -1455,29 +1455,29 @@
 			/* we've reached the end of a 'word' */
 			if (word && !(last_was_encoded && encoding)) {
 				/* output lwsp between non-encoded words */
-				g_string_append_len (out, start, word - start);
+				g_string_append_len (out, (const gchar*)start, word - start);
 				start = word;
 			}
 			
 			switch (encoding) {
 			case 0:
-				g_string_append_len (out, start, inptr - start);
+				g_string_append_len (out, (const gchar*)start, inptr - start);
 				last_was_encoded = FALSE;
 				break;
 			case 1:
 				if (last_was_encoded)
 					g_string_append_c (out, ' ');
 				
-				rfc2047_encode_word (out, start, inptr - start, "ISO-8859-1", CAMEL_MIME_IS_ESAFE);
+				rfc2047_encode_word (out, (const char *)start, inptr - start, "ISO-8859-1", CAMEL_MIME_IS_ESAFE);
 				last_was_encoded = TRUE;
 				break;
 			case 2:
 				if (last_was_encoded)
 					g_string_append_c (out, ' ');
 				
-				if (!(charset = camel_charset_best (start, inptr - start)))
+				if (!(charset = camel_charset_best ((const char*)start, inptr - start)))
 					charset = "UTF-8";
-				rfc2047_encode_word (out, start, inptr - start, charset, CAMEL_MIME_IS_ESAFE);
+				rfc2047_encode_word (out, (const char *)start, inptr - start, charset, CAMEL_MIME_IS_ESAFE);
 				last_was_encoded = TRUE;
 				break;
 			}
@@ -1499,32 +1499,32 @@
 		if (!(c < 256 && camel_mime_is_lwsp (c)) && !word)
 			word = inptr;
 		
-		inptr = newinptr;
+		inptr = (const unsigned char *)newinptr;
 	}
 	
 	if (inptr - start) {
 		if (word && !(last_was_encoded && encoding)) {
-			g_string_append_len (out, start, word - start);
+			g_string_append_len (out, (const gchar*)start, word - start);
 			start = word;
 		}
 		
 		switch (encoding) {
 		case 0:
-			g_string_append_len (out, start, inptr - start);
+			g_string_append_len (out, (const gchar*)start, inptr - start);
 			break;
 		case 1:
 			if (last_was_encoded)
 				g_string_append_c (out, ' ');
 			
-			rfc2047_encode_word (out, start, inptr - start, "ISO-8859-1", CAMEL_MIME_IS_ESAFE);
+			rfc2047_encode_word (out, (const char *)start, inptr - start, "ISO-8859-1", CAMEL_MIME_IS_ESAFE);
 			break;
 		case 2:
 			if (last_was_encoded)
 				g_string_append_c (out, ' ');
 			
-			if (!(charset = camel_charset_best (start, inptr - start)))
+			if (!(charset = camel_charset_best ( (const char *)start, inptr - start)))
 				charset = "UTF-8";
-			rfc2047_encode_word (out, start, inptr - start, charset, CAMEL_MIME_IS_ESAFE);
+			rfc2047_encode_word (out, (const char *)start, inptr - start, charset, CAMEL_MIME_IS_ESAFE);
 			break;
 		}
 	}
@@ -1603,7 +1603,7 @@
 		const char *newinptr;
 		
 		newinptr = g_utf8_next_char (inptr);
-		c = g_utf8_get_char (inptr);
+		c = g_utf8_get_char ((char*)inptr);
 		
 		if (!g_unichar_validate (c)) {
 			w(g_warning ("Invalid UTF-8 sequence encountered (pos %d, char '%c'): %s",
@@ -1612,7 +1612,7 @@
 			continue;
 		}
 		
-		inptr = newinptr;
+		inptr = (const unsigned char *) newinptr;
 		if (g_unichar_isspace (c)) {
 			if (count > 0) {
 				word = g_new0 (struct _phrase_word, 1);
@@ -1748,28 +1748,28 @@
 		if (last_word && !(last_word->type == WORD_2047 && word->type == WORD_2047)) {
 			/* one or both of the words are not encoded so we write the spaces out untouched */
 			len = word->start - last_word->end;
-			out = g_string_append_len (out, last_word->end, len);
+			out = g_string_append_len (out, (const gchar*) last_word->end, len);
 		}
 		
 		switch (word->type) {
 		case WORD_ATOM:
-			out = g_string_append_len (out, word->start, word->end - word->start);
+			out = g_string_append_len (out, (const gchar*) word->start, word->end - word->start);
 			break;
 		case WORD_QSTRING:
-			quote_word (out, TRUE, word->start, word->end - word->start);
+			quote_word (out, TRUE, (const char *) word->start, word->end - word->start);
 			break;
 		case WORD_2047:
 			if (last_word && last_word->type == WORD_2047) {
 				/* include the whitespace chars between these 2 words in the
                                    resulting rfc2047 encoded word. */
 				len = word->end - last_word->end;
-				start = last_word->end;
+				start = (const char *) last_word->end;
 				
 				/* encoded words need to be separated by linear whitespace */
 				g_string_append_c (out, ' ');
 			} else {
 				len = word->end - word->start;
-				start = word->start;
+				start = (const char *) word->start;
 			}
 			
 			if (word->encoding == 1) {
@@ -1959,11 +1959,12 @@
 static char *
 hex_decode (const char *in, size_t len)
 {
-	const unsigned char *inend = in + len;
+	const unsigned char *inend = (const unsigned char *) (in + len);
 	unsigned char *inptr, *outptr;
 	char *outbuf;
 	
-	outptr = outbuf = g_malloc (len + 1);
+	outbuf = (char*)g_malloc (len + 1);
+	outptr = (unsigned char *)outbuf;
 	
 	inptr = (unsigned char *) in;
 	while (inptr < inend) {
@@ -2210,12 +2211,13 @@
 CamelContentType *
 camel_content_type_new(const char *type, const char *subtype)
 {
-	CamelContentType *t = g_malloc(sizeof(*t));
+	CamelContentType *t = g_slice_new (CamelContentType);
 
 	t->type = g_strdup(type);
 	t->subtype = g_strdup(subtype);
 	t->params = NULL;
 	t->refcount = 1;
+
 	return t;
 }
 
@@ -2248,7 +2250,7 @@
 			camel_header_param_list_free(ct->params);
 			g_free(ct->type);
 			g_free(ct->subtype);
-			g_free(ct);
+			g_slice_free (CamelContentType, ct);
 			ct = NULL;
 		} else {
 			ct->refcount--;
@@ -3217,15 +3219,15 @@
 
 	/* if we have really broken utf8 passed in, we just treat it as binary data */
 
-	charset = camel_charset_best(in, strlen(in));
+	charset = camel_charset_best((char*)in, strlen((char*)in));
 	if (charset == NULL)
-		return g_strdup(in);
+		return g_strdup((gchar*)in);
 	
 	if (g_ascii_strcasecmp(charset, "UTF-8") != 0) {
-		if ((outbuf = header_convert(charset, "UTF-8", in, strlen(in))))
+		if ((outbuf = (unsigned char *)header_convert(charset, "UTF-8", (const char*)in, strlen((char*)in))))
 			inptr = outbuf;
 		else
-			return g_strdup(in);
+			return g_strdup((gchar*)in);
 	}
 	
 	/* FIXME: set the 'language' as well, assuming we can get that info...? */
@@ -3264,7 +3266,7 @@
 			continue;
 		}
 		
-		value = header_encode_param (p->value, &encoded);
+		value = header_encode_param ((unsigned char *)p->value, &encoded);
 		if (!value) {
 			w(g_warning ("appending parameter %s=%s violates rfc2184", p->name, p->value));
 			value = g_strdup (p->value);
@@ -3785,7 +3787,7 @@
 {
 	unsigned char *p;
 
-	p = h->value;
+	p = (unsigned char *)h->value;
 	while (p && *p) {
 		if (!isascii(*p)) {
 			w(g_warning("Appending header violates rfc: %s: %s", h->name, h->value));
@@ -3848,7 +3850,7 @@
 		camel_header_to_decode(value);
 	} else if (!g_ascii_strcasecmp(name, "Content-type")) {
 		printf("- Decoding content-type\n");
-		camel_content_type_dump(camel_content_type_decode(value));		
+		camel_content_type_dump(camel_content_type_decode(value));
 	} else if (!g_ascii_strcasecmp(name, "MIME-Version")) {
 		printf("- Decoding mime version\n");
 		camel_header_mime_decode(value);
@@ -4251,7 +4253,7 @@
 		switch (a->type) {
 		case CAMEL_HEADER_ADDRESS_NAME:
 			if (encode)
-				text = camel_header_encode_phrase (a->name);
+				text = camel_header_encode_phrase ((unsigned char*)a->name);
 			else
 				text = a->name;
 			if (text && *text)
@@ -4263,7 +4265,7 @@
 			break;
 		case CAMEL_HEADER_ADDRESS_GROUP:
 			if (encode)
-				text = camel_header_encode_phrase (a->name);
+				text = camel_header_encode_phrase ((unsigned char*)a->name);
 			else
 				text = a->name;
 			g_string_append_printf (out, "%s: ", text);
Only in .: camel-mime-utils.lo
Only in .: camel-mime-utils.o
Only in .: camel-movemail.lo
Only in .: camel-movemail.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-multipart.c ./camel-multipart.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-multipart.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-multipart.c	2007-05-12 10:01:18.000000000 +0200
@@ -363,12 +363,12 @@
 		bgen = g_strdup_printf ("%p:%lu:%lu", multipart,
 					(unsigned long) getpid(),
 					(unsigned long) time(0));
-		md5_get_digest (bgen, strlen (bgen), digest);
+		md5_get_digest (bgen, strlen ((char*)bgen), (guchar*) digest);
 		g_free (bgen);
 		strcpy (bbuf, "=-");
 		p = bbuf + 2;
 		state = save = 0;
-		p += camel_base64_encode_step (digest, 16, FALSE, p, &state, &save);
+		p += camel_base64_encode_step ((unsigned char *)digest, 16, FALSE, (unsigned char *)p, &state, &save);
 		*p = '\0';
 
 		boundary = bbuf;
Only in .: camel-multipart-encrypted.lo
Only in .: camel-multipart-encrypted.o
Only in .: camel-multipart.lo
Only in .: camel-multipart.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-multipart-signed.c ./camel-multipart-signed.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-multipart-signed.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-multipart-signed.c	2007-05-12 10:01:18.000000000 +0200
@@ -409,7 +409,7 @@
 	if ((mps->content || mps->contentraw) && mps->signature)
 		return 2;
 
-	if (mps->start1 == -1 && parse_content(mps) == -1) {
+	if (mps->start1 == -1 /*&& parse_content(mps) == -1*/) {
 		if (dw->stream == NULL)
 			return 0;
 		else
Only in .: camel-multipart-signed.lo
Only in .: camel-multipart-signed.o
Only in .: camel-net-utils.lo
Only in .: camel-net-utils.o
Only in .: camel-nntp-address.lo
Only in .: camel-nntp-address.o
Only in .: camel.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-object.c ./camel-object.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-object.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-object.c	2007-05-12 10:01:18.000000000 +0200
@@ -44,10 +44,8 @@
 #define h(x) 			/* hooks */
 
 /* I just mashed the keyboard for these... */
-#define CAMEL_OBJECT_MAGIC           	 0x77A344ED
 #define CAMEL_OBJECT_CLASS_MAGIC     	 0xEE26A997
 #define CAMEL_INTERFACE_MAGIC     	 0xBCE137A7
-#define CAMEL_OBJECT_FINALISED_MAGIC       0x84AC365F
 #define CAMEL_OBJECT_CLASS_FINALISED_MAGIC 0x7621ABCD
 #define CAMEL_INTERFACE_FINALISED_MAGIC    0x7CB2FE71
 
@@ -134,11 +132,6 @@
 
 /* ********************************************************************** */
 
-static pthread_mutex_t chunks_lock = PTHREAD_MUTEX_INITIALIZER;
-
-static EMemChunk *pair_chunks;
-static EMemChunk *hook_chunks;
-static unsigned int pair_id = 1;
 
 /* type-lock must be recursive, for atomically creating classes */
 static GStaticRecMutex type_lock = G_STATIC_REC_MUTEX_INIT;
@@ -146,14 +139,11 @@
 static GMutex *ref_lock;
 
 static GHashTable *type_table;
-static EMemChunk *type_chunks;
 
 /* fundamental types are accessed via global */
 CamelType camel_object_type;
 CamelType camel_interface_type;
 
-#define P_LOCK(l) (pthread_mutex_lock(&l))
-#define P_UNLOCK(l) (pthread_mutex_unlock(&l))
 #define CLASS_LOCK(k) (g_mutex_lock((((CamelObjectClass *)k)->lock)))
 #define CLASS_UNLOCK(k) (g_mutex_unlock((((CamelObjectClass *)k)->lock)))
 #define REF_LOCK() (g_mutex_lock(ref_lock))
@@ -164,14 +154,17 @@
 static struct _CamelHookPair *
 pair_alloc(void)
 {
+	static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
+	static guint next_id = 1;
 	CamelHookPair *pair;
 
-	P_LOCK(chunks_lock);
-	pair = e_memchunk_alloc(pair_chunks);
-	pair->id = pair_id++;
-	if (pair_id == 0)
-		pair_id = 1;
-	P_UNLOCK(chunks_lock);
+	pair = g_slice_new(CamelHookPair);
+
+	g_static_mutex_lock(&mutex);
+	pair->id = next_id++;
+	if (next_id == 0)
+		next_id = 1;
+	g_static_mutex_unlock(&mutex);
 
 	return pair;
 }
@@ -179,33 +172,19 @@
 static void
 pair_free(CamelHookPair *pair)
 {
-	g_assert(pair_chunks != NULL);
-
-	P_LOCK(chunks_lock);
-	e_memchunk_free(pair_chunks, pair);
-	P_UNLOCK(chunks_lock);
+	g_slice_free (CamelHookPair, pair);
 }
 
 static struct _CamelHookList *
 hooks_alloc(void)
 {
-	CamelHookList *hooks;
-
-	P_LOCK(chunks_lock);
-	hooks = e_memchunk_alloc(hook_chunks);
-	P_UNLOCK(chunks_lock);
-
-	return hooks;
+	return g_slice_new0 (CamelHookList);
 }
 
 static void
 hooks_free(CamelHookList *hooks)
 {
-	g_assert(hook_chunks != NULL);
-
-	P_LOCK(chunks_lock);
-	e_memchunk_free(hook_chunks, hooks);
-	P_UNLOCK(chunks_lock);
+	g_slice_free (CamelHookList, hooks);
 }
 
 /* not checked locked, who cares, only required for people that want to redefine root objects */
@@ -218,9 +197,6 @@
 		return;
 
 	init = TRUE;
-	pair_chunks = e_memchunk_new(16, sizeof(CamelHookPair));
-	hook_chunks = e_memchunk_new(16, sizeof(CamelHookList));
-	type_chunks = e_memchunk_new(32, sizeof(CamelType));
 	type_table = g_hash_table_new(NULL, NULL);
 	ref_lock = g_mutex_new();
 }
@@ -234,7 +210,6 @@
 cobject_init(CamelObject *o, CamelObjectClass *klass)
 {
 	o->klass = klass;
-	o->magic = CAMEL_OBJECT_MAGIC;
 	o->ref_count = 1;
 	o->flags = 0;
 }
@@ -249,7 +224,6 @@
 
 	camel_object_free_hooks(o);
 
-	o->magic = CAMEL_OBJECT_FINALISED_MAGIC;
 	o->klass = NULL;
 }
 
@@ -474,7 +448,7 @@
 			switch(argv->argv[argv->argc].tag & CAMEL_ARG_TYPE) {
 			case CAMEL_ARG_INT:
 			case CAMEL_ARG_BOO:
-				if (camel_file_util_decode_uint32(fp, &argv->argv[argv->argc].ca_int) == -1)
+				if (camel_file_util_decode_uint32(fp, (guint32*) &argv->argv[argv->argc].ca_int) == -1)
 					goto cleanup;
 				break;
 			case CAMEL_ARG_STR:
@@ -583,7 +557,7 @@
 
 	res = 0;
 abort:
-	for (i=0;i<argv->argc;i++) {
+/*	for (i=0;i<argv->argc;i++) {
 		CamelArg *arg = &argv->argv[i];
 
 		if ((argv->argv[i].tag & CAMEL_ARG_TYPE) == CAMEL_ARG_STR)
@@ -598,7 +572,7 @@
 
 	if (meta)
 		camel_object_free(obj, CAMEL_OBJECT_METADATA, meta);
-
+*/
 	return res;
 }
 
@@ -747,7 +721,7 @@
 
 	size = offset + klass_size;
 
-	klass = g_malloc0(size);
+	klass = g_slice_alloc0(size);
 
 	klass->klass_size = size;
 	klass->klass_data = offset;
@@ -765,12 +739,12 @@
 		return NULL;
 	}
 
-	klass = g_malloc0(klass_size);
+	klass = g_slice_alloc (klass_size);
 	klass->klass_size = klass_size;
 	klass->object_size = object_size;
 	klass->lock = g_mutex_new();
-	klass->instance_chunks = e_memchunk_new(8, object_size);
-	
+	klass->hooks = NULL;
+
 	klass->parent = parent;
 	if (parent) {
 		klass->next = parent->child;
@@ -851,20 +825,17 @@
 
 	CLASS_LOCK(type);
 
-	o = e_memchunk_alloc0(type->instance_chunks);
-
-#ifdef CAMEL_OBJECT_TRACK_INSTANCES
-	if (type->instances)
-		type->instances->prev = o;
-	o->next = type->instances;
-	o->prev = NULL;
-	type->instances = o;
-#endif
+	o = g_slice_alloc0 (type->object_size);
 
 	CLASS_UNLOCK(type);
 
 	camel_object_init(o, type, type);
 
+	if (o->flags & CAMEL_OBJECT_REF_DEBUG)
+	{
+		printf ("An object of the type that you are debugging got created\n");
+	}
+
 	d(printf("%p: new %s()\n", o, o->klass->name));
 
 	return o;
@@ -875,7 +846,14 @@
 {
 	register CamelObject *o = vo;
 
-	g_return_if_fail(CAMEL_IS_OBJECT(o));
+	if (o->ref_count > 0)
+		g_return_if_fail(CAMEL_IS_OBJECT(o));
+
+
+	if (o->flags & CAMEL_OBJECT_REF_DEBUG)
+	{
+		printf ("An object of the type that you are debugging got referenced\n");
+	}
 
 	REF_LOCK();
 
@@ -893,9 +871,13 @@
 	CamelHookList *hooks = NULL;
 
 	g_return_if_fail(CAMEL_IS_OBJECT(o));
-	
 	klass = o->klass;
 
+	if (o->flags & CAMEL_OBJECT_REF_DEBUG)
+	{
+		printf ("An object of the type that you are debugging got unreferenced\n");
+	}
+
 	if (o->hooks)
 		hooks = camel_object_get_hooks(o);
 
@@ -913,6 +895,11 @@
 		return;
 	}
 
+	if (o->flags & CAMEL_OBJECT_REF_DEBUG)
+	{
+		printf ("An object of the type that you are debugging is about to be finalized\n");
+	}
+
 	o->flags |= CAMEL_OBJECT_DESTROY;
 
 	if (hooks)
@@ -932,18 +919,13 @@
 		k = k->parent;
 	}
 
-	o->magic = CAMEL_OBJECT_FINALISED_MAGIC;
-
 	CLASS_LOCK(klass);
-#ifdef CAMEL_OBJECT_TRACK_INSTANCES
-	if (o->prev)
-		o->prev->next = o->next;
-	else
-		klass->instances = o->next;
-	if (o->next)
-		o->next->prev = o->prev;
-#endif
-	e_memchunk_free(klass->instance_chunks, o);
+
+	memset (o, 0, klass->object_size);
+	o->flags |= CAMEL_OBJECT_DESTROYED;
+
+	g_slice_free1 (klass->object_size, o);
+
 	CLASS_UNLOCK(klass);
 }
 
@@ -969,72 +951,17 @@
 	return g_hash_table_lookup(type_table, name);
 }
 
-static char *
-desc_data(CamelObject *o, guint32 ok)
-{
-	char *what;
-
-	if (o == NULL)
-		what = g_strdup("NULL OBJECT");
-	else if (o->magic == ok)
-		what = NULL;
-	else if (o->magic == CAMEL_OBJECT_MAGIC)
-		what = g_strdup_printf("CLASS '%s'", ((CamelObjectClass *)o)->name);
-	else if (o->magic == CAMEL_OBJECT_CLASS_MAGIC)
-		what = g_strdup_printf("CLASS '%s'", ((CamelObjectClass *)o)->name);
-	else if (o->magic == CAMEL_INTERFACE_MAGIC)
-		what = g_strdup_printf("INTERFACE '%s'", ((CamelObjectClass *)o)->name);
-	else if (o->magic == CAMEL_OBJECT_FINALISED_MAGIC)
-		what = g_strdup_printf("finalised OBJECT");
-	else if (o->magic == CAMEL_OBJECT_CLASS_FINALISED_MAGIC)
-		what = g_strdup_printf("finalised CLASS");
-	else if (o->magic == CAMEL_INTERFACE_FINALISED_MAGIC)
-		what = g_strdup_printf("finalised INTERFACE");
-	else 
-		what = g_strdup_printf("junk data");
-
-	return what;
-}
-
-#define check_magic(o, ctype, omagic) \
-	( ((CamelObject *)(o))->magic == (omagic) \
-	&& (ctype)->magic == CAMEL_OBJECT_CLASS_MAGIC) \
-	? 1 : check_magic_fail(o, ctype, omagic)
-
-static gboolean
-check_magic_fail(void *o, CamelType ctype, guint32 omagic)
-{
-	char *what, *to;
-
-	what = desc_data(o, omagic);
-	to = desc_data((CamelObject *)ctype, CAMEL_OBJECT_CLASS_MAGIC);
-
-	if (what || to) {
-		if (what == NULL) {
-			if (omagic == CAMEL_OBJECT_MAGIC)
-				what = g_strdup_printf("OBJECT '%s'", ((CamelObject *)o)->klass->name);
-			else
-				what = g_strdup_printf("OBJECT '%s'", ((CamelObjectClass *)o)->name);
-		}		
-		if (to == NULL)
-			to = g_strdup_printf("OBJECT '%s'", ctype->name);
-		g_warning("Trying to check %s is %s", what, to);
-		g_free(what);
-		g_free(to);
-
-		return FALSE;
-	}
-
-	return TRUE;
-}
 
 gboolean
 camel_object_is(CamelObject *o, CamelType ctype)
 {
 	CamelObjectClass *k;
 
-	g_return_val_if_fail(o != NULL, FALSE);
-	g_return_val_if_fail(check_magic(o, ctype, CAMEL_OBJECT_MAGIC), FALSE);
+	if (o == NULL)
+		return FALSE;
+
+	if (o->flags & CAMEL_OBJECT_DESTROYED)
+		return FALSE;
 
 	k = o->klass;
 	while (k) {
@@ -1050,7 +977,6 @@
 camel_object_class_is(CamelObjectClass *k, CamelType ctype)
 {
 	g_return_val_if_fail(k != NULL, FALSE);
-	g_return_val_if_fail(check_magic(k, ctype, CAMEL_OBJECT_CLASS_MAGIC), FALSE);
 
 	while (k) {
 		if (k == ctype)
@@ -1065,7 +991,6 @@
 camel_interface_is(CamelObjectClass *k, CamelType ctype)
 {
 	g_return_val_if_fail(k != NULL, FALSE);
-	g_return_val_if_fail(check_magic(k, ctype, CAMEL_INTERFACE_MAGIC), FALSE);
 
 	while (k) {
 		if (k == ctype)
@@ -1081,8 +1006,6 @@
 {
 	CamelObjectClass *k;
 
-	g_return_val_if_fail(check_magic(o, ctype, CAMEL_OBJECT_MAGIC), NULL);
-
 	k = o->klass;
 	while (k) {
 		if (k == ctype)
@@ -1100,8 +1023,6 @@
 {
 	CamelObjectClass *r = k;
 
-	g_return_val_if_fail(check_magic(k, ctype, CAMEL_OBJECT_CLASS_MAGIC), NULL);
-
 	while (k) {
 		if (k == ctype)
 			return r;
@@ -1118,8 +1039,6 @@
 {
 	CamelObjectClass *r = k;
 
-	g_return_val_if_fail(check_magic(k, ctype, CAMEL_INTERFACE_MAGIC), NULL);
-
 	while (k) {
 		if (k == ctype)
 			return r;
@@ -1447,7 +1366,8 @@
 	int i, size;
 	const char *prepname;
 
-	g_return_if_fail (CAMEL_IS_OBJECT (obj));
+	if (obj->ref_count > 0)
+		g_return_if_fail (CAMEL_IS_OBJECT (obj));
 	g_return_if_fail (name);
 
 	hook = co_find_pair(obj->klass, name);
@@ -1848,7 +1768,7 @@
 
 	savename = camel_file_util_savename(file);
 	dirname = g_path_get_dirname(savename);
-	g_mkdir_with_parents(dirname, 0777);
+	e_util_mkdir_hier(dirname, 0777);
 	g_free(dirname);
 	fp = g_fopen(savename, "wb");
 	if (fp != NULL) {
@@ -1899,9 +1819,6 @@
 object_class_dump_tree_rec(CamelType root, int depth)
 {
 	char *p;
-#ifdef CAMEL_OBJECT_TRACK_INSTANCES
-	struct _CamelObject *o;
-#endif
 
 	p = alloca(depth*2+1);
 	memset(p, ' ', depth*2);
@@ -1919,22 +1836,7 @@
 				pair = pair->next;
 			}
 		}
-#ifdef CAMEL_OBJECT_TRACK_INSTANCES
-		o = root->instances;
-		while (o) {
-			printf("%s instance %p [%d]\n", p, o, o->ref_count);
-			/* todo: should lock hooks while it scans them */
-			if (o->hooks) {
-				CamelHookPair *pair = o->hooks->list;
-
-				while (pair) {
-					printf("%s  hook '%s' func %p data %p\n", p, pair->name, pair->func.event, pair->data);
-					pair = pair->next;
-				}
-			}
-			o = o->next;
-		}
-#endif
+
 		CLASS_UNLOCK(root);
 
 		if (root->child)
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-object.h ./camel-object.h
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-object.h	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-object.h	2007-05-12 10:01:18.000000000 +0200
@@ -34,9 +34,6 @@
 #include <camel/camel-arg.h>
 #include <camel/camel-types.h>	/* this is a @##$@#SF stupid header */
 
-/* turn on so that camel_object_class_dump_tree() dumps object instances as well */
-#define CAMEL_OBJECT_TRACK_INSTANCES
-
 G_BEGIN_DECLS
 
 typedef struct _CamelObjectClass *CamelType;
@@ -104,6 +101,8 @@
 
 typedef enum _CamelObjectFlags {
 	CAMEL_OBJECT_DESTROY = (1<<0),
+	CAMEL_OBJECT_DESTROYED = (1<<1),
+	CAMEL_OBJECT_REF_DEBUG = (1<<2),
 } CamelObjectFlags;
 
 /* returned by get::CAMEL_OBJECT_METADATA */
@@ -118,17 +117,11 @@
 struct _CamelObject {
 	struct _CamelObjectClass *klass;
 
-	guint32 magic;		/* only really needed for debugging ... */
-
 	/* current hooks on this object */
 	struct _CamelHookList *hooks;
 
 	guint32 ref_count:24;
 	guint32 flags:8;
-
-#ifdef CAMEL_OBJECT_TRACK_INSTANCES
-	struct _CamelObject *next, *prev;
-#endif
 };
 
 struct _CamelObjectClass
@@ -152,12 +145,6 @@
 	/* available hooks for this class */
 	struct _CamelHookPair *hooks;
 
-	/* memchunks for this type */
-	struct _EMemChunk *instance_chunks;
-#ifdef CAMEL_OBJECT_TRACK_INSTANCES
-	struct _CamelObject *instances;
-#endif
-
 	/* init class */
 	void (*klass_init)(struct _CamelObjectClass *);
 	void (*klass_finalise)(struct _CamelObjectClass *);
Only in .: camel-object.lo
Only in .: camel-object.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-offline-folder.c ./camel-offline-folder.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-offline-folder.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-offline-folder.c	2007-05-12 10:01:18.000000000 +0200
@@ -112,10 +112,11 @@
 	
 	if (m->changes) {
 		for (i = 0; i < m->changes->uid_added->len; i++) {
-			int pc = i * 100 / m->changes->uid_added->len;
 			
-			camel_operation_progress (NULL, pc);
-			if ((message = camel_folder_get_message (m->folder, m->changes->uid_added->pdata[i], &mm->ex)))
+			camel_operation_progress (NULL, i, m->changes->uid_added->len);
+			/* TNY: Partial message retrieval here is always body only */
+			/* TODO: Maybe detect what the original message was, if there was a message? */
+			if ((message = camel_folder_get_message (m->folder, m->changes->uid_added->pdata[i], CAMEL_FOLDER_RECEIVE_PARTIAL, -1, &mm->ex)))
 				camel_object_unref (message);
 		}
 	} else {
@@ -264,10 +265,11 @@
 	}
 	
 	for (i = 0; i < uids->len; i++) {
-		int pc = i * 100 / uids->len;
 		
-		message = camel_folder_get_message (folder, uids->pdata[i], ex);
-		camel_operation_progress (NULL, pc);
+		/* TNY: Partial message retrieval here is always body only */
+		/* TODO: Maybe detect what the original message was, if there was a message? */		
+		message = camel_folder_get_message (folder, uids->pdata[i], CAMEL_FOLDER_RECEIVE_PARTIAL, -1, ex);
+		camel_operation_progress (NULL, i, uids->len);
 		if (message == NULL)
 			break;
 		
Only in .: camel-offline-folder.lo
Only in .: camel-offline-folder.o
Only in .: camel-offline-journal.lo
Only in .: camel-offline-journal.o
Only in .: camel-offline-store.lo
Only in .: camel-offline-store.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-operation.c ./camel-operation.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-operation.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-operation.c	2007-05-12 10:01:18.000000000 +0200
@@ -46,7 +46,7 @@
 struct _status_stack {
 	guint32 flags;
 	char *msg;
-	int pc;				/* last pc reported */
+	int sofar, oftotal;
 	unsigned int stamp;		/* last stamp reported */
 };
 
@@ -514,12 +514,14 @@
 	s = g_malloc0(sizeof(*s));
 	s->msg = msg;
 	s->flags = 0;
+	s->sofar = 0;
+	s->oftotal = 100;
 	cc->lastreport = s;
 	cc->status_stack = g_slist_prepend(cc->status_stack, s);
 
 	UNLOCK();
 
-	cc->status(cc, msg, CAMEL_OPERATION_START, cc->status_data);
+	cc->status(cc, msg, CAMEL_OPERATION_START, 100, cc->status_data);
 
 	d(printf("start '%s'\n", msg, pc));
 }
@@ -578,17 +580,17 @@
 /**
  * camel_operation_progress:
  * @cc: Operation to report to.
- * @pc: Percent complete, 0 to 100.
+ * @sofar: Amount complete
+ * @oftotal: Max amount (or, amount when completed)
  * 
  * Report progress on the current operation.  If @cc is NULL, then the
- * currently registered operation is used.  @pc reports the current
- * percentage of completion, which should be in the range of 0 to 100.
+ * currently registered operation is used.  @
  *
  * If the total percentage is not know, then use
  * camel_operation_progress_count().
  **/
 void
-camel_operation_progress (CamelOperation *cc, int pc)
+camel_operation_progress (CamelOperation *cc, int sofar, int oftotal)
 {
 	unsigned int now;
 	struct _status_stack *s;
@@ -608,7 +610,8 @@
 	}
 
 	s = cc->status_stack->data;
-	s->pc = pc;
+	s->sofar = sofar;
+	s->oftotal = oftotal;
 
 	/* Transient messages dont start updating till 4 seconds after
 	   they started, then they update every second */
@@ -632,7 +635,7 @@
 	UNLOCK();
 
 	if (cc) {
-		cc->status(cc, msg, pc, cc->status_data);
+		cc->status(cc, msg, sofar, oftotal, cc->status_data);
 		g_free(msg);
 	}
 }
@@ -646,7 +649,7 @@
 void
 camel_operation_progress_count (CamelOperation *cc, int sofar)
 {
-	camel_operation_progress(cc, sofar);
+	camel_operation_progress(cc, sofar, 100);
 }
 
 /**
@@ -664,7 +667,8 @@
 	struct _status_stack *s, *p;
 	unsigned int now;
 	char *msg = NULL;
-	int pc = 0;
+	int sofar = 0;
+	int oftotal = 100;
 
 	if (cc == NULL)
 		cc = co_getcc();
@@ -693,13 +697,15 @@
 				if (p->flags & CAMEL_OPERATION_TRANSIENT) {
 					if (p->stamp + CAMEL_OPERATION_TRANSIENT_DELAY < now) {
 						msg = g_strdup(p->msg);
-						pc = p->pc;
+						sofar = p->sofar;
+						oftotal = p->oftotal;
 						cc->lastreport = p;
 						break;
 					}
 				} else {
 					msg = g_strdup(p->msg);
-					pc = p->pc;
+					sofar = p->sofar;
+					oftotal = p->oftotal;
 					cc->lastreport = p;
 					break;
 				}
@@ -709,7 +715,8 @@
 		g_free(s->msg);
 	} else {
 		msg = s->msg;
-		pc = CAMEL_OPERATION_END;
+		sofar = CAMEL_OPERATION_END;
+		oftotal = 100;
 		cc->lastreport = s;
 	}
 	g_free(s);
@@ -718,7 +725,7 @@
 	UNLOCK();
 
 	if (msg) {
-		cc->status(cc, msg, pc, cc->status_data);
+		cc->status(cc, msg, sofar, oftotal, cc->status_data);
 		g_free(msg);
 	}
 }
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-operation.h ./camel-operation.h
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-operation.h	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-operation.h	2007-05-12 10:01:18.000000000 +0200
@@ -28,7 +28,7 @@
 
 typedef struct _CamelOperation CamelOperation;
 
-typedef void (*CamelOperationStatusFunc)(struct _CamelOperation *op, const char *what, int pc, void *data);
+typedef void (*CamelOperationStatusFunc)(struct _CamelOperation *op, const char *what, int sofar, int oftotal, void *data);
 
 typedef enum _camel_operation_status_t {
 	CAMEL_OPERATION_START = -1,
@@ -59,7 +59,7 @@
 
 void camel_operation_start(CamelOperation *cc, char *what, ...);
 void camel_operation_start_transient(CamelOperation *cc, char *what, ...);
-void camel_operation_progress(CamelOperation *cc, int pc);
+void camel_operation_progress(CamelOperation *cc, int sofar, int oftotal);
 void camel_operation_progress_count(CamelOperation *cc, int sofar);
 void camel_operation_end(CamelOperation *cc);
 
Only in .: camel-operation.lo
Only in .: camel-operation.o
Only in .: camel-partition-table.lo
Only in .: camel-partition-table.o
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/: camel.pc.in
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-private.h ./camel-private.h
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-private.h	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-private.h	2007-05-12 10:01:18.000000000 +0200
@@ -84,6 +84,8 @@
 	(g_static_rec_mutex_lock(&((CamelService *)f)->priv->l))
 #define CAMEL_SERVICE_REC_UNLOCK(f, l) \
 	(g_static_rec_mutex_unlock(&((CamelService *)f)->priv->l))
+#define CAMEL_SERVICE_REC_TRYLOCK(f, l) \
+	(g_static_rec_mutex_trylock(&((CamelService *)f)->priv->l))
 
 
 struct _CamelSessionPrivate {
@@ -114,12 +116,9 @@
 
 	struct _CamelStreamFilter *filter_stream;
 
-	struct _CamelIndex *index;
-	
 	GMutex *summary_lock;	/* for the summary hashtable/array */
 	GMutex *io_lock;	/* load/save lock, for access to saved_count, etc */
 	GMutex *filter_lock;	/* for accessing any of the filtering/indexing stuff, since we share them */
-	GMutex *alloc_lock;	/* for setting up and using allocators */
 	GMutex *ref_lock;	/* for reffing/unreffing messageinfo's ALWAYS obtain before summary_lock */
 };
 
@@ -130,7 +129,6 @@
 struct _CamelStoreSummaryPrivate {
 	GMutex *summary_lock;	/* for the summary hashtable/array */
 	GMutex *io_lock;	/* load/save lock, for access to saved_count, etc */
-	GMutex *alloc_lock;	/* for setting up and using allocators */
 	GMutex *ref_lock;	/* for reffing/unreffing messageinfo's ALWAYS obtain before summary_lock */
 };
 
@@ -163,13 +161,19 @@
 struct _CamelCertDBPrivate {
 	GMutex *db_lock;	/* for the db hashtable/array */
 	GMutex *io_lock;	/* load/save lock, for access to saved_count, etc */
-	GMutex *alloc_lock;	/* for setting up and using allocators */
 	GMutex *ref_lock;	/* for reffing/unreffing certs */
 };
 
 #define CAMEL_CERTDB_LOCK(db, l) (g_mutex_lock (((CamelCertDB *) db)->priv->l))
 #define CAMEL_CERTDB_UNLOCK(db, l) (g_mutex_unlock (((CamelCertDB *) db)->priv->l))
 
+#if !GLIB_CHECK_VERSION(2,8,0)
+#define g_access access
+#define g_chmod chmod
+#define g_creat creat
+#define g_chdir chdir
+#endif
+
 #ifdef G_OS_WIN32
 int fsync (int fd);
 
@@ -177,8 +181,8 @@
 const char *_camel_get_libexecdir (void) G_GNUC_CONST;
 const char *_camel_get_providerdir (void) G_GNUC_CONST;
 
-#undef EVOLUTION_LOCALEDIR
-#define EVOLUTION_LOCALEDIR _camel_get_localedir ()
+#undef LOCALEDIR
+#define LOCALEDIR _camel_get_localedir ()
 
 #undef CAMEL_LIBEXECDIR
 #define CAMEL_LIBEXECDIR _camel_get_libexecdir ()
Only in .: camel-provider.lo
Only in .: camel-provider.o
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/: camel-provider.pc.in
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-sasl-anonymous.c ./camel-sasl-anonymous.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-sasl-anonymous.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-sasl-anonymous.c	2007-05-12 10:01:18.000000000 +0200
@@ -137,7 +137,7 @@
 		}
 		camel_object_unref (cia);
 		ret = g_byte_array_new ();
-		g_byte_array_append (ret, sasl_anon->trace_info, strlen (sasl_anon->trace_info));
+		g_byte_array_append (ret, (const guchar*)sasl_anon->trace_info, strlen (sasl_anon->trace_info));
 		break;
 	case CAMEL_SASL_ANON_TRACE_OPAQUE:
 		if (strchr (sasl_anon->trace_info, '@')) {
@@ -147,7 +147,7 @@
 			return NULL;
 		}
 		ret = g_byte_array_new ();
-		g_byte_array_append (ret, sasl_anon->trace_info, strlen (sasl_anon->trace_info));
+		g_byte_array_append (ret, (const guchar*)sasl_anon->trace_info, strlen (sasl_anon->trace_info));
 		break;
 	case CAMEL_SASL_ANON_TRACE_EMPTY:
 		ret = g_byte_array_new ();
Only in .: camel-sasl-anonymous.lo
Only in .: camel-sasl-anonymous.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-sasl.c ./camel-sasl.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-sasl.c	2007-04-20 13:25:00.000000000 +0200
+++ ./camel-sasl.c	2007-03-11 16:44:11.000000000 +0100
@@ -138,8 +138,8 @@
 	if (token) {
 		token_binary = g_byte_array_new ();
 		len = strlen (token);
-		g_byte_array_append (token_binary, token, len);
-		token_binary->len = camel_base64_decode_simple (token_binary->data, len);
+		g_byte_array_append (token_binary, (guchar *) token, len);
+		token_binary->len = camel_base64_decode_simple ((char *) token_binary->data, len);
 	} else
 		token_binary = NULL;
 	
@@ -149,7 +149,7 @@
 	if (!ret_binary)
 		return NULL;
 	
-	ret = camel_base64_encode_simple (ret_binary->data, ret_binary->len);
+	ret = camel_base64_encode_simple ((const char *) ret_binary->data, ret_binary->len);
 	g_byte_array_free (ret_binary, TRUE);
 
 	return ret;
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-sasl-cram-md5.c ./camel-sasl-cram-md5.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-sasl-cram-md5.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-sasl-cram-md5.c	2007-05-12 10:01:18.000000000 +0200
@@ -134,11 +134,11 @@
 	
 	/* lowercase hexify that bad-boy... */
 	for (s = digest, p = md5asc; p < md5asc + 32; s++, p += 2)
-		sprintf (p, "%.2x", *s);
+		sprintf ((char*)p, "%.2x", *s);
 	
 	ret = g_byte_array_new ();
-	g_byte_array_append (ret, sasl->service->url->user, strlen (sasl->service->url->user));
-	g_byte_array_append (ret, " ", 1);
+	g_byte_array_append (ret, (const guchar*)sasl->service->url->user, strlen (sasl->service->url->user));
+	g_byte_array_append (ret, (const guchar*)" ", 1);
 	g_byte_array_append (ret, md5asc, 32);
 	
 	sasl->authenticated = TRUE;
Only in .: camel-sasl-cram-md5.lo
Only in .: camel-sasl-cram-md5.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-sasl-digest-md5.c ./camel-sasl-digest-md5.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-sasl-digest-md5.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-sasl-digest-md5.c	2007-05-12 10:01:18.000000000 +0200
@@ -546,7 +546,7 @@
 	
 	/* lowercase hexify that bad-boy... */
 	for (s = digest, p = hex; p < hex + 32; s++, p += 2)
-		sprintf (p, "%.2x", *s);
+		sprintf ((char *) p, "%.2x", *s);
 }
 
 static char *
@@ -568,22 +568,22 @@
 	
 	/* compute A1 */
 	md5_init (&ctx);
-	md5_update (&ctx, resp->username, strlen (resp->username));
-	md5_update (&ctx, ":", 1);
-	md5_update (&ctx, resp->realm, strlen (resp->realm));
-	md5_update (&ctx, ":", 1);
-	md5_update (&ctx, passwd, strlen (passwd));
+	md5_update (&ctx, (const guchar*) resp->username, strlen (resp->username));
+	md5_update (&ctx, (const guchar*) ":", 1);
+	md5_update (&ctx, (const guchar*) resp->realm, strlen (resp->realm));
+	md5_update (&ctx, (const guchar*) ":", 1);
+	md5_update (&ctx, (const guchar*) passwd, strlen (passwd));
 	md5_final (&ctx, digest);
 	
 	md5_init (&ctx);
 	md5_update (&ctx, digest, 16);
-	md5_update (&ctx, ":", 1);
-	md5_update (&ctx, resp->nonce, strlen (resp->nonce));
-	md5_update (&ctx, ":", 1);
-	md5_update (&ctx, resp->cnonce, strlen (resp->cnonce));
+	md5_update (&ctx, (const guchar*) ":", 1);
+	md5_update (&ctx, (const guchar*) resp->nonce, strlen (resp->nonce));
+	md5_update (&ctx, (const guchar*) ":", 1);
+	md5_update (&ctx, (const guchar*) resp->cnonce, strlen (resp->cnonce));
 	if (resp->authzid) {
-		md5_update (&ctx, ":", 1);
-		md5_update (&ctx, resp->authzid, strlen (resp->authzid));
+		md5_update (&ctx, (const guchar*) ":", 1);
+		md5_update (&ctx, (const guchar*) resp->authzid, strlen (resp->authzid));
 	}
 	
 	/* hexify A1 */
@@ -594,18 +594,18 @@
 	md5_init (&ctx);
 	if (client) {
 		/* we are calculating the client response */
-		md5_update (&ctx, "AUTHENTICATE:", strlen ("AUTHENTICATE:"));
+		md5_update (&ctx, (const guchar*) "AUTHENTICATE:", strlen ("AUTHENTICATE:"));
 	} else {
 		/* we are calculating the server rspauth */
-		md5_update (&ctx, ":", 1);
+		md5_update (&ctx, (const guchar*) ":", 1);
 	}
 	
 	buf = digest_uri_to_string (resp->uri);
-	md5_update (&ctx, buf, strlen (buf));
+	md5_update (&ctx, (const guchar*) buf, strlen (buf));
 	g_free (buf);
 	
 	if (resp->qop == QOP_AUTH_INT || resp->qop == QOP_AUTH_CONF)
-		md5_update (&ctx, ":00000000000000000000000000000000", 33);
+		md5_update (&ctx, (const guchar*) ":00000000000000000000000000000000", 33);
 	
 	/* now hexify A2 */
 	md5_final (&ctx, digest);
@@ -613,17 +613,17 @@
 	
 	/* compute KD */
 	md5_init (&ctx);
-	md5_update (&ctx, hex_a1, 32);
-	md5_update (&ctx, ":", 1);
-	md5_update (&ctx, resp->nonce, strlen (resp->nonce));
-	md5_update (&ctx, ":", 1);
-	md5_update (&ctx, resp->nc, 8);
-	md5_update (&ctx, ":", 1);
-	md5_update (&ctx, resp->cnonce, strlen (resp->cnonce));
-	md5_update (&ctx, ":", 1);
-	md5_update (&ctx, qop_to_string (resp->qop), strlen (qop_to_string (resp->qop)));
-	md5_update (&ctx, ":", 1);
-	md5_update (&ctx, hex_a2, 32);
+	md5_update (&ctx, (const guchar*) hex_a1, 32);
+	md5_update (&ctx, (const guchar*) ":", 1);
+	md5_update (&ctx, (const guchar*) resp->nonce, strlen (resp->nonce));
+	md5_update (&ctx, (const guchar*) ":", 1);
+	md5_update (&ctx, (const guchar*) resp->nc, 8);
+	md5_update (&ctx, (const guchar*) ":", 1);
+	md5_update (&ctx, (const guchar*) resp->cnonce, strlen (resp->cnonce));
+	md5_update (&ctx, (const guchar*) ":", 1);
+	md5_update (&ctx,(const guchar*)  qop_to_string (resp->qop), strlen (qop_to_string (resp->qop)));
+	md5_update (&ctx, (const guchar*) ":", 1);
+	md5_update (&ctx, (const guchar*) hex_a2, 32);
 	md5_final (&ctx, digest);
 	
 	digest_hex (digest, out);
@@ -651,7 +651,7 @@
 	bgen = g_strdup_printf ("%p:%lu:%lu", resp,
 				(unsigned long) getpid (),
 				(unsigned long) time (0));
-	md5_get_digest (bgen, strlen (bgen), digest);
+	md5_get_digest (bgen, strlen (bgen), (guchar*) digest);
 	g_free (bgen);
 	/* take our recommended 64 bits of entropy */
 	resp->cnonce = camel_base64_encode_simple (digest, 8);
@@ -688,7 +688,7 @@
 	/* we don't really care about this... */
 	resp->authzid = NULL;
 	
-	compute_response (resp, passwd, TRUE, resp->resp);
+	compute_response (resp, passwd, TRUE, (guchar*) resp->resp);
 	
 	return resp;
 }
@@ -701,7 +701,7 @@
 	char *buf;
 	
 	buffer = g_byte_array_new ();
-	g_byte_array_append (buffer, "username=\"", 10);
+	g_byte_array_append (buffer, (guchar*) "username=\"", 10);
 	if (resp->charset) {
 		/* Encode the username using the requested charset */
 		char *username, *outbuf;
@@ -734,61 +734,61 @@
 		if (cd != (iconv_t) -1)
 			e_iconv_close (cd);
 		
-		g_byte_array_append (buffer, username, strlen (username));
+		g_byte_array_append (buffer, (guchar *) username, strlen (username));
 		g_free (username);
 	} else {
-		g_byte_array_append (buffer, resp->username, strlen (resp->username));
+		g_byte_array_append (buffer, (guchar *) resp->username, strlen (resp->username));
 	}
 	
-	g_byte_array_append (buffer, "\",realm=\"", 9);
-	g_byte_array_append (buffer, resp->realm, strlen (resp->realm));
+	g_byte_array_append (buffer, (guchar *) "\",realm=\"", 9);
+	g_byte_array_append (buffer,(guchar *)  resp->realm, strlen (resp->realm));
 	
-	g_byte_array_append (buffer, "\",nonce=\"", 9);
-	g_byte_array_append (buffer, resp->nonce, strlen (resp->nonce));
+	g_byte_array_append (buffer, (guchar *) "\",nonce=\"", 9);
+	g_byte_array_append (buffer, (guchar *) resp->nonce, strlen (resp->nonce));
 	
-	g_byte_array_append (buffer, "\",cnonce=\"", 10);
-	g_byte_array_append (buffer, resp->cnonce, strlen (resp->cnonce));
+	g_byte_array_append (buffer, (guchar *) "\",cnonce=\"", 10);
+	g_byte_array_append (buffer, (guchar *) resp->cnonce, strlen (resp->cnonce));
 	
-	g_byte_array_append (buffer, "\",nc=", 5);
-	g_byte_array_append (buffer, resp->nc, 8);
+	g_byte_array_append (buffer, (guchar *) "\",nc=", 5);
+	g_byte_array_append (buffer,(guchar *)  resp->nc, 8);
 	
-	g_byte_array_append (buffer, ",qop=", 5);
+	g_byte_array_append (buffer, (guchar *) ",qop=", 5);
 	str = qop_to_string (resp->qop);
-	g_byte_array_append (buffer, str, strlen (str));
+	g_byte_array_append (buffer, (guchar *) str, strlen (str));
 	
-	g_byte_array_append (buffer, ",digest-uri=\"", 13);
+	g_byte_array_append (buffer, (guchar *) ",digest-uri=\"", 13);
 	buf = digest_uri_to_string (resp->uri);
-	g_byte_array_append (buffer, buf, strlen (buf));
+	g_byte_array_append (buffer, (guchar *) buf, strlen (buf));
 	g_free (buf);
 	
-	g_byte_array_append (buffer, "\",response=", 11);
-	g_byte_array_append (buffer, resp->resp, 32);
+	g_byte_array_append (buffer, (guchar *) "\",response=", 11);
+	g_byte_array_append (buffer, (guchar *) resp->resp, 32);
 	
 	if (resp->maxbuf > 0) {
-		g_byte_array_append (buffer, ",maxbuf=", 8);
+		g_byte_array_append (buffer, (guchar *) ",maxbuf=", 8);
 		buf = g_strdup_printf ("%u", resp->maxbuf);
-		g_byte_array_append (buffer, buf, strlen (buf));
+		g_byte_array_append (buffer, (guchar *) buf, strlen (buf));
 		g_free (buf);
 	}
 	
 	if (resp->charset) {
-		g_byte_array_append (buffer, ",charset=", 9);
-		g_byte_array_append (buffer, resp->charset, strlen (resp->charset));
+		g_byte_array_append (buffer, (guchar *) ",charset=", 9);
+		g_byte_array_append (buffer, (guchar *) resp->charset, strlen ((char *) resp->charset));
 	}
 	
 	if (resp->cipher != CIPHER_INVALID) {
 		str = cipher_to_string (resp->cipher);
 		if (str) {
-			g_byte_array_append (buffer, ",cipher=\"", 9);
-			g_byte_array_append (buffer, str, strlen (str));
-			g_byte_array_append (buffer, "\"", 1);
+			g_byte_array_append (buffer, (guchar *) ",cipher=\"", 9);
+			g_byte_array_append (buffer, (guchar *) str, strlen (str));
+			g_byte_array_append (buffer, (guchar *) "\"", 1);
 		}
 	}
 	
 	if (resp->authzid) {
-		g_byte_array_append (buffer, ",authzid=\"", 10);
-		g_byte_array_append (buffer, resp->authzid, strlen (resp->authzid));
-		g_byte_array_append (buffer, "\"", 1);
+		g_byte_array_append (buffer, (guchar *) ",authzid=\"", 10);
+		g_byte_array_append (buffer, (guchar *) resp->authzid, strlen (resp->authzid));
+		g_byte_array_append (buffer, (guchar *) "\"", 1);
 	}
 	
 	return buffer;
@@ -821,7 +821,7 @@
 			return NULL;
 		}
 		
-		tokens = g_strndup (token->data, token->len);
+		tokens = g_strndup ((gchar *) token->data, token->len);
 		priv->challenge = parse_server_challenge (tokens, &abort);
 		g_free (tokens);
 		if (!priv->challenge || abort) {
@@ -855,7 +855,7 @@
 		break;
 	case STATE_FINAL:
 		if (token->len)
-			tokens = g_strndup (token->data, token->len);
+			tokens = g_strndup ((gchar *) token->data, token->len);
 		else
 			tokens = NULL;
 		
Only in .: camel-sasl-digest-md5.lo
Only in .: camel-sasl-digest-md5.o
Only in .: camel-sasl-gssapi.lo
Only in .: camel-sasl-gssapi.o
Only in .: camel-sasl-kerberos4.lo
Only in .: camel-sasl-kerberos4.o
Only in .: camel-sasl.lo
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-sasl-login.c ./camel-sasl-login.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-sasl-login.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-sasl-login.c	2007-05-12 10:01:18.000000000 +0200
@@ -121,11 +121,11 @@
 	switch (priv->state) {
 	case LOGIN_USER:
 		buf = g_byte_array_new ();
-		g_byte_array_append (buf, url->user, strlen (url->user));
+		g_byte_array_append (buf, (guchar *) url->user, strlen (url->user));
 		break;
 	case LOGIN_PASSWD:
 		buf = g_byte_array_new ();
-		g_byte_array_append (buf, url->passwd, strlen (url->passwd));
+		g_byte_array_append (buf, (guchar *) url->passwd, strlen (url->passwd));
 		
 		sasl->authenticated = TRUE;
 		break;
Only in .: camel-sasl-login.lo
Only in .: camel-sasl-login.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-sasl-ntlm.c ./camel-sasl-ntlm.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-sasl-ntlm.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-sasl-ntlm.c	2007-05-12 10:01:18.000000000 +0200
@@ -105,15 +105,15 @@
 	ret = g_byte_array_new ();
 
 	if (!token || !token->len) {
-		g_byte_array_append (ret, NTLM_REQUEST,
+		g_byte_array_append (ret, (guchar *) NTLM_REQUEST,
 				     sizeof (NTLM_REQUEST) - 1);
 		return ret;
 	}
 
 	memcpy (nonce, token->data + NTLM_CHALLENGE_NONCE_OFFSET, 8);
-	ntlm_lanmanager_hash (sasl->service->url->passwd, hash);
+	ntlm_lanmanager_hash (sasl->service->url->passwd, (char *) hash);
 	ntlm_calc_response (hash, nonce, lm_resp);
-	ntlm_nt_hash (sasl->service->url->passwd, hash);
+	ntlm_nt_hash (sasl->service->url->passwd, (char *) hash);
 	ntlm_calc_response (hash, nonce, nt_resp);
 
 	ret = g_byte_array_new ();
@@ -125,17 +125,17 @@
 		NTLM_RESPONSE_FLAGS, sizeof (NTLM_RESPONSE_FLAGS) - 1);
 
 	ntlm_set_string (ret, NTLM_RESPONSE_DOMAIN_OFFSET,
-			 token->data + NTLM_CHALLENGE_DOMAIN_OFFSET,
-			 atoi (token->data + NTLM_CHALLENGE_DOMAIN_LEN_OFFSET));
+			 (const char *) token->data + NTLM_CHALLENGE_DOMAIN_OFFSET,
+			 atoi ((char *) token->data + NTLM_CHALLENGE_DOMAIN_LEN_OFFSET));
 	ntlm_set_string (ret, NTLM_RESPONSE_USER_OFFSET,
 			 sasl->service->url->user,
 			 strlen (sasl->service->url->user));
 	ntlm_set_string (ret, NTLM_RESPONSE_HOST_OFFSET,
 			 "UNKNOWN", sizeof ("UNKNOWN") - 1);
 	ntlm_set_string (ret, NTLM_RESPONSE_LM_RESP_OFFSET,
-			 lm_resp, sizeof (lm_resp));
+			 (const char *) lm_resp, sizeof (lm_resp));
 	ntlm_set_string (ret, NTLM_RESPONSE_NT_RESP_OFFSET,
-			 nt_resp, sizeof (nt_resp));
+			 (const char *) nt_resp, sizeof (nt_resp));
 
 	sasl->authenticated = TRUE;
 	return ret;
@@ -177,10 +177,10 @@
 	memcpy (hash, LM_PASSWORD_MAGIC, 21);
 
 	setup_schedule (lm_password, ks);
-	des (ks, hash);
+	des (ks, (unsigned char *) hash);
 
 	setup_schedule (lm_password + 7, ks);
-	des (ks, hash + 8);
+	des (ks, (unsigned char *) hash + 8);
 }
 
 static void
@@ -195,7 +195,7 @@
 		*p++ = '\0';
 	}
 
-	md4sum (buf, p - buf, hash);
+	md4sum (buf, p - buf, ( unsigned char *) hash);
 	memset (hash + 16, 0, 5);
 
 	g_free (buf);
@@ -208,7 +208,7 @@
 	ba->data[offset + 1] = ba->data[offset + 3] = (len >> 8) & 0xFF;
 	ba->data[offset + 4] =  ba->len       & 0xFF;
 	ba->data[offset + 5] = (ba->len >> 8) & 0xFF;
-	g_byte_array_append (ba, data, len);
+	g_byte_array_append (ba, (guchar *) data, len);
 }
 
 
Only in .: camel-sasl-ntlm.lo
Only in .: camel-sasl-ntlm.o
Only in .: camel-sasl.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-sasl-plain.c ./camel-sasl-plain.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-sasl-plain.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-sasl-plain.c	2007-05-12 10:01:18.000000000 +0200
@@ -97,10 +97,10 @@
 	
 	/* FIXME: make sure these are "UTF8-SAFE" */
 	buf = g_byte_array_new ();
-	g_byte_array_append (buf, "", 1);
-	g_byte_array_append (buf, url->user, strlen (url->user));
-	g_byte_array_append (buf, "", 1);
-	g_byte_array_append (buf, url->passwd, strlen (url->passwd));
+	g_byte_array_append (buf, (guchar *) "", 1);
+	g_byte_array_append (buf,(guchar *)  url->user, strlen (url->user));
+	g_byte_array_append (buf,(guchar *)  "", 1);
+	g_byte_array_append (buf, (guchar *) url->passwd, strlen (url->passwd));
 	
 	sasl->authenticated = TRUE;
 	
Only in .: camel-sasl-plain.lo
Only in .: camel-sasl-plain.o
Only in .: camel-sasl-popb4smtp.lo
Only in .: camel-sasl-popb4smtp.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-search-private.c ./camel-search-private.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-search-private.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-search-private.c	2007-05-12 10:01:18.000000000 +0200
@@ -248,7 +248,7 @@
 	
 	puni = nuni = g_alloca (sizeof (gunichar) * strlen (needle));
 	
-	p = needle;
+	p = (const unsigned char *) needle;
 	while ((u = camel_utf8_getc(&p)))
 		*puni++ = g_unichar_tolower (u);
 	
@@ -379,7 +379,10 @@
 	/* from dan the man, if we have mixed case, perform a case-sensitive match,
 	   otherwise not */
 	p = (const unsigned char *)match;
-	while ((c = camel_utf8_getc(&p))) {
+
+	c = camel_utf8_getc (&p);
+	while (c) 
+	{
 		if (g_unichar_isupper(c)) {
 			switch (how) {
 			case CAMEL_SEARCH_MATCH_EXACT:
@@ -395,8 +398,9 @@
 			}
 			return FALSE;
 		}
+		c = camel_utf8_getc (&p);
 	}
-	
+
 	switch (how) {
 	case CAMEL_SEARCH_MATCH_EXACT:
 		return camel_ustrcasecmp(value, match) == 0;
@@ -510,7 +514,7 @@
 		
 		camel_data_wrapper_write_to_stream (containee, CAMEL_STREAM (mem));
 		camel_stream_write (CAMEL_STREAM (mem), "", 1);
-		truth = regexec (pattern, mem->buffer->data, 0, NULL, 0) == 0;
+		truth = regexec (pattern, (char *) mem->buffer->data, 0, NULL, 0) == 0;
 		camel_object_unref (mem);
 	}
 	
@@ -622,14 +626,14 @@
 			word->word = g_strdup(wordin->words[i]->word);
 			g_ptr_array_add(list, word);
 		} else {
-			ptr = wordin->words[i]->word;
+			ptr = (const unsigned char *) wordin->words[i]->word;
 			start = last = ptr;
 			do {
 				c = camel_utf8_getc(&ptr);
 				if (c == 0 || !g_unichar_isalnum(c)) {
 					if (last > start) {
 						word = g_malloc0(sizeof(*word));
-						word->word = g_strndup(start, last-start);
+						word->word = g_strndup((gchar *) start, last-start);
 						word->type = type;
 						g_ptr_array_add(list, word);
 						all |= type;
Only in .: camel-search-private.lo
Only in .: camel-search-private.o
Only in .: camel-seekable-stream.lo
Only in .: camel-seekable-stream.o
Only in .: camel-seekable-substream.lo
Only in .: camel-seekable-substream.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-service.c ./camel-service.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-service.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-service.c	2007-05-12 10:01:18.000000000 +0200
@@ -93,7 +93,8 @@
 camel_service_init (void *o, void *k)
 {
 	CamelService *service = o;
-	
+
+	service->data = NULL;
 	service->priv = g_malloc0(sizeof(*service->priv));
 	g_static_rec_mutex_init(&service->priv->connect_lock);
 	g_static_mutex_init(&service->priv->connect_op_lock);
@@ -120,7 +121,8 @@
 		camel_url_free (service->url);
 	if (service->session)
 		camel_object_unref (service->session);
-	
+	service->data = NULL;
+
 	g_static_rec_mutex_free (&service->priv->connect_lock);
 	g_static_mutex_free (&service->priv->connect_op_lock);
 	
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-service.h ./camel-service.h
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-service.h	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-service.h	2007-05-12 10:01:18.000000000 +0200
@@ -68,6 +68,7 @@
 	CamelServiceConnectionStatus status;
 	CamelOperation *connect_op;
 	CamelURL *url;
+	gpointer data;
 };
 
 typedef struct {
Only in .: camel-service.lo
Only in .: camel-service.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-session.c ./camel-session.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-session.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-session.c	2007-05-12 10:01:18.000000000 +0200
@@ -294,7 +294,7 @@
 #endif
 		return path;
 
-	if (g_mkdir_with_parents (path, S_IRWXU) == -1) {
+	if (e_util_mkdir_hier (path, S_IRWXU) == -1) {
 		camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
 				      _("Could not create directory %s:\n%s"),
 				      path, g_strerror (errno));
@@ -336,7 +336,7 @@
  * @session: a #CamelSession object
  * @service: the #CamelService this query is being made by
  * @domain: domain of password request.  May be null to use the default.
- * @prompt: prompt to provide to user
+ * @prompt: prompt to provide to user. May be null.
  * @item: an identifier, unique within this service, for the information
  * @flags: #CAMEL_SESSION_PASSWORD_REPROMPT, the prompt should force a reprompt
  * #CAMEL_SESSION_PASSWORD_SECRET, whether the password is secret
@@ -352,6 +352,9 @@
  * @prompt is a question to ask the user (if the application doesn't
  * already have the answer cached). If #CAMEL_SESSION_PASSWORD_SECRET
  * is set, the user's input will not be echoed back.
+ * This is a human-readable password question, possibly containing an untranslated error 
+ * message directly from the server. This should be ignored by most implementations, 
+ * so NULL is an acceptable value.
  *
  * If #CAMEL_SESSION_PASSWORD_STATIC is set, it means the password returned
  * will be stored statically by the caller automatically, for the current
@@ -474,11 +477,11 @@
 }
 
 static void
-cs_thread_status(CamelOperation *op, const char *what, int pc, void *data)
+cs_thread_status(CamelOperation *op, const char *what, int sofar, int oftotal, void *data)
 {
 	CamelSessionThreadMsg *m = data;
 
-	CS_CLASS(m->session)->thread_status(m->session, m, what, pc);
+	CS_CLASS(m->session)->thread_status(m->session, m, what, sofar * 100 / oftotal);
 }
 
 static void *session_thread_msg_new(CamelSession *session, CamelSessionThreadOps *ops, unsigned int size)
Only in .: camel-session.lo
Only in .: camel-session.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-smime-context.c ./camel-smime-context.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-smime-context.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-smime-context.c	2007-05-12 10:01:18.000000000 +0200
@@ -157,7 +157,7 @@
 					   NULL, NULL,	/* password callback    */
 					   NULL, NULL); /* decrypt key callback */
 		
-		NSS_CMSDecoder_Update(dec, istream->buffer->data, istream->buffer->len);
+		NSS_CMSDecoder_Update(dec, (char*) istream->buffer->data, istream->buffer->len);
 		camel_object_unref(istream);
 		
 		cmsg = NSS_CMSDecoder_Finish(dec);
@@ -401,7 +401,7 @@
 		goto fail;
 	}
 
-	if (NSS_CMSEncoder_Update(enc, ((CamelStreamMem *)istream)->buffer->data, ((CamelStreamMem *)istream)->buffer->len) != SECSuccess) {
+	if (NSS_CMSEncoder_Update(enc, (char *) ((CamelStreamMem *)istream)->buffer->data, ((CamelStreamMem *)istream)->buffer->len) != SECSuccess) {
 		NSS_CMSEncoder_Cancel(enc);
 		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Failed to add data to CMS encoder"));
 		goto fail;
@@ -717,7 +717,7 @@
 				   NULL, NULL); /* decrypt key callback */
 
 	camel_data_wrapper_decode_to_stream(camel_medium_get_content_object((CamelMedium *)sigpart), (CamelStream *)mem);
-	(void)NSS_CMSDecoder_Update(dec, mem->buffer->data, mem->buffer->len);
+	(void)NSS_CMSDecoder_Update(dec, (char *) mem->buffer->data, mem->buffer->len);
 	cmsg = NSS_CMSDecoder_Finish(dec);
 	if (cmsg == NULL) {
 		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Decoder failed"));
@@ -853,7 +853,7 @@
 	/* FIXME: Canonicalise the input? */
 	mem = (CamelStreamMem *)camel_stream_mem_new();
 	camel_data_wrapper_write_to_stream((CamelDataWrapper *)ipart, (CamelStream *)mem);
-	if (NSS_CMSEncoder_Update(enc, mem->buffer->data, mem->buffer->len) != SECSuccess) {
+	if (NSS_CMSEncoder_Update(enc, (char *) mem->buffer->data, mem->buffer->len) != SECSuccess) {
 		NSS_CMSEncoder_Cancel(enc);
 		camel_object_unref(mem);
 		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Failed to add data to encoder"));
@@ -936,7 +936,7 @@
 				   NULL, NULL,
 				   NULL, NULL); /* decrypt key callback */
 
-	if (NSS_CMSDecoder_Update(dec, istream->buffer->data, istream->buffer->len) != SECSuccess) {
+	if (NSS_CMSDecoder_Update(dec, (char *) istream->buffer->data, istream->buffer->len) != SECSuccess) {
 		printf("decoder update failed\n");
 	}
 	camel_object_unref(istream);
Only in .: camel-smime-context.lo
Only in .: camel-smime-context.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-store.c ./camel-store.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-store.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-store.c	2007-05-12 10:00:17.000000000 +0200
@@ -84,6 +84,8 @@
 static int store_setv (CamelObject *object, CamelException *ex, CamelArgV *args);
 static int store_getv (CamelObject *object, CamelException *ex, CamelArgGetV *args);
 
+static GPtrArray* get_recent_messages (CamelStore *store, const char *folder_name, int *unseen, int *messages);
+
 static void
 camel_store_class_init (CamelStoreClass *camel_store_class)
 {
@@ -109,7 +111,8 @@
 	camel_store_class->subscribe_folder = subscribe_folder;
 	camel_store_class->unsubscribe_folder = unsubscribe_folder;
 	camel_store_class->noop = noop;
-	
+	camel_store_class->get_recent_messages = get_recent_messages;
+
 	/* virtual method overload */
 	camel_service_class->construct = construct;
 	
@@ -177,6 +180,29 @@
 	return camel_store_type;
 }
 
+
+GPtrArray* 
+camel_store_get_recent_messages (CamelStore *store, const char *folder_name, 
+			int *unseen, int *messages)
+{
+	GPtrArray *ret;
+
+	CAMEL_STORE_LOCK(store, folder_lock);
+	ret = CS_CLASS (store)->get_recent_messages (store, folder_name, unseen, messages);
+	CAMEL_STORE_UNLOCK(store, folder_lock);
+
+	return ret;
+}
+
+static GPtrArray* 
+get_recent_messages (CamelStore *store, const char *folder_name, int *unseen, int *messages)
+{
+	*unseen = 0;
+	*messages = 0;
+	return NULL;
+}
+
+
 static int
 store_setv (CamelObject *object, CamelException *ex, CamelArgV *args)
 {
@@ -713,7 +739,7 @@
 		g_free (vinfo->uri);
 	} else {
 		/* There wasn't a Trash/Junk folder so create a new folder entry */
-		vinfo = g_new0 (CamelFolderInfo, 1);
+		vinfo = camel_folder_info_new ();
 		
 		g_assert(parent != NULL);
 		
@@ -858,6 +884,7 @@
 	;
 }
 
+
 /**
  * camel_folder_info_free:
  * @fi: a #CamelFolderInfo
@@ -873,10 +900,25 @@
 		g_free (fi->name);
 		g_free (fi->full_name);
 		g_free (fi->uri);
-		g_free (fi);
+		g_slice_free (CamelFolderInfo, fi);
 	}
 }
 
+
+/**
+ * camel_folder_info_new:
+ *
+ * Return value: a new empty CamelFolderInfo instance
+ **/
+CamelFolderInfo* 
+camel_folder_info_new (void)
+{
+	CamelFolderInfo *retval = g_slice_new0 (CamelFolderInfo);
+	retval->unread = 0;
+	retval->total = 0;
+	return retval;
+}
+
 static int
 folder_info_cmp (const void *ap, const void *bp)
 {
@@ -945,7 +987,7 @@
 				CamelURL *url;
 				char *sep;
 
-				pfi = g_new0 (CamelFolderInfo, 1);
+				pfi = camel_folder_info_new ();
 				if (short_names) {
 					pfi->name = strrchr (pname, separator);
 					if (pfi->name)
@@ -1088,7 +1130,9 @@
 	gboolean ret;
 
 	g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
-	g_return_val_if_fail (store->flags & CAMEL_STORE_SUBSCRIPTIONS, FALSE);
+
+	if (! (store->flags & CAMEL_STORE_SUBSCRIPTIONS) ) 
+		return FALSE;
 
 	CAMEL_STORE_LOCK(store, folder_lock);
 
@@ -1099,6 +1143,8 @@
 	return ret;
 }
 
+
+
 static void
 subscribe_folder(CamelStore *store, const char *folder_name, CamelException *ex)
 {
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-store.h ./camel-store.h
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-store.h	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-store.h	2007-05-12 10:00:17.000000000 +0200
@@ -51,6 +51,8 @@
 	guint32 flags;
 	guint32 unread;
 	guint32 total;
+	guint32 local_size;
+
 } CamelFolderInfo;
 
 /* Note: these are abstractions (duh), its upto the provider to make them make sense */
@@ -185,6 +187,10 @@
 						     CamelException *ex);
 	void            (*noop)                     (CamelStore *store,
 						     CamelException *ex);
+	GPtrArray*      (*get_recent_messages)      (CamelStore *store, 
+						     const char *folder_name, 
+						     int *unseen, int *messages);
+
 } CamelStoreClass;
 
 /* Standard Camel function */
@@ -228,6 +234,8 @@
 void             camel_store_free_folder_info_nop  (CamelStore *store,
 						    CamelFolderInfo *fi);
 
+
+CamelFolderInfo *camel_folder_info_new             (void);
 void             camel_folder_info_free            (CamelFolderInfo *fi);
 CamelFolderInfo *camel_folder_info_build           (GPtrArray *folders,
 						    const char *namespace,
@@ -253,6 +261,11 @@
 						       const char *uri0,
 						       const char *uri1);
 
+GPtrArray*       camel_store_get_recent_messages      (CamelStore *store, 
+						       const char *folder_name, 
+						       int *unseen, int *messages);
+
+
 typedef struct _CamelISubscribe CamelISubscribe;
 struct _CamelISubscribe {
 	CamelInterface iface;
Only in .: camel-store.lo
Only in .: camel-store.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-store-summary.c ./camel-store-summary.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-store-summary.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-store-summary.c	2007-05-12 10:01:18.000000000 +0200
@@ -98,8 +98,6 @@
 
 	s->store_info_size = sizeof(CamelStoreInfo);
 
-	s->store_info_chunks = NULL;
-
 	s->version = CAMEL_STORE_SUMMARY_VERSION;
 	s->flags = 0;
 	s->count = 0;
@@ -110,7 +108,6 @@
 	
 	p->summary_lock = g_mutex_new();
 	p->io_lock = g_mutex_new();
-	p->alloc_lock = g_mutex_new();
 	p->ref_lock = g_mutex_new();
 }
 
@@ -122,18 +119,19 @@
 
 	p = _PRIVATE(obj);
 
+	camel_store_summary_save (s);
+
 	camel_store_summary_clear(s);
 	g_ptr_array_free(s->folders, TRUE);
 	g_hash_table_destroy(s->folders_path);
 
 	g_free(s->summary_path);
 
-	if (s->store_info_chunks)
-		e_memchunk_destroy(s->store_info_chunks);
-	
+	if (s->uri_base)
+                camel_url_free(s->uri_base);
+
 	g_mutex_free(p->summary_lock);
 	g_mutex_free(p->io_lock);
-	g_mutex_free(p->alloc_lock);
 	g_mutex_free(p->ref_lock);
 	
 	g_free(p);
@@ -831,11 +829,7 @@
 {
 	CamelStoreInfo *info;
 
-	CAMEL_STORE_SUMMARY_LOCK(s, alloc_lock);
-	if (s->store_info_chunks == NULL)
-		s->store_info_chunks = e_memchunk_new(32, s->store_info_size);
-	info = e_memchunk_alloc0(s->store_info_chunks);
-	CAMEL_STORE_SUMMARY_UNLOCK(s, alloc_lock);
+	info = g_slice_alloc0(s->store_info_size);
 	info->refcount = 1;
 	return info;
 }
@@ -944,7 +938,7 @@
 {
 	g_free(info->path);
 	g_free(info->uri);
-	e_memchunk_free(s->store_info_chunks, info);
+	g_slice_free1(s->store_info_size, info);
 }
 
 static const char *
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-store-summary.h ./camel-store-summary.h
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-store-summary.h	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-store-summary.h	2007-05-12 10:01:18.000000000 +0200
@@ -99,9 +99,6 @@
 	/* sizes of memory objects */
 	guint32 store_info_size;
 
-	/* memory allocators (setup automatically) */
-	struct _EMemChunk *store_info_chunks;
-
 	char *summary_path;
 
 	GPtrArray *folders;	/* CamelStoreInfo's */
Only in .: camel-store-summary.lo
Only in .: camel-store-summary.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-stream-buffer.c ./camel-stream-buffer.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-stream-buffer.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-stream-buffer.c	2007-05-12 10:01:18.000000000 +0200
@@ -32,6 +32,7 @@
 #include <sys/types.h>
 
 #include "camel-stream-buffer.h"
+#include "camel-tcp-stream.h"
 
 static CamelStreamClass *parent_class = NULL;
 
@@ -126,7 +127,7 @@
 		g_free(sbf->buf);
 	}
 	if (buf) {
-		sbf->buf = buf;
+		sbf->buf = (unsigned char*)buf;
 		sbf->flags |= BUF_USER;
 	} else {
 		sbf->buf = g_malloc(size);
@@ -253,7 +254,7 @@
 					bptr += bytes_read;
 				}
 			} else {
-				bytes_read = camel_stream_read(sbf->stream, sbf->buf, sbf->size);
+				bytes_read = camel_stream_read(sbf->stream, (char *)sbf->buf, sbf->size);
 				if (bytes_read>0) {
 					size_t bytes_used = bytes_read > n ? n : bytes_read;
 					sbf->ptr = sbf->buf;
@@ -312,7 +313,7 @@
 
 	/* if we've filled the buffer, write it out, reset buffer */
 	if (left == todo) {
-		if (stream_write_all(sbf->stream, sbf->buf, sbf->size) == -1)
+		if (stream_write_all(sbf->stream, (const char *)sbf->buf, sbf->size) == -1)
 			return -1;
 
 		sbf->ptr = sbf->buf;
@@ -340,7 +341,7 @@
 	if ((sbf->mode & CAMEL_STREAM_BUFFER_MODE) == CAMEL_STREAM_BUFFER_WRITE) {
 		size_t len = sbf->ptr - sbf->buf;
 		
-		if (camel_stream_write (sbf->stream, sbf->buf, len) == -1)
+		if (camel_stream_write (sbf->stream, (const char *)sbf->buf, len) == -1)
 			return -1;
 		
 		sbf->ptr = sbf->buf;
@@ -391,8 +392,8 @@
 	int bytes_read;
 
 	outptr = buf;
-	inptr = sbf->ptr;
-	inend = sbf->end;
+	inptr = (char*)sbf->ptr;
+	inend = (char*)sbf->end;
 	outend = buf+max-1;	/* room for NUL */
 
 	do {
@@ -401,25 +402,71 @@
 			*outptr++ = c;
 			if (c == '\n') {
 				*outptr = 0;
-				sbf->ptr = inptr;
+				sbf->ptr = (unsigned char*) inptr;
 				return outptr-buf;
 			}
 		}
 		if (outptr == outend)
 			break;
 
-		bytes_read = camel_stream_read (sbf->stream, sbf->buf, sbf->size);
+		bytes_read = camel_stream_read (sbf->stream, (char*)sbf->buf, sbf->size);
 		if (bytes_read == -1) {
 			if (buf == outptr)
 				return -1;
 			else
 				bytes_read = 0;
 		}
-		inptr = sbf->ptr = sbf->buf;
-		inend = sbf->end = sbf->buf + bytes_read;
+		sbf->ptr = sbf->buf;
+		sbf->end = sbf->buf + bytes_read;
+		inptr = (char*)sbf->ptr;
+		inend = (char*)sbf->end;
+	} while (bytes_read>0);
+
+	sbf->ptr = (unsigned char*)inptr;
+	*outptr = 0;
+
+	return (int)(outptr - buf);
+}
+
+
+int
+camel_tcp_stream_buffer_gets_nb (CamelStreamBuffer *sbf, char *buf, unsigned int max)
+{
+	register char *outptr, *inptr, *inend, c, *outend;
+	int bytes_read;
+
+	outptr = buf;
+	inptr = (char*)sbf->ptr;
+	inend = (char*)sbf->end;
+	outend = buf+max-1;	/* room for NUL */
+
+	do {
+		while (inptr<inend && outptr<outend) {
+			c = *inptr++;
+			*outptr++ = c;
+			if (c == '\n') {
+				*outptr = 0;
+				sbf->ptr = (unsigned char*) inptr;
+				return outptr-buf;
+			}
+		}
+		if (outptr == outend)
+			break;
+
+		bytes_read = camel_tcp_stream_read_nb ((CamelTcpStream *)sbf->stream, (char*)sbf->buf, sbf->size);
+		if (bytes_read == -1) {
+			if (buf == outptr)
+				return -1;
+			else
+				bytes_read = 0;
+		}
+		sbf->ptr = sbf->buf;
+		sbf->end = sbf->buf + bytes_read;
+		inptr = (char*)sbf->ptr;
+		inend = (char*)sbf->end;
 	} while (bytes_read>0);
 
-	sbf->ptr = inptr;
+	sbf->ptr = (unsigned char*)inptr;
 	*outptr = 0;
 
 	return (int)(outptr - buf);
@@ -445,7 +492,7 @@
 	p = sbf->linebuf;
 
 	while (1) {
-		nread = camel_stream_buffer_gets (sbf, p, sbf->linesize - (p - sbf->linebuf));
+		nread = camel_stream_buffer_gets (sbf, (char*)p, sbf->linesize - (p - sbf->linebuf));
 		if (nread <=0) {
 			if (p > sbf->linebuf)
 				break;
@@ -467,5 +514,5 @@
 		p--;
 	p[0] = 0;
 
-	return g_strdup(sbf->linebuf);
+	return g_strdup((gchar*)sbf->linebuf);
 }
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-stream-buffer.h ./camel-stream-buffer.h
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-stream-buffer.h	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-stream-buffer.h	2007-05-12 10:01:18.000000000 +0200
@@ -94,6 +94,7 @@
 int camel_stream_buffer_gets (CamelStreamBuffer *sbf, char *buf, unsigned int max);
 
 char *camel_stream_buffer_read_line (CamelStreamBuffer *sbf);
+int camel_tcp_stream_buffer_gets_nb (CamelStreamBuffer *sbf, char *buf, unsigned int max);
 
 G_END_DECLS
 
Only in .: camel-stream-buffer.lo
Only in .: camel-stream-buffer.o
Only in .: camel-stream-filter.lo
Only in .: camel-stream-filter.o
Only in .: camel-stream-fs.lo
Only in .: camel-stream-fs.o
Only in .: camel-stream-gzip.c
Only in .: camel-stream-gzip.h
Only in .: camel-stream-gzip.lo
Only in .: camel-stream-gzip.o
Only in .: camel-stream.lo
Only in .: camel-stream-mem.lo
Only in .: camel-stream-mem.o
Only in .: camel-stream-null.lo
Only in .: camel-stream-null.o
Only in .: camel-stream.o
Only in .: camel-stream-process.lo
Only in .: camel-stream-process.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-stream-vfs.c ./camel-stream-vfs.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-stream-vfs.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-stream-vfs.c	2007-05-12 10:01:17.000000000 +0200
@@ -122,6 +122,7 @@
 {
 	CamelStreamVFS *stream_vfs;
 	off_t offset;
+	GnomeVFSResult result;
 	
 	if (!handle)
 		return NULL;
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-string-utils.c ./camel-string-utils.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-string-utils.c	2007-04-20 13:25:00.000000000 +0200
+++ ./camel-string-utils.c	2007-03-11 16:44:11.000000000 +0100
@@ -141,10 +141,15 @@
 	return c;
 }
 
+#ifdef MEMDEBUG
+static int cnt=0;
+#endif
+
 /* working stuff for pstrings */
 static pthread_mutex_t pstring_lock = PTHREAD_MUTEX_INITIALIZER;
 static GHashTable *pstring_table = NULL;
 
+
 /**
  * camel_pstring_add:
  * @str: string to add to the string pool
@@ -184,6 +189,11 @@
 			g_free (str);
 	} else {
 		pstr = own ? str : g_strdup (str);
+
+#ifdef MEMDEBUG
+		cnt++;
+		printf ("%d\n", cnt); 
+#endif
 		g_hash_table_insert (pstring_table, pstr, GINT_TO_POINTER (1));
 	}
 	
@@ -240,6 +250,10 @@
 		if (count == 0) {
 			g_hash_table_remove(pstring_table, p);
 			g_free(p);
+#ifdef MEMDEBUG
+			cnt--;
+			printf ("%d\n", cnt);
+#endif
 		} else {
 			g_hash_table_insert(pstring_table, p, GINT_TO_POINTER(count));
 		}
Only in .: camel-string-utils.lo
Only in .: camel-string-utils.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-tcp-stream.c ./camel-tcp-stream.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-tcp-stream.c	2007-04-20 13:25:00.000000000 +0200
+++ ./camel-tcp-stream.c	2007-03-11 16:44:11.000000000 +0100
@@ -40,6 +40,7 @@
 static int tcp_setsockopt (CamelTcpStream *stream, const CamelSockOptData *data);
 static struct sockaddr *tcp_get_local_address (CamelTcpStream *stream, socklen_t *len);
 static struct sockaddr *tcp_get_remote_address (CamelTcpStream *stream, socklen_t *len);
+static ssize_t tcp_read_nb (CamelTcpStream *stream, char *buffer, size_t n);
 
 static void
 camel_tcp_stream_class_init (CamelTcpStreamClass *camel_tcp_stream_class)
@@ -49,6 +50,7 @@
 	parent_class = CAMEL_STREAM_CLASS (camel_type_get_global_classfuncs (CAMEL_STREAM_TYPE));
 	
 	/* tcp stream methods */
+	camel_tcp_stream_class->read_nb            = tcp_read_nb;
 	camel_tcp_stream_class->connect            = tcp_connect;
 	camel_tcp_stream_class->getsockopt         = tcp_getsockopt;
 	camel_tcp_stream_class->setsockopt         = tcp_setsockopt;
@@ -81,6 +83,12 @@
 	return type;
 }
 
+static ssize_t
+tcp_read_nb (CamelTcpStream *stream, char *buffer, size_t n)
+{
+	w(g_warning ("CamelTcpStream::read_nb called on default implementation"));
+	return -1;
+}
 
 static int
 tcp_connect (CamelTcpStream *stream, struct addrinfo *host)
@@ -181,6 +189,13 @@
 	return CTS_CLASS (stream)->get_local_address (stream, len);
 }
 
+int 
+camel_tcp_stream_read_nb (CamelTcpStream *stream, char *buffer, size_t n)
+{
+	return CTS_CLASS (stream)->read_nb (stream, buffer, n);
+}
+
+
 static struct sockaddr *
 tcp_get_remote_address (CamelTcpStream *stream, socklen_t *len)
 {
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-tcp-stream.h ./camel-tcp-stream.h
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-tcp-stream.h	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-tcp-stream.h	2007-05-12 10:01:18.000000000 +0200
@@ -106,6 +106,8 @@
 	
 	struct sockaddr * (*get_local_address)  (CamelTcpStream *stream, socklen_t *len);
 	struct sockaddr * (*get_remote_address) (CamelTcpStream *stream, socklen_t *len);
+	ssize_t (*read_nb)   (CamelTcpStream *stream, char *buffer, size_t n);
+	
 } CamelTcpStreamClass;
 
 /* Standard Camel function */
@@ -119,6 +121,8 @@
 struct sockaddr *camel_tcp_stream_get_local_address  (CamelTcpStream *stream, socklen_t *len);
 struct sockaddr *camel_tcp_stream_get_remote_address (CamelTcpStream *stream, socklen_t *len);
 
+int         camel_tcp_stream_read_nb    (CamelTcpStream *stream, char *buffer, size_t n);
+
 G_END_DECLS
 
 #endif /* CAMEL_TCP_STREAM_H */
Only in .: camel-tcp-stream.lo
Only in .: camel-tcp-stream.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-tcp-stream-openssl.c ./camel-tcp-stream-openssl.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-tcp-stream-openssl.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-tcp-stream-openssl.c	2007-05-12 10:23:33.000000000 +0200
@@ -1,6 +1,8 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
- *  Authors: Jeffrey Stedfast <fejj@ximian.com>
+ *  Authors: 
+ *   Jeffrey Stedfast <fejj@ximian.com>
+ *   Philip Van Hoof <pvanhoof@gnome.org>
  *
  *  Copyright 2001 Ximian, Inc. (www.ximian.com)
  *
@@ -21,19 +23,23 @@
  */
 
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
-#endif
 
+#ifndef HAVE_NSS
 #ifdef HAVE_OPENSSL
 
-#include <errno.h>
-#include <fcntl.h>
+#include "camel-tcp-stream-ssl.h"
+
 #include <string.h>
-#include <unistd.h>
-#include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "camel-session.h"
+#include "camel-i18n.h"
 
 #include <openssl/err.h>
 #include <openssl/ssl.h>
@@ -55,24 +61,25 @@
 /* Returns the class for a CamelTcpStreamSSL */
 #define CTSR_CLASS(so) CAMEL_TCP_STREAM_SSL_CLASS (CAMEL_OBJECT_GET_CLASS (so))
 
+static ssize_t stream_read_nb (CamelStream *stream, char *buffer, size_t n);
 static ssize_t stream_read (CamelStream *stream, char *buffer, size_t n);
 static ssize_t stream_write (CamelStream *stream, const char *buffer, size_t n);
 static int stream_flush  (CamelStream *stream);
 static int stream_close  (CamelStream *stream);
 
-static int stream_connect (CamelTcpStream *stream, struct hostent *host, int port);
+static int stream_connect (CamelTcpStream *stream, struct addrinfo *host);
 static int stream_getsockopt (CamelTcpStream *stream, CamelSockOptData *data);
 static int stream_setsockopt (CamelTcpStream *stream, const CamelSockOptData *data);
-static CamelTcpAddress *stream_get_local_address (CamelTcpStream *stream);
-static CamelTcpAddress *stream_get_remote_address (CamelTcpStream *stream);
+static struct sockaddr *stream_get_local_address (CamelTcpStream *stream, socklen_t *len);
+static struct sockaddr *stream_get_remote_address (CamelTcpStream *stream, socklen_t *len);
 
-static SSL *open_ssl_connection (CamelService *service, int sockfd, CamelTcpStreamSSL *openssl);
+static SSL *open_ssl_connection (CamelSession *session, int sockfd, CamelTcpStreamSSL *openssl);
 
 struct _CamelTcpStreamSSLPrivate {
 	int sockfd;
 	SSL *ssl;
 	
-	CamelService *service;
+	CamelSession *session;
 	char *expected_host;
 	gboolean ssl_mode;
 	guint32 flags;
@@ -94,6 +101,7 @@
 	camel_stream_class->flush = stream_flush;
 	camel_stream_class->close = stream_close;
 	
+	camel_tcp_stream_class->read_nb = stream_read_nb;
 	camel_tcp_stream_class->connect = stream_connect;
 	camel_tcp_stream_class->getsockopt = stream_getsockopt;
 	camel_tcp_stream_class->setsockopt = stream_setsockopt;
@@ -158,9 +166,10 @@
 }
 
 
+
 /**
  * camel_tcp_stream_ssl_new:
- * @service: camel service
+ * @session: camel session
  * @expected_host: host that the stream is expecting to connect with.
  * @flags: flags
  *
@@ -171,13 +180,13 @@
  * Return value: a ssl stream (in ssl mode)
  **/
 CamelStream *
-camel_tcp_stream_ssl_new (CamelService *service, const char *expected_host, guint32 flags)
+camel_tcp_stream_ssl_new (struct _CamelSession *session, const char *expected_host, guint32 flags)
 {
 	CamelTcpStreamSSL *stream;
 	
 	stream = CAMEL_TCP_STREAM_SSL (camel_object_new (camel_tcp_stream_ssl_get_type ()));
 	
-	stream->priv->service = service;
+	stream->priv->session = session;
 	stream->priv->expected_host = g_strdup (expected_host);
 	stream->priv->ssl_mode = TRUE;
 	stream->priv->flags = flags;
@@ -188,7 +197,7 @@
 
 /**
  * camel_tcp_stream_ssl_new_raw:
- * @service: camel service
+ * @session: camel session
  * @expected_host: host that the stream is expecting to connect with.
  * @flags: flags
  *
@@ -199,13 +208,13 @@
  * Return value: a ssl-capable stream (in non ssl mode)
  **/
 CamelStream *
-camel_tcp_stream_ssl_new_raw (CamelService *service, const char *expected_host, guint32 flags)
+camel_tcp_stream_ssl_new_raw (struct _CamelSession *session, const char *expected_host, guint32 flags)
 {
 	CamelTcpStreamSSL *stream;
 	
 	stream = CAMEL_TCP_STREAM_SSL (camel_object_new (camel_tcp_stream_ssl_get_type ()));
 	
-	stream->priv->service = service;
+	stream->priv->session = session;
 	stream->priv->expected_host = g_strdup (expected_host);
 	stream->priv->ssl_mode = FALSE;
 	stream->priv->flags = flags;
@@ -257,7 +266,7 @@
 	g_return_val_if_fail (CAMEL_IS_TCP_STREAM_SSL (stream), -1);
 	
 	if (stream->priv->sockfd != -1 && !stream->priv->ssl_mode) {
-		ssl = open_ssl_connection (stream->priv->service, stream->priv->sockfd, stream);
+		ssl = open_ssl_connection (stream->priv->session, stream->priv->sockfd, stream);
 		if (ssl == NULL) {
 			stream->priv->sockfd = -1;
 			return -1;
@@ -273,6 +282,58 @@
 
 
 static ssize_t
+stream_read_nb (CamelStream *stream, char *buffer, size_t n)
+{
+	CamelTcpStreamSSL *openssl = CAMEL_TCP_STREAM_SSL (stream);
+	SSL *ssl = openssl->priv->ssl;
+	ssize_t nread;
+
+	int error, flags, fdmax;
+	struct timeval timeout;
+	fd_set rdset;
+	int res;
+
+	flags = fcntl (openssl->priv->sockfd, F_GETFL);
+	fcntl (openssl->priv->sockfd, F_SETFL, flags | O_NONBLOCK);
+	
+	fdmax = openssl->priv->sockfd + 1;
+	
+	do {
+		FD_ZERO (&rdset);
+		FD_SET (openssl->priv->sockfd, &rdset);
+		nread = -1;
+		timeout.tv_sec = 0;
+		timeout.tv_usec = 0;
+		res = select (fdmax, &rdset, 0, 0, &timeout);
+		
+		if (res == -1)
+			;
+		else if (res == 0)
+			errno = ETIMEDOUT;
+		else {
+
+		  do {
+			if (ssl) {
+				nread = SSL_read (ssl, buffer, n);
+				if (nread < 0)
+					errno = ssl_errno (ssl, nread);
+			} else {
+				nread = read (openssl->priv->sockfd, buffer, n);
+			}
+		  } while (0 && (nread < 0 && errno == EINTR));
+		}
+	} while (0 && (nread < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)));
+	
+	error = errno;
+	fcntl (openssl->priv->sockfd, F_SETFL, flags);
+	errno = error;
+
+
+	return nread;
+}
+
+
+static ssize_t
 stream_read (CamelStream *stream, char *buffer, size_t n)
 {
 	CamelTcpStreamSSL *openssl = CAMEL_TCP_STREAM_SSL (stream);
@@ -284,7 +345,7 @@
 		errno = EINTR;
 		return -1;
 	}
-	
+
 	cancel_fd = camel_operation_cancel_fd (NULL);
 	if (cancel_fd == -1) {
 		do {
@@ -335,7 +396,7 @@
 		fcntl (openssl->priv->sockfd, F_SETFL, flags);
 		errno = error;
 	}
-	
+
 	return nread;
 }
 
@@ -457,13 +518,9 @@
 /* this is a 'cancellable' connect, cancellable from camel_operation_cancel etc */
 /* returns -1 & errno == EINTR if the connection was cancelled */
 static int
-socket_connect (struct hostent *h, int port)
+socket_connect (struct addrinfo *host)
 {
-#ifdef ENABLE_IPv6
-	struct sockaddr_in6 sin6;
-#endif
-	struct sockaddr_in sin;
-	struct sockaddr *saddr;
+	struct sockaddr *saddr = host->ai_addr;
 	struct timeval tv;
 	socklen_t len;
 	int cancel_fd;
@@ -474,27 +531,8 @@
 		errno = EINTR;
 		return -1;
 	}
-	
-	/* setup connect, we do it using a nonblocking socket so we can poll it */
-#ifdef ENABLE_IPv6
-	if (h->h_addrtype == AF_INET6) {
-		sin6.sin6_port = htons (port);
-		sin6.sin6_family = h->h_addrtype;
-		memcpy (&sin6.sin6_addr, h->h_addr, sizeof (sin6.sin6_addr));
-		saddr = (struct sockaddr *) &sin6;
-		len = sizeof (sin6);
-	} else {
-#endif
-		sin.sin_port = htons (port);
-		sin.sin_family = h->h_addrtype;
-		memcpy (&sin.sin_addr, h->h_addr, sizeof (sin.sin_addr));
-		saddr = (struct sockaddr *) &sin;
-		len = sizeof (sin);
-#ifdef ENABLE_IPv6
-	}
-#endif
-	
-	fd = socket (h->h_addrtype, SOCK_STREAM, 0);
+
+	fd = socket (host->ai_family, SOCK_STREAM, 0);
 	
 	cancel_fd = camel_operation_cancel_fd (NULL);
 	if (cancel_fd == -1) {
@@ -639,11 +677,12 @@
 {
 	unsigned char md5sum[16], fingerprint[40], *f;
 	CamelTcpStreamSSL *stream;
-	CamelService *service;
+	CamelSession *session;
 	CamelCertDB *certdb = NULL;
 	CamelCert *ccert = NULL;
 	char *prompt, *cert_str;
-	int err, md5len, i;
+	int err, i;
+	unsigned int md5len;
 	char buf[257];
 	X509 *cert;
 	SSL *ssl;
@@ -657,7 +696,7 @@
 	if (!stream)
 		return FALSE;
 	
-	service = stream->priv->service;
+	session = stream->priv->session;
 	
 	cert = X509_STORE_CTX_get_current_cert (ctx);
 	err = X509_STORE_CTX_get_error (ctx);
@@ -666,13 +705,13 @@
 	md5len = sizeof (md5sum);
 	X509_digest (cert, EVP_md5 (), md5sum, &md5len);
 	for (i = 0, f = fingerprint; i < 16; i++, f += 3)
-		sprintf (f, "%.2x%c", md5sum[i], i != 15 ? ':' : '\0');
+		sprintf ((char *) f, "%.2x%c", md5sum[i], i != 15 ? ':' : '\0');
 	
 #define GET_STRING(name) X509_NAME_oneline (name, buf, 256)
 	
 	certdb = camel_certdb_get_default ();
 	if (certdb) {
-		ccert = camel_certdb_get_cert (certdb, fingerprint);
+		ccert = camel_certdb_get_cert (certdb, (const char *) fingerprint);
 		if (ccert) {
 			if (ccert->trust != CAMEL_CERT_TRUST_UNKNOWN) {
 				ok = ccert->trust != CAMEL_CERT_TRUST_NEVER;
@@ -686,8 +725,8 @@
 			ccert = camel_certdb_cert_new (certdb);
 			camel_cert_set_issuer (certdb, ccert, GET_STRING (X509_get_issuer_name (cert)));
 			camel_cert_set_subject (certdb, ccert, GET_STRING (X509_get_subject_name (cert)));
-			camel_cert_set_hostname (certdb, ccert, stream->priv->expected_host);
-			camel_cert_set_fingerprint (certdb, ccert, fingerprint);
+			camel_cert_set_hostname (certdb, ccert, (const char *) stream->priv->expected_host);
+			camel_cert_set_fingerprint (certdb, ccert, (const char *) fingerprint);
 			camel_cert_set_trust (certdb, ccert, CAMEL_CERT_TRUST_UNKNOWN);
 			
 			/* Add the certificate to our db */
@@ -703,11 +742,11 @@
 				    GET_STRING (X509_get_subject_name (cert)),
 				    fingerprint, cert->valid ? _("GOOD") : _("BAD"));
 	
-	prompt = g_strdup_printf (_("Bad certificate from %s:\n\n%s\n\n%s\n\n"
-				    "Do you wish to accept anyway?"),
-				  service->url->host, cert_str, x509_strerror (err));
+	prompt = g_strdup_printf (_("Bad certificate\n\n%s\n\n%s\n\n"
+				    "Do you wish to accept anyway?"), 
+				    cert_str, x509_strerror (err));
 	
-	ok = camel_session_alert_user (service->session, CAMEL_SESSION_ALERT_WARNING, prompt, TRUE);
+	ok = camel_session_alert_user (session, CAMEL_SESSION_ALERT_WARNING, prompt, TRUE);
 	g_free (prompt);
 	
 	if (ok && ccert) {
@@ -724,7 +763,7 @@
 }
 
 static SSL *
-open_ssl_connection (CamelService *service, int sockfd, CamelTcpStreamSSL *openssl)
+open_ssl_connection (CamelSession *session, int sockfd, CamelTcpStreamSSL *openssl)
 {
 	SSL_CTX *ssl_ctx = NULL;
 	SSL *ssl = NULL;
@@ -761,8 +800,7 @@
 	return ssl;
 }
 
-static int
-stream_connect (CamelTcpStream *stream, struct hostent *host, int port)
+static int stream_connect_do (CamelTcpStream *stream, struct addrinfo *host)
 {
 	CamelTcpStreamSSL *openssl = CAMEL_TCP_STREAM_SSL (stream);
 	SSL *ssl = NULL;
@@ -770,12 +808,12 @@
 	
 	g_return_val_if_fail (host != NULL, -1);
 	
-	fd = socket_connect (host, port);
+	fd = socket_connect (host);
 	if (fd == -1)
 		return -1;
 	
 	if (openssl->priv->ssl_mode) {
-		ssl = open_ssl_connection (openssl->priv->service, fd, openssl);
+		ssl = open_ssl_connection (openssl->priv->session, fd, openssl);
 		if (!ssl)
 			return -1;
 	}
@@ -786,6 +824,18 @@
 	return 0;
 }
 
+static int
+stream_connect (CamelTcpStream *stream, struct addrinfo *host)
+{
+	while (host) {
+		if (stream_connect_do (stream, host) == 0)
+			return 0;
+		host = host->ai_next;
+	}
+
+	return -1;
+}
+
 
 static int
 get_sockopt_level (const CamelSockOptData *data)
@@ -850,7 +900,7 @@
 			   get_sockopt_level (data),
 			   optname,
 			   (void *) &data->value,
-			   &optlen);
+			   (socklen_t *) &optlen);
 }
 
 static int
@@ -884,74 +934,27 @@
 			   sizeof (data->value));
 }
 
-#ifdef ENABLE_IPv6
-#define MIN_SOCKADDR_BUFLEN  (sizeof (struct sockaddr_in6))
-#else
-#define MIN_SOCKADDR_BUFLEN  (sizeof (struct sockaddr_in))
-#endif
-
-static CamelTcpAddress *
-stream_get_local_address (CamelTcpStream *stream)
-{
-	unsigned char buf[MIN_SOCKADDR_BUFLEN];
-#ifdef ENABLE_IPv6
-	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) buf;
-#endif
-	struct sockaddr_in *sin = (struct sockaddr_in *) buf;
-	struct sockaddr *saddr = (struct sockaddr *) buf;
-	gpointer address;
-	socklen_t len;
-	int family;
-	
-	len = MIN_SOCKADDR_BUFLEN;
-	
-	if (getsockname (CAMEL_TCP_STREAM_SSL (stream)->priv->sockfd, saddr, &len) == -1)
-		return NULL;
-	
-	if (saddr->sa_family == AF_INET) {
-		family = CAMEL_TCP_ADDRESS_IPv4;
-		address = &sin->sin_addr;
-#ifdef ENABLE_IPv6
-	} else if (saddr->sa_family == AF_INET6) {
-		family = CAMEL_TCP_ADDRESS_IPv6;
-		address = &sin6->sin6_addr;
-#endif
-	} else
+static struct sockaddr *
+stream_get_local_address (CamelTcpStream *stream, socklen_t *len)
+{
+	struct sockaddr *saddr = (struct sockaddr *) (malloc (*len));
+
+	if (getsockname (CAMEL_TCP_STREAM_SSL (stream)->priv->sockfd, saddr, len) == -1)
 		return NULL;
-	
-	return camel_tcp_address_new (family, sin->sin_port, len, address);
+
+	return saddr;
 }
 
-static CamelTcpAddress *
-stream_get_remote_address (CamelTcpStream *stream)
+static struct sockaddr *
+stream_get_remote_address (CamelTcpStream *stream, socklen_t *len)
 {
-	unsigned char buf[MIN_SOCKADDR_BUFLEN];
-#ifdef ENABLE_IPv6
-	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) buf;
-#endif
-	struct sockaddr_in *sin = (struct sockaddr_in *) buf;
-	struct sockaddr *saddr = (struct sockaddr *) buf;
-	gpointer address;
-	socklen_t len;
-	int family;
-	
-	len = MIN_SOCKADDR_BUFLEN;
-	
-	if (getpeername (CAMEL_TCP_STREAM_SSL (stream)->priv->sockfd, saddr, &len) == -1)
-		return NULL;
-	
-	if (saddr->sa_family == AF_INET) {
-		family = CAMEL_TCP_ADDRESS_IPv4;
-		address = &sin->sin_addr;
-#ifdef ENABLE_IPv6
-	} else if (saddr->sa_family == AF_INET6) {
-		family = CAMEL_TCP_ADDRESS_IPv6;
-		address = &sin6->sin6_addr;
-#endif
-	} else
+	struct sockaddr *saddr = (struct sockaddr *) (malloc (*len));
+
+	if (getpeername (CAMEL_TCP_STREAM_SSL (stream)->priv->sockfd, saddr, len) == -1)
 		return NULL;
-	
-	return camel_tcp_address_new (family, sin->sin_port, len, address);
+
+	return saddr;
 }
 
 #endif /* HAVE_OPENSSL */
+#endif /* HAVE_NSS */
Only in .: camel-tcp-stream-openssl.c.rej
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-tcp-stream-raw.c ./camel-tcp-stream-raw.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-tcp-stream-raw.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-tcp-stream-raw.c	2007-05-12 10:24:11.000000000 +0200
@@ -26,6 +26,7 @@
 
 #include <errno.h>
 #include <fcntl.h>
+#include <signal.h>
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
@@ -63,6 +64,12 @@
 static int stream_setsockopt (CamelTcpStream *stream, const CamelSockOptData *data);
 static struct sockaddr *stream_get_local_address (CamelTcpStream *stream, socklen_t *len);
 static struct sockaddr *stream_get_remote_address (CamelTcpStream *stream, socklen_t *len);
+static ssize_t stream_read_nb (CamelTcpStream *stream, char *buffer, size_t n);
+
+static void signal_swallow( int num )
+{
+	printf ("Connection troubles\n");
+}
 
 static void
 camel_tcp_stream_raw_class_init (CamelTcpStreamRawClass *camel_tcp_stream_raw_class)
@@ -73,13 +80,16 @@
 		CAMEL_STREAM_CLASS (camel_tcp_stream_raw_class);
 	
 	parent_class = CAMEL_TCP_STREAM_CLASS (camel_type_get_global_classfuncs (camel_tcp_stream_get_type ()));
-	
+
+	signal( SIGPIPE, signal_swallow );
+
 	/* 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;
 	
+	camel_tcp_stream_class->read_nb = stream_read_nb;
 	camel_tcp_stream_class->connect = stream_connect;
 	camel_tcp_stream_class->getsockopt = stream_getsockopt;
 	camel_tcp_stream_class->setsockopt  = stream_setsockopt;
@@ -253,6 +263,14 @@
 }
 
 static ssize_t
+stream_read_nb (CamelTcpStream *stream, char *buffer, size_t n)
+{
+	CamelTcpStreamRaw *raw = CAMEL_TCP_STREAM_RAW (stream);
+	
+	return camel_read_socket_nb (raw->sockfd, buffer, n);
+}
+
+static ssize_t
 stream_write (CamelStream *stream, const char *buffer, size_t n)
 {
 	CamelTcpStreamRaw *raw = CAMEL_TCP_STREAM_RAW (stream);
@@ -487,7 +505,7 @@
 			   get_sockopt_level (data),
 			   optname,
 			   (void *) &data->value,
-			   &optlen);
+			   (socklen_t*) &optlen);
 }
 
 static int
Only in .: camel-tcp-stream-raw.c.rej
Only in .: camel-tcp-stream-raw.lo
Only in .: camel-tcp-stream-raw.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-tcp-stream-ssl.c ./camel-tcp-stream-ssl.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-tcp-stream-ssl.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-tcp-stream-ssl.c	2007-05-12 10:32:23.000000000 +0200
@@ -86,6 +86,7 @@
 static int stream_setsockopt (CamelTcpStream *stream, const CamelSockOptData *data);
 static struct sockaddr *stream_get_local_address (CamelTcpStream *stream, socklen_t *len);
 static struct sockaddr *stream_get_remote_address (CamelTcpStream *stream, socklen_t *len);
+static ssize_t stream_read_nb (CamelTcpStream *stream, char *buffer, size_t n);
 
 struct _CamelTcpStreamSSLPrivate {
 	PRFileDesc *sockfd;
@@ -94,6 +95,7 @@
 	char *expected_host;
 	gboolean ssl_mode;
 	guint32 flags;
+	gboolean accepted;
 };
 
 static void
@@ -111,7 +113,8 @@
 	camel_stream_class->write = stream_write;
 	camel_stream_class->flush = stream_flush;
 	camel_stream_class->close = stream_close;
-	
+
+	camel_tcp_stream_class->read_nb = stream_read_nb;
 	camel_tcp_stream_class->connect = stream_connect;
 	camel_tcp_stream_class->getsockopt = stream_getsockopt;
 	camel_tcp_stream_class->setsockopt = stream_setsockopt;
@@ -336,6 +339,60 @@
 
 
 static ssize_t
+stream_read_nb (CamelTcpStream *stream, char *buffer, size_t n)
+{
+	CamelTcpStreamSSL *tcp_stream_ssl = CAMEL_TCP_STREAM_SSL (stream);
+	ssize_t nread;
+	PRSocketOptionData sockopts;
+	PRPollDesc pollfds[2];
+	gboolean nonblock;
+
+	/* get O_NONBLOCK options */
+	sockopts.option = PR_SockOpt_Nonblocking;
+	PR_GetSocketOption (tcp_stream_ssl->priv->sockfd, &sockopts);
+	sockopts.option = PR_SockOpt_Nonblocking;
+	nonblock = sockopts.value.non_blocking;
+	sockopts.value.non_blocking = TRUE;
+	PR_SetSocketOption (tcp_stream_ssl->priv->sockfd, &sockopts);
+
+	pollfds[0].fd = tcp_stream_ssl->priv->sockfd;
+	pollfds[0].in_flags = PR_POLL_READ;
+	
+	do {
+		PRInt32 res;
+
+		pollfds[0].out_flags = 0;
+		pollfds[1].out_flags = 0;
+		nread = -1;
+
+		res = PR_Poll(pollfds, 1, 0);
+		if (res == -1)
+			set_errno(PR_GetError());
+		else if (res == 0) {
+#ifdef ETIMEDOUT
+			errno = ETIMEDOUT;
+#else
+			errno = EIO;
+#endif
+		} else {
+			 do { 
+				nread = -1;
+				if (PR_Available (tcp_stream_ssl->priv->sockfd) != 0)
+					nread = PR_Read (tcp_stream_ssl->priv->sockfd, buffer, n);
+				if (nread == -1)
+					set_errno (PR_GetError ());
+			 } while (0 && (nread == -1 && PR_GetError () == PR_PENDING_INTERRUPT_ERROR)); 
+		}
+	} while (0 && (nread == -1 && (PR_GetError () == PR_PENDING_INTERRUPT_ERROR ||
+				 PR_GetError () == PR_IO_PENDING_ERROR ||
+				 PR_GetError () == PR_WOULD_BLOCK_ERROR)));
+	
+	/* restore O_NONBLOCK options */
+
+	return nread;
+}
+
+static ssize_t
 stream_read (CamelStream *stream, char *buffer, size_t n)
 {
 	CamelTcpStreamSSL *tcp_stream_ssl = CAMEL_TCP_STREAM_SSL (stream);
@@ -382,7 +439,8 @@
 			pollfds[1].out_flags = 0;
 			nread = -1;
 
-			res = PR_Poll(pollfds, 2, IO_TIMEOUT);
+			res = PR_Poll(pollfds, 2, PR_TicksPerSecond () * 15 /*IO_TIMEOUT*/);
+
 			if (res == -1)
 				set_errno(PR_GetError());
 			else if (res == 0) {
@@ -469,7 +527,7 @@
 			pollfds[1].out_flags = 0;
 			w = -1;
 
-			res = PR_Poll (pollfds, 2, IO_TIMEOUT);
+			res = PR_Poll (pollfds, 2, PR_TicksPerSecond () * 15 /*IO_TIMEOUT*/);
 			if (res == -1) {
 				set_errno(PR_GetError());
 				if (PR_GetError () == PR_PENDING_INTERRUPT_ERROR)
@@ -658,7 +716,7 @@
 	int i;
 	const char tohex[16] = "0123456789abcdef";
 
-	md5_get_digest (cert->derCert.data, cert->derCert.len, md5sum);
+	md5_get_digest ((const gchar *) cert->derCert.data, cert->derCert.len, md5sum);
 	for (i=0,f = fingerprint; i<16; i++) {
 		unsigned int c = md5sum[i];
 
@@ -676,7 +734,7 @@
 
 	fingerprint[47] = 0;
 
-	return g_strdup(fingerprint);
+	return g_strdup((gchar*) fingerprint);
 }
 
 /* lookup a cert uses fingerprint to index an on-disk file */
@@ -731,7 +789,7 @@
 		close (fd);
 		
 		if (nread != st.st_size) {
-			g_warning ("cert size read truncated %s: %u != %ld", path, nread, st.st_size);
+			/* g_warning ("cert size read truncated %s: %u != %ld", path, nread, st.st_size); */
 			g_byte_array_free(ccert->rawcert, TRUE);
 			ccert->rawcert = NULL;
 			g_free(fingerprint);
@@ -810,7 +868,7 @@
 	
 	stream = camel_stream_fs_new_with_name (path, O_WRONLY | O_CREAT | O_TRUNC, 0600);
 	if (stream != NULL) {
-		if (camel_stream_write (stream, ccert->rawcert->data, ccert->rawcert->len) == -1) {
+		if (camel_stream_write (stream, (const char *) ccert->rawcert->data, ccert->rawcert->len) == -1) {
 			g_warning ("Could not save cert: %s: %s", path, strerror (errno));
 			g_unlink (path);
 		}
@@ -861,11 +919,13 @@
 	CamelTcpStreamSSL *ssl;
 	CERTCertificate *cert;
 	SECStatus status = SECFailure;
+	struct _CamelTcpStreamSSLPrivate *priv;
 
 	g_return_val_if_fail (data != NULL, SECFailure);
 	g_return_val_if_fail (CAMEL_IS_TCP_STREAM_SSL (data), SECFailure);
 
 	ssl = data;
+	priv = ssl->priv;
 	
 	cert = SSL_PeerCertificate (sockfd);
 	if (cert == NULL)
@@ -910,6 +970,8 @@
 	camel_certdb_cert_unref(certdb, ccert);
 	camel_object_unref(certdb);
 
+	priv->accepted = accept;
+
 	return accept ? SECSuccess : SECFailure;
 
 #if 0
@@ -1057,19 +1119,22 @@
 		return NULL;
 	
 	SSL_OptionSet (ssl_fd, SSL_SECURITY, PR_TRUE);
+
 	if (ssl->priv->flags & CAMEL_TCP_STREAM_SSL_ENABLE_SSL2)
 		SSL_OptionSet (ssl_fd, SSL_ENABLE_SSL2, PR_TRUE);
 	else
 		SSL_OptionSet (ssl_fd, SSL_ENABLE_SSL2, PR_FALSE);
+
 	if (ssl->priv->flags & CAMEL_TCP_STREAM_SSL_ENABLE_SSL3)
 		SSL_OptionSet (ssl_fd, SSL_ENABLE_SSL3, PR_TRUE);
 	else
 		SSL_OptionSet (ssl_fd, SSL_ENABLE_SSL3, PR_FALSE);
+
 	if (ssl->priv->flags & CAMEL_TCP_STREAM_SSL_ENABLE_TLS)
 		SSL_OptionSet (ssl_fd, SSL_ENABLE_TLS, PR_TRUE);
 	else
 		SSL_OptionSet (ssl_fd, SSL_ENABLE_TLS, PR_FALSE);
-	
+
 	SSL_SetURL (ssl_fd, ssl->priv->expected_host);
 	
 	/*SSL_GetClientAuthDataHook (sslSocket, ssl_get_client_auth, (void *) certNickname);*/
Only in .: camel-tcp-stream-ssl.c.rej
Only in .: camel-tcp-stream-ssl.lo
Only in .: camel-tcp-stream-ssl.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-text-index.c ./camel-text-index.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-text-index.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-text-index.c	2007-05-12 10:01:18.000000000 +0200
@@ -1460,14 +1460,14 @@
 		return 0;
 	}
 
-	ptr = buffer;
-	ptrend = buffer+len;
+	ptr = (const unsigned char *) buffer;
+	ptrend = (const unsigned char *) buffer+len;
 	while ((c = camel_utf8_next(&ptr, ptrend))) {
 		if (g_unichar_isalnum(c)) {
 			c = g_unichar_tolower(c);
-			utf8len = g_unichar_to_utf8(c, utf8);
+			utf8len = g_unichar_to_utf8(c, (gchar *) utf8);
 			utf8[utf8len] = 0;
-			g_string_append(p->buffer, utf8);
+			g_string_append(p->buffer, (gchar *) utf8);
 		} else {
 			if (p->buffer->len > 0 && p->buffer->len <= CAMEL_TEXT_INDEX_MAX_WORDLEN) {
 				text_index_name_add_word(idn, p->buffer->str);
Only in .: camel-text-index.lo
Only in .: camel-text-index.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-transport.c ./camel-transport.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-transport.c	2007-04-20 13:25:00.000000000 +0200
+++ ./camel-transport.c	2007-03-11 16:44:11.000000000 +0100
@@ -66,7 +66,10 @@
 camel_transport_finalize (CamelObject *object)
 {
 	CamelTransport *xport = CAMEL_TRANSPORT (object);
-	
+
+	g_mutex_lock (xport->priv->send_lock);
+	g_mutex_unlock (xport->priv->send_lock);
+
 	g_mutex_free (xport->priv->send_lock);
 	g_free (xport->priv);
 }
Only in .: camel-transport.lo
Only in .: camel-transport.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-types.h ./camel-types.h
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-types.h	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-types.h	2007-05-12 10:00:17.000000000 +0200
@@ -62,6 +62,7 @@
 typedef struct _CamelStore CamelStore;
 typedef struct _CamelStream CamelStream;
 typedef struct _CamelStreamNull CamelStreamNull;
+typedef struct _CamelStreamGZip CamelStreamGZip;
 typedef struct _CamelStreamBuffer CamelStreamBuffer;
 typedef struct _CamelStreamDataWrapper CamelStreamDataWrapper;
 typedef struct _CamelStreamFilter CamelStreamFilter;
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-uid-cache.c ./camel-uid-cache.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-uid-cache.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-uid-cache.c	2007-05-12 10:01:18.000000000 +0200
@@ -66,7 +66,7 @@
 	int fd, i;
 	
 	dirname = g_path_get_dirname (filename);
-	if (g_mkdir_with_parents (dirname, 0777) == -1) {
+	if (e_util_mkdir_hier (dirname, 0777) == -1) {
 		g_free (dirname);
 		return NULL;
 	}
Only in .: camel-uid-cache.lo
Only in .: camel-uid-cache.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-url.c ./camel-url.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-url.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-url.c	2007-05-12 10:01:18.000000000 +0200
@@ -207,7 +207,9 @@
 		url->protocol = g_strdup (base->protocol);
 		url->user = g_strdup (base->user);
 		url->authmech = g_strdup (base->authmech);
-		url->passwd = g_strdup (base->passwd);
+		if (base->passwd)
+			url->passwd = g_strdup (base->passwd);
+		else url->passwd = NULL;
 		url->host = g_strdup (base->host);
 		url->port = base->port;
 
@@ -330,7 +332,7 @@
 #ifdef G_OS_WIN32
 	if (url->protocol && !strcmp(url->protocol, "file"))
 		return g_filename_to_uri(url->path, url->host, NULL);
-#endif
+#endif /* G_OS_WIN32 */
 	
 	str = g_string_sized_new (20);
 	
@@ -415,7 +417,8 @@
 		g_datalist_clear (&url->params);
 		g_free (url->query);
 		g_free (url->fragment);
-		
+
+		memset (url, 0, sizeof (CamelURL));
 		g_free (url);
 	}
 }
@@ -705,11 +708,12 @@
 {
 	CamelURL *out;
 
-	out = g_malloc(sizeof(*out));
+	out = g_malloc0(sizeof(*out));
 	out->protocol = g_strdup(in->protocol);
 	out->user = g_strdup(in->user);
 	out->authmech = g_strdup(in->authmech);
-	out->passwd = g_strdup(in->passwd);
+	if (in->passwd)
+		out->passwd = g_strdup(in->passwd);
 	out->host = g_strdup(in->host);
 	out->port = in->port;
 	out->path = g_strdup(in->path);
@@ -721,33 +725,3 @@
 
 	return out;
 }
-
-char *
-camel_url_decode_path (const char *path)
-{
-        gchar **comps;
-        char *new_path = NULL;
-        GString *str;
-        int i = 0;
-
-        if (!path)
-                return g_strdup("");    /* ??? or NULL? */
-
-        str = g_string_new (NULL);
-
-        comps = g_strsplit (path, "/", -1);
-        while (comps[i]) {
-                camel_url_decode (comps[i]);
-                g_string_append (str, comps[i]);
-                g_string_append_c (str, '/');
-                i++;
-        }
-
-        /* Strip-off the trailing "/" */
-        new_path = g_strndup (str->str, str->len-1);
-
-        g_strfreev (comps);
-        g_string_free (str, TRUE);
-
-        return new_path;
-}
Only in .: camel-url.lo
Only in .: camel-url.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-url-scanner.c ./camel-url-scanner.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-url-scanner.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-url-scanner.c	2007-05-12 10:01:18.000000000 +0200
@@ -100,7 +100,7 @@
 			return TRUE;
 		
 		inptr = pos;
-		if (camel_utf8_getc_limit ((const unsigned char **) &inptr, inend) == 0xffff)
+		if (camel_utf8_getc_limit ((const unsigned char **) &inptr, (const unsigned char *) inend) == 0xffff)
 			break;
 		
 		inlen = inend - inptr;
@@ -180,7 +180,7 @@
 	int i;
 
 	if (open_brace != NULL)
-		*open_brace == '\0';
+		*open_brace = '\0';
 
 	if (so > 0) {
 		for (i = 0; i < G_N_ELEMENTS (url_braces); i++) {
Only in .: camel-url-scanner.lo
Only in .: camel-url-scanner.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-utf8.c ./camel-utf8.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-utf8.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-utf8.c	2007-05-12 10:01:18.000000000 +0200
@@ -177,7 +177,7 @@
 
 	camel_utf8_putc(&p, c);
 	*p = 0;
-	g_string_append(out, buffer);
+	g_string_append(out, (const char*) buffer);
 }
 
 static const char utf7_alphabet[] =
@@ -363,10 +363,10 @@
 	while ( (c = camel_utf8_getc((const unsigned char **)&ptr)) ) {
 		guint16 s = g_htons(c);
 
-		g_byte_array_append(work, (char *)&s, 2);
+		g_byte_array_append(work, (const unsigned char *)&s, 2);
 	}
 
-	g_byte_array_append(work, "\000\000", 2);
+	g_byte_array_append(work,  (const unsigned char *) "\000\000", 2);
 	out = g_malloc(work->len);
 	memcpy(out, work->data, work->len);
 	g_byte_array_free(work, TRUE);
Only in .: camel-utf8.lo
Only in .: camel-utf8.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-vee-folder.c ./camel-vee-folder.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-vee-folder.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-vee-folder.c	2007-05-12 10:01:18.000000000 +0200
@@ -60,7 +60,7 @@
 static void vee_freeze(CamelFolder *folder);
 static void vee_thaw(CamelFolder *folder);
 
-static CamelMimeMessage *vee_get_message (CamelFolder *folder, const gchar *uid, CamelException *ex);
+static CamelMimeMessage *vee_get_message (CamelFolder *folder, const gchar *uid, gboolean full, CamelException *ex);
 static void vee_append_message(CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, char **appended_uid, CamelException *ex);
 static void vee_transfer_messages_to(CamelFolder *source, GPtrArray *uids, CamelFolder *dest, GPtrArray **transferred_uids, gboolean delete_originals, CamelException *ex);
 
@@ -385,11 +385,12 @@
 
 	md5_init(&ctx);
 	tmp = camel_service_get_url((CamelService *)folder->parent_store);
-	md5_update(&ctx, tmp, strlen(tmp));
+	md5_update(&ctx, (unsigned char*) tmp, strlen(tmp));
 	g_free(tmp);
-	md5_update(&ctx, folder->full_name, strlen(folder->full_name));
+	md5_update(&ctx, (unsigned char*)folder->full_name, strlen(folder->full_name));
 	md5_final(&ctx, digest);
-	camel_base64_encode_close(digest, 6, FALSE, buffer, &state, &save);
+
+	camel_base64_encode_close(digest, 6, FALSE, (unsigned char *) buffer, (int*) &state, (int*) &save);
 
 	for (i=0;i<8;i++) {
 		if (buffer[i] == '+')
@@ -508,14 +509,14 @@
 }
 
 static CamelMimeMessage *
-vee_get_message(CamelFolder *folder, const char *uid, CamelException *ex)
+vee_get_message(CamelFolder *folder, const char *uid, CamelFolderReceiveType type, gint param, CamelException *ex)
 {
 	CamelVeeMessageInfo *mi;
 	CamelMimeMessage *msg = NULL;
 
 	mi = (CamelVeeMessageInfo *)camel_folder_summary_uid(folder->summary, uid);
 	if (mi) {
-		msg =  camel_folder_get_message(mi->real->summary->folder, camel_message_info_uid(mi)+8, ex);
+		msg =  camel_folder_get_message(mi->real->summary->folder, camel_message_info_uid(mi)+8, type, param, ex);
 		camel_message_info_free((CamelMessageInfo *)mi);
 	} else {
 		camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID,
@@ -1336,6 +1337,7 @@
 			g_hash_table_insert(matches_hash, matches_changed->pdata[i], matches_changed->pdata[i]);
 		}
 		dd(printf("\n"));
+
 		for (i=0;i<changed->len;i++) {
 			uid = changed->pdata[i];
 			if (strlen(uid)+9 > vuidlen) {
Only in .: camel-vee-folder.lo
Only in .: camel-vee-folder.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-vee-store.c ./camel-vee-store.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-vee-store.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-vee-store.c	2007-05-12 10:01:18.000000000 +0200
@@ -147,7 +147,7 @@
 	const char *tmp;
 	CamelURL *url;
 
-	fi = g_malloc0(sizeof(*fi));
+	fi = camel_folder_info_new ();
 	fi->full_name = g_strdup(name);
 	tmp = strrchr(name, '/');
 	if (tmp == NULL)
Only in .: camel-vee-store.lo
Only in .: camel-vee-store.o
Only in .: camel-vee-summary.lo
Only in .: camel-vee-summary.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-vtrash-folder.c ./camel-vtrash-folder.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-vtrash-folder.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-vtrash-folder.c	2007-05-12 10:01:18.000000000 +0200
@@ -51,8 +51,6 @@
 } vdata[] = {
 	{ CAMEL_VTRASH_NAME, N_("Trash"), "(match-all (system-flag \"Deleted\"))", CAMEL_MESSAGE_DELETED, CAMEL_FOLDER_IS_TRASH,
 	  N_("Cannot copy messages to the Trash folder") },
-	{ CAMEL_VJUNK_NAME, N_("Junk"), "(match-all (system-flag \"Junk\"))", CAMEL_MESSAGE_JUNK, CAMEL_FOLDER_IS_JUNK,
-	  N_("Cannot copy messages to the Junk folder") },
 };
 
 static CamelVeeFolderClass *camel_vtrash_folder_parent;
@@ -119,7 +117,7 @@
 	CamelFolder *folder = (CamelFolder *)object;
 	int i;
 	guint32 tag;
-	int unread = -1, deleted = 0, junked = 0, visible = 0, count = -1;
+	int unread = -1, deleted = 0, count = -1;
 
 	for (i=0;i<args->argc;i++) {
 		CamelArgGet *arg = &args->argv[i];
@@ -131,8 +129,6 @@
 		switch (tag & CAMEL_ARG_TAG) {
 		case CAMEL_FOLDER_ARG_UNREAD:
 		case CAMEL_FOLDER_ARG_DELETED:
-		case CAMEL_FOLDER_ARG_JUNKED:
-		case CAMEL_FOLDER_ARG_VISIBLE:
 			/* This is so we can get the values atomically, and also so we can calculate them only once */
 			if (unread == -1) {
 				int j;
@@ -148,10 +144,6 @@
 							unread++;
 						if (flags & CAMEL_MESSAGE_DELETED)
 							deleted++;
-						if (flags & CAMEL_MESSAGE_JUNK)
-							junked++;
-						if ((flags & (CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_JUNK)) == 0)
-							visible++;
 						camel_message_info_free(info);
 					}
 				}
@@ -164,12 +156,6 @@
 			case CAMEL_FOLDER_ARG_DELETED:
 				count = deleted;
 				break;
-			case CAMEL_FOLDER_ARG_JUNKED:
-				count = junked;
-				break;
-			case CAMEL_FOLDER_ARG_VISIBLE:
-				count = visible;
-				break;
 			}
 
 			*arg->ca_int = count;
Only in .: camel-vtrash-folder.lo
Only in .: camel-vtrash-folder.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-win32.c ./camel-win32.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/camel-win32.c	2007-05-12 09:58:58.000000000 +0200
+++ ./camel-win32.c	2007-05-12 10:01:18.000000000 +0200
@@ -55,7 +55,7 @@
                 return;
         }
 
-        localedir = e_util_replace_prefix (E_DATA_SERVER_PREFIX, e_util_get_cp_prefix (), EVOLUTION_LOCALEDIR);
+        localedir = e_util_replace_prefix (E_DATA_SERVER_PREFIX, e_util_get_cp_prefix (), LOCALEDIR);
 
 	libexecdir = e_util_replace_prefix (E_DATA_SERVER_PREFIX, e_util_get_prefix (), CAMEL_LIBEXECDIR);
 	providerdir = e_util_replace_prefix (E_DATA_SERVER_PREFIX, e_util_get_prefix (), CAMEL_PROVIDERDIR);
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/: ChangeLog
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/: ChangeLog.pre-1-4
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/: CODING.STYLE
Only in .: .deps
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/: devel-docs
Only in .: libcamel-lite-1.2.la
Only in .: libcamel-lite-provider-1.2.la
Only in .: .libs
Only in .: Makefile
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/Makefile.am ./Makefile.am
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/Makefile.am	2007-05-12 09:58:58.000000000 +0200
+++ ./Makefile.am	2007-05-12 10:01:18.000000000 +0200
@@ -1,12 +1,10 @@
-## Process this file with automake to produce Makefile.in
+SUBDIRS = . providers
 
-SUBDIRS = . providers tests
+AM_CFLAGS = -fPIC
 
 if OS_WIN32
-LIBCAMEL_PLATFORM_DEP_SOURCES = \
-	camel-win32.c
+LIBCAMEL_PLATFORM_DEP_SOURCES = camel-win32.c
 LIBCAMEL_PROVIDER_PLATFORM_DEP_SOURCES =
-LOCK_HELPER =
 else
 LIBCAMEL_PLATFORM_DEP_SOURCES = \
 	camel-lock-client.c \
@@ -14,34 +12,38 @@
 LIBCAMEL_PROVIDER_PLATFORM_DEP_SOURCES =	\
 	camel-movemail.c			\
 	camel-sasl-kerberos4.c
-LOCK_HELPER = camel-lock-helper-1.2
 endif
 
 %-$(API_VERSION).pc: %.pc
 	 cp $< $@
 
 pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_in_files = camel.pc.in camel-provider.pc.in
+pkgconfig_in_files = camel-lite.pc.in camel-lite-provider.pc.in
 pkgconfig_DATA = $(pkgconfig_in_files:.pc.in=-$(API_VERSION).pc)
 
-libcamelincludedir = $(privincludedir)/camel
-libcamel_providerincludedir = $(privincludedir)/camel
-
-camellibexecdir = $(libexecdir)
-camellibexec_PROGRAMS =	$(LOCK_HELPER) camel-index-control-1.2
-
-lib_LTLIBRARIES = libcamel-1.2.la libcamel-provider-1.2.la
-
-INCLUDES = -I.. -I$(srcdir)/.. 			 	\
-	-I$(top_srcdir)/intl			 	\
-	-DCAMEL_LIBEXECDIR=\""$(camellibexecdir)"\"	\
-	-DCAMEL_PROVIDERDIR=\""$(camel_providerdir)"\" 	\
-	-DG_LOG_DOMAIN=\"camel\"			\
-	-DE_DATA_SERVER_PREFIX=\"$(prefix)\"		\
-	-DEVOLUTION_LOCALEDIR=\""$(localedir)"\"	\
+libcamel_liteincludedir = $(includedir)/camel-lite/camel
+libcamel_lite_providerincludedir = $(includedir)/camel-lite/camel
+camel_litelibexecdir = $(libexecdir)
+
+lib_LTLIBRARIES = libcamel-lite-1.2.la libcamel-lite-provider-1.2.la
+
+INCLUDES = -I.. -I$(srcdir)/.. \
+	-I$(top_srcdir)/intl \
+	-DCAMEL_LIBEXECDIR=\""$(camel_litelibexecdir)"\" \
+	-DCAMEL_PROVIDERDIR=\""$(camel_lite_providerdir)"\" \
+	-DG_LOG_DOMAIN=\"camel-lite\" \
+	-DTRANSDOM=\"$(GETTEXT_PACKAGE)\" \
+	-DE_DATA_SERVER_PREFIX=\"$(prefix)\" \
+	-DLOCALEDIR=\""$(localedir)"\" \
 	$(CAMEL_CFLAGS)
 
-libcamel_provider_1_2_la_SOURCES = 		\
+if ENABLE_OPENSSL
+SSL_FILE = camel-tcp-stream-openssl.c
+else
+SSL_FILE = camel-tcp-stream-ssl.c
+endif
+
+libcamel_lite_provider_1_2_la_SOURCES = 	\
 	camel-cipher-context.c			\
 	camel-digest-folder.c			\
 	camel-digest-store.c			\
@@ -76,9 +78,8 @@
 	camel-smime-context.c			\
 	camel-store-summary.c			\
 	camel-store.c				\
-	camel-tcp-stream-openssl.c		\
+	$(SSL_FILE)				\
 	camel-tcp-stream-raw.c			\
-	camel-tcp-stream-ssl.c			\
 	camel-tcp-stream.c			\
 	camel-transport.c			\
 	camel-uid-cache.c			\
@@ -88,7 +89,7 @@
 	camel-vtrash-folder.c			\
 	$(LIBCAMEL_PROVIDER_PLATFORM_DEP_SOURCES)
 
-libcamel_providerinclude_HEADERS =		\
+libcamel_lite_providerinclude_HEADERS =		\
 	camel-cipher-context.h			\
 	camel-digest-folder.h			\
 	camel-digest-store.h			\
@@ -139,16 +140,17 @@
 	camel-vee-summary.h			\
 	camel-vtrash-folder.h
 
-libcamel_provider_1_2_la_LDFLAGS = -version-info $(LIBCAMEL_CURRENT):$(LIBCAMEL_REVISION):$(LIBCAMEL_AGE) $(NO_UNDEFINED)
+libcamel_lite_provider_1_2_la_LDFLAGS = -version-info $(LIBCAMEL_CURRENT):$(LIBCAMEL_REVISION):$(LIBCAMEL_AGE) $(NO_UNDEFINED)
 
-libcamel_provider_1_2_la_LIBADD =			\
-	$(top_builddir)/libedataserver/libedataserver-${API_VERSION}.la 	\
-	libcamel-1.2.la				\
+libcamel_lite_provider_1_2_la_LIBADD =		\
+	$(top_builddir)/libedataserver/libedataserver-${API_VERSION}.a 	\
+	libcamel-lite-1.2.la			\
 	$(CAMEL_LIBS)				\
 	$(SOCKET_LIBS)				\
-	$(REGEX_LIBS)
+	$(REGEX_LIBS)				\
+	$(SSL_LIBS)
 
-libcamel_1_2_la_SOURCES = 			\
+libcamel_lite_1_2_la_SOURCES = 			\
 	broken-date-parser.c			\
 	camel-address.c				\
 	camel-arg.c				\
@@ -204,8 +206,8 @@
 	camel-stream-filter.c			\
 	camel-stream-fs.c			\
 	camel-stream-mem.c			\
+	camel-stream-gzip.c			\
 	camel-stream-null.c			\
-	camel-stream-vfs.c			\
 	camel-stream.c				\
 	camel-string-utils.c			\
 	camel-text-index.c			\
@@ -215,7 +217,7 @@
 	camel.c					\
 	$(LIBCAMEL_PLATFORM_DEP_SOURCES)
 
-libcamelinclude_HEADERS =			\
+libcamel_liteinclude_HEADERS =			\
 	broken-date-parser.h			\
 	camel-address.h				\
 	camel-arg.h				\
@@ -273,9 +275,9 @@
 	camel-stream-filter.h			\
 	camel-stream-fs.h			\
 	camel-stream-mem.h			\
+	camel-stream-gzip.h			\
 	camel-stream-null.h			\
 	camel-stream-process.h			\
-	camel-stream-vfs.h			\
 	camel-stream.h				\
 	camel-string-utils.h			\
 	camel-text-index.h			\
@@ -283,69 +285,21 @@
 	camel-url-scanner.h			\
 	camel-url.h				\
 	camel-utf8.h				\
+	camel-lock-helper.h			\
 	camel.h
 
-libcamel_1_2_la_LDFLAGS = -version-info $(LIBCAMEL_CURRENT):$(LIBCAMEL_REVISION):$(LIBCAMEL_AGE) $(NO_UNDEFINED)
+libcamel_lite_1_2_la_LDFLAGS = -version-info 0:0:0 $(NO_UNDEFINED)
 
-libcamel_1_2_la_LIBADD =				\
-	$(top_builddir)/libedataserver/libedataserver-${API_VERSION}.la \
+libcamel_lite_1_2_la_LIBADD =				\
+	$(top_builddir)/libedataserver/libedataserver-${API_VERSION}.a  \
 	$(CAMEL_LIBS)							\
 	$(SOCKET_LIBS)							\
-	$(REGEX_LIBS)
-
-
-camel_lock_helper_1_2_SOURCES = 		\
-	camel-lock-helper.c 			\
-	camel-lock-helper.h
-
-# NOTE: This needs to be cleaned up, it shouldn't link with all this crap,
-# because it might be setuid.
-camel_lock_helper_1_2_LDADD =			\
-	camel-lock.o				\
-	$(libcamel_1_2_la_LIBADD)
-
-camel_index_control_1_2_SOURCES =		\
-	camel-index-control.c
-
-camel_index_control_1_2_LDADD =			\
-	libcamel-1.2.la				\
-	$(libcamel_1_2_la_LIBADD)
+	$(REGEX_LIBS)							\
+	$(SSL_LIBS)
 
 camel-mime-tables.c: gentables.pl
 	perl gentables.pl > $@
 
-install-exec-hook:
-	@if test -n "$(CAMEL_LOCK_HELPER_USER)"; then \
-	    if test `whoami` = root ; then \
-	 	chown $(CAMEL_LOCK_HELPER_USER) $(DESTDIR)$(camellibexecdir)/camel-lock-helper-$(API_VERSION) ; \
-		chmod u+s $(DESTDIR)$(camellibexecdir)/camel-lock-helper-$(API_VERSION) ; \
-	    else \
-	    	echo '*** WARNING ***' ; \
-		    echo "Camel will not be able to open mbox files until you perform the following steps:" ; \
-		    echo "    1. Become root" ; \
-		    echo "    2. chown $(CAMEL_LOCK_HELPER_USER) $(DESTDIR)$(sbindir)/camel-lock-helper" ; \
-		    echo "    3. chmod u+s $(DESTDIR)$(sbindir)/camel-lock-helper" ; \
-		    echo '*** WARNING ***' ; \
-	    fi \
-	else \
-	    echo "No user to chown to"; \
-	fi
-	@if test -n "$(CAMEL_LOCK_HELPER_GROUP)"; then \
-	    if test `whoami` = root ; then \
-	    	chgrp $(CAMEL_LOCK_HELPER_GROUP) $(DESTDIR)$(camellibexecdir)/camel-lock-helper-$(API_VERSION) ; \
-		    chmod g+s $(DESTDIR)$(camellibexecdir)/camel-lock-helper-$(API_VERSION) ; \
-	    else \
-	    	echo '*** WARNING ***' ; \
-		    echo "Camel will not be able to open mbox files until you perform the following steps:" ; \
-		    echo "    1. Become root" ; \
-		    echo "    2. chgrp $(CAMEL_LOCK_HELPER_GROUP) $(DESTDIR)$(camellibexecdir)/camel-lock-helper-$(API_VERSION)" ; \
-		    echo "    3. chmod g+s $(DESTDIR)$(camellibexecdir)/camel-lock-helper-$(API_VERSION)" ; \
-		    echo '*** WARNING ***' ; \
-	    fi \
-	else \
-	    echo "No user to chown to"; \
-	fi
-
 noinst_HEADERS =				\
 	broken-date-parser.h			\
 	camel-charset-map-private.h		\
@@ -353,8 +307,6 @@
 
 EXTRA_DIST =					\
 	$(pkgconfig_in_files)	 		\
-	gentables.pl				\
-	ChangeLog.pre-1-4			\
-	README
+	gentables.pl
 
 DISTCLEANFILES = $(pkgconfig_DATA)
Only in .: Makefile.am.rej
Only in .: Makefile.in
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers: .cvsignore
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers: groupwise
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers: hula
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/camel-imap-command.c ./providers/imap/camel-imap-command.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/camel-imap-command.c	2007-05-12 09:58:53.000000000 +0200
+++ ./providers/imap/camel-imap-command.c	2007-05-12 10:17:00.000000000 +0200
@@ -60,6 +60,10 @@
 static char *imap_command_strdup_printf (CamelImapStore *store,
 					 const char *fmt, ...);
 
+
+
+
+
 /**
  * camel_imap_command:
  * @store: the IMAP store
@@ -93,19 +97,24 @@
 {
 	va_list ap;
 	char *cmd;
-	
+
 	CAMEL_SERVICE_REC_LOCK (store, connect_lock);
-	
+
 	if (fmt) {
 		va_start (ap, fmt);
 		cmd = imap_command_strdup_vprintf (store, fmt, ap);
 		va_end (ap);
 	} else {
-		camel_object_ref(folder);
-		if (store->current_folder)
-			camel_object_unref(store->current_folder);
+
+		/* camel_object_ref(folder); 
+		if (store->current_folder && CAMEL_IS_OBJECT (store->current_folder))
+			camel_object_unref(store->current_folder); */
+
 		store->current_folder = folder;
-		cmd = imap_command_strdup_printf (store, "SELECT %F", folder->full_name);
+		if (store->capabilities & IMAP_CAPABILITY_CONDSTORE) 
+			cmd = imap_command_strdup_printf (store, "SELECT %F (CONDSTORE)", folder->full_name);
+		else 
+			cmd = imap_command_strdup_printf (store, "SELECT %F", folder->full_name);
 	}
 	
 	if (!imap_command_start (store, folder, cmd, ex)) {
@@ -118,6 +127,7 @@
 	return imap_read_response (store, ex);
 }
 
+
 /**
  * camel_imap_command_start:
  * @store: the IMAP store
@@ -163,13 +173,15 @@
 	va_start (ap, fmt);
 	cmd = imap_command_strdup_vprintf (store, fmt, ap);
 	va_end (ap);
-	
+
 	CAMEL_SERVICE_REC_LOCK (store, connect_lock);
+
 	ok = imap_command_start (store, folder, cmd, ex);
 	g_free (cmd);
-	
+
 	if (!ok)
 		CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
+
 	return ok;
 }
 
@@ -178,20 +190,43 @@
 		    const char *cmd, CamelException *ex)
 {
 	ssize_t nwritten;
-	
-	g_return_val_if_fail(store->ostream!=NULL, FALSE);
-	g_return_val_if_fail(store->istream!=NULL, FALSE);
-	
+	gchar *resp = NULL;
+	CamelException myex = CAMEL_EXCEPTION_INITIALISER;
+	gchar *full_cmd = NULL;
+	guint len = 0;
+
+	if (store->ostream == NULL || ((CamelObject *)store->ostream)->ref_count <= 0)
+	{
+		if (store->has_login && !camel_service_connect ((CamelService*)store, ex))
+			return FALSE;
+	}
+
+	/* g_mutex_lock (store->stream_lock); */
+
+	if (store->ostream==NULL) return FALSE;
+	if (store->istream==NULL) return FALSE;
+
+	/* g_mutex_unlock (store->stream_lock);*/
+
+
+	/* Also read imap_update_summary and all of the IDLE crap */
+	if (!store->dontdistridlehack) 
+		camel_imap_store_stop_idle (store);
+	/* else
+		printf ("dont distr\n"); */
+
 	/* Check for current folder */
-	if (folder && folder != store->current_folder) {
+	if (folder && folder != store->current_folder) 
+	{
 		CamelImapResponse *response;
 		CamelException internal_ex;
-		
+
 		response = camel_imap_command (store, folder, ex, NULL);
 		if (!response)
 			return FALSE;
 		camel_exception_init (&internal_ex);
-		camel_imap_folder_selected (folder, response, &internal_ex);
+		/* g_print ("select\n"); */
+		camel_imap_folder_selected (folder, response, &internal_ex, FALSE);
 		camel_imap_response_free (store, response);
 		if (camel_exception_is_set (&internal_ex)) {
 			camel_exception_xfer (ex, &internal_ex);
@@ -214,19 +249,51 @@
 		
 		fprintf (stderr, "sending : %c%.5u %s\r\n", store->tag_prefix, store->command, mask);
 	}
-	
-	nwritten = camel_stream_printf (store->ostream, "%c%.5u %s\r\n",
-					store->tag_prefix, store->command++, cmd);
-	
-	if (nwritten == -1) {
+
+	/* g_mutex_lock (store->stream_lock); */
+
+	if (store->ostream==NULL || ((CamelObject *)store->ostream)->ref_count <= 0) 
+		{ /* g_mutex_unlock (store->stream_lock); */ return FALSE; }
+	if (store->istream==NULL || ((CamelObject *)store->istream)->ref_count <= 0) 
+		{ /* g_mutex_unlock (store->stream_lock); */ return FALSE; }
+
+	/* Read away whatever we got */
+	while (camel_imap_store_readline_nb (store, &resp, &myex) > 0)
+	{
+		imap_debug ("unsolitcited: ");
+		imap_debug (resp);
+		imap_debug ("\n");
+
+		g_free (resp);
+		resp=NULL;
+	}
+	if (resp)
+		g_free (resp);
+
+	full_cmd = g_strdup_printf ("%c%.5u %s\r\n", store->tag_prefix, 
+		store->command++, cmd);
+	len = strlen (full_cmd);
+
+	/* printf ("-> %s\n", full_cmd); */
+
+	nwritten = camel_stream_write (store->ostream, full_cmd, len);
+
+	/* g_mutex_unlock (store->stream_lock); */
+
+	if (nwritten != len) 
+	{
+		CamelException mex = CAMEL_EXCEPTION_INITIALISER;
+
 		if (errno == EINTR)
 			camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
 					     _("Operation cancelled"));
 		else
 			camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
 					     g_strerror (errno));
-		
-		camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
+
+		camel_service_disconnect (CAMEL_SERVICE (store), FALSE, &mex);
+		camel_service_connect (CAMEL_SERVICE (store), &mex);
+
 		return FALSE;
 	}
 	
@@ -253,7 +320,7 @@
 camel_imap_command_continuation (CamelImapStore *store, const char *cmd,
 				 size_t cmdlen, CamelException *ex)
 {
-	if (!camel_imap_store_connected (store, ex))
+	if (!camel_disco_store_check_online ((CamelDiscoStore*)store, ex))
 		return NULL;
 
 	g_return_val_if_fail(store->ostream!=NULL, NULL);
@@ -268,6 +335,7 @@
 			camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
 					     g_strerror (errno));
 		camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
+
 		CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
 		return NULL;
 	}
@@ -275,6 +343,7 @@
 	return imap_read_response (store, ex);
 }
 
+
 /**
  * camel_imap_command_response:
  * @store: the IMAP store
@@ -301,7 +370,9 @@
 		CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
 		return CAMEL_IMAP_RESPONSE_ERROR;
 	}
-	
+
+	/* printf ("<-- %s\n", respbuf); */
+
 	switch (*respbuf) {
 	case '*':
 		if (!g_ascii_strncasecmp (respbuf, "* BYE", 5)) {
@@ -344,10 +415,67 @@
 		break;
 	}
 	*response = respbuf;
-	
+
 	if (type == CAMEL_IMAP_RESPONSE_ERROR ||
-	    type == CAMEL_IMAP_RESPONSE_TAGGED)
+	    type == CAMEL_IMAP_RESPONSE_TAGGED) 
 		CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
+
+	return type;
+}
+
+
+CamelImapResponseType
+camel_imap_command_response_idle (CamelImapStore *store, char **response,
+			     CamelException *ex)
+{
+	CamelImapResponseType type;
+	char *respbuf;
+
+	if (camel_imap_store_readline (store, &respbuf, ex) < 0)
+		return CAMEL_IMAP_RESPONSE_ERROR;
+
+	switch (*respbuf) {
+	case '*':
+		if (!g_ascii_strncasecmp (respbuf, "* BYE", 5)) {
+			/* Connection was lost, no more data to fetch */
+			camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
+			camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+					      _("Server unexpectedly disconnected: %s"),
+					      _("Unknown error")); /* g_strerror (104));  FIXME after 1.0 is released */
+			store->connected = FALSE;
+			g_free (respbuf);
+			respbuf = NULL;
+			type = CAMEL_IMAP_RESPONSE_ERROR;
+			break;
+		}
+		
+		/* Read the rest of the response. */
+		type = CAMEL_IMAP_RESPONSE_UNTAGGED;
+		respbuf = imap_read_untagged (store, respbuf, ex);
+		if (!respbuf)
+			type = CAMEL_IMAP_RESPONSE_ERROR;
+		else if (!g_ascii_strncasecmp (respbuf, "* OK [ALERT]", 12)
+			 || !g_ascii_strncasecmp (respbuf, "* NO [ALERT]", 12)
+			 || !g_ascii_strncasecmp (respbuf, "* BAD [ALERT]", 13)) {
+			char *msg;
+
+			/* for imap ALERT codes, account user@host */
+			/* we might get a ']' from a BAD response since we +12, but who cares? */
+			msg = g_strdup_printf(_("Alert from IMAP server %s@%s:\n%s"),
+					      ((CamelService *)store)->url->user, ((CamelService *)store)->url->host, respbuf+12);
+			camel_session_alert_user(((CamelService *)store)->session, CAMEL_SESSION_ALERT_WARNING, msg, FALSE);
+			g_free(msg);
+		} else if (!g_ascii_strncasecmp (respbuf, "* BAD Invalid tag",17))
+			type = CAMEL_IMAP_RESPONSE_ERROR;
+		break;
+	case '+':
+		type = CAMEL_IMAP_RESPONSE_CONTINUATION;
+		break;
+	default:
+		type = CAMEL_IMAP_RESPONSE_TAGGED;
+		break;
+	}
+	*response = respbuf;
 	
 	return type;
 }
@@ -364,8 +492,9 @@
 	 * we're still locked. This lock is owned by response
 	 * and gets unlocked when response is freed.
 	 */
+
 	CAMEL_SERVICE_REC_LOCK (store, connect_lock);
-	
+
 	response = g_new0 (CamelImapResponse, 1);
 	if (store->current_folder && camel_disco_store_status (CAMEL_DISCO_STORE (store)) != CAMEL_DISCO_STORE_RESYNCING) {
 		response->folder = store->current_folder;
@@ -383,7 +512,7 @@
 	}
 	
 	response->status = respbuf;
-	
+
 	/* Check for OK or continuation response. */
 	if (*respbuf == '+')
 		return response;
@@ -622,6 +751,7 @@
 	}
 	
 	g_free (response);
+
 	CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
 }
 
@@ -780,8 +910,9 @@
 			} else if (*p == 'G') {
 				string = camel_utf8_utf7(string);
 			}
-				
-			arglen = strlen (string);
+
+			if (string)
+				arglen = strlen (string);
 			g_ptr_array_add (args, string);
 			if (imap_is_atom (string)) {
 				len += arglen;
Only in ./providers/imap: camel-imap-command.c.rej
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/camel-imap-command.h ./providers/imap/camel-imap-command.h
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/camel-imap-command.h	2007-05-12 09:58:53.000000000 +0200
+++ ./providers/imap/camel-imap-command.h	2007-05-12 10:01:04.000000000 +0200
@@ -74,6 +74,9 @@
 						    char **respbuf,
 						    CamelException *ex);
 
+CamelImapResponseType camel_imap_command_response_idle (CamelImapStore *store, char **response,
+						        CamelException *ex);
+
 G_END_DECLS
 
 #endif /* CAMEL_IMAP_COMMAND_H */
Only in ./providers/imap: camel-imap-command.lo
Only in ./providers/imap: camel-imap-command.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/camel-imap-folder.c ./providers/imap/camel-imap-folder.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/camel-imap-folder.c	2007-05-12 09:58:53.000000000 +0200
+++ ./providers/imap/camel-imap-folder.c	2007-05-12 10:15:55.000000000 +0200
@@ -1,10 +1,15 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-imap-folder.c: class for an imap folder */
-
-/* 
+/* camel-imap-folder.c: class for an imap folder
+ * 
+ * This is the mmap version of camel-imap-folder.c which has a memory
+ * consumption reduced imap_update_summary implementation that will
+ * periodically instruct the mmap CamelFolderSummary instance to sync
+ * headers to disk.
+ *
  * Authors:
  *   Dan Winship <danw@ximian.com>
  *   Jeffrey Stedfast <fejj@ximian.com> 
+ *   Philip Van Hoof <pvanhoof@gnome.org>
  *
  * Copyright (C) 2000, 2001 Ximian, Inc.
  *
@@ -23,6 +28,11 @@
  * USA
  */
 
+/* BODY always returns "textual data", which means a series of characters 
+   no containing NUL, CR, or LF, of length <= 1000.*/
+
+#define MAX_LINE_LEN 1024 
+
 #include <config.h> 
 
 #include <ctype.h>
@@ -39,6 +49,7 @@
 #include <libedataserver/e-data-server-util.h>
 #include <libedataserver/e-time-utils.h>
 
+
 #include "camel-data-wrapper.h"
 #include "camel-debug.h"
 #include "camel-disco-diary.h"
@@ -71,6 +82,9 @@
 #include "camel-imap-utils.h"
 #include "camel-imap-wrapper.h"
 
+
+#include <camel/camel-tcp-stream.h>
+
 #define d(x) 
 
 /* set to -1 for infinite size (suggested max command-line length is
@@ -86,7 +100,8 @@
 static void imap_finalize (CamelObject *object);
 static int imap_getv(CamelObject *object, CamelException *ex, CamelArgGetV *args);
 
-static void imap_rescan (CamelFolder *folder, int exists, CamelException *ex);
+static gboolean imap_rescan_condstore (CamelFolder *folder, int exists, const char *highestmodseq, CamelException *ex);
+static gboolean imap_rescan (CamelFolder *folder, int exists, CamelException *ex);
 static void imap_refresh_info (CamelFolder *folder, CamelException *ex);
 static void imap_sync_online (CamelFolder *folder, CamelException *ex);
 static void imap_sync_offline (CamelFolder *folder, CamelException *ex);
@@ -95,10 +110,11 @@
 static void imap_expunge_uids_resyncing (CamelFolder *folder, GPtrArray *uids, CamelException *ex);
 static void imap_cache_message (CamelDiscoFolder *disco_folder, const char *uid, CamelException *ex);
 static void imap_rename (CamelFolder *folder, const char *new);
+static void imap_set_push_email (CamelFolder *folder, gboolean setting);
 
 /* message manipulation */
 static CamelMimeMessage *imap_get_message (CamelFolder *folder, const gchar *uid,
-					   CamelException *ex);
+					   CamelFolderReceiveType type, gint param, CamelException *ex);
 static void imap_append_online (CamelFolder *folder, CamelMimeMessage *message,
 				const CamelMessageInfo *info, char **appended_uid,
 				CamelException *ex);
@@ -132,6 +148,10 @@
 static CamelObjectClass *parent_class;
 
 static GData *parse_fetch_response (CamelImapFolder *imap_folder, char *msg_att);
+static void camel_imap_folder_changed_for_idle (CamelFolder *folder, int exists,
+			   GArray *expunged, CamelException *ex);
+
+GPtrArray* _camel_imap_store_get_recent_messages (CamelImapStore *imap_store, const char *folder_name, int *messages, int *unseen, gboolean withthem);
 
 #ifdef G_OS_WIN32
 /* The strtok() in Microsoft's C library is MT-safe (but still uses
@@ -141,6 +161,8 @@
 #define strtok_r(s,sep,lasts) (*(lasts)=strtok((s),(sep)))
 #endif
 
+
+
 static void
 camel_imap_folder_class_init (CamelImapFolderClass *camel_imap_folder_class)
 {
@@ -152,6 +174,7 @@
 	/* virtual method overload */
 	((CamelObjectClass *)camel_imap_folder_class)->getv = imap_getv;
 
+	camel_folder_class->set_push_email = imap_set_push_email;
 	camel_folder_class->get_message = imap_get_message;
 	camel_folder_class->rename = imap_rename;
 	camel_folder_class->search_by_expression = imap_search_by_expression;
@@ -178,12 +201,21 @@
 	camel_disco_folder_class->cache_message = imap_cache_message;
 }
 
+
 static void
 camel_imap_folder_init (gpointer object, gpointer klass)
 {
 	CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (object);
 	CamelFolder *folder = CAMEL_FOLDER (object);
-	
+
+	/* ((CamelObject *)folder)-> flags |= CAMEL_OBJECT_REF_DEBUG; */
+
+	imap_folder->idle_lock = g_new0 (GStaticRecMutex, 1);
+	g_static_rec_mutex_init (imap_folder->idle_lock);
+	imap_folder->stopping = FALSE;
+	imap_folder->in_idle = FALSE;
+
+	imap_folder->do_push_email = TRUE;
 	folder->permanent_flags = CAMEL_MESSAGE_ANSWERED | CAMEL_MESSAGE_DELETED |
 		CAMEL_MESSAGE_DRAFT | CAMEL_MESSAGE_FLAGGED | CAMEL_MESSAGE_SEEN;
 	
@@ -229,7 +261,7 @@
 	const char *short_name;
 	char *summary_file, *state_file;
 
-	if (g_mkdir_with_parents (folder_dir, S_IRWXU) != 0) {
+	if (e_util_mkdir_hier (folder_dir, S_IRWXU) != 0) {
 		camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
 				      _("Could not create directory %s: %s"),
 				      folder_dir, g_strerror (errno));
@@ -237,6 +269,10 @@
 	}
 
 	folder = CAMEL_FOLDER (camel_object_new (camel_imap_folder_get_type ()));
+	imap_folder = CAMEL_IMAP_FOLDER (folder);
+
+	imap_folder->folder_dir = g_strdup (folder_dir);
+
 	short_name = strrchr (folder_name, '/');
 	if (short_name)
 		short_name++;
@@ -244,7 +280,7 @@
 		short_name = folder_name;
 	camel_folder_construct (folder, parent, folder_name, short_name);
 
-	summary_file = g_strdup_printf ("%s/summary", folder_dir);
+	summary_file = g_strdup_printf ("%s/summary.mmap", folder_dir);
 	folder->summary = camel_imap_summary_new (folder, summary_file);
 	g_free (summary_file);
 	if (!folder->summary) {
@@ -261,8 +297,8 @@
 	g_free(state_file);
 	camel_object_state_read(folder);
 
-	imap_folder = CAMEL_IMAP_FOLDER (folder);
 	imap_folder->cache = camel_imap_message_cache_new (folder_dir, folder->summary, ex);
+
 	if (!imap_folder->cache) {
 		camel_object_unref (CAMEL_OBJECT (folder));
 		return NULL;
@@ -278,15 +314,78 @@
 			folder->folder_flags |= CAMEL_FOLDER_FILTER_JUNK;
 	}
 
+	if (imap_store->capabilities & IMAP_CAPABILITY_IDLE)
+		folder->folder_flags |= CAMEL_FOLDER_HAS_PUSHEMAIL_CAPABILITY;
+
 	imap_folder->search = camel_imap_search_new(folder_dir);
 
 	return folder;
 }
 
+
+static void 
+put_highestmodseq (CamelImapFolder *imap_folder, const char *highestmodseq)
+{
+	char *filename = g_strdup_printf ("%s/highestmodseq", imap_folder->folder_dir);
+	FILE *file;
+	
+	file = fopen (filename, "w");
+	g_free (filename);
+
+	if (file != NULL)
+	{
+		fprintf (file, "%s", highestmodseq);
+		fclose (file);
+	}
+}
+
+static char* 
+get_highestmodseq (CamelImapFolder *imap_folder)
+{
+	char *filename = g_strdup_printf ("%s/highestmodseq", imap_folder->folder_dir);
+	char *retval = NULL;
+	FILE *file;
+
+	file = fopen (filename, "r");
+	g_free (filename);
+
+	if (file != NULL)
+	{
+		retval = g_malloc0 (25); /* a 64bit number must fit in it */
+		fscanf (file, "%s", retval);
+		fclose (file);
+	}
+
+	return retval;
+}
+
 /* Called with the store's connect_lock locked */
+
+
+/*
+The assumption we have to make is that any folder can have been offline 
+before it got here to become selected. 
+
+Which is nasty because that means that our IDLE code might not have kept it
+synchronized. We might not have been notified by EXISTS, FETCH and EXPUNGE
+unsolicited events (you can't assume that).
+
+We also can't assume the availability of HIGHESTMODSEQ (or CONDSTORE). Not
+even if the IMAP service announced the condstore capability. That's because
+condstore is to be enabled per mailbox!
+
+UIDNEXT might be incorrect, I have seen IMAP servers that simply get it wrong.
+
+Although it has been reported that Exchange's IMAP server sometimes gives to high
+values for EXISTS, it's quite safe to assume that the EXISTS is going to be 
+correct on most servers. Just don't crash on sequences that don't exist remote.
+
+More documentation inline
+*/
+
 void
 camel_imap_folder_selected (CamelFolder *folder, CamelImapResponse *response,
-			    CamelException *ex)
+			    CamelException *ex, gboolean idle)
 {
 	CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
 	CamelImapSummary *imap_summary = CAMEL_IMAP_SUMMARY (folder->summary);
@@ -294,13 +393,29 @@
 	CamelMessageInfo *info;
 	guint32 perm_flags = 0;
 	GData *fetch_data;
-	int i, count;
-	char *resp;
-	
+	int i, count, uidnext = -1;
+	char *resp, *phighestmodseq = NULL, *highestmodseq = NULL;
+	CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
+	gboolean removals = FALSE, condstore = FALSE, needtoput=FALSE, suc=FALSE;
+
 	count = camel_folder_summary_count (folder->summary);
-	
-	for (i = 0; i < response->untagged->len; i++) {
+
+	/* With CONDSTORE this is the typical output.
+	 * C: A142 SELECT INBOX (CONDSTORE)
+	 * S: * 172 EXISTS
+	 * S: * 1 RECENT
+	 * S: * OK [UNSEEN 12] Message 12 is first unseen
+	 * S: * OK [UIDVALIDITY 3857529045] UIDs valid
+	 * S: * OK [UIDNEXT 4392] Predicted next UID
+	 * S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
+	 * S: * OK [PERMANENTFLAGS (\Deleted \Seen \*)] Limited
+	 * S: * OK [HIGHESTMODSEQ 715194045007]
+	 * S: A142 OK [READ-WRITE] SELECT completed, CONDSTORE is now enabled */
+
+	for (i = 0; i < response->untagged->len; i++) 
+	{
 		resp = response->untagged->pdata[i] + 2;
+
 		if (!g_ascii_strncasecmp (resp, "FLAGS ", 6) && !perm_flags) {
 			resp += 6;
 			folder->permanent_flags = imap_parse_flag_list (&resp);
@@ -311,6 +426,44 @@
 			 * even tho they do allow storing flags. *Sigh* So many fucking broken IMAP servers out there. */
 			if ((perm_flags = imap_parse_flag_list (&resp)) != 0)
 				folder->permanent_flags = perm_flags;
+		} else if (!g_ascii_strncasecmp (resp, "OK [UIDNEXT ", 12)) {
+			char *marker = strchr (resp, ']');
+			if (marker) *marker='\0';
+			uidnext = strtoul (resp + 12, NULL, 10);
+		} else if (!g_ascii_strncasecmp (resp, "OK [HIGHESTMODSEQ ", 18)) 
+		{
+		
+			/* So we have a HIGHESTMODSEQ, we are going to store this
+			 * one assuming that our code that will follow is correct
+			 * and that after that upcoming code, the local folder 
+			 * state will be in sync with that remote HIGHESTMODSEQ 
+			 * value. */
+			
+			char *marker;
+			unsigned int len;
+			resp += 18;
+
+			marker = strchr (resp, ']');
+
+			if (marker) 
+			{
+				condstore = TRUE;
+				len = (unsigned int) (marker - resp);
+				
+				highestmodseq = g_strndup (resp, len);
+				phighestmodseq = get_highestmodseq (imap_folder);
+
+				if (phighestmodseq !=NULL && !strcmp (phighestmodseq, highestmodseq)) 
+				{
+					g_free (phighestmodseq);
+					phighestmodseq = NULL;
+				} else 
+					needtoput = TRUE;
+			} else {
+				phighestmodseq = NULL;
+				highestmodseq = NULL;
+			}
+
 		} else if (!g_ascii_strncasecmp (resp, "OK [UIDVALIDITY ", 16)) {
 			validity = strtoul (resp + 16, NULL, 10);
 		} else if (isdigit ((unsigned char)*resp)) {
@@ -319,8 +472,7 @@
 			if (!g_ascii_strncasecmp (resp, " EXISTS", 7)) {
 				exists = num;
 				/* Remove from the response so nothing
-				 * else tries to interpret it.
-				 */
+				 * else tries to interpret it. */
 				g_free (response->untagged->pdata[i]);
 				g_ptr_array_remove_index (response->untagged, i--);
 			}
@@ -328,18 +480,31 @@
 	}
 
 	if (camel_strstrcase (response->status, "OK [READ-ONLY]"))
+	{
+		folder->folder_flags |= CAMEL_FOLDER_IS_READONLY;
 		imap_folder->read_only = TRUE;
+	}
 
-	if (camel_disco_store_status (CAMEL_DISCO_STORE (folder->parent_store)) == CAMEL_DISCO_STORE_RESYNCING) {
+	if (camel_disco_store_status (CAMEL_DISCO_STORE (folder->parent_store)) == CAMEL_DISCO_STORE_RESYNCING) 
+	{
+		if (phighestmodseq != NULL)
+			g_free (phighestmodseq);
+		if (highestmodseq != NULL)
+			g_free (highestmodseq);
+		
 		if (validity != imap_summary->validity) {
 			camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_SUMMARY_INVALID,
 					      _("Folder was destroyed and recreated on server."));
 			return;
 		}
-		
+
 		/* FIXME: find missing UIDs ? */
 		return;
 	}
+
+	/* If there's no match on VALIDITY, we are dealing with a different 
+	 * folder. For example the folder got removed and re-created. We'll
+	 * simply clear everyting and do things from scratch. */
 	
 	if (!imap_summary->validity)
 		imap_summary->validity = validity;
@@ -351,82 +516,163 @@
 		CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
 		imap_folder->need_rescan = FALSE;
 		camel_imap_folder_changed (folder, exists, NULL, ex);
+		
+		if (phighestmodseq != NULL)
+			g_free (phighestmodseq);
+		if (highestmodseq != NULL)
+			g_free (highestmodseq);
+		
 		return;
 	}
+
+	/* If we already had stuff locally, get the last one's UID . Store it in
+	 * what we will start calling VAL */
 	
-	/* If we've lost messages, we have to rescan everything */
-	if (exists < count)
-		imap_folder->need_rescan = TRUE;
-	else if (count != 0 && !imap_folder->need_rescan) {
-		CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
-		
-		/* Similarly, if the UID of the highest message we
-		 * know about has changed, then that indicates that
-		 * messages have been both added and removed, so we
-		 * have to rescan to find the removed ones. (We pass
-		 * NULL for the folder since we know that this folder
-		 * is selected, and we don't want camel_imap_command
-		 * to worry about it.)
-		 */
-		response = camel_imap_command (store, NULL, ex, "FETCH %d UID", count);
-		if (!response)
-			return;
-		uid = 0;
-		for (i = 0; i < response->untagged->len; i++) {
-			resp = response->untagged->pdata[i];
-			val = strtoul (resp + 2, &resp, 10);
-			if (val == 0)
-				continue;
-			if (!g_ascii_strcasecmp (resp, " EXISTS")) {
-				/* Another one?? */
-				exists = val;
-				continue;
-			}
-			if (uid != 0 || val != count || g_ascii_strncasecmp (resp, " FETCH (", 8) != 0)
-				continue;
-			
-			fetch_data = parse_fetch_response (imap_folder, resp + 7);
-			uid = strtoul (g_datalist_get_data (&fetch_data, "UID"), NULL, 10);
-			g_datalist_clear (&fetch_data);
-		}
-		camel_imap_response_free_without_processing (store, response);
-		
+	if (count > 0)
+	{
 		info = camel_folder_summary_index (folder->summary, count - 1);
 		val = strtoul (camel_message_info_uid (info), NULL, 10);
 		camel_message_info_free(info);
-		if (uid == 0 || uid != val)
-			imap_folder->need_rescan = TRUE;
+	} else 
+		val = -1;
+
+	/* If we are going the CONDSTORE route and if (uidnext-1) is not the 
+	 * same as the last uid in our summary, it's very likely that expunges
+	 * happened. This CONDSTORE code does not yet support expunges. 
+	 * Therefore we will simply use the old code. */
+
+	if (phighestmodseq != NULL && (val != uidnext-1))
+	{
+		g_free (phighestmodseq); 
+		phighestmodseq = NULL;
+		removals = TRUE;
 	}
+
+	/* If our local count isn't the same as the EXISTS, then our CONDSTORE 
+	 * implementation can't be used. Period. */
 	
-	/* Now rescan if we need to */
-	if (imap_folder->need_rescan) {
-		imap_rescan (folder, exists, ex);
-		return;
+	if (exists != count)
+	{
+		if (phighestmodseq != NULL)
+			g_free (phighestmodseq); 
+		phighestmodseq = NULL;
+		removals = TRUE;
 	}
-	
-	/* If we don't need to rescan completely, but new messages
-	 * have been added, find out about them.
-	 */
-	if (exists > count)
+
+	if (removals)
+		imap_folder->need_rescan = TRUE;
+	else if (condstore && (store->capabilities & IMAP_CAPABILITY_CONDSTORE))
+		imap_folder->need_rescan = FALSE;
+
+	/* We still aren't certain. For example if at the end of the mailbox 
+	 * both an add and an expunge happened, then all of above figured out
+	 * nothing meaningful. So we will compare the last local uid with the
+	 * remote uid at the same sequence number (that's count, as the count
+	 * is the index + 1). This is where we need the VAL thingy of above. */
+	
+	if (!imap_folder->need_rescan) 
+	{
+		int mval = 0;
+
+		/* If the UID of the highest message we know about has changed, 
+		 * then that indicates that messages have been both added and 
+		 * removed, so we have to rescan to find the removed ones */
+
+		response = camel_imap_command (store, NULL, ex, "FETCH %d UID", count);
+		if (response) {
+			uid = 0;
+			for (i = 0; i < response->untagged->len; i++) 
+			{
+				resp = response->untagged->pdata[i];
+				mval = strtoul (resp + 2, &resp, 10);
+				if (mval == 0)
+					continue;
+				if (!g_ascii_strcasecmp (resp, " EXISTS")) 
+				{
+					/* Another one?? */
+					exists = mval;
+					continue;
+				}
+				if (uid != 0 || mval != count || g_ascii_strncasecmp (resp, " FETCH (", 8) != 0)
+					continue;
+				
+				fetch_data = parse_fetch_response (imap_folder, resp + 7);
+				uid = strtoul (g_datalist_get_data (&fetch_data, "UID"), NULL, 10);
+				g_datalist_clear (&fetch_data);
+			}
+			camel_imap_response_free_without_processing (store, response);
+			if (uid == 0 || uid != val)
+				imap_folder->need_rescan = TRUE;
+		} else 
+			imap_folder->need_rescan = TRUE;
+	}
+
+	/* Okay, it survived ALL checks and CONDSTORE is available too. Lucky we 
+	 * are, aren't we? So we use CONDSTORE. Note, however, that if condstore 
+	 * still finds removals (sequences don't match) or if anything goes wrong
+	 * during the CONDSTORE code, that it'll set need_rescan TRUE and that 
+	 * as a result the lines below this if{} block will still happen. This is
+	 * indeed on purpose and as a fall-back situation (our detection got it
+	 * wrong) */
+	
+	if (phighestmodseq)
+	{
+		if (!imap_folder->need_rescan)
+			suc = imap_rescan_condstore (folder, exists, phighestmodseq, ex);
+		g_free (phighestmodseq);
+		phighestmodseq = NULL;
+	}
+
+	if (imap_folder->need_rescan)
+		suc = imap_rescan (folder, exists, ex);
+	else if (exists > count)
 		camel_imap_folder_changed (folder, exists, NULL, ex);
-	
-	/* And we're done. */
+
+	if (highestmodseq != NULL && suc && needtoput)
+		put_highestmodseq (imap_folder, (const char *) highestmodseq);
+
+	if (highestmodseq != NULL)
+		g_free (highestmodseq);
+
+	if (idle)
+		camel_imap_folder_start_idle (folder);
 }
 
-static void           
+static void 
 imap_finalize (CamelObject *object)
 {
 	CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (object);
+	CamelImapStore *store = CAMEL_IMAP_STORE (CAMEL_FOLDER(imap_folder)->parent_store);
+
+	imap_folder->do_push_email = FALSE;
+
+	imap_folder->stopping = TRUE;
+
+	if (imap_folder->idle_signal > 0) 
+		g_source_remove (imap_folder->idle_signal);
+
+	if (!imap_folder->in_idle || imap_folder->idle_lock != NULL)
+	{
+		g_static_rec_mutex_free (imap_folder->idle_lock);
+		imap_folder->idle_lock = NULL;
+	}
+
+	if (store->current_folder == (CamelFolder*) object)
+		store->current_folder = NULL;
 
 	if (imap_folder->search)
 		camel_object_unref (CAMEL_OBJECT (imap_folder->search));
 	if (imap_folder->cache)
 		camel_object_unref (CAMEL_OBJECT (imap_folder->cache));
 
+	if (imap_folder->folder_dir)
+		g_free (imap_folder->folder_dir);
+
 #ifdef ENABLE_THREADS
 	g_static_mutex_free(&imap_folder->priv->search_lock);
 	g_static_rec_mutex_free(&imap_folder->priv->cache_lock);
 #endif
+
 	g_free(imap_folder->priv);
 }
 
@@ -519,21 +765,20 @@
 	 * should do it.  */
 	CAMEL_SERVICE_REC_LOCK (imap_store, connect_lock);
 
-	if (!camel_imap_store_connected(imap_store, ex))
+	if (!camel_disco_store_check_online ((CamelDiscoStore*)imap_store, ex))
 		goto done;
 
 	if (imap_store->current_folder != folder
 	    || g_ascii_strcasecmp(folder->full_name, "INBOX") == 0) {
 		response = camel_imap_command (imap_store, folder, ex, NULL);
 		if (response) {
-			camel_imap_folder_selected (folder, response, ex);
+			camel_imap_folder_selected (folder, response, ex, TRUE);
 			camel_imap_response_free (imap_store, response);
 		}
 	} else if (imap_folder->need_rescan) {
 		/* Otherwise, if we need a rescan, do it, and if not, just do
 		 * a NOOP to give the server a chance to tell us about new
-		 * messages.
-		 */
+		 * messages. */
 		imap_rescan (folder, camel_folder_summary_count (folder->summary), ex);
 	} else {
 #if 0
@@ -542,10 +787,12 @@
 		if (g_ascii_strcasecmp(folder->full_name, "INBOX") == 0) {
 			response = camel_imap_command (imap_store, folder, ex, "CHECK");
 			camel_imap_response_free (imap_store, response);
+			camel_imap_folder_start_idle (folder);
 		}
 #endif
 		response = camel_imap_command (imap_store, folder, ex, "NOOP");
 		camel_imap_response_free (imap_store, response);
+		camel_imap_folder_start_idle (folder);
 	}
 
 	si = camel_store_summary_path((CamelStoreSummary *)((CamelImapStore *)folder->parent_store)->summary, folder->full_name);
@@ -564,10 +811,13 @@
 done:
 	CAMEL_SERVICE_REC_UNLOCK (imap_store, connect_lock);
 
-	camel_folder_summary_save(folder->summary);
+	/* TNY TOCHECK: I think all situations are already saving the summary?!
+	 * camel_folder_summary_save(folder->summary); */
+
 	camel_store_summary_save((CamelStoreSummary *)((CamelImapStore *)folder->parent_store)->summary);
 }
 
+#if 0
 static void
 flags_to_label(CamelFolder *folder, CamelImapMessageInfo *mi)
 {
@@ -596,14 +846,198 @@
 		}
 
 		mi->info.flags = (mi->info.flags & ~CAMEL_IMAP_MESSAGE_LABEL_MASK) | mask;
+
+#ifdef NON_TINYMAIL_FEATURES
 		camel_tag_set(&mi->info.user_tags, "label", label);
+#endif
+	}
+}
+
+#endif
+
+static gboolean 
+imap_rescan_condstore (CamelFolder *folder, int exists, const char *highestmodseq, CamelException *ex)
+{
+
+	/* So this is what we'll get. All the changes since highestmodseq.
+	 * C: s100 UID FETCH 1:* (FLAGS) (CHANGEDSINCE 12345)
+	 * S: * 1 FETCH (UID 4 MODSEQ (65402) FLAGS (\Seen))
+	 * S: * 2 FETCH (UID 6 MODSEQ (75403) FLAGS (\Deleted))
+	 * S: * 4 FETCH (UID 8 MODSEQ (29738) FLAGS ($NoJunk $AutoJunk $MDNSent))
+	 * S: s100 OK FETCH completed */
+
+	CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
+	CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
+	char *resp;
+	CamelImapResponseType type;
+	int summary_len, summary_got;
+	CamelMessageInfo *info;
+	CamelImapMessageInfo *iinfo;
+	gboolean ok, retval = TRUE;
+	CamelFolderChangeInfo *changes = NULL;
+
+	imap_folder->need_rescan = FALSE;
+
+	summary_len = camel_folder_summary_count (folder->summary);
+	if (summary_len == 0) {
+		if (exists)
+			camel_imap_folder_changed (folder, exists, NULL, ex);
+		return TRUE;
+	}
+
+	camel_operation_start (NULL, _("Scanning for changed messages in %s"), folder->name);
+	ok = camel_imap_command_start (store, folder, ex,
+				       "UID FETCH 1:* (FLAGS) (CHANGEDSINCE %s)",
+				       highestmodseq);
+	if (!ok) {
+
+		/* This probably means that the server doesn't understand 
+		 * CHANGEDSINCE, though it advertised support for CONDSTORE.
+		 * But we are the client, we need to forgive! So we'll simply
+		 * set need_rescan to TRUE and let the fallback stuff in the
+		 * 'selected' method deal with it by launching imap_rescan. */
+
+		imap_folder->need_rescan = TRUE;
+
+		/* TNY TODO: turn-off the CONDSTORE capability? */
+
+		camel_operation_end (NULL);
+		return FALSE;
+	}
+
+	/* Highfive! everything is still up and running. It's still possible 
+	 * that things go wrong. But there's no need to stop then: we'll need
+	 * to read-away what the server is sending anyway. So why not perform 
+	 * some work each time both the UID and the SEQUENCE match with what
+	 * we have locally?
+	 * 
+	 * If not, we simply set need_rescan TRUE and keep on going. This does,
+	 * however, mean that we actually didn't really win traffic by using
+	 * condstore. We even lost some. But being truly in sync is far more
+	 * important. */
+
+	summary_got = 0;
+	while ((type = camel_imap_command_response (store, &resp, ex)) == CAMEL_IMAP_RESPONSE_UNTAGGED) 
+	{
+		GData *data;
+		char *uid;
+		guint32 flags, seq;
+
+		data = parse_fetch_response (imap_folder, resp);
+		g_free (resp);
+
+		if (!data)
+			continue;
+
+		uid = g_datalist_get_data (&data, "UID");
+		flags = GPOINTER_TO_UINT (g_datalist_get_data (&data, "FLAGS"));
+		seq = GPOINTER_TO_UINT (g_datalist_get_data (&data, "SEQUENCE"));
+
+		/* So basically: if the UID is not found locally, we have flags
+		 * for a new message. That's cool, but not an error as the 
+		 * camel_imap_folder_changed will launch imap_update_summary 
+		 * who will deal with that.
+		 * 
+		 * See, we wont find it if it's larger than the count of the
+		 * local summary list. We don't even have to check that, right? 
+		 * 
+		 * We also check for negative sequences. No reason for that, 
+		 * it's just wrong (actually impossible since it's a unsigned 
+		 * int, but it's just for security-clarity here. Let it be, it 
+		 * doesn't hurt either) */
+		
+		if (!uid || seq < 0 || seq-1 > summary_len) {
+			imap_folder->need_rescan = TRUE;
+			retval = FALSE;
+			g_datalist_clear (&data);
+			continue;
+		}
+
+		info = camel_folder_summary_index (folder->summary, seq-1);
+		iinfo = (CamelImapMessageInfo *) info;
+		
+		
+		/* However, if we do find the message-info at that index then we 
+		 * we should also check whether the UID matches. If not, well ..
+		 * that's not good eh. That means that we shouldn't have been 
+		 * using this CONDSTORE code in the first place! Bad luck, we 
+		 * just set need_rescan TRUE and let the selected metod launch
+		 * the conventional imap_rescan later-on. Since we are receiving 
+		 * stuff anyway, and we need to read that away nonetheless, we
+		 * just continue doing our stuff. */
+		
+		if (info) 
+		{
+			/* printf ("%s vs %s on %d\n", info->uid, uid, seq-1); */
+			if (!strcmp (info->uid, uid))
+			{
+			  if (flags != iinfo->server_flags) 
+			  {
+				camel_folder_summary_touch (folder->summary);
+				guint32 server_set, server_cleared;
+				server_set = flags & ~iinfo->server_flags;
+				server_cleared = iinfo->server_flags & ~flags;
+				iinfo->info.flags = (iinfo->info.flags | server_set) & ~server_cleared;
+				iinfo->server_flags = flags;
+				if (changes == NULL)
+					changes = camel_folder_change_info_new();
+				camel_folder_change_info_change_uid(changes, uid);
+				/* flags_to_label(folder, (CamelImapMessageInfo *)info); */
+			  }
+			  camel_message_info_free (info);
+			} else {
+				imap_folder->need_rescan = TRUE;
+				retval = FALSE;
+			}
+		} else 
+			retval = FALSE;
+
+		camel_operation_progress (NULL, ++summary_got , summary_len);
+		g_datalist_clear (&data);
 	}
+
+	camel_operation_end (NULL);
+
+	if (type == CAMEL_IMAP_RESPONSE_ERROR)
+		return FALSE;
+
+	/* Free the final tagged response */
+	if (resp)
+		g_free (resp);
+
+	if (changes) 
+	{
+		camel_object_trigger_event(CAMEL_OBJECT (folder), "folder_changed", changes);
+		camel_folder_change_info_free(changes);
+	}
+
+	/* The thing with te if is that the selected folder will do imap_rescan 
+	 * anyway, that function will call the camel_imap_folder_changed too.
+	 * There's no need to let this happen twice, so we filter it. 
+	 * 
+	 * However. If we were lucky and condstore succeeded without problems,
+	 * then we must check for new messages of course. We can't have removals
+	 * which is why it's set to NULL. If we had removals, then need_rescan
+	 * has been set to TRUE. Right? Right! */
+	
+	if (!imap_folder->need_rescan)
+		camel_imap_folder_changed (folder, exists, NULL, ex);
+	
+	return retval;
 }
 
 /* Called with the store's connect_lock locked */
-static void
+static gboolean
 imap_rescan (CamelFolder *folder, int exists, CamelException *ex)
 {
+	gboolean retval = TRUE;
+	
+	/* Welcome to the most hairy code of Camel. On the left you
+	 * have the bathroom where you can puke. On the right you have 
+	 * fresh water and soap to clean it up. In front of you, you have ..
+	 * 
+	 * The code */
+	
 	CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
 	CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
 	struct {
@@ -622,10 +1056,12 @@
 	imap_folder->need_rescan = FALSE;
 	
 	summary_len = camel_folder_summary_count (folder->summary);
-	if (summary_len == 0) {
+	
+	if (summary_len == 0) 
+	{
 		if (exists)
 			camel_imap_folder_changed (folder, exists, NULL, ex);
-		return;
+		return TRUE;
 	}
 	
 	/* Check UIDs and flags of all messages we already know of. */
@@ -637,12 +1073,20 @@
 	camel_message_info_free(info);
 	if (!ok) {
 		camel_operation_end (NULL);
-		return;
+		return FALSE;
 	}
 	
+	/* Soo ... we allocate a matrix of the exact size of the local summary 
+	 * after we launched a command that asks for the flags of all messages
+	 * until the last uid we have locally. Let's iterate them ... */
+	
 	new = g_malloc0 (summary_len * sizeof (*new));
 	summary_got = 0;
-	while ((type = camel_imap_command_response (store, &resp, ex)) == CAMEL_IMAP_RESPONSE_UNTAGGED) {
+	resp = NULL;
+	
+	while ((type = camel_imap_command_response (store, &resp, ex)) 
+	       	== CAMEL_IMAP_RESPONSE_UNTAGGED) 
+	{
 		GData *data;
 		char *uid;
 		guint32 flags;
@@ -656,40 +1100,66 @@
 		uid = g_datalist_get_data (&data, "UID");
 		flags = GPOINTER_TO_UINT (g_datalist_get_data (&data, "FLAGS"));
 		
-		if (!uid || !seq || seq > summary_len) {
+		if (!uid || !seq || seq > summary_len || seq < 0) 
+		{
+			retval = FALSE;
 			g_datalist_clear (&data);
 			continue;
 		}
 		
-		camel_operation_progress (NULL, ++summary_got * 100 / summary_len);
+		/* See, we are just storing them in that matrix. Nothing
+		 * difficult here. */
+		
+		camel_operation_progress (NULL, ++summary_got , summary_len);
 		new[seq - 1].uid = g_strdup (uid);
 		new[seq - 1].flags = flags;
 		g_datalist_clear (&data);
 	}
 	
 	camel_operation_end (NULL);
-	if (type == CAMEL_IMAP_RESPONSE_ERROR) {
+	
+	if (type == CAMEL_IMAP_RESPONSE_ERROR) 
+	{
 		for (i = 0; i < summary_len && new[i].uid; i++)
 			g_free (new[i].uid);
 		g_free (new);
-		return;
+		return FALSE;
 	}
 	
 	/* Free the final tagged response */
-	g_free (resp);
+	if (resp)
+		g_free (resp);
 	
 	/* If we find a UID in the summary that doesn't correspond to
 	 * the UID in the folder, then either: (a) it's a real UID,
 	 * but the message was deleted on the server, or (b) it's a
 	 * fake UID, and needs to be removed from the summary in order
 	 * to sync up with the server. So either way, we remove it
-	 * from the summary.
-	 */
+	 * from the summary. */
+	
 	removed = g_array_new (FALSE, FALSE, sizeof (int));
-	for (i = 0; i < summary_len && new[i].uid; i++) {
+	for (i = 0; i < summary_len && new[i].uid; i++) 
+	{
 		info = camel_folder_summary_index (folder->summary, i);
 		iinfo = (CamelImapMessageInfo *)info;
-		
+
+		if (!info)
+			continue;
+
+		/* This is where it gets hairy. It tries to mimic what an 
+		 * EXPUNGE would cause. That's because we will pass the removed
+		 * sequences to the same handler for it (check below and in
+		 * the code in imap-command and the IDLE stuff that handles
+		 * EXPUNGE responses). 
+		 * 
+		 * Now. the consequences are that if at the very beginning of
+		 * the remote mailbox a message got expunged, all local messages
+		 * will be marked for removal caused by this. That's a terrible
+		 * idea, but it is what it is .... */
+
+		/* TODO: recalculating rather than marking a lot perfectly fine
+		 * material for removal */
+
 		if (strcmp (camel_message_info_uid (info), new[i].uid) != 0) {
 			camel_message_info_free(info);
 			seq = i + 1;
@@ -699,8 +1169,12 @@
 			continue;
 		}
 		
-		/* Update summary flags */
-		if (new[i].flags != iinfo->server_flags) {
+		
+		/* In case both the uid and the sequence are in match remote and
+		 * locally, we can securely update the flags locally. */
+
+		if (new[i].flags != iinfo->server_flags) 
+		{
 			guint32 server_set, server_cleared;
 			
 			server_set = new[i].flags & ~iinfo->server_flags;
@@ -712,14 +1186,15 @@
 			if (changes == NULL)
 				changes = camel_folder_change_info_new();
 			camel_folder_change_info_change_uid(changes, new[i].uid);
-			flags_to_label(folder, (CamelImapMessageInfo *)info);
+			/* flags_to_label(folder, (CamelImapMessageInfo *)info); */
 		}
 
 		camel_message_info_free(info);
 		g_free (new[i].uid);
 	}
 
-	if (changes) {
+	if (changes) 
+	{
 		camel_object_trigger_event(CAMEL_OBJECT (folder), "folder_changed", changes);
 		camel_folder_change_info_free(changes);
 	}
@@ -730,11 +1205,9 @@
 	while (i < summary_len && new[i].uid)
 		g_free (new[i++].uid);
 	g_free (new);
-	
-	/* Remove any leftover cached summary messages. (Yes, we
-	 * repeatedly add the same number to the removed array.
-	 * See RFC2060 7.4.1)
-	 */
+
+	/* Remove any leftover cached summary messages. (Yes, we repeatedly add
+	 * the same number to the removed array. See RFC2060 7.4.1) */
 
 	for (i = seq; i <= summary_len; i++)
 		g_array_append_val (removed, seq);
@@ -742,6 +1215,8 @@
 	/* And finally update the summary. */
 	camel_imap_folder_changed (folder, exists, removed, ex);
 	g_array_free (removed, TRUE);
+
+	return retval;
 }
 
 /* the max number of chars that an unsigned 32-bit int can be is 10 chars plus 1 for a possible : */
@@ -751,8 +1226,7 @@
  * If no messages match, returns %NULL. Otherwise, returns an array of
  * CamelMessageInfo and sets *@set to a message set corresponding the
  * UIDs of the matched messages (up to @UID_SET_LIMIT bytes). The
- * caller must free the infos, the array, and the set string.
- */
+ * caller must free the infos, the array, and the set string. */
 static GPtrArray *
 get_matching (CamelFolder *folder, guint32 flags, guint32 mask, char **set)
 {
@@ -836,8 +1310,7 @@
 	
 	/* Find a message with changed flags, find all of the other
 	 * messages like it, sync them as a group, mark them as
-	 * updated, and continue.
-	 */
+	 * updated, and continue.*/
 	max = camel_folder_summary_count (folder->summary);
 	for (i = 0; i < max; i++) {
 		if (!(info = (CamelImapMessageInfo *)camel_folder_summary_index (folder->summary, i)))
@@ -865,7 +1338,7 @@
 			continue;
 		
 		/* Make sure we're connected before issuing commands */
-		if (!camel_imap_store_connected(store, ex)) {
+		if (!camel_disco_store_check_online ((CamelDiscoStore*)store, ex)) {
 			g_free(set);
 			break;
 		}
@@ -916,6 +1389,7 @@
 	imap_sync_offline (folder, ex);
 	
 	CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
+	/* camel_imap_folder_start_idle (folder); */
 }
 
 static int
@@ -948,8 +1422,7 @@
 		camel_folder_summary_remove_uid (folder->summary, uids->pdata[i]);
 		camel_folder_change_info_remove_uid (changes, uids->pdata[i]);
 		/* We intentionally don't remove it from the cache because
-		 * the cached data may be useful in replaying a COPY later.
-		 */
+		 * the cached data may be useful in replaying a COPY later. */
 	}
 	camel_folder_summary_save (folder->summary);
 
@@ -1004,6 +1477,9 @@
 	}
 	
 	CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
+
+	camel_imap_folder_start_idle (folder);
+
 }
 
 static void
@@ -1026,8 +1502,7 @@
 	/* If we don't have UID EXPUNGE we need to avoid expunging any
 	 * of the wrong messages. So we search for deleted messages,
 	 * and any that aren't in our to-expunge list get temporarily
-	 * marked un-deleted.
-	 */
+	 * marked un-deleted. */
 	
 	CAMEL_SERVICE_REC_LOCK (store, connect_lock);
 
@@ -1080,8 +1555,7 @@
 		}
 	} else {
 		/* Empty SEARCH result, meaning nothing is marked deleted
-		 * on server.
-		 */
+		 * on server. */
 		
 		keep_uids = NULL;
 		mark_uids = uids;
@@ -1109,6 +1583,7 @@
 				return;
 			}
 			camel_imap_response_free (store, response);
+
 		}
 	}
 	
@@ -1132,7 +1607,6 @@
 				CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
 				return;
 			}
-			camel_imap_response_free (store, response);
 		}
 
 		if (mark_uids != uids)
@@ -1170,6 +1644,9 @@
 	g_free (result);
 	
 	CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
+
+	camel_imap_folder_start_idle (folder);
+
 }
 
 static gchar *
@@ -1290,7 +1767,7 @@
 	}
 	
 	/* send the rest of our data - the mime message */
-	response2 = camel_imap_command_continuation (store, ba->data, ba->len, ex);
+	response2 = camel_imap_command_continuation (store, (const char *) ba->data, ba->len, ex);
 	g_byte_array_free (ba, TRUE);
 
 	/* free it only after message is sent. This may cause more FETCHes. */
@@ -1355,6 +1832,9 @@
 	    camel_folder_summary_count (folder->summary) == count)
 		imap_refresh_info (folder, ex);
 	CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
+
+	camel_imap_folder_start_idle (folder);
+
 }
 
 static void
@@ -1429,7 +1909,8 @@
 		mi = camel_folder_summary_uid (source->summary, uid);
 		g_return_if_fail (mi != NULL);
 
-		message = camel_folder_get_message (source, uid, NULL);
+		/* TNY TODO: detect whether or not to persist partial message retrieval */
+		message = camel_folder_get_message (source, uid, CAMEL_FOLDER_RECEIVE_FULL, -1, NULL);
 
 		if (message) {
 			camel_imap_summary_add_offline (dest->summary, destuid, message, mi);
@@ -1552,9 +2033,7 @@
 		      CamelFolder *dest, GPtrArray **transferred_uids,
 		      gboolean delete_originals, CamelException *ex)
 {
-	CamelImapStore *store = CAMEL_IMAP_STORE (source->parent_store);
 	int count;
-
 	/* Sync message flags if needed. */
 	imap_sync_online (source, ex);
 	if (camel_exception_is_set (ex))
@@ -1570,13 +2049,17 @@
 		return;
 
 	/* Make the destination notice its new messages */
-	if (store->current_folder != dest ||
+
+	/*if (store->current_folder != dest ||
 	    camel_folder_summary_count (dest->summary) == count)
-		camel_folder_refresh_info (dest, ex);
-	
+		camel_folder_refresh_info (dest, ex); */
+
 	/* FIXME */
 	if (transferred_uids)
 		*transferred_uids = NULL;
+
+	camel_imap_folder_start_idle (source);
+
 }
 
 static void
@@ -1629,8 +2112,11 @@
 		       !isdigit (*(unsigned char *)(uids->pdata[i])) &&
 		       !camel_exception_is_set (ex)) {
 			uid = uids->pdata[i];
-			message = camel_folder_get_message (source, uid, NULL);
+
+			/* TNY TODO: detect whether or not to persist partial message retrieval */
+			message = camel_folder_get_message (source, uid, CAMEL_FOLDER_RECEIVE_FULL, -1, NULL);
 			if (!message) {
+				i++;
 				/* Message must have been expunged */
 				continue;
 			}
@@ -1708,7 +2194,7 @@
 static CamelMimeMessage *get_message (CamelImapFolder *imap_folder,
 				      const char *uid,
 				      CamelMessageContentInfo *ci,
-				      CamelException *ex);
+				      CamelFolderReceiveType type, gint param, CamelException *ex);
 
 struct _part_spec_stack {
 	struct _part_spec_stack *parent;
@@ -1829,7 +2315,8 @@
 			strcpy(spec, part_spec);
 		g_free(part_spec);
 		
-		stream = camel_imap_folder_fetch_data (imap_folder, uid, spec, FALSE, ex);
+		/* TNY TODO: partial message retrieval exception */
+		stream = camel_imap_folder_fetch_data (imap_folder, uid, spec, FALSE, CAMEL_FOLDER_RECEIVE_FULL, -1, ex);
 		if (stream) {
 			ret = camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (body_mp), stream);
 			camel_object_unref (CAMEL_OBJECT (stream));
@@ -1866,7 +2353,8 @@
 		num = 1;
 		while (ci) {
 			sprintf (child_spec + speclen, "%d.MIME", num++);
-			stream = camel_imap_folder_fetch_data (imap_folder, uid, child_spec, FALSE, ex);
+			/* TNY TODO: partial message retrieval exception */
+			stream = camel_imap_folder_fetch_data (imap_folder, uid, child_spec, TRUE, CAMEL_FOLDER_RECEIVE_FULL, -1, ex);
 			if (stream) {
 				int ret;
 				
@@ -1922,7 +2410,8 @@
 		
 		return (CamelDataWrapper *) body_mp;
 	} else if (camel_content_type_is (ci->type, "message", "rfc822")) {
-		content = (CamelDataWrapper *) get_message (imap_folder, uid, ci->childs, ex);
+		/* TNY TODO: partial message retrieval exception */
+		content = (CamelDataWrapper *) get_message (imap_folder, uid, ci->childs, CAMEL_FOLDER_RECEIVE_FULL, -1, ex);
 		g_free (part_spec);
 		return content;
 	} else {
@@ -1946,7 +2435,7 @@
 static CamelMimeMessage *
 get_message (CamelImapFolder *imap_folder, const char *uid,
 	     CamelMessageContentInfo *ci,
-	     CamelException *ex)
+	     CamelFolderReceiveType type, gint param, CamelException *ex)
 {
 	CamelImapStore *store = CAMEL_IMAP_STORE (CAMEL_FOLDER (imap_folder)->parent_store);
 	CamelDataWrapper *content;
@@ -1960,7 +2449,8 @@
 	section_text = g_strdup_printf ("%s%s%s", part_spec, *part_spec ? "." : "",
 					store->server_level >= IMAP_LEVEL_IMAP4REV1 ? "HEADER" : "0");
 
-	stream = camel_imap_folder_fetch_data (imap_folder, uid, section_text, FALSE, ex);
+	/* TNY: partial message retrieval */
+	stream = camel_imap_folder_fetch_data (imap_folder, uid, section_text, FALSE, type, param, ex);
 	g_free (section_text);
 	g_free(part_spec);
 	if (!stream)
@@ -2000,14 +2490,14 @@
 
 static CamelMimeMessage *
 get_message_simple (CamelImapFolder *imap_folder, const char *uid,
-		    CamelStream *stream, CamelException *ex)
+		    CamelStream *stream, CamelFolderReceiveType type, gint param, CamelException *ex)
 {
 	CamelMimeMessage *msg;
 	int ret;
 	
 	if (!stream) {
 		stream = camel_imap_folder_fetch_data (imap_folder, uid, "",
-						       FALSE, ex);
+						       FALSE, type, param, ex);
 		if (!stream)
 			return NULL;
 	}
@@ -2046,7 +2536,7 @@
 }
 
 static CamelMimeMessage *
-imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
+imap_get_message (CamelFolder *folder, const char *uid, CamelFolderReceiveType type, gint param, CamelException *ex)
 {
 	CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
 	CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
@@ -2064,8 +2554,12 @@
 
 	/* If its cached in full, just get it as is, this is only a shortcut,
 	   since we get stuff from the cache anyway.  It affects a busted connection though. */
-	if ( (stream = camel_imap_folder_fetch_data(imap_folder, uid, "", TRUE, NULL))
-	     && (msg = get_message_simple(imap_folder, uid, stream, ex)))
+	if ( (stream = camel_imap_folder_fetch_data (imap_folder, uid, "", TRUE, type, param, NULL))
+	     && (msg = get_message_simple(imap_folder, uid, stream, type, param, ex)))
+		goto done;
+
+
+	if (camel_disco_store_status (CAMEL_DISCO_STORE (folder->parent_store)) == CAMEL_DISCO_STORE_OFFLINE)
 		goto done;
 
 	/* All this mess is so we silently retry a fetch if we fail with
@@ -2080,7 +2574,7 @@
 		    || store->braindamaged
 		    || mi->info.size < IMAP_SMALL_BODY_SIZE
 		    || (!content_info_incomplete(mi->info.content) && !mi->info.content->childs)) {
-			msg = get_message_simple (imap_folder, uid, NULL, ex);
+			msg = get_message_simple (imap_folder, uid, NULL, type, param, ex);
 		} else {
 			if (content_info_incomplete (mi->info.content)) {
 				/* For larger messages, fetch the structure and build a message
@@ -2094,7 +2588,7 @@
 				int i;
 				
 				CAMEL_SERVICE_REC_LOCK(store, connect_lock);
-				if (!camel_imap_store_connected(store, ex)) {
+				if (!camel_disco_store_check_online ((CamelDiscoStore*)store, ex)) {
 					CAMEL_SERVICE_REC_UNLOCK(store, connect_lock);
 					camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
 							     _("This message is not currently available"));
@@ -2129,7 +2623,8 @@
 					
 					camel_imap_response_free (store, response);
 				} else {
-					camel_exception_clear(ex);
+					/* camel_exception_clear(ex); */
+					goto fail;
 				}
 			}
 
@@ -2146,21 +2641,24 @@
 			 * let the mailer's "bad MIME" code handle it.
 			 */
 			if (content_info_incomplete (mi->info.content))
-				msg = get_message_simple (imap_folder, uid, NULL, ex);
+				msg = get_message_simple (imap_folder, uid, NULL, type, param, ex);
 			else
-				msg = get_message (imap_folder, uid, mi->info.content, ex);
+				msg = get_message (imap_folder, uid, mi->info.content, type, param, ex);
 		}
 	} while (msg == NULL
 		 && retry < 2
 		 && camel_exception_get_id(ex) == CAMEL_EXCEPTION_SERVICE_UNAVAILABLE);
 
-done:	/* FIXME, this shouldn't be done this way. */
-	if (msg)
-		camel_medium_set_header (CAMEL_MEDIUM (msg), "X-Evolution-Source", store->base_url);
+done:
+	camel_message_info_free(&mi->info);
+	return msg;
+
 fail:
 	camel_message_info_free(&mi->info);
+	if (msg && CAMEL_IS_OBJECT (msg))
+		camel_object_unref (CAMEL_OBJECT (msg));
 	
-	return msg;
+	return NULL;
 }
 
 static void
@@ -2170,7 +2668,8 @@
 	CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (disco_folder);
 	CamelStream *stream;
 
-	stream = camel_imap_folder_fetch_data (imap_folder, uid, "", FALSE, ex);
+	/* TNY TODO: partial message retrieval exception */
+	stream = camel_imap_folder_fetch_data (imap_folder, uid, "", FALSE, CAMEL_FOLDER_RECEIVE_FULL, -1, ex);
 	if (stream)
 		camel_object_unref (CAMEL_OBJECT (stream));
 }
@@ -2224,7 +2723,7 @@
 	return TRUE;
 }
 
-static time_t
+time_t
 decode_internaldate (const unsigned char *in)
 {
 	const unsigned char *inptr = in;
@@ -2235,7 +2734,7 @@
 	
 	memset ((void *) &tm, 0, sizeof (struct tm));
 	
-	tm.tm_mday = strtoul (inptr, (char **) &buf, 10);
+	tm.tm_mday = strtoul ((char *) inptr, (char **) &buf, 10);
 	if (buf == inptr || *buf != '-')
 		return (time_t) -1;
 	
@@ -2244,7 +2743,7 @@
 		return (time_t) -1;
 	
 	for (n = 0; n < 12; n++) {
-		if (!g_ascii_strncasecmp (inptr, tm_months[n], 3))
+		if (!g_ascii_strncasecmp ((gchar *) inptr, tm_months[n], 3))
 			break;
 	}
 	
@@ -2255,7 +2754,7 @@
 	
 	inptr += 4;
 	
-	n = strtoul (inptr, (char **) &buf, 10);
+	n = strtoul ((char *) inptr, (char **) &buf, 10);
 	if (buf == inptr || *buf != ' ')
 		return (time_t) -1;
 	
@@ -2269,7 +2768,7 @@
 	tm.tm_min = min;
 	tm.tm_sec = sec;
 	
-	n = strtol (inptr, NULL, 10);
+	n = strtol ((char *) inptr, NULL, 10);
 	
 	date = e_mktime_utc (&tm);
 	
@@ -2281,9 +2780,52 @@
 	return date;
 }
 
-static void
-add_message_from_data (CamelFolder *folder, GPtrArray *messages,
-		       int first, GData *data)
+
+static CamelImapMessageInfo*
+message_from_data (CamelFolder *folder, GData *data)
+{
+	CamelMimeMessage *msg;
+	CamelStream *stream;
+	CamelImapMessageInfo *mi;
+	const char *idate;
+	gint size = 0;
+
+	stream = g_datalist_get_data (&data, "BODY_PART_STREAM");
+	if (!stream)
+		return NULL;
+
+	msg = camel_mime_message_new ();
+	if (camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (msg), stream) == -1) {
+		camel_object_unref (CAMEL_OBJECT (msg));
+		return NULL;
+	}
+
+	mi = (CamelImapMessageInfo *)camel_folder_summary_info_new_from_message (folder->summary, msg);
+	camel_object_unref (CAMEL_OBJECT (msg));
+
+	size = GPOINTER_TO_INT (g_datalist_get_data (&data, "RFC822.SIZE"));
+	if (size)
+		mi->info.size = size;
+
+	/* TNY TODO: This is a hack! But else we need to parse 
+	 * BODYSTRUCTURE (and I'm lazy). It needs fixing though. */
+	if (size > 102400)
+		((CamelMessageInfoBase *)mi)->flags |= CAMEL_MESSAGE_ATTACHMENTS;
+	/* ... it does */
+
+	if ((idate = g_datalist_get_data (&data, "INTERNALDATE")))
+		mi->info.date_received = decode_internaldate ((const unsigned char *) idate);
+	
+	if (mi->info.date_received == -1)
+		mi->info.date_received = mi->info.date_sent;
+
+	return mi;
+}
+
+#if 0
+static void
+add_message_from_data (CamelFolder *folder, GPtrArray *messages,
+		       int first, GData *data)
 {
 	CamelMimeMessage *msg;
 	CamelStream *stream;
@@ -2308,327 +2850,856 @@
 	}
 	
 	mi = (CamelImapMessageInfo *)camel_folder_summary_info_new_from_message (folder->summary, msg);
+	
 	camel_object_unref (CAMEL_OBJECT (msg));
 	
 	if ((idate = g_datalist_get_data (&data, "INTERNALDATE")))
-		mi->info.date_received = decode_internaldate (idate);
+		mi->info.date_received = decode_internaldate ((const unsigned char *) idate);
 	
 	if (mi->info.date_received == -1)
 		mi->info.date_received = mi->info.date_sent;
-	
+
 	messages->pdata[seq - first] = mi;
+
+	return;
 }
 
+#endif
+
+/* #define CAMEL_MESSAGE_INFO_HEADERS "DATE FROM TO CC SUBJECT REFERENCES IN-REPLY-TO MESSAGE-ID MIME-VERSION CONTENT-TYPE " */
+
+#ifdef NON_TINYMAIL_FEATURES
+#define CAMEL_MESSAGE_INFO_HEADERS "DATE FROM TO CC SUBJECT REFERENCES IN-REPLY-TO MESSAGE-ID MIME-VERSION CONTENT-TYPE X-PRIORITY X-MSMAIL-PRIORITY"
+#else
+#define CAMEL_MESSAGE_INFO_HEADERS "DATE FROM TO CC SUBJECT MESSAGE-ID X-PRIORITY X-MSMAIL-PRIORITY X-MS-HAS-ATTACH CONTENT-TYPE"
+#endif
 
-#define CAMEL_MESSAGE_INFO_HEADERS "DATE FROM TO CC SUBJECT REFERENCES IN-REPLY-TO MESSAGE-ID MIME-VERSION CONTENT-TYPE "
 
 /* FIXME: this needs to be kept in sync with camel-mime-utils.c's list
    of mailing-list headers and so might be best if this were
    auto-generated? */
-#define MAILING_LIST_HEADERS "X-MAILING-LIST X-LOOP LIST-ID LIST-POST MAILING-LIST ORIGINATOR X-LIST SENDER RETURN-PATH X-BEENTHERE "
+#define MAILING_LIST_HEADERS " X-MAILING-LIST X-LOOP LIST-ID LIST-POST MAILING-LIST ORIGINATOR X-LIST SENDER RETURN-PATH X-BEENTHERE"
+
+
+static guint32 
+imap_get_uids (CamelFolder *folder, CamelImapStore *store, CamelException *ex, GPtrArray *needheaders, int size)
+{
+	char *resp = NULL;
+	CamelImapResponseType type;
+	guint32 cnt = 0;
+	gchar *uid, *str;
+
+	while ((type = camel_imap_command_response (store, &resp, ex)) ==
+			CAMEL_IMAP_RESPONSE_UNTAGGED) 
+	{
+		str = strstr (resp, "SEARCH");
+
+		if (str)
+		{
+			str+=7;
+			uid = strtok (str, " ");
+
+			while (uid != NULL)
+			{
+				if (uid)
+					g_ptr_array_add (needheaders, g_strdup (uid));
+				uid = strtok (NULL, " ");
+				cnt++;
+			}
+		}
+
+		g_free (resp); 
+		resp=NULL;
+	}
+	if (type == CAMEL_IMAP_RESPONSE_TAGGED && resp)
+		g_free (resp);
+
+	if (type == CAMEL_IMAP_RESPONSE_ERROR) 
+	{
+		if (resp) 
+			g_free (resp);
+		camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
+				_("Connection canceled"));
+		cnt = 0;
+	}
+
+	return cnt;
+
+}
 
 static void
 imap_update_summary (CamelFolder *folder, int exists,
 		     CamelFolderChangeInfo *changes,
 		     CamelException *ex)
 {
-	CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
-	CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
-	GPtrArray *fetch_data = NULL, *messages = NULL, *needheaders;
-	guint32 flags, uidval;
-	int i, seq, first, size, got;
-	CamelImapResponseType type;
-	GString *header_spec = NULL;
-	CamelImapMessageInfo *mi, *info;
-	CamelStream *stream;
-	char *uid, *resp;
-	GData *data;
-	
-	if (store->server_level >= IMAP_LEVEL_IMAP4REV1) {
-		if (store->headers == IMAP_FETCH_ALL_HEADERS)
-			header_spec = g_string_new ("HEADER");
-		else {
-			gchar *temp;
-			header_spec = g_string_new ("HEADER.FIELDS (");
-			header_spec = g_string_append (header_spec, CAMEL_MESSAGE_INFO_HEADERS);
-			if (store->headers == IMAP_FETCH_MAILING_LIST_HEADERS)
-				header_spec = g_string_append (header_spec, MAILING_LIST_HEADERS);
-			if (store->custom_headers)
-				header_spec = g_string_append (header_spec, store->custom_headers);
-
-			temp = g_strdup(header_spec->str);
-			temp = g_strstrip (temp);
-			header_spec = g_string_new (temp);
-			g_free (temp);
-			header_spec = g_string_append (header_spec, ")");
-		}
-	} else
-		header_spec = g_string_new ("0");
+   CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
+   CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
+   GPtrArray *needheaders;
+   guint32 flags;
+   int seq=0;
+   CamelImapResponseType type;
+   const char *header_spec;
+   CamelImapMessageInfo *mi;
+   char *resp;
+   GData *data;
+   gboolean more = TRUE, oosync = FALSE, oldrescval = imap_folder->need_rescan;
+   unsigned int nextn, cnt=0, tcnt=0, ucnt=0, ineed = 0, allhdrs = 0;
 
-	d(printf("Header is : %s", header_spec->str));
-	
-	/* Figure out if any of the new messages are already cached (which
-	 * may be the case if we're re-syncing after disconnected operation).
-	 * If so, get their UIDs, FLAGS, and SIZEs. If not, get all that
-	 * and ask for the headers too at the same time.
-	 */
+   if (!store->ostream || !store->istream)
+	return;
+
+   if (store->server_level >= IMAP_LEVEL_IMAP4REV1)
+   	header_spec = "HEADER.FIELDS (" CAMEL_MESSAGE_INFO_HEADERS ")";
+   else
+   	header_spec = "0";
+
+   if( g_getenv ("TNY_IMAP_FETCH_ALL_HEADERS") )
+   	header_spec = "HEADER";
+
+   nextn = 0;
+   if (folder->summary)
+   	nextn = camel_folder_summary_count (folder->summary);
+   if (nextn <= 0) {
+   	camel_folder_summary_load (folder->summary);
+   	nextn = camel_folder_summary_count (folder->summary);
+   }
+
+   ineed = (exists - nextn);
+   nextn = 1;
+   tcnt = 0;
+
+   camel_operation_start (NULL, _("Fetching summary information for new messages in folder"));
+
+   camel_folder_summary_prepare_hash (folder->summary);
+
+   store->dontdistridlehack = TRUE;
+
+   while (more)
+   {
+	gboolean did_hack = FALSE;
+	gint hcnt = 0;
+	CamelFolderChangeInfo *mchanges;
+
+	imap_folder->need_rescan = TRUE;
+	camel_folder_summary_save (folder->summary);
 	seq = camel_folder_summary_count (folder->summary);
-	first = seq + 1;
-	if (seq > 0) {
-		mi = (CamelImapMessageInfo *)camel_folder_summary_index (folder->summary, seq - 1);
-		uidval = strtoul(camel_message_info_uid (mi), NULL, 10);
-		camel_message_info_free(&mi->info);
-	} else
-		uidval = 0;
-	
-	size = (exists - seq) * (IMAP_PRETEND_SIZEOF_FLAGS + IMAP_PRETEND_SIZEOF_SIZE + IMAP_PRETEND_SIZEOF_HEADERS);
-	got = 0;
+
 	if (!camel_imap_command_start (store, folder, ex,
-				       "UID FETCH %d:* (FLAGS RFC822.SIZE INTERNALDATE BODY.PEEK[%s])",
-				       uidval + 1, header_spec->str)) {
-		g_string_free (header_spec, TRUE);
+		"UID SEARCH %d:%d ALL", seq + 1, seq + 1 + nextn)) 
+		{ if (!camel_operation_cancel_check (NULL))
+			g_warning ("IMAP error getting UIDs (1)"); 
+		 camel_operation_end (NULL); return; }
+
+	more = FALSE; 
+	needheaders = g_ptr_array_new ();
+	cnt = imap_get_uids (folder, store, ex, needheaders, (exists - seq));
+
+	if (cnt == 0 && camel_exception_get_id (ex) == CAMEL_EXCEPTION_USER_CANCEL)
+	{
+		if (!camel_operation_cancel_check (NULL))
+			g_warning ("IMAP error getting UIDs (1,1)");
+
+		g_ptr_array_foreach (needheaders, (GFunc)g_free, NULL);
+		g_ptr_array_free (needheaders, TRUE);
+		camel_operation_end (NULL);
+		more = FALSE;
+		camel_folder_summary_kill_hash (folder->summary);
+		store->dontdistridlehack = FALSE;
 		return;
 	}
-	camel_operation_start (NULL, _("Fetching summary information for new messages in %s"), folder->name);
-	
-	/* Parse the responses. We can't add a message to the summary
-	 * until we've gotten its headers, and there's no guarantee
-	 * the server will send the responses in a useful order...
-	 */
-	fetch_data = g_ptr_array_new ();
-	messages = g_ptr_array_new ();
-	while ((type = camel_imap_command_response (store, &resp, ex)) ==
-	       CAMEL_IMAP_RESPONSE_UNTAGGED) {
-		data = parse_fetch_response (imap_folder, resp);
-		g_free (resp);
-		if (!data)
-			continue;
-		
-		seq = GPOINTER_TO_INT (g_datalist_get_data (&data, "SEQUENCE"));
-		if (seq < first) {
-			g_datalist_clear (&data);
-			continue;
-		}
-		
-		if (g_datalist_get_data (&data, "FLAGS"))
-			got += IMAP_PRETEND_SIZEOF_FLAGS;
-		if (g_datalist_get_data (&data, "RFC822.SIZE"))
-			got += IMAP_PRETEND_SIZEOF_SIZE;
-		stream = g_datalist_get_data (&data, "BODY_PART_STREAM");
-		if (stream) {
-			got += IMAP_PRETEND_SIZEOF_HEADERS;
-			
-			/* Use the stream now so we don't tie up many
-			 * many fds if we're fetching many many messages.
-			 */
-			add_message_from_data (folder, messages, first, data);
-			g_datalist_set_data (&data, "BODY_PART_STREAM", NULL);
+
+	tcnt += cnt;
+
+	/* Figure out whether we need more */
+	more = (cnt < (exists - seq));
+	/* If we received less than what we asked for, yet need more */
+	if ((cnt < nextn) && more)
+	{
+		if (!camel_imap_command_start (store, folder, ex,
+			"UID SEARCH %d:* ALL", seq + 1 + cnt)) 
+			{ if (!camel_operation_cancel_check (NULL))
+				g_warning ("IMAP error getting UIDs (2)"); 
+			  camel_operation_end (NULL); 
+			  store->dontdistridlehack = FALSE; return; }
+		cnt = imap_get_uids (folder, store, ex, needheaders, (exists - seq) - cnt);
+
+		if (cnt == 0 && camel_exception_get_id (ex) == CAMEL_EXCEPTION_USER_CANCEL)
+		{
+			if (!camel_operation_cancel_check (NULL))
+				g_warning ("IMAP error getting UIDs (2,1)");
+
+			g_ptr_array_foreach (needheaders, (GFunc)g_free, NULL);
+			g_ptr_array_free (needheaders, TRUE);
+			camel_operation_end (NULL);
+			more = FALSE;
+			camel_folder_summary_kill_hash (folder->summary);
+			store->dontdistridlehack = FALSE;
+			return;
 		}
-		
-		camel_operation_progress (NULL, got * 100 / size);
-		g_ptr_array_add (fetch_data, data);
-	}
-	camel_operation_end (NULL);
-	
-	if (type == CAMEL_IMAP_RESPONSE_ERROR)
-		goto lose;
-	
-	/* Free the final tagged response */
-	g_free (resp);
-	
-	/* Figure out which headers we still need to fetch. */
-	needheaders = g_ptr_array_new ();
-	size = got = 0;
-	for (i = 0; i < fetch_data->len; i++) {
-		data = fetch_data->pdata[i];
-		if (g_datalist_get_data (&data, "BODY_PART_LEN"))
-			continue;
-		
-		uid = g_datalist_get_data (&data, "UID");
-		if (uid) {
-			g_ptr_array_add (needheaders, uid);
-			size += IMAP_PRETEND_SIZEOF_HEADERS;
+
+		tcnt += cnt;
+		/* If we still received too few */
+		if (tcnt < (exists - seq))
+		{
+			g_ptr_array_foreach (needheaders, (GFunc)g_free, NULL);
+			g_ptr_array_free (needheaders, TRUE);
+			needheaders = g_ptr_array_new ();
+			if (!camel_imap_command_start (store, folder, ex,
+				"UID SEARCH 1:* ALL"))
+				{ if (!camel_operation_cancel_check (NULL)) 
+					g_warning ("IMAP error getting UIDs (3)");
+					camel_folder_summary_kill_hash (folder->summary);
+				  camel_operation_end (NULL); 
+				  store->dontdistridlehack = FALSE; return; }
+			camel_folder_summary_clear (folder->summary);
+			tcnt = cnt = imap_get_uids (folder, store, ex, needheaders, (exists - seq) - tcnt);
+
+			if (cnt == 0 && camel_exception_get_id (ex) == CAMEL_EXCEPTION_USER_CANCEL)
+			{
+				if (!camel_operation_cancel_check (NULL))
+					g_warning ("IMAP error getting UIDs (3,1)");
+
+				g_ptr_array_foreach (needheaders, (GFunc)g_free, NULL);
+				g_ptr_array_free (needheaders, TRUE);
+				camel_operation_end (NULL);
+				more = FALSE;
+				camel_folder_summary_kill_hash (folder->summary);
+				store->dontdistridlehack = FALSE;
+				return;
+			}
 		}
+		camel_operation_end (NULL);
+		more = FALSE;
+		did_hack = TRUE;
 	}
-	
-	/* And fetch them */
-	if (needheaders->len) {
-		char *uidset;
+
+	nextn = (nextn < 1000) ? nextn+nextn+25 : 1000;
+
+	if (needheaders->len) 
+	{
 		int uid = 0;
-		
+		char *uidset;
+
+		ucnt = 0;
 		qsort (needheaders->pdata, needheaders->len,
-		       sizeof (void *), uid_compar);
-		
-		camel_operation_start (NULL, _("Fetching summary information for new messages in %s"), folder->name);
-		
-		while (uid < needheaders->len) {
+			sizeof (void *), uid_compar);
+
+		mchanges = camel_folder_change_info_new ();
+
+		while (uid < needheaders->len) 
+		{
 			uidset = imap_uid_array_to_set (folder->summary, needheaders, uid, UID_SET_LIMIT, &uid);
 			if (!camel_imap_command_start (store, folder, ex,
-						       "UID FETCH %s BODY.PEEK[%s]",
-						       uidset, header_spec->str)) {
+						       "UID FETCH %s (FLAGS RFC822.SIZE INTERNALDATE BODY.PEEK[%s])",
+						       uidset, header_spec)) 
+			{
+				if (!camel_operation_cancel_check (NULL))
+					g_warning ("IMAP error getting headers (1)");
+				g_ptr_array_foreach (needheaders, (GFunc)g_free, NULL);
 				g_ptr_array_free (needheaders, TRUE);
 				camel_operation_end (NULL);
 				g_free (uidset);
-				g_string_free (header_spec, TRUE);
-				goto lose;
+				more = FALSE;
+				camel_folder_summary_kill_hash (folder->summary);
+				store->dontdistridlehack = FALSE;
+				return;
 			}
 			g_free (uidset);
-			
+
+			resp = NULL;
 			while ((type = camel_imap_command_response (store, &resp, ex))
-			       == CAMEL_IMAP_RESPONSE_UNTAGGED) {
+				== CAMEL_IMAP_RESPONSE_UNTAGGED) 
+			{
+				gchar *muid;
+				guint32 sequence, curlen;
+
 				data = parse_fetch_response (imap_folder, resp);
-				g_free (resp);
+				g_free (resp); resp = NULL;
+
 				if (!data)
 					continue;
-				
-				stream = g_datalist_get_data (&data, "BODY_PART_STREAM");
-				if (stream) {
-					add_message_from_data (folder, messages, first, data);
-					got += IMAP_PRETEND_SIZEOF_HEADERS;
-					camel_operation_progress (NULL, got * 100 / size);
+
+				mi = message_from_data (folder, data);
+
+				if (mi) 
+				{
+				  flags = GPOINTER_TO_INT (g_datalist_get_data (&data, "FLAGS"));
+				  if (flags) 
+				  {
+					mi->server_flags = flags;
+					mi->info.flags |= flags;
+					/* flags_to_label(folder, mi); */
+				  }
+
+				  muid = g_datalist_get_data (&data, "UID");
+				  if (muid) 
+				  {
+					if (mi->info.uid && mi->info.flags & CAMEL_MESSAGE_INFO_UID_NEEDS_FREE)
+						g_free (mi->info.uid);
+					mi->info.uid = g_strdup (muid);
+					mi->info.flags |= CAMEL_MESSAGE_INFO_UID_NEEDS_FREE;
+				  }
+
+				  ucnt++;
+
+				  allhdrs++;
+				  camel_operation_progress (NULL, allhdrs , ineed);
+				  sequence = GPOINTER_TO_INT (g_datalist_get_data (&data, "SEQUENCE"));
+				  curlen = camel_folder_summary_count (folder->summary);
+
+				  if (sequence > 0 && sequence <= exists && sequence != curlen)
+				  {
+					int r;
+					if (curlen > sequence)
+					{
+						for (r = curlen-1; r >= sequence -1; r--)
+						{ 
+							g_warning ("Problem with your local summary store (too much), correcting: curlen=%d, r=%d, seq=%d\n", curlen, r, sequence);
+							CamelMessageInfo *ri = g_ptr_array_index (folder->summary->messages, r);
+							if (ri) {
+								/* camel_folder_change_info_remove_uid (mchange, camel_message_info_uid (mi)); */
+								((CamelMessageInfoBase*)ri)->flags |= CAMEL_MESSAGE_EXPUNGED;
+								((CamelMessageInfoBase*)ri)->flags |= CAMEL_MESSAGE_FREED;
+								camel_folder_summary_remove (folder->summary, ri);
+							}
+						}
+					} else {
+						for (r=0; r < sequence - curlen - 1; r++)
+						{
+							CamelMessageInfo *ni = camel_message_info_clone (mi);
+							if (ni) {
+								g_warning ("Problem with your local summary store (too few), correcting: curlen=%d, r=%d, seq=%d\n", curlen, r, sequence);
+								camel_folder_summary_add (folder->summary, (CamelMessageInfo *)ni);
+								/* camel_folder_change_info_add_uid (mchanges, camel_message_info_uid (ni)); */
+							}
+						}
+					}
+					oosync = TRUE;
+				  }
+
+				  camel_folder_summary_add (folder->summary, (CamelMessageInfo *)mi);
+
+				  /* printf ("Change: %s!\n", camel_message_info_uid (mi)); */
+				  camel_folder_change_info_add_uid (mchanges, camel_message_info_uid (mi));
+				   if ((mi->info.flags & CAMEL_IMAP_MESSAGE_RECENT))
+					camel_folder_change_info_recent_uid(mchanges, camel_message_info_uid (mi));
 				}
+
+				if (did_hack) {
+					hcnt++;
+					if (hcnt > 1000) {
+						camel_folder_summary_save (folder->summary);
+						camel_folder_summary_prepare_hash (folder->summary);
+						hcnt = 0;
+					}
+				}
+
 				g_datalist_clear (&data);
 			}
-			
-			if (type == CAMEL_IMAP_RESPONSE_ERROR) {
+
+			if (resp != NULL) 
+				g_free (resp);
+
+			if (type == CAMEL_IMAP_RESPONSE_ERROR) 
+			{
+				if (!camel_operation_cancel_check (NULL))
+					g_warning ("IMAP error getting headers (2)");
+				g_ptr_array_foreach (needheaders, (GFunc)g_free, NULL);
 				g_ptr_array_free (needheaders, TRUE);
 				camel_operation_end (NULL);
-				goto lose;
+				more = FALSE;
+				camel_folder_summary_kill_hash (folder->summary);
+				store->dontdistridlehack = FALSE;
+				return;
 			}
+
 		}
-		g_string_free (header_spec, TRUE);	
-		g_ptr_array_free (needheaders, TRUE);
-		camel_operation_end (NULL);
-	}
-	
-	/* Now finish up summary entries (fix UIDs, set flags and size) */
-	for (i = 0; i < fetch_data->len; i++) {
-		data = fetch_data->pdata[i];
+
 		
-		seq = GPOINTER_TO_INT (g_datalist_get_data (&data, "SEQUENCE"));
-		if (seq >= first + messages->len) {
-			g_datalist_clear (&data);
-			continue;
+		if (camel_folder_change_info_changed (mchanges)) {
+			camel_object_trigger_event (CAMEL_OBJECT (folder), "folder_changed", mchanges);
+			/* printf ("Changes!\n"); */
 		}
-		
-		mi = messages->pdata[seq - first];
-		if (mi == NULL) {
-			CamelMessageInfo *pmi = NULL;
-			int j;
-			
-			/* This is a kludge around a bug in Exchange
-			 * 5.5 that sometimes claims multiple messages
-			 * have the same UID. See bug #17694 for
-			 * details. The "solution" is to create a fake
-			 * message-info with the same details as the
-			 * previously valid message. Yes, the user
-			 * will have a clone in his/her message-list,
-			 * but at least we don't crash.
-			 */
-			
-			/* find the previous valid message info */
-			for (j = seq - first - 1; j >= 0; j--) {
-				pmi = messages->pdata[j];
-				if (pmi != NULL)
-					break;
-			}
-			
-			if (pmi == NULL) {
-				/* Server response is *really* fucked up,
-				   I guess we just pretend it never happened? */
-				continue;
+		camel_folder_change_info_free (mchanges);
+
+	}
+
+	if (ucnt < needheaders->len)
+		g_warning ("Problem while receiving headers from IMAP "
+			"(I didn't receive enough headers %d vs %d)\n",
+			ucnt, needheaders->len);
+
+	g_ptr_array_foreach (needheaders, (GFunc)g_free, NULL);
+	g_ptr_array_free (needheaders, TRUE);
+
+   } /* more */
+
+   if (oosync)
+	imap_folder->need_rescan = TRUE;
+
+   camel_folder_summary_save (folder->summary);
+   camel_folder_summary_kill_hash (folder->summary);
+   camel_operation_end (NULL);
+
+   imap_folder->need_rescan = oldrescval;
+   store->dontdistridlehack = FALSE;
+
+}
+
+typedef struct {
+	guint32 id;
+	guint32 flags;
+} FetchIdleResponse;
+
+typedef struct {
+	guint32 exists;
+	guint32 recent;
+	GArray *expunged;
+	GPtrArray *fetch;
+	gboolean fetch_happened;
+	CamelFolder *folder;
+} IdleResponse;
+
+static void 
+process_idle_response (IdleResponse *idle_resp)
+{
+	CamelException ex = CAMEL_EXCEPTION_INITIALISER;
+
+	idle_debug ("process_idle_response\n");
+
+	if (!idle_resp)
+		return;
+
+	if (idle_resp->fetch && idle_resp->folder)
+	{
+		CamelMessageInfo *info;
+		CamelImapMessageInfo *iinfo;
+		CamelFolderChangeInfo *changes = NULL;
+
+		guint i=0;
+		for (i=0; i < idle_resp->fetch->len; i++)
+		{
+			FetchIdleResponse *fid = idle_resp->fetch->pdata[i];
+			info = camel_folder_summary_index (idle_resp->folder->summary, fid->id);
+			iinfo = (CamelImapMessageInfo *) info;
+
+			if (info) 
+			{
+				if (fid->flags != iinfo->server_flags) 
+				{
+					camel_folder_summary_touch (idle_resp->folder->summary);
+					guint32 server_set, server_cleared;
+					server_set = fid->flags & ~iinfo->server_flags;
+					server_cleared = iinfo->server_flags & ~fid->flags;
+					iinfo->info.flags = (iinfo->info.flags | server_set) & ~server_cleared;
+					iinfo->server_flags = fid->flags;
+					if (changes == NULL)
+						changes = camel_folder_change_info_new();
+					camel_folder_change_info_change_uid(changes, info->uid);
+				}
+				camel_message_info_free (info);
 			}
-			
-			mi = (CamelImapMessageInfo *)camel_message_info_clone(pmi);
 		}
-		
-		uid = g_datalist_get_data (&data, "UID");
-		if (uid)
-			mi->info.uid = g_strdup (uid);
-		flags = GPOINTER_TO_INT (g_datalist_get_data (&data, "FLAGS"));
-		if (flags) {
-			((CamelImapMessageInfo *)mi)->server_flags = flags;
-			/* "or" them in with the existing flags that may
-			 * have been set by summary_info_new_from_message.
-			 */
-			mi->info.flags |= flags;
-			flags_to_label(folder, mi);
+
+		if (changes)
+		{
+			if (camel_folder_change_info_changed (changes))
+				camel_object_trigger_event (CAMEL_OBJECT (idle_resp->folder), "folder_changed", changes);
+			camel_folder_change_info_free (changes);
+			camel_folder_summary_save (idle_resp->folder->summary);
 		}
-		size = GPOINTER_TO_INT (g_datalist_get_data (&data, "RFC822.SIZE"));
-		if (size)
-			mi->info.size = size;
-		
-		g_datalist_clear (&data);
+
 	}
-	g_ptr_array_free (fetch_data, TRUE);
-	
-	/* And add the entries to the summary, etc. */
-	for (i = 0; i < messages->len; i++) {
-		mi = messages->pdata[i];
-		if (!mi) {
-			g_warning ("No information for message %d", i + first);
-			camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
-					      _("Incomplete server response: no information provided for message %d"),
-					      i + first);
-			break;
-		}
-		uid = (char *)camel_message_info_uid(mi);
-		if (uid[0] == 0) {
-			g_warning("Server provided no uid: message %d", i + first);
-			camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
-					      _("Incomplete server response: no UID provided for message %d"),
-					      i + first);
-			break;
+
+	camel_imap_folder_changed_for_idle (idle_resp->folder, idle_resp->exists, 
+		idle_resp->expunged, &ex);
+
+}
+
+static void
+read_idle_response (CamelFolder *folder, char *resp, IdleResponse *idle_resp)
+{
+	char *ptr = strchr (resp, '*');
+
+	idle_debug ("read_idle_response\n");
+
+	if (ptr && strstr (resp, "EXISTS") != NULL)
+		idle_resp->exists = strtoul (resp + 1, NULL, 10);
+
+	if (ptr && strstr (resp, "RECENT") != NULL)
+		idle_resp->recent = strtoul (resp + 1, NULL, 10);
+
+	if (ptr && strstr (resp, "FETCH") != NULL)
+	{
+		char *fptr = resp;
+
+		FetchIdleResponse *fid = g_slice_new0 (FetchIdleResponse);
+		fid->id = strtoul (resp + 1, NULL, 10);
+		fptr += 9;
+		fid->flags = imap_parse_flag_list (&fptr);
+
+		if (idle_resp->fetch == NULL)
+			idle_resp->fetch = g_ptr_array_new ();
+		g_ptr_array_add (idle_resp->fetch, fid);
+	}
+
+	if (ptr && strstr (resp, "EXPUNGE") != NULL) 
+	{
+		guint32 id = strtoul (resp + 1, NULL, 10);
+
+		if (idle_resp->expunged == NULL)
+			idle_resp->expunged = g_array_new (FALSE, FALSE, sizeof (int));
+		g_array_append_val (idle_resp->expunged, id);
+	}
+}
+
+static IdleResponse*
+idle_response_new (CamelFolder *folder)
+{
+	IdleResponse *idle_resp = g_slice_new0 (IdleResponse);
+
+	idle_debug ("idle_response_new\n");
+
+	idle_resp->folder = folder;
+	camel_object_ref (CAMEL_OBJECT (folder));
+	return idle_resp;
+}
+
+static void
+idle_response_free (IdleResponse *idle_resp)
+{
+	idle_debug ("idle_response_free\n");
+
+	guint i=0;
+
+	if (idle_resp->expunged)
+		g_array_free (idle_resp->expunged, TRUE);
+
+	if (idle_resp->fetch) 
+		for (i=0 ;i < idle_resp->fetch->len; i++)
+			g_slice_free (FetchIdleResponse, idle_resp->fetch->pdata[i]);
+
+	if (idle_resp->folder)
+		camel_object_unref (CAMEL_OBJECT (idle_resp->folder));
+
+	g_slice_free (IdleResponse, idle_resp);
+}
+
+static void
+idle_real_start (CamelImapStore *store)
+{
+	idle_debug ("idle_real_start\n");
+
+	g_mutex_lock (store->stream_lock);
+	store->idle_prefix = g_strdup_printf ("%c%.5u", 
+		store->tag_prefix, store->command++);
+	camel_stream_printf (store->ostream, "%s IDLE\r\n",
+		store->idle_prefix);
+	g_mutex_unlock (store->stream_lock);
+
+}
+
+static IdleResponse*
+idle_deal_with_stuff (CamelFolder *folder, CamelImapStore *store, gboolean *had_err, gboolean *had_lock)
+{
+  IdleResponse *idle_resp = NULL;
+  CamelException ex = CAMEL_EXCEPTION_INITIALISER;
+  char *resp = NULL;
+  int nwritten;
+  CamelImapResponseType type;
+  gboolean hlock = FALSE;
+
+  idle_debug ("idle_deal_with_stuff\n");
+
+  if (!folder || !CAMEL_IS_IMAP_FOLDER (folder))
+	return NULL;
+  if (!store || !CAMEL_IS_IMAP_STORE (store))
+	return NULL;
+  if (!camel_disco_store_check_online ((CamelDiscoStore*)store, &ex))
+	return NULL;
+  if (store->istream == NULL || ((CamelObject *)store->istream)->ref_count <= 0)
+	return NULL;
+  if (store->ostream == NULL || ((CamelObject *)store->istream)->ref_count <= 0)
+	return NULL;
+
+  hlock = CAMEL_SERVICE_REC_TRYLOCK (store, connect_lock);
+
+  if (hlock)
+  {
+	if (store->current_folder)
+	{
+		resp = NULL;
+		while (camel_imap_store_readline_nb (store, &resp, &ex) > 0)
+		{
+			/* printf ("resp: %s\n", resp); */
+			if (strchr (resp, '*') != NULL && (strstr (resp, "EXISTS") || 
+				strstr (resp, "FETCH")|| strstr (resp, "EXPUNGE") || 
+				strstr (resp, "RECENT")))
+			{
+				if (!idle_resp) 
+					idle_resp = idle_response_new (folder);
+				read_idle_response (folder, resp, idle_resp);
+			}
+			g_free (resp); resp=NULL;
 		}
-		info = (CamelImapMessageInfo *)camel_folder_summary_uid(folder->summary, uid);
-		if (info) {
-			for (seq = 0; seq < camel_folder_summary_count (folder->summary); seq++) {
-				if (folder->summary->messages->pdata[seq] == info)
-					break;
+		if (resp)
+			g_free (resp);
+
+		g_mutex_lock (store->stream_lock);
+		if (!camel_disco_store_check_online ((CamelDiscoStore*)store, &ex))
+			{ g_mutex_unlock (store->stream_lock); return NULL; }
+		if (store->istream == NULL || ((CamelObject *)store->istream)->ref_count <= 0)
+			{ g_mutex_unlock (store->stream_lock); return NULL; }
+		if (store->ostream == NULL || ((CamelObject *)store->istream)->ref_count <= 0)
+			{ g_mutex_unlock (store->stream_lock); return NULL; }
+		if (store->ostream && CAMEL_IS_STREAM (store->ostream)) {
+			idle_debug ("Sending DONE in idle_deal_with_stuff (nb)\n");
+			nwritten = camel_stream_printf (store->ostream, "DONE\r\n");
+		}
+		g_mutex_unlock (store->stream_lock);
+
+		if (nwritten == -1) 
+			goto outofhere;
+
+		resp = NULL;
+		while ((type = camel_imap_command_response_idle (store, &resp, &ex)) == CAMEL_IMAP_RESPONSE_UNTAGGED) 
+		{
+			/* printf ("D resp: %s\n", resp); */
+			if (strchr (resp, '*') != NULL && (strstr (resp, "EXISTS") ||
+				strstr (resp, "FETCH") || strstr (resp, "EXPUNGE") || 
+				strstr (resp, "RECENT")))
+			{
+				if (!idle_resp)
+					idle_resp = idle_response_new (folder);
+				read_idle_response (folder, resp, idle_resp);
 			}
-			
-			g_warning("Message already present? %s", camel_message_info_uid(mi));
-			camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
-					      _("Unexpected server response: Identical UIDs provided for messages %d and %d"),
-					      seq + 1, i + first);
-			
-			camel_message_info_free(&info->info);
-			break;
+			g_free (resp); resp=NULL;
+		}
+
+		if (type == CAMEL_IMAP_RESPONSE_ERROR)
+			*had_err = TRUE;
+
+		if (resp)
+			g_free (resp);
+
+	} else {
+		g_mutex_lock (store->stream_lock);
+		if (!camel_disco_store_check_online ((CamelDiscoStore*)store, &ex))
+			{ g_mutex_unlock (store->stream_lock); return NULL; }
+		if (store->istream == NULL || ((CamelObject *)store->istream)->ref_count <= 0)
+			{ g_mutex_unlock (store->stream_lock); return NULL; }
+		if (store->ostream == NULL || ((CamelObject *)store->istream)->ref_count <= 0)
+			{ g_mutex_unlock (store->stream_lock); return NULL; }
+		if (store->ostream && CAMEL_IS_STREAM (store->ostream)) {
+			idle_debug ("Sending DONE in idle_deal_with_stuff (b)\n");
+			nwritten = camel_stream_printf (store->ostream, "DONE\r\n");
+		}
+		g_mutex_unlock (store->stream_lock);
+		if (nwritten == -1) 
+			goto outofhere;
+		resp = NULL;
+		while ((type = camel_imap_command_response_idle (store, &resp, &ex)) == CAMEL_IMAP_RESPONSE_UNTAGGED) 
+			{ g_free (resp); resp=NULL; }
+		if (resp)
+			g_free (resp);
+	}
+
+outofhere:
+
+	CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
+  } 
+
+  *had_lock = hlock;
+
+  return idle_resp;
+}
+
+void
+camel_imap_folder_stop_idle (CamelFolder *folder)
+{
+	CamelImapStore *store;
+	IdleResponse *idle_resp = NULL;
+	gboolean had_err = FALSE;
+	CamelException ex = CAMEL_EXCEPTION_INITIALISER;
+
+	idle_debug ("camel_imap_folder_stop_idle\n");
+
+	if (!folder || !CAMEL_IS_IMAP_FOLDER (folder))
+		return;
+
+	store = CAMEL_IMAP_STORE (folder->parent_store);
+
+	if (!store || !CAMEL_IS_IMAP_STORE (store))
+		return;
+	if (!camel_disco_store_check_online ((CamelDiscoStore*)store, &ex))
+		return;
+	if (store->istream == NULL || ((CamelObject *)store->istream)->ref_count <= 0)
+		return;
+	if (store->ostream == NULL || ((CamelObject *)store->istream)->ref_count <= 0)
+		return;
+
+	g_static_rec_mutex_lock (((CamelImapFolder *)folder)->idle_lock);
+
+	if ((store->capabilities & IMAP_CAPABILITY_IDLE) && store->idle_prefix)
+	{
+		gboolean had_lock = FALSE;
+		g_free (store->idle_prefix);
+		store->idle_prefix = NULL;
+
+		if (store->idle_signal > 0) 
+			g_source_remove (store->idle_signal);
+
+		idle_resp = idle_deal_with_stuff (folder, store, &had_err, &had_lock);
+
+		/* Outside of the lock of course */
+		if (idle_resp && !had_err)
+			process_idle_response (idle_resp);
+
+		/* idle_real_start (store); */
+
+		if (idle_resp) 
+			idle_response_free (idle_resp);
+	}
+
+	g_static_rec_mutex_unlock (((CamelImapFolder *)folder)->idle_lock);
+}
+
+static void
+idle_timeout_checker_destroy (gpointer data)
+{
+	idle_debug ("idle_timeout_checker_destroy\n");
+
+	return;
+}
+
+static gboolean 
+idle_timeout_checker (gpointer data)
+{
+	CamelFolder *folder = (CamelFolder *) data;
+	CamelImapFolder *imap_folder;
+	CamelImapStore *store;
+	gboolean had_err = FALSE, hadlock = FALSE;
+	CamelException ex = CAMEL_EXCEPTION_INITIALISER;
+
+	((CamelImapFolder *)folder)->in_idle = TRUE;
+
+	idle_debug ("idle_timeout_checker\n");
+
+	if ((!folder) || ((((CamelObject *)data)->ref_count <= 0) && (!CAMEL_IS_IMAP_FOLDER (folder))))
+		return FALSE;
+
+	store = CAMEL_IMAP_STORE (folder->parent_store);
+	if (!(store->capabilities & IMAP_CAPABILITY_IDLE))
+		return FALSE;
+	if (!camel_disco_store_check_online ((CamelDiscoStore*)store, &ex))
+		return FALSE;
+	if (store->istream == NULL || ((CamelObject *)store->istream)->ref_count <= 0)
+		return FALSE;
+	if (store->ostream == NULL || ((CamelObject *)store->istream)->ref_count <= 0)
+		return FALSE;
+
+	g_static_rec_mutex_lock (((CamelImapFolder *)folder)->idle_lock);
+
+
+	imap_folder = CAMEL_IMAP_FOLDER (folder);
+	if (!imap_folder->do_push_email)
+	{
+		g_static_rec_mutex_unlock (((CamelImapFolder *)folder)->idle_lock);
+		return FALSE;
+	}
+
+	if (store->idle_prefix != NULL)
+	{
+		gboolean had_lock = FALSE;
+		IdleResponse *idle_resp = idle_deal_with_stuff (folder, store, &had_err,&hadlock);
+
+		if (idle_resp && !had_err)
+			process_idle_response (idle_resp);
+
+		if (hadlock)
+			idle_real_start (store);
+
+		if (idle_resp)
+			idle_response_free (idle_resp);
+	}
+
+	g_static_rec_mutex_unlock (((CamelImapFolder *)folder)->idle_lock);
+
+	if (((CamelImapFolder *)folder)->stopping)
+	{
+		g_static_rec_mutex_free (((CamelImapFolder *)folder)->idle_lock);
+		((CamelImapFolder *)folder)->idle_lock = NULL;
+		((CamelImapFolder *)folder)->in_idle = FALSE;
+		return FALSE;
+	}
+
+	((CamelImapFolder *)folder)->in_idle = FALSE;
+
+	return TRUE;
+}
+
+
+void
+camel_imap_folder_start_idle (CamelFolder *folder)
+{
+	CamelImapStore *store;
+	CamelImapFolder *imap_folder = (CamelImapFolder *) folder;
+	CamelException ex = CAMEL_EXCEPTION_INITIALISER;
+
+	idle_debug ("camel_imap_folder_start_idle\n");
+
+	if (!folder || !CAMEL_IS_IMAP_FOLDER (folder))
+		return;
+
+	store = CAMEL_IMAP_STORE (folder->parent_store);
+	if (!store || !CAMEL_IS_IMAP_STORE (store))
+		return;
+	if (!camel_disco_store_check_online ((CamelDiscoStore*)store, &ex))
+		return;
+	if (store->istream == NULL || ((CamelObject *)store->istream)->ref_count <= 0)
+		return;
+	if (store->ostream == NULL || ((CamelObject *)store->istream)->ref_count <= 0)
+		return;
+
+	g_static_rec_mutex_lock (((CamelImapFolder *)folder)->idle_lock);
+
+	if (store->capabilities & IMAP_CAPABILITY_IDLE)
+	{
+		if (store->current_folder && !store->idle_prefix)
+		{
+			folder->folder_flags |= CAMEL_FOLDER_HAS_PUSHEMAIL_CAPABILITY;
+
+			idle_real_start (store);
+
+			store->idle_signal = g_timeout_add_full (G_PRIORITY_DEFAULT_IDLE, 5 * 1000,
+				idle_timeout_checker, folder, idle_timeout_checker_destroy);
+
+			imap_folder->idle_signal = store->idle_signal;
 		}
-		
-		camel_folder_summary_add (folder->summary, (CamelMessageInfo *)mi);
-		camel_folder_change_info_add_uid (changes, camel_message_info_uid (mi));
-		
-		if ((mi->info.flags & CAMEL_IMAP_MESSAGE_RECENT))
-			camel_folder_change_info_recent_uid(changes, camel_message_info_uid (mi));
 	}
 
-	for ( ; i < messages->len; i++) {
-		if ((mi = messages->pdata[i]))
-			camel_message_info_free(&mi->info);
-	}
-	
-	g_ptr_array_free (messages, TRUE);
-	
-	return;
-	
- lose:
-	if (fetch_data) {
-		for (i = 0; i < fetch_data->len; i++) {
-			data = fetch_data->pdata[i];
-			g_datalist_clear (&data);
-		}
-		g_ptr_array_free (fetch_data, TRUE);
+	g_static_rec_mutex_unlock (((CamelImapFolder *)folder)->idle_lock);
+
+}
+
+
+static void 
+imap_set_push_email (CamelFolder *folder, gboolean setting)
+{
+	CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
+
+	if (imap_folder->do_push_email && !setting) {
+		imap_folder->do_push_email = setting;
+		camel_imap_folder_stop_idle (folder);
 	}
-	if (messages) {
-		for (i = 0; i < messages->len; i++) {
-			if (messages->pdata[i])
-				camel_message_info_free(messages->pdata[i]);
-		}
-		g_ptr_array_free (messages, TRUE);
+
+	if (!imap_folder->do_push_email && setting) {
+		imap_folder->do_push_email = setting;
+		camel_imap_folder_start_idle (folder);
 	}
-}
 
+	return;
+}
 /* Called with the store's connect_lock locked */
 void
 camel_imap_folder_changed (CamelFolder *folder, int exists,
@@ -2643,9 +3714,11 @@
 	if (expunged) {
 		int i, id;
 		
-		for (i = 0; i < expunged->len; i++) {
+		for (i = 0; i < expunged->len; i++) 
+		{
 			id = g_array_index (expunged, int, i);
 			info = camel_folder_summary_index (folder->summary, id - 1);
+
 			if (info == NULL) {
 				/* FIXME: danw: does this mean that the summary is corrupt? */
 				/* I guess a message that we never retrieved got expunged? */
@@ -2653,9 +3726,71 @@
 			}
 			
 			camel_folder_change_info_remove_uid (changes, camel_message_info_uid (info));
+
+			CAMEL_IMAP_FOLDER_REC_LOCK (imap_folder, cache_lock);
+			camel_imap_message_cache_remove (imap_folder->cache, camel_message_info_uid (info));
+			CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
+
+			((CamelMessageInfoBase *)info)->flags |= CAMEL_MESSAGE_EXPUNGED;
+
+			camel_folder_summary_remove (folder->summary, info);
+			camel_message_info_free(info);
+		}
+	}
+
+	len = camel_folder_summary_count (folder->summary);
+
+	if (exists > len) {
+		camel_imap_folder_stop_idle (folder);
+		imap_update_summary (folder, exists, changes, ex);
+		/* camel_imap_folder_start_idle (folder); will happen later? */
+	}
+
+	if (camel_folder_change_info_changed (changes))
+		camel_object_trigger_event (CAMEL_OBJECT (folder), "folder_changed", changes);
+	
+	camel_folder_change_info_free (changes);
+	camel_folder_summary_save (folder->summary);
+}
+
+
+static void
+camel_imap_folder_changed_for_idle (CamelFolder *folder, int exists,
+			   GArray *expunged, CamelException *ex)
+{
+	CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
+	CamelFolderChangeInfo *changes;
+	CamelMessageInfo *info;
+	int len;
+
+	/* printf ("FOR IDLE: %d vs %d\n", exists, camel_folder_summary_count (folder->summary)); */
+
+	changes = camel_folder_change_info_new ();
+	if (expunged) {
+		int i, id;
+		
+		for (i = 0; i < expunged->len; i++) 
+		{
+			const char *uid;
+
+			id = g_array_index (expunged, int, i);
+			info = camel_folder_summary_index (folder->summary, id - 1);
+
+			if (info == NULL) {
+				/* FIXME: danw: does this mean that the summary is corrupt? */
+				/* I guess a message that we never retrieved got expunged? */
+				continue;
+			}
+
+			uid = camel_message_info_uid (info);
+			camel_folder_change_info_remove_uid (changes, uid);
+
 			CAMEL_IMAP_FOLDER_REC_LOCK (imap_folder, cache_lock);
 			camel_imap_message_cache_remove (imap_folder->cache, camel_message_info_uid (info));
 			CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
+
+			((CamelMessageInfoBase *)info)->flags |= CAMEL_MESSAGE_EXPUNGED;
+
 			camel_folder_summary_remove (folder->summary, info);
 			camel_message_info_free(info);
 		}
@@ -2688,95 +3823,554 @@
 	}
 }
 
+static void 
+handle_freeup (CamelImapStore *store, gint nread, CamelException *ex)
+{
+	if (nread <= 0) 
+	{
+		if (errno == EINTR)
+			camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL, _("Operation cancelled"));
+		else
+			camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+					      _("Server unexpectedly disconnected: %s"),
+					      g_strerror (errno));
+		
+		camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
+	}
+}
+
 
 CamelStream *
 camel_imap_folder_fetch_data (CamelImapFolder *imap_folder, const char *uid,
 			      const char *section_text, gboolean cache_only,
-			      CamelException *ex)
+			      CamelFolderReceiveType type, gint param, CamelException *ex)
 {
 	CamelFolder *folder = CAMEL_FOLDER (imap_folder);
-	CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
-	CamelImapResponse *response;
-	CamelStream *stream;
-	GData *fetch_data;
-	char *found_uid;
-	int i;
-	
-	/* EXPUNGE responses have to modify the cache, which means
-	 * they have to grab the cache_lock while holding the
-	 * connect_lock.
-
-	 * Because getting the service lock may cause MUCH unecessary
-	 * delay when we already have the data locally, we do the
-	 * locking separately.  This could cause a race
-	 * getting the same data from the cache, but that is only
-	 * an inefficiency, and bad luck.
-	 */
+	CamelImapStore *store = NULL;
+	CamelStream *stream = NULL;
+	gboolean connected = FALSE, idle_rt = FALSE;
+	CamelException  tex = CAMEL_EXCEPTION_INITIALISER;
+	ssize_t nread = 0; gboolean amcon = FALSE;
+
 	CAMEL_IMAP_FOLDER_REC_LOCK (imap_folder, cache_lock);
-	stream = camel_imap_message_cache_get (imap_folder->cache, uid, section_text, ex);
-	if (!stream && (!strcmp (section_text, "HEADER") || !strcmp (section_text, "0"))) {
-		camel_exception_clear (ex);
-		stream = camel_imap_message_cache_get (imap_folder->cache, uid, "", ex);
+
+	connected = camel_disco_store_check_online(CAMEL_DISCO_STORE (folder->parent_store), &tex);
+
+	if (connected && ((type & CAMEL_FOLDER_RECEIVE_FULL) && camel_imap_message_cache_is_partial (imap_folder->cache, uid)))
+		camel_imap_message_cache_remove (imap_folder->cache, uid);
+	else if (connected && ((type & CAMEL_FOLDER_RECEIVE_PARTIAL || type & CAMEL_FOLDER_RECEIVE_SIZE_LIMITED) 
+			&& !camel_imap_message_cache_is_partial (imap_folder->cache, uid)))
+		camel_imap_message_cache_remove (imap_folder->cache, uid);
+	else
+	{
+		stream = camel_imap_message_cache_get (imap_folder->cache, uid, section_text, ex);
+		if (!stream && (!strcmp (section_text, "HEADER") || !strcmp (section_text, "0"))) 
+		{
+			camel_exception_clear (ex);
+			stream = camel_imap_message_cache_get (imap_folder->cache, uid, "", ex);
+		}
 	}
 	CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
-	
+
 	if (stream || cache_only)
 		return stream;
 
-	camel_exception_clear(ex);
-
-	CAMEL_SERVICE_REC_LOCK (store, connect_lock);
-	CAMEL_IMAP_FOLDER_REC_LOCK (imap_folder, cache_lock);
-
-	if (!camel_imap_store_connected(store, ex)) {
+	if (!camel_disco_store_check_online (CAMEL_DISCO_STORE (folder->parent_store), ex)) 
+	{
 		camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
 				     _("This message is not currently available"));
 		CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
-		CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
 		return NULL;
 	}
-	
 	camel_exception_clear (ex);
-	if (store->server_level < IMAP_LEVEL_IMAP4REV1 && !*section_text) {
-		response = camel_imap_command (store, folder, ex,
-					       "UID FETCH %s RFC822.PEEK",
-					       uid);
-	} else {
-		response = camel_imap_command (store, folder, ex,
-					       "UID FETCH %s BODY.PEEK[%s]",
-					       uid, section_text);
+
+	store = CAMEL_IMAP_STORE (camel_object_new (CAMEL_IMAP_STORE_TYPE));
+
+	camel_service_construct (CAMEL_SERVICE (store), 
+		camel_service_get_session (CAMEL_SERVICE (folder->parent_store)),
+		camel_service_get_provider (CAMEL_SERVICE (folder->parent_store)),
+		CAMEL_SERVICE (folder->parent_store)->url, ex);
+
+	if (camel_exception_is_set (ex))
+	{
+		g_critical ("Severe interal error while trying to construct a new connection\n");
+		camel_object_unref (store);
+		return NULL;
 	}
-	/* We won't need the connect_lock again after this. */
-	CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
-	
-	if (!response) {
+
+	camel_operation_start (NULL, _("Preparing to get message"));
+
+	amcon = camel_service_connect (CAMEL_SERVICE (store), ex);
+
+	if (!amcon || camel_exception_is_set (ex) || !camel_disco_store_check_online (CAMEL_DISCO_STORE (store), ex)) 
+	{
+		camel_object_unref (store);
+		camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+					_("This message is not currently available"
+					" (can't let a new connection go online)"));
 		CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
 		return NULL;
 	}
-	
-	for (i = 0; i < response->untagged->len; i++) {
-		fetch_data = parse_fetch_response (imap_folder, response->untagged->pdata[i]);
-		found_uid = g_datalist_get_data (&fetch_data, "UID");
-		stream = g_datalist_get_data (&fetch_data, "BODY_PART_STREAM");
-		if (found_uid && stream && !strcmp (uid, found_uid))
-			break;
-		
-		g_datalist_clear (&fetch_data);
-		stream = NULL;
+	camel_exception_clear (ex);
+
+	camel_operation_end (NULL);
+
+	camel_operation_start (NULL, _("Retrieving message"));
+
+  CAMEL_SERVICE_REC_LOCK(store, connect_lock); 
+
+	CAMEL_IMAP_FOLDER_REC_LOCK (imap_folder, cache_lock);
+
+	if (type & CAMEL_FOLDER_RECEIVE_FULL)
+		stream = camel_imap_message_cache_insert (imap_folder->cache, 
+			uid, section_text, "", 0, NULL);
+	else /* CAMEL_FOLDER_RECEIVE_PARTIAL, CAMEL_FOLDER_RECEIVE_SIZE_LIMITED or any */
+		stream = camel_imap_message_cache_insert (imap_folder->cache, 
+			uid, "", "", 0, NULL);
+
+	if (stream == NULL)
+		stream = camel_stream_mem_new ();
+
+	if (type & CAMEL_FOLDER_RECEIVE_FULL)
+	{
+		camel_imap_message_cache_set_partial (imap_folder->cache, uid, FALSE);
+
+		if (store->capabilities & IMAP_CAPABILITY_BINARY)
+		{
+			gchar line[MAX_LINE_LEN];
+			gboolean err = FALSE;
+			char two_bytes[2];
+			char t_str [1024];
+			int f = 0;
+			ssize_t hread = 1;
+			gint length=0, rec=0;
+			char *pos, *ppos;
+
+			nread = 1;
+
+			/* Stops idle */
+			camel_imap_command_start (store, folder, ex,
+				"UID FETCH %s BINARY.PEEK[%s]", uid, section_text);
+
+			g_mutex_lock (store->stream_lock);
+
+			two_bytes [0] = ' ';
+
+			/* a01 uid fetch 1 BINARY.PEEK[]
+			 * * 1 FETCH (UID 1 BINARY[] {24693}\r\n
+			 * Subject: Testing....
+			 * )\r\n
+			 * a01 OK .... \r\n */
+
+			/* Read the length in the "\*.*[~|]{<LENGTH>}" */
+			while (two_bytes[0] != '\n' && f < 1023 && nread > 0)
+			{
+				nread = camel_stream_read (store->ostream, two_bytes, 1);
+				line [f] = two_bytes [0];
+/* printf ("%c%c", two_bytes[0], two_bytes[1]); */
+				f++;
+			}
+			line[f] = '\0';
+/* printf ("\n"); */
+
+			/* The first line is very unlikely going to consume 1023 bytes */
+			if (f > 1023 || nread <= 0) {
+				g_warning ("BINARY: Long first line, UID=%s", uid);
+				goto berrorhander;
+			}
+
+			/* If the line doesn't start with "* " */
+			if (*line != '*' || *(line + 1) != ' ')
+				{ err = TRUE; g_warning ("BINARY: Line doesn't start with \"* \", UID=%s (%s)", uid, line); goto berrorhander; }
+			pos = strchr (line, '{');
+
+			/* If we don't find a '{' character */
+			if (!pos) 
+				{ err = TRUE; g_warning ("BINARY: Line doesn't contain a {, UID=%s (%s)", uid, line); goto berrorhander; }
+
+			/* Set the '}' character to \0 */
+			ppos = strchr (pos, '}');
+			if (ppos) 
+				*ppos = '\0';
+			else /* If we didn't find it */
+				{ err = TRUE; g_warning ("BINARY: Line doesn't contain a }, UID=%s (%s)", uid, line); goto berrorhander; }
+
+			length = strtol (pos + 1, NULL, 10);
+
+			/* If strtol failed (it's important enough to check this) */
+			if (errno == ERANGE)
+				{ err = TRUE; g_warning ("BINARY: strtol failed, UID=%s (%s)", uid, line); goto berrorhander; }
+
+			/* Until we have reached the length, read 1024 at the time */
+			while (hread > 0 && rec < length)
+			{
+				int wread = (length - rec);
+				if (wread < 1 || wread > 1024)
+					wread = 1024;
+				hread = camel_stream_read (store->ostream, t_str, wread);
+				if (hread > 0) 
+				{
+					/* And write them too */
+					camel_stream_write (stream, t_str, hread);
+					rec += hread;
+					camel_operation_progress (NULL, rec, length);
+				} else {
+					if (hread != 0) {
+						g_warning ("BINARY: read failed, UID=%s", uid);
+						err = TRUE;
+						goto berrorhander;
+					}
+				}
+			}
+
+
+			camel_stream_reset (stream);
+
+			/* Read away the last two lines */
+			for (f = 0; f < 2; f++) { 
+				nread = 1; two_bytes[0] = 'x';
+				while (two_bytes[0] != '\n' && nread > 0)
+					nread = camel_stream_read (store->ostream, two_bytes, 1); 
+			}
+berrorhander:
+			g_mutex_unlock (store->stream_lock);
+			CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
+			/* Starts idle */
+			camel_imap_folder_start_idle ((CamelFolder *) imap_folder);
+			idle_rt = TRUE;
+
+			if (err)
+				goto errorhander;
+		} else 
+		{
+			gboolean err=FALSE;
+			gchar line [MAX_LINE_LEN];
+			guint linenum = 0;
+			CamelStreamBuffer *server_stream;
+			gchar *tag;
+			guint taglen;
+			gboolean isnextdone = FALSE, hadr = FALSE;
+			guint tread = 0, exread = 0;
+
+			nread = 0;
+
+			/* Stops idle */
+			if (store->server_level < IMAP_LEVEL_IMAP4REV1 && !*section_text)
+				camel_imap_command_start (store, folder, ex,
+					"UID FETCH %s RFC822.PEEK", uid);
+			else
+				camel_imap_command_start (store, folder, ex,
+					"UID FETCH %s BODY.PEEK[%s]", uid, section_text);
+
+			tag = g_strdup_printf ("%c%.5u", store->tag_prefix, store->command-1);
+			taglen = strlen (tag);
+
+			g_mutex_lock (store->stream_lock);
+			server_stream = (CamelStreamBuffer*) store->istream;
+
+			if (!server_stream)
+				err = TRUE;
+			else
+				store->command++;
+
+			if (server_stream) 
+			  while ((nread = camel_stream_buffer_gets (server_stream, line, MAX_LINE_LEN) > 0))
+			  {
+				gint llen = 0;
+
+				/* It might be the line before the last line
+				 * TNY TODO: why no check for (linenum != 0) then ? */
+
+				if (line[0] == ')' && (line[1] == '\n' || (line[1] == '\r' && line[2] == '\n')))
+				{
+					if (line[1] == '\r')
+						hadr = TRUE;
+					isnextdone = TRUE;
+					continue;
+				}
+
+				/* It's the first line */
+				if (linenum == 0 && (line [0] != '*' || line[1] != ' '))
+					{ err=TRUE; break; } 
+				else if (linenum == 0) 
+				{ 
+					char *pos, *ppos;
+					pos = strchr (line, '{');
+					if (pos) { 
+						ppos = strchr (pos, '}');
+						if (ppos) {
+							*ppos = '\0';
+							exread = strtol (pos + 1, NULL, 10);
+						}
+					}
+					linenum++; 
+					continue; 
+				}
+
+				/* It's the last line (isnextdone will be ignored if that is the case) */
+			 	if (!strncmp (line, tag, taglen))
+					break;
+
+				camel_seekable_stream_seek (CAMEL_SEEKABLE_STREAM (stream), 0, CAMEL_STREAM_END);
+
+				if (isnextdone)
+				{
+					if (hadr)
+						camel_stream_write (stream, ")\n", 2);
+					else
+						camel_stream_write (stream, ")\r\n", 3);
+
+					hadr = FALSE;
+					isnextdone = FALSE;
+				}
+
+				llen = strlen (line);
+				camel_stream_write (stream, line, llen);
+				linenum++;
+				tread += llen;
+
+				camel_operation_progress (NULL, tread, exread);
+
+				memset (line, 0, MAX_LINE_LEN);
+			  }
+
+			g_mutex_unlock (store->stream_lock);
+			CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
+			/* Starts idle */
+			camel_imap_folder_start_idle ((CamelFolder *) imap_folder);
+			idle_rt = TRUE;
+
+			if (nread <= 0) 
+				err = TRUE;
+
+			if (tag)
+				g_free (tag);
+
+			if (err)
+				goto errorhander;
+
+			camel_stream_reset (stream);
+
+		} /* NON-BINARY */
+
+	} else 
+	{
+
+		/* Partial message retrieval feature gets the message like this: 
+		   { HEADER boundary 1.HEADER 1 boundary } */
+
+		char *boundary = NULL;
+		int t = 0, boundary_len = 0;
+		const gchar *infos[2] = { "HEADER", /*"1.HEADER",*/ "1" };
+
+		camel_imap_message_cache_set_partial (imap_folder->cache, uid, TRUE);
+
+		for (t=0; t < 2; t++)
+		{
+			gboolean err=FALSE;
+			gchar line[MAX_LINE_LEN];
+			guint linenum = 0; 
+			CamelStreamBuffer *server_stream;
+			gchar *tag;
+			guint taglen;
+			gboolean isnextdone = FALSE;
+			guint tread = 0, exread = 0;
+
+			nread = 0;
+
+			/* Stops idle */
+			camel_imap_command_start (store, folder, ex,
+				"UID FETCH %s BODY.PEEK[%s]", uid, infos[t]);
+
+			tag = g_strdup_printf ("%c%.5u", store->tag_prefix, store->command-1);
+			taglen = strlen (tag);
+
+			g_mutex_lock (store->stream_lock);
+
+			if (!store->istream || ((CamelObject *)store->istream)->ref_count <= 0)
+			{
+				err = TRUE;
+				nread = -1;
+				goto rerrorhandler;
+			}
+
+			if (!store->ostream || ((CamelObject *)store->ostream)->ref_count <= 0)
+			{
+				err = TRUE;
+				nread = -1;
+				goto rerrorhandler;
+			}
+			
+			if (camel_imap_store_restore_stream_buffer (store))
+				server_stream = store->istream ? CAMEL_STREAM_BUFFER (store->istream) : NULL;
+			else server_stream = NULL;
+
+			if (server_stream == NULL)
+				err = TRUE;
+			else
+				store->command++;
+
+			if (server_stream) 
+			  while ((nread = camel_stream_buffer_gets (server_stream, line, MAX_LINE_LEN) > 0))
+			  {
+				gint llen = 0;
+
+				/* It might be the line before the last line */
+				if (line[0] == ')' && (line[1] == '\n' || (line[1] == '\r' && line[2] == '\n')))
+					{ isnextdone = TRUE; continue; }
+
+				/* It's the first line */
+				if (linenum == 0 && (line [0] != '*' || line[1] != ' '))
+					{ err=TRUE; break; } 
+				else if (linenum == 0) 
+				{ 
+					char *pos, *ppos;
+					pos = strchr (line, '{');
+					if (pos) { 
+						ppos = strchr (pos, '}');
+						if (ppos) {
+							*ppos = '\0';
+							exread = strtol (pos + 1, NULL, 10);
+						}
+					}
+					linenum++; 
+					continue; 
+				}
+
+
+				/* It's the last line */
+				if (!strncmp (line, tag, taglen))
+				{
+					if ((t == 0 || t == 1 /* 2 */) && boundary_len > 0)
+					{
+						camel_seekable_stream_seek (CAMEL_SEEKABLE_STREAM (stream), 0, CAMEL_STREAM_END);
+						camel_stream_write (stream, "\n--", 3);
+						camel_stream_write (stream, boundary, boundary_len);
+						camel_stream_write (stream, "\n", 1);
+					}
+					break;
+				}
+
+				if (t == 0 && boundary_len == 0 && !boundary)
+				{
+					CamelContentType *ct = NULL;
+					const char *bound=NULL;
+					char *pstr = (char*)strcasestr (line, "Content-Type:");
+
+					/* If it's the Content-Type line (TODO: use BODYSTRUCTURE for this) */
+
+					if (pstr) 
+					{
+						pstr = strchr (pstr, ':'); 
+						if (pstr) 
+						{ 
+							pstr++;
+							ct = camel_content_type_decode(pstr); 
+						} 
+					}
+
+					if (ct) 
+					{ 
+						bound = camel_content_type_param(ct, "boundary");
+						if (bound) 
+						{ 
+							boundary_len = strlen (bound);
+							if (boundary_len > 0) 
+								boundary = g_strdup (bound);
+							else 
+								boundary_len = 0;
+						}
+					}
+				}
+
+				camel_seekable_stream_seek (CAMEL_SEEKABLE_STREAM (stream), 0, CAMEL_STREAM_END);
+
+				if (isnextdone)
+				{
+					camel_stream_write (stream, ")\n", 2);
+					isnextdone = FALSE;
+				}
+
+				llen = strlen (line);
+				camel_stream_write (stream, line, llen);
+
+				tread += llen;
+				camel_operation_progress (NULL, tread, exread);
+
+				linenum++;
+				memset (line, 0, MAX_LINE_LEN);
+			  }
+rerrorhandler:
+			g_mutex_unlock (store->stream_lock);
+			CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
+			/* Starts idle */
+			camel_imap_store_start_idle (store);
+			idle_rt = TRUE;
+
+			if (nread <= 0) 
+				err = TRUE;
+			
+			if (tag)
+				g_free (tag);
+
+			if (err) 
+			{
+				if (boundary_len > 0)
+					g_free (boundary);
+				goto errorhander;
+			}
+		}
+
+		if (boundary_len > 0)
+			g_free (boundary);
+
+		camel_stream_reset (stream);
 	}
-	camel_imap_response_free (store, response);
+
 	CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
-	if (!stream) {
-		camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
-				      _("Could not find message body in FETCH response."));
-	} else {
-		camel_object_ref (CAMEL_OBJECT (stream));
-		g_datalist_clear (&fetch_data);
-	}
-	
+
+  CAMEL_SERVICE_REC_UNLOCK(store, connect_lock); 
+
+	camel_service_disconnect (CAMEL_SERVICE (store), TRUE, NULL);
+	camel_object_unref (CAMEL_OBJECT (store));
+
+	camel_operation_end (NULL);
+
 	return stream;
+
+errorhander:
+
+	if (!idle_rt)
+		camel_imap_folder_start_idle ((CamelFolder *) imap_folder);
+
+	CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
+	camel_imap_message_cache_remove (imap_folder->cache, uid);
+
+	camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+		    _("Could not find message body in FETCH response."));
+
+	handle_freeup (store, nread, ex);
+
+	if (stream && ((CamelObject *)stream)->ref_count > 0)
+		camel_object_unref (CAMEL_OBJECT (stream));
+
+  if (store)
+  {
+
+  CAMEL_SERVICE_REC_UNLOCK(store, connect_lock);
+	camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
+	camel_object_unref (CAMEL_OBJECT (store));
+  }
+
+	camel_operation_end (NULL);
+
+	return NULL;
 }
 
+
+
+
+
 static GData *
 parse_fetch_response (CamelImapFolder *imap_folder, char *response)
 {
@@ -2784,7 +4378,7 @@
 	char *start, *part_spec = NULL, *body = NULL, *uid = NULL, *idate = NULL;
 	gboolean cache_header = TRUE, header = FALSE;
 	size_t body_len = 0;
-	
+
 	if (*response != '(') {
 		long seq;
 		
@@ -2886,6 +4480,13 @@
 				g_datalist_set_data_full (&data, "INTERNALDATE", idate, g_free);
 				response += len + 1;
 			}
+		} else if (!g_ascii_strncasecmp (response, "MODSEQ ", 7)) {
+			char *marker = strchr (response + 7, ')');
+			if (marker)
+				response = marker + 1;
+			
+			if (!marker)
+				g_warning ("Unexpected MODSEQ format: %s", response); 
 		} else {
 			g_warning ("Unexpected FETCH response from server: (%s", response);
 			break;
Only in ./providers/imap: camel-imap-folder.c.rej
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/camel-imap-folder.h ./providers/imap/camel-imap-folder.h
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/camel-imap-folder.h	2007-05-12 09:58:53.000000000 +0200
+++ ./providers/imap/camel-imap-folder.h	2007-05-12 10:01:04.000000000 +0200
@@ -41,7 +41,7 @@
 struct _CamelImapFolder {
 	CamelDiscoFolder parent_object;
 
-        struct _CamelImapFolderPrivate *priv;
+	struct _CamelImapFolderPrivate *priv;
 	
 	CamelFolderSearch *search;
 	CamelImapMessageCache *cache;
@@ -49,12 +49,16 @@
 	unsigned int need_rescan:1;
 	unsigned int need_refresh:1;
 	unsigned int read_only:1;
+	gchar *folder_dir;
+	gboolean do_push_email, stopping, in_idle;
+	guint idle_signal;
+	GStaticRecMutex *idle_lock;
 };
 
 typedef struct {
 	CamelDiscoFolderClass parent_class;
 
-	/* Virtual methods */	
+	/* Virtual methods */
 	
 } CamelImapFolderClass;
 
@@ -67,7 +71,7 @@
 
 void camel_imap_folder_selected (CamelFolder *folder,
 				 CamelImapResponse *response,
-				 CamelException *ex);
+				 CamelException *ex, gboolean idle);
 
 void camel_imap_folder_changed (CamelFolder *folder, int exists,
 				GArray *expunged, CamelException *ex);
@@ -76,11 +80,17 @@
 					   const char *uid,
 					   const char *section_text,
 					   gboolean cache_only,
-					   CamelException *ex);
+					   CamelFolderReceiveType type, gint param, CamelException *ex);
+
+time_t decode_internaldate (const unsigned char *in);
 
 /* Standard Camel function */
 CamelType camel_imap_folder_get_type (void);
 
+void camel_imap_folder_stop_idle (CamelFolder *folder);
+void camel_imap_folder_start_idle (CamelFolder *folder);
+
+
 G_END_DECLS
 
 #endif /* CAMEL_IMAP_FOLDER_H */
Only in ./providers/imap: camel-imap-folder.lo
Only in ./providers/imap: camel-imap-folder.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/camel-imap-message-cache.c ./providers/imap/camel-imap-message-cache.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/camel-imap-message-cache.c	2007-05-12 09:58:53.000000000 +0200
+++ ./providers/imap/camel-imap-message-cache.c	2007-05-12 10:01:04.000000000 +0200
@@ -170,6 +170,9 @@
 	cache->parts = g_hash_table_new (g_str_hash, g_str_equal);
 	cache->cached = g_hash_table_new (NULL, NULL);
 	deletes = g_ptr_array_new ();
+
+	camel_folder_summary_prepare_hash (summary);
+
 	while ((dname = g_dir_read_name (dir))) {
 		if (!isdigit (dname[0]))
 			continue;
@@ -188,6 +191,7 @@
 		g_free (uid);
 	}
 	g_dir_close (dir);
+	camel_folder_summary_kill_hash (summary);
 
 	while (deletes->len) {
 		g_unlink (deletes->pdata[0]);
@@ -329,6 +333,59 @@
 	return insert_finish (cache, uid, path, key, stream);
 }
 
+void
+camel_imap_message_cache_set_flags (const gchar *folder_dir, CamelMessageInfoBase *mi)
+{
+	char mystring [512];
+	snprintf (mystring, 512, "%s/%s.", folder_dir, mi->uid);
+	if (g_file_test (mystring, G_FILE_TEST_IS_REGULAR))
+	{
+		mi->flags |= CAMEL_MESSAGE_CACHED;
+		snprintf (mystring, 512, "%s/%s.partial", folder_dir, mi->uid);
+		if (g_file_test (mystring, G_FILE_TEST_IS_REGULAR))
+			mi->flags |= CAMEL_MESSAGE_PARTIAL;
+		else
+			mi->flags &= ~CAMEL_MESSAGE_PARTIAL;
+	} else {
+		mi->flags &= ~CAMEL_MESSAGE_CACHED;
+		mi->flags &= ~CAMEL_MESSAGE_PARTIAL;
+	}
+}
+
+gboolean
+camel_imap_message_cache_is_partial (CamelImapMessageCache *cache, const char *uid)
+{
+	gchar *path = g_strdup_printf ("%s/%s.ispartial", cache->path, uid);
+	gboolean retval = FALSE;
+
+	retval = g_file_test (path, G_FILE_TEST_IS_REGULAR);
+
+	g_free (path);
+
+	return retval;
+}
+
+void
+camel_imap_message_cache_set_partial (CamelImapMessageCache *cache, const char *uid, gboolean partial)
+{
+	gchar *path = g_strdup_printf ("%s/%s.ispartial", cache->path, uid);
+	int fd;
+
+	if (!partial)
+	{
+		if (g_file_test (path, G_FILE_TEST_IS_REGULAR))
+			g_unlink (path);
+	} else {
+		if (!g_file_test (path, G_FILE_TEST_IS_REGULAR))
+		{
+		    fd = g_open (path, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0600);
+		    if (fd) close (fd);
+		}
+	}
+
+	g_free (path);
+}
+
 /**
  * camel_imap_message_cache_insert_stream:
  * @cache: the cache
@@ -429,6 +486,12 @@
 		return stream;
 	}
 	
+	if (!g_file_test (path, G_FILE_TEST_IS_REGULAR))
+	{
+		g_free (path);
+		return NULL;
+	}
+	
 	stream = camel_stream_fs_new_with_name (path, O_RDONLY, 0);
 	if (stream) {
 		cache_put (cache, uid, key, stream);
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/camel-imap-message-cache.h ./providers/imap/camel-imap-message-cache.h
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/camel-imap-message-cache.h	2007-05-12 09:58:53.000000000 +0200
+++ ./providers/imap/camel-imap-message-cache.h	2007-05-12 10:01:04.000000000 +0200
@@ -86,6 +86,12 @@
 					      const char *part_spec,
 					      CamelException *ex);
 
+gboolean     camel_imap_message_cache_is_partial (CamelImapMessageCache *cache,
+					      const char *uid);
+
+void         camel_imap_message_cache_set_partial (CamelImapMessageCache *cache,
+					      const char *uid, gboolean partial);
+
 void         camel_imap_message_cache_remove (CamelImapMessageCache *cache,
 					      const char *uid);
 
@@ -97,6 +103,9 @@
 					      const char *dest_uid,
 					      CamelException *ex);
 
+void camel_imap_message_cache_set_flags (const gchar *folder_dir, CamelMessageInfoBase *mi);
+
+
 /* Standard Camel function */
 CamelType camel_imap_message_cache_get_type (void);
 
Only in ./providers/imap: camel-imap-message-cache.lo
Only in ./providers/imap: camel-imap-message-cache.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/camel-imap-provider.c ./providers/imap/camel-imap-provider.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/camel-imap-provider.c	2007-05-12 09:58:53.000000000 +0200
+++ ./providers/imap/camel-imap-provider.c	2007-05-12 10:01:04.000000000 +0200
@@ -87,7 +87,7 @@
 	CAMEL_PROVIDER_IS_REMOTE | CAMEL_PROVIDER_IS_SOURCE |
 	CAMEL_PROVIDER_IS_STORAGE | CAMEL_PROVIDER_SUPPORTS_SSL,
 
-	CAMEL_URL_NEED_USER | CAMEL_URL_NEED_HOST | CAMEL_URL_ALLOW_AUTH,
+	/* CAMEL_URL_NEED_USER | */ CAMEL_URL_NEED_HOST | CAMEL_URL_ALLOW_AUTH,
 
 	imap_conf_entries,
 
Only in ./providers/imap: camel-imap-provider.lo
Only in ./providers/imap: camel-imap-provider.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/camel-imap-search.c ./providers/imap/camel-imap-search.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/camel-imap-search.c	2007-05-12 09:58:53.000000000 +0200
+++ ./providers/imap/camel-imap-search.c	2007-05-12 10:01:03.000000000 +0200
@@ -185,11 +185,11 @@
 	md5_init(&ctx);
 	for (i=0;i<argc;i++) {
 		if (argv[i]->type == ESEXP_RES_STRING)
-			md5_update(&ctx, argv[i]->value.string, strlen(argv[i]->value.string));
+			md5_update(&ctx, (const guchar *) argv[i]->value.string, strlen(argv[i]->value.string));
 	}
 	md5_final(&ctx, digest);
 
-	camel_base64_encode_close(digest, 12, FALSE, hash, &state, &save);
+	camel_base64_encode_close(digest, 12, FALSE, (unsigned char *) hash, (int *) &state, (int *) &save);
 
 	for (i=0;i<16;i++) {
 		if (hash[i] == '+')
@@ -328,7 +328,7 @@
 	/* TODO: Handle multiple search terms */
 	
 	/* This handles multiple search words within a single term */
-	words = camel_search_words_split (mr->terms[0]);
+	words = camel_search_words_split ((const unsigned char *) mr->terms[0]);
 	search = g_string_new ("");
 	g_string_append_printf (search, "UID %d:%d", mr->lastuid + 1, is->lastuid);
 	for (i = 0; i < words->len; i++) {
Only in ./providers/imap: camel-imap-search.lo
Only in ./providers/imap: camel-imap-search.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/camel-imap-store.c ./providers/imap/camel-imap-store.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/camel-imap-store.c	2007-05-12 09:58:53.000000000 +0200
+++ ./providers/imap/camel-imap-store.c	2007-05-12 10:00:49.000000000 +0200
@@ -35,6 +35,9 @@
 #include <glib.h>
 #include <glib/gi18n-lib.h>
 #include <glib/gstdio.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <dirent.h>
 
 #include "camel/camel-debug.h"
 #include "camel/camel-disco-diary.h"
@@ -49,6 +52,8 @@
 #include "camel/camel-stream-fs.h"
 #include "camel/camel-stream-process.h"
 #include "camel/camel-stream.h"
+#include "camel/camel-stream-mem.h"
+#include "camel/camel-mime-message.h"
 #include "camel/camel-string-utils.h"
 #include "camel/camel-tcp-stream-raw.h"
 #include "camel/camel-tcp-stream-ssl.h"
@@ -63,6 +68,10 @@
 #include "camel-imap-summary.h"
 #include "camel-imap-utils.h"
 
+#if !GLIB_CHECK_VERSION (2, 8, 0)
+#define g_access access
+#endif
+
 #define d(x) 
 
 /* Specified in RFC 2060 */
@@ -128,6 +137,40 @@
 static void imap_forget_folder(CamelImapStore *imap_store, const char *folder_name, CamelException *ex);
 static void imap_set_server_level (CamelImapStore *store);
 
+static GPtrArray* imap_get_recent_messages (CamelStore *store, const char *folder_name, int *unseen, int *messages);
+
+static void let_idle_die (CamelImapStore *imap_store)
+{
+	if (imap_store->idle_signal > 0) 
+		g_source_remove (imap_store->idle_signal);
+
+	if (imap_store->idle_prefix)
+	{
+		g_free (imap_store->idle_prefix); 
+		imap_store->idle_prefix=NULL;
+		g_mutex_lock (imap_store->stream_lock);
+		idle_debug ("Sending DONE in let_idle_die\n");
+		camel_stream_printf (imap_store->ostream, "DONE\r\n");
+		g_mutex_unlock (imap_store->stream_lock);
+	}
+
+}
+
+void
+camel_imap_store_stop_idle (CamelImapStore *store)
+{
+	if (store->current_folder && CAMEL_IS_IMAP_FOLDER (store->current_folder))
+		camel_imap_folder_stop_idle (store->current_folder);
+}
+
+
+void
+camel_imap_store_start_idle (CamelImapStore *store)
+{
+	if (store->current_folder && CAMEL_IS_IMAP_FOLDER (store->current_folder))
+		camel_imap_folder_start_idle (store->current_folder);
+}
+
 static void
 camel_imap_store_class_init (CamelImapStoreClass *camel_imap_store_class)
 {
@@ -162,7 +205,8 @@
 	camel_store_class->noop = imap_noop;
 	camel_store_class->get_trash = imap_get_trash;
 	camel_store_class->get_junk = imap_get_junk;
-	
+	camel_store_class->get_recent_messages = imap_get_recent_messages;
+
 	camel_disco_store_class->can_work_offline = can_work_offline;
 	camel_disco_store_class->connect_online = imap_connect_online;
 	camel_disco_store_class->connect_offline = imap_connect_offline;
@@ -189,6 +233,8 @@
 	CamelImapStore *imap_store = CAMEL_IMAP_STORE (object);
 	CamelDiscoStore *disco = CAMEL_DISCO_STORE (object);
 
+	let_idle_die (imap_store);
+
 	/* This frees current_folder, folders, authtypes, streams, and namespace. */
 	camel_service_disconnect((CamelService *)imap_store, TRUE, NULL);
 
@@ -207,18 +253,24 @@
 		disco->diary = NULL;
 	}
 
-	if (imap_store->custom_headers)
-		g_free (imap_store->custom_headers);
+	
+	g_mutex_free (imap_store->stream_lock);
+
 }
 
 static void
 camel_imap_store_init (gpointer object, gpointer klass)
 {
 	CamelImapStore *imap_store = CAMEL_IMAP_STORE (object);
-	
+
+	imap_store->dontdistridlehack = FALSE;
+	imap_store->idle_signal = 0;
+	imap_store->idle_prefix = NULL;
 	imap_store->istream = NULL;
 	imap_store->ostream = NULL;
-	
+	imap_store->stream_lock = g_mutex_new ();
+	imap_store->has_login = FALSE;
+
 	imap_store->dir_sep = '\0';
 	imap_store->current_folder = NULL;
 	imap_store->connected = FALSE;
@@ -293,17 +345,6 @@
 	if (camel_url_get_param (url, "filter_junk_inbox"))
 		imap_store->parameters |= IMAP_PARAM_FILTER_JUNK_INBOX;
 
-	imap_store->headers = IMAP_FETCH_MAILING_LIST_HEADERS;
-	if (camel_url_get_param (url, "all_headers"))
-		imap_store->headers = IMAP_FETCH_ALL_HEADERS;
-	else if (camel_url_get_param (url, "basic_headers"))
-		imap_store->headers = IMAP_FETCH_MINIMAL_HEADERS;
-
-	if (camel_url_get_param (url, "imap_custom_headers")) {
-		imap_store->custom_headers = g_strdup(camel_url_get_param (url, "imap_custom_headers"));
-	}
-
-
 	/* setup journal*/
 	path = g_strdup_printf ("%s/journal", imap_store->storage_path);
 	disco_store->diary = camel_disco_diary_new (disco_store, path, ex);
@@ -335,6 +376,8 @@
 	}
 }
 
+
+
 static int
 imap_setv (CamelObject *object, CamelException *ex, CamelArgV *args)
 {
@@ -484,6 +527,9 @@
 	{ "XGWEXTENSIONS",      IMAP_CAPABILITY_XGWEXTENSIONS },
 	{ "XGWMOVE",            IMAP_CAPABILITY_XGWMOVE },
 	{ "LOGINDISABLED",      IMAP_CAPABILITY_LOGINDISABLED },
+	{ "CONDSTORE",          IMAP_CAPABILITY_CONDSTORE },
+	{ "IDLE",         	IMAP_CAPABILITY_IDLE },	
+	{ "BINARY",         	IMAP_CAPABILITY_BINARY },
 	{ NULL, 0 }
 };
 
@@ -560,9 +606,37 @@
 
 #ifdef HAVE_SSL
 #define SSL_PORT_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_SSL2 | CAMEL_TCP_STREAM_SSL_ENABLE_SSL3)
-#define STARTTLS_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_TLS)
+#define STARTTLS_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_TLS | CAMEL_TCP_STREAM_SSL_ENABLE_SSL3)
 #endif
 
+gboolean 
+camel_imap_store_restore_stream_buffer (CamelImapStore *store)
+{
+	if (store->istream == NULL || !CAMEL_IS_STREAM_BUFFER (store->istream))
+	{
+		if (store->ostream && CAMEL_IS_STREAM (store->ostream))
+		{
+			/* This is a recoverable situation. It's strange though */
+			store->istream = camel_stream_buffer_new (store->ostream, CAMEL_STREAM_BUFFER_READ);
+		} else {
+			CamelException ex = CAMEL_EXCEPTION_INITIALISER;
+			g_mutex_unlock (store->stream_lock);
+			camel_operation_uncancel (NULL);
+			camel_service_disconnect (CAMEL_SERVICE (store), FALSE, &ex);
+			camel_exception_clear (&ex);
+			g_warning ("Something terrible happened with your connection.\nTrying to recover. (%s)\n", 
+				g_strerror (errno));
+			camel_service_connect (CAMEL_SERVICE (store), &ex);
+			if (camel_exception_is_set (&ex))
+				g_warning ("Connection recovery failed: %s",
+					camel_exception_get_description (&ex));
+			g_mutex_lock (store->stream_lock);
+			return FALSE;
+		}
+	}
+	return TRUE;
+}
+
 static gboolean
 connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, CamelException *ex)
 {
@@ -573,8 +647,10 @@
 	gboolean force_imap4 = FALSE;
 	gboolean clean_quit = TRUE;
 	char *buf;
-	
+	gboolean not_ssl = TRUE;
+
 	if (ssl_mode != MODE_CLEAR) {
+		not_ssl = FALSE;
 #ifdef HAVE_SSL
 		if (ssl_mode == MODE_TLS) {
 			tcp_stream = camel_tcp_stream_ssl_new_raw (service->session, service->url->host, STARTTLS_FLAGS);
@@ -606,10 +682,12 @@
 		
 		return FALSE;
 	}
-	
+
+	g_mutex_lock (store->stream_lock);
 	store->ostream = tcp_stream;
 	store->istream = camel_stream_buffer_new (tcp_stream, CAMEL_STREAM_BUFFER_READ);
-	
+	g_mutex_unlock (store->stream_lock);
+
 	store->connected = TRUE;
 	store->preauthed = FALSE;
 	store->command = 0;
@@ -625,7 +703,10 @@
 	camel_tcp_stream_setsockopt((CamelTcpStream *)tcp_stream, &sockopt);
 
 	/* Read the greeting, if any, and deal with PREAUTH */
-	if (camel_imap_store_readline (store, &buf, ex) < 0) {
+	if (camel_imap_store_readline (store, &buf, ex) < 0) 
+	{
+
+		g_mutex_lock (store->stream_lock);
 		if (store->istream) {
 			camel_object_unref (store->istream);
 			store->istream = NULL;
@@ -635,7 +716,8 @@
 			camel_object_unref (store->ostream);
 			store->ostream = NULL;
 		}
-		
+		g_mutex_unlock (store->stream_lock);
+
 		store->connected = FALSE;
 		
 		return FALSE;
@@ -672,10 +754,20 @@
 		force_imap4 = TRUE;
 	}
 	
+
+	/* Tinymail hack: always use IMAP4, not IMAP4rev1 (sorry) */
+
+	/* force_imap4 = TRUE; */
+	store->braindamaged = TRUE;
+
+	/* end of hack :) */
+
 	g_free (buf);
 	
 	/* get the imap server capabilities */
-	if (!imap_get_capability (service, ex)) {
+	if (!imap_get_capability (service, ex)) 
+	{
+		g_mutex_lock (store->stream_lock);
 		if (store->istream) {
 			camel_object_unref (store->istream);
 			store->istream = NULL;
@@ -685,7 +777,8 @@
 			camel_object_unref (store->ostream);
 			store->ostream = NULL;
 		}
-		
+		g_mutex_unlock (store->stream_lock);
+
 		store->connected = FALSE;
 		return FALSE;
 	}
@@ -695,9 +788,12 @@
 		store->server_level = IMAP_LEVEL_IMAP4;
 	}
 	
-	if (ssl_mode != MODE_TLS) {
+	if (not_ssl || ssl_mode != MODE_TLS) {
+
 		/* we're done */
+
 		return TRUE;
+
 	}
 	
 #ifdef HAVE_SSL
@@ -713,10 +809,15 @@
 	clean_quit = FALSE;
 	
 	response = camel_imap_command (store, NULL, ex, "STARTTLS");
-	if (!response) {
+	if (!response) 
+	{
+		g_mutex_lock (store->stream_lock);
 		camel_object_unref (store->istream);
 		camel_object_unref (store->ostream);
-		store->istream = store->ostream = NULL;
+		store->istream = NULL;
+		store->ostream = NULL;
+		g_mutex_unlock (store->stream_lock);
+
 		return FALSE;
 	}
 	
@@ -738,7 +839,10 @@
 	
 	/* rfc2595, section 4 states that after a successful STLS
            command, the client MUST discard prior CAPA responses */
-	if (!imap_get_capability (service, ex)) {
+	if (!imap_get_capability (service, ex)) 
+	{
+
+		g_mutex_lock (store->stream_lock);
 		if (store->istream) {
 			camel_object_unref (store->istream);
 			store->istream = NULL;
@@ -748,7 +852,8 @@
 			camel_object_unref (store->ostream);
 			store->ostream = NULL;
 		}
-		
+		g_mutex_unlock (store->stream_lock);
+
 		store->connected = FALSE;
 		
 		return FALSE;
@@ -771,7 +876,8 @@
 		if (response)
 			camel_imap_response_free_without_processing (store, response);
 	}
-	
+
+	g_mutex_lock (store->stream_lock);
 	if (store->istream) {
 		camel_object_unref (store->istream);
 		store->istream = NULL;
@@ -781,7 +887,8 @@
 		camel_object_unref (store->ostream);
 		store->ostream = NULL;
 	}
-	
+	g_mutex_unlock (store->stream_lock);
+
 	store->connected = FALSE;
 	
 	return FALSE;
@@ -887,16 +994,20 @@
 		return FALSE;
 	}
 	g_free (full_cmd);
-	
+
+	g_mutex_lock (store->stream_lock);
 	store->ostream = cmd_stream;
 	store->istream = camel_stream_buffer_new (cmd_stream, CAMEL_STREAM_BUFFER_READ);
-	
+	g_mutex_unlock (store->stream_lock);
+
 	store->connected = TRUE;
 	store->preauthed = FALSE;
 	store->command = 0;
 	
 	/* Read the greeting, if any, and deal with PREAUTH */
-	if (camel_imap_store_readline (store, &buf, ex) < 0) {
+	if (camel_imap_store_readline (store, &buf, ex) < 0) 
+	{
+		g_mutex_lock (store->stream_lock);
 		if (store->istream) {
 			camel_object_unref (store->istream);
 			store->istream = NULL;
@@ -906,7 +1017,8 @@
 			camel_object_unref (store->ostream);
 			store->ostream = NULL;
 		}
-		
+		g_mutex_unlock (store->stream_lock);
+
 		store->connected = FALSE;
 		return FALSE;
 	}
@@ -915,7 +1027,9 @@
 	g_free (buf);
 	
 	/* get the imap server capabilities */
-	if (!imap_get_capability (service, ex)) {
+	if (!imap_get_capability (service, ex)) 
+	{
+		g_mutex_lock (store->stream_lock);
 		if (store->istream) {
 			camel_object_unref (store->istream);
 			store->istream = NULL;
@@ -925,7 +1039,8 @@
 			camel_object_unref (store->ostream);
 			store->ostream = NULL;
 		}
-		
+		g_mutex_unlock (store->stream_lock);
+
 		store->connected = FALSE;
 		return FALSE;
 	}
@@ -949,12 +1064,13 @@
 	{ NULL,            "imap",  IMAP_PORT,  MODE_CLEAR },
 };
 
+
 static gboolean
 connect_to_server_wrapper (CamelService *service, CamelException *ex)
 {
 	const char *ssl_mode;
 	struct addrinfo hints, *ai;
-	int mode, ret, i;
+	int mode = -1, ret, i;
 	char *serv;
 	const char *port;
 
@@ -1003,6 +1119,12 @@
 	return ret;
 }
 
+gboolean 
+camel_imap_service_connect (CamelService *service, CamelException *ex)
+{
+	return connect_to_server_wrapper (service, ex);
+}
+
 extern CamelServiceAuthType camel_imap_password_authtype;
 
 static GList *
@@ -1015,12 +1137,13 @@
 	
 	if (!camel_disco_store_check_online (CAMEL_DISCO_STORE (store), ex))
 		return NULL;
-	
+
 	CAMEL_SERVICE_REC_LOCK (store, connect_lock);
 	connected = store->istream != NULL && store->connected;
 	if (!connected)
 		connected = connect_to_server_wrapper (service, ex);
 	CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
+
 	if (!connected)
 		return NULL;
 	
@@ -1046,11 +1169,9 @@
 	const char *name;
 	CamelFolderInfo *fi;
 
-	fi = g_malloc0(sizeof(*fi));
-
+	fi = camel_folder_info_new ();
 	fi->full_name = g_strdup(folder_name);
-	fi->unread = -1;
-	fi->total = -1;
+
 
 	url = camel_url_new (imap_store->base_url, NULL);
 	g_free (url->path);
@@ -1132,23 +1253,11 @@
 		g_free (folder_dir);
 		goto event;
 	}
-	camel_object_unref (summary);
-
-	g_unlink (summary_file);
-	g_free (summary_file);
-
-	summary_file = g_strdup_printf ("%s/summary-meta", folder_dir);
-	summary = camel_imap_summary_new (NULL, summary_file);
-	if (!summary) {
-		g_free (summary_file);
-		g_free (folder_dir);
-		goto event;
-	}
 	
 	cache = camel_imap_message_cache_new (folder_dir, summary, ex);
 	if (cache)
 		camel_imap_message_cache_clear (cache);
-	
+
 	camel_object_unref (cache);
 	camel_object_unref (summary);
 	
@@ -1397,6 +1506,14 @@
 		if (authtype)
 			authenticated = try_auth (store, authtype->authproto, ex);
 		else {
+
+			if (!service->url->passwd)
+			{
+				camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
+						     _("You did not enter a password."));
+				return FALSE;
+			}
+
 			response = camel_imap_command (store, NULL, ex,
 						       "LOGIN %S %S",
 						       service->url->user,
@@ -1414,9 +1531,17 @@
 						    "to IMAP server.\n%s\n\n"),
 						  camel_exception_get_description (ex));
 			camel_exception_clear (ex);
-		}
+		} else
+			if (!imap_get_capability (service, ex))
+			{
+				errbuf = g_strdup_printf (_("Unable to authenticate "
+							    "to IMAP server.\n%s\n\n"),
+							  camel_exception_get_description (ex));
+				camel_exception_clear (ex);
+				return FALSE;
+			}
 	}
-	
+
 	return TRUE;
 }
 
@@ -1438,11 +1563,14 @@
 	size_t len;
 	CamelImapStoreNamespace *ns;
 
+	let_idle_die (store);
+
 	CAMEL_SERVICE_REC_LOCK (store, connect_lock);
+
 	if (!connect_to_server_wrapper (service, ex) ||
 	    !imap_auth_loop (service, ex)) {
 		CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
-		camel_service_disconnect (service, TRUE, NULL);
+		/* camel_service_disconnect (service, TRUE, NULL); */
 		return FALSE;
 	}
 	
@@ -1559,6 +1687,7 @@
 	
 	
  done:
+
 	/* save any changes we had */
 	camel_store_summary_save((CamelStoreSummary *)store->summary);
 
@@ -1566,7 +1695,9 @@
 	
 	if (camel_exception_is_set (ex))
 		camel_service_disconnect (service, TRUE, NULL);
-	
+	else
+		store->has_login = TRUE;
+
 	return !camel_exception_is_set (ex);
 }
 
@@ -1576,9 +1707,11 @@
 	CamelImapStore *store = CAMEL_IMAP_STORE (service);
 	CamelDiscoStore *disco_store = CAMEL_DISCO_STORE (service);
 
+	let_idle_die (store);
+
 	if (!disco_store->diary)
 		return FALSE;
-	
+
 	store->connected = !camel_exception_is_set (ex);
 	return store->connected;
 }
@@ -1588,6 +1721,9 @@
 {
 	CamelImapStore *store = CAMEL_IMAP_STORE (service);
 
+	let_idle_die (store);
+
+	g_mutex_lock (store->stream_lock);
 	if (store->istream) {
 		camel_stream_close(store->istream);
 		camel_object_unref(store->istream);
@@ -1599,13 +1735,13 @@
 		camel_object_unref(store->ostream);
 		store->ostream = NULL;
 	}
-	
+	g_mutex_unlock (store->stream_lock);
+
 	store->connected = FALSE;
-	if (store->current_folder) {
-		camel_object_unref (store->current_folder);
-		store->current_folder = NULL;
-	}
-	
+	/* if (store->current_folder && CAMEL_IS_OBJECT (store->current_folder)) 
+		camel_object_unref (store->current_folder); */
+	store->current_folder = NULL;
+
 	if (store->authtypes) {
 		g_hash_table_foreach_remove (store->authtypes,
 					     free_key, NULL);
@@ -1626,7 +1762,9 @@
 {
 	CamelImapStore *store = CAMEL_IMAP_STORE (service);
 	CamelImapResponse *response;
-	
+
+	let_idle_die (store);
+
 	if (store->connected && clean) {
 		response = camel_imap_command (store, NULL, NULL, "LOGOUT");
 		camel_imap_response_free (store, response);
@@ -1666,11 +1804,11 @@
 	
 	CAMEL_SERVICE_REC_LOCK (imap_store, connect_lock);
 
-	if (!camel_imap_store_connected(imap_store, ex))
+	if (!camel_disco_store_check_online((CamelDiscoStore *)store, ex))
 		goto done;
 
 	current_folder = imap_store->current_folder;
-	if (current_folder && imap_summary_is_dirty (current_folder->summary)) {
+	if (current_folder && CAMEL_IS_IMAP_FOLDER (current_folder) && imap_summary_is_dirty (current_folder->summary)) {
 		/* let's sync the flags instead.  NB: must avoid folder lock */
 		((CamelFolderClass *)((CamelObject *)current_folder)->klass)->sync(current_folder, FALSE, ex);
 	} else {
@@ -1762,10 +1900,12 @@
 	struct imap_status_item *items, *item, *tail;
 	CamelImapResponse *response;
 	char *status, *name, *p;
-	
-	/* FIXME: we assume the server is STATUS-capable */
-	
-	response = camel_imap_command (imap_store, NULL, NULL,
+	CamelException ex = CAMEL_EXCEPTION_INITIALISER;
+
+	if (!(imap_store->capabilities & IMAP_CAPABILITY_STATUS))
+		return NULL;
+
+	response = camel_imap_command (imap_store, NULL, &ex,
 				       "STATUS %F (%s)",
 				       folder_name,
 				       type);
@@ -1846,6 +1986,266 @@
 	return items;
 }
 
+static void
+camel_imap_store_set_status_for (CamelImapStore *imap_store, const char *folder_name, guint32 messages, guint32 unseen, guint32 uidnext)
+{
+	char *storage_path, *folder_dir, *filename;
+	FILE *file = NULL;
+
+	storage_path = g_strdup_printf("%s/folders", imap_store->storage_path);
+	folder_dir = imap_path_to_physical (storage_path, folder_name);
+	g_free(storage_path);
+	filename = g_strdup_printf ("%s/status", folder_dir);
+	g_free (folder_dir);
+
+	file = fopen (filename, "w");
+	g_free (filename);
+
+	if (file != NULL)
+	{
+		fprintf (file, "%d %d %d", messages, unseen, uidnext);
+		fclose (file);
+	}
+
+	return;
+}
+
+static void 
+camel_imap_store_get_status_for (CamelImapStore *imap_store, const char *folder_name, guint32 *messages, guint32 *unseen, guint32 *uidnext)
+{
+	char *storage_path, *folder_dir, *filename;
+	FILE *file = NULL;
+	int nmessages, nunseen, nuidnext;
+
+	storage_path = g_strdup_printf("%s/folders", imap_store->storage_path);
+	folder_dir = imap_path_to_physical (storage_path, folder_name);
+	g_free(storage_path);
+	filename = g_strdup_printf ("%s/status", folder_dir);
+	g_free (folder_dir);
+
+	file = fopen (filename, "r");
+	g_free (filename);
+
+	if (file != NULL)
+	{
+		fscanf (file, "%i %i %i", &nmessages, &nunseen, &nuidnext);
+		*messages = nmessages; 
+		*unseen = nunseen; 
+		*uidnext = nuidnext;
+		fclose (file);
+	}
+
+	return;
+}
+
+static CamelMessageInfo*
+parse_message_header (char *response)
+{
+	CamelMessageInfoBase *mi = NULL;
+	char *uid = NULL, *idate = NULL;
+	size_t body_len = 0;
+	guint32 flags = 0, size = 0;
+
+	if (*response != '(') {
+		long seq;
+		
+		if (*response != '*' || *(response + 1) != ' ')
+			return NULL;
+		seq = strtol (response + 2, &response, 10);
+		if (seq == 0)
+			return NULL;
+		if (g_ascii_strncasecmp (response, " FETCH (", 8) != 0)
+			return NULL;
+		response += 7;
+	}
+	
+	do {
+		response++;
+		if (!g_ascii_strncasecmp (response, "FLAGS ", 6)) {
+			response += 6;
+			flags = imap_parse_flag_list (&response);
+		} else if (!g_ascii_strncasecmp (response, "RFC822.SIZE ", 12)) {
+			response += 12;
+			size = strtoul (response, &response, 10);
+		} else if (!g_ascii_strncasecmp (response, "BODY[", 5) ||
+			   !g_ascii_strncasecmp (response, "RFC822 ", 7)) 
+		{
+			char *p, *body;
+			if (*response == 'B') {
+				response += 5;
+				p = strchr (response, ']');
+				if (!p || *(p + 1) != ' ')
+					break;
+				response = p + 2;
+			} else
+				response += 7;
+
+			body = imap_parse_nstring ((const char **) &response, &body_len);
+			if (!response)
+				break;
+			if (body)
+			{
+				CamelMimeMessage *msg = camel_mime_message_new ();
+				CamelStream *stream = camel_stream_mem_new_with_buffer (body, body_len);
+				g_free (body);
+
+				if (camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (msg), stream) == -1) {
+					camel_object_unref (CAMEL_OBJECT (msg));
+					break;
+				}
+
+				mi = (CamelMessageInfoBase *) camel_folder_summary_info_new_from_message (NULL, msg);
+				camel_object_unref (CAMEL_OBJECT (msg));
+			}
+		} else if (!g_ascii_strncasecmp (response, "UID ", 4)) {
+			int len = strcspn (response + 4, " )");
+			uid = g_strndup (response + 4, len);
+			response += 4 + len;
+		} else if (!g_ascii_strncasecmp (response, "INTERNALDATE ", 13)) {
+			int len; response += 13;
+			if (*response == '"') {
+				response++;
+				len = strcspn (response, "\"");
+				idate = g_strndup (response, len);
+				response += len + 1;
+			}
+		} else {
+			g_warning ("Unexpected FETCH response from server: (%s", response);
+			break;
+		}
+	} while (response && *response != ')');
+
+	if (mi)
+	{
+		mi->flags |= flags;
+		if (uid) {
+			if (mi->uid && (mi->flags & CAMEL_MESSAGE_INFO_UID_NEEDS_FREE))
+				g_free (mi->uid);
+
+			mi->uid = uid;
+			mi->flags |= CAMEL_MESSAGE_INFO_UID_NEEDS_FREE;
+		}
+		if (idate) {
+			mi->date_received = decode_internaldate ((const unsigned char *) idate);
+			g_free (idate);
+		}
+		mi->size = size;
+	}
+
+	return (CamelMessageInfo *) mi;
+}
+
+GPtrArray*
+_camel_imap_store_get_recent_messages (CamelImapStore *imap_store, const char *folder_name, int *unseen, int *messages, gboolean withthem)
+{
+	guint32 uidnext=-1;
+	struct imap_status_item *items, *item;
+	guint ounseen, omessages, ouidnext;
+	GPtrArray *retval = NULL;
+	CamelException ex = CAMEL_EXCEPTION_INITIALISER;
+	CamelImapResponse *response;
+	CamelException tex = CAMEL_EXCEPTION_INITIALISER;
+
+	if (!camel_disco_store_check_online (CAMEL_DISCO_STORE (imap_store), &ex))
+		return NULL;
+
+/*
+      Example:    C: A042 STATUS blurdybloop (UIDNEXT MESSAGES)
+                  S: * STATUS blurdybloop (MESSAGES 231 UIDNEXT 44292)
+                  S: A042 OK STATUS completed
+*/
+
+	camel_operation_uncancel (NULL);
+
+
+	/* On for example courier, the selected's STATUS is cached (kill that cache) */
+	if (withthem)
+	{
+	    response = camel_imap_command (imap_store, NULL, &tex,
+			    "SELECT"/*, folder_name*/);
+
+printf ("SELECT %s\n", folder_name);
+
+	    if (response)
+		    camel_imap_response_free (imap_store, response);
+	}
+
+	item = items = get_folder_status (imap_store, folder_name, "MESSAGES UNSEEN UIDNEXT");
+	while (item != NULL) {
+		if (!g_ascii_strcasecmp (item->name, "MESSAGES"))
+			*messages = item->value;
+		if (!g_ascii_strcasecmp (item->name, "UNSEEN"))
+			*unseen = item->value;
+		if (!g_ascii_strcasecmp (item->name, "UIDNEXT"))
+			uidnext = item->value;
+		item = item->next;
+	}
+	imap_status_item_free (items);
+printf ("%d %d %d\n", *messages, *unseen, uidnext);
+
+	if (withthem)
+	{
+		camel_imap_store_get_status_for (imap_store, folder_name, &omessages, &ounseen, &ouidnext);
+
+		if (ouidnext != uidnext)
+		{
+			CamelImapResponseType type;
+			char *resp; 
+
+			camel_exception_clear (&tex);
+
+			if (!camel_imap_command_start (imap_store, NULL, &tex,
+				"UID FETCH %d:* (FLAGS RFC822.SIZE INTERNALDATE BODY.PEEK[HEADER])", ouidnext-1))
+				goto done;
+
+			while ((type = camel_imap_command_response (imap_store, &resp, &tex))
+				== CAMEL_IMAP_RESPONSE_UNTAGGED) 
+			{
+			   if (resp)
+			   {
+				CamelMessageInfo *mi = parse_message_header (resp);
+				g_free (resp);
+
+				if (mi)
+				{
+					if (retval == NULL)
+						retval = g_ptr_array_new ();
+					g_ptr_array_add (retval, mi);
+				}
+			   }
+			}
+
+			/* Restore the original folder selection */
+			if (imap_store->current_folder != NULL && imap_store->current_folder->full_name != NULL)
+			{
+				response = camel_imap_command (imap_store, NULL, &tex,
+						"SELECT %F", imap_store->current_folder->full_name);
+				if (response)
+					camel_imap_response_free (imap_store, response);
+			}
+		}
+	}
+
+done:
+
+	camel_imap_store_set_status_for (imap_store, folder_name, *messages, *unseen, uidnext);
+
+	return retval;
+}
+
+static GPtrArray*
+imap_get_recent_messages (CamelStore *store, const char *folder_name, int *unseen, int *messages)
+{
+	GPtrArray *retval = NULL;
+	CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
+
+	CAMEL_SERVICE_REC_LOCK(imap_store, connect_lock);
+	retval = _camel_imap_store_get_recent_messages (imap_store, folder_name, unseen, messages, TRUE);
+	CAMEL_SERVICE_REC_UNLOCK (imap_store, connect_lock);
+
+	return retval;
+}
+
 static CamelFolder *
 get_folder_online (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex)
 {
@@ -1863,7 +2263,7 @@
 
 	CAMEL_SERVICE_REC_LOCK(imap_store, connect_lock);
 
-	if (!camel_imap_store_connected(imap_store, ex)) {
+	if (!camel_disco_store_check_online((CamelDiscoStore *)imap_store, ex)) {
 		CAMEL_SERVICE_REC_UNLOCK (imap_store, connect_lock);
 		return NULL;
 	}
@@ -1872,9 +2272,10 @@
 		folder_name = "INBOX";
 
 	if (imap_store->current_folder) {
-		camel_object_unref (imap_store->current_folder);
+		/* camel_object_unref (imap_store->current_folder); */
 		imap_store->current_folder = NULL;
 	}
+
 	response = camel_imap_command (imap_store, NULL, ex, "SELECT %F", folder_name);
 	if (!response) {
 		char *folder_real, *parent_name, *parent_real;
@@ -1931,7 +2332,7 @@
 			for (i = 0; i < response->untagged->len; i++) {
 				resp = response->untagged->pdata[i];
 				
-				if (!imap_parse_list_response (imap_store, resp, &flags, NULL, &thisone))
+				if (!imap_parse_list_response (imap_store, resp, (int *) &flags, NULL, &thisone))
 					continue;
 				
 				if (!strcmp (parent_name, thisone)) {
@@ -2038,13 +2439,13 @@
 		CamelException local_ex;
 
 		imap_store->current_folder = new_folder;
-		camel_object_ref (new_folder);
+		/* camel_object_ref (new_folder); */
 		camel_exception_init (&local_ex);
-		camel_imap_folder_selected (new_folder, response, &local_ex);
+		camel_imap_folder_selected (new_folder, response, &local_ex, TRUE);
 
 		if (camel_exception_is_set (&local_ex)) {
 			camel_exception_xfer (ex, &local_ex);
-			camel_object_unref (imap_store->current_folder);
+			/* camel_object_unref (imap_store->current_folder); */
 			imap_store->current_folder = NULL;
 			camel_object_unref (new_folder);
 			new_folder = NULL;
@@ -2095,7 +2496,7 @@
 
 	CAMEL_SERVICE_REC_LOCK (imap_store, connect_lock);
 
-	if (!camel_imap_store_connected(imap_store, ex))
+	if (!camel_disco_store_check_online((CamelDiscoStore *)imap_store, ex))
 		goto fail;
 	
 	/* make sure this folder isn't currently SELECTed */
@@ -2104,8 +2505,9 @@
 		goto fail;
 
 	camel_imap_response_free_without_processing (imap_store, response);
-	if (imap_store->current_folder)
-		camel_object_unref (imap_store->current_folder);
+	/*if (imap_store->current_folder)
+		camel_object_unref (imap_store->current_folder);*/
+
 	/* no need to actually create a CamelFolder for INBOX */
 	imap_store->current_folder = NULL;
 
@@ -2195,7 +2597,7 @@
 
 	CAMEL_SERVICE_REC_LOCK (imap_store, connect_lock);
 
-	if (!camel_imap_store_connected(imap_store, ex))
+	if (!camel_disco_store_check_online((CamelDiscoStore *)imap_store, ex))
 		goto fail;
 	
 	/* make sure this folder isn't currently SELECTed - it's
@@ -2206,8 +2608,8 @@
 		goto fail;
 
 	camel_imap_response_free_without_processing (imap_store, response);
-	if (imap_store->current_folder)
-		camel_object_unref (imap_store->current_folder);
+	/*if (imap_store->current_folder)
+		camel_object_unref (imap_store->current_folder); */
 	/* no need to actually create a CamelFolder for INBOX */
 	imap_store->current_folder = NULL;
 
@@ -2426,7 +2828,8 @@
 
 	flags = (flags & ~CAMEL_FOLDER_SUBSCRIBED) | (si->info.flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED);
 
-	fi = g_new0 (CamelFolderInfo, 1);
+	fi = camel_folder_info_new ();
+	
 	fi->full_name = g_strdup(camel_store_info_path(imap_store->summary, si));
 	if (!g_ascii_strcasecmp(fi->full_name, "inbox")) {
 		flags |= CAMEL_FOLDER_SYSTEM|CAMEL_FOLDER_TYPE_INBOX;
@@ -2451,9 +2854,6 @@
 	fi->uri = camel_url_to_string (url, 0);
 	camel_url_free (url);
 
-	fi->total = -1;
-	fi->unread = -1;
-
 	return fi;
 }
 
@@ -2525,29 +2925,68 @@
 
 	/* We do a LIST followed by LSUB, and merge the results.  LSUB may not be a strict
 	   subset of LIST for some servers, so we can't use either or separately */
+
+	/* TNY TODO! It used to loop until 2, but I think it's just wrong to 
+	   merge with LSUB?! (It doesn't make any sense) */
+
 	present = g_hash_table_new(folder_hash, folder_eq);
-	for (j=0;j<2;j++) {
+
+	for (j=0;j<2;j++) 
+	{
 		response = camel_imap_command (imap_store, NULL, ex,
 					       "%s \"\" %G", j==1 ? "LSUB" : "LIST",
 					       pattern);
 		if (!response)
 			goto fail;
 
-		for (i = 0; i < response->untagged->len; i++) {
+		for (i = 0; i < response->untagged->len; i++) 
+		{
 			list = response->untagged->pdata[i];
 			fi = parse_list_response_as_folder_info (imap_store, list);
-			if (fi) {
+
+			if (fi) 
+			{
+				if (FALSE && j == 0)
+				{
+					struct imap_status_item *item, *items;
+					item = items = get_folder_status (imap_store, fi->full_name, "MESSAGES UNSEEN");
+					while (item != NULL) 
+					{
+						if (!g_ascii_strcasecmp (item->name, "MESSAGES"))
+							fi->total = item->value;
+						if (!g_ascii_strcasecmp (item->name, "UNSEEN"))
+							fi->unread = item->value;
+						item = item->next;
+					}
+					imap_status_item_free (items);
+				}
+
 				hfi = g_hash_table_lookup(present, fi->full_name);
-				if (hfi == NULL) {
-					if (j==1) {
+
+				if (hfi == NULL) 
+				{
+					if (j == 1) 
+					{
+						/* It's in LSUB but not in LIST? */
+
 						fi->flags |= CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
 						if ((fi->flags & (CAMEL_IMAP_FOLDER_MARKED | CAMEL_IMAP_FOLDER_UNMARKED)))
 							imap_store->capabilities |= IMAP_CAPABILITY_useful_lsub;
 					}
-					g_hash_table_insert(present, fi->full_name, fi);
+
+					if (j == 0) /* From the LSUB we don't add folders */
+						g_hash_table_insert(present, fi->full_name, fi);
+					else 
+						camel_folder_info_free(fi);
 				} else {
 					if (j == 1)
 						hfi->flags |= CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
+
+					if (j == 0) 
+					{
+						hfi->unread = fi->unread;
+						hfi->total = fi->total;
+					}
 					camel_folder_info_free(fi);
 				}
 			}
@@ -2559,17 +2998,22 @@
 
 	/* FIXME: we need to emit folder_create/subscribed/etc events for any new folders */
 	count = camel_store_summary_count((CamelStoreSummary *)imap_store->summary);
-	for (i=0;i<count;i++) {
+
+	for (i=0;i<count;i++) 
+	{
 		si = camel_store_summary_index((CamelStoreSummary *)imap_store->summary, i);
 		if (si == NULL)
 			continue;
 
-		if (imap_match_pattern(imap_store->dir_sep, pattern, camel_imap_store_info_full_name(imap_store->summary, si))) {
-			if ((fi = g_hash_table_lookup(present, camel_store_info_path(imap_store->summary, si))) != NULL) {
-				if (((fi->flags ^ si->flags) & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED)) {
+		if (imap_match_pattern(imap_store->dir_sep, pattern, camel_imap_store_info_full_name(imap_store->summary, si))) 
+		{
+			if ((fi = g_hash_table_lookup(present, camel_store_info_path(imap_store->summary, si))) != NULL) 
+			{
+				if (((fi->flags ^ si->flags) & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED))
 					si->flags = (si->flags & ~CAMEL_FOLDER_SUBSCRIBED) | (fi->flags & CAMEL_FOLDER_SUBSCRIBED);
-					camel_store_summary_touch((CamelStoreSummary *)imap_store->summary);
-				}
+				si->unread = fi->unread;
+				si->total = fi->total;
+				camel_store_summary_touch((CamelStoreSummary *)imap_store->summary);
 			} else {
 				camel_store_summary_remove((CamelStoreSummary *)imap_store->summary, si);
 				count--;
@@ -2608,17 +3052,120 @@
 }
 #endif
 
+
+static int
+isdir (char *name)
+{
+	struct stat st;
+	if (stat (name, &st))
+		return 0;
+	return S_ISDIR (st.st_mode);
+}
+
+static char *ignored_names[] = { ".", "..", "subfolders", NULL };
+
+int
+ignorent (char *name)
+{
+	char **p;
+	for (p = ignored_names; *p; p++)
+		if (strcmp (name, *p) == 0)
+			return 1;
+	return 0;
+}
+
+
+void
+my_du (char *name, int *my_size)
+{
+	DIR *dir;
+	struct dirent *ent;
+
+	chdir (name);
+	dir = opendir (name);
+
+	if (!dir)
+		return;
+
+	while ((ent = readdir (dir)))
+	{
+		if (!ignorent (ent->d_name))
+		{
+			char *p = g_strdup_printf ("%s/%s", name, ent->d_name);
+			if (isdir (p))
+				my_du (p, my_size);
+			else 
+			{
+				struct stat st;
+				if (stat (p, &st) == 0)
+					*my_size += st.st_size;
+			}
+			g_free (p);
+		}
+	}
+
+	closedir (dir);
+}
+
 static void
 fill_fi(CamelStore *store, CamelFolderInfo *fi, guint32 flags)
 {
 	CamelFolder *folder;
+	CamelImapStore *imap_store = (CamelImapStore *) store;
+	gint msize = 0;
+	char *storage_path = g_strdup_printf("%s/folders", imap_store->storage_path);
+	char *folder_dir = imap_path_to_physical (storage_path, fi->full_name);
+
+	g_free(storage_path);
+	my_du (folder_dir, &msize);
 
 	folder = camel_object_bag_peek(store->folders, fi->full_name);
-	if (folder) {
+
+	if (folder) 
+	{
 		fi->unread = camel_folder_get_unread_message_count(folder);
 		fi->total = camel_folder_get_message_count(folder);
 		camel_object_unref(folder);
+
+	} else if ((fi->unread == -1) || (fi->total == -1)) {
+
+
+		/* This code reads the beginning of the summary.mmap file for
+		 * the length and unread-count of the folder. It makes it 
+		 * possible to read the total and unread values of the 
+		 * CamelFolderInfo structure without having to read the entire
+		 * folder in (mmap it) 
+		 * It's called by get_folder_info_offline and therefore also by 
+		 * get_folder_info_online for each node in the tree. */
+
+		gchar *spath = g_strdup_printf ("%s/summary.mmap", folder_dir);
+		FILE *f = fopen (spath, "r");
+		g_free (spath);
+
+		if (f) {
+
+			gint tsize = ((sizeof (guint32) * 5) + sizeof (time_t));
+			char *buffer = malloc (tsize), *ptr;
+			guint32 version, a;
+			a = fread (buffer, 1, tsize, f);
+			if (a == tsize) 
+			{
+				ptr = buffer;
+				version = g_ntohl(get_unaligned_u32(ptr));
+				ptr += 16;
+				if (fi->total == -1)
+					fi->total = g_ntohl(get_unaligned_u32(ptr));
+				ptr += 4;
+				if (fi->unread == -1 && (version < 0x100 && version >= 13))
+					fi->unread = g_ntohl(get_unaligned_u32(ptr));
+			}
+			g_free (buffer);
+			fclose (f);
+		}
 	}
+
+	fi->local_size = msize;
+	g_free (folder_dir);
 }
 
 struct _refresh_msg {
@@ -2636,7 +3183,7 @@
 
 	CAMEL_SERVICE_REC_LOCK(m->store, connect_lock);
 
-	if (!camel_imap_store_connected((CamelImapStore *)m->store, &m->ex))
+	if (!camel_disco_store_check_online((CamelDiscoStore *)m->store, &m->ex))
 		goto done;
 
 	if (store->namespace && store->namespace[0]) {
@@ -2718,7 +3265,7 @@
 
 		CAMEL_SERVICE_REC_LOCK(store, connect_lock);
 
-		if (!camel_imap_store_connected((CamelImapStore *)store, ex))
+		if (!camel_disco_store_check_online((CamelDiscoStore *)imap_store, ex))
 			goto fail;
 
 		if (top[0] == 0) {
@@ -2814,8 +3361,7 @@
 	/* folder_info_build will insert parent nodes as necessary and mark
 	 * them as noselect, which is information we actually don't have at
 	 * the moment. So let it do the right thing by bailing out if it's
-	 * not a folder we're explicitly interested in.
-	 */
+	 * not a folder we're explicitly interested in. */
 
 	for (i=0;i<camel_store_summary_count((CamelStoreSummary *)imap_store->summary);i++) {
 		CamelStoreInfo *si = camel_store_summary_index((CamelStoreSummary *)imap_store->summary, i);
@@ -2828,17 +3374,26 @@
 		     || (include_inbox && !g_ascii_strcasecmp (camel_imap_store_info_full_name(imap_store->summary, si), "INBOX")))
 		    && ((imap_store->parameters & IMAP_PARAM_SUBSCRIPTIONS) == 0
 			|| (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED) == 0
-			|| (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED))) {
+			|| (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED))) 
+		{
+
 			fi = imap_build_folder_info(imap_store, camel_store_info_path((CamelStoreSummary *)imap_store->summary, si));
+			fi->flags = si->flags;
 			fi->unread = si->unread;
 			fi->total = si->total;
-			fi->flags = si->flags;
+
+			if (fi->unread == 0 || fi->total == 0) 
+			{ 
+				fi->unread = -1;
+				fi->total = -1;
+			}
+
 			/* HACK: some servers report noinferiors for all folders (uw-imapd)
 			   We just translate this into nochildren, and let the imap layer enforce
 			   it.  See create folder */
 			if (fi->flags & CAMEL_FOLDER_NOINFERIORS)
 				fi->flags = (fi->flags & ~CAMEL_FOLDER_NOINFERIORS) | CAMEL_FOLDER_NOCHILDREN;
-			
+
 			/* blah, this gets lost somewhere, i can't be bothered finding out why */
 			if (!g_ascii_strcasecmp(fi->full_name, "inbox"))
 				fi->flags = (fi->flags & ~CAMEL_FOLDER_TYPE_MASK) | CAMEL_FOLDER_TYPE_INBOX;
@@ -2852,6 +3407,11 @@
 				camel_url_free (url);
 			} else {
 				fill_fi((CamelStore *)imap_store, fi, 0);
+				if (fi->unread == -1)
+					fi->unread = 0;
+
+				if (fi->total == -1) 
+					fi->total = 0;
 			}
 			g_ptr_array_add (folders, fi);
 		}
@@ -2863,6 +3423,8 @@
 	g_ptr_array_free (folders, TRUE);
 	g_free(name);
 
+	camel_store_summary_save ((CamelStoreSummary *)imap_store->summary);
+
 	return fi;
 }
 
@@ -2894,7 +3456,7 @@
 
 	CAMEL_SERVICE_REC_LOCK(store, connect_lock);
 
-	if (!camel_imap_store_connected (imap_store, ex))
+	if (!camel_disco_store_check_online((CamelDiscoStore *)imap_store, ex))
 		goto done;
 	
 	response = camel_imap_command (imap_store, NULL, ex,
@@ -2902,7 +3464,7 @@
 	if (!response)
 		goto done;
 	camel_imap_response_free (imap_store, response);
-	
+
 	si = camel_store_summary_path((CamelStoreSummary *)imap_store->summary, folder_name);
 	if (si) {
 		if ((si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) == 0) {
@@ -2938,7 +3500,7 @@
 
 	CAMEL_SERVICE_REC_LOCK(store, connect_lock);
 	
-	if (!camel_imap_store_connected (imap_store, ex))
+	if (!camel_disco_store_check_online((CamelDiscoStore *)imap_store, ex))
 		goto done;
 	
 	response = camel_imap_command (imap_store, NULL, ex,
@@ -3017,28 +3579,36 @@
 	 * close the connection. We can't expect a read to have any
 	 * meaning if we reconnect, so always set an exception.
 	 */
-	
-	if (!camel_imap_store_connected (store, ex))
+
+	if (!camel_disco_store_check_online((CamelDiscoStore *)store, ex))
 		return -1;
-	
+
+	g_mutex_lock (store->stream_lock);
+	camel_imap_store_restore_stream_buffer (store);
 	stream = CAMEL_STREAM_BUFFER (store->istream);
-	
+
 	ba = g_byte_array_new ();
 	while ((nread = camel_stream_buffer_gets (stream, linebuf, sizeof (linebuf))) > 0) {
-		g_byte_array_append (ba, linebuf, nread);
+		g_byte_array_append (ba, (const guchar*) linebuf, nread);
 		if (linebuf[nread - 1] == '\n')
 			break;
 	}
-	
+	g_mutex_unlock (store->stream_lock);
+
 	if (nread <= 0) {
 		if (errno == EINTR)
+		{
+			CamelException mex = CAMEL_EXCEPTION_INITIALISER;
 			camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL, _("Operation cancelled"));
-		else
+			camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
+			camel_service_connect (CAMEL_SERVICE (store), &mex);
+		} else {
 			camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
 					      _("Server unexpectedly disconnected: %s"),
 					      g_strerror (errno));
-		
-		camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
+			camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
+		}
+
 		g_byte_array_free (ba, TRUE);
 		return -1;
 	}
@@ -3057,7 +3627,55 @@
 		nread--;
 	}
 	
-	*dest = ba->data;
+	*dest = (char *) ba->data;
+	g_byte_array_free (ba, FALSE);
+	
+	return nread;
+}
+
+
+ssize_t
+camel_imap_store_readline_nb (CamelImapStore *store, char **dest, CamelException *ex)
+{
+	CamelStreamBuffer *stream;
+	char linebuf[1024] = {0};
+	GByteArray *ba;
+	ssize_t nread;
+	
+	g_return_val_if_fail (CAMEL_IS_IMAP_STORE (store), -1);
+	g_return_val_if_fail (dest, -1);
+
+	*dest = NULL;
+
+	g_mutex_lock (store->stream_lock);
+	if (store->istream == NULL || ((CamelObject *)store->istream)->ref_count <= 0)
+	{
+		g_mutex_unlock (store->stream_lock);
+		return -1;
+	}
+	stream = CAMEL_STREAM_BUFFER (store->istream);
+	ba = g_byte_array_new ();
+	while ((nread = camel_tcp_stream_buffer_gets_nb (stream, linebuf, sizeof (linebuf))) > 0) 
+	{
+		g_byte_array_append (ba, (const guchar*) linebuf, nread);
+		if (linebuf[nread - 1] == '\n')
+			break;
+	}
+	g_mutex_unlock (store->stream_lock);
+
+	if (nread <= 0) {
+		g_byte_array_free (ba, TRUE);
+		return -1;
+	}
+
+	nread = ba->len - 1;
+	ba->data[nread] = '\0';
+	if (ba->data[nread - 1] == '\r') {
+		ba->data[nread - 1] = '\0';
+		nread--;
+	}
+	
+	*dest = (char *) ba->data;
 	g_byte_array_free (ba, FALSE);
 	
 	return nread;
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/camel-imap-store.h ./providers/imap/camel-imap-store.h
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/camel-imap-store.h	2007-05-12 09:58:53.000000000 +0200
+++ ./providers/imap/camel-imap-store.h	2007-05-12 10:11:29.000000000 +0200
@@ -25,6 +25,22 @@
 #ifndef CAMEL_IMAP_STORE_H
 #define CAMEL_IMAP_STORE_H 1
 
+/* #define IDLE_DEBUG 1 */
+/* #define IMAP_DEBUG 1 */
+
+#ifdef IDLE_DEBUG
+#define idle_debug(o)	printf ("%s\n", o)
+#else
+#define idle_debug(o)	
+#endif
+
+#ifdef IMAP_DEBUG
+#define imap_debug(o)	printf ("%s\n", o)
+#else
+#define imap_debug(o)	
+#endif
+
+
 #include "camel-imap-types.h"
 #include <camel/camel-disco-store.h>
 #include <sys/time.h>
@@ -98,6 +114,9 @@
 #define IMAP_CAPABILITY_XGWEXTENSIONS		(1 << 9)
 #define IMAP_CAPABILITY_XGWMOVE			(1 << 10)
 #define IMAP_CAPABILITY_LOGINDISABLED		(1 << 11)
+#define IMAP_CAPABILITY_CONDSTORE		(1 << 12)
+#define IMAP_CAPABILITY_IDLE			(1 << 13)
+#define IMAP_CAPABILITY_BINARY			(1 << 14)
 
 #define IMAP_PARAM_OVERRIDE_NAMESPACE		(1 << 0)
 #define IMAP_PARAM_CHECK_ALL			(1 << 1)
@@ -106,15 +125,12 @@
 #define IMAP_PARAM_FILTER_JUNK_INBOX		(1 << 4)
 #define IMAP_PARAM_SUBSCRIPTIONS		(1 << 5)
 
-#define IMAP_FETCH_ALL_HEADERS 1
-#define IMAP_FETCH_MAILING_LIST_HEADERS 2 /* Fetches Minimal and Mailing List Headers. Default behavior */
-#define IMAP_FETCH_MINIMAL_HEADERS 3
-
 struct _CamelImapStore {
 	CamelDiscoStore parent_object;	
 	
 	CamelStream *istream;
 	CamelStream *ostream;
+	GMutex *stream_lock;
 
 	struct _CamelImapStoreSummary *summary;
 	
@@ -140,9 +156,9 @@
 	GHashTable *authtypes;
 	
 	time_t refresh_stamp;
-
-	guint32 headers;
-	char *custom_headers;
+	gchar *idle_prefix;
+	guint idle_signal;
+	gboolean dontdistridlehack, has_login;
 };
 
 typedef struct {
@@ -157,7 +173,14 @@
 
 gboolean camel_imap_store_connected (CamelImapStore *store, CamelException *ex);
 
+ssize_t camel_imap_store_readline_nb (CamelImapStore *store, char **dest, CamelException *ex);
 ssize_t camel_imap_store_readline (CamelImapStore *store, char **dest, CamelException *ex);
+gboolean camel_imap_service_connect (CamelService *service, CamelException *ex);
+
+gboolean camel_imap_store_restore_stream_buffer (CamelImapStore *store);
+
+void camel_imap_store_stop_idle (CamelImapStore *store);
+void camel_imap_store_start_idle (CamelImapStore *store);
 
 G_END_DECLS
 
Only in ./providers/imap: camel-imap-store.h.rej
Only in ./providers/imap: camel-imap-store.lo
Only in ./providers/imap: camel-imap-store.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/camel-imap-store-summary.c ./providers/imap/camel-imap-store-summary.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/camel-imap-store-summary.c	2007-05-12 09:58:53.000000000 +0200
+++ ./providers/imap/camel-imap-store-summary.c	2007-05-12 10:01:04.000000000 +0200
@@ -468,27 +468,44 @@
 	guint32 sep = '/';
 
 	ns = g_malloc0(sizeof(*ns));
-	if (camel_file_util_decode_string(in, &ns->path) == -1
-	    || camel_file_util_decode_string(in, &ns->full_name) == -1
-	    || camel_file_util_decode_uint32(in, &sep) == -1) {
-		namespace_free(s, ns);
-		ns = NULL;
-	} else {
-		ns->sep = sep;
-	}
+
+	if (camel_file_util_decode_string(in, &ns->path) == -1)
+		goto nserror;
+
+	if (camel_file_util_decode_string(in, &ns->full_name) == -1)
+		goto nserror;
+	
+	if (camel_file_util_decode_uint32(in, &sep) == -1)
+		goto nserror;
+
+	ns->sep = sep;
 
 	return ns;
+
+ nserror:
+
+	namespace_free(s, ns);
+	return NULL;
 }
 
 static int
 namespace_save(CamelStoreSummary *s, FILE *in, CamelImapStoreNamespace *ns)
 {
-	if (camel_file_util_encode_string(in, ns->path) == -1
-	    || camel_file_util_encode_string(in, ns->full_name) == -1
-	    || camel_file_util_encode_uint32(in, (guint32)ns->sep) == -1)
-		return -1;
+	if (camel_file_util_encode_string(in, ns->path) == -1)
+		goto serr;
+
+	if (camel_file_util_encode_string(in, ns->full_name) == -1)
+		goto serr;
+
+	if (camel_file_util_encode_uint32(in, (guint32)ns->sep) == -1)
+		goto serr;
 
 	return 0;
+
+ serr:
+	printf ("Error happend while writing\n");
+	return -1;
+
 }
 
 static int
Only in ./providers/imap: camel-imap-store-summary.lo
Only in ./providers/imap: camel-imap-store-summary.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/camel-imap-summary.c ./providers/imap/camel-imap-summary.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/camel-imap-summary.c	2007-05-12 09:58:53.000000000 +0200
+++ ./providers/imap/camel-imap-summary.c	2007-05-12 10:09:12.000000000 +0200
@@ -33,19 +33,21 @@
 
 #include "camel-file-utils.h"
 
+#include "camel-imap-message-cache.h"
 #include "camel-imap-summary.h"
 #include "camel-imap-utils.h"
+#include "camel-imap-folder.h"
 
 #define CAMEL_IMAP_SUMMARY_VERSION (3)
 
-static int summary_header_load (CamelFolderSummary *, FILE *);
+static int summary_header_load (CamelFolderSummary *);
 static int summary_header_save (CamelFolderSummary *, FILE *);
 
-static CamelMessageInfo *message_info_load (CamelFolderSummary *s, FILE *in);
+static CamelMessageInfo *message_info_load (CamelFolderSummary *s, gboolean *must_add);
 static int message_info_save (CamelFolderSummary *s, FILE *out,
 			      CamelMessageInfo *info);
 static gboolean info_set_user_tag(CamelMessageInfo *info, const char *name, const char  *value);
-static CamelMessageContentInfo *content_info_load (CamelFolderSummary *s, FILE *in);
+static CamelMessageContentInfo *content_info_load (CamelFolderSummary *s);
 static int content_info_save (CamelFolderSummary *s, FILE *out,
 			      CamelMessageContentInfo *info);
 
@@ -108,10 +110,18 @@
 }
 
 static void
+camel_imap_summary_set_extra_flags (CamelFolder *folder, CamelMessageInfoBase *mi)
+{
+	CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
+	camel_imap_message_cache_set_flags (imap_folder->folder_dir, mi);
+}
+
+static void
 camel_imap_summary_init (CamelImapSummary *obj)
 {
 	CamelFolderSummary *s = (CamelFolderSummary *)obj;
 
+	s->set_extra_flags_func = camel_imap_summary_set_extra_flags;
 	/* subclasses need to set the right instance data sizes */
 	s->message_info_size = sizeof(CamelImapMessageInfo);
 	s->content_info_size = sizeof(CamelImapMessageContentInfo);
@@ -146,31 +156,31 @@
 }
 
 static int
-summary_header_load (CamelFolderSummary *s, FILE *in)
+summary_header_load (CamelFolderSummary *s)
 {
 	CamelImapSummary *ims = CAMEL_IMAP_SUMMARY (s);
 	
-	if (camel_imap_summary_parent->summary_header_load (s, in) == -1)
+	if (camel_imap_summary_parent->summary_header_load (s) == -1)
 		return -1;
 
 	/* Legacy version */
-	if (s->version == 0x30c)
-		return camel_file_util_decode_uint32(in, &ims->validity);
+	if (s->version == 0x30c) {
+		unsigned char* ptrchr = s->filepos;
+		ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &ims->validity, FALSE);
+		s->filepos = ptrchr;
+		return 0;
+	}
 
 	/* Version 1 */
-	if (camel_file_util_decode_fixed_int32(in, &ims->version) == -1)
-		return -1;
+	ims->version = g_ntohl(get_unaligned_u32(s->filepos)); s->filepos += 4;
 	
 	if (ims->version == 2) {
 		/* Version 2: for compat with version 2 of the imap4 summary files */
 		int have_mlist;
-		
-		if (camel_file_util_decode_fixed_int32 (in, &have_mlist) == -1)
-			return -1;
+		have_mlist = g_ntohl(get_unaligned_u32(s->filepos)); s->filepos += 4;
 	}
-	
-	if (camel_file_util_decode_fixed_int32(in, &ims->validity) == -1)
-		return -1;
+
+	ims->validity = g_ntohl(get_unaligned_u32(s->filepos)); s->filepos += 4;
 	
 	if (ims->version > CAMEL_IMAP_SUMMARY_VERSION) {
 		g_warning("Unkown summary version\n");
@@ -207,25 +217,22 @@
 }
 
 static CamelMessageInfo *
-message_info_load (CamelFolderSummary *s, FILE *in)
+message_info_load (CamelFolderSummary *s, gboolean *must_add)
 {
 	CamelMessageInfo *info;
 	CamelImapMessageInfo *iinfo;
 
-	info = camel_imap_summary_parent->message_info_load (s, in);
-	if (info) {
-		iinfo = (CamelImapMessageInfo *)info;
-
-		if (camel_file_util_decode_uint32 (in, &iinfo->server_flags) == -1)
-			goto error;
+	info = camel_imap_summary_parent->message_info_load (s, must_add);
+	iinfo = (CamelImapMessageInfo*)info;
 
+	if (info) {
+		unsigned char* ptrchr = s->filepos;
+		ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &iinfo->server_flags, FALSE);
+		s->filepos = ptrchr;
 		label_to_flags(iinfo);
 	}
 
 	return info;
-error:
-	camel_message_info_free(info);
-	return NULL;
 }
 
 static int
@@ -253,10 +260,16 @@
 }
 
 static CamelMessageContentInfo *
-content_info_load (CamelFolderSummary *s, FILE *in)
+content_info_load (CamelFolderSummary *s)
 {
-	if (fgetc (in))
-		return camel_imap_summary_parent->content_info_load (s, in);
+	guint32 doit;
+	unsigned char* ptrchr = s->filepos;
+
+	ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &doit, FALSE);
+	s->filepos = ptrchr;
+
+	if (doit == 1)
+		return camel_imap_summary_parent->content_info_load (s);
 	else
 		return camel_folder_summary_content_info_new (s);
 }
@@ -266,10 +279,10 @@
 		   CamelMessageContentInfo *info)
 {
 	if (info->type) {
-		fputc (1, out);
+		camel_file_util_encode_uint32 (out, 1);
 		return camel_imap_summary_parent->content_info_save (s, out, info);
 	} else
-		return fputc (0, out);
+		return camel_file_util_encode_uint32 (out, 0);
 }
 
 void
@@ -278,8 +291,10 @@
 				const CamelMessageInfo *info)
 {
 	CamelImapMessageInfo *mi;
+#ifdef NON_TINYMAIL_FEATURES
 	const CamelFlag *flag;
 	const CamelTag *tag;
+#endif
 
 	/* Create summary entry */
 	mi = (CamelImapMessageInfo *)camel_folder_summary_info_new_from_message (summary, message);
@@ -287,6 +302,7 @@
 	/* Copy flags 'n' tags */
 	mi->info.flags = camel_message_info_flags(info);
 
+#ifdef NON_TINYMAIL_FEATURES
 	flag = camel_message_info_user_flags(info);
 	while (flag) {
 		camel_message_info_set_user_flag((CamelMessageInfo *)mi, flag->name, TRUE);
@@ -297,8 +313,10 @@
 		camel_message_info_set_user_tag((CamelMessageInfo *)mi, tag->name, tag->value);
 		tag = tag->next;
 	}
+#endif
 
-	mi->info.size = camel_message_info_size(info);
+	mi->info.size = ((CamelMessageInfoBase *)info)->size;
+	mi->info.flags |= CAMEL_MESSAGE_INFO_UID_NEEDS_FREE;
 	mi->info.uid = g_strdup (uid);
 
 	label_to_flags(mi);
@@ -313,7 +331,9 @@
 	CamelImapMessageInfo *mi;
 
 	mi = camel_message_info_clone(info);
+
 	mi->info.uid = g_strdup(uid);
+	mi->info.flags |= CAMEL_MESSAGE_INFO_UID_NEEDS_FREE;
 
 	label_to_flags(mi);
 
Only in ./providers/imap: camel-imap-summary.c.rej
Only in ./providers/imap: camel-imap-summary.lo
Only in ./providers/imap: camel-imap-summary.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/camel-imap-utils.c ./providers/imap/camel-imap-utils.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/camel-imap-utils.c	2007-05-12 09:58:53.000000000 +0200
+++ ./providers/imap/camel-imap-utils.c	2007-05-12 10:00:49.000000000 +0200
@@ -125,7 +125,7 @@
 			}
 			
 			/* decode IMAP's modified UTF-7 into UTF-8 */
-			node->prefix = imap_mailbox_decode (astring, len);
+			node->prefix = imap_mailbox_decode ((const unsigned char *) astring, len);
 			g_free (astring);
 			if (!node->prefix) {
 				g_free (node);
@@ -375,7 +375,6 @@
 	
 	if (folder) {
 		char *astring;
-		char *mailbox;
 		
 		/* get the folder name */
 		word = imap_next_word (word);
@@ -385,7 +384,9 @@
 
 		*folder = astring;
 
-		mailbox = imap_mailbox_decode (astring, strlen (astring));
+		char *mailbox;
+
+		mailbox = imap_mailbox_decode ((const unsigned char *) astring, strlen (astring));
 		g_free (astring);
 		if (!mailbox)
 			return FALSE;
@@ -480,8 +481,6 @@
 		g_string_append (gstr, "\\Flagged ");
 	if (flags & CAMEL_MESSAGE_SEEN)
 		g_string_append (gstr, "\\Seen ");
-	if (flags & CAMEL_MESSAGE_JUNK)
-		g_string_append (gstr, "Junk ");
 	if (flags & CAMEL_IMAP_MESSAGE_LABEL1)
 		g_string_append(gstr, "$Label1 ");
 	if (flags & CAMEL_IMAP_MESSAGE_LABEL2)
@@ -555,9 +554,7 @@
 		else if (!g_ascii_strncasecmp (flag_list, "\\Recent", len))
 			flags |= CAMEL_IMAP_MESSAGE_RECENT;
 		else if (!g_ascii_strncasecmp(flag_list, "\\*", len))
-			flags |= CAMEL_MESSAGE_USER|CAMEL_MESSAGE_JUNK|CAMEL_IMAP_MESSAGE_LABEL_MASK;
-		else if (!g_ascii_strncasecmp(flag_list, "Junk", len))
-			flags |= CAMEL_MESSAGE_JUNK;
+			flags |= CAMEL_MESSAGE_USER|CAMEL_IMAP_MESSAGE_LABEL_MASK;
 		else if (!g_ascii_strncasecmp(flag_list, "$Label1", len))
 			flags |= CAMEL_IMAP_MESSAGE_LABEL1;
 		else if (!g_ascii_strncasecmp(flag_list, "$Label2", len))
@@ -967,7 +964,7 @@
 		
 		/* size */
 		size = strtoul ((const char *) inptr, &p, 10);
-		inptr = (const unsigned char *) p;
+		inptr = (const char *) p;
 		
 		if (camel_content_type_is (ctype, "message", "rfc822")) {
 			/* body_type_msg */
@@ -990,14 +987,14 @@
 			
 			/* lines */
 			strtoul ((const char *) inptr, &p, 10);
-			inptr = (const unsigned char *) p;
+			inptr = (const char *) p;
 		} else if (camel_content_type_is (ctype, "text", "*")) {
 			if (*inptr++ != ' ')
 				goto exception;
 			
 			/* lines */
 			strtoul ((const char *) inptr, &p, 10);
-			inptr = (const unsigned char *) p;
+			inptr = (const char *) p;
 		} else {
 			/* body_type_basic */
 		}
Only in ./providers/imap: camel-imap-utils.lo
Only in ./providers/imap: camel-imap-utils.o
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/camel-imap-wrapper.c ./providers/imap/camel-imap-wrapper.c
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/camel-imap-wrapper.c	2007-05-12 09:58:53.000000000 +0200
+++ ./providers/imap/camel-imap-wrapper.c	2007-05-12 10:01:04.000000000 +0200
@@ -141,9 +141,10 @@
 	if (data_wrapper->offline) {
 		CamelStream *datastream;
 		
+		/* TNY TODO: partial message retrieval exception */
 		datastream = camel_imap_folder_fetch_data (
 			imap_wrapper->folder, imap_wrapper->uid,
-			imap_wrapper->part_spec, FALSE, NULL);
+			imap_wrapper->part_spec, FALSE, CAMEL_FOLDER_RECEIVE_FULL, -1, NULL);
 		if (!datastream) {
 			CAMEL_IMAP_WRAPPER_UNLOCK (imap_wrapper, lock);
 #ifdef ENETUNREACH
@@ -188,8 +189,9 @@
 	imap_wrapper->part = part;
 
 	/* Try the cache. */
+	/* TNY TODO: Partial message retrieval exception */
 	stream = camel_imap_folder_fetch_data (imap_folder, uid, part_spec,
-					       TRUE, NULL);
+					       TRUE, CAMEL_FOLDER_RECEIVE_FULL, -1, NULL);
 	if (stream) {
 		imap_wrapper_hydrate (imap_wrapper, stream);
 		camel_object_unref (stream);
Only in ./providers/imap: camel-imap-wrapper.lo
Only in ./providers/imap: camel-imap-wrapper.o
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap: ChangeLog
Only in ./providers/imap: .deps
Only in ./providers/imap: libcamelimap.la
Only in ./providers/imap: .libs
Only in ./providers/imap: Makefile
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/Makefile.am ./providers/imap/Makefile.am
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/Makefile.am	2007-05-12 09:58:53.000000000 +0200
+++ ./providers/imap/Makefile.am	2007-05-12 10:01:04.000000000 +0200
@@ -12,6 +12,7 @@
 	$(CAMEL_CFLAGS)				\
 	$(GNOME_INCLUDEDIR)			\
 	$(GTK_INCLUDEDIR)			\
+	-DTRANSDOM=\"$(GETTEXT_PACKAGE)\"	\
 	-DG_LOG_DOMAIN=\"camel-imap-provider\"
 
 libcamelimap_la_SOURCES = 			\
@@ -42,9 +43,8 @@
 libcamelimap_la_LDFLAGS = -avoid-version -module $(NO_UNDEFINED)
 
 libcamelimap_la_LIBADD = \
-	$(top_builddir)/libedataserver/libedataserver-${API_VERSION}.la \
-	$(top_builddir)/camel/libcamel-provider-1.2.la			\
-	$(top_builddir)/camel/libcamel-1.2.la				\
+	$(top_builddir)/camel/libcamel-lite-provider-1.2.la			\
+	$(top_builddir)/camel/libcamel-lite-1.2.la				\
 	$(CAMEL_LIBS)
 
 EXTRA_DIST = libcamelimap.urls
Only in ./providers/imap: Makefile.am.rej
Only in ./providers/imap: Makefile.in
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/all-wcprops ./providers/imap/.svn/all-wcprops
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/all-wcprops	2007-05-12 09:58:53.000000000 +0200
+++ ./providers/imap/.svn/all-wcprops	2007-05-12 10:49:08.000000000 +0200
@@ -1,155 +1,155 @@
 K 25
 svn:wc:ra_dav:version-url
-V 67
-/svn/evolution-data-server/!svn/ver/7736/trunk/camel/providers/imap
+V 83
+/svn/tinymail/!svn/ver/1943/trunk/libtinymail-camel/camel-lite/camel/providers/imap
 END
-camel-imap-store-summary.h
+camel-imap-store.c
 K 25
 svn:wc:ra_dav:version-url
-V 94
-/svn/evolution-data-server/!svn/ver/7720/trunk/camel/providers/imap/camel-imap-store-summary.h
+V 102
+/svn/tinymail/!svn/ver/1943/trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-store.c
 END
-camel-imap-store.c
+camel-imap-store-summary.h
 K 25
 svn:wc:ra_dav:version-url
-V 86
-/svn/evolution-data-server/!svn/ver/7720/trunk/camel/providers/imap/camel-imap-store.c
+V 110
+/svn/tinymail/!svn/ver/1943/trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-store-summary.h
 END
 camel-imap-summary.c
 K 25
 svn:wc:ra_dav:version-url
-V 88
-/svn/evolution-data-server/!svn/ver/7720/trunk/camel/providers/imap/camel-imap-summary.c
+V 104
+/svn/tinymail/!svn/ver/1943/trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-summary.c
 END
 camel-imap-utils.c
 K 25
 svn:wc:ra_dav:version-url
-V 86
-/svn/evolution-data-server/!svn/ver/7720/trunk/camel/providers/imap/camel-imap-utils.c
+V 102
+/svn/tinymail/!svn/ver/1943/trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-utils.c
 END
 camel-imap-store.h
 K 25
 svn:wc:ra_dav:version-url
-V 86
-/svn/evolution-data-server/!svn/ver/7720/trunk/camel/providers/imap/camel-imap-store.h
+V 102
+/svn/tinymail/!svn/ver/1943/trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-store.h
 END
 camel-imap-summary.h
 K 25
 svn:wc:ra_dav:version-url
-V 88
-/svn/evolution-data-server/!svn/ver/7720/trunk/camel/providers/imap/camel-imap-summary.h
+V 104
+/svn/tinymail/!svn/ver/1943/trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-summary.h
 END
-ChangeLog
+.svnignore
 K 25
 svn:wc:ra_dav:version-url
-V 77
-/svn/evolution-data-server/!svn/ver/7736/trunk/camel/providers/imap/ChangeLog
+V 94
+/svn/tinymail/!svn/ver/1019/trunk/libtinymail-camel/camel-lite/camel/providers/imap/.svnignore
 END
-camel-imap-utils.h
+camel-imap-search.c
 K 25
 svn:wc:ra_dav:version-url
-V 86
-/svn/evolution-data-server/!svn/ver/7720/trunk/camel/providers/imap/camel-imap-utils.h
+V 103
+/svn/tinymail/!svn/ver/1943/trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-search.c
 END
-camel-imap-search.c
+camel-imap-utils.h
 K 25
 svn:wc:ra_dav:version-url
-V 87
-/svn/evolution-data-server/!svn/ver/7720/trunk/camel/providers/imap/camel-imap-search.c
+V 102
+/svn/tinymail/!svn/ver/1943/trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-utils.h
 END
 camel-imap-types.h
 K 25
 svn:wc:ra_dav:version-url
-V 86
-/svn/evolution-data-server/!svn/ver/7720/trunk/camel/providers/imap/camel-imap-types.h
+V 102
+/svn/tinymail/!svn/ver/1943/trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-types.h
 END
 camel-imap-search.h
 K 25
 svn:wc:ra_dav:version-url
-V 87
-/svn/evolution-data-server/!svn/ver/7720/trunk/camel/providers/imap/camel-imap-search.h
+V 103
+/svn/tinymail/!svn/ver/1943/trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-search.h
 END
 camel-imap-folder.c
 K 25
 svn:wc:ra_dav:version-url
-V 87
-/svn/evolution-data-server/!svn/ver/7720/trunk/camel/providers/imap/camel-imap-folder.c
+V 103
+/svn/tinymail/!svn/ver/1943/trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.c
 END
 camel-imap-command.c
 K 25
 svn:wc:ra_dav:version-url
-V 88
-/svn/evolution-data-server/!svn/ver/7720/trunk/camel/providers/imap/camel-imap-command.c
+V 104
+/svn/tinymail/!svn/ver/1943/trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-command.c
 END
-libcamelimap.urls
+camel-imap-private.h
 K 25
 svn:wc:ra_dav:version-url
-V 85
-/svn/evolution-data-server/!svn/ver/1352/trunk/camel/providers/imap/libcamelimap.urls
+V 104
+/svn/tinymail/!svn/ver/1943/trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-private.h
 END
-camel-imap-private.h
+libcamelimap.urls
 K 25
 svn:wc:ra_dav:version-url
-V 88
-/svn/evolution-data-server/!svn/ver/7720/trunk/camel/providers/imap/camel-imap-private.h
+V 101
+/svn/tinymail/!svn/ver/1014/trunk/libtinymail-camel/camel-lite/camel/providers/imap/libcamelimap.urls
 END
 camel-imap-folder.h
 K 25
 svn:wc:ra_dav:version-url
-V 87
-/svn/evolution-data-server/!svn/ver/7720/trunk/camel/providers/imap/camel-imap-folder.h
+V 103
+/svn/tinymail/!svn/ver/1943/trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.h
 END
 camel-imap-wrapper.c
 K 25
 svn:wc:ra_dav:version-url
-V 88
-/svn/evolution-data-server/!svn/ver/7720/trunk/camel/providers/imap/camel-imap-wrapper.c
+V 104
+/svn/tinymail/!svn/ver/1943/trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-wrapper.c
 END
 camel-imap-command.h
 K 25
 svn:wc:ra_dav:version-url
-V 88
-/svn/evolution-data-server/!svn/ver/7720/trunk/camel/providers/imap/camel-imap-command.h
+V 104
+/svn/tinymail/!svn/ver/1943/trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-command.h
 END
 camel-imap-message-cache.c
 K 25
 svn:wc:ra_dav:version-url
-V 94
-/svn/evolution-data-server/!svn/ver/7720/trunk/camel/providers/imap/camel-imap-message-cache.c
+V 110
+/svn/tinymail/!svn/ver/1943/trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-message-cache.c
 END
 Makefile.am
 K 25
 svn:wc:ra_dav:version-url
-V 79
-/svn/evolution-data-server/!svn/ver/7720/trunk/camel/providers/imap/Makefile.am
+V 95
+/svn/tinymail/!svn/ver/1078/trunk/libtinymail-camel/camel-lite/camel/providers/imap/Makefile.am
 END
 camel-imap-wrapper.h
 K 25
 svn:wc:ra_dav:version-url
-V 88
-/svn/evolution-data-server/!svn/ver/7720/trunk/camel/providers/imap/camel-imap-wrapper.h
+V 104
+/svn/tinymail/!svn/ver/1943/trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-wrapper.h
 END
 camel-imap-store-summary.c
 K 25
 svn:wc:ra_dav:version-url
-V 94
-/svn/evolution-data-server/!svn/ver/7720/trunk/camel/providers/imap/camel-imap-store-summary.c
+V 110
+/svn/tinymail/!svn/ver/1943/trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-store-summary.c
 END
 .cvsignore
 K 25
 svn:wc:ra_dav:version-url
-V 78
-/svn/evolution-data-server/!svn/ver/1187/trunk/camel/providers/imap/.cvsignore
+V 94
+/svn/tinymail/!svn/ver/1014/trunk/libtinymail-camel/camel-lite/camel/providers/imap/.cvsignore
 END
 camel-imap-provider.c
 K 25
 svn:wc:ra_dav:version-url
-V 89
-/svn/evolution-data-server/!svn/ver/7736/trunk/camel/providers/imap/camel-imap-provider.c
+V 105
+/svn/tinymail/!svn/ver/1943/trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-provider.c
 END
 camel-imap-message-cache.h
 K 25
 svn:wc:ra_dav:version-url
-V 94
-/svn/evolution-data-server/!svn/ver/7720/trunk/camel/providers/imap/camel-imap-message-cache.h
+V 110
+/svn/tinymail/!svn/ver/1943/trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-message-cache.h
 END
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/dir-prop-base ./providers/imap/.svn/dir-prop-base
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/dir-prop-base	2007-05-12 09:58:49.000000000 +0200
+++ ./providers/imap/.svn/dir-prop-base	2007-04-22 11:56:49.000000000 +0200
@@ -1,16 +1,9 @@
 K 10
 svn:ignore
-V 72
-.deps
-Makefile
+V 33
 Makefile.in
 .libs
 .deps
-*.lo
-*.la
-*.bb
-*.bbg
-*.da
-*.gcov
+Makefile
 
 END
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/entries ./providers/imap/.svn/entries
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/entries	2007-05-12 09:58:59.000000000 +0200
+++ ./providers/imap/.svn/entries	2007-05-12 10:49:08.000000000 +0200
@@ -1,15 +1,15 @@
 8
 
 dir
-7738
-http://svn.gnome.org/svn/evolution-data-server/trunk/camel/providers/imap
-http://svn.gnome.org/svn/evolution-data-server
+1943
+https://svn.tinymail.org/svn/tinymail/trunk/libtinymail-camel/camel-lite/camel/providers/imap
+https://svn.tinymail.org/svn/tinymail
 
 
 
-2007-05-11T18:31:18.634404Z
-7736
-sragavan
+2007-05-12T08:30:21.902504Z
+1943
+pvanhoof
 has-props
 
 svn:special svn:externals svn:needs-lock
@@ -24,7 +24,7 @@
 
 
 
-d0434b6f-c725-0410-8785-fd8a057797ef
+d4f517bd-a70b-0410-9f68-c17655437c52
 
 camel-imap-store.c
 file
@@ -32,12 +32,11 @@
 
 
 
-2007-05-12T07:58:53.000000Z
-7eba60014db1dcb95b1af27475e7e02d
-2007-04-28T01:42:04.098476Z
-7720
-mbarnes
-has-props
+2007-05-12T08:00:49.000000Z
+77ad4eae29652d3119273c87cd426634
+2007-05-12T08:30:21.902504Z
+1943
+pvanhoof
 
 camel-imap-store-summary.h
 file
@@ -45,12 +44,11 @@
 
 
 
-2007-05-12T07:58:53.000000Z
+2007-05-12T08:00:49.000000Z
 af4ec743c60bf3ad2be944a0f15a89c0
-2007-04-28T01:42:04.098476Z
-7720
-mbarnes
-has-props
+2007-05-12T08:30:21.902504Z
+1943
+pvanhoof
 
 camel-imap-summary.c
 file
@@ -58,12 +56,11 @@
 
 
 
-2007-05-12T07:58:53.000000Z
-9bbd0f7518d5201fed7fce809f631179
-2007-04-28T01:42:04.098476Z
-7720
-mbarnes
-has-props
+2007-05-12T08:09:12.000000Z
+f642efa760729841b01fd61a02f8f7cf
+2007-05-12T08:30:21.902504Z
+1943
+pvanhoof
 
 camel-imap-utils.c
 file
@@ -71,12 +68,11 @@
 
 
 
-2007-05-12T07:58:53.000000Z
-8a8bcf82411207058954ade2160908cf
-2007-04-28T01:42:04.098476Z
-7720
-mbarnes
-has-props
+2007-05-12T08:00:49.000000Z
+5eb9aa62a9871744cf2e85e8af385e19
+2007-05-12T08:30:21.902504Z
+1943
+pvanhoof
 
 camel-imap-store.h
 file
@@ -84,12 +80,11 @@
 
 
 
-2007-05-12T07:58:53.000000Z
-2877ca95c846448546109c271133bd7c
-2007-04-28T01:42:04.098476Z
-7720
-mbarnes
-has-props
+2007-05-12T08:11:29.000000Z
+30f84c1dfa2bea8a78b4f10fe30b9957
+2007-05-12T08:30:21.902504Z
+1943
+pvanhoof
 
 camel-imap-summary.h
 file
@@ -97,24 +92,23 @@
 
 
 
-2007-05-12T07:58:53.000000Z
+2007-05-12T08:01:01.000000Z
 6c3ac8d793ee95f5cdce563463cb207e
-2007-04-28T01:42:04.098476Z
-7720
-mbarnes
-has-props
+2007-05-12T08:30:21.902504Z
+1943
+pvanhoof
 
-ChangeLog
+.svnignore
 file
 
 
 
 
-2007-05-12T07:58:53.000000Z
-64fa7e5386bd253cde04fb5078c38400
-2007-05-11T18:31:18.634404Z
-7736
-sragavan
+2007-03-11T15:44:08.000000Z
+349bfb6574e6f84ca228f148c7fb1129
+2006-10-16T23:45:03.608857Z
+1019
+pvanhoof
 
 camel-imap-search.c
 file
@@ -122,12 +116,11 @@
 
 
 
-2007-05-12T07:58:53.000000Z
-858d42167939c33a671302f10d4c20a6
-2007-04-28T01:42:04.098476Z
-7720
-mbarnes
-has-props
+2007-05-12T08:01:03.000000Z
+4102a31b17553d02a902ff487fb8dd17
+2007-05-12T08:30:21.902504Z
+1943
+pvanhoof
 
 camel-imap-utils.h
 file
@@ -135,12 +128,11 @@
 
 
 
-2007-05-12T07:58:53.000000Z
+2007-05-12T08:01:03.000000Z
 6b137f9debb71b87550f833e9ff30663
-2007-04-28T01:42:04.098476Z
-7720
-mbarnes
-has-props
+2007-05-12T08:30:21.902504Z
+1943
+pvanhoof
 
 camel-imap-types.h
 file
@@ -148,12 +140,11 @@
 
 
 
-2007-05-12T07:58:53.000000Z
+2007-05-12T08:01:03.000000Z
 5f3bda53f01f40f5787096d96a995609
-2007-04-28T01:42:04.098476Z
-7720
-mbarnes
-has-props
+2007-05-12T08:30:21.902504Z
+1943
+pvanhoof
 
 camel-imap-search.h
 file
@@ -161,12 +152,11 @@
 
 
 
-2007-05-12T07:58:53.000000Z
+2007-05-12T08:01:03.000000Z
 f5321638abadbde77b286b5c9f4d28c9
-2007-04-28T01:42:04.098476Z
-7720
-mbarnes
-has-props
+2007-05-12T08:30:21.902504Z
+1943
+pvanhoof
 
 camel-imap-folder.c
 file
@@ -174,12 +164,11 @@
 
 
 
-2007-05-12T07:58:53.000000Z
-a5b37dd33a064724fd52c95f1aa16dce
-2007-04-28T01:42:04.098476Z
-7720
-mbarnes
-has-props
+2007-05-12T08:15:55.000000Z
+a0ed8ca02615043b0fab2b1cd809cec2
+2007-05-12T08:30:21.902504Z
+1943
+pvanhoof
 
 camel-imap-command.c
 file
@@ -187,12 +176,11 @@
 
 
 
-2007-05-12T07:58:53.000000Z
-6fc11cfb17e2cb41bf7ed7043245a141
-2007-04-28T01:42:04.098476Z
-7720
-mbarnes
-has-props
+2007-05-12T08:17:00.000000Z
+4acd760158d31d6a41e1748dbc802bc4
+2007-05-12T08:30:21.902504Z
+1943
+pvanhoof
 
 camel-imap-private.h
 file
@@ -200,12 +188,11 @@
 
 
 
-2007-05-12T07:58:53.000000Z
+2007-05-12T08:01:04.000000Z
 e68703f00e6e4d1fd4f700c42703c457
-2007-04-28T01:42:04.098476Z
-7720
-mbarnes
-has-props
+2007-05-12T08:30:21.902504Z
+1943
+pvanhoof
 
 libcamelimap.urls
 file
@@ -213,11 +200,11 @@
 
 
 
-2007-04-20T11:24:56.000000Z
+2007-03-11T15:44:08.000000Z
 626a2232193e7dcca9e18cc90922f9a8
-2001-03-27T05:22:44.000000Z
-1352
-danw
+2006-10-16T23:10:20.309538Z
+1014
+pvanhoof
 
 camel-imap-folder.h
 file
@@ -225,12 +212,11 @@
 
 
 
-2007-05-12T07:58:53.000000Z
-aba96eea2c77565797bb951813eca925
-2007-04-28T01:42:04.098476Z
-7720
-mbarnes
-has-props
+2007-05-12T08:01:04.000000Z
+b80eec9804afd5c0dab8a71653abf459
+2007-05-12T08:30:21.902504Z
+1943
+pvanhoof
 
 camel-imap-wrapper.c
 file
@@ -238,12 +224,11 @@
 
 
 
-2007-05-12T07:58:53.000000Z
-ee5b3e0dcdccb857cff11d810d6909fe
-2007-04-28T01:42:04.098476Z
-7720
-mbarnes
-has-props
+2007-05-12T08:01:04.000000Z
+1806282273e06f6eaefad72aea2166da
+2007-05-12T08:30:21.902504Z
+1943
+pvanhoof
 
 camel-imap-command.h
 file
@@ -251,12 +236,11 @@
 
 
 
-2007-05-12T07:58:53.000000Z
-e6c274c76599459792e012221514a520
-2007-04-28T01:42:04.098476Z
-7720
-mbarnes
-has-props
+2007-05-12T08:01:04.000000Z
+4dfdf651e9517d44de2a61635c408c6e
+2007-05-12T08:30:21.902504Z
+1943
+pvanhoof
 
 camel-imap-message-cache.c
 file
@@ -264,12 +248,11 @@
 
 
 
-2007-05-12T07:58:53.000000Z
-9021592367ed3acc210bd1518ca60662
-2007-04-28T01:42:04.098476Z
-7720
-mbarnes
-has-props
+2007-05-12T08:01:04.000000Z
+2c96b3481340f2b66d17fec8419fe739
+2007-05-12T08:30:21.902504Z
+1943
+pvanhoof
 
 Makefile.am
 file
@@ -277,11 +260,11 @@
 
 
 
-2007-05-12T07:58:53.000000Z
-996091003d0f5318b57a5d1c29b7f4c6
-2007-04-28T01:42:04.098476Z
-7720
-mbarnes
+2007-05-12T08:01:04.000000Z
+ba0afda4913b41290bf774beb5796930
+2006-10-30T14:48:07.262395Z
+1078
+pvanhoof
 
 camel-imap-wrapper.h
 file
@@ -289,12 +272,11 @@
 
 
 
-2007-05-12T07:58:53.000000Z
+2007-05-12T08:01:04.000000Z
 43043fc0422276c8a92f482ad4f5446a
-2007-04-28T01:42:04.098476Z
-7720
-mbarnes
-has-props
+2007-05-12T08:30:21.902504Z
+1943
+pvanhoof
 
 camel-imap-store-summary.c
 file
@@ -302,12 +284,11 @@
 
 
 
-2007-05-12T07:58:53.000000Z
-9096fbb1f97a5f412d8d96d492b0e583
-2007-04-28T01:42:04.098476Z
-7720
-mbarnes
-has-props
+2007-05-12T08:01:04.000000Z
+1805027ff12abe812e058100e2fd24fa
+2007-05-12T08:30:21.902504Z
+1943
+pvanhoof
 
 .cvsignore
 file
@@ -315,11 +296,11 @@
 
 
 
-2007-04-20T11:24:56.000000Z
+2007-03-11T15:44:08.000000Z
 8ed39a9d365e0613ec1d61142135e223
-2001-01-22T11:57:29.000000Z
-1187
-zucchi
+2006-10-16T23:10:20.309538Z
+1014
+pvanhoof
 
 camel-imap-provider.c
 file
@@ -327,12 +308,11 @@
 
 
 
-2007-05-12T07:58:53.000000Z
-cf5bf7aaeb1268e2971b2fd5975da83a
-2007-05-11T18:31:18.634404Z
-7736
-sragavan
-has-props
+2007-05-12T08:01:04.000000Z
+91499d3da894df288e2bcac03cf04092
+2007-05-12T08:30:21.902504Z
+1943
+pvanhoof
 
 camel-imap-message-cache.h
 file
@@ -340,10 +320,9 @@
 
 
 
-2007-05-12T07:58:53.000000Z
-bb57d0d57e49300c7bc58f32d045f4be
-2007-04-28T01:42:04.098476Z
-7720
-mbarnes
-has-props
+2007-05-12T08:01:04.000000Z
+2f303f7978077de6735392d6a99e45c9
+2007-05-12T08:30:21.902504Z
+1943
+pvanhoof
 
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/prop-base: camel-imap-command.c.svn-base
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/prop-base: camel-imap-command.h.svn-base
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/prop-base: camel-imap-folder.c.svn-base
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/prop-base: camel-imap-folder.h.svn-base
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/prop-base: camel-imap-message-cache.c.svn-base
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/prop-base: camel-imap-message-cache.h.svn-base
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/prop-base: camel-imap-private.h.svn-base
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/prop-base: camel-imap-provider.c.svn-base
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/prop-base: camel-imap-search.c.svn-base
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/prop-base: camel-imap-search.h.svn-base
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/prop-base: camel-imap-store.c.svn-base
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/prop-base: camel-imap-store.h.svn-base
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/prop-base: camel-imap-store-summary.c.svn-base
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/prop-base: camel-imap-store-summary.h.svn-base
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/prop-base: camel-imap-summary.c.svn-base
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/prop-base: camel-imap-summary.h.svn-base
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/prop-base: camel-imap-types.h.svn-base
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/prop-base: camel-imap-utils.c.svn-base
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/prop-base: camel-imap-utils.h.svn-base
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/prop-base: camel-imap-wrapper.c.svn-base
Only in /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/prop-base: camel-imap-wrapper.h.svn-base
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/text-base/camel-imap-command.c.svn-base ./providers/imap/.svn/text-base/camel-imap-command.c.svn-base
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/text-base/camel-imap-command.c.svn-base	2007-05-12 09:58:53.000000000 +0200
+++ ./providers/imap/.svn/text-base/camel-imap-command.c.svn-base	2007-05-12 10:17:00.000000000 +0200
@@ -60,6 +60,10 @@
 static char *imap_command_strdup_printf (CamelImapStore *store,
 					 const char *fmt, ...);
 
+
+
+
+
 /**
  * camel_imap_command:
  * @store: the IMAP store
@@ -93,19 +97,24 @@
 {
 	va_list ap;
 	char *cmd;
-	
+
 	CAMEL_SERVICE_REC_LOCK (store, connect_lock);
-	
+
 	if (fmt) {
 		va_start (ap, fmt);
 		cmd = imap_command_strdup_vprintf (store, fmt, ap);
 		va_end (ap);
 	} else {
-		camel_object_ref(folder);
-		if (store->current_folder)
-			camel_object_unref(store->current_folder);
+
+		/* camel_object_ref(folder); 
+		if (store->current_folder && CAMEL_IS_OBJECT (store->current_folder))
+			camel_object_unref(store->current_folder); */
+
 		store->current_folder = folder;
-		cmd = imap_command_strdup_printf (store, "SELECT %F", folder->full_name);
+		if (store->capabilities & IMAP_CAPABILITY_CONDSTORE) 
+			cmd = imap_command_strdup_printf (store, "SELECT %F (CONDSTORE)", folder->full_name);
+		else 
+			cmd = imap_command_strdup_printf (store, "SELECT %F", folder->full_name);
 	}
 	
 	if (!imap_command_start (store, folder, cmd, ex)) {
@@ -118,6 +127,7 @@
 	return imap_read_response (store, ex);
 }
 
+
 /**
  * camel_imap_command_start:
  * @store: the IMAP store
@@ -163,13 +173,15 @@
 	va_start (ap, fmt);
 	cmd = imap_command_strdup_vprintf (store, fmt, ap);
 	va_end (ap);
-	
+
 	CAMEL_SERVICE_REC_LOCK (store, connect_lock);
+
 	ok = imap_command_start (store, folder, cmd, ex);
 	g_free (cmd);
-	
+
 	if (!ok)
 		CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
+
 	return ok;
 }
 
@@ -178,20 +190,43 @@
 		    const char *cmd, CamelException *ex)
 {
 	ssize_t nwritten;
-	
-	g_return_val_if_fail(store->ostream!=NULL, FALSE);
-	g_return_val_if_fail(store->istream!=NULL, FALSE);
-	
+	gchar *resp = NULL;
+	CamelException myex = CAMEL_EXCEPTION_INITIALISER;
+	gchar *full_cmd = NULL;
+	guint len = 0;
+
+	if (store->ostream == NULL || ((CamelObject *)store->ostream)->ref_count <= 0)
+	{
+		if (store->has_login && !camel_service_connect ((CamelService*)store, ex))
+			return FALSE;
+	}
+
+	/* g_mutex_lock (store->stream_lock); */
+
+	if (store->ostream==NULL) return FALSE;
+	if (store->istream==NULL) return FALSE;
+
+	/* g_mutex_unlock (store->stream_lock);*/
+
+
+	/* Also read imap_update_summary and all of the IDLE crap */
+	if (!store->dontdistridlehack) 
+		camel_imap_store_stop_idle (store);
+	/* else
+		printf ("dont distr\n"); */
+
 	/* Check for current folder */
-	if (folder && folder != store->current_folder) {
+	if (folder && folder != store->current_folder) 
+	{
 		CamelImapResponse *response;
 		CamelException internal_ex;
-		
+
 		response = camel_imap_command (store, folder, ex, NULL);
 		if (!response)
 			return FALSE;
 		camel_exception_init (&internal_ex);
-		camel_imap_folder_selected (folder, response, &internal_ex);
+		/* g_print ("select\n"); */
+		camel_imap_folder_selected (folder, response, &internal_ex, FALSE);
 		camel_imap_response_free (store, response);
 		if (camel_exception_is_set (&internal_ex)) {
 			camel_exception_xfer (ex, &internal_ex);
@@ -214,19 +249,51 @@
 		
 		fprintf (stderr, "sending : %c%.5u %s\r\n", store->tag_prefix, store->command, mask);
 	}
-	
-	nwritten = camel_stream_printf (store->ostream, "%c%.5u %s\r\n",
-					store->tag_prefix, store->command++, cmd);
-	
-	if (nwritten == -1) {
+
+	/* g_mutex_lock (store->stream_lock); */
+
+	if (store->ostream==NULL || ((CamelObject *)store->ostream)->ref_count <= 0) 
+		{ /* g_mutex_unlock (store->stream_lock); */ return FALSE; }
+	if (store->istream==NULL || ((CamelObject *)store->istream)->ref_count <= 0) 
+		{ /* g_mutex_unlock (store->stream_lock); */ return FALSE; }
+
+	/* Read away whatever we got */
+	while (camel_imap_store_readline_nb (store, &resp, &myex) > 0)
+	{
+		imap_debug ("unsolitcited: ");
+		imap_debug (resp);
+		imap_debug ("\n");
+
+		g_free (resp);
+		resp=NULL;
+	}
+	if (resp)
+		g_free (resp);
+
+	full_cmd = g_strdup_printf ("%c%.5u %s\r\n", store->tag_prefix, 
+		store->command++, cmd);
+	len = strlen (full_cmd);
+
+	/* printf ("-> %s\n", full_cmd); */
+
+	nwritten = camel_stream_write (store->ostream, full_cmd, len);
+
+	/* g_mutex_unlock (store->stream_lock); */
+
+	if (nwritten != len) 
+	{
+		CamelException mex = CAMEL_EXCEPTION_INITIALISER;
+
 		if (errno == EINTR)
 			camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
 					     _("Operation cancelled"));
 		else
 			camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
 					     g_strerror (errno));
-		
-		camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
+
+		camel_service_disconnect (CAMEL_SERVICE (store), FALSE, &mex);
+		camel_service_connect (CAMEL_SERVICE (store), &mex);
+
 		return FALSE;
 	}
 	
@@ -253,7 +320,7 @@
 camel_imap_command_continuation (CamelImapStore *store, const char *cmd,
 				 size_t cmdlen, CamelException *ex)
 {
-	if (!camel_imap_store_connected (store, ex))
+	if (!camel_disco_store_check_online ((CamelDiscoStore*)store, ex))
 		return NULL;
 
 	g_return_val_if_fail(store->ostream!=NULL, NULL);
@@ -268,6 +335,7 @@
 			camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
 					     g_strerror (errno));
 		camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
+
 		CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
 		return NULL;
 	}
@@ -275,6 +343,7 @@
 	return imap_read_response (store, ex);
 }
 
+
 /**
  * camel_imap_command_response:
  * @store: the IMAP store
@@ -301,7 +370,9 @@
 		CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
 		return CAMEL_IMAP_RESPONSE_ERROR;
 	}
-	
+
+	/* printf ("<-- %s\n", respbuf); */
+
 	switch (*respbuf) {
 	case '*':
 		if (!g_ascii_strncasecmp (respbuf, "* BYE", 5)) {
@@ -344,10 +415,67 @@
 		break;
 	}
 	*response = respbuf;
-	
+
 	if (type == CAMEL_IMAP_RESPONSE_ERROR ||
-	    type == CAMEL_IMAP_RESPONSE_TAGGED)
+	    type == CAMEL_IMAP_RESPONSE_TAGGED) 
 		CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
+
+	return type;
+}
+
+
+CamelImapResponseType
+camel_imap_command_response_idle (CamelImapStore *store, char **response,
+			     CamelException *ex)
+{
+	CamelImapResponseType type;
+	char *respbuf;
+
+	if (camel_imap_store_readline (store, &respbuf, ex) < 0)
+		return CAMEL_IMAP_RESPONSE_ERROR;
+
+	switch (*respbuf) {
+	case '*':
+		if (!g_ascii_strncasecmp (respbuf, "* BYE", 5)) {
+			/* Connection was lost, no more data to fetch */
+			camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
+			camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+					      _("Server unexpectedly disconnected: %s"),
+					      _("Unknown error")); /* g_strerror (104));  FIXME after 1.0 is released */
+			store->connected = FALSE;
+			g_free (respbuf);
+			respbuf = NULL;
+			type = CAMEL_IMAP_RESPONSE_ERROR;
+			break;
+		}
+		
+		/* Read the rest of the response. */
+		type = CAMEL_IMAP_RESPONSE_UNTAGGED;
+		respbuf = imap_read_untagged (store, respbuf, ex);
+		if (!respbuf)
+			type = CAMEL_IMAP_RESPONSE_ERROR;
+		else if (!g_ascii_strncasecmp (respbuf, "* OK [ALERT]", 12)
+			 || !g_ascii_strncasecmp (respbuf, "* NO [ALERT]", 12)
+			 || !g_ascii_strncasecmp (respbuf, "* BAD [ALERT]", 13)) {
+			char *msg;
+
+			/* for imap ALERT codes, account user@host */
+			/* we might get a ']' from a BAD response since we +12, but who cares? */
+			msg = g_strdup_printf(_("Alert from IMAP server %s@%s:\n%s"),
+					      ((CamelService *)store)->url->user, ((CamelService *)store)->url->host, respbuf+12);
+			camel_session_alert_user(((CamelService *)store)->session, CAMEL_SESSION_ALERT_WARNING, msg, FALSE);
+			g_free(msg);
+		} else if (!g_ascii_strncasecmp (respbuf, "* BAD Invalid tag",17))
+			type = CAMEL_IMAP_RESPONSE_ERROR;
+		break;
+	case '+':
+		type = CAMEL_IMAP_RESPONSE_CONTINUATION;
+		break;
+	default:
+		type = CAMEL_IMAP_RESPONSE_TAGGED;
+		break;
+	}
+	*response = respbuf;
 	
 	return type;
 }
@@ -364,8 +492,9 @@
 	 * we're still locked. This lock is owned by response
 	 * and gets unlocked when response is freed.
 	 */
+
 	CAMEL_SERVICE_REC_LOCK (store, connect_lock);
-	
+
 	response = g_new0 (CamelImapResponse, 1);
 	if (store->current_folder && camel_disco_store_status (CAMEL_DISCO_STORE (store)) != CAMEL_DISCO_STORE_RESYNCING) {
 		response->folder = store->current_folder;
@@ -383,7 +512,7 @@
 	}
 	
 	response->status = respbuf;
-	
+
 	/* Check for OK or continuation response. */
 	if (*respbuf == '+')
 		return response;
@@ -622,6 +751,7 @@
 	}
 	
 	g_free (response);
+
 	CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
 }
 
@@ -780,8 +910,9 @@
 			} else if (*p == 'G') {
 				string = camel_utf8_utf7(string);
 			}
-				
-			arglen = strlen (string);
+
+			if (string)
+				arglen = strlen (string);
 			g_ptr_array_add (args, string);
 			if (imap_is_atom (string)) {
 				len += arglen;
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/text-base/camel-imap-command.h.svn-base ./providers/imap/.svn/text-base/camel-imap-command.h.svn-base
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/text-base/camel-imap-command.h.svn-base	2007-05-12 09:58:53.000000000 +0200
+++ ./providers/imap/.svn/text-base/camel-imap-command.h.svn-base	2007-05-12 10:01:04.000000000 +0200
@@ -74,6 +74,9 @@
 						    char **respbuf,
 						    CamelException *ex);
 
+CamelImapResponseType camel_imap_command_response_idle (CamelImapStore *store, char **response,
+						        CamelException *ex);
+
 G_END_DECLS
 
 #endif /* CAMEL_IMAP_COMMAND_H */
diff -ru /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/text-base/camel-imap-folder.c.svn-base ./providers/imap/.svn/text-base/camel-imap-folder.c.svn-base
--- /home/pvanhoof/repos/gnome/evolution-data-server/camel/providers/imap/.svn/text-base/camel-imap-folder.c.svn-base	2007-05-12 09:58:53.000000000 +0200
+++ ./providers/imap/.svn/text-base/camel-imap-folder.c.svn-base	2007-05-12 10:15:55.000000000 +0200
@@ -1,10 +1,15 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-imap-folder.c: class for an imap folder */
-
-/* 
+/* camel-imap-folder.c: class for an imap folder
+ * 
+ * This is the mmap version of camel-imap-folder.c which has a memory
+ * consumption reduced imap_update_summary implementation that will
+ * periodically instruct the mmap CamelFolderSummary instance to sync
+ * headers to disk.
+ *
  * Authors:
  *   Dan Winship <danw@ximian.com>
  *   Jeffrey Stedfast <fejj@ximian.com> 
+ *   Philip Van Hoof <pvanhoof@gnome.org>
  *
  * Copyright (C) 2000, 2001 Ximian, Inc.
  *
@@ -23,6 +28,11 @@
  * USA
  */
 
+/* BODY always returns "textual data", which means a series of characters 
+   no containing NUL, CR, or LF, of length <= 1000.*/
+
+#define MAX_LINE_LEN 1024 
+
 #include <config.h> 
 
 #include <ctype.h>
@@ -39,6 +49,7 @@
 #include <libedataserver/e-data-server-util.h>
 #include <libedataserver/e-time-utils.h>
 
+
 #include "camel-data-wrapper.h"
 #include "camel-debug.h"
 #include "camel-disco-diary.h"
@@ -71,6 +82,9 @@
 #include "camel-imap-utils.h"
 #include "camel-imap-wrapper.h"
 
+
+#include <camel/camel-tcp-stream.h>
+
 #define d(x) 
 
 /* set to -1 for infinite size (suggested max command-line length is
@@ -86,7 +100,8 @@
 static void imap_finalize (CamelObject *object);
 static int imap_getv(CamelObject *object, CamelException *ex, CamelArgGetV *args);
 
-static void imap_rescan (CamelFolder *folder, int exists, CamelException *ex);
+static gboolean imap_rescan_condstore (CamelFolder *folder, int exists, const char *highestmodseq, CamelException *ex);
+static gboolean imap_rescan (CamelFolder *folder, int exists, CamelException *ex);
 static void imap_refresh_info (CamelFolder *folder, CamelException *ex);
 static void imap_sync_online (CamelFolder *folder, CamelException *ex);
 static void imap_sync_offline (CamelFolder *folder, CamelException *ex);
@@ -95,10 +110,11 @@
 static void imap_expunge_uids_resyncing (CamelFolder *folder, GPtrArray *uids, CamelException *ex);
 static void imap_cache_message (CamelDiscoFolder *disco_folder, const char *uid, CamelException *ex);
 static void imap_rename (CamelFolder *folder, const char *new);
+static void imap_set_push_email (CamelFolder *folder, gboolean setting);
 
 /* message manipulation */
 static CamelMimeMessage *imap_get_message (CamelFolder *folder, const gchar *uid,
-					   CamelException *ex);
+					   CamelFolderReceiveType type, gint param, CamelException *ex);
 static void imap_append_online (CamelFolder *folder, CamelMimeMessage *message,
 				const CamelMessageInfo *info, char **appended_uid,
 				CamelException *ex);
@@ -132,6 +148,10 @@
 static CamelObjectClass *parent_class;
 
 static GData *parse_fetch_response (CamelImapFolder *imap_folder, char *msg_att);
+static void camel_imap_folder_changed_for_idle (CamelFolder *folder, int exists,
+			   GArray *expunged, CamelException *ex);
+
+GPtrArray* _camel_imap_store_get_recent_messages (CamelImapStore *imap_store, const char *folder_name, int *messages, int *unseen, gboolean withthem);
 
 #ifdef G_OS_WIN32
 /* The strtok() in Microsoft's C library is MT-safe (but still uses
@@ -141,6 +161,8 @@
 #define strtok_r(s,sep,lasts) (*(lasts)=strtok((s),(sep)))
 #endif
 
+
+
 static void
 camel_imap_folder_class_init (CamelImapFolderClass *camel_imap_folder_class)
 {
@@ -152,6 +174,7 @@
 	/* virtual method overload */
 	((CamelObjectClass *)camel_imap_folder_class)->getv = imap_getv;
 
+	camel_folder_class->set_push_email = imap_set_push_email;
 	camel_folder_class->get_message = imap_get_message;
 	camel_folder_class->rename = imap_rename;
 	camel_folder_class->search_by_expression = imap_search_by_expression;
@@ -178,12 +201,21 @@
 	camel_disco_folder_class->cache_message = imap_cache_message;
 }
 
+
 static void
 camel_imap_folder_init (gpointer object, gpointer klass)
 {
 	CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (object);
 	CamelFolder *folder = CAMEL_FOLDER (object);
-	
+
+	/* ((CamelObject *)folder)-> flags |= CAMEL_OBJECT_REF_DEBUG; */
+
+	imap_folder->idle_lock = g_new0 (GStaticRecMutex, 1);
+	g_static_rec_mutex_init (imap_folder->idle_lock);
+	imap_folder->stopping = FALSE;
+	imap_folder->in_idle = FALSE;
+
+	imap_folder->do_push_email = TRUE;
 	folder->permanent_flags = CAMEL_MESSAGE_ANSWERED | CAMEL_MESSAGE_DELETED |
 		CAMEL_MESSAGE_DRAFT | CAMEL_MESSAGE_FLAGGED | CAMEL_MESSAGE_SEEN;
 	
@@ -229,7 +261,7 @@
 	const char *short_name;
 	char *summary_file, *state_file;
 
-	if (g_mkdir_with_parents (folder_dir, S_IRWXU) != 0) {
+	if (e_util_mkdir_hier (folder_dir, S_IRWXU) != 0) {
 		camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
 				      _("Could not create directory %s: %s"),
 				      folder_dir, g_strerror (errno));
@@ -237,6 +269,10 @@
 	}
 
 	folder = CAMEL_FOLDER (camel_object_new (camel_imap_folder_get_type ()));
+	imap_folder = CAMEL_IMAP_FOLDER (folder);
+
+	imap_folder->folder_dir = g_strdup (folder_dir);
+
 	short_name = strrchr (folder_name, '/');
 	if (short_name)
 		short_name++;
@@ -244,7 +280,7 @@
 		short_name = folder_name;
 	camel_folder_construct (folder, parent, folder_name, short_name);
 
-	summary_file = g_strdup_printf ("%s/summary", folder_dir);
+	summary_file = g_strdup_printf ("%s/summary.mmap", folder_dir);
 	folder->summary = camel_imap_summary_new (folder, summary_file);
 	g_free (summary_file);
 	if (!folder->summary) {
@@ -261,8 +297,8 @@
 	g_free(state_file);
 	camel_object_state_read(folder);
 
-	imap_folder = CAMEL_IMAP_FOLDER (folder);
 	imap_folder->cache = camel_imap_message_cache_new (folder_dir, folder->summary, ex);
+
 	if (!imap_folder->cache) {
 		camel_object_unref (CAMEL_OBJECT (folder));
 		return NULL;
@@ -278,15 +314,78 @@
 			folder->folder_flags |= CAMEL_FOLDER_FILTER_JUNK;
 	}
 
+	if (imap_store->capabilities & IMAP_CAPABILITY_IDLE)
+		folder->folder_flags |= CAMEL_FOLDER_HAS_PUSHEMAIL_CAPABILITY;
+
 	imap_folder->search = camel_imap_search_new(folder_dir);
 
 	return folder;
 }
 
+
+static void 
+put_highestmodseq (CamelImapFolder *imap_folder, const char *highestmodseq)
+{
+	char *filename = g_strdup_printf ("%s/highestmodseq", imap_folder->folder_dir);
+	FILE *file;
+	
+	file = fopen (filename, "w");
+	g_free (filename);
+
+	if (file != NULL)
+	{
+		fprintf (file, "%s", highestmodseq);
+		fclose (file);
+	}
+}
+
+static char* 
+get_highestmodseq (CamelImapFolder *imap_folder)
+{
+	char *filename = g_strdup_printf ("%s/highestmodseq", imap_folder->folder_dir);
+	char *retval = NULL;
+	FILE *file;
+
+	file = fopen (filename, "r");
+	g_free (filename);
+
+	if (file != NULL)
+	{
+		retval = g_malloc0 (25); /* a 64bit number must fit in it */
+		fscanf (file, "%s", retval);
+		fclose (file);
+	}
+
+	return retval;
+}
+
 /* Called with the store's connect_lock locked */
+
+
+/*
+The assumption we have to make is that any folder can have been offline 
+before it got here to become selected. 
+
+Which is nasty because that means that our IDLE code might not have kept it
+synchronized. We might not have been notified by EXISTS, FETCH and EXPUNGE
+unsolicited events (you can't assume that).
+
+We also can't assume the availability of HIGHESTMODSEQ (or CONDSTORE). Not
+even if the IMAP service announced the condstore capability. That's because
+condstore is to be enabled per mailbox!
+
+UIDNEXT might be incorrect, I have seen IMAP servers that simply get it wrong.
+
+Although it has been reported that Exchange's IMAP server sometimes gives to high
+values for EXISTS, it's quite safe to assume that the EXISTS is going to be 
+correct on most servers. Just don't crash on sequences that don't exist remote.
+
+More documentation inline
+*/
+
 void
 camel_imap_folder_selected (CamelFolder *folder, CamelImapResponse *response,
-			    CamelException *ex)
+			    CamelException *ex, gboolean idle)
 {
 	CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
 	CamelImapSummary *imap_summary = CAMEL_IMAP_SUMMARY (folder->summary);
@@ -294,13 +393,29 @@
 	CamelMessageInfo *info;
 	guint32 perm_flags = 0;
 	GData *fetch_data;
-	int i, count;
-	char *resp;
-	
+	int i, count, uidnext = -1;
+	char *resp, *phighestmodseq = NULL, *highestmodseq = NULL;
+	CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
+	gboolean removals = FALSE, condstore = FALSE, needtoput=FALSE, suc=FALSE;
+
 	count = camel_folder_summary_count (folder->summary);
-	
-	for (i = 0; i < response->untagged->len; i++) {
+
+	/* With CONDSTORE this is the typical output.
+	 * C: A142 SELECT INBOX (CONDSTORE)
+	 * S: * 172 EXISTS
+	 * S: * 1 RECENT
+	 * S: * OK [UNSEEN 12] Message 12 is first unseen
+	 * S: * OK [UIDVALIDITY 3857529045] UIDs valid
+	 * S: * OK [UIDNEXT 4392] Predicted next UID
+	 * S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
+	 * S: * OK [PERMANENTFLAGS (\Deleted \Seen \*)] Limited
+	 * S: * OK [HIGHESTMODSEQ 715194045007]
+	 * S: A142 OK [READ-WRITE] SELECT completed, CONDSTORE is now enabled */
+
+	for (i = 0; i < response->untagged->len; i++) 
+	{
 		resp = response->untagged->pdata[i] + 2;
+
 		if (!g_ascii_strncasecmp (resp, "FLAGS ", 6) && !perm_flags) {
 			resp += 6;
 			folder->permanent_flags = imap_parse_flag_list (&resp);
@@ -311,6 +426,44 @@
 			 * even tho they do allow storing flags. *Sigh* So many fucking broken IMAP servers out there. */
 			if ((perm_flags = imap_parse_flag_list (&resp)) != 0)
 				folder->permanent_flags = perm_flags;
+		} else if (!g_ascii_strncasecmp (resp, "OK [UIDNEXT ", 12)) {
+			char *marker = strchr (resp, ']');
+			if (marker) *marker='\0';
+			uidnext = strtoul (resp + 12, NULL, 10);
+		} else if (!g_ascii_strncasecmp (resp, "OK [HIGHESTMODSEQ ", 18)) 
+		{
+		
+			/* So we have a HIGHESTMODSEQ, we are going to store this
+			 * one assuming that our code that will follow is correct
+			 * and that after that upcoming code, the local folder 
+			 * state will be in sync with that remote HIGHESTMODSEQ 
+			 * value. */
+			
+			char *marker;
+			unsigned int len;
+			resp += 18;
+
+			marker = strchr (resp, ']');
+
+			if (marker) 
+			{
+				condstore = TRUE;
+				len = (unsigned int) (marker - resp);
+				
+				highestmodseq = g_strndup (resp, len);
+				phighestmodseq = get_highestmodseq (imap_folder);
+
+				if (phighestmodseq !=NULL && !strcmp (phighestmodseq, highestmodseq)) 
+				{
+					g_free (phighestmodseq);
+					phighestmodseq = NULL;
+				} else 
+					needtoput = TRUE;
+			} else {
+				phighestmodseq = NULL;
+				highestmodseq = NULL;
+			}
+
 		} else if (!g_ascii_strncasecmp (resp, "OK [UIDVALIDITY ", 16)) {
 			validity = strtoul (resp + 16, NULL, 10);
 		} else if (isdigit ((unsigned char)*resp)) {
@@ -319,8 +472,7 @@
 			if (!g_ascii_strncasecmp (resp, " EXISTS", 7)) {
 				exists = num;
 				/* Remove from the response so nothing
-				 * else tries to interpret it.
-				 */
+				 * else tries to interpret it. */
 				g_free (response->untagged->pdata[i]);
 				g_ptr_array_remove_index (response->untagged, i--);
 			}
@@ -328,18 +480,31 @@
 	}
 
 	if (camel_strstrcase (response->status, "OK [READ-ONLY]"))
+	{
+		folder->folder_flags |= CAMEL_FOLDER_IS_READONLY;
 		imap_folder->read_only = TRUE;
+	}
 
-	if (camel_disco_store_status (CAMEL_DISCO_STORE (folder->parent_store)) == CAMEL_DISCO_STORE_RESYNCING) {
+	if (camel_disco_store_status (CAMEL_DISCO_STORE (folder->parent_store)) == CAMEL_DISCO_STORE_RESYNCING) 
+	{
+		if (phighestmodseq != NULL)
+			g_free (phighestmodseq);
+		if (highestmodseq != NULL)
+			g_free (highestmodseq);
+		
 		if (validity != imap_summary->validity) {
 			camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_SUMMARY_INVALID,
 					      _("Folder was destroyed and recreated on server."));
 			return;
 		}
-		
+
 		/* FIXME: find missing UIDs ? */
 		return;
 	}
+
+	/* If there's no match on VALIDITY, we are dealing with a different 
+	 * folder. For example the folder got removed and re-created. We'll
+	 * simply clear everyting and do things from scratch. */
 	
 	if (!imap_summary->validity)
 		imap_summary->validity = validity;
@@ -351,82 +516,163 @@
 		CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
 		imap_folder->need_rescan = FALSE;
 		camel_imap_folder_changed (folder, exists, NULL, ex);
+		
+		if (phighestmodseq != NULL)
+			g_free (phighestmodseq);
+		if (highestmodseq != NULL)
+			g_free (highestmodseq);
+		
 		return;
 	}
+
+	/* If we already had stuff locally, get the last one's UID . Store it in
+	 * what we will start calling VAL */
 	
-	/* If we've lost messages, we have to rescan everything */
-	if (exists < count)
-		imap_folder->need_rescan = TRUE;
-	else if (count != 0 && !imap_folder->need_rescan) {
-		CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
-		
-		/* Similarly, if the UID of the highest message we
-		 * know about has changed, then that indicates that
-		 * messages have been both added and removed, so we
-		 * have to rescan to find the removed ones. (We pass
-		 * NULL for the folder since we know that this folder
-		 * is selected, and we don't want camel_imap_command
-		 * to worry about it.)
-		 */
-		response = camel_imap_command (store, NULL, ex, "FETCH %d UID", count);
-		if (!response)
-			return;
-		uid = 0;
-		for (i = 0; i < response->untagged->len; i++) {
-			resp = response->untagged->pdata[i];
-			val = strtoul (resp + 2, &resp, 10);
-			if (val == 0)
-				continue;
-			if (!g_ascii_strcasecmp (resp, " EXISTS")) {
-				/* Another one?? */
-				exists = val;
-				continue;
-			}
-			if (uid != 0 || val != count || g_ascii_strncasecmp (resp, " FETCH (", 8) != 0)
-				continue;
-			
-			fetch_data = parse_fetch_response (imap_folder, resp + 7);
-			uid = strtoul (g_datalist_get_data (&fetch_data, "UID"), NULL, 10);
-			g_datalist_clear (&fetch_data);
-		}
-		camel_imap_response_free_without_processing (store, response);
-		
+	if (count > 0)
+	{
 		info = camel_folder_summary_index (folder->summary, count - 1);
 		val = strtoul (camel_message_info_uid (info), NULL, 10);
 		camel_message_info_free(info);
-		if (uid == 0 || uid != val)
-			imap_folder->need_rescan = TRUE;
+	} else 
+		val = -1;
+
+	/* If we are going the CONDSTORE route and if (uidnext-1) is not the 
+	 * same as the last uid in our summary, it's very likely that expunges
+	 * happened. This CONDSTORE code does not yet support expunges. 
+	 * Therefore we will simply use the old code. */
+
+	if (phighestmodseq != NULL && (val != uidnext-1))
+	{
+		g_free (phighestmodseq); 
+		phighestmodseq = NULL;
+		removals = TRUE;
 	}
+
+	/* If our local count isn't the same as the EXISTS, then our CONDSTORE 
+	 * implementation can't be used. Period. */
 	
-	/* Now rescan if we need to */
-	if (imap_folder->need_rescan) {
-		imap_rescan (folder, exists, ex);
-		return;
+	if (exists != count)
+	{
+		if (phighestmodseq != NULL)
+			g_free (phighestmodseq); 
+		phighestmodseq = NULL;
+		removals = TRUE;
 	}
-	
-	/* If we don't need to rescan completely, but new messages
-	 * have been added, find out about them.
-	 */
-	if (exists > count)
+
+	if (removals)
+		imap_folder->need_rescan = TRUE;
+	else if (condstore && (store->capabilities & IMAP_CAPABILITY_CONDSTORE))
+		imap_folder->need_rescan = FALSE;
+
+	/* We still aren't certain. For example if at the end of the mailbox 
+	 * both an add and an expunge happened, then all of above figured out
+	 * nothing meaningful. So we will compare the last local uid with the
+	 * remote uid at the same sequence number (that's count, as the count
+	 * is the index + 1). This is where we need the VAL thingy of above. */
+	
+	if (!imap_folder->need_rescan) 
+	{
+		int mval = 0;
+
+		/* If the UID of the highest message we know about has changed, 
+		 * then that indicates that messages have been both added and 
+		 * removed, so we have to rescan to find the removed ones */
+
+		response = camel_imap_command (store, NULL, ex, "FETCH %d UID", count);
+		if (response) {
+			uid = 0;
+			for (i = 0; i < response->untagged->len; i++) 
+			{
+				resp = response->untagged->pdata[i];
+				mval = strtoul (resp + 2, &resp, 10);
+				if (mval == 0)
+					continue;
+				if (!g_ascii_strcasecmp (resp, " EXISTS")) 
+				{
+					/* Another one?? */
+					exists = mval;
+					continue;
+				}
+				if (uid != 0 || mval != count || g_ascii_strncasecmp (resp, " FETCH (", 8) != 0)
+					continue;
+				
+				fetch_data = parse_fetch_response (imap_folder, resp + 7);
+				uid = strtoul (g_datalist_get_data (&fetch_data, "UID"), NULL, 10);
+				g_datalist_clear (&fetch_data);
+			}
+			camel_imap_response_free_without_processing (store, response);
+			if (uid == 0 || uid != val)
+				imap_folder->need_rescan = TRUE;
+		} else 
+			imap_folder->need_rescan = TRUE;
+	}
+
+	/* Okay, it survived ALL checks and CONDSTORE is available too. Lucky we 
+	 * are, aren't we? So we use CONDSTORE. Note, however, that if condstore 
+	 * still finds removals (sequences don't match) or if anything goes wrong
+	 * during the CONDSTORE code, that it'll set need_rescan TRUE and that 
+	 * as a result the lines below this if{} block will still happen. This is
+	 * indeed on purpose and as a fall-back situation (our detection got it
+	 * wrong) */
+	
+	if (phighestmodseq)
+	{
+		if (!imap_folder->need_rescan)
+			suc = imap_rescan_condstore (folder, exists, phighestmodseq, ex);
+		g_free (phighestmodseq);
+		phighestmodseq = NULL;
+	}
+
+	if (imap_folder->need_rescan)
+		suc = imap_rescan (folder, exists, ex);
+	else if (exists > count)
 		camel_imap_folder_changed (folder, exists, NULL, ex);
-	
-	/* And we're done. */
+
+	if (highestmodseq != NULL && suc && needtoput)
+		put_highestmodseq (imap_folder, (const char *) highestmodseq);
+
+	if (highestmodseq != NULL)
+		g_free (highestmodseq);
+
+	if (idle)
+		camel_imap_folder_start_idle (folder);
 }
 
-static void           
+static void 
 imap_finalize (CamelObject *object)
 {
 	CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (object);
+	CamelImapStore *store = CAMEL_IMAP_STORE (CAMEL_FOLDER(imap_folder)->parent_store);
+
+	imap_folder->do_push_email = FALSE;
+
+	imap_folder->stopping = TRUE;
+
+	if (imap_folder->idle_signal > 0) 
+		g_source_remove (imap_folder->idle_signal);
+
+	if (!imap_folder->in_idle || imap_folder->idle_lock != NULL)
+	{
+		g_static_rec_mutex_free (imap_folder->idle_lock);
+		imap_folder->idle_lock = NULL;
+	}
+
+	if (store->current_folder == (CamelFolder*) object)
+		store->current_folder = NULL;
 
 	if (imap_folder->search)
 		camel_object_unref (CAMEL_OBJECT (imap_folder->search));
 	if (imap_folder->cache)
 		camel_object_unref (CAMEL_OBJECT (imap_folder->cache));
 
+	if (imap_folder->folder_dir)
+		g_free (imap_folder->folder_dir);
+
 #ifdef ENABLE_THREADS
 	g_static_mutex_free(&imap_folder->priv->search_lock);
 	g_static_rec_mutex_free(&imap_folder->priv->cache_lock);
 #endif
+
 	g_free(imap_folder->priv);
 }
 
@@ -519,21 +765,20 @@
 	 * should do it.  */
 	CAMEL_SERVICE_REC_LOCK (imap_store, c