[evolution-data-server/camel-gobject: 2/4] Keep raw headers in a GQueue.



commit 8814cc202bd7a5ea10dc308a0a572dccb92d1ad1
Author: Matthew Barnes <mbarnes redhat com>
Date:   Sat Oct 17 16:21:30 2009 -0500

    Keep raw headers in a GQueue.
    
    Also make them opaque structures so we have more flexibility.

 camel/camel-filter-driver.c                        |   31 +-
 camel/camel-filter-search.c                        |   53 +++-
 camel/camel-folder-search.c                        |   74 ++++-
 camel/camel-folder-summary.c                       |  146 ++++++---
 camel/camel-folder-summary.h                       |   10 +-
 camel/camel-folder.c                               |    8 +-
 camel/camel-http-stream.c                          |   61 ++--
 camel/camel-http-stream.h                          |    2 +-
 camel/camel-mime-filter-linewrap.c                 |    4 +-
 camel/camel-mime-message.c                         |   14 +-
 camel/camel-mime-parser.c                          |   93 ++----
 camel/camel-mime-parser.h                          |    2 +-
 camel/camel-mime-part.c                            |  182 +++++++----
 camel/camel-mime-part.h                            |    3 +-
 camel/camel-mime-utils.c                           |  335 +++++++++++++-------
 camel/camel-mime-utils.h                           |   51 ++--
 camel/camel-stream-filter.c                        |    2 +-
 camel/providers/imap/camel-imap-folder.c           |    6 +-
 camel/providers/imap/camel-imap-store.c            |    2 +-
 camel/providers/local/camel-local-summary.c        |   32 ++-
 camel/providers/local/camel-local-summary.h        |    2 +-
 camel/providers/local/camel-maildir-folder.c       |    2 +
 camel/providers/local/camel-maildir-summary.c      |    7 +-
 camel/providers/local/camel-mbox-summary.c         |   12 +-
 camel/providers/local/camel-spool-summary.h        |    2 +-
 camel/providers/nntp/camel-nntp-folder.c           |   31 +--
 camel/providers/nntp/camel-nntp-summary.c          |   19 +-
 camel/providers/pop3/camel-pop3-folder.c           |   25 +-
 .../providers/sendmail/camel-sendmail-transport.c  |   32 +--
 camel/providers/smtp/camel-smtp-transport.c        |   26 +--
 docs/reference/camel/camel-sections.txt            |   11 +-
 .../reference/camel/tmpl/camel-folder-summary.sgml |    6 +-
 docs/reference/camel/tmpl/camel-local-summary.sgml |    2 +-
 docs/reference/camel/tmpl/camel-mime-utils.sgml    |   99 ++++---
 docs/reference/camel/tmpl/camel-spool-summary.sgml |    2 +-
 docs/reference/camel/tmpl/camel-unused.sgml        |   38 +++
 36 files changed, 876 insertions(+), 551 deletions(-)
