[evolution-data-server/wip/camel-more-gobject] Bug 773787 - Replace CamelHeaderRaw by CamelNameValueArray



commit fc2e5c78ecc1eb1afddd5724718503103d4baeee
Author: Corentin Noël <corentin elementary io>
Date:   Fri Nov 4 12:38:15 2016 +0100

    Bug 773787 - Replace CamelHeaderRaw by CamelNameValueArray

 src/camel/camel-enums.h                            |   14 +
 src/camel/camel-filter-driver.c                    |   12 +-
 src/camel/camel-filter-search.c                    |   30 +-
 src/camel/camel-folder-search.c                    |   25 +-
 src/camel/camel-folder-summary.c                   |  116 +++---
 src/camel/camel-folder-summary.h                   |   15 +-
 src/camel/camel-folder.c                           |    7 +-
 src/camel/camel-medium.c                           |   30 ++-
 src/camel/camel-medium.h                           |    4 +
 src/camel/camel-message-info-base.c                |   10 +-
 src/camel/camel-message-info.c                     |   12 +-
 src/camel/camel-mime-message.c                     |   11 +-
 src/camel/camel-mime-parser.c                      |   96 ++++-
 src/camel/camel-mime-parser.h                      |    5 +-
 src/camel/camel-mime-part-utils.c                  |   23 +-
 src/camel/camel-mime-part-utils.h                  |    4 +-
 src/camel/camel-mime-part.c                        |  156 ++++----
 src/camel/camel-mime-part.h                        |    3 +-
 src/camel/camel-mime-utils.c                       |  427 +++++---------------
 src/camel/camel-mime-utils.h                       |   24 +-
 src/camel/camel-movemail.c                         |   24 +-
 src/camel/camel-name-value-array.c                 |   49 ++-
 src/camel/camel-name-value-array.h                 |    9 +-
 src/camel/camel-named-flags.c                      |    4 +-
 src/camel/camel-search-private.c                   |    6 +-
 .../providers/imapx/camel-imapx-message-info.c     |    2 +-
 src/camel/providers/imapx/camel-imapx-summary.c    |   19 +-
 src/camel/providers/local/camel-local-summary.c    |   39 +-
 src/camel/providers/local/camel-local-summary.h    |    2 +-
 src/camel/providers/local/camel-maildir-summary.c  |   18 +-
 src/camel/providers/local/camel-mbox-summary.c     |   36 +-
 src/camel/providers/local/camel-spool-summary.h    |    3 -
 src/camel/providers/nntp/camel-nntp-folder.c       |   39 +-
 src/camel/providers/nntp/camel-nntp-summary.c      |   22 +-
 src/camel/providers/pop3/camel-pop3-folder.c       |   19 +-
 .../providers/sendmail/camel-sendmail-transport.c  |   55 ++-
 src/camel/providers/smtp/camel-smtp-transport.c    |   33 +-
 37 files changed, 681 insertions(+), 722 deletions(-)
---
diff --git a/src/camel/camel-enums.h b/src/camel/camel-enums.h
index 13577db..e20578e 100644
--- a/src/camel/camel-enums.h
+++ b/src/camel/camel-enums.h
@@ -474,4 +474,18 @@ typedef enum {
        CAMEL_THREE_STATE_INCONSISTENT
 } CamelThreeState;
 
+/**
+ * CamelCompareType:
+ * @CAMEL_COMPARE_CASE_INSENSITIVE: compare case insensitively
+ * @CAMEL_COMPARE_CASE_SENSITIVE: compare case sensitively
+ *
+ * Declares the compare type to use.
+ *
+ * Since: 3.24
+ **/
+typedef enum {
+       CAMEL_COMPARE_CASE_INSENSITIVE,
+       CAMEL_COMPARE_CASE_SENSITIVE
+} CamelCompareType;
+
 #endif /* CAMEL_ENUMS_H */
diff --git a/src/camel/camel-filter-driver.c b/src/camel/camel-filter-driver.c
index ed32998..eacab5d 100644
--- a/src/camel/camel-filter-driver.c
+++ b/src/camel/camel-filter-driver.c
@@ -1422,6 +1422,7 @@ camel_filter_driver_filter_mbox (CamelFilterDriver *driver,
        while (camel_mime_parser_step (mp, NULL, NULL) == CAMEL_MIME_PARSER_STATE_FROM) {
                CamelMessageInfo *info;
                CamelMimeMessage *message;
+               const CamelNameValueArray *headers;
                CamelMimePart *mime_part;
                gint pc = 0;
                const gchar *xev;
@@ -1449,9 +1450,10 @@ camel_filter_driver_filter_mbox (CamelFilterDriver *driver,
                        goto fail;
                }
 
-               info = camel_message_info_new_from_header (NULL, mime_part->headers);
+               headers = camel_medium_get_headers (CAMEL_MEDIUM (mime_part));
+               info = camel_message_info_new_from_headers (NULL, headers);
                /* Try and see if it has X-Evolution headers */
-               xev = camel_header_raw_find (&mime_part->headers, "X-Evolution", NULL);
+               xev = camel_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE, 
"X-Evolution");
                if (xev)
                        decode_flags_from_xev (xev, info);
 
@@ -1691,7 +1693,7 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver,
        g_return_val_if_fail (message != NULL || (source != NULL && uid != NULL), -1);
 
        if (info == NULL) {
-               CamelHeaderRaw *h;
+               const CamelNameValueArray *headers;
 
                if (message) {
                        g_object_ref (message);
@@ -1702,8 +1704,8 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver,
                                return -1;
                }
 
-               h = CAMEL_MIME_PART (message)->headers;
-               info = camel_message_info_new_from_header (NULL, h);
+               headers = camel_medium_get_headers (CAMEL_MEDIUM (message));
+               info = camel_message_info_new_from_headers (NULL, headers);
                freeinfo = TRUE;
        } else {
                if (camel_message_info_get_flags (info) & CAMEL_MESSAGE_DELETED)
diff --git a/src/camel/camel-filter-search.c b/src/camel/camel-filter-search.c
index b32cb89..1d85d59 100644
--- a/src/camel/camel-filter-search.c
+++ b/src/camel/camel-filter-search.c
@@ -254,10 +254,12 @@ check_header (struct _CamelSExp *f,
                } else if (fms->message || !check_header_in_message_info (fms->info, argc, argv, how, 
&matched)) {
                        CamelMimeMessage *message;
                        CamelMimePart *mime_part;
-                       CamelHeaderRaw *header;
+                       const CamelNameValueArray *headers;
                        const gchar *charset = NULL;
                        camel_search_t type = CAMEL_SEARCH_TYPE_ENCODED;
                        CamelContentType *ct;
+                       guint ii;
+                       const gchar *header_name = NULL, *header_value = NULL;
 
                        message = camel_filter_search_get_message (fms, f);
                        mime_part = CAMEL_MIME_PART (message);
@@ -272,12 +274,13 @@ check_header (struct _CamelSExp *f,
                                }
                        }
 
-                       for (header = mime_part->headers; header && !matched; header = header->next) {
+                       headers = camel_medium_get_headers (CAMEL_MEDIUM (mime_part));
+                       for (ii = 0; camel_name_value_array_get (headers, ii, &header_name, &header_value); 
ii++) {
                                /* empty name means any header */
-                               if (!name || !*name || !g_ascii_strcasecmp (header->name, name)) {
+                               if (!name || !*name || !g_ascii_strcasecmp (header_name, name)) {
                                        for (i = 1; i < argc && !matched; i++) {
                                                if (argv[i]->type == CAMEL_SEXP_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);
                                        }
                                }
                        }
@@ -933,25 +936,28 @@ junk_test (struct _CamelSExp *f,
        /* Not every message info has headers available, thus try headers of the message itself */
        message = camel_filter_search_get_message (fms, f);
        if (message) {
-               CamelHeaderRaw *h;
+               const CamelNameValueArray *headers;
+               const gchar *raw_name = NULL, *raw_value = NULL;
+               guint ii;
 
-               for (h = CAMEL_MIME_PART (message)->headers; h; h = h->next) {
+               headers = camel_medium_get_headers (CAMEL_MEDIUM (message));
+               for (ii = 0; camel_name_value_array_get (headers, ii, &raw_name, &raw_value); ii++) {
                        const gchar *value;
-
-                       if (!h->name)
+                       if (!raw_name)
                                continue;
 
-                       value = g_hash_table_lookup ((GHashTable *) ht, h->name);
+                       value = g_hash_table_lookup ((GHashTable *) ht, raw_name);
                        if (!value)
                                continue;
 
-                       message_is_junk = camel_strstrcase (h->value, value) != NULL;
+                       message_is_junk = camel_strstrcase (raw_value, value) != NULL;
 
                        if (message_is_junk) {
-                               if (camel_debug ("junk"))
+                               if (camel_debug ("junk")) {
                                        printf (
                                                "Message contains \"%s: %s\"",
-                                               h->name, value);
+                                               raw_name, value);
+                               }
                                goto done;
                        }
                }
diff --git a/src/camel/camel-folder-search.c b/src/camel/camel-folder-search.c
index 289c59f..850d27d 100644
--- a/src/camel/camel-folder-search.c
+++ b/src/camel/camel-folder-search.c
@@ -309,7 +309,6 @@ check_header (CamelSExp *sexp,
                camel_search_t type = CAMEL_SEARCH_TYPE_ASIS;
                struct _camel_search_words *words;
                CamelMimeMessage *message = NULL;
-               CamelHeaderRaw *raw_header;
 
                /* only a subset of headers are supported .. */
                headername = argv[0]->value.string;
@@ -361,15 +360,20 @@ check_header (CamelSExp *sexp,
                                        truth = TRUE;
                                        for (j = 0; j < words->len && truth; j++) {
                                                if (message) {
-                                                       for (raw_header = ((CamelMimePart *) 
message)->headers; raw_header; raw_header = raw_header->next) {
+                                                       const CamelNameValueArray *headers = NULL;
+                                                       const gchar *raw_name = NULL, *raw_value = NULL;
+                                                       guint ii;
+
+                                                       headers = camel_medium_get_headers (CAMEL_MEDIUM 
(message));
+                                                       for (ii = 0; camel_name_value_array_get (headers, ii, 
&raw_name, &raw_value); ii++) {
                                                                /* empty name means any header */
-                                                               if (!headername || !*headername || 
!g_ascii_strcasecmp (raw_header->name, headername)) {
-                                                                       if (camel_search_header_match 
(raw_header->value, words->words[j]->word, how, type, charset))
+                                                               if (!headername || !*headername || 
!g_ascii_strcasecmp (raw_name, headername)) {
+                                                                       if (camel_search_header_match 
(raw_value, words->words[j]->word, how, type, charset))
                                                                                break;
                                                                }
                                                        }
 
-                                                       truth = raw_header != NULL;
+                                                       truth = ii < camel_name_value_array_get_length 
(headers);
                                                } else
                                                        truth = camel_search_header_match (
                                                                header,
@@ -379,11 +383,16 @@ check_header (CamelSExp *sexp,
                                        camel_search_words_free (words);
                                } else {
                                        if (message) {
-                                               for (raw_header = ((CamelMimePart *) message)->headers; 
raw_header && !truth; raw_header = raw_header->next) {
+                                               const CamelNameValueArray *headers = NULL;
+                                               const gchar *raw_name = NULL, *raw_value = NULL;
+                                               guint ii;
+
+                                               headers = camel_medium_get_headers (CAMEL_MEDIUM (message));
+                                               for (ii = 0; camel_name_value_array_get (headers, ii, 
&raw_name, &raw_value); ii++) {
                                                        /* empty name means any header */
-                                                       if (!headername || !*headername || 
!g_ascii_strcasecmp (raw_header->name, headername)) {
+                                                       if (!headername || !*headername || 
!g_ascii_strcasecmp (raw_name, headername)) {
                                                                truth = camel_search_header_match (
-                                                                       raw_header->value,
+                                                                       raw_value,
                                                                        argv[i]->value.string,
                                                                        how, type, charset);
                                                        }
diff --git a/src/camel/camel-folder-summary.c b/src/camel/camel-folder-summary.c
index 13c0043..e7f0234 100644
--- a/src/camel/camel-folder-summary.c
+++ b/src/camel/camel-folder-summary.c
@@ -121,7 +121,7 @@ static void cfs_schedule_info_release_timer (CamelFolderSummary *summary);
 static void summary_traverse_content_with_parser (CamelFolderSummary *summary, CamelMessageInfo *msginfo, 
CamelMimeParser *mp);
 static void summary_traverse_content_with_part (CamelFolderSummary *summary, CamelMessageInfo *msginfo, 
CamelMimePart *object);
 
-static CamelMessageInfo * message_info_new_from_header (CamelFolderSummary *, CamelHeaderRaw *);
+static CamelMessageInfo * message_info_new_from_headers (CamelFolderSummary *, const CamelNameValueArray *);
 static CamelMessageInfo * message_info_new_from_parser (CamelFolderSummary *, CamelMimeParser *);
 static CamelMessageInfo * message_info_new_from_message (CamelFolderSummary *summary, CamelMimeMessage *msg);
 
@@ -614,7 +614,7 @@ camel_folder_summary_class_init (CamelFolderSummaryClass *class)
        class->summary_header_load = summary_header_load;
        class->summary_header_save = summary_header_save;
 
-       class->message_info_new_from_header = message_info_new_from_header;
+       class->message_info_new_from_headers = message_info_new_from_headers;
        class->message_info_new_from_parser = message_info_new_from_parser;
        class->message_info_new_from_message = message_info_new_from_message;
        class->message_info_from_uid = message_info_from_uid;
@@ -867,7 +867,7 @@ camel_folder_summary_get_version (CamelFolderSummary *summary)
 }
 
 /**
- * camel_folder_summary_get_version:
+ * camel_folder_summary_set_version:
  * @summary: a #CamelFolderSummary
  * @version: version to set
  *
@@ -2324,27 +2324,29 @@ camel_folder_summary_add (CamelFolderSummary *summary,
 }
 
 /**
- * camel_folder_summary_info_new_from_header:
+ * camel_folder_summary_info_new_from_headers:
  * @summary: a #CamelFolderSummary object
- * @headers: rfc822 headers
+ * @headers: rfc822 headers as #CamelNameValueArray
  *
  * Create a new info record from a header.
  *
  * Returns: (transfer full): a newly created #CamelMessageInfo. Unref it
  *   with g_object_unref(), when done with it.
+ *
+ * Since: 3.24
  **/
 CamelMessageInfo *
-camel_folder_summary_info_new_from_header (CamelFolderSummary *summary,
-                                           CamelHeaderRaw *h)
+camel_folder_summary_info_new_from_headers (CamelFolderSummary *summary,
+                                           const CamelNameValueArray *headers)
 {
        CamelFolderSummaryClass *class;
 
        g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), NULL);
 
        class = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary);
-       g_return_val_if_fail (class->message_info_new_from_header != NULL, NULL);
+       g_return_val_if_fail (class->message_info_new_from_headers != NULL, NULL);
 
-       return class->message_info_new_from_header (summary, h);
+       return class->message_info_new_from_headers (summary, headers);
 }
 
 /**
@@ -2694,6 +2696,7 @@ message_info_new_from_parser (CamelFolderSummary *summary,
                               CamelMimeParser *mp)
 {
        CamelMessageInfo *mi = NULL;
+       CamelNameValueArray *headers;
        gint state;
 
        state = camel_mime_parser_state (mp);
@@ -2701,7 +2704,9 @@ message_info_new_from_parser (CamelFolderSummary *summary,
        case CAMEL_MIME_PARSER_STATE_HEADER:
        case CAMEL_MIME_PARSER_STATE_MESSAGE:
        case CAMEL_MIME_PARSER_STATE_MULTIPART:
-               mi = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->message_info_new_from_header (summary, 
camel_mime_parser_headers_raw (mp));
+               headers = camel_mime_parser_dup_headers (mp);
+               mi = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->message_info_new_from_headers (summary, 
headers);
+               camel_name_value_array_free (headers);
                break;
        default:
                g_error ("Invalid parser state");
@@ -2714,24 +2719,26 @@ static CamelMessageInfo *
 message_info_new_from_message (CamelFolderSummary *summary,
                                CamelMimeMessage *msg)
 {
-       return CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->message_info_new_from_header (summary, 
((CamelMimePart *) msg)->headers);
+       return CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->message_info_new_from_headers (summary, 
camel_medium_get_headers (CAMEL_MEDIUM (msg)));
 }
 
 static gchar *
-summary_format_address (CamelHeaderRaw *h,
+summary_format_address (const CamelNameValueArray *headers,
                         const gchar *name,
                         const gchar *charset)
 {
-       CamelHeaderAddress *addr;
-       gchar *text, *str;
+       CamelHeaderAddress *addr = NULL;
+       gchar *text = NULL, *str = NULL;
+       const gchar *value;
 
-       if (!(text = (gchar *) camel_header_raw_find (&h, name, NULL)))
+       value = camel_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE, name);
+       if (!value)
                return NULL;
 
-       while (isspace ((unsigned) *text))
-               text++;
+       while (*value && g_ascii_isspace (*value))
+               value++;
 
-       text = camel_header_unfold (text);
+       text = camel_header_unfold (value);
 
        if ((addr = camel_header_address_decode (text, charset))) {
                str = camel_header_address_list_format (addr);
@@ -2745,19 +2752,21 @@ summary_format_address (CamelHeaderRaw *h,
 }
 
 static gchar *
-summary_format_string (CamelHeaderRaw *h,
+summary_format_string (const CamelNameValueArray *headers,
                        const gchar *name,
                        const gchar *charset)
 {
        gchar *text, *str;
+       const gchar *value;
 
-       if (!(text = (gchar *) camel_header_raw_find (&h, name, NULL)))
+       value = camel_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE, name);
+       if (!value)
                return NULL;
 
-       while (isspace ((unsigned) *text))
-               text++;
+       while (*value && g_ascii_isspace (*value))
+               value++;
 
-       text = camel_header_unfold (text);
+       text = camel_header_unfold (value);
        str = camel_header_decode_string (text, charset);
        g_free (text);
 
@@ -2765,8 +2774,8 @@ summary_format_string (CamelHeaderRaw *h,
 }
 
 static CamelMessageInfo *
-message_info_new_from_header (CamelFolderSummary *summary,
-                              CamelHeaderRaw *h)
+message_info_new_from_headers (CamelFolderSummary *summary,
+                              const CamelNameValueArray *headers)
 {
        const gchar *received, *date, *content, *charset = NULL;
        GSList *refs, *irt, *scan;
@@ -2785,7 +2794,7 @@ message_info_new_from_header (CamelFolderSummary *summary,
 
        camel_message_info_set_abort_notifications (mi, TRUE);
 
-       if ((content = camel_header_raw_find (&h, "Content-Type", NULL))
+       if ((content = camel_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE, 
"Content-Type"))
             && (ct = camel_content_type_decode (content))
             && (charset = camel_content_type_param (ct, "charset"))
             && (g_ascii_strcasecmp (charset, "us-ascii") == 0))
@@ -2793,11 +2802,11 @@ message_info_new_from_header (CamelFolderSummary *summary,
 
        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 (headers, "subject", charset);
+       from = summary_format_address (headers, "from", charset);
+       to = summary_format_address (headers, "to", charset);
+       cc = summary_format_address (headers, "cc", charset);
+       mlist = camel_headers_dup_mailing_list (headers);
 
        if (ct)
                camel_content_type_unref (ct);
@@ -2814,12 +2823,12 @@ message_info_new_from_header (CamelFolderSummary *summary,
        g_free (cc);
        g_free (mlist);
 
-       if ((date = camel_header_raw_find (&h, "date", NULL)))
+       if ((date = camel_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE, "Date")))
                camel_message_info_set_date_sent (mi, camel_header_decode_date (date, NULL));
        else
                camel_message_info_set_date_sent (mi, 0);
 
-       received = camel_header_raw_find (&h, "received", NULL);
+       received = camel_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE, "Received");
        if (received)
                received = strrchr (received, ';');
        if (received)
@@ -2835,7 +2844,7 @@ message_info_new_from_header (CamelFolderSummary *summary,
        if (!camel_message_info_get_date_sent (mi))
                camel_message_info_set_date_sent (mi, (gint64) time (NULL));
 
-       msgid = camel_header_msgid_decode (camel_header_raw_find (&h, "message-id", NULL));
+       msgid = camel_header_msgid_decode (camel_name_value_array_get_named (headers, 
CAMEL_COMPARE_CASE_INSENSITIVE, "Message-ID"));
        if (msgid) {
                GChecksum *checksum;
                CamelSummaryMessageID message_id;
@@ -2852,8 +2861,8 @@ message_info_new_from_header (CamelFolderSummary *summary,
        }
 
        /* decode our references and in-reply-to headers */
-       refs = camel_header_references_decode (camel_header_raw_find (&h, "references", NULL));
-       irt = camel_header_references_decode (camel_header_raw_find (&h, "in-reply-to", NULL));
+       refs = camel_header_references_decode (camel_name_value_array_get_named (headers, 
CAMEL_COMPARE_CASE_INSENSITIVE, "References"));
+       irt = camel_header_references_decode (camel_name_value_array_get_named (headers, 
CAMEL_COMPARE_CASE_INSENSITIVE, "In-Reply-To"));
        if (refs || irt) {
                GArray *references;
                CamelSummaryMessageID message_id;
@@ -3072,8 +3081,9 @@ summary_traverse_content_with_part (CamelFolderSummary *summary,
        gint parts, i;
        CamelFolderSummaryPrivate *p = summary->priv;
        CamelContentType *ct;
-       const CamelHeaderRaw *header;
+       const CamelNameValueArray *headers;
        gboolean is_calendar = FALSE, is_note = FALSE;
+       const gchar *header_name, *header_value;
 
        containee = camel_medium_get_content (CAMEL_MEDIUM (object));
 
@@ -3100,22 +3110,22 @@ summary_traverse_content_with_part (CamelFolderSummary *summary,
                camel_message_info_set_flags (msginfo, CAMEL_MESSAGE_SECURE, CAMEL_MESSAGE_SECURE);
        }
 
-       for (header = object->headers; header; header = header->next) {
-               const gchar *value = header->value;
+       headers = camel_medium_get_headers (CAMEL_MEDIUM (object));
+       for (i = 0; camel_name_value_array_get (headers, i, &header_name, &header_value); i++) {
+               const gchar *value = header_value;
 
-               /* skip preceding spaces in the value */
-               while (value && *value && isspace (*value))
+               while (value && *value && g_ascii_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 (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))) {
                        is_calendar = TRUE;
                        if (is_note)
                                break;
                }
 
-               if (header->name && value && g_ascii_strcasecmp (header->name, "X-Evolution-Note") == 0) {
+               if (header_name && value && g_ascii_strcasecmp (header_name, "X-Evolution-Note") == 0) {
                        is_note = TRUE;
                        if (is_calendar)
                                break;
@@ -3225,23 +3235,25 @@ camel_system_flag_get (CamelMessageFlags flags,
 }
 
 /**
- * camel_message_info_new_from_header:
+ * camel_message_info_new_from_headers:
  * @summary: a #CamelFolderSummary object or %NULL
- * @header: raw header
+ * @headers: a #CamelNameValueArray
  *
  * Create a new #CamelMessageInfo pre-populated with info from
- * @header.
+ * @headers.
  *
  * Returns: (transfer full): a new #CamelMessageInfo
+ *
+ * Since: 3.24
  **/
 CamelMessageInfo *
-camel_message_info_new_from_header (CamelFolderSummary *summary,
-                                    CamelHeaderRaw *header)
+camel_message_info_new_from_headers (CamelFolderSummary *summary,
+                                    const CamelNameValueArray *headers)
 {
        if (summary != NULL)
-               return CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->message_info_new_from_header (summary, 
header);
+               return CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->message_info_new_from_headers (summary, 
headers);
        else
-               return message_info_new_from_header (NULL, header);
+               return message_info_new_from_headers (NULL, headers);
 }
 
 /**
diff --git a/src/camel/camel-folder-summary.h b/src/camel/camel-folder-summary.h
index ca4c198..8fb53bb 100644
--- a/src/camel/camel-folder-summary.h
+++ b/src/camel/camel-folder-summary.h
@@ -99,9 +99,9 @@ struct _CamelFolderSummaryClass {
 
        /* create an individual message info */
        CamelMessageInfo *
-                       (*message_info_new_from_header)
+                       (*message_info_new_from_headers)
                                        (CamelFolderSummary *summary,
-                                        CamelHeaderRaw *header);
+                                        const CamelNameValueArray *headers);
        CamelMessageInfo *
                        (*message_info_new_from_parser)
                                        (CamelFolderSummary *summary,
@@ -189,9 +189,9 @@ void                camel_folder_summary_touch      (CamelFolderSummary *summary);
 
 /* Just build raw summary items */
 CamelMessageInfo *
-               camel_folder_summary_info_new_from_header
+               camel_folder_summary_info_new_from_headers
                                                (CamelFolderSummary *summary,
-                                                CamelHeaderRaw *headers);
+                                                const CamelNameValueArray *headers);
 CamelMessageInfo *
                camel_folder_summary_info_new_from_parser
                                                (CamelFolderSummary *summary,
@@ -211,7 +211,8 @@ gboolean    camel_folder_summary_remove     (CamelFolderSummary *summary,
 
 gboolean       camel_folder_summary_remove_uid (CamelFolderSummary *summary,
                                                 const gchar *uid);
-gboolean       camel_folder_summary_remove_uids (CamelFolderSummary *summary,
+gboolean       camel_folder_summary_remove_uids
+                                               (CamelFolderSummary *summary,
                                                 GList *uids);
 
 /* remove all items */
@@ -263,9 +264,9 @@ gboolean    camel_system_flag_get           (CamelMessageFlags flags,
                                                 const gchar *name);
 
 CamelMessageInfo *
-               camel_message_info_new_from_header
+               camel_message_info_new_from_headers
                                                (CamelFolderSummary *summary,
-                                                CamelHeaderRaw *header);
+                                                const CamelNameValueArray *headers);
 G_END_DECLS
 
 #endif /* CAMEL_FOLDER_SUMMARY_H */
diff --git a/src/camel/camel-folder.c b/src/camel/camel-folder.c
index 3fa60fc..3d221c8 100644
--- a/src/camel/camel-folder.c
+++ b/src/camel/camel-folder.c
@@ -501,8 +501,11 @@ folder_transfer_message_to (CamelFolder *source,
            && (minfo = camel_folder_get_message_info (source, uid))) {
                info = camel_message_info_clone (minfo, NULL);
                g_clear_object (&minfo);
-       } else
-               info = camel_message_info_new_from_header (NULL, ((CamelMimePart *) msg)->headers);
+       } else {
+               const CamelNameValueArray *headers = camel_medium_get_headers (CAMEL_MEDIUM (msg));
+
+               info = camel_message_info_new_from_headers (NULL, headers);
+       }
 
        /* unset deleted flag when transferring from trash folder */
        if ((source_folder_flags & CAMEL_FOLDER_IS_TRASH) != 0)
diff --git a/src/camel/camel-medium.c b/src/camel/camel-medium.c
index c4a9767..2165881 100644
--- a/src/camel/camel-medium.c
+++ b/src/camel/camel-medium.c
@@ -256,7 +256,7 @@ camel_medium_remove_header (CamelMedium *medium,
  *
  * If the header occurs more than once, only retrieve the first
  * instance of the header.  For multi-occuring headers, use
- * camel_medium_dup_headers().
+ * camel_medium_dup_headers() or camel_medium_get_headers().
  *
  * Returns: (nullable): the value of the named header, or %NULL
  **/
@@ -281,8 +281,11 @@ camel_medium_get_header (CamelMedium *medium,
  *
  * Gets an array of all header name/value pairs. The values will be
  * decoded to UTF-8 for any headers that are recognized by Camel.
+ * See also camel_medium_get_headers().
  *
  * Returns: (transfer full): the array of headers, which must be freed with camel_name_value_array_free().
+ *
+ * Since: 3.24
  **/
 CamelNameValueArray *
 camel_medium_dup_headers (CamelMedium *medium)
@@ -298,6 +301,31 @@ camel_medium_dup_headers (CamelMedium *medium)
 }
 
 /**
+ * camel_medium_get_headers:
+ * @medium: a #CamelMedium object
+ *
+ * Gets an array of all header name/value pairs. The values will be
+ * decoded to UTF-8 for any headers that are recognized by Camel.
+ * See also camel_medium_dup_headers().
+ *
+ * Returns: (transfer none): the array of headers, owned by @medium.
+ *
+ * Since: 3.24
+ **/
+const CamelNameValueArray *
+camel_medium_get_headers (CamelMedium *medium)
+{
+       CamelMediumClass *class;
+
+       g_return_val_if_fail (CAMEL_IS_MEDIUM (medium), NULL);
+
+       class = CAMEL_MEDIUM_GET_CLASS (medium);
+       g_return_val_if_fail (class->get_headers != NULL, NULL);
+
+       return class->get_headers (medium);
+}
+
+/**
  * camel_medium_get_content:
  * @medium: a #CamelMedium object
  *
diff --git a/src/camel/camel-medium.h b/src/camel/camel-medium.h
index 6d59275..9872cc6 100644
--- a/src/camel/camel-medium.h
+++ b/src/camel/camel-medium.h
@@ -74,6 +74,8 @@ struct _CamelMediumClass {
                                                 const gchar *name);
        CamelNameValueArray *
                        (*dup_headers)          (CamelMedium *medium);
+       const CamelNameValueArray *
+                       (*get_headers)          (CamelMedium *medium);
        CamelDataWrapper *
                        (*get_content)          (CamelMedium *medium);
        void            (*set_content)          (CamelMedium *medium,
@@ -96,6 +98,8 @@ const gchar * camel_medium_get_header         (CamelMedium *medium,
                                                 const gchar *name);
 CamelNameValueArray *
                camel_medium_dup_headers        (CamelMedium *medium);
+const CamelNameValueArray *
+               camel_medium_get_headers        (CamelMedium *medium);
 CamelDataWrapper *
                camel_medium_get_content        (CamelMedium *medium);
 void           camel_medium_set_content        (CamelMedium *medium,
diff --git a/src/camel/camel-message-info-base.c b/src/camel/camel-message-info-base.c
index ce8315e..71b1b70 100644
--- a/src/camel/camel-message-info-base.c
+++ b/src/camel/camel-message-info-base.c
@@ -209,7 +209,7 @@ message_info_base_get_user_tag (const CamelMessageInfo *mi,
 
        camel_message_info_property_lock (mi);
        if (bmi->priv->user_tags)
-               result = camel_name_value_array_get_named (bmi->priv->user_tags, TRUE, name);
+               result = camel_name_value_array_get_named (bmi->priv->user_tags, 
CAMEL_COMPARE_CASE_SENSITIVE, name);
        else
                result = NULL;
        camel_message_info_property_unlock (mi);
@@ -235,9 +235,9 @@ message_info_base_set_user_tag (CamelMessageInfo *mi,
                bmi->priv->user_tags = camel_name_value_array_new ();
 
        if (value)
-               changed = camel_name_value_array_set_named (bmi->priv->user_tags, TRUE, name, value);
+               changed = camel_name_value_array_set_named (bmi->priv->user_tags, 
CAMEL_COMPARE_CASE_SENSITIVE, name, value);
        else
-               changed = camel_name_value_array_remove_named (bmi->priv->user_tags, TRUE, name, FALSE);
+               changed = camel_name_value_array_remove_named (bmi->priv->user_tags, 
CAMEL_COMPARE_CASE_SENSITIVE, name, FALSE);
        camel_message_info_property_unlock (mi);
 
        return changed;
@@ -290,7 +290,7 @@ message_info_base_take_user_tags (CamelMessageInfo *mi,
 
        camel_message_info_property_lock (mi);
 
-       changed = !camel_name_value_array_equal (bmi->priv->user_tags, user_tags, TRUE);
+       changed = !camel_name_value_array_equal (bmi->priv->user_tags, user_tags, 
CAMEL_COMPARE_CASE_SENSITIVE);
 
        if (changed) {
                camel_name_value_array_free (bmi->priv->user_tags);
@@ -775,7 +775,7 @@ message_info_base_take_headers (CamelMessageInfo *mi,
 
        camel_message_info_property_lock (mi);
 
-       changed = !camel_name_value_array_equal (bmi->priv->headers, headers, TRUE);
+       changed = !camel_name_value_array_equal (bmi->priv->headers, headers, CAMEL_COMPARE_CASE_SENSITIVE);
 
        if (changed) {
                camel_name_value_array_free (bmi->priv->headers);
diff --git a/src/camel/camel-message-info.c b/src/camel/camel-message-info.c
index c4d4152..864e572 100644
--- a/src/camel/camel-message-info.c
+++ b/src/camel/camel-message-info.c
@@ -238,7 +238,7 @@ message_info_load (CamelMessageInfo *mi,
                        value = camel_util_bdata_get_string (&part, NULL);
 
                        if (name)
-                               camel_name_value_array_set_named (user_tags, TRUE, name, value ? value : "");
+                               camel_name_value_array_set_named (user_tags, CAMEL_COMPARE_CASE_SENSITIVE, 
name, value ? value : "");
 
                        g_free (name);
                        g_free (value);
@@ -2724,8 +2724,8 @@ camel_message_info_set_message_id (CamelMessageInfo *mi,
  * message as an array of guint64 numbers, partial MD5 sums. Each value
  * can be cast to #CamelSummaryMessageID.
  *
- * Returns: (transfer none) (nullable): A #GArray of guint64 encoded
- *   Message-ID-s; or %NULL when none are available.
+ * Returns: (transfer none) (nullable) (element-type guint64): A #GArray of
+ *   guint64 encoded Message-ID-s; or %NULL when none are available.
  *
  * Since: 3.24
  **/
@@ -2756,9 +2756,9 @@ camel_message_info_get_references (const CamelMessageInfo *mi)
  * message as an array of guint64 numbers, partial MD5 sums. Each value
  * can be cast to #CamelSummaryMessageID.
  *
- * Returns: (transfer full) (nullable): A #GArray of guint64 encoded
- *   Message-ID-s; or %NULL when none are available. Free returned array
- *   with g_array_unref() when no longer needed.
+ * Returns: (transfer full) (nullable) (element-type guint64): A #GArray of
+ *   guint64 encoded Message-ID-s; or %NULL when none are available. Free returned
+ *   array with g_array_unref() when no longer needed.
  *
  * Since: 3.24
  **/
diff --git a/src/camel/camel-mime-message.c b/src/camel/camel-mime-message.c
index b352d6b..8697a20 100644
--- a/src/camel/camel-mime-message.c
+++ b/src/camel/camel-mime-message.c
@@ -1224,7 +1224,7 @@ static const gchar tz_days[][4] = {
 gchar *
 camel_mime_message_build_mbox_from (CamelMimeMessage *message)
 {
-       CamelHeaderRaw *header = ((CamelMimePart *) message)->headers;
+       const CamelNameValueArray *headers;
        GString *out = g_string_new ("From ");
        gchar *ret;
        const gchar *tmp;
@@ -1232,9 +1232,10 @@ camel_mime_message_build_mbox_from (CamelMimeMessage *message)
        gint offset;
        struct tm tm;
 
-       tmp = camel_header_raw_find (&header, "Sender", NULL);
+       headers = camel_medium_get_headers (CAMEL_MEDIUM (message));
+       tmp = camel_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE, "Sender");
        if (tmp == NULL)
-               tmp = camel_header_raw_find (&header, "From", NULL);
+               tmp = camel_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE, "From");
        if (tmp != NULL) {
                CamelHeaderAddress *addr = camel_header_address_decode (tmp, NULL);
 
@@ -1252,7 +1253,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_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE, "Received");
        if (tmp) {
                tmp = strrchr (tmp, ';');
                if (tmp)
@@ -1261,7 +1262,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_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE, "Date");
 
        thetime = camel_header_decode_date (tmp, &offset);
        thetime += ((offset / 100) * (60 * 60)) + (offset % 100) * 60;
diff --git a/src/camel/camel-mime-parser.c b/src/camel/camel-mime-parser.c
index 51fefcd..cfbb4c5 100644
--- a/src/camel/camel-mime-parser.c
+++ b/src/camel/camel-mime-parser.c
@@ -60,6 +60,15 @@ gint inend_id = -1,
 #define _header_scan_state _CamelMimeParserPrivate
 #define _PRIVATE(obj) (((CamelMimeParser *)(obj))->priv)
 
+/* a raw rfc822 header */
+/* the value MUST be US-ASCII */
+typedef struct _camel_header_raw {
+       struct _camel_header_raw *next;
+       gchar *name;
+       gchar *value;
+       gint offset;            /* in file, if known */
+} CamelHeaderRaw;
+
 struct _header_scan_state {
 
     /* global state */
@@ -154,8 +163,13 @@ static goffset 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);
 
+static const gchar * header_raw_find (CamelHeaderRaw **list, const gchar *name, gint *offset);
+
 #ifdef MEMPOOL
 static void header_append_mempool (struct _header_scan_state *s, struct _header_scan_stack *h, gchar 
*header, gint offset);
+#else
+static void header_raw_free (CamelHeaderRaw *l);
+static void header_raw_clear (CamelHeaderRaw *l);
 #endif
 
 #if d(!)0
@@ -317,7 +331,7 @@ camel_mime_parser_header (CamelMimeParser *m,
        struct _header_scan_state *s = _PRIVATE (m);
 
        if (s->parts && s->parts->headers)
-               return camel_header_raw_find (&s->parts->headers, name, offset);
+               return header_raw_find (&s->parts->headers, name, offset);
 
        return NULL;
 }
@@ -330,18 +344,26 @@ camel_mime_parser_header (CamelMimeParser *m,
  * current state of the parser.  These headers are valid
  * until the next call to parser_step(), or parser_drop_step().
  *
- * Returns: (transfer none): The raw headers, or NULL if there are no headers
- * defined for the current part or state.  These are READ ONLY.
+ * Returns: (transfer full): The headers, or %NULL, if there are no headers
+ * defined for the current part or state. Free it with camel_name_value_array_free().
  *
- * Since: 2.22
+ * Since: 3.24
  **/
-CamelHeaderRaw *
-camel_mime_parser_headers_raw (CamelMimeParser *m)
+CamelNameValueArray *
+camel_mime_parser_dup_headers (CamelMimeParser *m)
 {
        struct _header_scan_state *s = _PRIVATE (m);
 
-       if (s->parts)
-               return s->parts->headers;
+       if (s->parts) {
+               CamelHeaderRaw *header = s->parts->headers;
+               CamelNameValueArray *header_copy = camel_name_value_array_new ();
+               while (header) {
+                       camel_name_value_array_append (header_copy, header->name, header->value);
+                       header = header->next;
+               }
+
+               return header_copy;
+       }
        return NULL;
 }
 
@@ -1688,7 +1710,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 = header_raw_find (&h->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")
@@ -1892,6 +1914,60 @@ folder_scan_drop_step (struct _header_scan_state *s)
        }
 }
 
+static CamelHeaderRaw *
+header_raw_find_node (CamelHeaderRaw **list,
+                      const gchar *name)
+{
+       CamelHeaderRaw *l;
+
+       l = *list;
+       while (l) {
+               if (!g_ascii_strcasecmp (l->name, name))
+                       break;
+               l = l->next;
+       }
+       return l;
+}
+
+static const gchar *
+header_raw_find (CamelHeaderRaw **list,
+                const gchar *name,
+                gint *offset)
+{
+       CamelHeaderRaw *l;
+
+       l = header_raw_find_node (list, name);
+       if (l) {
+               if (offset)
+                       *offset = l->offset;
+               return l->value;
+       } else
+               return NULL;
+}
+
+#ifndef MEMPOOL
+static void
+header_raw_free (CamelHeaderRaw *l)
+{
+       g_free (l->name);
+       g_free (l->value);
+       g_free (l);
+}
+
+static void
+header_raw_clear (CamelHeaderRaw **list)
+{
+       CamelHeaderRaw *l, *n;
+       l = *list;
+       while (l) {
+               n = l->next;
+               header_raw_free (l);
+               l = n;
+       }
+       *list = NULL;
+}
+#endif
+
 #ifdef STANDALONE
 gint main (gint argc, gchar **argv)
 {
@@ -1948,7 +2024,7 @@ gint main (gint argc, gchar **argv)
                                        charset = NULL;
                                }
 
-                               encoding = camel_header_raw_find (&s->parts->headers, 
"Content-transfer-encoding", 0);
+                               encoding = header_raw_find (&s->parts->headers, "Content-transfer-encoding", 
NULL);
                                printf ("encoding = '%s'\n", encoding);
                                if (encoding && !g_ascii_strncasecmp (encoding, " base64", 7)) {
                                        printf ("adding base64 filter\n");
diff --git a/src/camel/camel-mime-parser.h b/src/camel/camel-mime-parser.h
index 7fc0dfe..17cbaaf 100644
--- a/src/camel/camel-mime-parser.h
+++ b/src/camel/camel-mime-parser.h
@@ -27,6 +27,7 @@
 #include <camel/camel-mime-utils.h>
 #include <camel/camel-mime-filter.h>
 #include <camel/camel-stream.h>
+#include <camel/camel-name-value-array.h>
 
 /* Stardard GObject macros */
 #define CAMEL_TYPE_MIME_PARSER \
@@ -131,8 +132,8 @@ CamelContentType *camel_mime_parser_content_type (CamelMimeParser *parser);
 /* get/change raw header by name */
 const gchar *camel_mime_parser_header (CamelMimeParser *m, const gchar *name, gint *offset);
 
-/* get all raw headers. READ ONLY! */
-CamelHeaderRaw *camel_mime_parser_headers_raw (CamelMimeParser *m);
+/* get all raw headers */
+CamelNameValueArray *camel_mime_parser_dup_headers (CamelMimeParser *m);
 
 /* get multipart pre/postface */
 const gchar *camel_mime_parser_preface (CamelMimeParser *m);
diff --git a/src/camel/camel-mime-part-utils.c b/src/camel/camel-mime-part-utils.c
index babeee1..a87408f 100644
--- a/src/camel/camel-mime-part-utils.c
+++ b/src/camel/camel-mime-part-utils.c
@@ -195,6 +195,7 @@ CamelMessageContentInfo *
 camel_message_content_info_new_from_parser (CamelMimeParser *mp)
 {
        CamelMessageContentInfo *ci = NULL;
+       CamelNameValueArray *headers = NULL;
 
        g_return_val_if_fail (CAMEL_IS_MIME_PARSER (mp), NULL);
 
@@ -202,7 +203,9 @@ camel_message_content_info_new_from_parser (CamelMimeParser *mp)
        case CAMEL_MIME_PARSER_STATE_HEADER:
        case CAMEL_MIME_PARSER_STATE_MESSAGE:
        case CAMEL_MIME_PARSER_STATE_MULTIPART:
-               ci = camel_message_content_info_new_from_header (camel_mime_parser_headers_raw (mp));
+               headers = camel_mime_parser_dup_headers (mp);
+               ci = camel_message_content_info_new_from_headers (headers);
+               camel_name_value_array_free (headers);
                if (ci) {
                        if (ci->type)
                                camel_content_type_unref (ci->type);
@@ -220,13 +223,19 @@ camel_message_content_info_new_from_parser (CamelMimeParser *mp)
 CamelMessageContentInfo *
 camel_message_content_info_new_from_message (CamelMimePart *mp)
 {
+       CamelMessageContentInfo *ci = NULL;
+       const CamelNameValueArray *headers = NULL;
+
        g_return_val_if_fail (CAMEL_IS_MIME_PART (mp), NULL);
 
-       return camel_message_content_info_new_from_header (mp->headers);
+       headers = camel_medium_get_headers (CAMEL_MEDIUM (mp));
+       ci = camel_message_content_info_new_from_headers (headers);
+
+       return ci;
 }
 
 CamelMessageContentInfo *
-camel_message_content_info_new_from_header (CamelHeaderRaw *h)
+camel_message_content_info_new_from_headers (const CamelNameValueArray *headers)
 {
        CamelMessageContentInfo *ci;
        const gchar *charset;
@@ -234,10 +243,10 @@ camel_message_content_info_new_from_header (CamelHeaderRaw *h)
        ci = camel_message_content_info_new ();
 
        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));
+       ci->id = camel_header_msgid_decode (camel_name_value_array_get_named (headers, 
CAMEL_COMPARE_CASE_INSENSITIVE, "Content-ID"));
+       ci->description = camel_header_decode_string (camel_name_value_array_get_named (headers, 
CAMEL_COMPARE_CASE_INSENSITIVE, "Content-Description"), charset);
+       ci->encoding = camel_content_transfer_encoding_decode (camel_name_value_array_get_named (headers, 
CAMEL_COMPARE_CASE_INSENSITIVE, "Content-Transfer-Encoding"));
+       ci->type = camel_content_type_decode (camel_name_value_array_get_named (headers, 
CAMEL_COMPARE_CASE_INSENSITIVE, "Content-Type"));
 
        return ci;
 }
diff --git a/src/camel/camel-mime-part-utils.h b/src/camel/camel-mime-part-utils.h
index c76a686..dbb4175 100644
--- a/src/camel/camel-mime-part-utils.h
+++ b/src/camel/camel-mime-part-utils.h
@@ -57,8 +57,8 @@ CamelMessageContentInfo *
                camel_message_content_info_new  (void);
 void           camel_message_content_info_free (CamelMessageContentInfo *ci);
 CamelMessageContentInfo *
-               camel_message_content_info_new_from_header
-                                               (CamelHeaderRaw *header);
+               camel_message_content_info_new_from_headers
+                                               (const CamelNameValueArray *headers);
 CamelMessageContentInfo *
                camel_message_content_info_new_from_parser
                                                (CamelMimeParser *parser);
diff --git a/src/camel/camel-mime-part.c b/src/camel/camel-mime-part.c
index f2c92a3..beabf46 100644
--- a/src/camel/camel-mime-part.c
+++ b/src/camel/camel-mime-part.c
@@ -59,6 +59,8 @@ struct _CamelMimePartPrivate {
        gchar *content_location;
        GList *content_languages;
        CamelTransferEncoding encoding;
+       /* mime headers */
+       CamelNameValueArray *headers;
 };
 
 struct _AsyncContext {
@@ -450,8 +452,7 @@ mime_part_finalize (GObject *object)
 
        g_list_free_full (priv->content_languages, (GDestroyNotify) g_free);
        camel_content_disposition_unref (priv->disposition);
-
-       camel_header_raw_clear (&CAMEL_MIME_PART (object)->headers);
+       camel_name_value_array_free (priv->headers);
 
        /* Chain up to parent's finalize() method. */
        G_OBJECT_CLASS (camel_mime_part_parent_class)->finalize (object);
@@ -470,9 +471,9 @@ mime_part_add_header (CamelMedium *medium,
 
        /* If it was one of the headers we handled, it must be unique, set it instead of add */
        if (mime_part_process_header (medium, name, value))
-               camel_header_raw_replace (&part->headers, name, value, -1);
-       else
-               camel_header_raw_append (&part->headers, name, value, -1);
+               camel_name_value_array_remove_named (part->priv->headers, CAMEL_COMPARE_CASE_INSENSITIVE, 
name, TRUE);
+
+       camel_name_value_array_append (part->priv->headers, name, value);
 }
 
 static void
@@ -483,27 +484,29 @@ mime_part_set_header (CamelMedium *medium,
        CamelMimePart *part = CAMEL_MIME_PART (medium);
 
        mime_part_process_header (medium, name, value);
-       camel_header_raw_replace (&part->headers, name, value, -1);
+       camel_name_value_array_remove_named (part->priv->headers, CAMEL_COMPARE_CASE_INSENSITIVE, name, TRUE);
+
+       camel_name_value_array_append (part->priv->headers, name, value);
 }
 
 static void
 mime_part_remove_header (CamelMedium *medium,
                          const gchar *name)
 {
-       CamelMimePart *part = (CamelMimePart *) medium;
+       CamelMimePart *part = CAMEL_MIME_PART (medium);
 
        mime_part_process_header (medium, name, NULL);
-       camel_header_raw_remove (&part->headers, name);
+       camel_name_value_array_remove_named (part->priv->headers, CAMEL_COMPARE_CASE_INSENSITIVE, name, TRUE);
 }
 
 static const gchar *
 mime_part_get_header (CamelMedium *medium,
                       const gchar *name)
 {
-       CamelMimePart *part = (CamelMimePart *) medium;
+       CamelMimePart *part = CAMEL_MIME_PART (medium);
        const gchar *value;
 
-       value = camel_header_raw_find (&part->headers, name, NULL);
+       value = camel_name_value_array_get_named (part->priv->headers, CAMEL_COMPARE_CASE_INSENSITIVE, name);
 
        /* Skip leading whitespace. */
        while (value != NULL && g_ascii_isspace (*value))
@@ -515,16 +518,17 @@ mime_part_get_header (CamelMedium *medium,
 static CamelNameValueArray *
 mime_part_dup_headers (CamelMedium *medium)
 {
-       CamelMimePart *part = (CamelMimePart *) medium;
-       CamelNameValueArray *headers;
-       CamelHeaderRaw *h;
+       CamelMimePart *part = CAMEL_MIME_PART (medium);
 
-       headers = camel_name_value_array_new ();
-       for (h = part->headers; h; h = h->next) {
-               camel_name_value_array_append (headers, h->name, h->value);
-       }
+       return camel_name_value_array_copy (part->priv->headers);
+}
 
-       return headers;
+static const CamelNameValueArray *
+mime_part_get_headers (CamelMedium *medium)
+{
+       CamelMimePart *part = CAMEL_MIME_PART (medium);
+
+       return part->priv->headers;
 }
 
 static void
@@ -562,45 +566,38 @@ mime_part_write_to_stream_sync (CamelDataWrapper *dw,
        gssize total = 0;
        gssize count;
        gint errnosav;
+       guint ii;
+       const gchar *header_name = NULL, *header_value = NULL;
 
        d (printf ("mime_part::write_to_stream\n"));
 
        /* FIXME: something needs to be done about this ... */
        /* TODO: content-languages header? */
 
-       if (mp->headers) {
-               CamelHeaderRaw *h = mp->headers;
-               gchar *val;
+       for (ii = 0; camel_name_value_array_get (mp->priv->headers, ii, &header_name, &header_value); ii++) {
                gssize (*writefn) (
                        gpointer stream,
                        const gchar *name,
                        const gchar *value,
                        GCancellable *cancellable,
                        GError **error);
-
-               /* 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);
-                               count = 0;
-                       } else if ((writefn = g_hash_table_lookup (header_formatted_table, h->name)) == NULL) 
{
-                               val = camel_header_fold (val, strlen (h->name));
-                               count = write_header (
-                                       stream, h->name, val,
-                                       cancellable, error);
-                               g_free (val);
-                       } else {
-                               count = writefn (
-                                       stream, h->name, h->value,
-                                       cancellable, error);
-                       }
-                       if (count == -1)
-                               return -1;
-                       total += count;
-                       h = h->next;
+               if (header_value == NULL) {
+                       g_warning ("header_value is NULL here for %s", header_name);
+                       count = 0;
+               } else if ((writefn = g_hash_table_lookup (header_formatted_table, header_name)) == NULL) {
+                       gchar *val = camel_header_fold (header_value, strlen (header_name));
+                       count = write_header (
+                               stream, header_name, val,
+                               cancellable, error);
+                       g_free (val);
+               } else {
+                       count = writefn (
+                               stream, header_name, header_value,
+                               cancellable, error);
                }
+               if (count == -1)
+                       return -1;
+               total += count;
        }
 
        count = camel_stream_write (stream, "\n", 1, cancellable, error);
@@ -755,46 +752,39 @@ mime_part_write_to_output_stream_sync (CamelDataWrapper *dw,
        gssize total = 0;
        gssize result;
        gboolean success;
+       guint ii;
+       const gchar *header_name = NULL, *header_value = NULL;
 
        d (printf ("mime_part::write_to_stream\n"));
 
        /* FIXME: something needs to be done about this ... */
        /* TODO: content-languages header? */
 
-       if (mp->headers) {
-               CamelHeaderRaw *h = mp->headers;
-               gchar *val;
+       for (ii = 0; camel_name_value_array_get (mp->priv->headers, ii, &header_name, &header_value); ii++) {
                gssize (*writefn) (
                        gpointer stream,
                        const gchar *name,
                        const gchar *value,
                        GCancellable *cancellable,
                        GError **error);
-
-               /* 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);
-                               bytes_written = 0;
-                               result = 0;
-                       } else if ((writefn = g_hash_table_lookup (header_formatted_table, h->name)) == NULL) 
{
-                               val = camel_header_fold (val, strlen (h->name));
-                               result = write_header (
-                                       output_stream, h->name, val,
-                                       cancellable, error);
-                               g_free (val);
-                       } else {
-                               result = writefn (
-                                       output_stream, h->name, h->value,
-                                       cancellable, error);
-                       }
-                       if (result == -1)
-                               return -1;
-                       total += result;
-                       h = h->next;
+               if (header_value == NULL) {
+                       g_warning ("header_value is NULL here for %s", header_name);
+                       bytes_written = 0;
+                       result = 0;
+               } else if ((writefn = g_hash_table_lookup (header_formatted_table, header_name)) == NULL) {
+                       gchar *val = camel_header_fold (header_value, strlen (header_name));
+                       result = write_header (
+                               output_stream, header_name, val,
+                               cancellable, error);
+                       g_free (val);
+               } else {
+                       result = writefn (
+                               output_stream, header_name, header_value,
+                               cancellable, error);
                }
+               if (result == -1)
+                       return -1;
+               total += result;
        }
 
        success = g_output_stream_write_all (
@@ -960,12 +950,14 @@ mime_part_construct_from_parser_sync (CamelMimePart *mime_part,
                                       GError **error)
 {
        CamelDataWrapper *dw = (CamelDataWrapper *) mime_part;
-       CamelHeaderRaw *headers;
+       CamelNameValueArray *headers;
        const gchar *content;
        gchar *buf;
        gsize len;
        gint err;
+       guint ii;
        gboolean success = TRUE;
+       const gchar *header_name = NULL, *header_value = NULL;
 
        switch (camel_mime_parser_step (parser, &buf, &len)) {
        case CAMEL_MIME_PARSER_STATE_MESSAGE:
@@ -976,22 +968,22 @@ mime_part_construct_from_parser_sync (CamelMimePart *mime_part,
        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 (parser);
+               headers = camel_mime_parser_dup_headers (parser);
 
                /* if content-type exists, process it first, set for fallback charset in headers */
-               content = camel_header_raw_find (&headers, "content-type", NULL);
+               content = camel_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE, 
"Content-Type");
                if (content)
-                       mime_part_process_header ((CamelMedium *) dw, "content-type", content);
+                       mime_part_process_header (CAMEL_MEDIUM (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);
+               for (ii = 0; camel_name_value_array_get (headers, ii, &header_name, &header_value); ii++) {
+                       if (g_ascii_strcasecmp (header_name, "content-type") == 0 && header_value != content)
+                               camel_medium_add_header (CAMEL_MEDIUM (dw), "X-Invalid-Content-Type", 
header_value);
                        else
-                               camel_medium_add_header ((CamelMedium *) dw, headers->name, headers->value);
-                       headers = headers->next;
+                               camel_medium_add_header (CAMEL_MEDIUM (dw), header_name, header_value);
                }
 
+               camel_name_value_array_free (headers);
+
                success = camel_mime_part_construct_content_from_parser (
                        mime_part, parser, cancellable, error);
                break;
@@ -1032,6 +1024,7 @@ camel_mime_part_class_init (CamelMimePartClass *class)
        medium_class->remove_header = mime_part_remove_header;
        medium_class->get_header = mime_part_get_header;
        medium_class->dup_headers = mime_part_dup_headers;
+       medium_class->get_headers = mime_part_get_headers;
        medium_class->set_content = mime_part_set_content;
 
        data_wrapper_class = CAMEL_DATA_WRAPPER_CLASS (class);
@@ -1092,6 +1085,7 @@ camel_mime_part_init (CamelMimePart *mime_part)
 
        mime_part->priv = CAMEL_MIME_PART_GET_PRIVATE (mime_part);
        mime_part->priv->encoding = CAMEL_TRANSFER_ENCODING_DEFAULT;
+       mime_part->priv->headers = camel_name_value_array_new ();
 
        data_wrapper = CAMEL_DATA_WRAPPER (mime_part);
 
diff --git a/src/camel/camel-mime-part.h b/src/camel/camel-mime-part.h
index 0e5fa4d..b21a486 100644
--- a/src/camel/camel-mime-part.h
+++ b/src/camel/camel-mime-part.h
@@ -29,6 +29,7 @@
 #include <camel/camel-medium.h>
 #include <camel/camel-mime-utils.h>
 #include <camel/camel-mime-parser.h>
+#include <camel/camel-name-value-array.h>
 
 /* Standard GObject macros */
 #define CAMEL_TYPE_MIME_PART \
@@ -58,8 +59,6 @@ typedef struct _CamelMimePartPrivate CamelMimePartPrivate;
 struct _CamelMimePart {
        CamelMedium parent;
        CamelMimePartPrivate *priv;
-
-       CamelHeaderRaw *headers; /* mime headers */
 };
 
 struct _CamelMimePartClass {
diff --git a/src/camel/camel-mime-utils.c b/src/camel/camel-mime-utils.c
index 03bdd1a..c49d9a1 100644
--- a/src/camel/camel-mime-utils.c
+++ b/src/camel/camel-mime-utils.c
@@ -4465,261 +4465,6 @@ camel_header_location_decode (const gchar *in)
        return res;
 }
 
-/* extra rfc checks */
-#define CHECKS
-
-#ifdef CHECKS
-static void
-check_header (CamelHeaderRaw *header)
-{
-       guchar *cp;
-
-       cp = (guchar *) header->value;
-       while (cp && *cp) {
-               if (!isascii (*cp)) {
-                       w (g_warning ("Appending header violates rfc: %s: %s", header->name, header->value));
-                       return;
-               }
-               cp++;
-       }
-}
-#endif
-
-/**
- * camel_header_raw_append_parse:
- * @list: (array zero-terminated=1): a NULL-terminated list of #CamelHeaderRaw
- * @header: an unparsed header
- * @offset: the given offset
- *
- * Appends the parsed header to the list with the given offset.
- **/
-void
-camel_header_raw_append_parse (CamelHeaderRaw **list,
-                               const gchar *header,
-                               gint offset)
-{
-       register const gchar *in;
-       gsize fieldlen;
-       gchar *name;
-
-       in = header;
-       while (camel_mime_is_fieldname (*in) || *in == ':')
-               in++;
-       fieldlen = in - header - 1;
-       while (camel_mime_is_lwsp (*in))
-               in++;
-       if (fieldlen == 0 || header[fieldlen] != ':') {
-               printf ("Invalid header line: '%s'\n", header);
-               return;
-       }
-       name = g_alloca (fieldlen + 1);
-       memcpy (name, header, fieldlen);
-       name[fieldlen] = 0;
-
-       camel_header_raw_append (list, name, in, offset);
-}
-
-/**
- * camel_header_raw_append:
- * @list: (array zero-terminated=1): a NULL-terminated list of #CamelHeaderRaw
- * @name: the given name
- * @value: the given value
- * @offset: the given offset
- *
- * Appends a value with the given name and the given value to the list.
- **/
-void
-camel_header_raw_append (CamelHeaderRaw **list,
-                         const gchar *name,
-                         const gchar *value,
-                         gint offset)
-{
-       CamelHeaderRaw *l, *n;
-
-       d (printf ("Header: %s: %s\n", name, value));
-
-       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 = (CamelHeaderRaw *) list;
-       while (l->next) {
-               l = l->next;
-       }
-       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);
-       }
-#endif
-}
-
-/**
- * header_raw_find_node:
- * @list: (array zero-terminated=1): a NULL-terminated list of #CamelHeaderRaw
- * @name: the name to find
- *
- * Searches for the node with a given name.
- *
- * Returns: (transfer none) (nullable): the found #CamelHeaderRaw or NULL.
- **/
-static CamelHeaderRaw *
-header_raw_find_node (CamelHeaderRaw **list,
-                      const gchar *name)
-{
-       CamelHeaderRaw *l;
-
-       l = *list;
-       while (l) {
-               if (!g_ascii_strcasecmp (l->name, name))
-                       break;
-               l = l->next;
-       }
-       return l;
-}
-
-/**
- * camel_header_raw_find:
- * @list: (array zero-terminated=1): a NULL-terminated list of #CamelHeaderRaw
- * @name: the name to find
- * @offset: (out) (nullable): the offset corresponding to the name
- *
- * Searches for the first node with a given name and returns its value.
- *
- * Returns: (transfer none) (nullable): the value associated with the name
- **/
-const gchar *
-camel_header_raw_find (CamelHeaderRaw **list,
-                       const gchar *name,
-                       gint *offset)
-{
-       CamelHeaderRaw *l;
-
-       l = header_raw_find_node (list, name);
-       if (l) {
-               if (offset)
-                       *offset = l->offset;
-               return l->value;
-       } else
-               return NULL;
-}
-
-/**
- * camel_header_raw_find_next:
- * @list: (array zero-terminated=1): a NULL-terminated list of #CamelHeaderRaw
- * @name: the name to find
- * @offset: (out) (nullable): the offset corresponding to the name
- * @last: the last found value
- *
- * Searches for the next node with a given name and returns its value.
- *
- * Returns: (transfer none) (nullable): the value associated with the name
- **/
-const gchar *
-camel_header_raw_find_next (CamelHeaderRaw **list,
-                            const gchar *name,
-                            gint *offset,
-                            const gchar *last)
-{
-       CamelHeaderRaw *l;
-
-       if (last == NULL || name == NULL)
-               return NULL;
-
-       l = *list;
-       while (l && l->value != last)
-               l = l->next;
-       return camel_header_raw_find (&l, name, offset);
-}
-
-static void
-header_raw_free (CamelHeaderRaw *l)
-{
-       g_free (l->name);
-       g_free (l->value);
-       g_free (l);
-}
-
-/**
- * camel_header_raw_remove:
- * @list: (array zero-terminated=1): a NULL-terminated list of #CamelHeaderRaw
- * @name: the name to remove
- *
- * Remove all values associated with the given name
- **/
-void
-camel_header_raw_remove (CamelHeaderRaw **list,
-                         const gchar *name)
-{
-       CamelHeaderRaw *l, *p;
-
-       /* the next pointer is at the head of the structure, so this is safe */
-       p = (CamelHeaderRaw *) 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;
-               }
-       }
-}
-
-/**
- * camel_header_raw_replace:
- * @list: (array zero-terminated=1): a NULL-terminated list of #CamelHeaderRaw
- * @name: the name to remove
- * @value: the new value
- * @offset: the new offset
- *
- * Replace the row associated with the given name by another value and offset.
- **/
-void
-camel_header_raw_replace (CamelHeaderRaw **list,
-                          const gchar *name,
-                          const gchar *value,
-                          gint offset)
-{
-       camel_header_raw_remove (list, name);
-       camel_header_raw_append (list, name, value, offset);
-}
-
-
-/**
- * camel_header_raw_clear:
- * @list: (array zero-terminated=1): a NULL-terminated list of #CamelHeaderRaw
- *
- * Removes all the raws of the list.
- **/
-void
-camel_header_raw_clear (CamelHeaderRaw **list)
-{
-       CamelHeaderRaw *l, *n;
-       l = *list;
-       while (l) {
-               n = l->next;
-               header_raw_free (l);
-               l = n;
-       }
-       *list = NULL;
-}
-
 /**
  * camel_header_msgid_generate:
  * @domain: domain to use (like "example.com") for the ID suffix; can be NULL
@@ -4847,15 +4592,16 @@ mailing_list_init (gpointer param)
 }
 
 /**
- * camel_header_raw_check_mailing_list:
- * @list: (array zero-terminated=1): a NULL-terminated list of #CamelHeaderRaw
+ * camel_headers_dup_mailing_list:
+ * @headers: a #CamelNameValueArray with headers
  *
- * TODO: Document me.
+ * Searches for a mailing list information among known headers and returns
+ * a newly allocated string with its value.
  *
- * Returns: (transfer full) (nullable):
+ * Returns: (nullable) (transfer full): The mailing list header, or %NULL, if none is found
  **/
 gchar *
-camel_header_raw_check_mailing_list (CamelHeaderRaw **list)
+camel_headers_dup_mailing_list (const CamelNameValueArray *headers)
 {
        static GOnce once = G_ONCE_INIT;
        const gchar *v;
@@ -4865,7 +4611,7 @@ camel_header_raw_check_mailing_list (CamelHeaderRaw **list)
        g_once (&once, mailing_list_init, NULL);
 
        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_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE, 
mail_list_magic[i].name);
                for (j = 0; j < 3; j++) {
                        match[j].rm_so = -1;
                        match[j].rm_eo = -1;
@@ -4929,69 +4675,77 @@ camel_header_address_new_group (const gchar *name)
 }
 
 CamelHeaderAddress *
-camel_header_address_ref (CamelHeaderAddress *h)
+camel_header_address_ref (CamelHeaderAddress *addrlist)
 {
-       if (h)
-               h->refcount++;
+       if (addrlist)
+               addrlist->refcount++;
 
-       return h;
+       return addrlist;
 }
 
 void
-camel_header_address_unref (CamelHeaderAddress *h)
+camel_header_address_unref (CamelHeaderAddress *addrlist)
 {
-       if (h) {
-               if (h->refcount <= 1) {
-                       if (h->type == CAMEL_HEADER_ADDRESS_GROUP) {
-                               camel_header_address_list_clear (&h->v.members);
-                       } else if (h->type == CAMEL_HEADER_ADDRESS_NAME) {
-                               g_free (h->v.addr);
+       if (addrlist) {
+               if (addrlist->refcount <= 1) {
+                       if (addrlist->type == CAMEL_HEADER_ADDRESS_GROUP) {
+                               camel_header_address_list_clear (&addrlist->v.members);
+                       } else if (addrlist->type == CAMEL_HEADER_ADDRESS_NAME) {
+                               g_free (addrlist->v.addr);
                        }
-                       g_free (h->name);
-                       g_free (h);
+                       g_free (addrlist->name);
+                       g_free (addrlist);
                } else {
-                       h->refcount--;
+                       addrlist->refcount--;
                }
        }
 }
 
 void
-camel_header_address_set_name (CamelHeaderAddress *h,
+camel_header_address_set_name (CamelHeaderAddress *addrlist,
                                const gchar *name)
 {
-       if (h) {
-               g_free (h->name);
-               h->name = g_strdup (name);
+       if (addrlist) {
+               g_free (addrlist->name);
+               addrlist->name = g_strdup (name);
        }
 }
 
 void
-camel_header_address_set_addr (CamelHeaderAddress *h,
+camel_header_address_set_addr (CamelHeaderAddress *addrlist,
                                const gchar *addr)
 {
-       if (h) {
-               if (h->type == CAMEL_HEADER_ADDRESS_NAME
-                   || h->type == CAMEL_HEADER_ADDRESS_NONE) {
-                       h->type = CAMEL_HEADER_ADDRESS_NAME;
-                       g_free (h->v.addr);
-                       h->v.addr = g_strdup (addr);
+       if (addrlist) {
+               if (addrlist->type == CAMEL_HEADER_ADDRESS_NAME
+                   || addrlist->type == CAMEL_HEADER_ADDRESS_NONE) {
+                       addrlist->type = CAMEL_HEADER_ADDRESS_NAME;
+                       g_free (addrlist->v.addr);
+                       addrlist->v.addr = g_strdup (addr);
                } else {
                        g_warning ("Trying to set the address on a group");
                }
        }
 }
 
+/**
+ * camel_header_address_set_members:
+ * @addrlist: a #CamelHeaderAddress object
+ * @group: (array zero-terminated=1): a NULL-terminated list of #CamelHeaderAddress
+ *
+ * TODO: Document me.
+ *
+ **/
 void
-camel_header_address_set_members (CamelHeaderAddress *h,
+camel_header_address_set_members (CamelHeaderAddress *addrlist,
                                   CamelHeaderAddress *group)
 {
-       if (h) {
-               if (h->type == CAMEL_HEADER_ADDRESS_GROUP
-                   || h->type == CAMEL_HEADER_ADDRESS_NONE) {
-                       h->type = CAMEL_HEADER_ADDRESS_GROUP;
-                       camel_header_address_list_clear (&h->v.members);
+       if (addrlist) {
+               if (addrlist->type == CAMEL_HEADER_ADDRESS_GROUP
+                   || addrlist->type == CAMEL_HEADER_ADDRESS_NONE) {
+                       addrlist->type = CAMEL_HEADER_ADDRESS_GROUP;
+                       camel_header_address_list_clear (&addrlist->v.members);
                        /* should this ref them? */
-                       h->v.members = group;
+                       addrlist->v.members = group;
                } else {
                        g_warning ("Trying to set the members on a name, not group");
                }
@@ -4999,52 +4753,75 @@ camel_header_address_set_members (CamelHeaderAddress *h,
 }
 
 void
-camel_header_address_add_member (CamelHeaderAddress *h,
+camel_header_address_add_member (CamelHeaderAddress *addrlist,
                                  CamelHeaderAddress *member)
 {
-       if (h) {
-               if (h->type == CAMEL_HEADER_ADDRESS_GROUP
-                   || h->type == CAMEL_HEADER_ADDRESS_NONE) {
-                       h->type = CAMEL_HEADER_ADDRESS_GROUP;
-                       camel_header_address_list_append (&h->v.members, member);
+       if (addrlist) {
+               if (addrlist->type == CAMEL_HEADER_ADDRESS_GROUP
+                   || addrlist->type == CAMEL_HEADER_ADDRESS_NONE) {
+                       addrlist->type = CAMEL_HEADER_ADDRESS_GROUP;
+                       camel_header_address_list_append (&addrlist->v.members, member);
                }
        }
 }
 
+/**
+ * camel_header_address_list_append_list:
+ * @addrlistp: (array zero-terminated=1): a NULL-terminated list of #CamelHeaderAddress objects
+ * @addrs: (array zero-terminated=1): a NULL-terminated list of #CamelHeaderAddress to add
+ *
+ * TODO: Document me.
+ *
+ **/
 void
-camel_header_address_list_append_list (CamelHeaderAddress **l,
-                                       CamelHeaderAddress **h)
+camel_header_address_list_append_list (CamelHeaderAddress **addrlistp,
+                                       CamelHeaderAddress **addrs)
 {
-       if (l) {
-               CamelHeaderAddress *n = (CamelHeaderAddress *) l;
+       if (addrlistp) {
+               CamelHeaderAddress *n = (CamelHeaderAddress *) addrlistp;
 
                while (n->next)
                        n = n->next;
-               n->next = *h;
+               n->next = *addrs;
        }
 }
 
+/**
+ * camel_header_address_list_append:
+ * @addrlistp: (array zero-terminated=1): a NULL-terminated list of #CamelHeaderAddress objects
+ * @addr: the #CamelHeaderAddress to add
+ *
+ * TODO: Document me.
+ *
+ **/
 void
-camel_header_address_list_append (CamelHeaderAddress **l,
-                                  CamelHeaderAddress *h)
+camel_header_address_list_append (CamelHeaderAddress **addrlistp,
+                                  CamelHeaderAddress *addr)
 {
-       if (h) {
-               camel_header_address_list_append_list (l, &h);
-               h->next = NULL;
+       if (addr) {
+               camel_header_address_list_append_list (addrlistp, &addr);
+               addr->next = NULL;
        }
 }
 
+/**
+ * camel_header_address_list_clear:
+ * @addrlistp: (array zero-terminated=1): a NULL-terminated list of #CamelHeaderAddress objects
+ *
+ * TODO: Document me.
+ *
+ **/
 void
-camel_header_address_list_clear (CamelHeaderAddress **l)
+camel_header_address_list_clear (CamelHeaderAddress **addrlistp)
 {
        CamelHeaderAddress *a, *n;
-       a = *l;
+       a = *addrlistp;
        while (a) {
                n = a->next;
                camel_header_address_unref (a);
                a = n;
        }
-       *l = NULL;
+       *addrlistp = NULL;
 }
 
 /* if encode is true, then the result is suitable for mailing, otherwise
@@ -5091,35 +4868,49 @@ header_address_list_encode_append (GString *out,
        }
 }
 
+/**
+ * camel_header_address_list_encode:
+ * @addrlist: (array zero-terminated=1): a NULL-terminated list of #CamelHeaderAddress objects
+ *
+ * TODO: Document me.
+ *
+ **/
 gchar *
-camel_header_address_list_encode (CamelHeaderAddress *a)
+camel_header_address_list_encode (CamelHeaderAddress *addrlist)
 {
        GString *out;
        gchar *ret;
 
-       if (a == NULL)
+       if (!addrlist)
                return NULL;
 
        out = g_string_new ("");
-       header_address_list_encode_append (out, TRUE, a);
+       header_address_list_encode_append (out, TRUE, addrlist);
        ret = out->str;
        g_string_free (out, FALSE);
 
        return ret;
 }
 
+/**
+ * camel_header_address_list_format:
+ * @addrlist: (array zero-terminated=1): a NULL-terminated list of #CamelHeaderAddress objects
+ *
+ * TODO: Document me.
+ *
+ **/
 gchar *
-camel_header_address_list_format (CamelHeaderAddress *a)
+camel_header_address_list_format (CamelHeaderAddress *addrlist)
 {
        GString *out;
        gchar *ret;
 
-       if (a == NULL)
+       if (!addrlist)
                return NULL;
 
        out = g_string_new ("");
 
-       header_address_list_encode_append (out, FALSE, a);
+       header_address_list_encode_append (out, FALSE, addrlist);
        ret = out->str;
        g_string_free (out, FALSE);
 
diff --git a/src/camel/camel-mime-utils.h b/src/camel/camel-mime-utils.h
index 12c647e..0e42793 100644
--- a/src/camel/camel-mime-utils.h
+++ b/src/camel/camel-mime-utils.h
@@ -30,6 +30,7 @@
 #include <glib-object.h>
 #include <camel/camel-enums.h>
 #include <camel/camel-utils.h>
+#include <camel/camel-name-value-array.h>
 
 G_BEGIN_DECLS
 
@@ -60,15 +61,6 @@ typedef struct {
        guint refcount;
 } CamelContentType;
 
-/* a raw rfc822 header */
-/* the value MUST be US-ASCII */
-typedef struct _camel_header_raw {
-       struct _camel_header_raw *next;
-       gchar *name;
-       gchar *value;
-       gint offset;            /* in file, if known */
-} CamelHeaderRaw;
-
 typedef struct _CamelContentDisposition {
        gchar *disposition;
        struct _camel_header_param *params;
@@ -82,6 +74,7 @@ typedef enum _camel_header_address_t {
 } CamelHeaderAddressType;
 
 typedef struct _camel_header_address {
+       /* < private > */
        struct _camel_header_address *next;
        CamelHeaderAddressType type;
        gchar *name;
@@ -153,22 +146,13 @@ gchar *camel_content_disposition_format (CamelContentDisposition *disposition);
 /* decode the contents of a content-encoding header */
 gchar *camel_content_transfer_encoding_decode (const gchar *in);
 
-/* raw headers */
-void camel_header_raw_append (CamelHeaderRaw **list, const gchar *name, const gchar *value, gint offset);
-void camel_header_raw_append_parse (CamelHeaderRaw **list, const gchar *header, gint offset);
-const gchar *camel_header_raw_find (CamelHeaderRaw **list, const gchar *name, gint *offset);
-const gchar *camel_header_raw_find_next (CamelHeaderRaw **list, const gchar *name, gint *offset, const gchar 
*last);
-void camel_header_raw_replace (CamelHeaderRaw **list, const gchar *name, const gchar *value, gint offset);
-void camel_header_raw_remove (CamelHeaderRaw **list, const gchar *name);
-void camel_header_raw_clear (CamelHeaderRaw **list);
-
-gchar *camel_header_raw_check_mailing_list (CamelHeaderRaw **list);
-
 /* fold a header */
 gchar *camel_header_address_fold (const gchar *in, gsize headerlen);
 gchar *camel_header_fold (const gchar *in, gsize headerlen);
 gchar *camel_header_unfold (const gchar *in);
 
+gchar *camel_headers_dup_mailing_list (const CamelNameValueArray *headers);
+
 /* decode a header which is a simple token */
 gchar *camel_header_token_decode (const gchar *in);
 
diff --git a/src/camel/camel-movemail.c b/src/camel/camel-movemail.c
index 05f065b..3bda653 100644
--- a/src/camel/camel-movemail.c
+++ b/src/camel/camel-movemail.c
@@ -431,22 +431,24 @@ camel_movemail_copy_filter (gint fromfd,
  * want        to maintain it! */
 static gint
 solaris_header_write (gint fd,
-                      CamelHeaderRaw *header)
+                      CamelNameValueArray *headers)
 {
        struct iovec iv[4];
        gint outlen = 0, len;
+       guint ii;
+       const gchar *header_name = NULL, *header_value = NULL;
 
        iv[1].iov_base = ":";
        iv[1].iov_len = 1;
        iv[3].iov_base = "\n";
        iv[3].iov_len = 1;
 
-       while (header) {
-               if (g_ascii_strcasecmp (header->name, "Content-Length")) {
-                       iv[0].iov_base = header->name;
-                       iv[0].iov_len = strlen (header->name);
-                       iv[2].iov_base = header->value;
-                       iv[2].iov_len = strlen (header->value);
+       for (ii = 0; camel_name_value_array_get (headers, ii, &header_name, &header_value); ii++) {
+               if (g_ascii_strcasecmp (header_name, "Content-Length")) {
+                       iv[0].iov_base = header_name;
+                       iv[0].iov_len = strlen (header_name);
+                       iv[2].iov_base = header_value;
+                       iv[2].iov_len = strlen (header_value);
 
                        do {
                                len = writev (fd, iv, 4);
@@ -456,7 +458,6 @@ solaris_header_write (gint fd,
                                return -1;
                        outlen += len;
                }
-               header = header->next;
        }
 
        do {
@@ -510,6 +511,7 @@ camel_movemail_solaris (gint oldsfd,
                g_return_val_if_fail (camel_mime_parser_from_line (mp), -1);
                from = g_strdup (camel_mime_parser_from_line (mp));
                if (camel_mime_parser_step (mp, &buffer, &len) != CAMEL_MIME_PARSER_STATE_FROM_END) {
+                       CamelNameValueArray *headers;
                        const gchar *cl;
                        gint length;
                        gint start, body;
@@ -524,9 +526,13 @@ camel_movemail_solaris (gint oldsfd,
                                goto fail;
 
                        /* write out headers, but NOT content-length header */
-                       if (solaris_header_write (dfd, camel_mime_parser_headers_raw (mp)) == -1)
+                       headers = camel_mime_parser_dup_headers (mp);
+                       if (solaris_header_write (dfd, headers) == -1) {
+                               camel_name_value_array_free (headers);
                                goto fail;
+                       }
 
+                       camel_name_value_array_free (headers);
                        cl = camel_mime_parser_header (mp, "content-length", NULL);
                        if (cl == NULL) {
                                g_warning ("Required Content-Length header is missing from solaris mail box @ 
%d", (gint) camel_mime_parser_tell (mp));
diff --git a/src/camel/camel-name-value-array.c b/src/camel/camel-name-value-array.c
index e66e1d8..0a90e02 100644
--- a/src/camel/camel-name-value-array.c
+++ b/src/camel/camel-name-value-array.c
@@ -196,7 +196,9 @@ camel_name_value_array_get (const CamelNameValueArray *array,
        CamelNameValuePair *pair;
 
        g_return_val_if_fail (array != NULL, FALSE);
-       g_return_val_if_fail (index < camel_name_value_array_get_length (array), FALSE);
+
+       if (index >= camel_name_value_array_get_length (array))
+               return FALSE;
 
        pair = &g_array_index (arr, CamelNameValuePair, index);
 
@@ -210,15 +212,18 @@ camel_name_value_array_get (const CamelNameValueArray *array,
 
 static guint
 camel_name_value_array_find_named (const CamelNameValueArray *array,
-                                  gboolean case_sensitive,
+                                  CamelCompareType compare_type,
                                   const gchar *name)
 {
        GArray *arr = (GArray *) array;
+       gboolean case_sensitive;
        gint ii;
 
        g_return_val_if_fail (array != NULL, (guint) -1);
        g_return_val_if_fail (name != NULL, (guint) -1);
 
+       case_sensitive = compare_type == CAMEL_COMPARE_CASE_SENSITIVE;
+
        for (ii = 0; ii < arr->len; ii++) {
                CamelNameValuePair *pair = &g_array_index (arr, CamelNameValuePair, ii);
 
@@ -234,12 +239,12 @@ camel_name_value_array_find_named (const CamelNameValueArray *array,
 /**
  * camel_name_value_array_get_named:
  * @array: a #CamelNameValueArray
- * @case_sensitive: whether to compare names case sensitively
+ * @compare_type: a compare type, one of #CamelCompareType
  * @name: a name
  *
  * Returns the value of the first element named @name, or %NULL when there
- * is no element of such @name in the @array. The @case_sensitive determines
- * whether compare names case sensitively (%TRUE) or insensitively (%FALSE).
+ * is no element of such @name in the @array. The @compare_type determines
+ * how to compare the names.
  *
  * Returns: (transfer none) (nullable): Value of the first element named @name, or %NULL.
  *
@@ -249,7 +254,7 @@ camel_name_value_array_find_named (const CamelNameValueArray *array,
  **/
 const gchar *
 camel_name_value_array_get_named (const CamelNameValueArray *array,
-                                 gboolean case_sensitive,
+                                 CamelCompareType compare_type,
                                  const gchar *name)
 {
        guint index;
@@ -257,7 +262,7 @@ camel_name_value_array_get_named (const CamelNameValueArray *array,
        g_return_val_if_fail (array != NULL, NULL);
        g_return_val_if_fail (name != NULL, NULL);
 
-       index = camel_name_value_array_find_named (array, case_sensitive, name);
+       index = camel_name_value_array_find_named (array, compare_type, name);
        if (index == (guint) -1)
                return NULL;
 
@@ -285,7 +290,6 @@ camel_name_value_array_get_name (const CamelNameValueArray *array,
        const gchar *name = NULL;
 
        g_return_val_if_fail (array != NULL, NULL);
-       g_return_val_if_fail (index < camel_name_value_array_get_length (array), NULL);
 
        if (!camel_name_value_array_get (array, index, &name, NULL))
                return NULL;
@@ -314,7 +318,6 @@ camel_name_value_array_get_value (const CamelNameValueArray *array,
        const gchar *value = NULL;
 
        g_return_val_if_fail (array != NULL, NULL);
-       g_return_val_if_fail (index < camel_name_value_array_get_length (array), NULL);
 
        if (!camel_name_value_array_get (array, index, NULL, &value))
                return NULL;
@@ -467,15 +470,15 @@ camel_name_value_array_set_value (CamelNameValueArray *array,
 /**
  * camel_name_value_array_set_named:
  * @array: a #CamelNameValueArray
- * @case_sensitive: whether to compare names case sensitively
+ * @compare_type: a compare type, one of #CamelCompareType
  * @name: a name
  * @value: a value
  *
  * Finds an element named @name and sets its value to @value, or appends
- * a new element, in case no such named lement exists in the @array yet.
+ * a new element, in case no such named element exists in the @array yet.
  * In case there are more elements named with @name only the first
- * occurrence is changed. The @case_sensitive determines whether compare
- * names case sensitively (%TRUE) or insensitively (%FALSE).
+ * occurrence is changed. The @compare_type determines how to compare
+ * the names.
  *
  * Returns: Whether the @array changed.
  *
@@ -485,7 +488,7 @@ camel_name_value_array_set_value (CamelNameValueArray *array,
  **/
 gboolean
 camel_name_value_array_set_named (CamelNameValueArray *array,
-                                 gboolean case_sensitive,
+                                 CamelCompareType compare_type,
                                  const gchar *name,
                                  const gchar *value)
 {
@@ -496,7 +499,7 @@ camel_name_value_array_set_named (CamelNameValueArray *array,
        g_return_val_if_fail (name != NULL, FALSE);
        g_return_val_if_fail (value != NULL, FALSE);
 
-       index = camel_name_value_array_find_named (array, case_sensitive, name);
+       index = camel_name_value_array_find_named (array, compare_type, name);
        if (index == (guint) -1) {
                camel_name_value_array_append (array, name, value);
                changed = TRUE;
@@ -533,12 +536,12 @@ camel_name_value_array_remove (CamelNameValueArray *array,
 /**
  * camel_name_value_array_remove_named:
  * @array: a #CamelNameValueArray
- * @case_sensitive: whether to compare names case sensitively
+ * @compare_type: a compare type, one of #CamelCompareType
  * @name: a name to remove
  * @all_occurrences: whether to remove all occurrences of the @name
  *
- * Removes elements of the @array with the given @name. The @case_sensitive
- * determines whether compare case sensitively (%TRUE) or insensitively (%FALSE).
+ * Removes elements of the @array with the given @name.
+ * The @compare_type determines hot to compare the names.
  * If the @all_occurrences is set to %TRUE, then every elements with the @name
  * are removed, otherwise only the first occurrence is removed.
  *
@@ -548,7 +551,7 @@ camel_name_value_array_remove (CamelNameValueArray *array,
  **/
 guint
 camel_name_value_array_remove_named (CamelNameValueArray *array,
-                                    gboolean case_sensitive,
+                                    CamelCompareType compare_type,
                                     const gchar *name,
                                     gboolean all_occurrences)
 {
@@ -557,7 +560,7 @@ camel_name_value_array_remove_named (CamelNameValueArray *array,
        g_return_val_if_fail (array != NULL, 0);
        g_return_val_if_fail (name != NULL, 0);
 
-       while (index = camel_name_value_array_find_named (array, case_sensitive, name), index != (guint) -1) {
+       while (index = camel_name_value_array_find_named (array, compare_type, name), index != (guint) -1) {
                if (!camel_name_value_array_remove (array, index))
                        break;
 
@@ -592,7 +595,7 @@ camel_name_value_array_clear (CamelNameValueArray *array)
  * camel_name_value_array_equal:
  * @array_a: (nullable): the first #CamelNameValueArray
  * @array_b: (nullable): the second #CamelNameValueArray
- * @case_sensitive: whether to search for names case sensitively
+ * @compare_type: a compare type, one of #CamelCompareType
  *
  * Compares content of the two #CamelNameValueArray and returns whether
  * they equal. Note this is an expensive operation for large arrays.
@@ -604,7 +607,7 @@ camel_name_value_array_clear (CamelNameValueArray *array)
 gboolean
 camel_name_value_array_equal (const CamelNameValueArray *array_a,
                              const CamelNameValueArray *array_b,
-                             gboolean case_sensitive)
+                             CamelCompareType compare_type)
 {
        guint ii, len;
 
@@ -622,7 +625,7 @@ camel_name_value_array_equal (const CamelNameValueArray *array_a,
                const gchar *value1, *value2;
 
                value1 = camel_name_value_array_get_value (array_a, ii);
-               value2 = camel_name_value_array_get_named (array_b, case_sensitive,
+               value2 = camel_name_value_array_get_named (array_b, compare_type,
                        camel_name_value_array_get_name (array_a, ii));
 
                if (g_strcmp0 (value1, value2) != 0)
diff --git a/src/camel/camel-name-value-array.h b/src/camel/camel-name-value-array.h
index aa902a9..b3886b7 100644
--- a/src/camel/camel-name-value-array.h
+++ b/src/camel/camel-name-value-array.h
@@ -23,6 +23,7 @@
 #define CAMEL_NAME_VALUE_ARRAY_H
 
 #include <glib-object.h>
+#include <camel/camel-enums.h>
 
 G_BEGIN_DECLS
 
@@ -53,7 +54,7 @@ gboolean      camel_name_value_array_get      (const CamelNameValueArray *array,
                                                 const gchar **out_value);
 const gchar *  camel_name_value_array_get_named
                                                (const CamelNameValueArray *array,
-                                                gboolean case_sensitive,
+                                                CamelCompareType compare_type,
                                                 const gchar *name);
 const gchar *  camel_name_value_array_get_name (const CamelNameValueArray *array,
                                                 guint index);
@@ -76,20 +77,20 @@ gboolean    camel_name_value_array_set_value
                                                 const gchar *value);
 gboolean       camel_name_value_array_set_named
                                                (CamelNameValueArray *array,
-                                                gboolean case_sensitive,
+                                                CamelCompareType compare_type,
                                                 const gchar *name,
                                                 const gchar *value);
 gboolean       camel_name_value_array_remove   (CamelNameValueArray *array,
                                                 guint index);
 guint          camel_name_value_array_remove_named
                                                (CamelNameValueArray *array,
-                                                gboolean case_sensitive,
+                                                CamelCompareType compare_type,
                                                 const gchar *name,
                                                 gboolean all_occurrences);
 void           camel_name_value_array_clear    (CamelNameValueArray *array);
 gboolean       camel_name_value_array_equal    (const CamelNameValueArray *array_a,
                                                 const CamelNameValueArray *array_b,
-                                                gboolean case_sensitive);
+                                                CamelCompareType compare_type);
 
 G_END_DECLS
 
diff --git a/src/camel/camel-named-flags.c b/src/camel/camel-named-flags.c
index c2869b4..04d9d30 100644
--- a/src/camel/camel-named-flags.c
+++ b/src/camel/camel-named-flags.c
@@ -275,7 +275,9 @@ camel_named_flags_get (const CamelNamedFlags *named_flags,
        const GPtrArray *arr = (const GPtrArray *) named_flags;
 
        g_return_val_if_fail (named_flags != NULL, NULL);
-       g_return_val_if_fail (index < camel_named_flags_get_length (named_flags), NULL);
+
+       if (index >= camel_named_flags_get_length (named_flags))
+               return NULL;
 
        return g_ptr_array_index (arr, index);
 }
diff --git a/src/camel/camel-search-private.c b/src/camel/camel-search-private.c
index 1401dd9..f722779 100644
--- a/src/camel/camel-search-private.c
+++ b/src/camel/camel-search-private.c
@@ -831,14 +831,14 @@ camel_search_get_all_headers_decoded (CamelMimeMessage *message)
 {
        CamelMedium *medium;
        GString *str;
-       CamelNameValueArray *headers;
+       const CamelNameValueArray *headers;
        const gchar *default_charset;
        guint ii, length;
 
        g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), NULL);
 
        medium = CAMEL_MEDIUM (message);
-       headers = camel_medium_dup_headers (medium);
+       headers = camel_medium_get_headers (medium);
        if (!headers)
                return NULL;
 
@@ -872,7 +872,5 @@ camel_search_get_all_headers_decoded (CamelMimeMessage *message)
                g_free (content);
        }
 
-       camel_name_value_array_free (headers);
-
        return g_string_free (str, FALSE);
 }
diff --git a/src/camel/providers/imapx/camel-imapx-message-info.c 
b/src/camel/providers/imapx/camel-imapx-message-info.c
index 9a324d1..c7d7fe4 100644
--- a/src/camel/providers/imapx/camel-imapx-message-info.c
+++ b/src/camel/providers/imapx/camel-imapx-message-info.c
@@ -415,7 +415,7 @@ camel_imapx_message_info_take_server_user_tags (CamelIMAPXMessageInfo *imi,
 
        camel_message_info_property_lock (mi);
 
-       changed = !camel_name_value_array_equal (imi->priv->server_user_tags, server_user_tags, TRUE);
+       changed = !camel_name_value_array_equal (imi->priv->server_user_tags, server_user_tags, 
CAMEL_COMPARE_CASE_SENSITIVE);
 
        if (changed) {
                camel_name_value_array_free (imi->priv->server_user_tags);
diff --git a/src/camel/providers/imapx/camel-imapx-summary.c b/src/camel/providers/imapx/camel-imapx-summary.c
index 6bb0757..b1af6bf 100644
--- a/src/camel/providers/imapx/camel-imapx-summary.c
+++ b/src/camel/providers/imapx/camel-imapx-summary.c
@@ -31,6 +31,9 @@
 #include "camel-imapx-message-info.h"
 #include "camel-imapx-summary.h"
 
+/* Don't do DB sort. Its pretty slow to load */
+/* #define SORT_DB 1 */
+
 #define CAMEL_IMAPX_SUMMARY_VERSION (4)
 
 G_DEFINE_TYPE (
@@ -106,8 +109,10 @@ camel_imapx_summary_class_init (CamelIMAPXSummaryClass *class)
 
        folder_summary_class = CAMEL_FOLDER_SUMMARY_CLASS (class);
        folder_summary_class->message_info_type = CAMEL_TYPE_IMAPX_MESSAGE_INFO;
+#ifdef SORT_DB
        folder_summary_class->sort_by = "uid";
        folder_summary_class->collate = "imapx_uid_sort";
+#endif
        folder_summary_class->summary_header_load = imapx_summary_summary_header_load;
        folder_summary_class->summary_header_save = imapx_summary_summary_header_save;
 }
@@ -117,6 +122,7 @@ camel_imapx_summary_init (CamelIMAPXSummary *obj)
 {
 }
 
+#ifdef SORT_DB
 static gint
 sort_uid_cmp (gpointer enc,
               gint len1,
@@ -144,6 +150,7 @@ sort_uid_cmp (gpointer enc,
 
        return (a1 < a2) ? -1 : (a1 > a2) ? 1 : 0;
 }
+#endif
 
 /**
  * camel_imapx_summary_new:
@@ -157,18 +164,18 @@ sort_uid_cmp (gpointer enc,
 CamelFolderSummary *
 camel_imapx_summary_new (CamelFolder *folder)
 {
+#ifdef SORT_DB
        CamelStore *parent_store;
+#endif
        CamelFolderSummary *summary;
        GError *local_error = NULL;
 
-       parent_store = camel_folder_get_parent_store (folder);
-
        summary = g_object_new (CAMEL_TYPE_IMAPX_SUMMARY, "folder", folder, NULL);
 
-       /* Don't do DB sort. Its pretty slow to load */
-       if (folder && 0) {
-               camel_db_set_collate (camel_store_get_db (parent_store), "uid", "imapx_uid_sort", 
(CamelDBCollate) sort_uid_cmp);
-       }
+#ifdef SORT_DB
+       parent_store = camel_folder_get_parent_store (folder);
+       camel_db_set_collate (camel_store_get_db (parent_store), "uid", "imapx_uid_sort", (CamelDBCollate) 
sort_uid_cmp);
+#endif
 
        if (!camel_folder_summary_load (summary, &local_error)) {
                /* FIXME: Isn't this dangerous ? We clear the summary
diff --git a/src/camel/providers/local/camel-local-summary.c b/src/camel/providers/local/camel-local-summary.c
index f70ddbf..1d0a2c3 100644
--- a/src/camel/providers/local/camel-local-summary.c
+++ b/src/camel/providers/local/camel-local-summary.c
@@ -44,8 +44,8 @@ static gboolean       summary_header_load             (CamelFolderSummary *,
                                                 CamelFIRecord *);
 
 static CamelMessageInfo *
-               message_info_new_from_header    (CamelFolderSummary *,
-                                                CamelHeaderRaw *);
+               message_info_new_from_headers   (CamelFolderSummary *,
+                                                const CamelNameValueArray *);
 
 static gint    local_summary_decode_x_evolution
                                                (CamelLocalSummary *cls,
@@ -119,7 +119,7 @@ camel_local_summary_class_init (CamelLocalSummaryClass *class)
        folder_summary_class = CAMEL_FOLDER_SUMMARY_CLASS (class);
        folder_summary_class->summary_header_load = summary_header_load;
        folder_summary_class->summary_header_save = summary_header_save;
-       folder_summary_class->message_info_new_from_header = message_info_new_from_header;
+       folder_summary_class->message_info_new_from_headers = message_info_new_from_headers;
 
        class->load = local_summary_load;
        class->check = local_summary_check;
@@ -373,7 +373,7 @@ camel_local_summary_add (CamelLocalSummary *cls,
 /**
  * camel_local_summary_write_headers:
  * @fd:
- * @header:
+ * @headers:
  * @xevline:
  * @status:
  * @xstatus:
@@ -387,13 +387,15 @@ camel_local_summary_add (CamelLocalSummary *cls,
  **/
 gint
 camel_local_summary_write_headers (gint fd,
-                                   CamelHeaderRaw *header,
+                                   CamelNameValueArray *headers,
                                    const gchar *xevline,
                                    const gchar *status,
                                    const gchar *xstatus)
 {
        gint outlen = 0, len;
        gint newfd;
+       guint ii;
+       const gchar *header_name = NULL, *header_value = NULL;
        FILE *out;
 
        /* dum de dum, maybe the whole sync function should just use stdio for output */
@@ -408,18 +410,17 @@ camel_local_summary_write_headers (gint fd,
                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);
+       for (ii = 0; camel_name_value_array_get (headers, ii, &header_name, &header_value); ii++) {
+               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);
                        if (len == -1) {
                                fclose (out);
                                return -1;
                        }
                        outlen += len;
                }
-               header = header->next;
        }
 
        if (status) {
@@ -729,22 +730,22 @@ summary_header_save (CamelFolderSummary *s,
 }
 
 static CamelMessageInfo *
-message_info_new_from_header (CamelFolderSummary *s,
-                              CamelHeaderRaw *h)
+message_info_new_from_headers (CamelFolderSummary *summary,
+                              const CamelNameValueArray *headers)
 {
        CamelMessageInfo *mi;
-       CamelLocalSummary *cls = (CamelLocalSummary *) s;
+       CamelLocalSummary *cls = (CamelLocalSummary *) summary;
 
-       mi = CAMEL_FOLDER_SUMMARY_CLASS (camel_local_summary_parent_class)->message_info_new_from_header (s, 
h);
+       mi = CAMEL_FOLDER_SUMMARY_CLASS (camel_local_summary_parent_class)->message_info_new_from_headers 
(summary, headers);
        if (mi) {
                const gchar *xev;
                gint doindex = FALSE;
 
-               xev = camel_header_raw_find (&h, "X-Evolution", NULL);
+               xev = camel_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE, 
"X-Evolution");
                if (xev == NULL || camel_local_summary_decode_x_evolution (cls, xev, mi) == -1) {
                        gchar *uid;
 
-                       uid = camel_folder_summary_next_uid_string (s);
+                       uid = camel_folder_summary_next_uid_string (summary);
 
                        /* to indicate it has no xev header */
                        camel_message_info_set_flags (mi, CAMEL_MESSAGE_FOLDER_FLAGGED | 
CAMEL_MESSAGE_FOLDER_NOXEV, CAMEL_MESSAGE_FOLDER_FLAGGED | CAMEL_MESSAGE_FOLDER_NOXEV);
@@ -761,10 +762,10 @@ message_info_new_from_header (CamelFolderSummary *s,
                        || cls->index_force
                        || !camel_index_has_name (cls->index, camel_message_info_get_uid (mi)))) {
                        d (printf ("Am indexing message %s\n", camel_message_info_get_uid (mi)));
-                       camel_folder_summary_set_index (s, cls->index);
+                       camel_folder_summary_set_index (summary, cls->index);
                } else {
                        d (printf ("Not indexing message %s\n", camel_message_info_get_uid (mi)));
-                       camel_folder_summary_set_index (s, NULL);
+                       camel_folder_summary_set_index (summary, NULL);
                }
        }
 
diff --git a/src/camel/providers/local/camel-local-summary.h b/src/camel/providers/local/camel-local-summary.h
index 35a7e05..284aca2 100644
--- a/src/camel/providers/local/camel-local-summary.h
+++ b/src/camel/providers/local/camel-local-summary.h
@@ -100,7 +100,7 @@ gchar *camel_local_summary_encode_x_evolution (CamelLocalSummary *cls, const Cam
 gint camel_local_summary_decode_x_evolution (CamelLocalSummary *cls, const gchar *xev, CamelMessageInfo 
*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, CamelHeaderRaw *header, const gchar *xevline, const gchar 
*status, const gchar *xstatus);
+gint camel_local_summary_write_headers (gint fd, CamelNameValueArray *headers, const gchar *xevline, const 
gchar *status, const gchar *xstatus);
 
 G_END_DECLS
 
diff --git a/src/camel/providers/local/camel-maildir-summary.c 
b/src/camel/providers/local/camel-maildir-summary.c
index de646f6..7b240f6 100644
--- a/src/camel/providers/local/camel-maildir-summary.c
+++ b/src/camel/providers/local/camel-maildir-summary.c
@@ -48,8 +48,8 @@
 #define CAMEL_MAILDIR_SUMMARY_VERSION (0x2000)
 
 static CamelMessageInfo *
-               message_info_new_from_header    (CamelFolderSummary *,
-                                                CamelHeaderRaw *);
+               message_info_new_from_headers   (CamelFolderSummary *,
+                                                const CamelNameValueArray *);
 static gint    maildir_summary_load            (CamelLocalSummary *cls,
                                                 gint forceindex,
                                                 GError **error);
@@ -127,7 +127,7 @@ camel_maildir_summary_class_init (CamelMaildirSummaryClass *class)
        folder_summary_class->message_info_type = CAMEL_TYPE_MAILDIR_MESSAGE_INFO;
        folder_summary_class->sort_by = "dreceived";
        folder_summary_class->collate = NULL;
-       folder_summary_class->message_info_new_from_header = message_info_new_from_header;
+       folder_summary_class->message_info_new_from_headers = message_info_new_from_headers;
        folder_summary_class->next_uid_string = maildir_summary_next_uid_string;
 
        local_summary_class = CAMEL_LOCAL_SUMMARY_CLASS (class);
@@ -306,26 +306,26 @@ maildir_summary_add (CamelLocalSummary *cls,
 }
 
 static CamelMessageInfo *
-message_info_new_from_header (CamelFolderSummary *s,
-                              CamelHeaderRaw *h)
+message_info_new_from_headers (CamelFolderSummary *summary,
+                              const CamelNameValueArray *headers)
 {
        CamelMessageInfo *mi, *info;
-       CamelMaildirSummary *mds = (CamelMaildirSummary *) s;
+       CamelMaildirSummary *mds = (CamelMaildirSummary *) summary;
        const gchar *uid;
 
-       mi = ((CamelFolderSummaryClass *) camel_maildir_summary_parent_class)->message_info_new_from_header 
(s, h);
+       mi = ((CamelFolderSummaryClass *) camel_maildir_summary_parent_class)->message_info_new_from_headers 
(summary, headers);
        /* assign the uid and new filename */
        if (mi) {
                uid = camel_message_info_get_uid (mi);
                if (uid == NULL || uid[0] == 0) {
-                       gchar *new_uid = camel_folder_summary_next_uid_string (s);
+                       gchar *new_uid = camel_folder_summary_next_uid_string (summary);
 
                        camel_message_info_set_uid (mi, new_uid);
                        g_free (new_uid);
                }
 
                /* handle 'duplicates' */
-               info = (uid && *uid) ? camel_folder_summary_peek_loaded (s, uid) : NULL;
+               info = (uid && *uid) ? camel_folder_summary_peek_loaded (summary, uid) : NULL;
                if (info) {
                        d (printf ("already seen uid '%s', just summarising instead\n", uid));
                        g_clear_object (&mi);
diff --git a/src/camel/providers/local/camel-mbox-summary.c b/src/camel/providers/local/camel-mbox-summary.c
index b9ac85d..f7c0765 100644
--- a/src/camel/providers/local/camel-mbox-summary.c
+++ b/src/camel/providers/local/camel-mbox-summary.c
@@ -60,8 +60,8 @@ static CamelFIRecord *
 static gboolean        summary_header_load             (CamelFolderSummary *,
                                                 CamelFIRecord *);
 static CamelMessageInfo *
-               message_info_new_from_header    (CamelFolderSummary *,
-                                                CamelHeaderRaw *);
+               message_info_new_from_headers   (CamelFolderSummary *,
+                                                const CamelNameValueArray *);
 static CamelMessageInfo *
                message_info_new_from_parser    (CamelFolderSummary *,
                                                 CamelMimeParser *);
@@ -120,7 +120,7 @@ camel_mbox_summary_class_init (CamelMboxSummaryClass *class)
        folder_summary_class->collate = "mbox_frompos_sort";
        folder_summary_class->summary_header_load = summary_header_load;
        folder_summary_class->summary_header_save = summary_header_save;
-       folder_summary_class->message_info_new_from_header = message_info_new_from_header;
+       folder_summary_class->message_info_new_from_headers = message_info_new_from_headers;
        folder_summary_class->message_info_new_from_parser = message_info_new_from_parser;
 
        local_summary_class = CAMEL_LOCAL_SUMMARY_CLASS (class);
@@ -238,13 +238,13 @@ summary_header_save (CamelFolderSummary *s,
 }
 
 static CamelMessageInfo *
-message_info_new_from_header (CamelFolderSummary *s,
-                              CamelHeaderRaw *h)
+message_info_new_from_headers (CamelFolderSummary *summary,
+                              const CamelNameValueArray *headers)
 {
        CamelMessageInfo *mi;
-       CamelMboxSummary *mbs = (CamelMboxSummary *) s;
+       CamelMboxSummary *mbs = (CamelMboxSummary *) summary;
 
-       mi = CAMEL_FOLDER_SUMMARY_CLASS (camel_mbox_summary_parent_class)->message_info_new_from_header (s, 
h);
+       mi = CAMEL_FOLDER_SUMMARY_CLASS (camel_mbox_summary_parent_class)->message_info_new_from_headers 
(summary, headers);
        if (mi) {
                const gchar *xev, *uid;
                CamelMessageInfo *info = NULL;
@@ -254,22 +254,22 @@ message_info_new_from_header (CamelFolderSummary *s,
 
                if (mbs->xstatus) {
                        /* check for existance of status & x-status headers */
-                       status = camel_header_raw_find (&h, "Status", NULL);
+                       status = camel_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE, 
"Status");
                        if (status)
                                flags = decode_status (status);
-                       xstatus = camel_header_raw_find (&h, "X-Status", NULL);
+                       xstatus = camel_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE, 
"X-Status");
                        if (xstatus)
                                flags |= decode_status (xstatus);
                }
 
                /* if we have an xev header, use it, else assign a new one */
-               xev = camel_header_raw_find (&h, "X-Evolution", NULL);
+               xev = camel_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE, 
"X-Evolution");
                if (xev != NULL
-                   && camel_local_summary_decode_x_evolution ((CamelLocalSummary *) s, xev, mi) == 0) {
+                   && camel_local_summary_decode_x_evolution ((CamelLocalSummary *) summary, xev, mi) == 0) {
                        uid = camel_message_info_get_uid (mi);
                        d (printf ("found valid x-evolution: %s\n", uid));
                        /* If one is there, it should be there already */
-                       info = camel_folder_summary_peek_loaded (s, uid);
+                       info = camel_folder_summary_peek_loaded (summary, uid);
                        if (info) {
                                if ((camel_message_info_get_flags (info) & CAMEL_MESSAGE_FOLDER_NOTSEEN)) {
                                        camel_message_info_set_flags (info, CAMEL_MESSAGE_FOLDER_NOTSEEN, 0);
@@ -290,14 +290,14 @@ message_info_new_from_header (CamelFolderSummary *s,
                }
 
                if ((add & 1) != 0) {
-                       gchar *new_uid = camel_folder_summary_next_uid_string (s);
+                       gchar *new_uid = camel_folder_summary_next_uid_string (summary);
 
                        camel_message_info_set_flags (mi, CAMEL_MESSAGE_FOLDER_FLAGGED | 
CAMEL_MESSAGE_FOLDER_NOXEV, CAMEL_MESSAGE_FOLDER_FLAGGED | CAMEL_MESSAGE_FOLDER_NOXEV);
                        camel_message_info_set_uid (mi, new_uid);
 
                        g_free (new_uid);
                } else {
-                       camel_folder_summary_set_next_uid (s, strtoul (camel_message_info_get_uid (mi), NULL, 
10));
+                       camel_folder_summary_set_next_uid (summary, strtoul (camel_message_info_get_uid (mi), 
NULL, 10));
                }
 
                if (mbs->xstatus && (add & 2) != 0) {
@@ -1116,6 +1116,7 @@ camel_mbox_summary_sync_mbox (CamelMboxSummary *cls,
                }
 
                if (info && (camel_message_info_get_flags (info) & (CAMEL_MESSAGE_FOLDER_NOXEV | 
CAMEL_MESSAGE_FOLDER_FLAGGED)) != 0) {
+                       CamelNameValueArray *header = NULL;
                        d (printf ("Updating header for %s flags = %08x\n", camel_message_info_get_uid 
(info), camel_message_info_get_flags (info)));
 
                        if (camel_mime_parser_step (mp, &buffer, &len) == CAMEL_MIME_PARSER_STATE_FROM_END) {
@@ -1123,17 +1124,20 @@ camel_mbox_summary_sync_mbox (CamelMboxSummary *cls,
                                goto error;
                        }
 
+                       header = camel_mime_parser_dup_headers (mp);
                        xevnew = camel_local_summary_encode_x_evolution ((CamelLocalSummary *) cls, info);
                        if (mbs->xstatus) {
                                guint32 flags = camel_message_info_get_flags (info);
 
                                encode_status (flags & STATUS_STATUS, statnew);
                                encode_status (flags & STATUS_XSTATUS, xstatnew);
-                               len = camel_local_summary_write_headers (fdout, camel_mime_parser_headers_raw 
(mp), xevnew, statnew, xstatnew);
+
+                               len = camel_local_summary_write_headers (fdout, header, xevnew, statnew, 
xstatnew);
                        } else {
-                               len = camel_local_summary_write_headers (fdout, camel_mime_parser_headers_raw 
(mp), xevnew, NULL, NULL);
+                               len = camel_local_summary_write_headers (fdout, header, xevnew, NULL, NULL);
                        }
 
+                       camel_name_value_array_free (header);
                        if (len == -1) {
                                d (printf ("Error writing to temporary mailbox\n"));
                                g_set_error (
diff --git a/src/camel/providers/local/camel-spool-summary.h b/src/camel/providers/local/camel-spool-summary.h
index bab4f92..74e49e3 100644
--- a/src/camel/providers/local/camel-spool-summary.h
+++ b/src/camel/providers/local/camel-spool-summary.h
@@ -77,9 +77,6 @@ CamelMessageInfo *camel_spool_summary_add (CamelSpoolSummary *cls, CamelMimeMess
 gchar *camel_spool_summary_encode_x_evolution (CamelSpoolSummary *cls, const CamelMessageInfo *info);
 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, CamelHeaderRaw *header, gchar *xevline);
-
 G_END_DECLS
 
 #endif /* CAMEL_SPOOL_SUMMARY_H */
diff --git a/src/camel/providers/nntp/camel-nntp-folder.c b/src/camel/providers/nntp/camel-nntp-folder.c
index 44a03b5..8ff03a1 100644
--- a/src/camel/providers/nntp/camel-nntp-folder.c
+++ b/src/camel/providers/nntp/camel-nntp-folder.c
@@ -404,8 +404,9 @@ nntp_folder_append_message_sync (CamelFolder *folder,
        CamelStream *filtered_stream;
        CamelMimeFilter *crlffilter;
        gint ret;
-       guint u;
-       CamelHeaderRaw *header, *savedhdrs, *n, *tail;
+       guint u, ii;
+       CamelNameValueArray *previous_headers = NULL;
+       const gchar *header_name = NULL, *header_value = NULL;
        const gchar *full_name;
        gchar *group, *line;
        gboolean success = TRUE;
@@ -439,24 +440,11 @@ nntp_folder_append_message_sync (CamelFolder *folder,
        /* the 'Newsgroups: ' header */
        group = g_strdup_printf ("Newsgroups: %s\r\n", full_name);
 
-       /* remove mail 'To', 'CC', and 'BCC' headers */
-       savedhdrs = NULL;
-       tail = (CamelHeaderRaw *) &savedhdrs;
-
-       header = (CamelHeaderRaw *) &CAMEL_MIME_PART (message)->headers;
-       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;
-       }
+       /* remove mail 'To', 'Cc', and 'Bcc' headers */
+       previous_headers = camel_medium_dup_headers (CAMEL_MEDIUM (message));
+       camel_medium_remove_header (CAMEL_MEDIUM (message), "To");
+       camel_medium_remove_header (CAMEL_MEDIUM (message), "Cc");
+       camel_medium_remove_header (CAMEL_MEDIUM (message), "Bcc");
 
        nntp_stream = camel_nntp_store_ref_stream (nntp_store);
 
@@ -503,7 +491,16 @@ nntp_folder_append_message_sync (CamelFolder *folder,
 
        g_object_unref (filtered_stream);
        g_free (group);
-       header->next = savedhdrs;
+       /* restore the bcc headers */
+       for (ii = 0; camel_name_value_array_get (previous_headers, ii, &header_name, &header_value); ii++) {
+               if (!g_ascii_strcasecmp (header_name, "To") ||
+                   !g_ascii_strcasecmp (header_name, "Cc") ||
+                   !g_ascii_strcasecmp (header_name, "Bcc")) {
+                       camel_medium_add_header (CAMEL_MEDIUM (message), header_name, header_value);
+               }
+       }
+
+       camel_name_value_array_free (previous_headers);
 
 exit:
        g_clear_object (&nntp_stream);
diff --git a/src/camel/providers/nntp/camel-nntp-summary.c b/src/camel/providers/nntp/camel-nntp-summary.c
index 4ce0460..bae3279 100644
--- a/src/camel/providers/nntp/camel-nntp-summary.c
+++ b/src/camel/providers/nntp/camel-nntp-summary.c
@@ -51,7 +51,7 @@ struct _CamelNNTPSummaryPrivate {
        gint xover_setup;
 };
 
-static CamelMessageInfo * message_info_new_from_header (CamelFolderSummary *, CamelHeaderRaw *);
+static CamelMessageInfo * message_info_new_from_headers (CamelFolderSummary *, const CamelNameValueArray *);
 static gboolean summary_header_load (CamelFolderSummary *s, CamelFIRecord *mir);
 static CamelFIRecord * summary_header_save (CamelFolderSummary *s, GError **error);
 
@@ -65,7 +65,7 @@ camel_nntp_summary_class_init (CamelNNTPSummaryClass *class)
        g_type_class_add_private (class, sizeof (CamelNNTPSummaryPrivate));
 
        folder_summary_class = CAMEL_FOLDER_SUMMARY_CLASS (class);
-       folder_summary_class->message_info_new_from_header = message_info_new_from_header;
+       folder_summary_class->message_info_new_from_headers = message_info_new_from_headers;
        folder_summary_class->summary_header_load = summary_header_load;
        folder_summary_class->summary_header_save = summary_header_save;
 }
@@ -92,17 +92,17 @@ camel_nntp_summary_new (CamelFolder *folder)
 }
 
 static CamelMessageInfo *
-message_info_new_from_header (CamelFolderSummary *s,
-                              CamelHeaderRaw *h)
+message_info_new_from_headers (CamelFolderSummary *summary,
+                              const CamelNameValueArray *headers)
 {
        CamelMessageInfo *mi;
-       CamelNNTPSummary *cns = (CamelNNTPSummary *) s;
+       CamelNNTPSummary *cns = (CamelNNTPSummary *) summary;
 
        /* error to call without this setup */
        if (cns->priv->uid == NULL)
                return NULL;
 
-       mi = CAMEL_FOLDER_SUMMARY_CLASS (camel_nntp_summary_parent_class)->message_info_new_from_header (s, 
h);
+       mi = CAMEL_FOLDER_SUMMARY_CLASS (camel_nntp_summary_parent_class)->message_info_new_from_headers 
(summary, headers);
        if (mi) {
                camel_message_info_set_uid (mi, cns->priv->uid);
                g_free (cns->priv->uid);
@@ -164,7 +164,7 @@ add_range_xover (CamelNNTPSummary *cns,
        CamelSettings *settings;
        CamelService *service;
        CamelFolderSummary *s;
-       CamelHeaderRaw *headers = NULL;
+       CamelNameValueArray *headers = NULL;
        gchar *line, *tab;
        gchar *host;
        guint len;
@@ -217,6 +217,7 @@ add_range_xover (CamelNNTPSummary *cns,
 
        count = 0;
        total = high - low + 1;
+       headers = camel_name_value_array_new ();
        while ((ret = camel_nntp_stream_line (nntp_stream, (guchar **) &line, &len, cancellable, error)) > 0) 
{
                camel_operation_progress (cancellable, (count * 100) / total);
                count++;
@@ -238,7 +239,7 @@ add_range_xover (CamelNNTPSummary *cns,
                        if (xover->name) {
                                line += xover->skip;
                                if (line < tab) {
-                                       camel_header_raw_append (&headers, xover->name, line, -1);
+                                       camel_name_value_array_append (headers, xover->name, line);
                                        switch (xover->type) {
                                        case XOVER_STRING:
                                                break;
@@ -262,7 +263,7 @@ add_range_xover (CamelNNTPSummary *cns,
                        if (!camel_folder_summary_check_uid (s, cns->priv->uid)) {
                                CamelMessageInfo *mi;
 
-                               mi = camel_folder_summary_info_new_from_header (s, headers);
+                               mi = camel_folder_summary_info_new_from_headers (s, headers);
                                camel_message_info_set_size (mi, size);
                                camel_folder_summary_add (s, mi, FALSE);
 
@@ -279,9 +280,10 @@ add_range_xover (CamelNNTPSummary *cns,
                        cns->priv->uid = NULL;
                }
 
-               camel_header_raw_clear (&headers);
+               camel_name_value_array_clear (headers);
        }
 
+       camel_name_value_array_free (headers);
        g_clear_object (&nntp_stream);
 
        camel_operation_pop_message (cancellable);
diff --git a/src/camel/providers/pop3/camel-pop3-folder.c b/src/camel/providers/pop3/camel-pop3-folder.c
index f844cb0..2beb51e 100644
--- a/src/camel/providers/pop3/camel-pop3-folder.c
+++ b/src/camel/providers/pop3/camel-pop3-folder.c
@@ -90,10 +90,12 @@ cmd_builduid (CamelPOP3Engine *pe,
 {
        GChecksum *checksum;
        CamelPOP3FolderInfo *fi = data;
-       CamelHeaderRaw *h;
+       CamelNameValueArray *h;
        CamelMimeParser *mp;
        guint8 *digest;
        gsize length;
+       guint ii;
+       const gchar *header_name = NULL, *header_value = NULL;
 
        length = g_checksum_type_get_length (G_CHECKSUM_MD5);
        digest = g_alloca (length);
@@ -109,15 +111,16 @@ cmd_builduid (CamelPOP3Engine *pe,
        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);
+               h = camel_mime_parser_dup_headers (mp);
+               for (ii = 0; camel_name_value_array_get (h, ii, &header_name, &header_value); ii++) {
+                       if (g_ascii_strcasecmp (header_name, "status") != 0
+                           && g_ascii_strcasecmp (header_name, "x-status") != 0) {
+                               g_checksum_update (checksum, (guchar *) header_name, -1);
+                               g_checksum_update (checksum, (guchar *) header_value, -1);
                        }
-                       h = h->next;
                }
+
+               camel_name_value_array_free (h);
        default:
                break;
        }
diff --git a/src/camel/providers/sendmail/camel-sendmail-transport.c 
b/src/camel/providers/sendmail/camel-sendmail-transport.c
index 0e069d5..ca1edf6 100644
--- a/src/camel/providers/sendmail/camel-sendmail-transport.c
+++ b/src/camel/providers/sendmail/camel-sendmail-transport.c
@@ -112,7 +112,8 @@ sendmail_send_to_sync (CamelTransport *transport,
                        GCancellable *cancellable,
                        GError **error)
 {
-       CamelHeaderRaw *header, *savedbcc, *n, *tail;
+       CamelNameValueArray *previous_headers = NULL;
+       const gchar *header_name = NULL, *header_value = NULL;
        const gchar *from_addr, *addr;
        GPtrArray *argv_arr;
        gint i, len, fd[2], nullfd, wstat;
@@ -125,6 +126,7 @@ sendmail_send_to_sync (CamelTransport *transport,
        gchar *custom_binary = NULL, *custom_args = NULL;
        gboolean success;
        pid_t pid;
+       guint ii;
 
        success = camel_internet_address_get (
                CAMEL_INTERNET_ADDRESS (from), 0, NULL, &from_addr);
@@ -203,23 +205,8 @@ sendmail_send_to_sync (CamelTransport *transport,
        }
 
        /* unlink the bcc headers */
-       savedbcc = NULL;
-       tail = (CamelHeaderRaw *) &savedbcc;
-
-       header = (CamelHeaderRaw *) &CAMEL_MIME_PART (message)->headers;
-       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;
-       }
+       previous_headers = camel_medium_dup_headers (CAMEL_MEDIUM (message));
+       camel_medium_remove_header (CAMEL_MEDIUM (message), "Bcc");
 
        if (pipe (fd) == -1) {
                g_set_error (
@@ -229,7 +216,13 @@ sendmail_send_to_sync (CamelTransport *transport,
                        "mail not sent"), binary, g_strerror (errno));
 
                /* restore the bcc headers */
-               header->next = savedbcc;
+               for (ii = 0; camel_name_value_array_get (previous_headers, ii, &header_name, &header_value); 
ii++) {
+                       if (!g_ascii_strcasecmp (header_name, "Bcc")) {
+                               camel_medium_add_header (CAMEL_MEDIUM (message), header_name, header_value);
+                       }
+               }
+
+               camel_name_value_array_free (previous_headers);
                g_free (custom_binary);
                g_free (custom_args);
                g_ptr_array_free (argv_arr, TRUE);
@@ -257,7 +250,13 @@ sendmail_send_to_sync (CamelTransport *transport,
                sigprocmask (SIG_SETMASK, &omask, NULL);
 
                /* restore the bcc headers */
-               header->next = savedbcc;
+               for (ii = 0; camel_name_value_array_get (previous_headers, ii, &header_name, &header_value); 
ii++) {
+                       if (!g_ascii_strcasecmp (header_name, "Bcc")) {
+                               camel_medium_add_header (CAMEL_MEDIUM (message), header_name, header_value);
+                       }
+               }
+
+               camel_name_value_array_free (previous_headers);
                g_free (custom_binary);
                g_free (custom_args);
                g_ptr_array_free (argv_arr, TRUE);
@@ -308,7 +307,13 @@ sendmail_send_to_sync (CamelTransport *transport,
                sigprocmask (SIG_SETMASK, &omask, NULL);
 
                /* restore the bcc headers */
-               header->next = savedbcc;
+               for (ii = 0; camel_name_value_array_get (previous_headers, ii, &header_name, &header_value); 
ii++) {
+                       if (!g_ascii_strcasecmp (header_name, "Bcc")) {
+                               camel_medium_add_header (CAMEL_MEDIUM (message), header_name, header_value);
+                       }
+               }
+
+               camel_name_value_array_free (previous_headers);
                g_free (custom_binary);
                g_free (custom_args);
 
@@ -324,7 +329,13 @@ sendmail_send_to_sync (CamelTransport *transport,
        sigprocmask (SIG_SETMASK, &omask, NULL);
 
        /* restore the bcc headers */
-       header->next = savedbcc;
+       for (ii = 0; camel_name_value_array_get (previous_headers, ii, &header_name, &header_value); ii++) {
+               if (!g_ascii_strcasecmp (header_name, "Bcc")) {
+                       camel_medium_add_header (CAMEL_MEDIUM (message), header_name, header_value);
+               }
+       }
+
+       camel_name_value_array_free (previous_headers);
 
        if (!WIFEXITED (wstat)) {
                g_set_error (
diff --git a/src/camel/providers/smtp/camel-smtp-transport.c b/src/camel/providers/smtp/camel-smtp-transport.c
index 03e2466..dc39930 100644
--- a/src/camel/providers/smtp/camel-smtp-transport.c
+++ b/src/camel/providers/smtp/camel-smtp-transport.c
@@ -1639,13 +1639,15 @@ smtp_data (CamelSmtpTransport *transport,
            GCancellable *cancellable,
            GError **error)
 {
-       CamelHeaderRaw *header, *savedbcc, *n, *tail;
+       CamelNameValueArray *previous_headers;
+       const gchar *header_name = NULL, *header_value = NULL;
        CamelBestencEncoding enctype = CAMEL_BESTENC_8BIT;
        CamelStream *filtered_stream;
        gchar *cmdbuf, *respbuf = NULL;
        CamelMimeFilter *filter;
        gsize bytes_written;
        gint ret;
+       guint ii;
 
        /* If the server doesn't support 8BITMIME, set our required encoding to be 7bit */
        if (!(transport->flags & CAMEL_SMTP_TRANSPORT_8BITMIME))
@@ -1694,24 +1696,9 @@ smtp_data (CamelSmtpTransport *transport,
        g_free (respbuf);
        respbuf = NULL;
 
-       /* unlink the bcc headers */
-       savedbcc = NULL;
-       tail = (CamelHeaderRaw *) &savedbcc;
-
-       header = (CamelHeaderRaw *) &CAMEL_MIME_PART (message)->headers;
-       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;
-       }
+       /* unlink the bcc headers and keep a copy of them */
+       previous_headers = camel_medium_dup_headers (CAMEL_MEDIUM (message));
+       camel_medium_remove_header (CAMEL_MEDIUM (message), "Bcc");
 
        /* find out how large the message is... */
        bytes_written = camel_data_wrapper_calculate_size_sync (CAMEL_DATA_WRAPPER (message), NULL, NULL);
@@ -1741,7 +1728,13 @@ smtp_data (CamelSmtpTransport *transport,
                filtered_stream, cancellable, error);
 
        /* restore the bcc headers */
-       header->next = savedbcc;
+       for (ii = 0; camel_name_value_array_get (previous_headers, ii, &header_name, &header_value); ii++) {
+               if (!g_ascii_strcasecmp (header_name, "Bcc")) {
+                       camel_medium_add_header (CAMEL_MEDIUM (message), header_name, header_value);
+               }
+       }
+
+       camel_name_value_array_free (previous_headers);
 
        if (ret == -1) {
                g_prefix_error (error, _("DATA command failed: "));


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