---
diff --git a/camel/camel-filter-driver.c b/camel/camel-filter-driver.c
index b06081f..aeddc10 100644
--- a/camel/camel-filter-driver.c
+++ b/camel/camel-filter-driver.c
@@ -1258,9 +1258,10 @@ camel_filter_driver_filter_mbox (CamelFilterDriver *driver, const gchar *mbox, c
 	source_url = g_filename_to_uri (mbox, NULL, NULL);
 
 	while (camel_mime_parser_step (mp, 0, 0) == CAMEL_MIME_PARSER_STATE_FROM) {
-		struct _camel_header_raw *headers;
 		CamelMessageInfo *info;
-		CamelMimeMessage *msg;
+		CamelMimeMessage *message;
+		CamelMimePart *mime_part;
+		GQueue *header_queue;
 		gint pc = 0;
 		const gchar *xev;
 
@@ -1269,27 +1270,29 @@ camel_filter_driver_filter_mbox (CamelFilterDriver *driver, const gchar *mbox, c
 
 		report_status (driver, CAMEL_FILTER_STATUS_START, pc, _("Getting message %d (%d%%)"), i, pc);
 
-		msg = camel_mime_message_new ();
-		if (camel_mime_part_construct_from_parser (CAMEL_MIME_PART (msg), mp) == -1) {
+		message = camel_mime_message_new ();
+		mime_part = CAMEL_MIME_PART (message);
+
+		if (camel_mime_part_construct_from_parser (mime_part, mp) == -1) {
 			camel_exception_set (ex, (errno==EINTR)?CAMEL_EXCEPTION_USER_CANCEL:CAMEL_EXCEPTION_SYSTEM, _("Cannot open message"));
 			report_status (driver, CAMEL_FILTER_STATUS_END, 100, _("Failed on message %d"), i);
-			g_object_unref (msg);
+			g_object_unref (message);
 			goto fail;
 		}
 
-		headers = camel_mime_part_get_raw_headers (CAMEL_MIME_PART (msg));
-		info = camel_message_info_new_from_header(NULL, headers);
+		header_queue = camel_mime_part_get_raw_headers (mime_part);
+		info = camel_message_info_new_from_header(NULL, header_queue);
 		/* Try and see if it has X-Evolution headers */
-		xev = camel_header_raw_find(&headers, "X-Evolution", NULL);
+		xev = camel_header_raw_find(header_queue, "X-Evolution", NULL);
 		if (xev)
 			decode_flags_from_xev (xev, (CamelMessageInfoBase *)info);
 
 		((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,
+		status = camel_filter_driver_filter_message (driver, message, info, NULL, NULL, source_url,
 							     original_source_url ? original_source_url : source_url, ex);
-		g_object_unref (msg);
+		g_object_unref (message);
 		if (camel_exception_is_set (ex) || status == -1) {
 			report_status (driver, CAMEL_FILTER_STATUS_END, 100, _("Failed on message %d"), i);
 			camel_message_info_free (info);
@@ -1472,6 +1475,7 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver, CamelMimeMessage
 				    CamelException *ex)
 {
 	struct _CamelFilterDriverPrivate *p = CAMEL_FILTER_DRIVER_GET_PRIVATE (driver);
+	CamelMimePart *mime_part;
 	struct _filter_rule *node;
 	gboolean freeinfo = FALSE;
 	gboolean filtered = FALSE;
@@ -1485,7 +1489,7 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver, CamelMimeMessage
 	}
 
 	if (info == NULL) {
-		struct _camel_header_raw *h;
+		GQueue *header_queue;
 
 		if (message) {
 			g_object_ref (message);
@@ -1495,8 +1499,9 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver, CamelMimeMessage
 				return -1;
 		}
 
-		h = camel_mime_part_get_raw_headers (CAMEL_MIME_PART (message));
-		info = camel_message_info_new_from_header (NULL, h);
+		mime_part = CAMEL_MIME_PART (message);
+		header_queue = camel_mime_part_get_raw_headers (mime_part);
+		info = camel_message_info_new_from_header (NULL, header_queue);
 		freeinfo = TRUE;
 	} else {
 		if (camel_message_info_flags(info) & CAMEL_MESSAGE_DELETED)
diff --git a/camel/camel-filter-search.c b/camel/camel-filter-search.c
index d078bf2..4775e2f 100644
--- a/camel/camel-filter-search.c
+++ b/camel/camel-filter-search.c
@@ -163,32 +163,46 @@ check_header (struct _ESExp *f, gint argc, struct _ESExpResult **argv, FilterMes
 			}
 		} else {
 			CamelMimeMessage *message;
-			struct _camel_header_raw *header;
+			CamelMimePart *mime_part;
+			GQueue *header_queue;
+			GList *link;
 			const gchar *charset = NULL;
 			camel_search_t type = CAMEL_SEARCH_TYPE_ENCODED;
 			CamelContentType *ct;
 
 			message = camel_filter_search_get_message (fms, f);
+			mime_part = CAMEL_MIME_PART (message);
 
 			/* FIXME: what about Resent-To, Resent-Cc and Resent-From? */
 			if (g_ascii_strcasecmp("to", name) == 0 || g_ascii_strcasecmp("cc", name) == 0 || g_ascii_strcasecmp("from", name) == 0)
 				type = CAMEL_SEARCH_TYPE_ADDRESS_ENCODED;
 			else if (message) {
-				ct = camel_mime_part_get_content_type (CAMEL_MIME_PART (message));
+				ct = camel_mime_part_get_content_type (mime_part);
 				if (ct) {
 					charset = camel_content_type_param (ct, "charset");
 					charset = camel_iconv_charset_name (charset);
 				}
 			}
 
-			header = camel_mime_part_get_raw_headers (CAMEL_MIME_PART (message));
-			for (; header && !matched; header = header->next) {
-				if (!g_ascii_strcasecmp(header->name, name)) {
+			header_queue = camel_mime_part_get_raw_headers (mime_part);
+			link = g_queue_peek_head_link (header_queue);
+
+			while (link != NULL) {
+				CamelHeaderRaw *raw_header = link->data;
+				const gchar *header_name;
+				const gchar *header_value;
+
+				header_name = camel_header_raw_get_name (raw_header);
+				header_value = camel_header_raw_get_value (raw_header);
+
+				if (!g_ascii_strcasecmp(header_name, name)) {
 					for (i=1; i<argc && !matched; i++) {
 						if (argv[i]->type == ESEXP_RES_STRING)
-							matched = camel_search_header_match(header->value, argv[i]->value.string, how, type, charset);
+							matched = camel_search_header_match(header_value, argv[i]->value.string, how, type, charset);
 					}
 				}
+
+				link = g_list_next (link);
 			}
 		}
 	}
@@ -274,21 +288,34 @@ header_regex (struct _ESExp *f, gint argc, struct _ESExpResult **argv, FilterMes
 static gchar *
 get_full_header (CamelMimeMessage *message)
 {
-	CamelMimePart *mp = CAMEL_MIME_PART (message);
+	CamelMimePart *mime_part;
 	GString *str = g_string_new ("");
+	GQueue *header_queue;
+	GList *link;
 	gchar   *ret;
-	struct _camel_header_raw *h;
 
-	for (h = camel_mime_part_get_raw_headers (mp); h; h = h->next) {
-		if (h->value != NULL) {
-			g_string_append (str, h->name);
-			if (isspace (h->value[0]))
+	mime_part = CAMEL_MIME_PART (message);
+	header_queue = camel_mime_part_get_raw_headers (mime_part);
+	link = g_queue_peek_head_link (header_queue);
+
+	while (link != NULL) {
+		CamelHeaderRaw *raw_header = link->data;
+		const gchar *name, *value;
+
+		name = camel_header_raw_get_name (raw_header);
+		value = camel_header_raw_get_value (raw_header);
+
+		if (value != NULL) {
+			g_string_append (str, name);
+			if (isspace (value[0]))
 				g_string_append (str, ":");
 			else
 				g_string_append (str, ": ");
-			g_string_append (str, h->value);
+			g_string_append (str, value);
 			g_string_append_c(str, '\n');
 		}
+
+		link = g_list_next (link);
 	}
 
 	ret = str->str;
diff --git a/camel/camel-folder-search.c b/camel/camel-folder-search.c
index 7069445..5093fc1 100644
--- a/camel/camel-folder-search.c
+++ b/camel/camel-folder-search.c
@@ -1051,7 +1051,6 @@ check_header (struct _ESExp *f, gint argc, struct _ESExpResult **argv, CamelFold
 		camel_search_t type = CAMEL_SEARCH_TYPE_ASIS;
 		struct _camel_search_words *words;
 		CamelMimeMessage *message = NULL;
-		struct _camel_header_raw *raw_header;
 
 		/* only a subset of headers are supported .. */
 		headername = argv[0]->value.string;
@@ -1099,24 +1098,56 @@ check_header (struct _ESExp *f, gint argc, struct _ESExpResult **argv, CamelFold
 					truth = TRUE;
 					for (j=0;j<words->len && truth;j++) {
 						if (message) {
-							for (raw_header = camel_mime_part_get_raw_headers (CAMEL_MIME_PART (message)); raw_header; raw_header = raw_header->next) {
-								if (!g_ascii_strcasecmp (raw_header->name, headername)) {
-									if (camel_search_header_match (raw_header->value, words->words[j]->word, how, type, charset))
+							CamelMimePart *mime_part;
+							GQueue *header_queue;
+							GList *link;
+
+							mime_part = CAMEL_MIME_PART (message);
+							header_queue = camel_mime_part_get_raw_headers (mime_part);
+							link = g_queue_peek_head_link (header_queue);
+
+							while (link != NULL) {
+								CamelHeaderRaw *raw_header = link->data;
+								const gchar *name, *value;
+
+								name = camel_header_raw_get_name (raw_header);
+								value = camel_header_raw_get_value (raw_header);
+
+								if (!g_ascii_strcasecmp (name, headername)) {
+									if (camel_search_header_match (value, words->words[j]->word, how, type, charset))
 										break;;
 								}
+
+								link = g_list_next (link);
 							}
 
-							truth = raw_header != NULL;
+							truth = (link != NULL);
 						} else
 							truth = camel_search_header_match(header, words->words[j]->word, how, type, charset);
 					}
 					camel_search_words_free(words);
 				} else {
 					if (message) {
-						for (raw_header = camel_mime_part_get_raw_headers (CAMEL_MIME_PART (message)); raw_header && !truth; raw_header = raw_header->next) {
-							if (!g_ascii_strcasecmp (raw_header->name, headername)) {
-								truth = camel_search_header_match(raw_header->value, argv[i]->value.string, how, type, charset);
+						CamelMimePart *mime_part;
+						GQueue *header_queue;
+						GList *link;
+
+						mime_part = CAMEL_MIME_PART (message);
+						header_queue = camel_mime_part_get_raw_headers (mime_part);
+						link = g_queue_peek_head_link (header_queue);
+
+						while (link != NULL) {
+							CamelHeaderRaw *raw_header = link->data;
+							const gchar *name, *value;
+
+							name = camel_header_raw_get_name (raw_header);
+							value = camel_header_raw_get_value (raw_header);
+
+							if (!g_ascii_strcasecmp (name, headername)) {
+								truth = camel_search_header_match(value, argv[i]->value.string, how, type, charset);
 							}
+
+							link = g_list_next (link);
 						}
 					} else
 						truth = camel_search_header_match(header, argv[i]->value.string, how, type, charset);
@@ -1227,20 +1258,33 @@ search_header_regex (struct _ESExp *f, gint argc, struct _ESExpResult **argv, Ca
 static gchar *
 get_full_header (CamelMimeMessage *message)
 {
-	CamelMimePart *mp = CAMEL_MIME_PART (message);
+	CamelMimePart *mime_part;
 	GString *str = g_string_new ("");
-	struct _camel_header_raw *h;
+	GQueue *header_queue;
+	GList *link;
+
+	mime_part = CAMEL_MIME_PART (message);
+	header_queue = camel_mime_part_get_raw_headers (mime_part);
+	link = g_queue_peek_head_link (header_queue);
 
-	for (h = camel_mime_part_get_raw_headers (mp); h; h = h->next) {
-		if (h->value != NULL) {
-			g_string_append (str, h->name);
-			if (isspace (h->value[0]))
+	while (link != NULL) {
+		CamelHeaderRaw *raw_header = link->data;
+		const gchar *name, *value;
+
+		name = camel_header_raw_get_name (raw_header);
+		value = camel_header_raw_get_value (raw_header);
+
+		if (value != NULL) {
+			g_string_append (str, name);
+			if (isspace (value[0]))
 				g_string_append (str, ":");
 			else
 				g_string_append (str, ": ");
-			g_string_append (str, h->value);
+			g_string_append (str, value);
 			g_string_append_c (str, '\n');
 		}
+
+		link = g_list_next (link);
 	}
 
 	return g_string_free (str, FALSE);
diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c
index 3229017..3aea9fb 100644
--- a/camel/camel-folder-summary.c
+++ b/camel/camel-folder-summary.c
@@ -115,7 +115,7 @@ static gint summary_meta_header_load(CamelFolderSummary *, FILE *);
 static gint summary_meta_header_save(CamelFolderSummary *, FILE *);
 #endif
 
-static CamelMessageInfo * message_info_new_from_header(CamelFolderSummary *, struct _camel_header_raw *);
+static CamelMessageInfo * message_info_new_from_header(CamelFolderSummary *, GQueue *header_queue);
 static CamelMessageInfo * message_info_new_from_parser(CamelFolderSummary *, CamelMimeParser *);
 static CamelMessageInfo * message_info_new_from_message(CamelFolderSummary *s, CamelMimeMessage *msg, const gchar *bodystructure);
 static CamelMessageInfo * message_info_load(CamelFolderSummary *, FILE *);
@@ -123,7 +123,7 @@ static gint		  message_info_save(CamelFolderSummary *, FILE *, CamelMessageInfo
 static gint		  meta_message_info_save(CamelFolderSummary *s, FILE *out_meta, FILE *out, CamelMessageInfo *info);
 static void		  message_info_free(CamelFolderSummary *, CamelMessageInfo *);
 
-static CamelMessageContentInfo * content_info_new_from_header(CamelFolderSummary *, struct _camel_header_raw *);
+static CamelMessageContentInfo * content_info_new_from_header(CamelFolderSummary *, GQueue *raw_headers);
 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 *);
@@ -2748,12 +2748,20 @@ update_summary (CamelFolderSummary *summary, CamelMessageInfoBase *info)
  * Returns: the newly added record
  **/
 CamelMessageInfo *
-camel_folder_summary_add_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
+camel_folder_summary_add_from_header (CamelFolderSummary *summary,
+                                      GQueue *header_queue)
 {
-	CamelMessageInfo *info = camel_folder_summary_info_new_from_header(s, h);
+	CamelMessageInfo *info;
+
+	g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), NULL);
+	g_return_val_if_fail (header_queue != NULL, NULL);
+
+	info = camel_folder_summary_info_new_from_header (
+		summary, header_queue);
+
+	camel_folder_summary_add (summary, info);
+	update_summary (summary, (CamelMessageInfoBase *) info);
 
-	camel_folder_summary_add (s, info);
-	update_summary (s, (CamelMessageInfoBase *) info);
 	return info;
 }
 
@@ -2815,9 +2823,18 @@ camel_folder_summary_add_from_message (CamelFolderSummary *s, CamelMimeMessage *
  * #camel_message_info_free
  **/
 CamelMessageInfo *
-camel_folder_summary_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
+camel_folder_summary_info_new_from_header (CamelFolderSummary *summary,
+                                           GQueue *header_queue)
 {
-	return CAMEL_FOLDER_SUMMARY_GET_CLASS (s)->message_info_new_from_header (s, h);
+	CamelFolderSummaryClass *class;
+
+	g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), NULL);
+	g_return_val_if_fail (header_queue != NULL, NULL);
+
+	class = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary);
+	g_return_val_if_fail (class->message_info_new_from_header != NULL, NULL);
+
+	return class->message_info_new_from_header (summary, header_queue);
 }
 
 /**
@@ -3594,35 +3611,39 @@ content_info_new_from_parser(CamelFolderSummary *s, CamelMimeParser *mp)
 static CamelMessageInfo *
 message_info_new_from_message(CamelFolderSummary *s, CamelMimeMessage *msg, const gchar *bodystructure)
 {
+	CamelMimePart *mime_part;
 	CamelMessageInfo *mi;
-	struct _camel_header_raw *headers;
+	GQueue *header_queue;
 
-	headers = camel_mime_part_get_raw_headers (CAMEL_MIME_PART (msg));
-	mi = CAMEL_FOLDER_SUMMARY_GET_CLASS (s)->message_info_new_from_header (s, headers);
+	mime_part = CAMEL_MIME_PART (msg);
+	header_queue = camel_mime_part_get_raw_headers (mime_part);
+	mi = CAMEL_FOLDER_SUMMARY_GET_CLASS (s)->message_info_new_from_header (s, header_queue);
 	((CamelMessageInfoBase *)mi)->bodystructure = g_strdup (bodystructure);
 
 	return mi;
 }
 
 static CamelMessageContentInfo *
-content_info_new_from_message(CamelFolderSummary *s, CamelMimePart *mp)
+content_info_new_from_message(CamelFolderSummary *s, CamelMimePart *mime_part)
 {
 	CamelMessageContentInfo *ci;
-	struct _camel_header_raw *headers;
+	GQueue *header_queue;
 
-	headers = camel_mime_part_get_raw_headers (mp);
-	ci = CAMEL_FOLDER_SUMMARY_GET_CLASS (s)->content_info_new_from_header (s, headers);
+	header_queue = camel_mime_part_get_raw_headers (mime_part);
+	ci = CAMEL_FOLDER_SUMMARY_GET_CLASS (s)->content_info_new_from_header (s, header_queue);
 
 	return ci;
 }
 
 static gchar *
-summary_format_address(struct _camel_header_raw *h, const gchar *name, const gchar *charset)
+summary_format_address (GQueue *header_queue,
+                        const gchar *header_name,
+                        const gchar *charset)
 {
 	struct _camel_header_address *addr;
 	gchar *text, *str;
 
-	if (!(text = (gchar *) camel_header_raw_find (&h, name, NULL)))
+	if (!(text = (gchar *) camel_header_raw_find (header_queue, header_name, NULL)))
 		return NULL;
 
 	while (isspace ((unsigned) *text))
@@ -3642,11 +3663,13 @@ summary_format_address(struct _camel_header_raw *h, const gchar *name, const gch
 }
 
 static gchar *
-summary_format_string (struct _camel_header_raw *h, const gchar *name, const gchar *charset)
+summary_format_string (GQueue *header_queue,
+                       const gchar *header_name,
+                       const gchar *charset)
 {
 	gchar *text, *str;
 
-	if (!(text = (gchar *) camel_header_raw_find (&h, name, NULL)))
+	if (!(text = (gchar *) camel_header_raw_find (header_queue, header_name, NULL)))
 		return NULL;
 
 	while (isspace ((unsigned) *text))
@@ -3692,7 +3715,8 @@ camel_folder_summary_content_info_new(CamelFolderSummary *s)
 }
 
 static CamelMessageInfo *
-message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
+message_info_new_from_header (CamelFolderSummary *s,
+                              GQueue *header_queue)
 {
 	const gchar *received, *date, *content, *charset = NULL;
 	struct _camel_header_references *refs, *irt, *scan;
@@ -3709,7 +3733,7 @@ message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
 
 	mi = (CamelMessageInfoBase *)camel_message_info_new(s);
 
-	if ((content = camel_header_raw_find(&h, "Content-Type", NULL))
+	if ((content = camel_header_raw_find(header_queue, "Content-Type", NULL))
 	     && (ct = camel_content_type_decode(content))
 	     && (charset = camel_content_type_param(ct, "charset"))
 	     && (g_ascii_strcasecmp(charset, "us-ascii") == 0))
@@ -3717,11 +3741,11 @@ message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
 
 	charset = charset ? camel_iconv_charset_name (charset) : NULL;
 
-	subject = summary_format_string(h, "subject", charset);
-	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);
+	subject = summary_format_string(header_queue, "subject", charset);
+	from = summary_format_address(header_queue, "from", charset);
+	to = summary_format_address(header_queue, "to", charset);
+	cc = summary_format_address(header_queue, "cc", charset);
+	mlist = camel_header_raw_check_mailing_list(header_queue);
 
 	if (ct)
 		camel_content_type_unref(ct);
@@ -3735,12 +3759,12 @@ message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
 	mi->user_flags = NULL;
 	mi->user_tags = NULL;
 
-	if ((date = camel_header_raw_find (&h, "date", NULL)))
+	if ((date = camel_header_raw_find (header_queue, "date", NULL)))
 		mi->date_sent = camel_header_decode_date (date, NULL);
 	else
 		mi->date_sent = 0;
 
-	received = camel_header_raw_find(&h, "received", NULL);
+	received = camel_header_raw_find(header_queue, "received", NULL);
 	if (received)
 		received = strrchr(received, ';');
 	if (received)
@@ -3748,7 +3772,7 @@ message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
 	else
 		mi->date_received = 0;
 
-	msgid = camel_header_msgid_decode(camel_header_raw_find(&h, "message-id", NULL));
+	msgid = camel_header_msgid_decode(camel_header_raw_find(header_queue, "message-id", NULL));
 	if (msgid) {
 		GChecksum *checksum;
 
@@ -3762,8 +3786,8 @@ message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
 	}
 
 	/* 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));
+	refs = camel_header_references_decode (camel_header_raw_find (header_queue, "references", NULL));
+	irt = camel_header_references_inreplyto_decode (camel_header_raw_find (header_queue, "in-reply-to", NULL));
 	if (refs || irt) {
 		if (irt) {
 			/* The References field is populated from the "References" and/or "In-Reply-To"
@@ -3996,18 +4020,33 @@ message_info_free(CamelFolderSummary *s, CamelMessageInfo *info)
 }
 
 static CamelMessageContentInfo *
-content_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
+content_info_new_from_header (CamelFolderSummary *s,
+                              GQueue *header_queue)
 {
 	CamelMessageContentInfo *ci;
 	const gchar *charset;
+	const gchar *header_name;
+	const gchar *header_value;
 
 	ci = camel_folder_summary_content_info_new (s);
 
 	charset = camel_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->type = camel_content_type_decode(camel_header_raw_find(&h, "content-type", NULL));
+
+	header_name = "content-id";
+	header_value = camel_header_raw_find (header_queue, header_name, NULL);
+	ci->id = camel_header_msgid_decode (header_value);
+
+	header_name = "content-description";
+	header_value = camel_header_raw_find (header_queue, header_name, NULL);
+	ci->description = camel_header_decode_string (header_value, charset);
+
+	header_name = "content-transfer-encoding";
+	header_value = camel_header_raw_find (header_queue, header_name, NULL);
+	ci->encoding = camel_content_transfer_encoding_decode (header_value);
+
+	header_name = "content-type";
+	header_value = camel_header_raw_find (header_queue, header_name, NULL);
+	ci->type = camel_content_type_decode (header_value);
 
 	return ci;
 }
@@ -4299,7 +4338,8 @@ summary_build_content_info_message(CamelFolderSummary *s, CamelMessageInfo *msgi
 	struct _CamelFolderSummaryPrivate *p = CAMEL_FOLDER_SUMMARY_GET_PRIVATE(s);
 	CamelMessageContentInfo *info = NULL, *child;
 	CamelContentType *ct;
-	const struct _camel_header_raw *header;
+	GQueue *header_queue;
+	GList *link;
 
 	if (s->build_content)
 		info = CAMEL_FOLDER_SUMMARY_GET_CLASS (s)->content_info_new_from_message (s, object);
@@ -4329,21 +4369,29 @@ summary_build_content_info_message(CamelFolderSummary *s, CamelMessageInfo *msgi
 		camel_message_info_set_flags(msginfo, CAMEL_MESSAGE_SECURE, CAMEL_MESSAGE_SECURE);
 	}
 
-	header = camel_mime_part_get_raw_headers (object);
-	for (; header; header = header->next) {
-		const gchar *value = header->value;
+	header_queue = camel_mime_part_get_raw_headers (object);
+	link = g_queue_peek_head_link (header_queue);
+
+	while (link != NULL) {
+		CamelHeaderRaw *raw_header = link->data;
+		const gchar *name, *value;
+
+		name = camel_header_raw_get_name (raw_header);
+		value = camel_header_raw_get_value (raw_header);
 
 		/* skip preceding spaces in the value */
 		while (value && *value && isspace (*value))
 			value++;
 
-		if (header->name && value && (
-		    (g_ascii_strcasecmp (header->name, "Content-class") == 0 && g_ascii_strcasecmp (value, "urn:content-classes:calendarmessage") == 0) ||
-		    (g_ascii_strcasecmp (header->name, "X-Calendar-Attachment") == 0)))
+		if (name && value && (
+		    (g_ascii_strcasecmp (name, "Content-class") == 0 && g_ascii_strcasecmp (value, "urn:content-classes:calendarmessage") == 0) ||
+		    (g_ascii_strcasecmp (name, "X-Calendar-Attachment") == 0)))
 			break;
+
+		link = g_list_next (link);
 	}
 
-	if (header || camel_content_type_is (ct, "text", "calendar"))
+	if (link != NULL || camel_content_type_is (ct, "text", "calendar"))
 		camel_message_info_set_user_flag (msginfo, "$has_cal", TRUE);
 
 	/* using the object types is more accurate than using the mime/types */
@@ -4834,12 +4882,14 @@ camel_message_info_ref(gpointer o)
  * Returns: a new #CamelMessageInfo
  **/
 CamelMessageInfo *
-camel_message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *header)
+camel_message_info_new_from_header (CamelFolderSummary *summary,
+                                    GQueue *header_queue)
 {
-	if (s)
-		return CAMEL_FOLDER_SUMMARY_GET_CLASS (s)->message_info_new_from_header(s, header);
+	if (summary != NULL)
+		return CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->
+			message_info_new_from_header (summary, header_queue);
 	else
-		return message_info_new_from_header(NULL, header);
+		return message_info_new_from_header (NULL, header_queue);
 }
 
 /**
diff --git a/camel/camel-folder-summary.h b/camel/camel-folder-summary.h
index f2d7a6a..530b990 100644
--- a/camel/camel-folder-summary.h
+++ b/camel/camel-folder-summary.h
@@ -296,7 +296,7 @@ struct _CamelFolderSummaryClass {
 	gint (*content_info_to_db) (CamelFolderSummary *, CamelMessageContentInfo *, struct _CamelMIRecord *);
 
 	/* create/save/load an individual message info */
-	CamelMessageInfo * (*message_info_new_from_header)(CamelFolderSummary *, struct _camel_header_raw *);
+	CamelMessageInfo * (*message_info_new_from_header)(CamelFolderSummary *, GQueue *);
 	CamelMessageInfo * (*message_info_new_from_parser)(CamelFolderSummary *, CamelMimeParser *);
 	CamelMessageInfo * (*message_info_new_from_message)(CamelFolderSummary *, CamelMimeMessage *, const gchar *);
 	CamelMessageInfo * (*message_info_load)(CamelFolderSummary *, FILE *);
@@ -307,7 +307,7 @@ struct _CamelFolderSummaryClass {
 	CamelMessageInfo * (*message_info_clone)(CamelFolderSummary *, const CamelMessageInfo *);
 
 	/* save/load individual content info's */
-	CamelMessageContentInfo * (*content_info_new_from_header)(CamelFolderSummary *, struct _camel_header_raw *);
+	CamelMessageContentInfo * (*content_info_new_from_header)(CamelFolderSummary *, GQueue *);
 	CamelMessageContentInfo * (*content_info_new_from_parser)(CamelFolderSummary *, CamelMimeParser *);
 	CamelMessageContentInfo * (*content_info_new_from_message)(CamelFolderSummary *, CamelMimePart *);
 	CamelMessageContentInfo * (*content_info_load)(CamelFolderSummary *, FILE *);
@@ -396,12 +396,12 @@ void camel_folder_summary_remove_index_fast (CamelFolderSummary *s, gint index);
 void camel_folder_summary_remove_uid_fast (CamelFolderSummary *s, const gchar *uid);
 
 /* build/add raw summary items */
-CamelMessageInfo *camel_folder_summary_add_from_header(CamelFolderSummary *summary, struct _camel_header_raw *headers);
+CamelMessageInfo *camel_folder_summary_add_from_header(CamelFolderSummary *summary, GQueue *header_queue);
 CamelMessageInfo *camel_folder_summary_add_from_parser(CamelFolderSummary *summary, CamelMimeParser *parser);
 CamelMessageInfo *camel_folder_summary_add_from_message(CamelFolderSummary *summary, CamelMimeMessage *message);
 
 /* Just build raw summary items */
-CamelMessageInfo *camel_folder_summary_info_new_from_header(CamelFolderSummary *summary, struct _camel_header_raw *headers);
+CamelMessageInfo *camel_folder_summary_info_new_from_header(CamelFolderSummary *summary, GQueue *header_queue);
 CamelMessageInfo *camel_folder_summary_info_new_from_parser(CamelFolderSummary *summary, CamelMimeParser *parser);
 CamelMessageInfo *camel_folder_summary_info_new_from_message(CamelFolderSummary *summary, CamelMimeMessage *message, const gchar *bodystructure);
 
@@ -456,7 +456,7 @@ void		camel_tag_list_free(CamelTag **list);
 /* Use anonymous pointers to avoid tons of cast crap */
 gpointer camel_message_info_new(CamelFolderSummary *summary);
 void camel_message_info_ref(gpointer info);
-CamelMessageInfo *camel_message_info_new_from_header(CamelFolderSummary *summary, struct _camel_header_raw *header);
+CamelMessageInfo *camel_message_info_new_from_header(CamelFolderSummary *summary, GQueue *header_queue);
 void camel_message_info_free(gpointer info);
 gpointer camel_message_info_clone(gconstpointer info);
 
diff --git a/camel/camel-folder.c b/camel/camel-folder.c
index d63782d..72433e3 100644
--- a/camel/camel-folder.c
+++ b/camel/camel-folder.c
@@ -1736,10 +1736,12 @@ transfer_message_to (CamelFolder *source, const gchar *uid, CamelFolder *dest,
 		info = camel_message_info_clone (minfo);
 		camel_folder_free_message_info (source, minfo);
 	} else {
-		struct _camel_header_raw *headers;
+		CamelMimePart *mime_part;
+		GQueue *header_queue;
 
-		headers = camel_mime_part_get_raw_headers (CAMEL_MIME_PART (msg));
-		info = camel_message_info_new_from_header (NULL, headers);
+		mime_part = CAMEL_MIME_PART (msg);
+		header_queue = camel_mime_part_get_raw_headers (mime_part);
+		info = camel_message_info_new_from_header (NULL, header_queue);
 	}
 
 	/* we don't want to retain the deleted flag */
diff --git a/camel/camel-http-stream.c b/camel/camel-http-stream.c
index bd54578..329b488 100644
--- a/camel/camel-http-stream.c
+++ b/camel/camel-http-stream.c
@@ -68,11 +68,6 @@ http_stream_dispose (GObject *object)
 		http->content_type = NULL;
 	}
 
-	if (http->headers != NULL) {
-		camel_header_raw_clear (&http->headers);
-		http->headers = NULL;
-	}
-
 	if (http->session != NULL) {
 		g_object_unref (http->session);
 		http->session = NULL;
@@ -97,6 +92,9 @@ http_stream_finalize (GObject *object)
 {
 	CamelHttpStream *http = CAMEL_HTTP_STREAM (object);
 
+	camel_header_raw_clear (http->raw_headers);
+	g_queue_free (http->raw_headers);
+
 	if (http->url != NULL)
 		camel_url_free (http->url);
 
@@ -133,16 +131,7 @@ http_stream_class_init (CamelHttpStreamClass *class)
 static void
 http_stream_init (CamelHttpStream *http)
 {
-	http->parser = NULL;
-	http->content_type = NULL;
-	http->headers = NULL;
-	http->session = NULL;
-	http->url = NULL;
-	http->proxy = NULL;
-	http->authrealm = NULL;
-	http->authpass = NULL;
-	http->statuscode = 0;
-	http->raw = NULL;
+	http->raw_headers = g_queue_new ();
 }
 
 GType
@@ -307,7 +296,8 @@ http_get_statuscode (CamelHttpStream *http)
 static gint
 http_get_headers (CamelHttpStream *http)
 {
-	struct _camel_header_raw *headers, *node, *tail;
+	GQueue *header_queue;
+	GList *link;
 	const gchar *type;
 	gchar *buf;
 	gsize len;
@@ -322,32 +312,31 @@ http_get_headers (CamelHttpStream *http)
 	switch (camel_mime_parser_step (http->parser, &buf, &len)) {
 	case CAMEL_MIME_PARSER_STATE_MESSAGE:
 	case CAMEL_MIME_PARSER_STATE_HEADER:
-		headers = camel_mime_parser_headers_raw (http->parser);
+		header_queue = camel_mime_parser_headers_raw (http->parser);
 		if (http->content_type)
 			camel_content_type_unref (http->content_type);
-		type = camel_header_raw_find (&headers, "Content-Type", NULL);
+		type = camel_header_raw_find (header_queue, "Content-Type", NULL);
 		if (type)
 			http->content_type = camel_content_type_decode (type);
 		else
 			http->content_type = NULL;
 
-		if (http->headers)
-			camel_header_raw_clear (&http->headers);
+		camel_header_raw_clear (http->raw_headers);
 
-		http->headers = NULL;
-		tail = (struct _camel_header_raw *) &http->headers;
+		link = g_queue_peek_head_link (header_queue);
 
 		d(printf("HTTP Headers:\n"));
-		while (headers) {
-			d(printf(" %s:%s\n", headers->name, headers->value));
-			node = g_new (struct _camel_header_raw, 1);
-			node->next = NULL;
-			node->name = g_strdup (headers->name);
-			node->value = g_strdup (headers->value);
-			node->offset = headers->offset;
-			tail->next = node;
-			tail = node;
-			headers = headers->next;
+		while (link != NULL) {
+			CamelHeaderRaw *raw_header = link->data;
+
+			d(printf(" %s:%s\n", name, value));
+			camel_header_raw_append (
+				http->raw_headers,
+				camel_header_raw_get_name (raw_header),
+				camel_header_raw_get_value (raw_header),
+				camel_header_raw_get_offset (raw_header));
+
+			link = g_list_next (link);
 		}
 
 		break;
@@ -491,9 +480,9 @@ stream_read (CamelStream *stream, gchar *buffer, gsize n)
 			http->content_type = NULL;
 			http_disconnect(http);
 
-			loc = g_strdup(camel_header_raw_find(&http->headers, "Location", NULL));
+			loc = g_strdup(camel_header_raw_find(http->raw_headers, "Location", NULL));
 			if (loc == NULL) {
-				camel_header_raw_clear(&http->headers);
+				camel_header_raw_clear(http->raw_headers);
 				return -1;
 			}
 
@@ -507,11 +496,11 @@ stream_read (CamelStream *stream, gchar *buffer, gsize n)
 				http->url = camel_url_new(loc, NULL);
 			g_free(loc);
 			if (http->url == NULL) {
-				camel_header_raw_clear (&http->headers);
+				camel_header_raw_clear (http->raw_headers);
 				return -1;
 			}
 			d(printf(" redirect url = %p\n", http->url));
-			camel_header_raw_clear (&http->headers);
+			camel_header_raw_clear (http->raw_headers);
 
 			goto redirect;
 			break; }
diff --git a/camel/camel-http-stream.h b/camel/camel-http-stream.h
index 77dbc28..5458b18 100644
--- a/camel/camel-http-stream.h
+++ b/camel/camel-http-stream.h
@@ -72,7 +72,7 @@ struct _CamelHttpStream {
 	CamelMimeParser *parser;
 
 	CamelContentType *content_type;
-	struct _camel_header_raw *headers;
+	GQueue *raw_headers;
 
 	CamelHttpMethod method;
 	struct _CamelSession *session;
diff --git a/camel/camel-mime-filter-linewrap.c b/camel/camel-mime-filter-linewrap.c
index 0efb331..2bd2d9e 100644
--- a/camel/camel-mime-filter-linewrap.c
+++ b/camel/camel-mime-filter-linewrap.c
@@ -217,7 +217,9 @@ camel_mime_filter_linewrap_new (guint preferred_len,
 	priv->wrap_len = preferred_len;
 	priv->max_len = max_len;
 	priv->nchars = 0;
-	priv->flags = flags | (indent_char == 0 ? CAMEL_MIME_FILTER_LINEWRAP_NOINDENT : 0);
+
+	if (indent_char == 0)
+		priv->flags |= CAMEL_MIME_FILTER_LINEWRAP_NOINDENT;
 
 	return filter;
 }
diff --git a/camel/camel-mime-message.c b/camel/camel-mime-message.c
index b6fa193..71fad18 100644
--- a/camel/camel-mime-message.c
+++ b/camel/camel-mime-message.c
@@ -1128,7 +1128,8 @@ static const gchar tz_days[][4] = {
 gchar *
 camel_mime_message_build_mbox_from (CamelMimeMessage *message)
 {
-	struct _camel_header_raw *header;
+	CamelMimePart *mime_part;
+	GQueue *header_queue;
 	GString *out = g_string_new("From ");
 	gchar *ret;
 	const gchar *tmp;
@@ -1136,11 +1137,12 @@ camel_mime_message_build_mbox_from (CamelMimeMessage *message)
 	gint offset;
 	struct tm tm;
 
-	header = camel_mime_part_get_raw_headers (CAMEL_MIME_PART (message));
+	mime_part = CAMEL_MIME_PART (message);
+	header_queue = camel_mime_part_get_raw_headers (mime_part);
 
-	tmp = camel_header_raw_find (&header, "Sender", NULL);
+	tmp = camel_header_raw_find (header_queue, "Sender", NULL);
 	if (tmp == NULL)
-		tmp = camel_header_raw_find (&header, "From", NULL);
+		tmp = camel_header_raw_find (header_queue, "From", NULL);
 	if (tmp != NULL) {
 		struct _camel_header_address *addr = camel_header_address_decode (tmp, NULL);
 
@@ -1158,7 +1160,7 @@ camel_mime_message_build_mbox_from (CamelMimeMessage *message)
 		g_string_append (out, "unknown nodomain now au");
 
 	/* try use the received header to get the date */
-	tmp = camel_header_raw_find (&header, "Received", NULL);
+	tmp = camel_header_raw_find (header_queue, "Received", NULL);
 	if (tmp) {
 		tmp = strrchr(tmp, ';');
 		if (tmp)
@@ -1167,7 +1169,7 @@ camel_mime_message_build_mbox_from (CamelMimeMessage *message)
 
 	/* if there isn't one, try the Date field */
 	if (tmp == NULL)
-		tmp = camel_header_raw_find (&header, "Date", NULL);
+		tmp = camel_header_raw_find (header_queue, "Date", NULL);
 
 	thetime = camel_header_decode_date (tmp, &offset);
 	thetime += ((offset / 100) * (60 * 60)) + (offset % 100) * 60;
diff --git a/camel/camel-mime-parser.c b/camel/camel-mime-parser.c
index d528234..bc2f2db 100644
--- a/camel/camel-mime-parser.c
+++ b/camel/camel-mime-parser.c
@@ -33,8 +33,6 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 
-#include <libedataserver/e-memory.h>
-
 #include "camel-mime-filter.h"
 #include "camel-mime-parser.h"
 #include "camel-mime-utils.h"
@@ -51,8 +49,6 @@
 
 /*#define PURIFY*/
 
-#define MEMPOOL
-
 #ifdef PURIFY
 gint inend_id = -1,
   inbuffer_id = -1;
@@ -117,10 +113,7 @@ struct _header_scan_stack {
 
 	camel_mime_parser_state_t savestate; /* state at invocation of this part */
 
-#ifdef MEMPOOL
-	EMemPool *pool;		/* memory pool to keep track of headers/etc at this level */
-#endif
-	struct _camel_header_raw *headers;	/* headers for this part */
+	GQueue *raw_headers;	/* headers for this part */
 
 	CamelContentType *content_type;
 
@@ -157,10 +150,6 @@ static off_t folder_tell(struct _header_scan_state *s);
 static gint folder_read(struct _header_scan_state *s);
 static void folder_push_part(struct _header_scan_state *s, struct _header_scan_stack *h);
 
-#ifdef MEMPOOL
-static void header_append_mempool(struct _header_scan_state *s, struct _header_scan_stack *h, gchar *header, gint offset);
-#endif
-
 static void mime_parser_class_init (CamelMimeParserClass *class);
 static void mime_parser_init       (CamelMimeParser *obj);
 
@@ -334,11 +323,10 @@ camel_mime_parser_header(CamelMimeParser *m, const gchar *name, gint *offset)
 {
 	struct _header_scan_state *s = _PRIVATE(m);
 
-	if (s->parts &&
-	    s->parts->headers) {
-		return camel_header_raw_find(&s->parts->headers, name, offset);
-	}
-	return NULL;
+	if (s->parts == NULL)
+		return NULL;
+
+	return camel_header_raw_find (s->parts->raw_headers, name, offset);
 }
 
 /**
@@ -352,13 +340,14 @@ camel_mime_parser_header(CamelMimeParser *m, const gchar *name, gint *offset)
  * Return value: The raw headers, or NULL if there are no headers
  * defined for the current part or state.  These are READ ONLY.
  **/
-struct _camel_header_raw *
+GQueue *
 camel_mime_parser_headers_raw(CamelMimeParser *m)
 {
 	struct _header_scan_state *s = _PRIVATE(m);
 
 	if (s->parts)
-		return s->parts->headers;
+		return s->parts->raw_headers;
+
 	return NULL;
 }
 
@@ -1001,11 +990,10 @@ folder_pull_part(struct _header_scan_state *s)
 	if (h) {
 		s->parts = h->parent;
 		g_free(h->boundary);
-#ifdef MEMPOOL
-		e_mempool_destroy(h->pool);
-#else
-		camel_header_raw_clear(&h->headers);
-#endif
+
+		camel_header_raw_clear(h->raw_headers);
+		g_queue_free (h->raw_headers);
+
 		camel_content_type_unref(h->content_type);
 		if (h->pretext)
 			g_byte_array_free(h->pretext, TRUE);
@@ -1100,46 +1088,24 @@ folder_boundary_check(struct _header_scan_state *s, const gchar *boundary, gint
 	return NULL;
 }
 
-#ifdef MEMPOOL
 static void
-header_append_mempool(struct _header_scan_state *s, struct _header_scan_stack *h, gchar *header, gint offset)
+header_raw_append_parse (GQueue *header_queue,
+                         gchar *header,
+                         gint offset)
 {
-	struct _camel_header_raw *l, *n;
-	gchar *content;
-
-	content = strchr(header, ':');
-	if (content) {
-		register gint len;
-		n = e_mempool_alloc(h->pool, sizeof(*n));
-		n->next = NULL;
-
-		len = content-header;
-		n->name = e_mempool_alloc(h->pool, len+1);
-		memcpy(n->name, header, len);
-		n->name[len] = 0;
-
-		content++;
-
-		len = s->outptr - content;
-		n->value = e_mempool_alloc(h->pool, len+1);
-		memcpy(n->value, content, len);
-		n->value[len] = 0;
+	gchar *colon;
 
-		n->offset = offset;
+	colon = strchr (header, ':');
+	if (colon != NULL) {
+		const gchar *name = header;
+		const gchar *value = colon + 1;
 
-		l = (struct _camel_header_raw *)&h->headers;
-		while (l->next) {
-			l = l->next;
-		}
-		l->next = n;
+		*colon = '\0';
+		camel_header_raw_append (header_queue, name, value, offset);
+		*colon = ':';
 	}
-
 }
 
-#define header_raw_append_parse(a, b, c) (header_append_mempool(s, h, b, c))
-
-#endif
-
 /* Copy the string start->inptr into the header buffer (s->outbuf),
    grow if necessary
    remove trailing \r chars (\n's assumed already removed)
@@ -1180,9 +1146,7 @@ folder_scan_header(struct _header_scan_state *s, gint *lastone)
 	h(printf("scanning first bit\n"));
 
 	h = g_malloc0(sizeof(*h));
-#ifdef MEMPOOL
-	h->pool = e_mempool_new(8192, 4096, E_MEMPOOL_ALIGN_STRUCT);
-#endif
+	h->raw_headers = g_queue_new ();
 
 	if (s->parts)
 		newatleast = s->parts->atleast;
@@ -1258,7 +1222,7 @@ folder_scan_header(struct _header_scan_state *s, gint *lastone)
 
 						h(printf("header '%s' at %d\n", s->outbuf, (gint)s->header_start));
 
-						header_raw_append_parse(&h->headers, s->outbuf, s->header_start);
+						header_raw_append_parse(h->raw_headers, s->outbuf, s->header_start);
 						s->outptr = s->outbuf;
 						s->header_start = -1;
 					}
@@ -1291,7 +1255,7 @@ header_truncated:
 	if (s->outbuf == s->outptr)
 		goto header_done;
 
-	header_raw_append_parse(&h->headers, s->outbuf, s->header_start);
+	header_raw_append_parse(h->raw_headers, s->outbuf, s->header_start);
 
 	s->outptr = s->outbuf;
 header_done:
@@ -1605,7 +1569,7 @@ tail_recurse:
 		/* FIXME: should this check for MIME-Version: 1.0 as well? */
 
 		type = CAMEL_MIME_PARSER_STATE_HEADER;
-		if ( (content = camel_header_raw_find(&h->headers, "Content-Type", NULL))
+		if ((content = camel_header_raw_find(h->raw_headers, "Content-Type", NULL))
 		     && (ct = camel_content_type_decode(content))) {
 			if (!g_ascii_strcasecmp(ct->type, "multipart")) {
 				if (!camel_content_type_is(ct, "multipart", "signed")
@@ -1620,7 +1584,8 @@ tail_recurse:
 					/*camel_content_type_unref(ct);
 					  ct = camel_content_type_decode("text/plain");*/
 /* We can't quite do this, as it will mess up all the offsets ... */
-/*					camel_header_raw_replace(&h->headers, "Content-Type", "text/plain", offset);*/
+/*					camel_header_raw_remove (&h->headers, "Content-Type");
+ *					camel_header_raw_append (&h->headers, "Content-Type", "text/plain", offset); */
 					/*g_warning("Multipart with no boundary, treating as text/plain");*/
 				}
 			} else if (!g_ascii_strcasecmp(ct->type, "message")) {
diff --git a/camel/camel-mime-parser.h b/camel/camel-mime-parser.h
index 232b407..8f1528a 100644
--- a/camel/camel-mime-parser.h
+++ b/camel/camel-mime-parser.h
@@ -134,7 +134,7 @@ CamelContentType *camel_mime_parser_content_type (CamelMimeParser *parser);
 const gchar *camel_mime_parser_header (CamelMimeParser *m, const gchar *name, gint *offset);
 
 /* get all raw headers. READ ONLY! */
-struct _camel_header_raw *camel_mime_parser_headers_raw (CamelMimeParser *m);
+GQueue *camel_mime_parser_headers_raw (CamelMimeParser *m);
 
 /* get multipart pre/postface */
 const gchar *camel_mime_parser_preface (CamelMimeParser *m);
diff --git a/camel/camel-mime-part.c b/camel/camel-mime-part.c
index a1389c2..dfc8a17 100644
--- a/camel/camel-mime-part.c
+++ b/camel/camel-mime-part.c
@@ -55,7 +55,7 @@
 
 struct _CamelMimePartPrivate {
 
-	struct _camel_header_raw *headers;  /* mime headers */
+	GQueue *raw_headers;  /* mime headers */
 
 	/* TODO: these should be in a camelcontentinfo */
 	gchar *description;
@@ -115,9 +115,8 @@ static gint             construct_from_parser           (CamelMimePart *mime_par
 static void set_disposition (CamelMimePart *mime_part, const gchar *disposition);
 
 /* format output of headers */
-static gssize write_references(CamelStream *stream, struct _camel_header_raw *h);
-/*static gint write_fold(CamelStream *stream, struct _camel_header_raw *h);*/
-static gssize write_raw(CamelStream *stream, struct _camel_header_raw *h);
+static gssize write_references(CamelStream *stream, CamelHeaderRaw *raw_header);
+static gssize write_raw(CamelStream *stream, CamelHeaderRaw *raw_header);
 
 /* loads in a hash table the set of header names we */
 /* recognize and associate them with a unique enum  */
@@ -266,16 +265,20 @@ mime_part_get_property (GObject *object,
 static void
 mime_part_finalize (GObject *object)
 {
-	CamelMimePart *mime_part = CAMEL_MIME_PART (object);
+	CamelMimePartPrivate *priv;
 
-	g_free (mime_part->priv->description);
-	g_free (mime_part->priv->content_id);
-	g_free (mime_part->priv->content_md5);
-	g_free (mime_part->priv->content_location);
-	camel_string_list_free (mime_part->priv->content_languages);
-	camel_content_disposition_unref (mime_part->priv->disposition);
+	priv = CAMEL_MIME_PART_GET_PRIVATE (object);
 
-	camel_header_raw_clear (&mime_part->priv->headers);
+	g_free (priv->description);
+	g_free (priv->content_id);
+	g_free (priv->content_md5);
+	g_free (priv->content_location);
+
+	camel_string_list_free (priv->content_languages);
+	camel_content_disposition_unref (priv->disposition);
+
+	camel_header_raw_clear (priv->raw_headers);
+	g_queue_free (priv->raw_headers);
 
 	/* Chain up to parent's finalize() method. */
 	G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -360,6 +363,7 @@ mime_part_init (CamelMimePart *mime_part)
 	CamelDataWrapper *data_wrapper;
 
 	mime_part->priv = CAMEL_MIME_PART_GET_PRIVATE (mime_part);
+	mime_part->priv->raw_headers = g_queue_new ();
 	mime_part->priv->encoding = CAMEL_TRANSFER_ENCODING_DEFAULT;
 
 	data_wrapper = CAMEL_DATA_WRAPPER (mime_part);
@@ -448,15 +452,22 @@ static void
 set_header (CamelMedium *medium, const gchar *name, gconstpointer value)
 {
 	CamelMimePart *part = CAMEL_MIME_PART (medium);
+	GQueue *header_queue;
+
+	header_queue = camel_mime_part_get_raw_headers (part);
 
-	process_header(medium, name, value);
-	camel_header_raw_replace(&part->priv->headers, name, value, -1);
+	process_header (medium, name, value);
+	camel_header_raw_remove (header_queue, name);
+	camel_header_raw_append (header_queue, name, value, -1);
 }
 
 static void
 add_header (CamelMedium *medium, const gchar *name, gconstpointer value)
 {
 	CamelMimePart *part = CAMEL_MIME_PART (medium);
+	GQueue *header_queue;
+
+	header_queue = camel_mime_part_get_raw_headers (part);
 
 	/* Try to parse the header pair. If it corresponds to something   */
 	/* known, the job is done in the parsing routine. If not,         */
@@ -464,26 +475,31 @@ add_header (CamelMedium *medium, const gchar *name, gconstpointer value)
 
 	/* If it was one of the headers we handled, it must be unique, set it instead of add */
 	if (process_header(medium, name, value))
-		camel_header_raw_replace(&part->priv->headers, name, value, -1);
-	else
-		camel_header_raw_append(&part->priv->headers, name, value, -1);
+		camel_header_raw_remove (header_queue, name);
+	camel_header_raw_append (header_queue, name, value, -1);
 }
 
 static void
 remove_header (CamelMedium *medium, const gchar *name)
 {
 	CamelMimePart *part = (CamelMimePart *)medium;
+	GQueue *header_queue;
+
+	header_queue = camel_mime_part_get_raw_headers (part);
 
-	process_header(medium, name, NULL);
-	camel_header_raw_remove(&part->priv->headers, name);
+	process_header (medium, name, NULL);
+	camel_header_raw_remove (header_queue, name);
 }
 
 static gconstpointer
 get_header (CamelMedium *medium, const gchar *name)
 {
 	CamelMimePart *part = (CamelMimePart *)medium;
+	GQueue *header_queue;
 
-	return camel_header_raw_find(&part->priv->headers, name, NULL);
+	header_queue = camel_mime_part_get_raw_headers (part);
+
+	return camel_header_raw_find (header_queue, name, NULL);
 }
 
 static GArray *
@@ -492,13 +508,22 @@ get_headers (CamelMedium *medium)
 	CamelMimePart *part = (CamelMimePart *)medium;
 	GArray *headers;
 	CamelMediumHeader header;
-	struct _camel_header_raw *h;
+	GQueue *header_queue;
+	GList *link;
+
+	header_queue = camel_mime_part_get_raw_headers (part);
+	link = g_queue_peek_head_link (header_queue);
 
 	headers = g_array_new (FALSE, FALSE, sizeof (CamelMediumHeader));
-	for (h = part->priv->headers; h; h = h->next) {
-		header.name = h->name;
-		header.value = h->value;
+
+	while (link != NULL) {
+		CamelHeaderRaw *raw_header = link->data;
+
+		header.name = camel_header_raw_get_name (raw_header);
+		header.value = camel_header_raw_get_value (raw_header);
 		g_array_append_val (headers, header);
+
+		link = g_list_next (link);
 	}
 
 	return headers;
@@ -929,12 +954,12 @@ camel_mime_part_get_content_type (CamelMimePart *mime_part)
 	return ((CamelDataWrapper *) mime_part)->mime_type;
 }
 
-struct _camel_header_raw *
+GQueue *
 camel_mime_part_get_raw_headers (CamelMimePart *mime_part)
 {
 	g_return_val_if_fail (CAMEL_IS_MIME_PART (mime_part), NULL);
 
-	return mime_part->priv->headers;
+	return mime_part->priv->raw_headers;
 }
 
 static void
@@ -962,28 +987,33 @@ set_content (CamelMedium *medium,
 /**********************************************************************/
 
 static gssize
-write_references(CamelStream *stream, struct _camel_header_raw *h)
+write_references (CamelStream *stream,
+                  CamelHeaderRaw *raw_header)
 {
 	gssize len, out, total;
-	gchar *v, *ids, *ide;
+	const gchar *ids, *ide;
+	const gchar *name;
+	const gchar *value;
 
 	/* this is only approximate, based on the next >, this way it retains any content
 	   from the original which may not be properly formatted, etc.  It also doesn't handle
 	   the case where an individual messageid is too long, however thats a bad mail to
 	   start with ... */
 
-	v = h->value;
-	len = strlen(h->name)+1;
-	total = camel_stream_printf(stream, "%s%s", h->name, isspace(v[0])?":":": ");
+	name = camel_header_raw_get_name (raw_header);
+	value = camel_header_raw_get_value (raw_header);
+
+	len = strlen(name)+1;
+	total = camel_stream_printf(stream, "%s%s", name, isspace(value[0])?":":": ");
 	if (total == -1)
 		return -1;
-	while (*v) {
-		ids = v;
+	while (*value) {
+		ids = value;
 		ide = strchr(ids+1, '>');
 		if (ide)
-			v = ++ide;
+			value = ++ide;
 		else
-			ide = v = strlen(ids)+ids;
+			ide = value = strlen(ids)+ids;
 
 		if (len>0 && len + (ide - ids) >= CAMEL_FOLD_SIZE) {
 			out = camel_stream_printf(stream, "\n\t");
@@ -1020,11 +1050,18 @@ write_fold(CamelStream *stream, struct _camel_header_raw *h)
 #endif
 
 static gssize
-write_raw(CamelStream *stream, struct _camel_header_raw *h)
+write_raw (CamelStream *stream,
+           CamelHeaderRaw *header_raw)
 {
-	gchar *val = h->value;
+	const gchar *name;
+	const gchar *value;
 
-	return camel_stream_printf(stream, "%s%s%s\n", h->name, isspace(val[0]) ? ":" : ": ", val);
+	name = camel_header_raw_get_name (header_raw);
+	value = camel_header_raw_get_value (header_raw);
+
+	return camel_stream_printf (
+		stream, "%s%s%s\n", name,
+		isspace(value[0]) ? ":" : ": ", value);
 }
 
 static gssize
@@ -1034,6 +1071,7 @@ write_to_stream (CamelDataWrapper *dw, CamelStream *stream)
 	CamelMedium *medium = CAMEL_MEDIUM (dw);
 	CamelStream *ostream = stream;
 	CamelDataWrapper *content;
+	GQueue *header_queue;
 	gssize total = 0;
 	gssize count;
 	gint errnosav;
@@ -1043,29 +1081,40 @@ write_to_stream (CamelDataWrapper *dw, CamelStream *stream)
 	/* FIXME: something needs to be done about this ... */
 	/* TODO: content-languages header? */
 
-	if (mp->priv->headers) {
-		struct _camel_header_raw *h = mp->priv->headers;
-		gchar *val;
-		gssize (*writefn)(CamelStream *stream, struct _camel_header_raw *);
+	header_queue = camel_mime_part_get_raw_headers (mp);
+
+	if (!g_queue_is_empty (header_queue)) {
+		GList *link;
+		gssize (*writefn)(CamelStream *stream, CamelHeaderRaw *);
+
+		link = g_queue_peek_head_link (header_queue);
 
 		/* fold/write the headers.   But dont fold headers that are already formatted
 		   (e.g. ones with parameter-lists, that we know about, and have created) */
-		while (h) {
-			val = h->value;
-			if (val == NULL) {
-				g_warning("h->value is NULL here for %s", h->name);
+		while (link != NULL) {
+			CamelHeaderRaw *raw_header = link->data;
+			const gchar *name, *value;
+
+			name = camel_header_raw_get_name (raw_header);
+			value = camel_header_raw_get_value (raw_header);
+
+			if (value == NULL) {
+				g_warning("value is NULL here for %s", name);
 				count = 0;
-			} else if ((writefn = g_hash_table_lookup(header_formatted_table, h->name)) == NULL) {
-				val = camel_header_fold(val, strlen(h->name));
-				count = camel_stream_printf(stream, "%s%s%s\n", h->name, isspace(val[0]) ? ":" : ": ", val);
-				g_free(val);
+			} else if ((writefn = g_hash_table_lookup(header_formatted_table, name)) == NULL) {
+				gchar *folded;
+
+				folded = camel_header_fold(value, strlen(name));
+				count = camel_stream_printf(stream, "%s%s%s\n", name, isspace(folded[0]) ? ":" : ": ", folded);
+				g_free(folded);
 			} else {
-				count = writefn(stream, h);
+				count = writefn(stream, raw_header);
 			}
 			if (count == -1)
 				return -1;
 			total += count;
-			h = h->next;
+
+			link = g_list_next (link);
 		}
 	}
 
@@ -1189,7 +1238,8 @@ static gint
 construct_from_parser (CamelMimePart *mime_part, CamelMimeParser *mp)
 {
 	CamelDataWrapper *dw = (CamelDataWrapper *) mime_part;
-	struct _camel_header_raw *headers;
+	GQueue *header_queue;
+	GList *link;
 	const gchar *content;
 	gchar *buf;
 	gsize len;
@@ -1206,20 +1256,30 @@ construct_from_parser (CamelMimePart *mime_part, CamelMimeParser *mp)
 	case CAMEL_MIME_PARSER_STATE_HEADER:
 	case CAMEL_MIME_PARSER_STATE_MULTIPART:
 		/* we have the headers, build them into 'us' */
-		headers = camel_mime_parser_headers_raw(mp);
+		header_queue = camel_mime_parser_headers_raw(mp);
 
 		/* if content-type exists, process it first, set for fallback charset in headers */
-		content = camel_header_raw_find(&headers, "content-type", NULL);
+		content = camel_header_raw_find(header_queue, "content-type", NULL);
 		if (content)
 			process_header((CamelMedium *)dw, "content-type", content);
 
-		while (headers) {
-			if (g_ascii_strcasecmp(headers->name, "content-type") == 0
-			    && headers->value != content)
-				camel_medium_add_header((CamelMedium *)dw, "X-Invalid-Content-Type", headers->value);
+		link = g_queue_peek_head_link (header_queue);
+
+		while (link != NULL) {
+			CamelHeaderRaw *raw_header = link->data;
+			const gchar *name;
+			const gchar *value;
+
+			name = camel_header_raw_get_name (raw_header);
+			value = camel_header_raw_get_value (raw_header);
+
+			if (g_ascii_strcasecmp(name, "content-type") == 0
+			    && value != content)
+				camel_medium_add_header((CamelMedium *)dw, "X-Invalid-Content-Type", value);
 			else
-				camel_medium_add_header((CamelMedium *)dw, headers->name, headers->value);
-			headers = headers->next;
+				camel_medium_add_header((CamelMedium *)dw, name, value);
+
+			link = g_list_next (link);
 		}
 
 		camel_mime_part_construct_content_from_parser (mime_part, mp);
diff --git a/camel/camel-mime-part.h b/camel/camel-mime-part.h
index 0329183..96a51fd 100644
--- a/camel/camel-mime-part.h
+++ b/camel/camel-mime-part.h
@@ -104,8 +104,7 @@ const	  GList *camel_mime_part_get_content_languages	(CamelMimePart *mime_part);
 void               camel_mime_part_set_content_type	(CamelMimePart *mime_part, const gchar *content_type);
 CamelContentType  *camel_mime_part_get_content_type	(CamelMimePart *mime_part);
 
-struct _camel_header_raw *
-		camel_mime_part_get_raw_headers	(CamelMimePart *mime_part);
+GQueue *	camel_mime_part_get_raw_headers	(CamelMimePart *mime_part);
 
 /* construction */
 gint		camel_mime_part_construct_from_parser  (CamelMimePart *mime_part, CamelMimeParser *parser);
diff --git a/camel/camel-mime-utils.c b/camel/camel-mime-utils.c
index 2800815..f31ca74 100644
--- a/camel/camel-mime-utils.c
+++ b/camel/camel-mime-utils.c
@@ -4245,174 +4245,283 @@ camel_header_location_decode(const gchar *in)
 	return res;
 }
 
+struct _CamelHeaderRaw {
+	const gchar *name;	/* interned header name */
+	gchar *value;		/* allocated header value */
+	gint offset;		/* in file, if known */
+};
+
 /* extra rfc checks */
 #define CHECKS
 
 #ifdef CHECKS
 static void
-check_header(struct _camel_header_raw *h)
+check_header (CamelHeaderRaw *header)
 {
-	guchar *p;
+	guchar *cp;
 
-	p = (guchar *) h->value;
-	while (p && *p) {
-		if (!isascii(*p)) {
-			w(g_warning("Appending header violates rfc: %s: %s", h->name, h->value));
+	cp = (guchar *) header->value;
+	while (cp && *cp) {
+		if (!isascii(*cp)) {
+			w(g_warning("Appending header violates rfc: %s: %s", header->name, header->value));
 			return;
 		}
-		p++;
+		cp++;
 	}
 }
 #endif
 
+static CamelHeaderRaw *
+header_raw_new (const gchar *header_name,
+                const gchar *header_value,
+                gint offset)
+{
+	CamelHeaderRaw *header;
+
+	header = g_slice_new (CamelHeaderRaw);
+	header->name = g_intern_string (header_name);
+	header->value = g_strdup (header_value);
+	header->offset = offset;
+
+#ifdef CHECKS
+	check_header (header);
+#endif
+	return header;
+}
+
+static void
+header_raw_free (CamelHeaderRaw *header)
+{
+	g_free (header->value);
+
+	g_slice_free (CamelHeaderRaw, header);
+}
+
+static gint
+header_raw_compare (const CamelHeaderRaw *header,
+                    const gchar *header_name)
+{
+	return g_ascii_strcasecmp (header->name, header_name);
+}
+
+const gchar *
+camel_header_raw_get_name (CamelHeaderRaw *raw_header)
+{
+	g_return_val_if_fail (raw_header != NULL, NULL);
+
+	return raw_header->name;
+}
+
+const gchar *
+camel_header_raw_get_value (CamelHeaderRaw *raw_header)
+{
+	g_return_val_if_fail (raw_header != NULL, NULL);
+
+	return raw_header->value;
+}
+
+gint
+camel_header_raw_get_offset (CamelHeaderRaw *raw_header)
+{
+	g_return_val_if_fail (raw_header != NULL, -1);
+
+	return raw_header->offset;
+}
+
+void
+camel_header_raw_append (GQueue *header_queue,
+                         const gchar *header_name,
+                         const gchar *header_value,
+                         gint offset)
+{
+	CamelHeaderRaw *header;
+
+	g_return_if_fail (header_queue != NULL);
+	g_return_if_fail (header_name != NULL);
+
+	header = header_raw_new (header_name, header_value, offset);
+	g_queue_push_tail (header_queue, header);
+}
+
+void
+camel_header_raw_append_queue (GQueue *header_queue,
+                               GQueue *source_queue)
+{
+	GList *link;
+
+	/* XXX There's nothing header-specific about this.
+	 *     Could be a general-purpose GQueue utility. */
+
+	g_return_if_fail (header_queue != NULL);
+	g_return_if_fail (source_queue != NULL);
+
+	while (!g_queue_is_empty (source_queue)) {
+		link = g_queue_pop_head_link (source_queue);
+		g_queue_push_tail_link (header_queue, link);
+	}
+}
+
 void
-camel_header_raw_append_parse(struct _camel_header_raw **list, const gchar *header, gint offset)
+camel_header_raw_append_parse (GQueue *header_queue,
+                               const gchar *string,
+                               gint offset)
 {
 	register const gchar *in;
 	gsize fieldlen;
 	gchar *name;
 
-	in = header;
-	while (camel_mime_is_fieldname(*in) || *in==':')
+	g_return_if_fail (header_queue != NULL);
+	g_return_if_fail (string != NULL);
+
+	in = string;
+	while (camel_mime_is_fieldname (*in) || *in==':')
 		in++;
-	fieldlen = in-header-1;
-	while (camel_mime_is_lwsp(*in))
+	fieldlen = in-string-1;
+	while (camel_mime_is_lwsp (*in))
 		in++;
-	if (fieldlen == 0 || header[fieldlen] != ':') {
-		printf("Invalid header line: '%s'\n", header);
+	if (fieldlen == 0 || string[fieldlen] != ':') {
+		printf ("Invalid header line: '%s'\n", string);
 		return;
 	}
 	name = g_alloca (fieldlen + 1);
-	memcpy(name, header, fieldlen);
+	memcpy (name, string, fieldlen);
 	name[fieldlen] = 0;
 
-	camel_header_raw_append(list, name, in, offset);
+	camel_header_raw_append (header_queue, name, in, offset);
 }
 
-void
-camel_header_raw_append(struct _camel_header_raw **list, const gchar *name, const gchar *value, gint offset)
+guint
+camel_header_raw_extract (GQueue *header_queue,
+                          GQueue *destination_queue,
+                          const gchar *header_name)
 {
-	struct _camel_header_raw *l, *n;
+	GList *list = NULL;
+	GList *link;
+	guint n_extracted = 0;
 
-	d(printf("Header: %s: %s\n", name, value));
+	g_return_val_if_fail (header_queue != NULL, 0);
+	g_return_val_if_fail (destination_queue != NULL, 0);
+	g_return_val_if_fail (header_name != NULL, 0);
 
-	n = g_malloc(sizeof(*n));
-	n->next = NULL;
-	n->name = g_strdup(name);
-	n->value = g_strdup(value);
-	n->offset = offset;
-#ifdef CHECKS
-	check_header(n);
-#endif
-	l = (struct _camel_header_raw *)list;
-	while (l->next) {
-		l = l->next;
+	link = g_queue_peek_head_link (header_queue);
+
+	/* Tag links to extract from the source queue. */
+	while (link != NULL) {
+		CamelHeaderRaw *header = link->data;
+
+		if (header_raw_compare (header, header_name) == 0)
+			list = g_list_prepend (list, link);
+
+		link = g_list_next (link);
 	}
-	l->next = n;
 
-	/* debug */
-#if 0
-	if (!g_ascii_strcasecmp(name, "To")) {
-		printf("- Decoding To\n");
-		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));
-	} else if (!g_ascii_strcasecmp(name, "MIME-Version")) {
-		printf("- Decoding mime version\n");
-		camel_header_mime_decode(value);
+	list = g_list_reverse (list);
+
+	/* Extract the tagged links and put them in the target queue. */
+	for (link = list; link != NULL; link = g_list_next (link)) {
+		GList *tagged_link = link->data;
+
+		g_queue_unlink (header_queue, tagged_link);
+		g_queue_push_tail_link (destination_queue, tagged_link);
+		n_extracted++;
 	}
-#endif
+
+	g_list_free (list);
+
+	return n_extracted;
 }
 
-static struct _camel_header_raw *
-header_raw_find_node(struct _camel_header_raw **list, const gchar *name)
+guint
+camel_header_raw_extract_prefix (GQueue *header_queue,
+                                 GQueue *destination_queue,
+                                 const gchar *header_prefix)
 {
-	struct _camel_header_raw *l;
+	GList *list = NULL;
+	GList *link;
+	guint n_extracted = 0;
+	gsize length;
 
-	l = *list;
-	while (l) {
-		if (!g_ascii_strcasecmp(l->name, name))
-			break;
-		l = l->next;
+	g_return_val_if_fail (header_queue != NULL, 0);
+	g_return_val_if_fail (destination_queue != NULL, 0);
+	g_return_val_if_fail (header_prefix != NULL, 0);
+
+	length = strlen (header_prefix);
+
+	link = g_queue_peek_head_link (header_queue);
+
+	/* Tag links to extract from the source queue. */
+	while (link != NULL) {
+		CamelHeaderRaw *header = link->data;
+		const gchar *name;
+
+		name = camel_header_raw_get_name (header);
+		if (g_ascii_strncasecmp (name, header_prefix, length) == 0)
+			list = g_list_prepend (list, link);
+
+		link = g_list_next (link);
 	}
-	return l;
-}
 
-const gchar *
-camel_header_raw_find(struct _camel_header_raw **list, const gchar *name, gint *offset)
-{
-	struct _camel_header_raw *l;
+	list = g_list_reverse (list);
 
-	l = header_raw_find_node(list, name);
-	if (l) {
-		if (offset)
-			*offset = l->offset;
-		return l->value;
-	} else
-		return NULL;
+	/* Extract the tagged links and put them in the target queue. */
+	for (link = list; link != NULL; link = g_list_next (link)) {
+		GList *tagged_link = link->data;
+
+		g_queue_unlink (header_queue, tagged_link);
+		g_queue_push_tail_link (destination_queue, tagged_link);
+		n_extracted++;
+	}
+
+	g_list_free (list);
+
+	return n_extracted;
 }
 
 const gchar *
-camel_header_raw_find_next(struct _camel_header_raw **list, const gchar *name, gint *offset, const gchar *last)
+camel_header_raw_find (GQueue *header_queue,
+                       const gchar *header_name,
+                       gint *offset)
 {
-	struct _camel_header_raw *l;
+	CamelHeaderRaw *header;
+	GList *link;
 
-	if (last == NULL || name == NULL)
+	g_return_val_if_fail (header_queue != NULL, NULL);
+	g_return_val_if_fail (header_name != NULL, NULL);
+
+	link = g_queue_find_custom (
+		header_queue, header_name, (GCompareFunc) header_raw_compare);
+
+	if (link == NULL)
 		return NULL;
 
-	l = *list;
-	while (l && l->value != last)
-		l = l->next;
-	return camel_header_raw_find(&l, name, offset);
-}
+	header = link->data;
 
-static void
-header_raw_free(struct _camel_header_raw *l)
-{
-	g_free(l->name);
-	g_free(l->value);
-	g_free(l);
-}
+	if (offset != NULL)
+		*offset = header->offset;
 
-void
-camel_header_raw_remove(struct _camel_header_raw **list, const gchar *name)
-{
-	struct _camel_header_raw *l, *p;
-
-	/* the next pointer is at the head of the structure, so this is safe */
-	p = (struct _camel_header_raw *)list;
-	l = *list;
-	while (l) {
-		if (!g_ascii_strcasecmp(l->name, name)) {
-			p->next = l->next;
-			header_raw_free(l);
-			l = p->next;
-		} else {
-			p = l;
-			l = l->next;
-		}
-	}
+	return header->value;
 }
 
 void
-camel_header_raw_replace(struct _camel_header_raw **list, const gchar *name, const gchar *value, gint offset)
+camel_header_raw_remove (GQueue *header_queue,
+                         const gchar *header_name)
 {
-	camel_header_raw_remove(list, name);
-	camel_header_raw_append(list, name, value, offset);
+	GQueue trash_queue = G_QUEUE_INIT;
+
+	g_return_if_fail (header_queue != NULL);
+	g_return_if_fail (header_name != NULL);
+
+	camel_header_raw_extract (header_queue, &trash_queue, header_name);
+	camel_header_raw_clear (&trash_queue);
 }
 
 void
-camel_header_raw_clear(struct _camel_header_raw **list)
-{
-	struct _camel_header_raw *l, *n;
-	l = *list;
-	while (l) {
-		n = l->next;
-		header_raw_free(l);
-		l = n;
-	}
-	*list = NULL;
+camel_header_raw_clear (GQueue *header_queue)
+{
+	g_return_if_fail (header_queue != NULL);
+
+	g_queue_foreach (header_queue, (GFunc) header_raw_free, NULL);
+	g_queue_clear (header_queue);
 }
 
 gchar *
@@ -4530,16 +4639,18 @@ mailing_list_init(void)
 }
 
 gchar *
-camel_header_raw_check_mailing_list(struct _camel_header_raw **list)
+camel_header_raw_check_mailing_list (GQueue *queue)
 {
 	const gchar *v;
 	regmatch_t match[3];
 	gint i, j;
 
+	g_return_val_if_fail (queue != NULL, NULL);
+
 	pthread_once(&mailing_list_init_once, mailing_list_init);
 
 	for (i = 0; i < G_N_ELEMENTS (mail_list_magic); i++) {
-		v = camel_header_raw_find (list, mail_list_magic[i].name, NULL);
+		v = camel_header_raw_find (queue, mail_list_magic[i].name, NULL);
 		for (j=0;j<3;j++) {
 			match[j].rm_so = -1;
 			match[j].rm_eo = -1;
diff --git a/camel/camel-mime-utils.h b/camel/camel-mime-utils.h
index 348b09f..31591ad 100644
--- a/camel/camel-mime-utils.h
+++ b/camel/camel-mime-utils.h
@@ -42,6 +42,11 @@
 
 G_BEGIN_DECLS
 
+/* Opaque RFC 822 Header
+ * The value must be in US-ASCII.  These are kept
+ * in GQueues for fast appending and removal. */
+typedef struct _CamelHeaderRaw CamelHeaderRaw;
+
 /* note, if you change this, make sure you change the 'encodings' array in camel-mime-part.c */
 typedef enum _CamelTransferEncoding {
 	CAMEL_TRANSFER_ENCODING_DEFAULT,
@@ -74,15 +79,6 @@ typedef struct {
 	guint refcount;
 } CamelContentType;
 
-/* a raw rfc822 header */
-/* the value MUST be US-ASCII */
-struct _camel_header_raw {
-	struct _camel_header_raw *next;
-	gchar *name;
-	gchar *value;
-	gint offset;		/* in file, if known */
-};
-
 typedef struct _CamelContentDisposition {
 	gchar *disposition;
 	struct _camel_header_param *params;
@@ -165,16 +161,33 @@ gchar *camel_content_disposition_format (CamelContentDisposition *disposition);
 gchar *camel_content_transfer_encoding_decode (const gchar *in);
 
 /* raw headers */
-void camel_header_raw_append (struct _camel_header_raw **list, const gchar *name, const gchar *value, gint offset);
-void camel_header_raw_append_parse (struct _camel_header_raw **list, const gchar *header, gint offset);
-const gchar *camel_header_raw_find (struct _camel_header_raw **list, const gchar *name, gint *offset);
-const gchar *camel_header_raw_find_next (struct _camel_header_raw **list, const gchar *name, gint *offset, const gchar *last);
-void camel_header_raw_replace (struct _camel_header_raw **list, const gchar *name, const gchar *value, gint offset);
-void camel_header_raw_remove (struct _camel_header_raw **list, const gchar *name);
-void camel_header_raw_fold (struct _camel_header_raw **list);
-void camel_header_raw_clear (struct _camel_header_raw **list);
-
-gchar *camel_header_raw_check_mailing_list (struct _camel_header_raw **list);
+const gchar *	camel_header_raw_get_name	(CamelHeaderRaw *raw_header);
+const gchar *	camel_header_raw_get_value	(CamelHeaderRaw *raw_header);
+gint		camel_header_raw_get_offset	(CamelHeaderRaw *raw_header);
+void		camel_header_raw_append		(GQueue *header_queue,
+						 const gchar *header_name,
+						 const gchar *header_value,
+						 gint offset);
+void		camel_header_raw_append_queue	(GQueue *header_queue,
+						 GQueue *source_queue);
+void		camel_header_raw_append_parse	(GQueue *header_queue,
+						 const gchar *string,
+						 gint offset);
+guint		camel_header_raw_extract	(GQueue *header_queue,
+						 GQueue *destination_queue,
+						 const gchar *header_name);
+guint		camel_header_raw_extract_prefix	(GQueue *header_queue,
+						 GQueue *destination_queue,
+						 const gchar *header_prefix);
+const gchar *	camel_header_raw_find		(GQueue *header_queue,
+						 const gchar *header_name,
+						 gint *offset);
+void		camel_header_raw_remove		(GQueue *header_queue,
+						 const gchar *header_name);
+void		camel_header_raw_clear		(GQueue *header_queue);
+
+gchar *		camel_header_raw_check_mailing_list
+						(GQueue *header_queue);
 
 /* fold a header */
 gchar *camel_header_address_fold (const gchar *in, gsize headerlen);
diff --git a/camel/camel-stream-filter.c b/camel/camel-stream-filter.c
index 81acfb0..71f4d93 100644
--- a/camel/camel-stream-filter.c
+++ b/camel/camel-stream-filter.c
@@ -368,7 +368,7 @@ camel_stream_filter_new (CamelStream *source)
 
 	priv->source = g_object_ref (source);
 
-	return source;
+	return stream;
 }
 
 CamelStream *
diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c
index 50805d4..d821273 100644
--- a/camel/providers/imap/camel-imap-folder.c
+++ b/camel/providers/imap/camel-imap-folder.c
@@ -3054,11 +3054,11 @@ done:
 
 		if (!mi->info.mlist || !*mi->info.mlist) {
 			/* update mailing list information, if necessary */
-			struct _camel_header_raw *headers;
+			GQueue *header_queue;
 			gchar *mlist;
 
-			headers = camel_mime_part_get_raw_headers (CAMEL_MIME_PART (msg));
-			mlist = camel_header_raw_check_mailing_list (&headers);
+			header_queue = camel_mime_part_get_raw_headers (CAMEL_MIME_PART (msg));
+			mlist = camel_header_raw_check_mailing_list (header_queue);
 
 			if (mlist) {
 				if (mi->info.mlist)
diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c
index aa1b83a..52dde05 100644
--- a/camel/providers/imap/camel-imap-store.c
+++ b/camel/providers/imap/camel-imap-store.c
@@ -136,8 +136,8 @@ imap_store_finalize (GObject *object)
 
 	g_free (imap_store->base_url);
 	g_free (imap_store->storage_path);
+	g_free (imap_store->users_namespace);
 	g_free (imap_store->custom_headers);
-        g_free (imap_store->users_namespace);
 
 	/* Chain up to parent's finalize() method. */
 	G_OBJECT_CLASS (parent_class)->finalize (object);
diff --git a/camel/providers/local/camel-local-summary.c b/camel/providers/local/camel-local-summary.c
index 5a4fa70..33444e8 100644
--- a/camel/providers/local/camel-local-summary.c
+++ b/camel/providers/local/camel-local-summary.c
@@ -49,7 +49,7 @@ static gint summary_header_from_db (CamelFolderSummary *, CamelFIRecord *);
 static gint summary_header_load (CamelFolderSummary *, FILE *);
 static gint summary_header_save (CamelFolderSummary *, FILE *);
 
-static CamelMessageInfo * message_info_new_from_header (CamelFolderSummary *, struct _camel_header_raw *);
+static CamelMessageInfo * message_info_new_from_header (CamelFolderSummary *, GQueue *header_queue);
 
 static gint local_summary_decode_x_evolution(CamelLocalSummary *cls, const gchar *xev, CamelLocalMessageInfo *mi);
 static gchar *local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelLocalMessageInfo *mi);
@@ -346,8 +346,9 @@ camel_local_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, const Cam
  * Return value: -1 on error, otherwise the number of bytes written.
  **/
 gint
-camel_local_summary_write_headers(gint fd, struct _camel_header_raw *header, const gchar *xevline, const gchar *status, const gchar *xstatus)
+camel_local_summary_write_headers(gint fd, GQueue *header_queue, const gchar *xevline, const gchar *status, const gchar *xstatus)
 {
+	GList *link;
 	gint outlen = 0, len;
 	gint newfd;
 	FILE *out;
@@ -364,18 +365,27 @@ camel_local_summary_write_headers(gint fd, struct _camel_header_raw *header, con
 		return -1;
 	}
 
-	while (header) {
-		if (strcmp(header->name, "X-Evolution") != 0
-		    && (status == NULL || strcmp(header->name, "Status") != 0)
-		    && (xstatus == NULL || strcmp(header->name, "X-Status") != 0)) {
-			len = fprintf(out, "%s:%s\n", header->name, header->value);
+	link = g_queue_peek_head_link (header_queue);
+
+	while (link != NULL) {
+		CamelHeaderRaw *raw_header = link->data;
+		const gchar *name, *value;
+
+		name = camel_header_raw_get_name (raw_header);
+		value = camel_header_raw_get_value (raw_header);
+
+		if (strcmp(name, "X-Evolution") != 0
+		    && (status == NULL || strcmp(name, "Status") != 0)
+		    && (xstatus == NULL || strcmp(name, "X-Status") != 0)) {
+			len = fprintf(out, "%s:%s\n", name, value);
 			if (len == -1) {
 				fclose(out);
 				return -1;
 			}
 			outlen += len;
 		}
-		header = header->next;
+
+		link = g_list_next (link);
 	}
 
 	if (status) {
@@ -721,17 +731,17 @@ summary_header_save(CamelFolderSummary *s, FILE *out)
 }
 
 static CamelMessageInfo *
-message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
+message_info_new_from_header(CamelFolderSummary *s, GQueue *header_queue)
 {
 	CamelLocalMessageInfo *mi;
 	CamelLocalSummary *cls = (CamelLocalSummary *)s;
 
-	mi = (CamelLocalMessageInfo *)CAMEL_FOLDER_SUMMARY_CLASS (parent_class)->message_info_new_from_header(s, h);
+	mi = (CamelLocalMessageInfo *)CAMEL_FOLDER_SUMMARY_CLASS (parent_class)->message_info_new_from_header(s, header_queue);
 	if (mi) {
 		const gchar *xev;
 		gint doindex = FALSE;
 
-		xev = camel_header_raw_find(&h, "X-Evolution", NULL);
+		xev = camel_header_raw_find(header_queue, "X-Evolution", NULL);
 		if (xev==NULL || camel_local_summary_decode_x_evolution(cls, xev, mi) == -1) {
 			/* to indicate it has no xev header */
 			mi->info.flags |= CAMEL_MESSAGE_FOLDER_FLAGGED | CAMEL_MESSAGE_FOLDER_NOXEV;
diff --git a/camel/providers/local/camel-local-summary.h b/camel/providers/local/camel-local-summary.h
index 204ff1c..fca613a 100644
--- a/camel/providers/local/camel-local-summary.h
+++ b/camel/providers/local/camel-local-summary.h
@@ -105,7 +105,7 @@ gchar *camel_local_summary_encode_x_evolution(CamelLocalSummary *cls, const Came
 gint camel_local_summary_decode_x_evolution(CamelLocalSummary *cls, const gchar *xev, CamelLocalMessageInfo *info);
 
 /* utility functions - write headers to a file with optional X-Evolution header and/or status header */
-gint camel_local_summary_write_headers(gint fd, struct _camel_header_raw *header, const gchar *xevline, const gchar *status, const gchar *xstatus);
+gint camel_local_summary_write_headers(gint fd, GQueue *header_queue, const gchar *xevline, const gchar *status, const gchar *xstatus);
 
 G_END_DECLS
 
diff --git a/camel/providers/local/camel-maildir-folder.c b/camel/providers/local/camel-maildir-folder.c
index b24381e..105ea2d 100644
--- a/camel/providers/local/camel-maildir-folder.c
+++ b/camel/providers/local/camel-maildir-folder.c
@@ -50,6 +50,7 @@ static CamelMimeMessage *maildir_get_message(CamelFolder * folder, const gchar *
 static gchar * maildir_get_filename (CamelFolder *folder, const gchar *uid, CamelException *ex);
 static gint maildir_cmp_uids (CamelFolder *folder, const gchar *uid1, const gchar *uid2);
 static void maildir_sort_uids (CamelFolder *folder, GPtrArray *uids);
+static void maildir_transfer_messages_to (CamelFolder *source, GPtrArray *uids, CamelFolder *dest, GPtrArray **transferred_uids, gboolean delete_originals, CamelException *ex);
 
 static gint
 maildir_folder_getv(CamelObject *object, CamelException *ex, CamelArgGetV *args)
@@ -98,6 +99,7 @@ maildir_folder_class_init (CamelObjectClass *class)
 	folder_class->get_filename = maildir_get_filename;
 	folder_class->cmp_uids = maildir_cmp_uids;
 	folder_class->sort_uids = maildir_sort_uids;
+	folder_class->transfer_messages_to = maildir_transfer_messages_to;
 
 	local_folder_class = CAMEL_LOCAL_FOLDER_CLASS (class);
 	local_folder_class->create_summary = maildir_create_summary;
diff --git a/camel/providers/local/camel-maildir-summary.c b/camel/providers/local/camel-maildir-summary.c
index e1599c9..efe92d3 100644
--- a/camel/providers/local/camel-maildir-summary.c
+++ b/camel/providers/local/camel-maildir-summary.c
@@ -49,7 +49,7 @@
 	((obj), CAMEL_TYPE_MAILDIR_SUMMARY, CamelMaildirSummaryPrivate))
 
 static CamelMessageInfo *message_info_load(CamelFolderSummary *s, FILE *in);
-static CamelMessageInfo *message_info_new_from_header(CamelFolderSummary *, struct _camel_header_raw *);
+static CamelMessageInfo *message_info_new_from_header(CamelFolderSummary *, GQueue *header_queue);
 static void message_info_free(CamelFolderSummary *, CamelMessageInfo *mi);
 
 static gint maildir_summary_load(CamelLocalSummary *cls, gint forceindex, CamelException *ex);
@@ -280,14 +280,15 @@ maildir_summary_add (CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelM
 	return (CamelMessageInfo *)mi;
 }
 
-static CamelMessageInfo *message_info_new_from_header(CamelFolderSummary * s, struct _camel_header_raw *h)
+static CamelMessageInfo *
+message_info_new_from_header(CamelFolderSummary * s, GQueue *header_queue)
 {
 	CamelMessageInfo *mi, *info;
 	CamelMaildirSummary *mds = (CamelMaildirSummary *)s;
 	CamelMaildirMessageInfo *mdi;
 	const gchar *uid;
 
-	mi = ((CamelFolderSummaryClass *) parent_class)->message_info_new_from_header(s, h);
+	mi = ((CamelFolderSummaryClass *) parent_class)->message_info_new_from_header(s, header_queue);
 	/* assign the uid and new filename */
 	if (mi) {
 		mdi = (CamelMaildirMessageInfo *)mi;
diff --git a/camel/providers/local/camel-mbox-summary.c b/camel/providers/local/camel-mbox-summary.c
index a86da80..a6ec6ac 100644
--- a/camel/providers/local/camel-mbox-summary.c
+++ b/camel/providers/local/camel-mbox-summary.c
@@ -54,7 +54,7 @@ static CamelMIRecord * message_info_to_db(CamelFolderSummary *s, CamelMessageInf
 static gint summary_header_load (CamelFolderSummary *, FILE *);
 static gint summary_header_save (CamelFolderSummary *, FILE *);
 
-static CamelMessageInfo * message_info_new_from_header(CamelFolderSummary *, struct _camel_header_raw *);
+static CamelMessageInfo * message_info_new_from_header(CamelFolderSummary *, GQueue *header_queue);
 static CamelMessageInfo * message_info_new_from_parser(CamelFolderSummary *, CamelMimeParser *);
 static CamelMessageInfo * message_info_load (CamelFolderSummary *, FILE *);
 static gint		  message_info_save (CamelFolderSummary *, FILE *, CamelMessageInfo *);
@@ -312,12 +312,12 @@ summary_header_save(CamelFolderSummary *s, FILE *out)
 }
 
 static CamelMessageInfo *
-message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
+message_info_new_from_header(CamelFolderSummary *s, GQueue *header_queue)
 {
 	CamelMboxMessageInfo *mi;
 	CamelMboxSummary *mbs = (CamelMboxSummary *)s;
 
-	mi = (CamelMboxMessageInfo *)CAMEL_FOLDER_SUMMARY_CLASS (parent_class)->message_info_new_from_header(s, h);
+	mi = (CamelMboxMessageInfo *)CAMEL_FOLDER_SUMMARY_CLASS (parent_class)->message_info_new_from_header(s, header_queue);
 	if (mi) {
 		const gchar *xev, *uid;
 		CamelMboxMessageInfo *info = NULL;
@@ -328,16 +328,16 @@ message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
 
 		if (mbs->xstatus) {
 			/* check for existance of status & x-status headers */
-			status = camel_header_raw_find(&h, "Status", NULL);
+			status = camel_header_raw_find(header_queue, "Status", NULL);
 			if (status)
 				flags = decode_status(status);
-			xstatus = camel_header_raw_find(&h, "X-Status", NULL);
+			xstatus = camel_header_raw_find(header_queue, "X-Status", NULL);
 			if (xstatus)
 				flags |= decode_status(xstatus);
 		}
 #endif
 		/* if we have an xev header, use it, else assign a new one */
-		xev = camel_header_raw_find(&h, "X-Evolution", NULL);
+		xev = camel_header_raw_find(header_queue, "X-Evolution", NULL);
 		if (xev != NULL
 		    && camel_local_summary_decode_x_evolution((CamelLocalSummary *)s, xev, &mi->info) == 0) {
 			uid = camel_message_info_uid(mi);
diff --git a/camel/providers/local/camel-spool-summary.h b/camel/providers/local/camel-spool-summary.h
index 98aa960..653600a 100644
--- a/camel/providers/local/camel-spool-summary.h
+++ b/camel/providers/local/camel-spool-summary.h
@@ -78,7 +78,7 @@ gchar *camel_spool_summary_encode_x_evolution(CamelSpoolSummary *cls, const Came
 gint camel_spool_summary_decode_x_evolution(CamelSpoolSummary *cls, const gchar *xev, CamelMessageInfo *info);
 
 /* utility functions - write headers to a file with optional X-Evolution header */
-gint camel_spool_summary_write_headers(gint fd, struct _camel_header_raw *header, gchar *xevline);
+gint camel_spool_summary_write_headers(gint fd, GQueue *header_queue, gchar *xevline);
 
 G_END_DECLS
 
diff --git a/camel/providers/nntp/camel-nntp-folder.c b/camel/providers/nntp/camel-nntp-folder.c
index 2b29576..8dca275 100644
--- a/camel/providers/nntp/camel-nntp-folder.c
+++ b/camel/providers/nntp/camel-nntp-folder.c
@@ -348,9 +348,11 @@ nntp_folder_append_message_online (CamelFolder *folder, CamelMimeMessage *mime_m
 	CamelStream *stream = (CamelStream*)nntp_store->stream;
 	CamelStream *filtered_stream;
 	CamelMimeFilter *crlffilter;
+	CamelMimePart *mime_part;
+	GQueue *header_queue;
+	GQueue save_queue = G_QUEUE_INIT;
 	gint ret;
 	guint u;
-	struct _camel_header_raw *header, *savedhdrs, *n, *tail;
 	gchar *group, *line;
 
 	CAMEL_SERVICE_REC_LOCK(nntp_store, connect_lock);
@@ -379,23 +381,11 @@ nntp_folder_append_message_online (CamelFolder *folder, CamelMimeMessage *mime_m
 	g_object_unref (crlffilter);
 
 	/* remove mail 'To', 'CC', and 'BCC' headers */
-	savedhdrs = NULL;
-	tail = (struct _camel_header_raw *) &savedhdrs;
-
-	header = camel_mime_part_get_raw_headers (CAMEL_MIME_PART (mime_message));
-	n = header->next;
-	while (n != NULL) {
-		if (!g_ascii_strcasecmp (n->name, "To") || !g_ascii_strcasecmp (n->name, "Cc") || !g_ascii_strcasecmp (n->name, "Bcc")) {
-			header->next = n->next;
-			tail->next = n;
-			n->next = NULL;
-			tail = n;
-		} else {
-			header = n;
-		}
-
-		n = header->next;
-	}
+	mime_part = CAMEL_MIME_PART (mime_message);
+	header_queue = camel_mime_part_get_raw_headers (mime_part);
+	camel_header_raw_extract (header_queue, &save_queue, "To");
+	camel_header_raw_extract (header_queue, &save_queue, "Cc");
+	camel_header_raw_extract (header_queue, &save_queue, "Bcc");
 
 	/* write the message */
 	if (camel_stream_write(stream, group, strlen(group)) == -1
@@ -413,11 +403,10 @@ nntp_folder_append_message_online (CamelFolder *folder, CamelMimeMessage *mime_m
 
 	g_object_unref (filtered_stream);
 	g_free(group);
-	header->next = savedhdrs;
 
-	CAMEL_SERVICE_REC_UNLOCK(nntp_store, connect_lock);
+	camel_header_raw_append_queue (header_queue, &save_queue);
 
-	return;
+	CAMEL_SERVICE_REC_UNLOCK(nntp_store, connect_lock);
 }
 
 static void
diff --git a/camel/providers/nntp/camel-nntp-summary.c b/camel/providers/nntp/camel-nntp-summary.c
index fa29049..357ca08 100644
--- a/camel/providers/nntp/camel-nntp-summary.c
+++ b/camel/providers/nntp/camel-nntp-summary.c
@@ -58,7 +58,7 @@ struct _CamelNNTPSummaryPrivate {
 	gint xover_setup;
 };
 
-static CamelMessageInfo * message_info_new_from_header (CamelFolderSummary *, struct _camel_header_raw *);
+static CamelMessageInfo * message_info_new_from_header (CamelFolderSummary *, GQueue *);
 static gint summary_header_load (CamelFolderSummary *, FILE *);
 static gint summary_header_save (CamelFolderSummary *, FILE *);
 static gint summary_header_from_db (CamelFolderSummary *s, CamelFIRecord *mir);
@@ -130,7 +130,8 @@ camel_nntp_summary_new (struct _CamelFolder *folder, const gchar *path)
 }
 
 static CamelMessageInfo *
-message_info_new_from_header (CamelFolderSummary *s, struct _camel_header_raw *h)
+message_info_new_from_header (CamelFolderSummary *s,
+                              GQueue *header_queue)
 {
 	CamelMessageInfoBase *mi;
 	CamelNNTPSummary *cns = (CamelNNTPSummary *)s;
@@ -139,7 +140,7 @@ message_info_new_from_header (CamelFolderSummary *s, struct _camel_header_raw *h
 	if (cns->priv->uid == NULL)
 		return NULL;
 
-	mi = (CamelMessageInfoBase *)CAMEL_FOLDER_SUMMARY_CLASS (parent_class)->message_info_new_from_header (s, h);
+	mi = (CamelMessageInfoBase *)CAMEL_FOLDER_SUMMARY_CLASS (parent_class)->message_info_new_from_header (s, header_queue);
 	if (mi) {
 		camel_pstring_free (mi->uid);
 		mi->uid = camel_pstring_strdup (cns->priv->uid);
@@ -242,7 +243,7 @@ add_range_xover (CamelNNTPSummary *cns, CamelNNTPStore *store, guint high, guint
 {
 	CamelFolderSummary *s;
 	CamelMessageInfoBase *mi;
-	struct _camel_header_raw *headers = NULL;
+	GQueue *header_queue;
 	gchar *line, *tab;
 	guint len;
 	gint ret;
@@ -264,6 +265,8 @@ add_range_xover (CamelNNTPSummary *cns, CamelNNTPStore *store, guint high, guint
 		return -1;
 	}
 
+	header_queue = g_queue_new ();
+
 	count = 0;
 	total = high-low+1;
 	while ((ret = camel_nntp_stream_line (store->stream, (guchar **)&line, &len)) > 0) {
@@ -287,7 +290,7 @@ add_range_xover (CamelNNTPSummary *cns, CamelNNTPStore *store, guint high, guint
 			if (xover->name) {
 				line += xover->skip;
 				if (line < tab) {
-					camel_header_raw_append (&headers, xover->name, line, -1);
+					camel_header_raw_append (header_queue, xover->name, line, -1);
 					switch (xover->type) {
 					case XOVER_STRING:
 						break;
@@ -309,7 +312,7 @@ add_range_xover (CamelNNTPSummary *cns, CamelNNTPStore *store, guint high, guint
 		/* truncated line? ignore? */
 		if (xover == NULL) {
 			if (!GPOINTER_TO_INT (g_hash_table_lookup (summary_table, cns->priv->uid))) {
-				mi = (CamelMessageInfoBase *)camel_folder_summary_add_from_header (s, headers);
+				mi = (CamelMessageInfoBase *)camel_folder_summary_add_from_header (s, header_queue);
 				if (mi) {
 					mi->size = size;
 					cns->high = n;
@@ -323,9 +326,11 @@ add_range_xover (CamelNNTPSummary *cns, CamelNNTPStore *store, guint high, guint
 			cns->priv->uid = NULL;
 		}
 
-		camel_header_raw_clear (&headers);
+		camel_header_raw_clear (header_queue);
 	}
 
+	g_queue_free (header_queue);
+
 	camel_operation_end (NULL);
 
 	camel_folder_summary_free_hashtable (summary_table);
diff --git a/camel/providers/pop3/camel-pop3-folder.c b/camel/providers/pop3/camel-pop3-folder.c
index 77aa9c1..51c6c50 100644
--- a/camel/providers/pop3/camel-pop3-folder.c
+++ b/camel/providers/pop3/camel-pop3-folder.c
@@ -142,8 +142,9 @@ cmd_builduid(CamelPOP3Engine *pe, CamelPOP3Stream *stream, gpointer data)
 {
 	GChecksum *checksum;
 	CamelPOP3FolderInfo *fi = data;
-	struct _camel_header_raw *h;
 	CamelMimeParser *mp;
+	GQueue *header_queue;
+	GList *link;
 	guint8 *digest;
 	gsize length;
 
@@ -161,14 +162,22 @@ cmd_builduid(CamelPOP3Engine *pe, CamelPOP3Stream *stream, gpointer data)
 	case CAMEL_MIME_PARSER_STATE_HEADER:
 	case CAMEL_MIME_PARSER_STATE_MESSAGE:
 	case CAMEL_MIME_PARSER_STATE_MULTIPART:
-		h = camel_mime_parser_headers_raw(mp);
-		while (h) {
-			if (g_ascii_strcasecmp(h->name, "status") != 0
-			    && g_ascii_strcasecmp(h->name, "x-status") != 0) {
-				g_checksum_update (checksum, (guchar *) h->name, -1);
-				g_checksum_update (checksum, (guchar *) h->value, -1);
+		header_queue = camel_mime_parser_headers_raw (mp);
+		link = g_queue_peek_head_link (header_queue);
+		while (link != NULL) {
+			CamelHeaderRaw *raw_header = link->data;
+			const gchar *name, *value;
+
+			name = camel_header_raw_get_name (raw_header);
+			value = camel_header_raw_get_value (raw_header);
+
+			if (g_ascii_strcasecmp(name, "status") != 0
+			    && g_ascii_strcasecmp(name, "x-status") != 0) {
+				g_checksum_update (checksum, (guchar *) name, -1);
+				g_checksum_update (checksum, (guchar *) value, -1);
 			}
-			h = h->next;
+
+			link = g_list_next (link);
 		}
 	default:
 		break;
diff --git a/camel/providers/sendmail/camel-sendmail-transport.c b/camel/providers/sendmail/camel-sendmail-transport.c
index 0818c7d..94c59a2 100644
--- a/camel/providers/sendmail/camel-sendmail-transport.c
+++ b/camel/providers/sendmail/camel-sendmail-transport.c
@@ -80,11 +80,13 @@ sendmail_send_to (CamelTransport *transport, CamelMimeMessage *message,
 		  CamelAddress *from, CamelAddress *recipients,
 		  CamelException *ex)
 {
-	struct _camel_header_raw *header, *savedbcc, *n, *tail;
 	const gchar *from_addr, *addr, **argv;
 	gint i, len, fd[2], nullfd, wstat;
 	CamelStream *filter;
 	CamelMimeFilter *crlf;
+	CamelMimePart *mime_part;
+	GQueue *header_queue;
+	GQueue bcc_queue = G_QUEUE_INIT;
 	sigset_t mask, omask;
 	CamelStream *out;
 	pid_t pid;
@@ -114,23 +116,9 @@ sendmail_send_to (CamelTransport *transport, CamelMimeMessage *message,
 	argv[i + 5] = NULL;
 
 	/* unlink the bcc headers */
-	savedbcc = NULL;
-	tail = (struct _camel_header_raw *) &savedbcc;
-
-	header = camel_mime_part_get_raw_headers (CAMEL_MIME_PART (message));
-	n = header->next;
-	while (n != NULL) {
-		if (!g_ascii_strcasecmp (n->name, "Bcc")) {
-			header->next = n->next;
-			tail->next = n;
-			n->next = NULL;
-			tail = n;
-		} else {
-			header = n;
-		}
-
-		n = header->next;
-	}
+	mime_part = CAMEL_MIME_PART (message);
+	header_queue = camel_mime_part_get_raw_headers (mime_part);
+	camel_header_raw_extract (header_queue, &bcc_queue, "Bcc");
 
 	if (pipe (fd) == -1) {
 		camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
@@ -139,7 +127,7 @@ sendmail_send_to (CamelTransport *transport, CamelMimeMessage *message,
 				      g_strerror (errno));
 
 		/* restore the bcc headers */
-		header->next = savedbcc;
+		camel_header_raw_append_queue (header_queue, &bcc_queue);
 
 		return FALSE;
 	}
@@ -164,7 +152,7 @@ sendmail_send_to (CamelTransport *transport, CamelMimeMessage *message,
 		g_free (argv);
 
 		/* restore the bcc headers */
-		header->next = savedbcc;
+		camel_header_raw_append_queue (header_queue, &bcc_queue);
 
 		return FALSE;
 	case 0:
@@ -207,7 +195,7 @@ sendmail_send_to (CamelTransport *transport, CamelMimeMessage *message,
 		sigprocmask (SIG_SETMASK, &omask, NULL);
 
 		/* restore the bcc headers */
-		header->next = savedbcc;
+		camel_header_raw_append_queue (header_queue, &bcc_queue);
 
 		return FALSE;
 	}
@@ -221,7 +209,7 @@ sendmail_send_to (CamelTransport *transport, CamelMimeMessage *message,
 	sigprocmask (SIG_SETMASK, &omask, NULL);
 
 	/* restore the bcc headers */
-	header->next = savedbcc;
+	camel_header_raw_append_queue (header_queue, &bcc_queue);
 
 	if (!WIFEXITED (wstat)) {
 		camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
diff --git a/camel/providers/smtp/camel-smtp-transport.c b/camel/providers/smtp/camel-smtp-transport.c
index 6c9308b..9af0f2c 100644
--- a/camel/providers/smtp/camel-smtp-transport.c
+++ b/camel/providers/smtp/camel-smtp-transport.c
@@ -1265,12 +1265,14 @@ smtp_rcpt (CamelSmtpTransport *transport, const gchar *recipient, CamelException
 static gboolean
 smtp_data (CamelSmtpTransport *transport, CamelMimeMessage *message, CamelException *ex)
 {
-	struct _camel_header_raw *header, *savedbcc, *n, *tail;
 	CamelBestencEncoding enctype = CAMEL_BESTENC_8BIT;
 	CamelStream *filtered_stream;
 	gchar *cmdbuf, *respbuf = NULL;
 	CamelMimeFilter *filter;
+	CamelMimePart *mime_part;
 	CamelStreamNull *null;
+	GQueue *header_queue;
+	GQueue bcc_queue = G_QUEUE_INIT;
 	gint ret;
 
 	/* If the server doesn't support 8BITMIME, set our required encoding to be 7bit */
@@ -1316,23 +1318,9 @@ smtp_data (CamelSmtpTransport *transport, CamelMimeMessage *message, CamelExcept
 	respbuf = NULL;
 
 	/* unlink the bcc headers */
-	savedbcc = NULL;
-	tail = (struct _camel_header_raw *) &savedbcc;
-
-	header = camel_mime_part_get_raw_headers (CAMEL_MIME_PART (message));
-	n = header->next;
-	while (n != NULL) {
-		if (!g_ascii_strcasecmp (n->name, "Bcc")) {
-			header->next = n->next;
-			tail->next = n;
-			n->next = NULL;
-			tail = n;
-		} else {
-			header = n;
-		}
-
-		n = header->next;
-	}
+	mime_part = CAMEL_MIME_PART (message);
+	header_queue = camel_mime_part_get_raw_headers (mime_part);
+	camel_header_raw_extract (header_queue, &bcc_queue, "Bcc");
 
 	/* find out how large the message is... */
 	null = CAMEL_STREAM_NULL (camel_stream_null_new ());
@@ -1361,7 +1349,7 @@ smtp_data (CamelSmtpTransport *transport, CamelMimeMessage *message, CamelExcept
 		CAMEL_DATA_WRAPPER (message), filtered_stream);
 
 	/* restore the bcc headers */
-	header->next = savedbcc;
+	camel_header_raw_append_queue (header_queue, &bcc_queue);
 
 	if (ret == -1) {
 		camel_exception_setv (ex, errno == EINTR ? CAMEL_EXCEPTION_USER_CANCEL : CAMEL_EXCEPTION_SYSTEM,
diff --git a/docs/reference/camel/camel-sections.txt b/docs/reference/camel/camel-sections.txt
index 0033a34..4edcbe0 100644
--- a/docs/reference/camel/camel-sections.txt
+++ b/docs/reference/camel/camel-sections.txt
@@ -3862,7 +3862,6 @@ CamelTransferEncoding
 camel_header_references
 camel_header_param
 CamelContentType
-camel_header_raw
 CamelContentDisposition
 camel_header_address_t
 camel_header_address
@@ -3904,13 +3903,17 @@ camel_content_disposition_ref
 camel_content_disposition_unref
 camel_content_disposition_format
 camel_content_transfer_encoding_decode
+CamelHeaderRaw
+camel_header_raw_get_name
+camel_header_raw_get_value
+camel_header_raw_get_offset
 camel_header_raw_append
+camel_header_raw_append_queue
 camel_header_raw_append_parse
+camel_header_raw_extract
+camel_header_raw_extract_prefix
 camel_header_raw_find
-camel_header_raw_find_next
-camel_header_raw_replace
 camel_header_raw_remove
-camel_header_raw_fold
 camel_header_raw_clear
 camel_header_raw_check_mailing_list
 camel_header_address_fold
diff --git a/docs/reference/camel/tmpl/camel-folder-summary.sgml b/docs/reference/camel/tmpl/camel-folder-summary.sgml
index f95e261..1e5856b 100644
--- a/docs/reference/camel/tmpl/camel-folder-summary.sgml
+++ b/docs/reference/camel/tmpl/camel-folder-summary.sgml
@@ -383,7 +383,7 @@ CamelFolderSummary
 </para>
 
 @summary: 
- headers: 
+ header_queue: 
 @Returns: 
 
 
@@ -413,7 +413,7 @@ CamelFolderSummary
 </para>
 
 @summary: 
- headers: 
+ header_queue: 
 @Returns: 
 
 
@@ -761,7 +761,7 @@ CamelFolderSummary
 </para>
 
 @summary: 
- header: 
+ header_queue: 
 @Returns: 
 
 
diff --git a/docs/reference/camel/tmpl/camel-local-summary.sgml b/docs/reference/camel/tmpl/camel-local-summary.sgml
index 1e75c55..37238be 100644
--- a/docs/reference/camel/tmpl/camel-local-summary.sgml
+++ b/docs/reference/camel/tmpl/camel-local-summary.sgml
@@ -129,7 +129,7 @@ CamelLocalSummary
 </para>
 
 @fd: 
- header: 
+ header_queue: 
 @xevline: 
 @status: 
 @xstatus: 
diff --git a/docs/reference/camel/tmpl/camel-mime-utils.sgml b/docs/reference/camel/tmpl/camel-mime-utils.sgml
index 5d47a94..8e3d480 100644
--- a/docs/reference/camel/tmpl/camel-mime-utils.sgml
+++ b/docs/reference/camel/tmpl/camel-mime-utils.sgml
@@ -101,16 +101,6 @@ camel-mime-utils
 @params: 
 @refcount: 
 
-<!-- ##### STRUCT camel_header_raw ##### -->
-<para>
-
-</para>
-
- next: 
- name: 
- value: 
- offset: 
-
 <!-- ##### STRUCT CamelContentDisposition ##### -->
 <para>
 
@@ -481,76 +471,109 @@ camel-mime-utils
 @Returns: 
 
 
+<!-- ##### STRUCT CamelHeaderRaw ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### FUNCTION camel_header_raw_get_name ##### -->
+<para>
+
+</para>
+
+ raw_header: 
+ Returns: 
+
+
+<!-- ##### FUNCTION camel_header_raw_get_value ##### -->
+<para>
+
+</para>
+
+ raw_header: 
+ Returns: 
+
+
+<!-- ##### FUNCTION camel_header_raw_get_offset ##### -->
+<para>
+
+</para>
+
+ raw_header: 
+ Returns: 
+
+
 <!-- ##### FUNCTION camel_header_raw_append ##### -->
 <para>
 
 </para>
 
- list: 
- name: 
- value: 
+ header_queue: 
+ header_name: 
+ header_value: 
 @offset: 
 
 
-<!-- ##### FUNCTION camel_header_raw_append_parse ##### -->
+<!-- ##### FUNCTION camel_header_raw_append_queue ##### -->
 <para>
 
 </para>
 
- list: 
- header: 
- offset: 
+ header_queue: 
+ source_queue: 
 
 
-<!-- ##### FUNCTION camel_header_raw_find ##### -->
+<!-- ##### FUNCTION camel_header_raw_append_parse ##### -->
 <para>
 
 </para>
 
- list: 
- name: 
+ header_queue: 
+ string: 
 @offset: 
- Returns: 
 
 
-<!-- ##### FUNCTION camel_header_raw_find_next ##### -->
+<!-- ##### FUNCTION camel_header_raw_extract ##### -->
 <para>
 
 </para>
 
- list: 
- name: 
- offset: 
- last: 
+ header_queue: 
+ destination_queue: 
+ header_name: 
 @Returns: 
 
 
-<!-- ##### FUNCTION camel_header_raw_replace ##### -->
+<!-- ##### FUNCTION camel_header_raw_extract_prefix ##### -->
 <para>
 
 </para>
 
- list: 
- name: 
- value: 
- offset: 
+ header_queue: 
+ destination_queue: 
+ header_prefix: 
+ Returns: 
 
 
-<!-- ##### FUNCTION camel_header_raw_remove ##### -->
+<!-- ##### FUNCTION camel_header_raw_find ##### -->
 <para>
 
 </para>
 
- list: 
- name: 
+ header_queue: 
+ header_name: 
+ offset: 
+ Returns: 
 
 
-<!-- ##### FUNCTION camel_header_raw_fold ##### -->
+<!-- ##### FUNCTION camel_header_raw_remove ##### -->
 <para>
 
 </para>
 
- list: 
+ header_queue: 
+ header_name: 
 
 
 <!-- ##### FUNCTION camel_header_raw_clear ##### -->
@@ -558,7 +581,7 @@ camel-mime-utils
 
 </para>
 
- list: 
+ header_queue: 
 
 
 <!-- ##### FUNCTION camel_header_raw_check_mailing_list ##### -->
@@ -566,7 +589,7 @@ camel-mime-utils
 
 </para>
 
- list: 
+ header_queue: 
 @Returns: 
 
 
diff --git a/docs/reference/camel/tmpl/camel-spool-summary.sgml b/docs/reference/camel/tmpl/camel-spool-summary.sgml
index 013566d..3fd7936 100644
--- a/docs/reference/camel/tmpl/camel-spool-summary.sgml
+++ b/docs/reference/camel/tmpl/camel-spool-summary.sgml
@@ -119,7 +119,7 @@ CamelSpoolSummary
 </para>
 
 @fd: 
- header: 
+ header_queue: 
 @xevline: 
 @Returns: 
 
diff --git a/docs/reference/camel/tmpl/camel-unused.sgml b/docs/reference/camel/tmpl/camel-unused.sgml
index dd988ae..911549f 100644
--- a/docs/reference/camel/tmpl/camel-unused.sgml
+++ b/docs/reference/camel/tmpl/camel-unused.sgml
@@ -741,6 +741,44 @@ camel-types
 @summary: 
 @array: 
 
+<!-- ##### STRUCT camel_header_raw ##### -->
+<para>
+
+</para>
+
+ next: 
+ name: 
+ value: 
+ offset: 
+
+<!-- ##### FUNCTION camel_header_raw_find_next ##### -->
+<para>
+
+</para>
+
+ header_queue: 
+ header_name: 
+ offset: 
+ last_value: 
+ Returns: 
+
+<!-- ##### FUNCTION camel_header_raw_fold ##### -->
+<para>
+
+</para>
+
+ list: 
+
+<!-- ##### FUNCTION camel_header_raw_replace ##### -->
+<para>
+
+</para>
+
+ header_queue: 
+ header_name: 
+ header_value: 
+ offset: 
+
 <!-- ##### FUNCTION camel_imap_store_summary_namespace_new ##### -->
 <para>
 



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