[evolution-data-server/imap-notify: 14/40] CamelIMAPXServer: Convert API to CamelIMAPXMailbox.



commit f86ef0826a2c9a40e4f7e853b30fec12b3b19291
Author: Matthew Barnes <mbarnes redhat com>
Date:   Tue Sep 3 07:05:22 2013 -0400

    CamelIMAPXServer: Convert API to CamelIMAPXMailbox.
    
    Convert CamelIMAPXServer to primarily use CamelIMAPXMailbox instead of
    CamelIMAPXFolder, the idea being to keep all the Camel-specific policy
    and limitations relegated to CamelIMAPXStore and CamelIMAPXFolder, and
    just have CamelIMAPXServer be a pure IMAP client implementation.
    
    This is a huge commit which I don't like doing, but CamelIMAPXServer,
    CamelIMAPXCommand and CamelIMAPXJob are so tightly intertwined that I
    was unable to split this into smaller steps.
    
    Added functions:
    
      camel_imapx_command_ref_mailbox()
      camel_imapx_job_has_mailbox()
      camel_imapx_job_ref_mailbox()
      camel_imapx_job_set_mailbox()
      camel_imapx_server_create_mailbox()
      camel_imapx_server_delete_mailbox()
      camel_imapx_server_rename_mailbox()
      camel_imapx_server_subscribe_mailbox()
      camel_imapx_server_unsubscribe_mailbox()
    
    Removed functions:
    
      camel_imapx_job_has_folder()
      camel_imapx_job_ref_folder()
      camel_imapx_job_set_mailbox()
      camel_imapx_server_manage_subscription()
      camel_imapx_server_create_folder()
      camel_imapx_server_delete_folder()
      camel_imapx_server_rename_folder()
    
    Modified function signatures:
    
      camel_imapx_command_new()
      camel_imapx_job_matches()
      camel_imapx_server_refresh_info()
      camel_imapx_server_sync_changes()
      camel_imapx_server_expunge()
      camel_imapx_server_fetch_messages()
      camel_imapx_server_noop()
      camel_imapx_server_get_message()
      camel_imapx_server_copy_message()
      camel_imapx_server_append_message()
      camel_imapx_server_sync_message()
      camel_imapx_server_manage_subscription()
      camel_imapx_server_update_quota_info()
      camel_imapx_server_uid_search()
      imapx_parse_status()

 camel/camel-imapx-command.c             |   21 +-
 camel/camel-imapx-command.h             |   10 +-
 camel/camel-imapx-folder.c              |  338 ++++--
 camel/camel-imapx-folder.h              |    3 -
 camel/camel-imapx-job.c                 |   71 +-
 camel/camel-imapx-job.h                 |   15 +-
 camel/camel-imapx-search.c              |   18 +-
 camel/camel-imapx-server.c              | 1883 ++++++++++++++++++-------------
 camel/camel-imapx-server.h              |   65 +-
 camel/camel-imapx-store.c               |  463 +++++----
 camel/camel-imapx-utils.c               |   65 +-
 camel/camel-imapx-utils.h               |    8 +-
 docs/reference/camel/camel-sections.txt |   16 +-
 13 files changed, 1735 insertions(+), 1241 deletions(-)
---
diff --git a/camel/camel-imapx-command.c b/camel/camel-imapx-command.c
index 6bbccf4..34103ae 100644
--- a/camel/camel-imapx-command.c
+++ b/camel/camel-imapx-command.c
@@ -42,6 +42,9 @@ struct _CamelIMAPXRealCommand {
        /* For building the part. */
        GString *buffer;
 
+       /* Mailbox to select before running command. */
+       GWeakRef mailbox;
+
        /* For network/parse errors. */
        GError *error;
 
@@ -59,7 +62,7 @@ struct _CamelIMAPXCommandQueue {
 CamelIMAPXCommand *
 camel_imapx_command_new (CamelIMAPXServer *is,
                          const gchar *name,
-                         CamelFolder *select,
+                         CamelIMAPXMailbox *mailbox,
                          const gchar *format,
                          ...)
 {
@@ -72,6 +75,7 @@ camel_imapx_command_new (CamelIMAPXServer *is,
        /* Initialize private bits. */
        real_ic->ref_count = 1;
        real_ic->buffer = g_string_sized_new (512);
+       g_weak_ref_set (&real_ic->mailbox, mailbox);
        g_cond_init (&real_ic->done_sync_cond);
        g_mutex_init (&real_ic->done_sync_mutex);
 
@@ -79,7 +83,6 @@ camel_imapx_command_new (CamelIMAPXServer *is,
        real_ic->public.is = is;
        real_ic->public.tag = tag++;
        real_ic->public.name = name;
-       real_ic->public.select = select;
        g_queue_init (&real_ic->public.parts);
 
        if (format != NULL && *format != '\0') {
@@ -144,6 +147,8 @@ camel_imapx_command_unref (CamelIMAPXCommand *ic)
 
                g_string_free (real_ic->buffer, TRUE);
 
+               g_weak_ref_set (&real_ic->mailbox, NULL);
+
                g_clear_error (&real_ic->error);
 
                g_cond_clear (&real_ic->done_sync_cond);
@@ -222,6 +227,18 @@ camel_imapx_command_set_job (CamelIMAPXCommand *ic,
        real_ic->job = job;
 }
 
+CamelIMAPXMailbox *
+camel_imapx_command_ref_mailbox (CamelIMAPXCommand *ic)
+{
+       CamelIMAPXRealCommand *real_ic;
+
+       g_return_val_if_fail (CAMEL_IS_IMAPX_COMMAND (ic), NULL);
+
+       real_ic = (CamelIMAPXRealCommand *) ic;
+
+       return g_weak_ref_get (&real_ic->mailbox);
+}
+
 void
 camel_imapx_command_add (CamelIMAPXCommand *ic,
                          const gchar *format,
diff --git a/camel/camel-imapx-command.h b/camel/camel-imapx-command.h
index 1094985..ed2c480 100644
--- a/camel/camel-imapx-command.h
+++ b/camel/camel-imapx-command.h
@@ -23,7 +23,8 @@
 #ifndef CAMEL_IMAPX_COMMAND_H
 #define CAMEL_IMAPX_COMMAND_H
 
-#include "camel-imapx-utils.h"
+#include <camel/camel-imapx-mailbox.h>
+#include <camel/camel-imapx-utils.h>
 
 #define CAMEL_IS_IMAPX_COMMAND(command) \
        (camel_imapx_command_check (command))
@@ -74,9 +75,6 @@ struct _CamelIMAPXCommand {
        /* Command name/type (e.g. FETCH) */
        const gchar *name;
 
-       /* Folder to select */
-       CamelFolder *select;
-
        /* Status for command, indicates it is complete if != NULL. */
        struct _status_info *status;
 
@@ -92,7 +90,7 @@ struct _CamelIMAPXCommand {
 CamelIMAPXCommand *
                camel_imapx_command_new         (struct _CamelIMAPXServer *is,
                                                 const gchar *name,
-                                                CamelFolder *select,
+                                                CamelIMAPXMailbox *mailbox,
                                                 const gchar *format,
                                                 ...);
 CamelIMAPXCommand *
@@ -105,6 +103,8 @@ struct _CamelIMAPXJob *
                camel_imapx_command_get_job     (CamelIMAPXCommand *ic);
 void           camel_imapx_command_set_job     (CamelIMAPXCommand *ic,
                                                 struct _CamelIMAPXJob *job);
+CamelIMAPXMailbox *
+               camel_imapx_command_ref_mailbox (CamelIMAPXCommand *ic);
 void           camel_imapx_command_add         (CamelIMAPXCommand *ic,
                                                 const gchar *format,
                                                 ...);
diff --git a/camel/camel-imapx-folder.c b/camel/camel-imapx-folder.c
index 643d711..23b8286 100644
--- a/camel/camel-imapx-folder.c
+++ b/camel/camel-imapx-folder.c
@@ -223,9 +223,6 @@ imapx_folder_finalize (GObject *object)
 {
        CamelIMAPXFolder *folder = CAMEL_IMAPX_FOLDER (object);
 
-       if (folder->ignore_recent != NULL)
-               g_hash_table_unref (folder->ignore_recent);
-
        g_mutex_clear (&folder->search_lock);
        g_mutex_clear (&folder->stream_lock);
 
@@ -455,22 +452,33 @@ imapx_append_message_sync (CamelFolder *folder,
        CamelStore *store;
        CamelIMAPXStore *imapx_store;
        CamelIMAPXServer *imapx_server;
+       CamelIMAPXMailbox *mailbox = NULL;
        gboolean success = FALSE;
 
+       if (appended_uid != NULL)
+               *appended_uid = NULL;
+
        store = camel_folder_get_parent_store (folder);
 
        imapx_store = CAMEL_IMAPX_STORE (store);
        imapx_server = camel_imapx_store_ref_server (imapx_store, error);
 
-       if (appended_uid != NULL)
-               *appended_uid = NULL;
+       if (imapx_server == NULL)
+               goto exit;
 
-       if (imapx_server != NULL) {
-               success = camel_imapx_server_append_message (
-                       imapx_server, folder, message, info,
-                       appended_uid, cancellable, error);
-       }
+       mailbox = camel_imapx_folder_list_mailbox (
+               CAMEL_IMAPX_FOLDER (folder), cancellable, error);
+
+       if (mailbox == NULL)
+               goto exit;
 
+       success = camel_imapx_server_append_message (
+               imapx_server, mailbox, folder->summary,
+               CAMEL_IMAPX_FOLDER (folder)->cache, message,
+               info, appended_uid, cancellable, error);
+
+exit:
+       g_clear_object (&mailbox);
        g_clear_object (&imapx_server);
 
        return success;
@@ -484,6 +492,7 @@ imapx_expunge_sync (CamelFolder *folder,
        CamelStore *store;
        CamelIMAPXStore *imapx_store;
        CamelIMAPXServer *imapx_server;
+       CamelIMAPXMailbox *mailbox = NULL;
        gboolean success = FALSE;
 
        store = camel_folder_get_parent_store (folder);
@@ -491,11 +500,20 @@ imapx_expunge_sync (CamelFolder *folder,
        imapx_store = CAMEL_IMAPX_STORE (store);
        imapx_server = camel_imapx_store_ref_server (imapx_store, error);
 
-       if (imapx_server != NULL) {
-               success = camel_imapx_server_expunge (
-                       imapx_server, folder, cancellable, error);
-       }
+       if (imapx_server == NULL)
+               goto exit;
+
+       mailbox = camel_imapx_folder_list_mailbox (
+               CAMEL_IMAPX_FOLDER (folder), cancellable, error);
+
+       if (mailbox == NULL)
+               goto exit;
+
+       success = camel_imapx_server_expunge (
+               imapx_server, mailbox, cancellable, error);
 
+exit:
+       g_clear_object (&mailbox);
        g_clear_object (&imapx_server);
 
        return success;
@@ -511,6 +529,8 @@ imapx_fetch_messages_sync (CamelFolder *folder,
        CamelStore *store;
        CamelIMAPXStore *imapx_store;
        CamelIMAPXServer *imapx_server;
+       CamelIMAPXMailbox *mailbox = NULL;
+       CamelFolderChangeInfo *changes;
        gboolean success = FALSE;
 
        store = camel_folder_get_parent_store (folder);
@@ -518,11 +538,27 @@ imapx_fetch_messages_sync (CamelFolder *folder,
        imapx_store = CAMEL_IMAPX_STORE (store);
        imapx_server = camel_imapx_store_ref_server (imapx_store, error);
 
-       if (imapx_server != NULL) {
-               success = camel_imapx_server_fetch_messages (
-                       imapx_server, folder, type, limit, cancellable, error);
+       if (imapx_server == NULL)
+               goto exit;
+
+       mailbox = camel_imapx_folder_list_mailbox (
+               CAMEL_IMAPX_FOLDER (folder), cancellable, error);
+
+       if (mailbox == NULL)
+               goto exit;
+
+       changes = camel_imapx_server_fetch_messages (
+               imapx_server, mailbox, type, limit, cancellable, error);
+
+       if (changes != NULL) {
+               if (camel_folder_change_info_changed (changes))
+                       camel_folder_changed (folder, changes);
+               camel_folder_change_info_free (changes);
+               success = TRUE;
        }
 
+exit:
+       g_clear_object (&mailbox);
        g_clear_object (&imapx_server);
 
        return success;
@@ -554,6 +590,7 @@ imapx_get_message_sync (CamelFolder *folder,
        stream = camel_data_cache_get (imapx_folder->cache, path, uid, NULL);
        if (stream == NULL) {
                CamelIMAPXServer *imapx_server;
+               CamelIMAPXMailbox *mailbox;
 
                if (offline_message) {
                        g_set_error (
@@ -566,11 +603,23 @@ imapx_get_message_sync (CamelFolder *folder,
                imapx_server = camel_imapx_store_ref_server (
                        CAMEL_IMAPX_STORE (store), error);
 
-               if (imapx_server != NULL) {
-                       stream = camel_imapx_server_get_message (
-                               imapx_server, folder, uid, cancellable, error);
+               if (imapx_server == NULL)
+                       return NULL;
+
+               mailbox = camel_imapx_folder_list_mailbox (
+                       CAMEL_IMAPX_FOLDER (folder), cancellable, error);
+
+               if (mailbox == NULL) {
+                       g_object_unref (imapx_server);
+                       return NULL;
                }
 
+               stream = camel_imapx_server_get_message (
+                       imapx_server, mailbox, folder->summary,
+                       CAMEL_IMAPX_FOLDER (folder)->cache, uid,
+                       cancellable, error);
+
+               g_clear_object (&mailbox);
                g_clear_object (&imapx_server);
        }
 
@@ -622,43 +671,50 @@ imapx_get_quota_info_sync (CamelFolder *folder,
        CamelStore *store;
        CamelIMAPXStore *imapx_store;
        CamelIMAPXServer *imapx_server;
+       CamelIMAPXMailbox *mailbox = NULL;
        CamelFolderQuotaInfo *quota_info = NULL;
-       const gchar *folder_name;
-       gchar **quota_root_names;
+       gchar **quota_roots;
        gboolean success = FALSE;
 
        store = camel_folder_get_parent_store (folder);
-       folder_name = camel_folder_get_full_name (folder);
 
        imapx_store = CAMEL_IMAPX_STORE (store);
        imapx_server = camel_imapx_store_ref_server (imapx_store, error);
 
-       if (imapx_server != NULL) {
-               success = camel_imapx_server_update_quota_info (
-                       imapx_server, folder_name, cancellable, error);
-       }
+       if (imapx_server == NULL)
+               goto exit;
 
-       g_clear_object (&imapx_server);
+       mailbox = camel_imapx_folder_list_mailbox (
+               CAMEL_IMAPX_FOLDER (folder), cancellable, error);
+       if (mailbox == NULL)
+               goto exit;
+
+       success = camel_imapx_server_update_quota_info (
+               imapx_server, mailbox, cancellable, error);
 
        if (!success)
-               return NULL;
+               goto exit;
 
-       quota_root_names = camel_imapx_folder_dup_quota_root_names (
+       quota_roots = camel_imapx_folder_dup_quota_root_names (
                CAMEL_IMAPX_FOLDER (folder));
 
-       /* XXX Just return info for the first quota root name, I guess. */
-       if (quota_root_names != NULL && quota_root_names[0] != NULL)
+       /* XXX Just return info for the first quota root, I guess. */
+       if (quota_roots != NULL && quota_roots[0] != NULL) {
                quota_info = camel_imapx_store_dup_quota_info (
-                       CAMEL_IMAPX_STORE (store),
-                       quota_root_names[0]);
+                       CAMEL_IMAPX_STORE (store), quota_roots[0]);
+       }
 
-       g_strfreev (quota_root_names);
+       g_strfreev (quota_roots);
 
        if (quota_info == NULL)
                g_set_error (
                        error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
                        _("No quota information available for folder '%s'"),
-                       folder_name);
+                       camel_folder_get_full_name (folder));
+
+exit:
+       g_clear_object (&mailbox);
+       g_clear_object (&imapx_server);
 
        return quota_info;
 }
@@ -682,6 +738,8 @@ imapx_refresh_info_sync (CamelFolder *folder,
        CamelStore *store;
        CamelIMAPXStore *imapx_store;
        CamelIMAPXServer *imapx_server;
+       CamelIMAPXMailbox *mailbox = NULL;
+       CamelFolderChangeInfo *changes;
        gboolean success = FALSE;
 
        store = camel_folder_get_parent_store (folder);
@@ -689,11 +747,27 @@ imapx_refresh_info_sync (CamelFolder *folder,
        imapx_store = CAMEL_IMAPX_STORE (store);
        imapx_server = camel_imapx_store_ref_server (imapx_store, error);
 
-       if (imapx_server != NULL) {
-               success = camel_imapx_server_refresh_info (
-                       imapx_server, folder, cancellable, error);
+       if (imapx_server == NULL)
+               goto exit;
+
+       mailbox = camel_imapx_folder_list_mailbox (
+               CAMEL_IMAPX_FOLDER (folder), cancellable, error);
+
+       if (mailbox == NULL)
+               goto exit;
+
+       changes = camel_imapx_server_refresh_info (
+               imapx_server, mailbox, cancellable, error);
+
+       if (changes != NULL) {
+               if (camel_folder_change_info_changed (changes))
+                       camel_folder_changed (folder, changes);
+               camel_folder_change_info_free (changes);
+               success = TRUE;
        }
 
+exit:
+       g_clear_object (&mailbox);
        g_clear_object (&imapx_server);
 
        return success;
@@ -707,6 +781,8 @@ imapx_move_to_real_junk (CamelIMAPXServer *imapx_server,
                          gboolean *out_need_to_expunge,
                          GError **error)
 {
+       CamelIMAPXFolder *imapx_folder;
+       CamelIMAPXMailbox *mailbox;
        CamelIMAPXSettings *settings;
        GPtrArray *uids_to_copy;
        gchar *real_junk_path = NULL;
@@ -714,6 +790,12 @@ imapx_move_to_real_junk (CamelIMAPXServer *imapx_server,
 
        *out_need_to_expunge = FALSE;
 
+       /* Caller already obtained the mailbox from the folder,
+        * so the folder should still have it readily available. */
+       imapx_folder = CAMEL_IMAPX_FOLDER (folder);
+       mailbox = camel_imapx_folder_ref_mailbox (imapx_folder);
+       g_return_val_if_fail (mailbox != NULL, FALSE);
+
        uids_to_copy = g_ptr_array_new_with_free_func (
                (GDestroyNotify) camel_pstring_free);
 
@@ -722,19 +804,19 @@ imapx_move_to_real_junk (CamelIMAPXServer *imapx_server,
                real_junk_path =
                        camel_imapx_settings_dup_real_junk_path (settings);
                imapx_folder_claim_move_to_real_junk_uids (
-                       CAMEL_IMAPX_FOLDER (folder), uids_to_copy);
+                       imapx_folder, uids_to_copy);
        }
        g_object_unref (settings);
 
        if (uids_to_copy->len > 0) {
-               CamelFolder *destination = NULL;
-               CamelIMAPXStore *store;
+               CamelIMAPXStore *imapx_store;
+               CamelIMAPXMailbox *destination = NULL;
 
-               store = camel_imapx_server_ref_store (imapx_server);
+               imapx_store = camel_imapx_server_ref_store (imapx_server);
 
                if (real_junk_path != NULL) {
-                       destination = camel_store_get_folder_sync (
-                               CAMEL_STORE (store),
+                       folder = camel_store_get_folder_sync (
+                               CAMEL_STORE (imapx_store),
                                real_junk_path, 0,
                                cancellable, error);
                } else {
@@ -742,15 +824,23 @@ imapx_move_to_real_junk (CamelIMAPXServer *imapx_server,
                                error, CAMEL_FOLDER_ERROR,
                                CAMEL_FOLDER_ERROR_INVALID_PATH,
                                _("No destination folder specified"));
+                       folder = NULL;
+               }
+
+               if (folder != NULL) {
+                       destination = camel_imapx_folder_list_mailbox (
+                               CAMEL_IMAPX_FOLDER (folder),
+                               cancellable, error);
+                       g_object_unref (folder);
                }
 
                /* Avoid duplicating messages in the Junk folder. */
-               if (destination == folder) {
+               if (destination == mailbox) {
                        success = TRUE;
                } else if (destination != NULL) {
                        success = camel_imapx_server_copy_message (
                                imapx_server,
-                               folder, destination,
+                               mailbox, destination,
                                uids_to_copy, TRUE,
                                cancellable, error);
                        *out_need_to_expunge = success;
@@ -764,12 +854,15 @@ imapx_move_to_real_junk (CamelIMAPXServer *imapx_server,
                                _("Unable to move junk messages"));
                }
 
-               g_object_unref (store);
+               g_clear_object (&destination);
+               g_clear_object (&imapx_store);
        }
 
        g_ptr_array_unref (uids_to_copy);
        g_free (real_junk_path);
 
+       g_clear_object (&mailbox);
+
        return success;
 }
 
@@ -781,6 +874,8 @@ imapx_move_to_real_trash (CamelIMAPXServer *imapx_server,
                           gboolean *out_need_to_expunge,
                           GError **error)
 {
+       CamelIMAPXFolder *imapx_folder;
+       CamelIMAPXMailbox *mailbox;
        CamelIMAPXSettings *settings;
        GPtrArray *uids_to_copy;
        gchar *real_trash_path = NULL;
@@ -788,6 +883,12 @@ imapx_move_to_real_trash (CamelIMAPXServer *imapx_server,
 
        *out_need_to_expunge = FALSE;
 
+       /* Caller already obtained the mailbox from the folder,
+        * so the folder should still have it readily available. */
+       imapx_folder = CAMEL_IMAPX_FOLDER (folder);
+       mailbox = camel_imapx_folder_ref_mailbox (imapx_folder);
+       g_return_val_if_fail (mailbox != NULL, FALSE);
+
        uids_to_copy = g_ptr_array_new_with_free_func (
                (GDestroyNotify) camel_pstring_free);
 
@@ -801,14 +902,14 @@ imapx_move_to_real_trash (CamelIMAPXServer *imapx_server,
        g_object_unref (settings);
 
        if (uids_to_copy->len > 0) {
-               CamelFolder *destination = NULL;
-               CamelIMAPXStore *store;
+               CamelIMAPXStore *imapx_store;
+               CamelIMAPXMailbox *destination = NULL;
 
-               store = camel_imapx_server_ref_store (imapx_server);
+               imapx_store = camel_imapx_server_ref_store (imapx_server);
 
                if (real_trash_path != NULL) {
-                       destination = camel_store_get_folder_sync (
-                               CAMEL_STORE (store),
+                       folder = camel_store_get_folder_sync (
+                               CAMEL_STORE (imapx_store),
                                real_trash_path, 0,
                                cancellable, error);
                } else {
@@ -816,15 +917,23 @@ imapx_move_to_real_trash (CamelIMAPXServer *imapx_server,
                                error, CAMEL_FOLDER_ERROR,
                                CAMEL_FOLDER_ERROR_INVALID_PATH,
                                _("No destination folder specified"));
+                       folder = NULL;
+               }
+
+               if (folder != NULL) {
+                       destination = camel_imapx_folder_list_mailbox (
+                               CAMEL_IMAPX_FOLDER (folder),
+                               cancellable, error);
+                       g_object_unref (folder);
                }
 
                /* Avoid duplicating messages in the Trash folder. */
-               if (destination == folder) {
+               if (destination == mailbox) {
                        success = TRUE;
                } else if (destination != NULL) {
                        success = camel_imapx_server_copy_message (
                                imapx_server,
-                               folder, destination,
+                               mailbox, destination,
                                uids_to_copy, TRUE,
                                cancellable, error);
                        *out_need_to_expunge = success;
@@ -838,12 +947,15 @@ imapx_move_to_real_trash (CamelIMAPXServer *imapx_server,
                                _("Unable to move deleted messages"));
                }
 
-               g_object_unref (store);
+               g_clear_object (&destination);
+               g_clear_object (&imapx_store);
        }
 
        g_ptr_array_unref (uids_to_copy);
        g_free (real_trash_path);
 
+       g_clear_object (&mailbox);
+
        return success;
 }
 
@@ -856,6 +968,8 @@ imapx_synchronize_sync (CamelFolder *folder,
        CamelStore *store;
        CamelIMAPXStore *imapx_store;
        CamelIMAPXServer *imapx_server;
+       CamelIMAPXMailbox *mailbox = NULL;
+       gboolean need_to_expunge;
        gboolean success = FALSE;
 
        store = camel_folder_get_parent_store (folder);
@@ -863,34 +977,41 @@ imapx_synchronize_sync (CamelFolder *folder,
        imapx_store = CAMEL_IMAPX_STORE (store);
        imapx_server = camel_imapx_store_ref_server (imapx_store, error);
 
-       if (imapx_server != NULL) {
-               gboolean need_to_expunge;
+       if (imapx_server == NULL)
+               goto exit;
 
-               success = camel_imapx_server_sync_changes (
-                       imapx_server, folder, cancellable, error);
+       mailbox = camel_imapx_folder_list_mailbox (
+               CAMEL_IMAPX_FOLDER (folder), cancellable, error);
+       if (mailbox == NULL)
+               goto exit;
 
-               if (success) {
-                       success = imapx_move_to_real_junk (
-                               imapx_server, folder, cancellable,
-                               &need_to_expunge, error);
-                       expunge |= need_to_expunge;
-               }
+       success = camel_imapx_server_sync_changes (
+               imapx_server, mailbox, cancellable, error);
 
-               if (success) {
-                       success = imapx_move_to_real_trash (
-                               imapx_server, folder, cancellable,
-                               &need_to_expunge, error);
-                       expunge |= need_to_expunge;
-               }
+       if (success) {
+               success = imapx_move_to_real_junk (
+                       imapx_server, folder, cancellable,
+                       &need_to_expunge, error);
+               expunge |= need_to_expunge;
+       }
+
+       if (success) {
+               success = imapx_move_to_real_trash (
+                       imapx_server, folder, cancellable,
+                       &need_to_expunge, error);
+               expunge |= need_to_expunge;
+       }
 
-               /* Sync twice - make sure deleted flags are written out,
-                * then sync again incase expunge changed anything */
+       /* Sync twice - make sure deleted flags are written out,
+        * then sync again incase expunge changed anything */
 
-               if (success && expunge)
-                       success = camel_imapx_server_expunge (
-                               imapx_server, folder, cancellable, error);
+       if (success && expunge) {
+               success = camel_imapx_server_expunge (
+                       imapx_server, mailbox, cancellable, error);
        }
 
+exit:
+       g_clear_object (&mailbox);
        g_clear_object (&imapx_server);
 
        return success;
@@ -905,6 +1026,7 @@ imapx_synchronize_message_sync (CamelFolder *folder,
        CamelStore *store;
        CamelIMAPXStore *imapx_store;
        CamelIMAPXServer *imapx_server;
+       CamelIMAPXMailbox *mailbox = NULL;
        gboolean success = FALSE;
 
        store = camel_folder_get_parent_store (folder);
@@ -912,11 +1034,22 @@ imapx_synchronize_message_sync (CamelFolder *folder,
        imapx_store = CAMEL_IMAPX_STORE (store);
        imapx_server = camel_imapx_store_ref_server (imapx_store, error);
 
-       if (imapx_server != NULL) {
-               success = camel_imapx_server_sync_message (
-                       imapx_server, folder, uid, cancellable, error);
-       }
+       if (imapx_server == NULL)
+               goto exit;
+
+       mailbox = camel_imapx_folder_list_mailbox (
+               CAMEL_IMAPX_FOLDER (folder), cancellable, error);
+
+       if (mailbox == NULL)
+               goto exit;
+
+       success = camel_imapx_server_sync_message (
+               imapx_server, mailbox, folder->summary,
+               CAMEL_IMAPX_FOLDER (folder)->cache, uid,
+               cancellable, error);
 
+exit:
+       g_clear_object (&mailbox);
        g_clear_object (&imapx_server);
 
        return success;
@@ -934,6 +1067,8 @@ imapx_transfer_messages_to_sync (CamelFolder *source,
        CamelStore *store;
        CamelIMAPXStore *imapx_store;
        CamelIMAPXServer *imapx_server;
+       CamelIMAPXMailbox *src_mailbox = NULL;
+       CamelIMAPXMailbox *dst_mailbox = NULL;
        gboolean success = FALSE;
 
        store = camel_folder_get_parent_store (source);
@@ -941,18 +1076,34 @@ imapx_transfer_messages_to_sync (CamelFolder *source,
        imapx_store = CAMEL_IMAPX_STORE (store);
        imapx_server = camel_imapx_store_ref_server (imapx_store, error);
 
-       if (imapx_server != NULL) {
-               success = camel_imapx_server_copy_message (
-                       imapx_server, source, dest, uids,
-                       delete_originals, cancellable, error);
+       if (imapx_server == NULL)
+               goto exit;
 
-               /* Update destination folder only if it's not frozen,
-                * to avoid updating for each "move" action on a single
-                * message while filtering. */
-               if (!camel_folder_is_frozen (dest))
-                       imapx_refresh_info_sync (dest, cancellable, NULL);
-       }
+       src_mailbox = camel_imapx_folder_list_mailbox (
+               CAMEL_IMAPX_FOLDER (source), cancellable, error);
+
+       if (src_mailbox == NULL)
+               goto exit;
+
+       dst_mailbox = camel_imapx_folder_list_mailbox (
+               CAMEL_IMAPX_FOLDER (dest), cancellable, error);
 
+       if (dst_mailbox == NULL)
+               goto exit;
+
+       success = camel_imapx_server_copy_message (
+               imapx_server, src_mailbox, dst_mailbox, uids,
+               delete_originals, cancellable, error);
+
+       /* Update destination folder only if it's not frozen,
+        * to avoid updating for each "move" action on a single
+        * message while filtering. */
+       if (!camel_folder_is_frozen (dest))
+               imapx_refresh_info_sync (dest, cancellable, NULL);
+
+exit:
+       g_clear_object (&src_mailbox);
+       g_clear_object (&dst_mailbox);
        g_clear_object (&imapx_server);
 
        return success;
@@ -1161,11 +1312,6 @@ camel_imapx_folder_new (CamelStore *store,
        imapx_folder->search = camel_imapx_search_new ();
        g_mutex_init (&imapx_folder->search_lock);
        g_mutex_init (&imapx_folder->stream_lock);
-       imapx_folder->ignore_recent = g_hash_table_new_full (
-               (GHashFunc) g_str_hash,
-               (GEqualFunc) g_str_equal,
-               (GDestroyNotify) g_free,
-               (GDestroyNotify) NULL);
        imapx_folder->exists_on_server = 0;
        imapx_folder->unread_on_server = 0;
        imapx_folder->modseq_on_server = 0;
diff --git a/camel/camel-imapx-folder.h b/camel/camel-imapx-folder.h
index f2120f0..48e4870 100644
--- a/camel/camel-imapx-folder.h
+++ b/camel/camel-imapx-folder.h
@@ -74,9 +74,6 @@ struct _CamelIMAPXFolder {
        guint64 uidvalidity_on_server;
        guint32 uidnext_on_server;
 
-       /* hash table of UIDs to ignore as recent when updating folder */
-       GHashTable *ignore_recent;
-
        GMutex search_lock;
        GMutex stream_lock;
 
diff --git a/camel/camel-imapx-job.c b/camel/camel-imapx-job.c
index 49c3988..07e09a3 100644
--- a/camel/camel-imapx-job.c
+++ b/camel/camel-imapx-job.c
@@ -20,6 +20,8 @@
 
 #include <string.h>
 
+#include <camel/camel-imapx-folder.h>
+
 typedef struct _CamelIMAPXRealJob CamelIMAPXRealJob;
 
 /* CamelIMAPXJob + some private bits */
@@ -43,8 +45,8 @@ struct _CamelIMAPXRealJob {
        gpointer data;
        GDestroyNotify destroy_data;
 
-       CamelFolder *folder;
-       GMutex folder_lock;
+       CamelIMAPXMailbox *mailbox;
+       GMutex mailbox_lock;
 };
 
 static void
@@ -75,7 +77,7 @@ camel_imapx_job_new (GCancellable *cancellable)
                g_object_ref (cancellable);
        real_job->cancellable = cancellable;
 
-       g_mutex_init (&real_job->folder_lock);
+       g_mutex_init (&real_job->mailbox_lock);
 
        return (CamelIMAPXJob *) real_job;
 }
@@ -123,9 +125,8 @@ camel_imapx_job_unref (CamelIMAPXJob *job)
                if (real_job->destroy_data != NULL)
                        real_job->destroy_data (real_job->data);
 
-               if (real_job->folder != NULL)
-                       g_object_unref (real_job->folder);
-               g_mutex_clear (&real_job->folder_lock);
+               g_clear_object (&real_job->mailbox);
+               g_mutex_clear (&real_job->mailbox_lock);
 
                /* Fill the memory with a bit pattern before releasing
                 * it back to the slab allocator, so we can more easily
@@ -265,21 +266,21 @@ camel_imapx_job_run (CamelIMAPXJob *job,
 
 gboolean
 camel_imapx_job_matches (CamelIMAPXJob *job,
-                         CamelFolder *folder,
+                         CamelIMAPXMailbox *mailbox,
                          const gchar *uid)
 {
-       /* XXX CamelFolder can be NULL.  I'm less sure about the
-        *     message UID but let's assume that can be NULL too. */
+       /* XXX CamelIMAPXMailbox can be NULL.  I'm less sure about
+        *     the message UID but let's assume that can be NULL too. */
 
        g_return_val_if_fail (CAMEL_IS_IMAPX_JOB (job), FALSE);
 
-       if (folder != NULL)
-               g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
+       if (mailbox != NULL)
+               g_return_val_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox), FALSE);
 
        if (job->matches == NULL)
                return FALSE;
 
-       return job->matches (job, folder, uid);
+       return job->matches (job, mailbox, uid);
 }
 
 gpointer
@@ -313,47 +314,47 @@ camel_imapx_job_set_data (CamelIMAPXJob *job,
 }
 
 gboolean
-camel_imapx_job_has_folder (CamelIMAPXJob *job,
-                            CamelFolder *folder)
+camel_imapx_job_has_mailbox (CamelIMAPXJob *job,
+                             CamelIMAPXMailbox *mailbox)
 {
        CamelIMAPXRealJob *real_job;
 
        g_return_val_if_fail (CAMEL_IS_IMAPX_JOB (job), FALSE);
 
-       if (folder != NULL)
-               g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
+       if (mailbox != NULL)
+               g_return_val_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox), FALSE);
 
        real_job = (CamelIMAPXRealJob *) job;
 
        /* Not necessary to lock the mutex since
         * we're just comparing memory addresses. */
 
-       return (folder == real_job->folder);
+       return (mailbox == real_job->mailbox);
 }
 
-CamelFolder *
-camel_imapx_job_ref_folder (CamelIMAPXJob *job)
+CamelIMAPXMailbox *
+camel_imapx_job_ref_mailbox (CamelIMAPXJob *job)
 {
        CamelIMAPXRealJob *real_job;
-       CamelFolder *folder = NULL;
+       CamelIMAPXMailbox *mailbox = NULL;
 
        g_return_val_if_fail (CAMEL_IS_IMAPX_JOB (job), NULL);
 
        real_job = (CamelIMAPXRealJob *) job;
 
-       g_mutex_lock (&real_job->folder_lock);
+       g_mutex_lock (&real_job->mailbox_lock);
 
-       if (real_job->folder != NULL)
-               folder = g_object_ref (real_job->folder);
+       if (real_job->mailbox != NULL)
+               mailbox = g_object_ref (real_job->mailbox);
 
-       g_mutex_unlock (&real_job->folder_lock);
+       g_mutex_unlock (&real_job->mailbox_lock);
 
-       return folder;
+       return mailbox;
 }
 
 void
-camel_imapx_job_set_folder (CamelIMAPXJob *job,
-                            CamelFolder *folder)
+camel_imapx_job_set_mailbox (CamelIMAPXJob *job,
+                             CamelIMAPXMailbox *mailbox)
 {
        CamelIMAPXRealJob *real_job;
 
@@ -361,19 +362,17 @@ camel_imapx_job_set_folder (CamelIMAPXJob *job,
 
        real_job = (CamelIMAPXRealJob *) job;
 
-       if (folder != NULL) {
-               g_return_if_fail (CAMEL_IS_FOLDER (folder));
-               g_object_ref (folder);
+       if (mailbox != NULL) {
+               g_return_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox));
+               g_object_ref (mailbox);
        }
 
-       g_mutex_lock (&real_job->folder_lock);
-
-       if (real_job->folder != NULL)
-               g_object_unref (real_job->folder);
+       g_mutex_lock (&real_job->mailbox_lock);
 
-       real_job->folder = folder;
+       g_clear_object (&real_job->mailbox);
+       real_job->mailbox = mailbox;
 
-       g_mutex_unlock (&real_job->folder_lock);
+       g_mutex_unlock (&real_job->mailbox_lock);
 }
 
 GCancellable *
diff --git a/camel/camel-imapx-job.h b/camel/camel-imapx-job.h
index 4b57864..840385b 100644
--- a/camel/camel-imapx-job.h
+++ b/camel/camel-imapx-job.h
@@ -49,7 +49,7 @@ struct _CamelIMAPXJob {
                                                 GCancellable *cancellable,
                                                 GError **error);
        gboolean        (*matches)              (CamelIMAPXJob *job,
-                                                CamelFolder *folder,
+                                                CamelIMAPXMailbox *mailbox,
                                                 const gchar *uid);
 
        guint noreply:1;        /* dont wait for reply */
@@ -70,17 +70,18 @@ gboolean    camel_imapx_job_run             (CamelIMAPXJob *job,
                                                 CamelIMAPXServer *is,
                                                 GError **error);
 gboolean       camel_imapx_job_matches         (CamelIMAPXJob *job,
-                                                CamelFolder *folder,
+                                                CamelIMAPXMailbox *mailbox,
                                                 const gchar *uid);
 gpointer       camel_imapx_job_get_data        (CamelIMAPXJob *job);
 void           camel_imapx_job_set_data        (CamelIMAPXJob *job,
                                                 gpointer data,
                                                 GDestroyNotify destroy_data);
-gboolean       camel_imapx_job_has_folder      (CamelIMAPXJob *job,
-                                                CamelFolder *folder);
-CamelFolder *  camel_imapx_job_ref_folder      (CamelIMAPXJob *job);
-void           camel_imapx_job_set_folder      (CamelIMAPXJob *job,
-                                                CamelFolder *folder);
+gboolean       camel_imapx_job_has_mailbox     (CamelIMAPXJob *job,
+                                                CamelIMAPXMailbox *mailbox);
+CamelIMAPXMailbox *
+               camel_imapx_job_ref_mailbox     (CamelIMAPXJob *job);
+void           camel_imapx_job_set_mailbox     (CamelIMAPXJob *job,
+                                                CamelIMAPXMailbox *mailbox);
 GCancellable * camel_imapx_job_get_cancellable (CamelIMAPXJob *job);
 void           camel_imapx_job_take_error      (CamelIMAPXJob *job,
                                                 GError *error);
diff --git a/camel/camel-imapx-search.c b/camel/camel-imapx-search.c
index cae7792..8b46de4 100644
--- a/camel/camel-imapx-search.c
+++ b/camel/camel-imapx-search.c
@@ -94,10 +94,11 @@ imapx_search_body_contains (CamelSExp *sexp,
                             CamelFolderSearch *search)
 {
        CamelIMAPXServer *server;
+       CamelIMAPXMailbox *mailbox;
        CamelSExpResult *result;
        CamelSExpResultType type;
        GString *criteria;
-       GPtrArray *uids;
+       GPtrArray *uids = NULL;
        gint ii, jj;
        GError *error = NULL;
 
@@ -157,8 +158,19 @@ imapx_search_body_contains (CamelSExp *sexp,
                }
        }
 
-       uids = camel_imapx_server_uid_search (
-               server, search->folder, criteria->str, NULL, &error);
+       mailbox = camel_imapx_folder_list_mailbox (
+               CAMEL_IMAPX_FOLDER (search->folder), NULL, &error);
+
+       /* Sanity check. */
+       g_return_val_if_fail (
+               ((mailbox != NULL) && (error == NULL)) ||
+               ((mailbox == NULL) && (error != NULL)), NULL);
+
+       if (mailbox != NULL) {
+               uids = camel_imapx_server_uid_search (
+                       server, mailbox, criteria->str, NULL, &error);
+               g_object_unref (mailbox);
+       }
 
        /* Sanity check. */
        g_return_val_if_fail (
diff --git a/camel/camel-imapx-server.c b/camel/camel-imapx-server.c
index 19cdace..1fb3b87 100644
--- a/camel/camel-imapx-server.c
+++ b/camel/camel-imapx-server.c
@@ -69,16 +69,13 @@ typedef struct _SyncChangesData SyncChangesData;
 typedef struct _AppendMessageData AppendMessageData;
 typedef struct _CopyMessagesData CopyMessagesData;
 typedef struct _ListData ListData;
-typedef struct _ManageSubscriptionsData ManageSubscriptionsData;
-typedef struct _RenameFolderData RenameFolderData;
-typedef struct _CreateFolderData CreateFolderData;
-typedef struct _DeleteFolderData DeleteFolderData;
-typedef struct _QuotaData QuotaData;
+typedef struct _MailboxData MailboxData;
 typedef struct _SearchData SearchData;
 
 struct _GetMessageData {
        /* in: uid requested */
        gchar *uid;
+       CamelDataCache *message_cache;
        /* in/out: message content stream output */
        CamelStream *stream;
        /* working variables */
@@ -126,7 +123,7 @@ struct _AppendMessageData {
 };
 
 struct _CopyMessagesData {
-       CamelFolder *dest;
+       CamelIMAPXMailbox *destination;
        GPtrArray *uids;
        gboolean delete_originals;
        gboolean use_move_command;
@@ -142,22 +139,9 @@ struct _ListData {
        GHashTable *folders;
 };
 
-struct _ManageSubscriptionsData {
-       gchar *folder_name;
-       gboolean subscribe;
-};
-
-struct _RenameFolderData {
-       gchar *old_folder_name;
-       gchar *new_folder_name;
-};
-
-struct _CreateFolderData {
-       gchar *folder_name;
-};
-
-struct _DeleteFolderData {
-       gchar *folder_name;
+struct _MailboxData {
+       CamelIMAPXMailbox *mailbox;
+       gchar *mailbox_name;
 };
 
 struct _SearchData {
@@ -165,10 +149,6 @@ struct _SearchData {
        GArray *results;
 };
 
-struct _QuotaData {
-       gchar *folder_name;
-};
-
 /* untagged response handling */
 
 /* May need to turn this into separate,
@@ -334,16 +314,10 @@ struct _CamelIMAPXServerPrivate {
 
        /* Info on currently selected folder. */
        GMutex select_lock;
-       GWeakRef select_folder;
+       GWeakRef select_mailbox;
        GWeakRef select_pending;
        CamelFolderChangeInfo *changes;
        guint32 permanentflags;
-       guint32 unseen;
-       guint64 uidvalidity;
-       guint64 highestmodseq;
-       guint32 uidnext;
-       guint32 exists;
-       guint32 recent;
 
        /* Data items to request in STATUS commands:
         * STATUS $mailbox_name ($status_data_items) */
@@ -432,22 +406,20 @@ enum {
        IMAPX_JOB_NOOP = 1 << 7,
        IMAPX_JOB_IDLE = 1 << 8,
        IMAPX_JOB_LIST = 1 << 9,
-       IMAPX_JOB_MANAGE_SUBSCRIPTION = 1 << 10,
-       IMAPX_JOB_CREATE_FOLDER = 1 << 11,
-       IMAPX_JOB_DELETE_FOLDER = 1 << 12,
-       IMAPX_JOB_RENAME_FOLDER = 1 << 13,
-       IMAPX_JOB_FETCH_MESSAGES = 1 << 14,
-       IMAPX_JOB_UPDATE_QUOTA_INFO = 1 << 15,
-       IMAPX_JOB_UID_SEARCH = 1 << 16
+       IMAPX_JOB_CREATE_MAILBOX = 1 << 10,
+       IMAPX_JOB_DELETE_MAILBOX = 1 << 11,
+       IMAPX_JOB_RENAME_MAILBOX = 1 << 12,
+       IMAPX_JOB_SUBSCRIBE_MAILBOX = 1 << 13,
+       IMAPX_JOB_UNSUBSCRIBE_MAILBOX = 1 << 14,
+       IMAPX_JOB_FETCH_MESSAGES = 1 << 15,
+       IMAPX_JOB_UPDATE_QUOTA_INFO = 1 << 16,
+       IMAPX_JOB_UID_SEARCH = 1 << 17
 };
 
-/* Operations on the store (folder_tree) will have highest priority as we know for sure they are sync
- * and user triggered. */
+/* Mailbox management operations have highest priority
+ * since we know for sure that they are user triggered. */
 enum {
-       IMAPX_PRIORITY_CREATE_FOLDER = 200,
-       IMAPX_PRIORITY_DELETE_FOLDER = 200,
-       IMAPX_PRIORITY_RENAME_FOLDER = 200,
-       IMAPX_PRIORITY_MANAGE_SUBSCRIPTION = 200,
+       IMAPX_PRIORITY_MAILBOX_MGMT = 200,
        IMAPX_PRIORITY_SYNC_CHANGES = 150,
        IMAPX_PRIORITY_EXPUNGE = 150,
        IMAPX_PRIORITY_SEARCH = 150,
@@ -483,7 +455,7 @@ static gint imapx_refresh_info_uid_cmp      (gconstpointer ap,
 static gint    imapx_uids_array_cmp            (gconstpointer ap,
                                                 gconstpointer bp);
 static gboolean        imapx_server_sync_changes       (CamelIMAPXServer *is,
-                                                CamelFolder *folder,
+                                                CamelIMAPXMailbox *mailbox,
                                                 guint32 job_type,
                                                 gint pri,
                                                 GCancellable *cancellable,
@@ -538,13 +510,13 @@ static CamelIMAPXIdleStopResult
                                                 CamelIMAPXStream *stream,
                                                 GError **error);
 static gboolean        camel_imapx_server_idle         (CamelIMAPXServer *is,
-                                                CamelFolder *folder,
+                                                CamelIMAPXMailbox *mailbox,
                                                 GCancellable *cancellable,
                                                 GError **error);
 
 static void    imapx_maybe_select              (CamelIMAPXServer *is,
                                                 CamelIMAPXJob *job,
-                                                CamelFolder *folder);
+                                                CamelIMAPXMailbox *mailbox);
 
 G_DEFINE_TYPE (CamelIMAPXServer, camel_imapx_server, CAMEL_TYPE_OBJECT)
 
@@ -610,8 +582,8 @@ get_message_data_free (GetMessageData *data)
 {
        g_free (data->uid);
 
-       if (data->stream != NULL)
-               g_object_unref (data->stream);
+       g_clear_object (&data->message_cache);
+       g_clear_object (&data->stream);
 
        g_slice_free (GetMessageData, data);
 }
@@ -638,7 +610,9 @@ refresh_info_data_infos_free (RefreshInfoData *data)
 static void
 refresh_info_data_free (RefreshInfoData *data)
 {
-       camel_folder_change_info_free (data->changes);
+       if (data->changes != NULL)
+               camel_folder_change_info_free (data->changes);
+
        refresh_info_data_infos_free (data);
 
        g_slice_free (RefreshInfoData, data);
@@ -672,8 +646,7 @@ append_message_data_free (AppendMessageData *data)
 static void
 copy_messages_data_free (CopyMessagesData *data)
 {
-       if (data->dest != NULL)
-               g_object_unref (data->dest);
+       g_clear_object (&data->destination);
 
        if (data->uids != NULL) {
                g_ptr_array_foreach (data->uids, (GFunc) g_free, NULL);
@@ -695,36 +668,12 @@ list_data_free (ListData *data)
 }
 
 static void
-manage_subscriptions_data_free (ManageSubscriptionsData *data)
-{
-       g_free (data->folder_name);
-
-       g_slice_free (ManageSubscriptionsData, data);
-}
-
-static void
-rename_folder_data_free (RenameFolderData *data)
-{
-       g_free (data->old_folder_name);
-       g_free (data->new_folder_name);
-
-       g_slice_free (RenameFolderData, data);
-}
-
-static void
-create_folder_data_free (CreateFolderData *data)
+mailbox_data_free (MailboxData *data)
 {
-       g_free (data->folder_name);
+       g_clear_object (&data->mailbox);
+       g_free (data->mailbox_name);
 
-       g_slice_free (CreateFolderData, data);
-}
-
-static void
-delete_folder_data_free (DeleteFolderData *data)
-{
-       g_free (data->folder_name);
-
-       g_slice_free (DeleteFolderData, data);
+       g_slice_free (MailboxData, data);
 }
 
 static void
@@ -738,14 +687,6 @@ search_data_free (SearchData *data)
        g_slice_free (SearchData, data);
 }
 
-static void
-quota_data_free (QuotaData *data)
-{
-       g_free (data->folder_name);
-
-       g_slice_free (QuotaData, data);
-}
-
 /*
   this creates a uid (or sequence number) set directly into a command,
   if total is set, then we break it up into total uids. (i.e. command time)
@@ -832,6 +773,47 @@ imapx_uidset_add (struct _uidset_state *ss,
        return 0;
 }
 
+static CamelFolder *
+imapx_server_ref_folder (CamelIMAPXServer *is,
+                         CamelIMAPXMailbox *mailbox)
+{
+       CamelFolder *folder;
+       CamelIMAPXStore *store;
+       const gchar *mailbox_name;
+       gchar *folder_path;
+       gchar separator;
+       GError *local_error = NULL;
+
+       mailbox_name = camel_imapx_mailbox_get_name (mailbox);
+       separator = camel_imapx_mailbox_get_separator (mailbox);
+
+       store = camel_imapx_server_ref_store (is);
+
+       folder_path = camel_imapx_mailbox_to_folder_path (
+               mailbox_name, separator);
+
+       folder = camel_store_get_folder_sync (
+               CAMEL_STORE (store), folder_path, 0, NULL, &local_error);
+
+       g_free (folder_path);
+
+       g_object_unref (store);
+
+       /* Sanity check. */
+       g_warn_if_fail (
+               ((folder != NULL) && (local_error == NULL)) ||
+               ((folder == NULL) && (local_error != NULL)));
+
+       if (local_error != NULL) {
+               g_warning (
+                       "%s: Failed to get folder for '%s': %s",
+                       G_STRFUNC, mailbox_name, local_error->message);
+               g_error_free (local_error);
+       }
+
+       return folder;
+}
+
 static void
 imapx_server_stash_command_arguments (CamelIMAPXServer *is)
 {
@@ -1202,7 +1184,7 @@ static void
 imapx_command_start_next (CamelIMAPXServer *is)
 {
        CamelIMAPXCommand *first_ic;
-       CamelFolder *folder;
+       CamelIMAPXMailbox *mailbox;
        gint min_pri = -128;
 
        c (is->tagprefix, "** Starting next command\n");
@@ -1214,20 +1196,21 @@ imapx_command_start_next (CamelIMAPXServer *is)
                return;
        }
 
-       folder = g_weak_ref_get (&is->priv->select_pending);
-       if (folder != NULL) {
+       mailbox = g_weak_ref_get (&is->priv->select_pending);
+       if (mailbox != NULL) {
                GQueue start = G_QUEUE_INIT;
                GList *head, *link;
 
                c (
                        is->tagprefix,
-                       "-- Checking job queue for non-folder jobs\n");
+                       "-- Checking job queue for non-mailbox jobs\n");
 
                head = camel_imapx_command_queue_peek_head_link (is->queue);
 
                /* Tag which commands in the queue to start. */
                for (link = head; link != NULL; link = g_list_next (link)) {
                        CamelIMAPXCommand *ic = link->data;
+                       CamelIMAPXMailbox *ic_mailbox;
 
                        if (ic->pri < min_pri)
                                break;
@@ -1236,7 +1219,10 @@ imapx_command_start_next (CamelIMAPXServer *is)
                                is->tagprefix,
                                "-- %3d '%s'?\n",
                                (gint) ic->pri, ic->name);
-                       if (!ic->select) {
+
+                       ic_mailbox = camel_imapx_command_ref_mailbox (ic);
+
+                       if (ic_mailbox == NULL) {
                                c (
                                        is->tagprefix,
                                        "--> starting '%s'\n",
@@ -1245,6 +1231,8 @@ imapx_command_start_next (CamelIMAPXServer *is)
                                g_queue_push_tail (&start, link);
                        }
 
+                       g_clear_object (&ic_mailbox);
+
                        if (g_queue_get_length (&start) == MAX_COMMANDS)
                                break;
                }
@@ -1253,7 +1241,7 @@ imapx_command_start_next (CamelIMAPXServer *is)
                        c (
                                is->tagprefix,
                                "* no, waiting for pending select '%s'\n",
-                               camel_folder_get_full_name (folder));
+                               camel_imapx_mailbox_get_name (mailbox));
 
                /* Start the tagged commands.
                 *
@@ -1273,7 +1261,7 @@ imapx_command_start_next (CamelIMAPXServer *is)
                                g_queue_clear (&start);
                }
 
-               g_clear_object (&folder);
+               g_clear_object (&mailbox);
 
                return;
        }
@@ -1334,8 +1322,8 @@ imapx_command_start_next (CamelIMAPXServer *is)
        }
 
        /* See if any queued jobs on this select first */
-       folder = g_weak_ref_get (&is->priv->select_folder);
-       if (folder != NULL) {
+       mailbox = g_weak_ref_get (&is->priv->select_mailbox);
+       if (mailbox != NULL) {
                GQueue start = G_QUEUE_INIT;
                GList *head, *link;
                gboolean commands_started = FALSE;
@@ -1343,7 +1331,7 @@ imapx_command_start_next (CamelIMAPXServer *is)
                c (
                        is->tagprefix,
                        "- we're selected on '%s', current jobs?\n",
-                       camel_folder_get_full_name (folder));
+                       camel_imapx_mailbox_get_name (mailbox));
 
                head = camel_imapx_command_queue_peek_head_link (is->active);
 
@@ -1363,7 +1351,7 @@ imapx_command_start_next (CamelIMAPXServer *is)
                                is->tagprefix,
                                "** too many jobs busy, "
                                "waiting for results for now\n");
-                       g_object_unref (folder);
+                       g_object_unref (mailbox);
                        return;
                }
 
@@ -1374,6 +1362,7 @@ imapx_command_start_next (CamelIMAPXServer *is)
                /* Tag which commands in the queue to start. */
                for (link = head; link != NULL; link = g_list_next (link)) {
                        CamelIMAPXCommand *ic = link->data;
+                       CamelIMAPXMailbox *ic_mailbox;
                        gboolean okay_to_start;
 
                        if (is->literal != NULL)
@@ -1387,9 +1376,11 @@ imapx_command_start_next (CamelIMAPXServer *is)
                                "-- %3d '%s'?\n",
                                (gint) ic->pri, ic->name);
 
+                       ic_mailbox = camel_imapx_command_ref_mailbox (ic);
+
                        okay_to_start =
-                               (ic->select == NULL) ||
-                               (ic->select == folder &&
+                               (ic_mailbox == NULL) ||
+                               (ic_mailbox == mailbox &&
                                !imapx_is_duplicate_fetch_or_refresh (is, ic));
 
                        if (okay_to_start) {
@@ -1400,18 +1391,20 @@ imapx_command_start_next (CamelIMAPXServer *is)
                                min_pri = ic->pri;
                                g_queue_push_tail (&start, link);
                        } else {
-                               /* This job isn't for the selected folder,
+                               /* This job isn't for the selected mailbox,
                                 * but we don't want to consider jobs with
                                 * lower priority than this, even if they
-                                * are for the selected folder. */
+                                * are for the selected mailbox. */
                                min_pri = ic->pri;
                        }
 
+                       g_clear_object (&ic_mailbox);
+
                        if (g_queue_get_length (&start) == MAX_COMMANDS)
                                break;
                }
 
-               g_clear_object (&folder);
+               g_clear_object (&mailbox);
 
                /* Start the tagged commands.
                 *
@@ -1441,22 +1434,25 @@ imapx_command_start_next (CamelIMAPXServer *is)
        /* This won't be NULL because we checked for an empty queue above. */
        first_ic = camel_imapx_command_queue_peek_head (is->queue);
 
-       /* If we need to select a folder for the first command, do
+       /* If we need to select a mailbox for the first command, do
         * so now.  It will re-call us if it completes successfully. */
-       if (first_ic->select) {
+       mailbox = camel_imapx_command_ref_mailbox (first_ic);
+       if (mailbox != NULL) {
                CamelIMAPXJob *job;
 
                c (
                        is->tagprefix,
-                       "Selecting folder '%s' for command '%s'(%p)\n",
-                       camel_folder_get_full_name (first_ic->select),
+                       "Selecting mailbox '%s' for command '%s'(%p)\n",
+                       camel_imapx_mailbox_get_name (mailbox),
                        first_ic->name, first_ic);
 
                /* Associate the SELECT command with the CamelIMAPXJob
                 * that triggered it.  Then if the SELECT command fails
                 * we have some destination to propagate the GError to. */
                job = camel_imapx_command_get_job (first_ic);
-               imapx_maybe_select (is, job, first_ic->select);
+               imapx_maybe_select (is, job, mailbox);
+
+               g_clear_object (&mailbox);
 
        } else {
                GQueue start = G_QUEUE_INIT;
@@ -1464,13 +1460,14 @@ imapx_command_start_next (CamelIMAPXServer *is)
 
                min_pri = first_ic->pri;
 
-               folder = g_weak_ref_get (&is->priv->select_folder);
+               mailbox = g_weak_ref_get (&is->priv->select_mailbox);
 
                head = camel_imapx_command_queue_peek_head_link (is->queue);
 
                /* Tag which commands in the queue to start. */
                for (link = head; link != NULL; link = g_list_next (link)) {
                        CamelIMAPXCommand *ic = link->data;
+                       CamelIMAPXMailbox *ic_mailbox;
                        gboolean okay_to_start;
 
                        if (is->literal != NULL)
@@ -1479,9 +1476,11 @@ imapx_command_start_next (CamelIMAPXServer *is)
                        if (ic->pri < min_pri)
                                break;
 
+                       ic_mailbox = camel_imapx_command_ref_mailbox (ic);
+
                        okay_to_start =
-                               (ic->select == NULL) ||
-                               (ic->select == folder &&
+                               (ic_mailbox == NULL) ||
+                               (ic_mailbox == mailbox &&
                                !imapx_is_duplicate_fetch_or_refresh (is, ic));
 
                        if (okay_to_start) {
@@ -1493,11 +1492,13 @@ imapx_command_start_next (CamelIMAPXServer *is)
                                g_queue_push_tail (&start, link);
                        }
 
+                       g_clear_object (&ic_mailbox);
+
                        if (g_queue_get_length (&start) == MAX_COMMANDS)
                                break;
                }
 
-               g_clear_object (&folder);
+               g_clear_object (&mailbox);
 
                /* Start the tagged commands.
                 *
@@ -1594,7 +1595,7 @@ imapx_match_active_job (CamelIMAPXServer *is,
 
        for (link = head; link != NULL; link = g_list_next (link)) {
                CamelIMAPXCommand *ic = link->data;
-               CamelFolder *folder;
+               CamelIMAPXMailbox *mailbox;
                CamelIMAPXJob *job;
                gboolean job_matches;
 
@@ -1606,9 +1607,9 @@ imapx_match_active_job (CamelIMAPXServer *is,
                if (!(job->type & type))
                        continue;
 
-               folder = g_weak_ref_get (&is->priv->select_folder);
-               job_matches = camel_imapx_job_matches (job, folder, uid);
-               g_clear_object (&folder);
+               mailbox = g_weak_ref_get (&is->priv->select_mailbox);
+               job_matches = camel_imapx_job_matches (job, mailbox, uid);
+               g_clear_object (&mailbox);
 
                if (job_matches) {
                        match = job;
@@ -1623,7 +1624,7 @@ imapx_match_active_job (CamelIMAPXServer *is,
 
 static CamelIMAPXJob *
 imapx_is_job_in_queue (CamelIMAPXServer *is,
-                       CamelFolder *folder,
+                       CamelIMAPXMailbox *mailbox,
                        guint32 type,
                        const gchar *uid)
 {
@@ -1641,7 +1642,7 @@ imapx_is_job_in_queue (CamelIMAPXServer *is,
                if (!job || !(job->type & type))
                        continue;
 
-               if (camel_imapx_job_matches (job, folder, uid)) {
+               if (camel_imapx_job_matches (job, mailbox, uid)) {
                        found = TRUE;
                        break;
                }
@@ -1658,16 +1659,20 @@ imapx_expunge_uid_from_summary (CamelIMAPXServer *is,
                                 gboolean unsolicited)
 {
        CamelFolder *folder;
-       CamelIMAPXFolder *ifolder;
+       CamelIMAPXMailbox *mailbox;
        CamelMessageInfo *mi;
+       guint32 messages;
+
+       mailbox = g_weak_ref_get (&is->priv->select_mailbox);
+       g_return_if_fail (mailbox != NULL);
 
-       folder = g_weak_ref_get (&is->priv->select_folder);
+       folder = imapx_server_ref_folder (is, mailbox);
        g_return_if_fail (folder != NULL);
 
-       ifolder = CAMEL_IMAPX_FOLDER (folder);
+       messages = camel_imapx_mailbox_get_messages (mailbox);
 
-       if (unsolicited && ifolder->exists_on_server)
-               ifolder->exists_on_server--;
+       if (unsolicited && messages > 0)
+               camel_imapx_mailbox_set_messages (mailbox, messages - 1);
 
        if (is->priv->changes == NULL)
                is->priv->changes = camel_folder_change_info_new ();
@@ -1691,6 +1696,7 @@ imapx_expunge_uid_from_summary (CamelIMAPXServer *is,
        }
 
        g_object_unref (folder);
+       g_object_unref (mailbox);
 }
 
 /* untagged response handler functions */
@@ -1723,7 +1729,7 @@ imapx_untagged_expunge (CamelIMAPXServer *is,
                         GCancellable *cancellable,
                         GError **error)
 {
-       CamelFolder *folder;
+       CamelIMAPXMailbox *mailbox;
        CamelIMAPXJob *job = NULL;
        guint32 expunge = 0;
 
@@ -1738,17 +1744,23 @@ imapx_untagged_expunge (CamelIMAPXServer *is,
 
        c (is->tagprefix, "expunged: %lu\n", is->priv->context->id);
 
-       folder = g_weak_ref_get (&is->priv->select_folder);
+       mailbox = g_weak_ref_get (&is->priv->select_mailbox);
 
-       if (folder != NULL) {
+       if (mailbox != NULL) {
+               CamelFolder *folder;
                gchar *uid;
 
-               uid = camel_imapx_dup_uid_from_summary_index (folder, expunge - 1);
+               folder = imapx_server_ref_folder (is, mailbox);
+               g_return_val_if_fail (folder != NULL, FALSE);
+
+               uid = camel_imapx_dup_uid_from_summary_index (
+                       folder, expunge - 1);
 
                if (uid != NULL)
                        imapx_expunge_uid_from_summary (is, uid, TRUE);
 
                g_object_unref (folder);
+               g_object_unref (mailbox);
        }
 
        return TRUE;
@@ -1761,6 +1773,7 @@ imapx_untagged_vanished (CamelIMAPXServer *is,
                          GError **error)
 {
        CamelFolder *folder;
+       CamelIMAPXMailbox *mailbox;
        GPtrArray *uids = NULL;
        GList *uid_list = NULL;
        gboolean unsolicited = TRUE;
@@ -1792,23 +1805,31 @@ imapx_untagged_vanished (CamelIMAPXServer *is,
        if (uids == NULL)
                return FALSE;
 
-       folder = g_weak_ref_get (&is->priv->select_folder);
+       mailbox = g_weak_ref_get (&is->priv->select_mailbox);
+       g_return_val_if_fail (mailbox != NULL, FALSE);
+
+       folder = imapx_server_ref_folder (is, mailbox);
        g_return_val_if_fail (folder != NULL, FALSE);
 
        if (unsolicited) {
-               CamelIMAPXFolder *ifolder = CAMEL_IMAPX_FOLDER (folder);
+               guint32 messages;
+
+               messages = camel_imapx_mailbox_get_messages (mailbox);
 
-               if (ifolder->exists_on_server < uids->len) {
+               if (messages < uids->len) {
                        c (
                                is->tagprefix,
-                               "Error: exists_on_folder %d is "
-                               "fewer than vanished %d\n",
-                               ifolder->exists_on_server,
-                               uids->len);
-                       ifolder->exists_on_server = 0;
-               } else
-                       ifolder->exists_on_server -= uids->len;
+                               "Error: mailbox messages (%u) is "
+                               "fewer than vanished %u\n",
+                               messages, uids->len);
+                       messages = 0;
+               } else {
+                       messages -= uids->len;
+               }
+
+               camel_imapx_mailbox_set_messages (mailbox, messages);
        }
+
        if (is->priv->changes == NULL)
                is->priv->changes = camel_folder_change_info_new ();
 
@@ -1841,6 +1862,7 @@ imapx_untagged_vanished (CamelIMAPXServer *is,
        g_ptr_array_free (uids, TRUE);
 
        g_object_unref (folder);
+       g_object_unref (mailbox);
 
        return TRUE;
 }
@@ -1961,35 +1983,42 @@ imapx_untagged_exists (CamelIMAPXServer *is,
                        GError **error)
 {
        CamelFolder *folder;
+       CamelIMAPXMailbox *mailbox;
+       guint32 exists;
        gboolean success = TRUE;
 
        g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), FALSE);
 
-       c (is->tagprefix, "exists: %lu\n", is->priv->context->id);
-       is->priv->exists = is->priv->context->id;
+       mailbox = camel_imapx_server_ref_selected (is);
 
-       folder = g_weak_ref_get (&is->priv->select_folder);
+       if (mailbox == NULL) {
+               g_warning ("%s: No mailbox available", G_STRFUNC);
+               return TRUE;
+       }
 
-       if (folder != NULL) {
-               CAMEL_IMAPX_FOLDER (folder)->exists_on_server =
-                       is->priv->context->id;
+       exists = (guint32) is->priv->context->id;
 
-               if (imapx_in_idle (is)) {
-                       guint count;
+       camel_imapx_mailbox_set_messages (mailbox, exists);
 
-                       count = camel_folder_summary_count (folder->summary);
-                       if (count < is->priv->context->id) {
-                               CamelIMAPXIdleStopResult stop_result;
+       folder = imapx_server_ref_folder (is, mailbox);
+       g_return_val_if_fail (folder != NULL, FALSE);
 
-                               stop_result =
-                                       imapx_stop_idle (is, stream, error);
-                               success = (stop_result != IMAPX_IDLE_STOP_ERROR);
-                       }
-               }
+       if (imapx_in_idle (is)) {
+               guint count;
 
-               g_object_unref (folder);
+               count = camel_folder_summary_count (folder->summary);
+               if (count < exists) {
+                       CamelIMAPXIdleStopResult stop_result;
+
+                       stop_result =
+                               imapx_stop_idle (is, stream, error);
+                       success = (stop_result != IMAPX_IDLE_STOP_ERROR);
+               }
        }
 
+       g_object_unref (folder);
+       g_object_unref (mailbox);
+
        return success;
 }
 
@@ -2064,8 +2093,8 @@ imapx_untagged_fetch (CamelIMAPXServer *is,
 
        if ((finfo->got & FETCH_FLAGS) && !(finfo->got & FETCH_HEADER)) {
                CamelIMAPXJob *job;
-               CamelFolder *select_folder;
-               CamelFolder *select_pending;
+               CamelIMAPXMailbox *select_mailbox;
+               CamelIMAPXMailbox *select_pending;
                RefreshInfoData *data = NULL;
 
                job = imapx_match_active_job (
@@ -2079,7 +2108,7 @@ imapx_untagged_fetch (CamelIMAPXServer *is,
                }
 
                g_mutex_lock (&is->priv->select_lock);
-               select_folder = g_weak_ref_get (&is->priv->select_folder);
+               select_mailbox = g_weak_ref_get (&is->priv->select_mailbox);
                select_pending = g_weak_ref_get (&is->priv->select_pending);
                g_mutex_unlock (&is->priv->select_lock);
 
@@ -2097,13 +2126,18 @@ imapx_untagged_fetch (CamelIMAPXServer *is,
                        r.exists = FALSE;
                        g_array_append_val (data->infos, r);
 
-               } else if (select_folder != NULL) {
+               } else if (select_mailbox != NULL) {
+                       CamelFolder *select_folder;
                        CamelMessageInfo *mi = NULL;
                        gboolean changed = FALSE;
                        gchar *uid = NULL;
 
                        c (is->tagprefix, "flag changed: %lu\n", is->priv->context->id);
 
+                       select_folder =
+                               imapx_server_ref_folder (is, select_mailbox);
+                       g_return_val_if_fail (select_folder != NULL, FALSE);
+
                        if (finfo->got & FETCH_UID) {
                                uid = finfo->uid;
                                finfo->uid = NULL;
@@ -2155,9 +2189,11 @@ imapx_untagged_fetch (CamelIMAPXServer *is,
 
                        if (mi)
                                camel_message_info_free (mi);
+
+                       g_object_unref (select_folder);
                }
 
-               g_clear_object (&select_folder);
+               g_clear_object (&select_mailbox);
                g_clear_object (&select_pending);
        }
 
@@ -2173,13 +2209,24 @@ imapx_untagged_fetch (CamelIMAPXServer *is,
                        IMAPX_JOB_FETCH_MESSAGES, NULL);
 
                if (job != NULL) {
+                       CamelIMAPXMailbox *mailbox;
                        CamelFolder *folder;
                        CamelMimeParser *mp;
                        CamelMessageInfo *mi;
+                       guint32 messages;
+                       guint32 unseen;
+                       guint32 uidnext;
+
+                       mailbox = camel_imapx_job_ref_mailbox (job);
+                       g_return_val_if_fail (mailbox != NULL, FALSE);
 
-                       folder = camel_imapx_job_ref_folder (job);
+                       folder = imapx_server_ref_folder (is, mailbox);
                        g_return_val_if_fail (folder != NULL, FALSE);
 
+                       messages = camel_imapx_mailbox_get_messages (mailbox);
+                       unseen = camel_imapx_mailbox_get_unseen (mailbox);
+                       uidnext = camel_imapx_mailbox_get_uidnext (mailbox);
+
                        /* Do we want to save these headers for later too?  Do we care? */
 
                        mp = camel_mime_parser_new ();
@@ -2245,14 +2292,15 @@ imapx_untagged_fetch (CamelIMAPXServer *is,
                                 * command completion, but update UNREAD count now according to the
                                 * message SEEN flag */
                                if (!(server_flags & CAMEL_MESSAGE_SEEN)) {
-                                       CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) folder;
-                                       guint64 uidl = strtoull (mi->uid, NULL, 10);
+                                       guint64 uidl;
+
+                                       uidl = strtoull (mi->uid, NULL, 10);
 
-                                       if (uidl >= ifolder->uidnext_on_server) {
-                                               c (is->tagprefix, "Updating unread count for new message 
%s\n", mi->uid);
-                                               ((CamelIMAPXFolder *) folder)->unread_on_server++;
+                                       if (uidl >= uidnext) {
+                                               c (is->tagprefix, "Updating unseen count for new message 
%s\n", mi->uid);
+                                               camel_imapx_mailbox_set_unseen (mailbox, unseen + 1);
                                        } else {
-                                               c (is->tagprefix, "Not updating unread count for new message 
%s\n", mi->uid);
+                                               c (is->tagprefix, "Not updating unseen count for new message 
%s\n", mi->uid);
                                        }
                                }
 
@@ -2261,7 +2309,6 @@ imapx_untagged_fetch (CamelIMAPXServer *is,
 
                                if (!camel_folder_summary_check_uid (folder->summary, mi->uid)) {
                                        RefreshInfoData *data;
-                                       CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) folder;
                                        gint cnt;
 
                                        data = camel_imapx_job_get_data (job);
@@ -2271,12 +2318,9 @@ imapx_untagged_fetch (CamelIMAPXServer *is,
                                        camel_folder_summary_add (folder->summary, mi);
                                        camel_folder_change_info_add_uid (data->changes, mi->uid);
 
-                                       if (!g_hash_table_lookup (ifolder->ignore_recent, mi->uid)) {
-                                               camel_folder_change_info_recent_uid (data->changes, mi->uid);
-                                               g_hash_table_remove (ifolder->ignore_recent, mi->uid);
-                                       }
+                                       camel_folder_change_info_recent_uid (data->changes, mi->uid);
 
-                                       cnt = (camel_folder_summary_count (folder->summary) * 100 ) / 
ifolder->exists_on_server;
+                                       cnt = (camel_folder_summary_count (folder->summary) * 100 ) / 
messages;
                                        camel_operation_progress (cancellable, cnt ? cnt : 1);
                                } else {
                                        camel_message_info_free (mi);
@@ -2288,6 +2332,7 @@ imapx_untagged_fetch (CamelIMAPXServer *is,
                        }
 
                        g_object_unref (folder);
+                       g_object_unref (mailbox);
                }
        }
 
@@ -2508,12 +2553,12 @@ imapx_untagged_quotaroot (CamelIMAPXServer *is,
        CamelIMAPXStoreNamespace *ns;
        CamelFolder *folder = NULL;
        gchar *mailbox_name = NULL;
-       gchar **quota_root_names = NULL;
+       gchar **quota_roots = NULL;
        gboolean success;
        GError *local_error = NULL;
 
        success = camel_imapx_parse_quotaroot (
-               stream, cancellable, &mailbox_name, &quota_root_names, error);
+               stream, cancellable, &mailbox_name, &quota_roots, error);
 
        /* Sanity check */
        g_return_val_if_fail (
@@ -2543,7 +2588,7 @@ imapx_untagged_quotaroot (CamelIMAPXServer *is,
        if (folder != NULL) {
                camel_imapx_folder_set_quota_root_names (
                        CAMEL_IMAPX_FOLDER (folder),
-                       (const gchar **) quota_root_names);
+                       (const gchar **) quota_roots);
                g_object_unref (folder);
        }
 
@@ -2555,7 +2600,7 @@ imapx_untagged_quotaroot (CamelIMAPXServer *is,
        }
 
        g_free (mailbox_name);
-       g_strfreev (quota_root_names);
+       g_strfreev (quota_roots);
 
        return TRUE;
 }
@@ -2566,10 +2611,23 @@ imapx_untagged_recent (CamelIMAPXServer *is,
                        GCancellable *cancellable,
                        GError **error)
 {
+       CamelIMAPXMailbox *mailbox;
+       guint32 recent;
+
        g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), FALSE);
 
-       c (is->tagprefix, "recent: %lu\n", is->priv->context->id);
-       is->priv->recent = is->priv->context->id;
+       mailbox = camel_imapx_server_ref_selected (is);
+
+       if (mailbox == NULL) {
+               g_warning ("%s: No mailbox available", G_STRFUNC);
+               return TRUE;
+       }
+
+       recent = (guint32) is->priv->context->id;
+
+       camel_imapx_mailbox_set_recent (mailbox, recent);
+
+       g_object_unref (mailbox);
 
        return TRUE;
 }
@@ -2717,6 +2775,8 @@ imapx_untagged_ok_no_bad (CamelIMAPXServer *is,
                           GCancellable *cancellable,
                           GError **error)
 {
+       CamelIMAPXMailbox *mailbox;
+
        g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), FALSE);
 
        /* TODO: validate which ones of these can happen as unsolicited responses */
@@ -2727,8 +2787,13 @@ imapx_untagged_ok_no_bad (CamelIMAPXServer *is,
                is->priv->context->token,
                is->priv->context->len);
 
+       mailbox = camel_imapx_server_ref_selected (is);
+
        is->priv->context->sinfo =
-               imapx_parse_status (stream, cancellable, error);
+               imapx_parse_status (stream, mailbox, cancellable, error);
+
+       g_clear_object (&mailbox);
+
        if (is->priv->context->sinfo == NULL)
                return FALSE;
 
@@ -2736,48 +2801,33 @@ imapx_untagged_ok_no_bad (CamelIMAPXServer *is,
        case IMAPX_CLOSED:
                c (
                        is->tagprefix,
-                       "previously selected folder is now closed\n");
+                       "previously selected mailbox is now closed\n");
                {
-                       CamelFolder *select_folder;
-                       CamelFolder *select_pending;
+                       CamelIMAPXMailbox *select_mailbox;
+                       CamelIMAPXMailbox *select_pending;
 
                        g_mutex_lock (&is->priv->select_lock);
 
-                       select_folder =
-                               g_weak_ref_get (&is->priv->select_folder);
+                       select_mailbox =
+                               g_weak_ref_get (&is->priv->select_mailbox);
                        select_pending =
                                g_weak_ref_get (&is->priv->select_pending);
 
-                       if (select_folder == NULL)
+                       if (select_mailbox == NULL)
                                g_weak_ref_set (
-                                       &is->priv->select_folder,
+                                       &is->priv->select_mailbox,
                                        select_pending);
 
-                       g_clear_object (&select_folder);
+                       g_clear_object (&select_mailbox);
                        g_clear_object (&select_pending);
 
                        g_mutex_unlock (&is->priv->select_lock);
                }
                break;
-       case IMAPX_UIDVALIDITY:
-               is->priv->uidvalidity =
-                       is->priv->context->sinfo->u.uidvalidity;
-               break;
-       case IMAPX_UNSEEN:
-               is->priv->unseen =
-                       is->priv->context->sinfo->u.unseen;
-               break;
-       case IMAPX_HIGHESTMODSEQ:
-               is->priv->highestmodseq =
-                       is->priv->context->sinfo->u.highestmodseq;
-               break;
        case IMAPX_PERMANENTFLAGS:
                is->priv->permanentflags =
                        is->priv->context->sinfo->u.permanentflags;
                break;
-       case IMAPX_UIDNEXT:
-               is->priv->uidnext = is->priv->context->sinfo->u.uidnext;
-               break;
        case IMAPX_ALERT:
                c (is->tagprefix, "ALERT!: %s\n", is->priv->context->sinfo->text);
                g_mutex_lock (&is->priv->known_alerts_lock);
@@ -3150,6 +3200,7 @@ imapx_completion (CamelIMAPXServer *is,
                   GError **error)
 {
        CamelIMAPXCommand *ic;
+       CamelIMAPXMailbox *mailbox;
        gboolean success = FALSE;
        guint tag;
 
@@ -3184,8 +3235,12 @@ imapx_completion (CamelIMAPXServer *is,
 
        if (camel_folder_change_info_changed (is->priv->changes)) {
                CamelFolder *folder;
+               CamelIMAPXMailbox *mailbox;
 
-               folder = g_weak_ref_get (&is->priv->select_folder);
+               mailbox = g_weak_ref_get (&is->priv->select_mailbox);
+               g_return_val_if_fail (mailbox != NULL, FALSE);
+
+               folder = imapx_server_ref_folder (is, mailbox);
                g_return_val_if_fail (folder != NULL, FALSE);
 
                camel_folder_summary_save_to_db (folder->summary, NULL);
@@ -3195,6 +3250,7 @@ imapx_completion (CamelIMAPXServer *is,
                camel_folder_change_info_clear (is->priv->changes);
 
                g_object_unref (folder);
+               g_object_unref (mailbox);
        }
 
        QUEUE_LOCK (is);
@@ -3220,7 +3276,11 @@ imapx_completion (CamelIMAPXServer *is,
 
        QUEUE_UNLOCK (is);
 
-       ic->status = imapx_parse_status (stream, cancellable, error);
+       mailbox = camel_imapx_server_ref_selected (is);
+
+       ic->status = imapx_parse_status (stream, mailbox, cancellable, error);
+
+       g_clear_object (&mailbox);
 
        if (ic->status == NULL)
                goto exit;
@@ -3490,16 +3550,16 @@ imapx_job_idle_start (CamelIMAPXJob *job,
                       GCancellable *cancellable,
                       GError **error)
 {
-       CamelFolder *folder;
        CamelIMAPXCommand *ic;
        CamelIMAPXCommandPart *cp;
+       CamelIMAPXMailbox *mailbox;
        gboolean success = TRUE;
 
-       folder = camel_imapx_job_ref_folder (job);
-       g_return_val_if_fail (folder != NULL, FALSE);
+       mailbox = camel_imapx_job_ref_mailbox (job);
+       g_return_val_if_fail (mailbox != NULL, FALSE);
 
        ic = camel_imapx_command_new (
-               is, "IDLE", folder, "IDLE");
+               is, "IDLE", mailbox, "IDLE");
        camel_imapx_command_set_job (ic, job);
        ic->pri = job->pri;
        ic->complete = imapx_command_idle_done;
@@ -3522,14 +3582,14 @@ imapx_job_idle_start (CamelIMAPXJob *job,
 
        camel_imapx_command_unref (ic);
 
-       g_object_unref (folder);
+       g_object_unref (mailbox);
 
        return success;
 }
 
 static gboolean
 camel_imapx_server_idle (CamelIMAPXServer *is,
-                         CamelFolder *folder,
+                         CamelIMAPXMailbox *mailbox,
                          GCancellable *cancellable,
                          GError **error)
 {
@@ -3540,7 +3600,7 @@ camel_imapx_server_idle (CamelIMAPXServer *is,
        job->type = IMAPX_JOB_IDLE;
        job->start = imapx_job_idle_start;
 
-       camel_imapx_job_set_folder (job, folder);
+       camel_imapx_job_set_mailbox (job, mailbox);
 
        success = imapx_submit_job (is, job, error);
 
@@ -3551,15 +3611,15 @@ camel_imapx_server_idle (CamelIMAPXServer *is,
 
 static gboolean
 imapx_job_fetch_new_messages_matches (CamelIMAPXJob *job,
-                                      CamelFolder *folder,
+                                      CamelIMAPXMailbox *mailbox,
                                       const gchar *uid)
 {
-       return camel_imapx_job_has_folder (job, folder);
+       return camel_imapx_job_has_mailbox (job, mailbox);
 }
 
 static gboolean
 imapx_server_fetch_new_messages (CamelIMAPXServer *is,
-                                 CamelFolder *folder,
+                                 CamelIMAPXMailbox *mailbox,
                                  gboolean async,
                                  gboolean update_unseen,
                                  GCancellable *cancellable,
@@ -3580,7 +3640,7 @@ imapx_server_fetch_new_messages (CamelIMAPXServer *is,
        job->matches = imapx_job_fetch_new_messages_matches;
        job->noreply = async;
 
-       camel_imapx_job_set_folder (job, folder);
+       camel_imapx_job_set_mailbox (job, mailbox);
 
        camel_imapx_job_set_data (
                job, data, (GDestroyNotify) refresh_info_data_free);
@@ -3610,6 +3670,7 @@ imapx_idle_thread (gpointer data)
 
                while (TRUE) {
                        CamelFolder *folder;
+                       CamelIMAPXMailbox *mailbox;
                        gboolean new_messages_on_server;
                        time_t dwelled;
 
@@ -3619,15 +3680,15 @@ imapx_idle_thread (gpointer data)
                        if (is->idle->idle_exit)
                                break;
 
-                       folder = g_weak_ref_get (&is->priv->select_folder);
-                       if (folder == NULL)
+                       mailbox = g_weak_ref_get (&is->priv->select_mailbox);
+                       if (mailbox == NULL)
                                break;
 
                        dwelled = time (NULL) - is->idle->started;
                        if (dwelled < IMAPX_IDLE_DWELL_TIME) {
                                gulong seconds;
 
-                               g_object_unref (folder);
+                               g_object_unref (mailbox);
 
                                IDLE_UNLOCK (is->idle);
                                seconds = IMAPX_IDLE_DWELL_TIME - dwelled;
@@ -3639,18 +3700,20 @@ imapx_idle_thread (gpointer data)
 
                        IDLE_UNLOCK (is->idle);
 
+                       folder = imapx_server_ref_folder (is, mailbox);
+
                        camel_imapx_server_idle (
-                               is, folder, cancellable, &local_error);
+                               is, mailbox, cancellable, &local_error);
 
                        new_messages_on_server =
-                               CAMEL_IMAPX_FOLDER (folder)->exists_on_server >
+                               camel_imapx_mailbox_get_messages (mailbox) >
                                camel_folder_summary_count (folder->summary);
 
                        if (local_error == NULL &&
                            new_messages_on_server &&
                            imapx_is_command_queue_empty (is)) {
                                imapx_server_fetch_new_messages (
-                                       is, folder, TRUE, TRUE,
+                                       is, mailbox, TRUE, TRUE,
                                        cancellable, &local_error);
                        }
 
@@ -3660,7 +3723,8 @@ imapx_idle_thread (gpointer data)
                                g_clear_error (&local_error);
                        }
 
-                       g_object_unref (folder);
+                       g_clear_object (&folder);
+                       g_clear_object (&mailbox);
 
                        IDLE_LOCK (is->idle);
                }
@@ -3859,38 +3923,43 @@ imapx_command_select_done (CamelIMAPXServer *is,
        if (camel_imapx_command_set_error_if_failed (ic, &local_error)) {
                GQueue failed = G_QUEUE_INIT;
                GQueue trash = G_QUEUE_INIT;
-               CamelFolder *folder;
+               CamelIMAPXMailbox *mailbox;
                GList *link;
 
                c (is->tagprefix, "Select failed\n");
 
                g_mutex_lock (&is->priv->select_lock);
-               folder = g_weak_ref_get (&is->priv->select_pending);
-               g_weak_ref_set (&is->priv->select_folder, NULL);
+               mailbox = g_weak_ref_get (&is->priv->select_pending);
+               g_weak_ref_set (&is->priv->select_mailbox, NULL);
                g_weak_ref_set (&is->priv->select_pending, NULL);
                is->state = IMAPX_INITIALISED;
                g_mutex_unlock (&is->priv->select_lock);
 
                QUEUE_LOCK (is);
 
-               if (folder != NULL) {
+               if (mailbox != NULL) {
                        GList *head = camel_imapx_command_queue_peek_head_link (is->queue);
 
                        for (link = head; link != NULL; link = g_list_next (link)) {
                                CamelIMAPXCommand *cw = link->data;
+                               CamelIMAPXMailbox *cw_mailbox;
+
+                               cw_mailbox = camel_imapx_command_ref_mailbox (cw);
 
-                               if (cw->select && cw->select == folder) {
+                               if (cw_mailbox == mailbox) {
                                        c (
                                                is->tagprefix,
                                                "Cancelling command '%s'(%p) "
-                                               "for folder '%s'\n",
+                                               "for mailbox '%s'\n",
                                                cw->name, cw,
-                                               camel_folder_get_full_name (cw->select));
+                                               camel_imapx_mailbox_get_name (cw_mailbox));
                                        g_queue_push_tail (&trash, link);
                                }
+
+                               g_clear_object (&cw_mailbox);
                        }
 
-                       g_object_unref (folder);
+                       g_object_unref (mailbox);
                }
 
                while ((link = g_queue_pop_head (&trash)) != NULL) {
@@ -3926,30 +3995,33 @@ imapx_command_select_done (CamelIMAPXServer *is,
 
        } else {
                CamelFolder *folder;
-               CamelIMAPXFolder *ifolder;
+               CamelIMAPXMailbox *mailbox;
+               CamelIMAPXSummary *imapx_summary;
+               guint32 uidnext;
 
                c (is->tagprefix, "Select ok!\n");
 
                g_mutex_lock (&is->priv->select_lock);
-               folder = g_weak_ref_get (&is->priv->select_pending);
-               g_weak_ref_set (&is->priv->select_folder, folder);
+               mailbox = g_weak_ref_get (&is->priv->select_pending);
+               g_weak_ref_set (&is->priv->select_mailbox, mailbox);
                g_weak_ref_set (&is->priv->select_pending, NULL);
                is->state = IMAPX_SELECTED;
                g_mutex_unlock (&is->priv->select_lock);
 
                /* We should have a strong reference
                 * on the newly-selected CamelFolder. */
+               folder = imapx_server_ref_folder (is, mailbox);
                g_return_if_fail (folder != NULL);
-               ifolder = CAMEL_IMAPX_FOLDER (folder);
 
-               ifolder->exists_on_server = is->priv->exists;
-               ifolder->modseq_on_server = is->priv->highestmodseq;
-               if (ifolder->uidnext_on_server < is->priv->uidnext) {
+               uidnext = camel_imapx_mailbox_get_uidnext (mailbox);
+               imapx_summary = CAMEL_IMAPX_SUMMARY (folder->summary);
+
+               if (imapx_summary->uidnext < uidnext) {
                        /* We don't want to fetch new messages if the command we selected this
                         * folder for is *already* fetching all messages (i.e. scan_changes).
                         * Bug #667725. */
                        CamelIMAPXJob *job = imapx_is_job_in_queue (
-                               is, folder, IMAPX_JOB_REFRESH_INFO, NULL);
+                               is, mailbox, IMAPX_JOB_REFRESH_INFO, NULL);
                        if (job) {
                                RefreshInfoData *data = camel_imapx_job_get_data (job);
 
@@ -3961,16 +4033,11 @@ imapx_command_select_done (CamelIMAPXServer *is,
                                        goto no_fetch_new;
                                }
                        }
-                       imapx_server_fetch_new_messages (is, folder, TRUE, TRUE, NULL, NULL);
+                       imapx_server_fetch_new_messages (
+                               is, mailbox, TRUE, TRUE, NULL, NULL);
                no_fetch_new:
                        ;
                }
-               ifolder->uidvalidity_on_server = is->priv->uidvalidity;
-
-               if (is->priv->uidvalidity > 0 &&
-                   is->priv->uidvalidity != ((CamelIMAPXSummary *) folder->summary)->validity)
-                       camel_imapx_folder_invalidate_local_cache (
-                               ifolder, is->priv->uidvalidity);
 
 #if 0  /* see comment for disabled bits in imapx_job_refresh_info_start() */
                /* This should trigger a new messages scan */
@@ -3981,7 +4048,8 @@ imapx_command_select_done (CamelIMAPXServer *is,
                                ((CamelIMAPXSummary *) folder->summary)->exists);
 #endif
 
-               g_object_unref (folder);
+               g_clear_object (&mailbox);
+               g_clear_object (&folder);
        }
 }
 
@@ -3989,58 +4057,51 @@ imapx_command_select_done (CamelIMAPXServer *is,
 static void
 imapx_maybe_select (CamelIMAPXServer *is,
                     CamelIMAPXJob *job,
-                    CamelFolder *folder)
+                    CamelIMAPXMailbox *mailbox)
 {
        CamelIMAPXCommand *ic;
-       CamelIMAPXMailbox *mailbox;
-       CamelFolder *select_folder;
-       CamelFolder *select_pending;
+       CamelIMAPXMailbox *select_mailbox;
+       CamelIMAPXMailbox *select_pending;
        gboolean nothing_to_do = FALSE;
 
        /* Select is complicated by the fact we may have commands
         * active on the server for a different selection.
         *
         * So this waits for any commands to complete, selects the
-        * new folder, and halts the queuing of any new commands.
-        * It is assumed whomever called is us about to issue a
-        * high-priority command anyway */
+        * new mailbox, and halts the queuing of any new commands.
+        * It is assumed whomever called us is about to issue a
+        * high-priority command anyway. */
 
        g_mutex_lock (&is->priv->select_lock);
 
-       select_folder = g_weak_ref_get (&is->priv->select_folder);
+       select_mailbox = g_weak_ref_get (&is->priv->select_mailbox);
        select_pending = g_weak_ref_get (&is->priv->select_pending);
 
        if (select_pending != NULL) {
                nothing_to_do = TRUE;
-       } else if (select_folder == folder) {
+       } else if (select_mailbox == mailbox) {
                nothing_to_do = TRUE;
        } else if (!camel_imapx_command_queue_is_empty (is->active)) {
                nothing_to_do = TRUE;
        } else {
-               g_weak_ref_set (&is->priv->select_pending, folder);
+               g_weak_ref_set (&is->priv->select_pending, mailbox);
 
-               if (select_folder != NULL) {
-                       g_weak_ref_set (&is->priv->select_folder, NULL);
+               if (select_mailbox != NULL) {
+                       g_weak_ref_set (&is->priv->select_mailbox, NULL);
                } else {
-                       /* If no folder was selected, we won't get a
-                        * [CLOSED] status so just point select_folder
-                        * at the newly-selected folder immediately. */
-                       g_weak_ref_set (&is->priv->select_folder, folder);
+                       /* If no mailbox was selected, we won't get a
+                        * [CLOSED] status so just point select_mailbox
+                        * at the newly-selected mailbox immediately. */
+                       g_weak_ref_set (&is->priv->select_mailbox, mailbox);
                }
 
-               is->priv->uidvalidity = 0;
-               is->priv->unseen = 0;
-               is->priv->highestmodseq = 0;
                is->priv->permanentflags = 0;
-               is->priv->exists = 0;
-               is->priv->recent = 0;
-               is->priv->uidnext = 0;
 
                /* Hrm, what about reconnecting? */
                is->state = IMAPX_INITIALISED;
        }
 
-       g_clear_object (&select_folder);
+       g_clear_object (&select_mailbox);
        g_clear_object (&select_pending);
 
        g_mutex_unlock (&is->priv->select_lock);
@@ -4048,16 +4109,16 @@ imapx_maybe_select (CamelIMAPXServer *is,
        if (nothing_to_do)
                return;
 
-       mailbox = camel_imapx_folder_ref_mailbox (CAMEL_IMAPX_FOLDER (folder));
-       g_warn_if_fail (mailbox != NULL);
-
        ic = camel_imapx_command_new (
                is, "SELECT", NULL, "SELECT %M", mailbox);
 
-       g_object_unref (mailbox);
+       if (is->use_qresync) {
+               CamelFolder *folder;
 
-       if (is->use_qresync)
+               folder = imapx_server_ref_folder (is, mailbox);
                camel_imapx_command_add_qresync_parameter (ic, folder);
+               g_clear_object (&folder);
+       }
 
        ic->complete = imapx_command_select_done;
        camel_imapx_command_set_job (ic, job);
@@ -4716,9 +4777,8 @@ imapx_command_fetch_message_done (CamelIMAPXServer *is,
                                   CamelIMAPXCommand *ic)
 {
        CamelIMAPXJob *job;
-       CamelFolder *folder;
        GetMessageData *data;
-       CamelIMAPXFolder *ifolder;
+       CamelIMAPXMailbox *mailbox;
        GCancellable *cancellable;
        GError *local_error = NULL;
 
@@ -4731,8 +4791,8 @@ imapx_command_fetch_message_done (CamelIMAPXServer *is,
        data = camel_imapx_job_get_data (job);
        g_return_if_fail (data != NULL);
 
-       folder = camel_imapx_job_ref_folder (job);
-       g_return_if_fail (folder != NULL);
+       mailbox = camel_imapx_job_ref_mailbox (job);
+       g_return_if_fail (mailbox != NULL);
 
        /* We either have more to fetch (partial mode?), we are complete,
         * or we failed.  Failure is handled in the fetch code, so
@@ -4762,7 +4822,7 @@ imapx_command_fetch_message_done (CamelIMAPXServer *is,
                                (data->fetch_offset *100) / data->size);
 
                        new_ic = camel_imapx_command_new (
-                               is, "FETCH", folder,
+                               is, "FETCH", mailbox,
                                "UID FETCH %t (BODY.PEEK[]",
                                data->uid);
                        camel_imapx_command_add (new_ic, "<%u.%u>", data->fetch_offset, MULTI_SIZE);
@@ -4787,8 +4847,6 @@ imapx_command_fetch_message_done (CamelIMAPXServer *is,
 
        /* No more messages to fetch, let's wrap things up. */
 
-       ifolder = CAMEL_IMAPX_FOLDER (folder);
-
        if (local_error == NULL) {
                camel_stream_flush (data->stream, cancellable, &local_error);
                g_prefix_error (
@@ -4809,10 +4867,10 @@ imapx_command_fetch_message_done (CamelIMAPXServer *is,
                gchar *dirname;
 
                cur_filename = camel_data_cache_get_filename (
-                       ifolder->cache, "cur", data->uid);
+                       data->message_cache, "cur", data->uid);
 
                tmp_filename = camel_data_cache_get_filename (
-                       ifolder->cache, "tmp", data->uid);
+                       data->message_cache, "tmp", data->uid);
 
                dirname = g_path_get_dirname (cur_filename);
                g_mkdir_with_parents (dirname, 0700);
@@ -4822,7 +4880,7 @@ imapx_command_fetch_message_done (CamelIMAPXServer *is,
                        /* Exchange the "tmp" stream for the "cur" stream. */
                        g_clear_object (&data->stream);
                        data->stream = camel_data_cache_get (
-                               ifolder->cache, "cur",
+                               data->message_cache, "cur",
                                data->uid, &local_error);
                } else {
                        g_set_error (
@@ -4840,11 +4898,11 @@ imapx_command_fetch_message_done (CamelIMAPXServer *is,
        if (local_error != NULL)
                camel_imapx_job_take_error (job, local_error);
 
-       camel_data_cache_remove (ifolder->cache, "tmp", data->uid, NULL);
+       camel_data_cache_remove (data->message_cache, "tmp", data->uid, NULL);
        imapx_unregister_job (is, job);
 
 exit:
-       g_object_unref (folder);
+       g_object_unref (mailbox);
 }
 
 static gboolean
@@ -4853,8 +4911,8 @@ imapx_job_get_message_start (CamelIMAPXJob *job,
                              GCancellable *cancellable,
                              GError **error)
 {
-       CamelFolder *folder;
        CamelIMAPXCommand *ic;
+       CamelIMAPXMailbox *mailbox;
        GetMessageData *data;
        gint i;
        gboolean success = TRUE;
@@ -4862,13 +4920,13 @@ imapx_job_get_message_start (CamelIMAPXJob *job,
        data = camel_imapx_job_get_data (job);
        g_return_val_if_fail (data != NULL, FALSE);
 
-       folder = camel_imapx_job_ref_folder (job);
-       g_return_val_if_fail (folder != NULL, FALSE);
+       mailbox = camel_imapx_job_ref_mailbox (job);
+       g_return_val_if_fail (mailbox != NULL, FALSE);
 
        if (data->use_multi_fetch) {
                for (i = 0; i < 3 && data->fetch_offset < data->size; i++) {
                        ic = camel_imapx_command_new (
-                               is, "FETCH", folder,
+                               is, "FETCH", mailbox,
                                "UID FETCH %t (BODY.PEEK[]",
                                data->uid);
                        camel_imapx_command_add (ic, "<%u.%u>", data->fetch_offset, MULTI_SIZE);
@@ -4888,7 +4946,7 @@ imapx_job_get_message_start (CamelIMAPXJob *job,
                }
        } else {
                ic = camel_imapx_command_new (
-                       is, "FETCH", folder,
+                       is, "FETCH", mailbox,
                        "UID FETCH %t (BODY.PEEK[])",
                        data->uid);
                ic->complete = imapx_command_fetch_message_done;
@@ -4901,14 +4959,14 @@ imapx_job_get_message_start (CamelIMAPXJob *job,
                camel_imapx_command_unref (ic);
        }
 
-       g_object_unref (folder);
+       g_object_unref (mailbox);
 
        return success;
 }
 
 static gboolean
 imapx_job_get_message_matches (CamelIMAPXJob *job,
-                               CamelFolder *folder,
+                               CamelIMAPXMailbox *mailbox,
                                const gchar *uid)
 {
        GetMessageData *data;
@@ -4916,7 +4974,7 @@ imapx_job_get_message_matches (CamelIMAPXJob *job,
        data = camel_imapx_job_get_data (job);
        g_return_val_if_fail (data != NULL, FALSE);
 
-       if (!camel_imapx_job_has_folder (job, folder))
+       if (!camel_imapx_job_has_mailbox (job, mailbox))
                return FALSE;
 
        if (g_strcmp0 (uid, data->uid) != 0)
@@ -4933,6 +4991,7 @@ imapx_command_copy_messages_step_done (CamelIMAPXServer *is,
 {
        CamelIMAPXJob *job;
        CamelFolder *folder;
+       CamelIMAPXMailbox *mailbox;
        CopyMessagesData *data;
        GPtrArray *uids;
        gint i;
@@ -4944,7 +5003,10 @@ imapx_command_copy_messages_step_done (CamelIMAPXServer *is,
        data = camel_imapx_job_get_data (job);
        g_return_if_fail (data != NULL);
 
-       folder = camel_imapx_job_ref_folder (job);
+       mailbox = camel_imapx_job_ref_mailbox (job);
+       g_return_if_fail (mailbox != NULL);
+
+       folder = imapx_server_ref_folder (is, mailbox);
        g_return_if_fail (folder != NULL);
 
        uids = data->uids;
@@ -4970,22 +5032,6 @@ imapx_command_copy_messages_step_done (CamelIMAPXServer *is,
                        camel_folder_delete_message (folder, uids->pdata[j]);
        }
 
-       /* TODO Copy the summary and cached messages to the new folder.
-        *      We might need a sorted insert to avoid refreshing the dest
-        *      folder. */
-       if (ic->status && ic->status->condition == IMAPX_COPYUID) {
-               gint i;
-
-               for (i = 0; i < ic->status->u.copyuid.copied_uids->len; i++) {
-                       guint32 uid = GPOINTER_TO_UINT (g_ptr_array_index (ic->status->u.copyuid.copied_uids, 
i));
-                       gchar *str = g_strdup_printf ("%d",uid);
-                       CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) data->dest;
-
-                       g_hash_table_insert (ifolder->ignore_recent, str, GINT_TO_POINTER (1));
-               }
-
-       }
-
        if (i < uids->len) {
                imapx_command_copy_messages_step_start (
                        is, job, i, &local_error);
@@ -4996,6 +5042,7 @@ imapx_command_copy_messages_step_done (CamelIMAPXServer *is,
 
 exit:
        g_object_unref (folder);
+       g_object_unref (mailbox);
 
        imapx_unregister_job (is, job);
 }
@@ -5006,8 +5053,7 @@ imapx_command_copy_messages_step_start (CamelIMAPXServer *is,
                                         gint index,
                                         GError **error)
 {
-       CamelFolder *folder;
-       CamelIMAPXMailbox *dest_mailbox;
+       CamelIMAPXMailbox *mailbox;
        CamelIMAPXCommand *ic;
        CopyMessagesData *data;
        GPtrArray *uids;
@@ -5017,24 +5063,21 @@ imapx_command_copy_messages_step_start (CamelIMAPXServer *is,
        data = camel_imapx_job_get_data (job);
        g_return_val_if_fail (data != NULL, FALSE);
 
-       folder = camel_imapx_job_ref_folder (job);
-       g_return_val_if_fail (folder != NULL, FALSE);
+       mailbox = camel_imapx_job_ref_mailbox (job);
+       g_return_val_if_fail (mailbox != NULL, FALSE);
 
        uids = data->uids;
 
        if (data->use_move_command)
-               ic = camel_imapx_command_new (is, "MOVE", folder, "UID MOVE ");
+               ic = camel_imapx_command_new (is, "MOVE", mailbox, "UID MOVE ");
        else
-               ic = camel_imapx_command_new (is, "COPY", folder, "UID COPY ");
+               ic = camel_imapx_command_new (is, "COPY", mailbox, "UID COPY ");
        ic->complete = imapx_command_copy_messages_step_done;
        camel_imapx_command_set_job (ic, job);
        ic->pri = job->pri;
        data->last_index = i;
 
-       g_object_unref (folder);
-
-       dest_mailbox = camel_imapx_folder_ref_mailbox (
-               CAMEL_IMAPX_FOLDER (data->dest));
+       g_object_unref (mailbox);
 
        for (; i < uids->len; i++) {
                gint res;
@@ -5042,7 +5085,7 @@ imapx_command_copy_messages_step_start (CamelIMAPXServer *is,
 
                res = imapx_uidset_add (&data->uidset, ic, uid);
                if (res == 1) {
-                       camel_imapx_command_add (ic, " %M", dest_mailbox);
+                       camel_imapx_command_add (ic, " %M", data->destination);
                        data->index = i + 1;
                        imapx_command_queue (is, ic);
                        goto exit;
@@ -5051,14 +5094,12 @@ imapx_command_copy_messages_step_start (CamelIMAPXServer *is,
 
        data->index = i;
        if (imapx_uidset_done (&data->uidset, ic)) {
-               camel_imapx_command_add (ic, " %M", dest_mailbox);
+               camel_imapx_command_add (ic, " %M", data->destination);
                imapx_command_queue (is, ic);
                goto exit;
        }
 
 exit:
-       g_object_unref (dest_mailbox);
-
        camel_imapx_command_unref (ic);
 
        return success;
@@ -5070,18 +5111,18 @@ imapx_job_copy_messages_start (CamelIMAPXJob *job,
                                GCancellable *cancellable,
                                GError **error)
 {
-       CamelFolder *folder;
+       CamelIMAPXMailbox *mailbox;
        CopyMessagesData *data;
        gboolean success;
 
        data = camel_imapx_job_get_data (job);
        g_return_val_if_fail (data != NULL, FALSE);
 
-       folder = camel_imapx_job_ref_folder (job);
-       g_return_val_if_fail (folder != NULL, FALSE);
+       mailbox = camel_imapx_job_ref_mailbox (job);
+       g_return_val_if_fail (mailbox != NULL, FALSE);
 
        success = imapx_server_sync_changes (
-               is, folder, job->type, job->pri, cancellable, error);
+               is, mailbox, job->type, job->pri, cancellable, error);
        if (!success)
                imapx_unregister_job (is, job);
 
@@ -5089,7 +5130,7 @@ imapx_job_copy_messages_start (CamelIMAPXJob *job,
        g_ptr_array_sort (data->uids, (GCompareFunc) imapx_uids_array_cmp);
        imapx_uidset_init (&data->uidset, 0, MAX_COMMAND_LEN);
 
-       g_object_unref (folder);
+       g_object_unref (mailbox);
 
        return imapx_command_copy_messages_step_start (is, job, 0, error);
 }
@@ -5102,10 +5143,12 @@ imapx_command_append_message_done (CamelIMAPXServer *is,
 {
        CamelIMAPXJob *job;
        CamelIMAPXFolder *ifolder;
+       CamelIMAPXMailbox *mailbox;
        CamelFolder *folder;
        CamelMessageInfo *mi;
        AppendMessageData *data;
        gchar *cur, *old_uid;
+       guint32 uidvalidity;
        GError *local_error = NULL;
 
        job = camel_imapx_command_get_job (ic);
@@ -5114,9 +5157,14 @@ imapx_command_append_message_done (CamelIMAPXServer *is,
        data = camel_imapx_job_get_data (job);
        g_return_if_fail (data != NULL);
 
-       folder = camel_imapx_job_ref_folder (job);
+       mailbox = camel_imapx_job_ref_mailbox (job);
+       g_return_if_fail (mailbox != NULL);
+
+       folder = imapx_server_ref_folder (is, mailbox);
        g_return_if_fail (folder != NULL);
 
+       uidvalidity = camel_imapx_mailbox_get_uidvalidity (mailbox);
+
        ifolder = CAMEL_IMAPX_FOLDER (folder);
 
        /* Append done.  If we the server supports UIDPLUS we will get
@@ -5136,7 +5184,7 @@ imapx_command_append_message_done (CamelIMAPXServer *is,
 
        } else if (ic->status && ic->status->condition == IMAPX_APPENDUID) {
                c (is->tagprefix, "Got appenduid %d %d\n", (gint) ic->status->u.appenduid.uidvalidity, (gint) 
ic->status->u.appenduid.uid);
-               if (ic->status->u.appenduid.uidvalidity == ifolder->uidvalidity_on_server) {
+               if (ic->status->u.appenduid.uidvalidity == uidvalidity) {
                        CamelFolderChangeInfo *changes;
 
                        data->appended_uid = g_strdup_printf ("%u", (guint) ic->status->u.appenduid.uid);
@@ -5167,6 +5215,7 @@ imapx_command_append_message_done (CamelIMAPXServer *is,
        g_free (old_uid);
 
        g_object_unref (folder);
+       g_object_unref (mailbox);
 
        imapx_unregister_job (is, job);
 }
@@ -5177,7 +5226,6 @@ imapx_job_append_message_start (CamelIMAPXJob *job,
                                 GCancellable *cancellable,
                                 GError **error)
 {
-       CamelFolder *folder;
        CamelIMAPXMailbox *mailbox;
        CamelIMAPXCommand *ic;
        AppendMessageData *data;
@@ -5185,11 +5233,8 @@ imapx_job_append_message_start (CamelIMAPXJob *job,
        data = camel_imapx_job_get_data (job);
        g_return_val_if_fail (data != NULL, FALSE);
 
-       folder = camel_imapx_job_ref_folder (job);
-       g_return_val_if_fail (folder != NULL, FALSE);
-
-       mailbox = camel_imapx_folder_ref_mailbox (CAMEL_IMAPX_FOLDER (folder));
-       g_warn_if_fail (mailbox != NULL);
+       mailbox = camel_imapx_job_ref_mailbox (job);
+       g_return_val_if_fail (mailbox != NULL, FALSE);
 
        /* TODO: we could supply the original append date from the file timestamp */
        ic = camel_imapx_command_new (
@@ -5208,7 +5253,6 @@ imapx_job_append_message_start (CamelIMAPXJob *job,
        camel_imapx_command_unref (ic);
 
        g_object_unref (mailbox);
-       g_object_unref (folder);
 
        return TRUE;
 }
@@ -5298,7 +5342,7 @@ static void
 imapx_command_step_fetch_done (CamelIMAPXServer *is,
                                CamelIMAPXCommand *ic)
 {
-       CamelIMAPXFolder *ifolder;
+       CamelIMAPXMailbox *mailbox;
        CamelIMAPXSummary *isum;
        CamelIMAPXJob *job;
        CamelFolder *folder;
@@ -5315,12 +5359,14 @@ imapx_command_step_fetch_done (CamelIMAPXServer *is,
        data = camel_imapx_job_get_data (job);
        g_return_if_fail (data != NULL);
 
-       folder = camel_imapx_job_ref_folder (job);
+       mailbox = camel_imapx_job_ref_mailbox (job);
+       g_return_if_fail (mailbox != NULL);
+
+       folder = imapx_server_ref_folder (is, mailbox);
        g_return_if_fail (folder != NULL);
 
        data->scan_changes = FALSE;
 
-       ifolder = CAMEL_IMAPX_FOLDER (folder);
        isum = CAMEL_IMAPX_SUMMARY (folder->summary);
 
        settings = camel_imapx_server_ref_settings (is);
@@ -5351,18 +5397,16 @@ imapx_command_step_fetch_done (CamelIMAPXServer *is,
                gint fetch_limit = data->fetch_msg_limit;
 
                ic = camel_imapx_command_new (
-                       is, "FETCH", folder, "UID FETCH ");
+                       is, "FETCH", mailbox, "UID FETCH ");
                ic->complete = imapx_command_step_fetch_done;
                camel_imapx_command_set_job (ic, job);
                ic->pri = job->pri - 1;
 
-               //printf ("Total: %d: %d, %d, %d\n", total, fetch_limit, i, data->last_index);
                data->last_index = i;
 
                /* If its mobile client and when total=0 (new account setup)
                 * fetch only one batch of mails, on futher attempts download
                 * all new mails as per the limit. */
-               //printf ("Total: %d: %d\n", total, fetch_limit);
                for (; i < data->infos->len &&
                        (!mobile_mode || (total && i == 0) ||
                        ((fetch_limit != -1 && i < fetch_limit) ||
@@ -5382,13 +5426,13 @@ imapx_command_step_fetch_done (CamelIMAPXServer *is,
                                        camel_imapx_command_unref (ic);
 
                                        g_object_unref (folder);
+                                       g_object_unref (mailbox);
 
                                        return;
                                }
                        }
                }
 
-               //printf ("Existing : %d Gonna fetch in %s for %d/%d\n", total, camel_folder_get_full_name 
(folder), i, data->infos->len);
                data->index = data->infos->len;
                if (imapx_uidset_done (&data->uidset, ic)) {
                        camel_imapx_command_add (ic, " (RFC822.SIZE RFC822.HEADER)");
@@ -5398,6 +5442,7 @@ imapx_command_step_fetch_done (CamelIMAPXServer *is,
                        camel_imapx_command_unref (ic);
 
                        g_object_unref (folder);
+                       g_object_unref (mailbox);
 
                        return;
                }
@@ -5411,27 +5456,37 @@ imapx_command_step_fetch_done (CamelIMAPXServer *is,
        }
 
        if (camel_folder_summary_count (folder->summary)) {
-               gchar *uid = camel_imapx_dup_uid_from_summary_index (
+               gchar *uid;
+               guint32 uidl;
+               guint32 uidnext;
+
+               uid = camel_imapx_dup_uid_from_summary_index (
                        folder,
                        camel_folder_summary_count (folder->summary) - 1);
-               guint64 uidl = strtoull (uid, NULL, 10);
+               uidl = (guint32) strtoull (uid, NULL, 10);
                g_free (uid);
 
                uidl++;
 
-               if (uidl > ifolder->uidnext_on_server) {
+               uidnext = camel_imapx_mailbox_get_uidnext (mailbox);
+
+               if (uidl > uidnext) {
                        c (
-                               is->tagprefix, "Updating uidnext_on_server for '%s' to %" G_GUINT64_FORMAT 
"\n",
-                               camel_folder_get_full_name (folder), uidl);
-                       ifolder->uidnext_on_server = uidl;
+                               is->tagprefix,
+                               "Updating uidnext for '%s' to %ul\n",
+                               camel_imapx_mailbox_get_name (mailbox),
+                               uidl);
+                       camel_imapx_mailbox_set_uidnext (mailbox, uidl);
                }
        }
-       isum->uidnext = ifolder->uidnext_on_server;
+
+       isum->uidnext = camel_imapx_mailbox_get_uidnext (mailbox);
 
 exit:
        refresh_info_data_infos_free (data);
 
        g_object_unref (folder);
+       g_object_unref (mailbox);
 
        imapx_unregister_job (is, job);
 }
@@ -5466,6 +5521,7 @@ imapx_job_scan_changes_done (CamelIMAPXServer *is,
                              CamelIMAPXCommand *ic)
 {
        CamelIMAPXJob *job;
+       CamelIMAPXMailbox *mailbox;
        CamelIMAPXSettings *settings;
        CamelFolder *folder;
        RefreshInfoData *data;
@@ -5483,7 +5539,10 @@ imapx_job_scan_changes_done (CamelIMAPXServer *is,
        data = camel_imapx_job_get_data (job);
        g_return_if_fail (data != NULL);
 
-       folder = camel_imapx_job_ref_folder (job);
+       mailbox = camel_imapx_job_ref_mailbox (job);
+       g_return_if_fail (mailbox != NULL);
+
+       folder = imapx_server_ref_folder (is, mailbox);
        g_return_if_fail (folder != NULL);
 
        data->scan_changes = FALSE;
@@ -5504,19 +5563,18 @@ imapx_job_scan_changes_done (CamelIMAPXServer *is,
                CamelMessageInfo *s_minfo = NULL;
                CamelIMAPXMessageInfo *info;
                CamelFolderSummary *s = folder->summary;
-               CamelIMAPXFolder *ifolder;
                GList *removed = NULL, *l;
                gboolean fetch_new = FALSE;
                gint i;
                guint j = 0;
                GPtrArray *uids;
 
-               ifolder = CAMEL_IMAPX_FOLDER (folder);
-
                /* Actually we wanted to do this after the SELECT but before the
                 * FETCH command was issued. But this should suffice. */
-               ((CamelIMAPXSummary *) s)->uidnext = ifolder->uidnext_on_server;
-               ((CamelIMAPXSummary *) s)->modseq = ifolder->modseq_on_server;
+               ((CamelIMAPXSummary *) s)->uidnext =
+                       camel_imapx_mailbox_get_uidnext (mailbox);
+               ((CamelIMAPXSummary *) s)->modseq =
+                       camel_imapx_mailbox_get_highestmodseq (mailbox);
 
                /* Here we do the typical sort/iterate/merge loop.
                 * If the server flags dont match what we had, we modify our
@@ -5636,6 +5694,7 @@ imapx_job_scan_changes_done (CamelIMAPXServer *is,
                        data->update_unseen = TRUE;
 
                        g_object_unref (folder);
+                       g_object_unref (mailbox);
 
                        return imapx_command_step_fetch_done (is, ic);
                }
@@ -5648,11 +5707,15 @@ imapx_job_scan_changes_done (CamelIMAPXServer *is,
         * mobile mode. In mobile mode we would have this filled up already
         * with a STATUS command.
         **/
-       if (!mobile_mode)
-               ((CamelIMAPXFolder *) folder)->unread_on_server =
-                       camel_folder_summary_get_unread_count (folder->summary);
+       if (!mobile_mode) {
+               guint32 unseen;
+
+               unseen = camel_folder_summary_get_unread_count (folder->summary);
+               camel_imapx_mailbox_set_unseen (mailbox, unseen);
+       }
 
        g_object_unref (folder);
+       g_object_unref (mailbox);
 
        imapx_unregister_job (is, job);
 }
@@ -5665,6 +5728,7 @@ imapx_job_scan_changes_start (CamelIMAPXJob *job,
 {
        CamelFolder *folder;
        CamelIMAPXCommand *ic;
+       CamelIMAPXMailbox *mailbox;
        RefreshInfoData *data;
        CamelIMAPXSettings *settings;
        gboolean mobile_mode;
@@ -5673,7 +5737,10 @@ imapx_job_scan_changes_start (CamelIMAPXJob *job,
        data = camel_imapx_job_get_data (job);
        g_return_val_if_fail (data != NULL, FALSE);
 
-       folder = camel_imapx_job_ref_folder (job);
+       mailbox = camel_imapx_job_ref_mailbox (job);
+       g_return_val_if_fail (mailbox != NULL, FALSE);
+
+       folder = imapx_server_ref_folder (is, mailbox);
        g_return_val_if_fail (folder != NULL, FALSE);
 
        settings = camel_imapx_server_ref_settings (is);
@@ -5691,11 +5758,12 @@ imapx_job_scan_changes_start (CamelIMAPXJob *job,
                camel_folder_get_display_name (folder));
 
        e (
-               'E', "Scanning from %s in %s\n", uid ? uid : "start",
-               camel_folder_get_full_name (folder));
+               'E', "Scanning from %s in %s\n",
+               uid ? uid : "start",
+               camel_imapx_mailbox_get_name (mailbox));
 
        ic = camel_imapx_command_new (
-               is, "FETCH", folder,
+               is, "FETCH", mailbox,
                "UID FETCH %s:* (UID FLAGS)", uid ? uid : "1");
        camel_imapx_command_set_job (ic, job);
        ic->complete = imapx_job_scan_changes_done;
@@ -5712,6 +5780,7 @@ imapx_job_scan_changes_start (CamelIMAPXJob *job,
        g_free (uid);
 
        g_object_unref (folder);
+       g_object_unref (mailbox);
 
        return TRUE;
 }
@@ -5722,7 +5791,7 @@ imapx_command_fetch_new_messages_done (CamelIMAPXServer *is,
 {
        CamelIMAPXJob *job;
        CamelIMAPXSummary *isum;
-       CamelIMAPXFolder *ifolder;
+       CamelIMAPXMailbox *mailbox;
        CamelFolder *folder;
        RefreshInfoData *data;
        GError *local_error = NULL;
@@ -5733,10 +5802,12 @@ imapx_command_fetch_new_messages_done (CamelIMAPXServer *is,
        data = camel_imapx_job_get_data (job);
        g_return_if_fail (data != NULL);
 
-       folder = camel_imapx_job_ref_folder (job);
+       mailbox = camel_imapx_job_ref_mailbox (job);
+       g_return_if_fail (mailbox != NULL);
+
+       folder = imapx_server_ref_folder (is, mailbox);
        g_return_if_fail (folder != NULL);
 
-       ifolder = CAMEL_IMAPX_FOLDER (folder);
        isum = CAMEL_IMAPX_SUMMARY (folder->summary);
 
        if (camel_imapx_command_set_error_if_failed (ic, &local_error)) {
@@ -5755,26 +5826,35 @@ imapx_command_fetch_new_messages_done (CamelIMAPXServer *is,
        }
 
        if (camel_folder_summary_count (folder->summary)) {
-               gchar *uid = camel_imapx_dup_uid_from_summary_index (
+               gchar *uid;
+               guint32 uidl;
+               guint32 uidnext;
+
+               uid = camel_imapx_dup_uid_from_summary_index (
                        folder,
                        camel_folder_summary_count (folder->summary) - 1);
-               guint64 uidl = strtoull (uid, NULL, 10);
+               uidl = (guint32) strtoull (uid, NULL, 10);
                g_free (uid);
 
                uidl++;
 
-               if (uidl > ifolder->uidnext_on_server) {
+               uidnext = camel_imapx_mailbox_get_uidnext (mailbox);
+
+               if (uidl > uidnext) {
                        c (
-                               is->tagprefix, "Updating uidnext_on_server for '%s' to %" G_GUINT64_FORMAT 
"\n",
-                               camel_folder_get_full_name (folder), uidl);
-                       ifolder->uidnext_on_server = uidl;
+                               is->tagprefix,
+                               "Updating uidnext for '%s' to %ul\n",
+                               camel_imapx_mailbox_get_name (mailbox),
+                               uidl);
+                       camel_imapx_mailbox_set_uidnext (mailbox, uidl);
                }
        }
 
-       isum->uidnext = ifolder->uidnext_on_server;
+       isum->uidnext = camel_imapx_mailbox_get_uidnext (mailbox);
 
 exit:
        g_object_unref (folder);
+       g_object_unref (mailbox);
 
        imapx_unregister_job (is, job);
 }
@@ -5811,18 +5891,22 @@ imapx_job_fetch_new_messages_start (CamelIMAPXJob *job,
 {
        CamelIMAPXCommand *ic;
        CamelFolder *folder;
-       CamelIMAPXFolder *ifolder;
+       CamelIMAPXMailbox *mailbox;
        CamelIMAPXSettings *settings;
        CamelSortType fetch_order;
        RefreshInfoData *data;
        guint32 total, diff;
+       guint32 messages;
        guint uidset_size;
        gchar *uid = NULL;
 
        data = camel_imapx_job_get_data (job);
        g_return_val_if_fail (data != NULL, FALSE);
 
-       folder = camel_imapx_job_ref_folder (job);
+       mailbox = camel_imapx_job_ref_mailbox (job);
+       g_return_val_if_fail (mailbox != NULL, FALSE);
+
+       folder = imapx_server_ref_folder (is, mailbox);
        g_return_val_if_fail (folder != NULL, FALSE);
 
        settings = camel_imapx_server_ref_settings (is);
@@ -5830,10 +5914,10 @@ imapx_job_fetch_new_messages_start (CamelIMAPXJob *job,
        uidset_size = camel_imapx_settings_get_batch_fetch_count (settings);
        g_object_unref (settings);
 
-       ifolder = CAMEL_IMAPX_FOLDER (folder);
+       messages = camel_imapx_mailbox_get_messages (mailbox);
 
        total = camel_folder_summary_count (folder->summary);
-       diff = ifolder->exists_on_server - total;
+       diff = messages - total;
 
        if (total > 0) {
                guint64 uidl;
@@ -5854,7 +5938,7 @@ imapx_job_fetch_new_messages_start (CamelIMAPXJob *job,
        //printf ("Fetch order: %d/%d\n", fetch_order, CAMEL_SORT_DESCENDING);
        if (diff > uidset_size || fetch_order == CAMEL_SORT_DESCENDING) {
                ic = camel_imapx_command_new (
-                       is, "FETCH", folder,
+                       is, "FETCH", mailbox,
                        "UID FETCH %s:* (UID FLAGS)", uid);
                imapx_uidset_init (&data->uidset, uidset_size, 0);
                refresh_info_data_infos_free (data);
@@ -5869,7 +5953,7 @@ imapx_job_fetch_new_messages_start (CamelIMAPXJob *job,
                        ic->complete = imapx_command_step_fetch_done;
        } else {
                ic = camel_imapx_command_new (
-                       is, "FETCH", folder,
+                       is, "FETCH", mailbox,
                        "UID FETCH %s:* (RFC822.SIZE RFC822.HEADER FLAGS)", uid);
                ic->pri = job->pri;
                ic->complete = imapx_command_fetch_new_messages_done;
@@ -5884,6 +5968,7 @@ imapx_job_fetch_new_messages_start (CamelIMAPXJob *job,
        g_free (uid);
 
        g_object_unref (folder);
+       g_object_unref (mailbox);
 
        return TRUE;
 }
@@ -5909,11 +5994,11 @@ imapx_job_fetch_messages_start (CamelIMAPXJob *job,
        data = camel_imapx_job_get_data (job);
        g_return_val_if_fail (data != NULL, FALSE);
 
-       folder = camel_imapx_job_ref_folder (job);
-       g_return_val_if_fail (folder != NULL, FALSE);
+       mailbox = camel_imapx_job_ref_mailbox (job);
+       g_return_val_if_fail (mailbox != NULL, FALSE);
 
-       mailbox = camel_imapx_folder_ref_mailbox (CAMEL_IMAPX_FOLDER (folder));
-       g_warn_if_fail (mailbox != NULL);
+       folder = imapx_server_ref_folder (is, mailbox);
+       g_return_val_if_fail (folder != NULL, FALSE);
 
        settings = camel_imapx_server_ref_settings (is);
        fetch_order = camel_imapx_settings_get_fetch_order (settings);
@@ -5974,7 +6059,7 @@ imapx_job_fetch_messages_start (CamelIMAPXJob *job,
 
                /* New account and fetching old messages, we would return just the limited number of newest 
messages */
                ic = camel_imapx_command_new (
-                       is, "FETCH", folder,
+                       is, "FETCH", mailbox,
                        "UID FETCH %s:* (UID FLAGS)", uid);
 
                imapx_uidset_init (&data->uidset, uidset_size, 0);
@@ -6006,8 +6091,9 @@ imapx_job_fetch_messages_start (CamelIMAPXJob *job,
                        camel_folder_get_display_name (folder));
 
                ic = camel_imapx_command_new (
-                       is, "FETCH", folder,
-                       "UID FETCH %s:%s (RFC822.SIZE RFC822.HEADER FLAGS)", start_uid, end_uid);
+                       is, "FETCH", mailbox,
+                       "UID FETCH %s:%s (RFC822.SIZE RFC822.HEADER FLAGS)",
+                       start_uid, end_uid);
                ic->pri = job->pri;
                ic->complete = imapx_command_fetch_new_messages_done;
 
@@ -6024,8 +6110,8 @@ imapx_job_fetch_messages_start (CamelIMAPXJob *job,
 
        camel_imapx_command_unref (ic);
 
-       g_object_unref (mailbox);
        g_object_unref (folder);
+       g_object_unref (mailbox);
 
        return TRUE;
 }
@@ -6036,7 +6122,6 @@ imapx_job_refresh_info_start (CamelIMAPXJob *job,
                               GCancellable *cancellable,
                               GError **error)
 {
-       CamelIMAPXFolder *ifolder;
        CamelIMAPXSettings *settings;
        CamelIMAPXSummary *isum;
        CamelFolder *folder;
@@ -6047,19 +6132,23 @@ imapx_job_refresh_info_start (CamelIMAPXJob *job,
        gboolean can_qresync = FALSE;
        gboolean mobile_mode;
        gboolean success;
+       guint32 messages;
+       guint32 unseen;
+       guint32 uidnext;
+       guint32 uidvalidity;
+       guint64 highestmodseq;
        guint32 total;
 
-       folder = camel_imapx_job_ref_folder (job);
-       g_return_val_if_fail (folder != NULL, FALSE);
+       mailbox = camel_imapx_job_ref_mailbox (job);
+       g_return_val_if_fail (mailbox != NULL, FALSE);
 
-       mailbox = camel_imapx_folder_ref_mailbox (CAMEL_IMAPX_FOLDER (folder));
-       g_warn_if_fail (mailbox != NULL);
+       folder = imapx_server_ref_folder (is, mailbox);
+       g_return_val_if_fail (folder != NULL, FALSE);
 
        settings = camel_imapx_server_ref_settings (is);
        mobile_mode = camel_imapx_settings_get_mobile_mode (settings);
        g_object_unref (settings);
 
-       ifolder = CAMEL_IMAPX_FOLDER (folder);
        isum = CAMEL_IMAPX_SUMMARY (folder->summary);
 
        full_name = camel_folder_get_full_name (folder);
@@ -6067,10 +6156,16 @@ imapx_job_refresh_info_start (CamelIMAPXJob *job,
        /* Sync changes first, else unread count will not
         * match. Need to think about better ways for this */
        success = imapx_server_sync_changes (
-               is, folder, job->type, job->pri, cancellable, error);
+               is, mailbox, job->type, job->pri, cancellable, error);
        if (!success)
                goto done;
 
+       messages = camel_imapx_mailbox_get_messages (mailbox);
+       unseen = camel_imapx_mailbox_get_unseen (mailbox);
+       uidnext = camel_imapx_mailbox_get_uidnext (mailbox);
+       uidvalidity = camel_imapx_mailbox_get_uidvalidity (mailbox);
+       highestmodseq = camel_imapx_mailbox_get_highestmodseq (mailbox);
+
 #if 0  /* There are issues with this still; continue with the buggy
         * behaviour where we issue STATUS on the current folder, for now. */
        if (is->priv->select_folder == folder)
@@ -6078,26 +6173,23 @@ imapx_job_refresh_info_start (CamelIMAPXJob *job,
 #endif
        total = camel_folder_summary_count (folder->summary);
 
-       if (ifolder->uidvalidity_on_server && isum->validity && isum->validity != 
ifolder->uidvalidity_on_server) {
-               camel_imapx_folder_invalidate_local_cache (
-                       ifolder, ifolder->uidvalidity_on_server);
+       if (uidvalidity > 0 && uidvalidity != isum->validity)
                need_rescan = TRUE;
-       }
 
        /* We don't have valid unread count or modseq for currently-selected server
         * (unless we want to re-SELECT it). We fake unread count when fetching
         * message flags, but don't depend on modseq for the selected folder */
-       if (total != ifolder->exists_on_server ||
-           isum->uidnext != ifolder->uidnext_on_server ||
-           camel_folder_summary_get_unread_count (folder->summary) != ifolder->unread_on_server ||
-           (!is_selected && isum->modseq != ifolder->modseq_on_server))
+       if (total != messages ||
+           isum->uidnext != uidnext ||
+           camel_folder_summary_get_unread_count (folder->summary) != unseen ||
+           (!is_selected && isum->modseq != highestmodseq))
                need_rescan = TRUE;
 
        /* This is probably the first check of this folder after startup;
         * use STATUS to check whether the cached summary is valid, rather
         * than blindly updating. Only for servers which support CONDSTORE
         * though. */
-       if ((isum->modseq && !ifolder->modseq_on_server))
+       if (isum->modseq > 0 && highestmodseq == 0)
                need_rescan = FALSE;
 
        /* If we don't think there's anything to do, poke it to check */
@@ -6144,10 +6236,16 @@ imapx_job_refresh_info_start (CamelIMAPXJob *job,
                }
 
                /* Recalulate need_rescan */
-               if (total != ifolder->exists_on_server ||
-                   isum->uidnext != ifolder->uidnext_on_server ||
-                   camel_folder_summary_get_unread_count (folder->summary) != ifolder->unread_on_server ||
-                   (!is_selected && isum->modseq != ifolder->modseq_on_server))
+
+               messages = camel_imapx_mailbox_get_messages (mailbox);
+               unseen = camel_imapx_mailbox_get_unseen (mailbox);
+               uidnext = camel_imapx_mailbox_get_uidnext (mailbox);
+               highestmodseq = camel_imapx_mailbox_get_highestmodseq (mailbox);
+
+               if (total != messages ||
+                   isum->uidnext != uidnext ||
+                   camel_folder_summary_get_unread_count (folder->summary) != unseen ||
+                   (!is_selected && isum->modseq != highestmodseq))
                        need_rescan = TRUE;
 
        } else if (mobile_mode) {
@@ -6173,7 +6271,13 @@ imapx_job_refresh_info_start (CamelIMAPXJob *job,
                }
        }
 
-       if (is->use_qresync && isum->modseq && ifolder->uidvalidity_on_server)
+       messages = camel_imapx_mailbox_get_messages (mailbox);
+       unseen = camel_imapx_mailbox_get_unseen (mailbox);
+       uidnext = camel_imapx_mailbox_get_uidnext (mailbox);
+       uidvalidity = camel_imapx_mailbox_get_uidvalidity (mailbox);
+       highestmodseq = camel_imapx_mailbox_get_highestmodseq (mailbox);
+
+       if (is->use_qresync && isum->modseq > 0 && uidvalidity > 0)
                can_qresync = TRUE;
 
        e (
@@ -6185,24 +6289,22 @@ imapx_job_refresh_info_start (CamelIMAPXJob *job,
                full_name,
                is_selected ? "" : "not ",
                total,
-               ifolder->exists_on_server,
+               messages,
                camel_folder_summary_get_unread_count (folder->summary),
-               ifolder->unread_on_server,
-               (guint64) isum->modseq,
-               (guint64) ifolder->modseq_on_server,
+               unseen,
+               isum->modseq,
+               highestmodseq,
                isum->uidnext,
-               ifolder->uidnext_on_server,
+               uidnext,
                need_rescan ? "" : "not ");
 
        /* Fetch new messages first, so that they appear to the user ASAP */
-       if (ifolder->exists_on_server > total ||
-           ifolder->uidnext_on_server > isum->uidnext)
-       {
+       if (messages > total || uidnext > isum->uidnext) {
                if (!total)
                        need_rescan = FALSE;
 
                success = imapx_server_fetch_new_messages (
-                       is, folder, FALSE, FALSE, cancellable, error);
+                       is, mailbox, FALSE, FALSE, cancellable, error);
                if (!success)
                        goto done;
 
@@ -6217,48 +6319,52 @@ imapx_job_refresh_info_start (CamelIMAPXJob *job,
        if (can_qresync) {
                /* Actually we only want to select it; no need for the NOOP */
                success = camel_imapx_server_noop (
-                       is, folder, cancellable, error);
+                       is, mailbox, cancellable, error);
                if (!success)
                        goto done;
        qresync_done:
-               isum->modseq = ifolder->modseq_on_server;
+               messages = camel_imapx_mailbox_get_messages (mailbox);
+               unseen = camel_imapx_mailbox_get_unseen (mailbox);
+               highestmodseq = camel_imapx_mailbox_get_highestmodseq (mailbox);
+
+               isum->modseq = highestmodseq;
                total = camel_folder_summary_count (folder->summary);
-               if (total != ifolder->exists_on_server ||
-                   camel_folder_summary_get_unread_count (folder->summary) != ifolder->unread_on_server ||
-                   (isum->modseq != ifolder->modseq_on_server)) {
+               if (total != messages ||
+                   camel_folder_summary_get_unread_count (folder->summary) != unseen ||
+                   (isum->modseq != highestmodseq)) {
                        c (
                                is->tagprefix,
                                "Eep, after QRESYNC we're out of sync. "
                                "total %u / %u, unread %u / %u, modseq %"
                                G_GUINT64_FORMAT " / %" G_GUINT64_FORMAT "\n",
-                               total, ifolder->exists_on_server,
+                               total, messages,
                                camel_folder_summary_get_unread_count (folder->summary),
-                               ifolder->unread_on_server,
+                               unseen,
                                isum->modseq,
-                               ifolder->modseq_on_server);
+                               highestmodseq);
                } else {
                        c (
                                is->tagprefix,
                                "OK, after QRESYNC we're still in sync. "
                                "total %u / %u, unread %u / %u, modseq %"
                                G_GUINT64_FORMAT " / %" G_GUINT64_FORMAT "\n",
-                               total, ifolder->exists_on_server,
+                               total, messages,
                                camel_folder_summary_get_unread_count (folder->summary),
-                               ifolder->unread_on_server,
+                               unseen,
                                isum->modseq,
-                               ifolder->modseq_on_server);
+                               highestmodseq);
                        goto done;
                }
        }
 
-       g_object_unref (mailbox);
        g_object_unref (folder);
+       g_object_unref (mailbox);
 
        return imapx_job_scan_changes_start (job, is, cancellable, error);
 
 done:
-       g_object_unref (mailbox);
        g_object_unref (folder);
+       g_object_unref (mailbox);
 
        imapx_unregister_job (is, job);
 
@@ -6267,10 +6373,10 @@ done:
 
 static gboolean
 imapx_job_refresh_info_matches (CamelIMAPXJob *job,
-                                CamelFolder *folder,
+                                CamelIMAPXMailbox *mailbox,
                                 const gchar *uid)
 {
-       return camel_imapx_job_has_folder (job, folder);
+       return camel_imapx_job_has_mailbox (job, mailbox);
 }
 
 /* ********************************************************************** */
@@ -6280,13 +6386,17 @@ imapx_command_expunge_done (CamelIMAPXServer *is,
                             CamelIMAPXCommand *ic)
 {
        CamelIMAPXJob *job;
+       CamelIMAPXMailbox *mailbox;
        CamelFolder *folder;
        GError *local_error = NULL;
 
        job = camel_imapx_command_get_job (ic);
        g_return_if_fail (CAMEL_IS_IMAPX_JOB (job));
 
-       folder = camel_imapx_job_ref_folder (job);
+       mailbox = camel_imapx_job_ref_mailbox (job);
+       g_return_if_fail (mailbox != NULL);
+
+       folder = imapx_server_ref_folder (is, mailbox);
        g_return_if_fail (folder != NULL);
 
        if (camel_imapx_command_set_error_if_failed (ic, &local_error)) {
@@ -6339,6 +6449,7 @@ imapx_command_expunge_done (CamelIMAPXServer *is,
        }
 
        g_object_unref (folder);
+       g_object_unref (mailbox);
 
        imapx_unregister_job (is, job);
 }
@@ -6350,19 +6461,19 @@ imapx_job_expunge_start (CamelIMAPXJob *job,
                          GError **error)
 {
        CamelIMAPXCommand *ic;
-       CamelFolder *folder;
+       CamelIMAPXMailbox *mailbox;
        gboolean success;
 
-       folder = camel_imapx_job_ref_folder (job);
-       g_return_val_if_fail (folder != NULL, FALSE);
+       mailbox = camel_imapx_job_ref_mailbox (job);
+       g_return_val_if_fail (mailbox != NULL, FALSE);
 
        success = imapx_server_sync_changes (
-               is, folder, job->type, job->pri, cancellable, error);
+               is, mailbox, job->type, job->pri, cancellable, error);
 
        if (success) {
                /* TODO handle UIDPLUS capability */
                ic = camel_imapx_command_new (
-                       is, "EXPUNGE", folder, "EXPUNGE");
+                       is, "EXPUNGE", mailbox, "EXPUNGE");
                camel_imapx_command_set_job (ic, job);
                ic->pri = job->pri;
                ic->complete = imapx_command_expunge_done;
@@ -6372,17 +6483,17 @@ imapx_job_expunge_start (CamelIMAPXJob *job,
                camel_imapx_command_unref (ic);
        }
 
-       g_object_unref (folder);
+       g_object_unref (mailbox);
 
        return success;
 }
 
 static gboolean
 imapx_job_expunge_matches (CamelIMAPXJob *job,
-                           CamelFolder *folder,
+                           CamelIMAPXMailbox *mailbox,
                            const gchar *uid)
 {
-       return camel_imapx_job_has_folder (job, folder);
+       return camel_imapx_job_has_mailbox (job, mailbox);
 }
 
 /* ********************************************************************** */
@@ -6444,7 +6555,7 @@ imapx_job_list_start (CamelIMAPXJob *job,
 
 static gboolean
 imapx_job_list_matches (CamelIMAPXJob *job,
-                        CamelFolder *folder,
+                        CamelIMAPXMailbox *mailbox,
                         const gchar *uid)
 {
        return TRUE;  /* matches everything */
@@ -6452,27 +6563,9 @@ imapx_job_list_matches (CamelIMAPXJob *job,
 
 /* ********************************************************************** */
 
-static gchar *
-imapx_encode_folder_name (CamelIMAPXStore *istore,
-                          const gchar *folder_name)
-{
-       gchar *mailbox;
-       gchar *encoded;
-
-       mailbox = camel_imapx_store_summary_mailbox_from_path (
-               istore->summary, folder_name);
-       if (mailbox != NULL) {
-               encoded = camel_utf8_utf7 (mailbox);
-               g_free (mailbox);
-       } else
-               encoded = camel_utf8_utf7 (folder_name);
-
-       return encoded;
-}
-
 static void
-imapx_command_subscription_done (CamelIMAPXServer *is,
-                                 CamelIMAPXCommand *ic)
+imapx_command_create_mailbox_done (CamelIMAPXServer *is,
+                                   CamelIMAPXCommand *ic)
 {
        CamelIMAPXJob *job;
        GError *local_error = NULL;
@@ -6483,7 +6576,7 @@ imapx_command_subscription_done (CamelIMAPXServer *is,
        if (camel_imapx_command_set_error_if_failed (ic, &local_error)) {
                g_prefix_error (
                        &local_error, "%s: ",
-                       _("Error subscribing to folder"));
+                       _("Error creating folder"));
                camel_imapx_job_take_error (job, local_error);
        }
 
@@ -6491,94 +6584,94 @@ imapx_command_subscription_done (CamelIMAPXServer *is,
 }
 
 static gboolean
-imapx_job_manage_subscription_start (CamelIMAPXJob *job,
-                                     CamelIMAPXServer *is,
-                                     GCancellable *cancellable,
-                                     GError **error)
+imapx_job_create_mailbox_start (CamelIMAPXJob *job,
+                                CamelIMAPXServer *is,
+                                GCancellable *cancellable,
+                                GError **error)
 {
        CamelIMAPXCommand *ic;
-       CamelIMAPXStore *store;
-       ManageSubscriptionsData *data;
-       gchar *encoded_fname = NULL;
+       MailboxData *data;
 
        data = camel_imapx_job_get_data (job);
        g_return_val_if_fail (data != NULL, FALSE);
 
-       store = camel_imapx_server_ref_store (is);
-       encoded_fname = imapx_encode_folder_name (store, data->folder_name);
-
-       if (data->subscribe)
-               ic = camel_imapx_command_new (
-                       is, "SUBSCRIBE", NULL,
-                       "SUBSCRIBE %s", encoded_fname);
-       else
-               ic = camel_imapx_command_new (
-                       is, "UNSUBSCRIBE", NULL,
-                       "UNSUBSCRIBE %s", encoded_fname);
-
+       ic = camel_imapx_command_new (
+               is, "CREATE", NULL, "CREATE %m",
+               data->mailbox_name);
        ic->pri = job->pri;
        camel_imapx_command_set_job (ic, job);
-       ic->complete = imapx_command_subscription_done;
+       ic->complete = imapx_command_create_mailbox_done;
 
        imapx_command_queue (is, ic);
 
        camel_imapx_command_unref (ic);
 
-       g_free (encoded_fname);
-       g_object_unref (store);
-
        return TRUE;
 }
 
 /* ********************************************************************** */
 
 static void
-imapx_command_create_folder_done (CamelIMAPXServer *is,
-                                  CamelIMAPXCommand *ic)
+imapx_command_delete_mailbox_done (CamelIMAPXServer *is,
+                                   CamelIMAPXCommand *ic)
 {
        CamelIMAPXJob *job;
+       MailboxData *data;
        GError *local_error = NULL;
 
        job = camel_imapx_command_get_job (ic);
        g_return_if_fail (CAMEL_IS_IMAPX_JOB (job));
 
+       data = camel_imapx_job_get_data (job);
+       g_return_if_fail (data != NULL);
+
        if (camel_imapx_command_set_error_if_failed (ic, &local_error)) {
                g_prefix_error (
                        &local_error, "%s: ",
-                       _("Error creating folder"));
+                       _("Error deleting folder"));
                camel_imapx_job_take_error (job, local_error);
+
+       } else {
+               /* Perform the same processing as imapx_untagged_list()
+                * would if the server notified us of a deleted mailbox. */
+
+               camel_imapx_mailbox_deleted (data->mailbox);
+               g_signal_emit (is, signals[MAILBOX_UPDATED], 0, data->mailbox);
        }
 
        imapx_unregister_job (is, job);
 }
 
 static gboolean
-imapx_job_create_folder_start (CamelIMAPXJob *job,
-                               CamelIMAPXServer *is,
-                               GCancellable *cancellable,
-                               GError **error)
+imapx_job_delete_mailbox_start (CamelIMAPXJob *job,
+                                CamelIMAPXServer *is,
+                                GCancellable *cancellable,
+                                GError **error)
 {
        CamelIMAPXCommand *ic;
-       CreateFolderData *data;
-       gchar *encoded_fname = NULL;
+       MailboxData *data;
+       CamelIMAPXMailbox *inbox;
 
        data = camel_imapx_job_get_data (job);
        g_return_val_if_fail (data != NULL, FALSE);
 
-       encoded_fname = camel_utf8_utf7 (data->folder_name);
+       /* Keep going, even if this returns NULL. */
+       inbox = camel_imapx_server_ref_mailbox (is, "INBOX");
 
+       /* Make sure the to-be-deleted folder is not
+        * selected by selecting INBOX for this operation. */
        ic = camel_imapx_command_new (
-               is, "CREATE", NULL,
-               "CREATE %s", encoded_fname);
+               is, "DELETE", inbox,
+               "DELETE %M", data->mailbox);
        ic->pri = job->pri;
        camel_imapx_command_set_job (ic, job);
-       ic->complete = imapx_command_create_folder_done;
+       ic->complete = imapx_command_delete_mailbox_done;
 
        imapx_command_queue (is, ic);
 
        camel_imapx_command_unref (ic);
 
-       g_free (encoded_fname);
+       g_clear_object (&inbox);
 
        return TRUE;
 }
@@ -6586,146 +6679,208 @@ imapx_job_create_folder_start (CamelIMAPXJob *job,
 /* ********************************************************************** */
 
 static void
-imapx_command_delete_folder_done (CamelIMAPXServer *is,
-                                  CamelIMAPXCommand *ic)
+imapx_command_rename_mailbox_done (CamelIMAPXServer *is,
+                                   CamelIMAPXCommand *ic)
 {
        CamelIMAPXJob *job;
+       MailboxData *data;
        GError *local_error = NULL;
 
        job = camel_imapx_command_get_job (ic);
        g_return_if_fail (CAMEL_IS_IMAPX_JOB (job));
 
+       data = camel_imapx_job_get_data (job);
+       g_return_if_fail (data != NULL);
+
        if (camel_imapx_command_set_error_if_failed (ic, &local_error)) {
                g_prefix_error (
                        &local_error, "%s: ",
-                       _("Error deleting folder"));
+                       _("Error renaming folder"));
                camel_imapx_job_take_error (job, local_error);
+
+       } else {
+               CamelIMAPXMailbox *old_mailbox;
+               CamelIMAPXMailbox *new_mailbox;
+               const gchar *old_mailbox_name;
+               const gchar *new_mailbox_name;
+
+               /* Perform the same processing as imapx_untagged_list()
+                * would if the server notified us of a renamed mailbox. */
+
+               old_mailbox = data->mailbox;
+               new_mailbox_name = data->mailbox_name;
+
+               old_mailbox_name = camel_imapx_mailbox_get_name (old_mailbox);
+
+               g_mutex_lock (&is->priv->mailboxes_lock);
+               new_mailbox = imapx_server_rename_mailbox_unlocked (
+                       is, old_mailbox_name, new_mailbox_name);
+               g_mutex_unlock (&is->priv->mailboxes_lock);
+
+               g_warn_if_fail (new_mailbox != NULL);
+
+               g_signal_emit (
+                       is, signals[MAILBOX_RENAMED], 0,
+                       new_mailbox, old_mailbox_name);
+
+               g_clear_object (&new_mailbox);
        }
 
        imapx_unregister_job (is, job);
 }
 
 static gboolean
-imapx_job_delete_folder_start (CamelIMAPXJob *job,
-                               CamelIMAPXServer *is,
-                               GCancellable *cancellable,
-                               GError **error)
+imapx_job_rename_mailbox_start (CamelIMAPXJob *job,
+                                CamelIMAPXServer *is,
+                                GCancellable *cancellable,
+                                GError **error)
 {
        CamelIMAPXCommand *ic;
-       CamelIMAPXStore *store;
-       CamelFolder *folder;
-       DeleteFolderData *data;
-       gchar *encoded_fname = NULL;
-       gboolean success = FALSE;
+       CamelIMAPXMailbox *inbox;
+       MailboxData *data;
 
        data = camel_imapx_job_get_data (job);
        g_return_val_if_fail (data != NULL, FALSE);
 
-       store = camel_imapx_server_ref_store (is);
-       encoded_fname = imapx_encode_folder_name (store, data->folder_name);
+       inbox = camel_imapx_server_ref_mailbox (is, "INBOX");
+       g_return_val_if_fail (inbox != NULL, FALSE);
 
-       folder = camel_store_get_folder_sync (
-               CAMEL_STORE (store), "INBOX", 0, cancellable, error);
+       camel_imapx_job_set_mailbox (job, inbox);
 
-       if (folder != NULL) {
-               camel_imapx_job_set_folder (job, folder);
-
-               /* Make sure the to-be-deleted folder is not
-                * selected by selecting INBOX for this operation. */
-               ic = camel_imapx_command_new (
-                       is, "DELETE", folder,
-                       "DELETE %s", encoded_fname);
-               ic->pri = job->pri;
-               camel_imapx_command_set_job (ic, job);
-               ic->complete = imapx_command_delete_folder_done;
-
-               imapx_command_queue (is, ic);
-
-               camel_imapx_command_unref (ic);
+       ic = camel_imapx_command_new (
+               is, "RENAME", inbox, "RENAME %M %m",
+               data->mailbox, data->mailbox_name);
+       ic->pri = job->pri;
+       camel_imapx_command_set_job (ic, job);
+       ic->complete = imapx_command_rename_mailbox_done;
 
-               g_object_unref (folder);
+       imapx_command_queue (is, ic);
 
-               success = TRUE;
-       }
+       camel_imapx_command_unref (ic);
 
-       g_free (encoded_fname);
-       g_object_unref (store);
+       g_object_unref (inbox);
 
-       return success;
+       return TRUE;
 }
 
 /* ********************************************************************** */
 
 static void
-imapx_command_rename_folder_done (CamelIMAPXServer *is,
-                                  CamelIMAPXCommand *ic)
+imapx_command_subscribe_mailbox_done (CamelIMAPXServer *is,
+                                      CamelIMAPXCommand *ic)
 {
        CamelIMAPXJob *job;
+       MailboxData *data;
        GError *local_error = NULL;
 
        job = camel_imapx_command_get_job (ic);
        g_return_if_fail (CAMEL_IS_IMAPX_JOB (job));
 
+       data = camel_imapx_job_get_data (job);
+       g_return_if_fail (data != NULL);
+
        if (camel_imapx_command_set_error_if_failed (ic, &local_error)) {
                g_prefix_error (
                        &local_error, "%s: ",
-                       _("Error renaming folder"));
+                       _("Error subscribing to folder"));
                camel_imapx_job_take_error (job, local_error);
+
+       } else {
+               /* Perform the same processing as imapx_untagged_list()
+                * would if the server notified us of a subscription. */
+
+               camel_imapx_mailbox_subscribed (data->mailbox);
+               g_signal_emit (is, signals[MAILBOX_UPDATED], 0, data->mailbox);
        }
 
        imapx_unregister_job (is, job);
 }
 
 static gboolean
-imapx_job_rename_folder_start (CamelIMAPXJob *job,
-                               CamelIMAPXServer *is,
-                               GCancellable *cancellable,
-                               GError **error)
+imapx_job_subscribe_mailbox_start (CamelIMAPXJob *job,
+                                   CamelIMAPXServer *is,
+                                   GCancellable *cancellable,
+                                   GError **error)
 {
        CamelIMAPXCommand *ic;
-       CamelIMAPXStore *store;
-       RenameFolderData *data;
-       CamelFolder *folder;
-       gchar *en_ofname = NULL;
-       gchar *en_nfname = NULL;
-       gboolean success = FALSE;
+       MailboxData *data;
 
        data = camel_imapx_job_get_data (job);
        g_return_val_if_fail (data != NULL, FALSE);
 
-       store = camel_imapx_server_ref_store (is);
+       ic = camel_imapx_command_new (
+               is, "SUBSCRIBE", NULL,
+               "SUBSCRIBE %M", data->mailbox);
 
-       en_ofname = imapx_encode_folder_name (store, data->old_folder_name);
-       en_nfname = imapx_encode_folder_name (store, data->new_folder_name);
+       ic->pri = job->pri;
+       camel_imapx_command_set_job (ic, job);
+       ic->complete = imapx_command_subscribe_mailbox_done;
 
-       folder = camel_store_get_folder_sync (
-               CAMEL_STORE (store), "INBOX", 0, cancellable, error);
+       imapx_command_queue (is, ic);
 
-       if (folder != NULL) {
-               camel_imapx_job_set_folder (job, folder);
+       camel_imapx_command_unref (ic);
 
-               ic = camel_imapx_command_new (
-                       is, "RENAME", folder,
-                       "RENAME %s %s", en_ofname, en_nfname);
-               ic->pri = job->pri;
-               camel_imapx_command_set_job (ic, job);
-               ic->complete = imapx_command_rename_folder_done;
+       return TRUE;
+}
 
-               imapx_command_queue (is, ic);
+/* ********************************************************************** */
 
-               camel_imapx_command_unref (ic);
+static void
+imapx_command_unsubscribe_mailbox_done (CamelIMAPXServer *is,
+                                        CamelIMAPXCommand *ic)
+{
+       CamelIMAPXJob *job;
+       MailboxData *data;
+       GError *local_error = NULL;
 
-               g_object_unref (folder);
+       job = camel_imapx_command_get_job (ic);
+       g_return_if_fail (CAMEL_IS_IMAPX_JOB (job));
 
-               success = TRUE;
+       data = camel_imapx_job_get_data (job);
+       g_return_if_fail (data != NULL);
+
+       if (camel_imapx_command_set_error_if_failed (ic, &local_error)) {
+               g_prefix_error (
+                       &local_error, "%s: ",
+                       _("Error unsubscribing from folder"));
+               camel_imapx_job_take_error (job, local_error);
+
+       } else {
+               /* Perform the same processing as imapx_untagged_list()
+                * would if the server notified us of an unsubscription. */
+
+               camel_imapx_mailbox_unsubscribed (data->mailbox);
+               g_signal_emit (is, signals[MAILBOX_UPDATED], 0, data->mailbox);
        }
 
-       g_free (en_ofname);
-       g_free (en_nfname);
+       imapx_unregister_job (is, job);
+}
+
+static gboolean
+imapx_job_unsubscribe_mailbox_start (CamelIMAPXJob *job,
+                                     CamelIMAPXServer *is,
+                                     GCancellable *cancellable,
+                                     GError **error)
+{
+       CamelIMAPXCommand *ic;
+       MailboxData *data;
 
-       g_object_unref (store);
+       data = camel_imapx_job_get_data (job);
+       g_return_val_if_fail (data != NULL, FALSE);
 
-       return success;
+       ic = camel_imapx_command_new (
+               is, "UNSUBSCRIBE", NULL,
+               "UNSUBSCRIBE %M", data->mailbox);
+
+       ic->pri = job->pri;
+       camel_imapx_command_set_job (ic, job);
+       ic->complete = imapx_command_unsubscribe_mailbox_done;
+
+       imapx_command_queue (is, ic);
+
+       camel_imapx_command_unref (ic);
+
+       return TRUE;
 }
 
 /* ********************************************************************** */
@@ -6757,19 +6912,14 @@ imapx_job_update_quota_info_start (CamelIMAPXJob *job,
                                    GError **error)
 {
        CamelIMAPXCommand *ic;
-       CamelIMAPXStore *store;
-       QuotaData *data;
-       gchar *encoded_fname;
+       CamelIMAPXMailbox *mailbox;
 
-       data = camel_imapx_job_get_data (job);
-       g_return_val_if_fail (data != NULL, FALSE);
-
-       store = camel_imapx_server_ref_store (is);
-       encoded_fname = imapx_encode_folder_name (store, data->folder_name);
+       mailbox = camel_imapx_job_ref_mailbox (job);
+       g_return_val_if_fail (mailbox != NULL, FALSE);
 
        ic = camel_imapx_command_new (
                is, "GETQUOTAROOT", NULL,
-               "GETQUOTAROOT %s", encoded_fname);
+               "GETQUOTAROOT %M", mailbox);
        ic->pri = job->pri;
        camel_imapx_command_set_job (ic, job);
        ic->complete = imapx_command_update_quota_info_done;
@@ -6778,8 +6928,7 @@ imapx_job_update_quota_info_start (CamelIMAPXJob *job,
 
        camel_imapx_command_unref (ic);
 
-       g_free (encoded_fname);
-       g_object_unref (store);
+       g_clear_object (&mailbox);
 
        return TRUE;
 }
@@ -6822,18 +6971,18 @@ imapx_job_uid_search_start (CamelIMAPXJob *job,
                             GCancellable *cancellable,
                             GError **error)
 {
-       CamelFolder *folder;
        CamelIMAPXCommand *ic;
+       CamelIMAPXMailbox *mailbox;
        SearchData *data;
 
        data = camel_imapx_job_get_data (job);
        g_return_val_if_fail (data != NULL, FALSE);
 
-       folder = camel_imapx_job_ref_folder (job);
-       g_return_val_if_fail (folder != NULL, FALSE);
+       mailbox = camel_imapx_job_ref_mailbox (job);
+       g_return_val_if_fail (mailbox != NULL, FALSE);
 
        ic = camel_imapx_command_new (
-               is, "UID SEARCH", folder,
+               is, "UID SEARCH", mailbox,
                "UID SEARCH %t", data->criteria);
        ic->pri = job->pri;
        camel_imapx_command_set_job (ic, job);
@@ -6843,7 +6992,7 @@ imapx_job_uid_search_start (CamelIMAPXJob *job,
 
        camel_imapx_command_unref (ic);
 
-       g_object_unref (folder);
+       g_object_unref (mailbox);
 
        return TRUE;
 }
@@ -6877,26 +7026,27 @@ imapx_job_noop_start (CamelIMAPXJob *job,
                       GError **error)
 {
        CamelIMAPXCommand *ic;
-       CamelFolder *folder;
+       CamelIMAPXMailbox *mailbox;
 
-       folder = camel_imapx_job_ref_folder (job);
+       /* This may be NULL. */
+       mailbox = camel_imapx_job_ref_mailbox (job);
 
        ic = camel_imapx_command_new (
-               is, "NOOP", folder, "NOOP");
+               is, "NOOP", mailbox, "NOOP");
 
        camel_imapx_command_set_job (ic, job);
        ic->complete = imapx_command_noop_done;
-       if (folder != NULL) {
+       if (mailbox != NULL)
                ic->pri = IMAPX_PRIORITY_REFRESH_INFO;
-               g_object_unref (folder);
-       } else {
+       else
                ic->pri = IMAPX_PRIORITY_NOOP;
-       }
 
        imapx_command_queue (is, ic);
 
        camel_imapx_command_unref (ic);
 
+       g_clear_object (&mailbox);
+
        return TRUE;
 }
 
@@ -6932,6 +7082,7 @@ imapx_command_sync_changes_done (CamelIMAPXServer *is,
                                  CamelIMAPXCommand *ic)
 {
        CamelIMAPXJob *job;
+       CamelIMAPXMailbox *mailbox;
        CamelFolder *folder;
        CamelStore *parent_store;
        SyncChangesData *data;
@@ -6946,7 +7097,10 @@ imapx_command_sync_changes_done (CamelIMAPXServer *is,
        data = camel_imapx_job_get_data (job);
        g_return_if_fail (data != NULL);
 
-       folder = camel_imapx_job_ref_folder (job);
+       mailbox = camel_imapx_job_ref_mailbox (job);
+       g_return_if_fail (mailbox != NULL);
+
+       folder = imapx_server_ref_folder (is, mailbox);
        g_return_if_fail (folder != NULL);
 
        settings = camel_imapx_server_ref_settings (is);
@@ -6978,6 +7132,7 @@ imapx_command_sync_changes_done (CamelIMAPXServer *is,
 
        /* lock cache ? */
        } else {
+               guint32 unseen;
                gint i;
 
                for (i = 0; i < data->changed_uids->len; i++) {
@@ -7002,9 +7157,12 @@ imapx_command_sync_changes_done (CamelIMAPXServer *is,
                        camel_folder_summary_touch (folder->summary);
                        camel_message_info_free (xinfo);
                }
+
                /* Apply the changes to server-side unread count; it won't tell
                 * us of these changes, of course. */
-               ((CamelIMAPXFolder *) folder)->unread_on_server += data->unread_change;
+               unseen = camel_imapx_mailbox_get_unseen (mailbox);
+               unseen += data->unread_change;
+               camel_imapx_mailbox_set_unseen (mailbox, unseen);
        }
 
        if (job->commands == 0) {
@@ -7037,6 +7195,7 @@ imapx_command_sync_changes_done (CamelIMAPXServer *is,
 
 exit:
        g_object_unref (folder);
+       g_object_unref (mailbox);
 }
 
 static gboolean
@@ -7047,6 +7206,7 @@ imapx_job_sync_changes_start (CamelIMAPXJob *job,
 {
        SyncChangesData *data;
        CamelFolder *folder;
+       CamelIMAPXMailbox *mailbox;
        guint32 i, j;
        struct _uidset_state ss;
        GPtrArray *uids;
@@ -7055,7 +7215,10 @@ imapx_job_sync_changes_start (CamelIMAPXJob *job,
        data = camel_imapx_job_get_data (job);
        g_return_val_if_fail (data != NULL, FALSE);
 
-       folder = camel_imapx_job_ref_folder (job);
+       mailbox = camel_imapx_job_ref_mailbox (job);
+       g_return_val_if_fail (mailbox != NULL, FALSE);
+
+       folder = imapx_server_ref_folder (is, mailbox);
        g_return_val_if_fail (folder != NULL, FALSE);
 
        uids = data->changed_uids;
@@ -7107,7 +7270,7 @@ imapx_job_sync_changes_start (CamelIMAPXJob *job,
                                     || (!on && (((flags ^ sflags) & ~flags) & flag))) {
                                        if (ic == NULL) {
                                                ic = camel_imapx_command_new (
-                                                       is, "STORE", folder,
+                                                       is, "STORE", mailbox,
                                                        "UID STORE ");
                                                ic->complete = imapx_command_sync_changes_done;
                                                camel_imapx_command_set_job (ic, job);
@@ -7146,7 +7309,7 @@ imapx_job_sync_changes_start (CamelIMAPXJob *job,
 
                                        if (ic == NULL) {
                                                ic = camel_imapx_command_new (
-                                                       is, "STORE", folder,
+                                                       is, "STORE", mailbox,
                                                        "UID STORE ");
                                                ic->complete = imapx_command_sync_changes_done;
                                                camel_imapx_command_set_job (ic, job);
@@ -7167,6 +7330,7 @@ imapx_job_sync_changes_start (CamelIMAPXJob *job,
        }
 
        g_object_unref (folder);
+       g_object_unref (mailbox);
 
        /* Since this may start in another thread ... we need to
         * lock the commands count, ho hum */
@@ -7179,10 +7343,10 @@ imapx_job_sync_changes_start (CamelIMAPXJob *job,
 
 static gboolean
 imapx_job_sync_changes_matches (CamelIMAPXJob *job,
-                                CamelFolder *folder,
+                                CamelIMAPXMailbox *mailbox,
                                 const gchar *uid)
 {
-       return camel_imapx_job_has_folder (job, folder);
+       return camel_imapx_job_has_mailbox (job, mailbox);
 }
 
 static void
@@ -7800,24 +7964,18 @@ camel_imapx_server_ref_mailbox (CamelIMAPXServer *is,
 CamelIMAPXMailbox *
 camel_imapx_server_ref_selected (CamelIMAPXServer *is)
 {
-       CamelIMAPXFolder *folder;
-       CamelIMAPXMailbox *mailbox = NULL;
+       CamelIMAPXMailbox *mailbox;
 
        g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), NULL);
 
        g_mutex_lock (&is->priv->select_lock);
 
-       folder = g_weak_ref_get (&is->priv->select_folder);
-       if (folder == NULL)
-               folder = g_weak_ref_get (&is->priv->select_pending);
+       mailbox = g_weak_ref_get (&is->priv->select_mailbox);
+       if (mailbox == NULL)
+               mailbox = g_weak_ref_get (&is->priv->select_pending);
 
        g_mutex_unlock (&is->priv->select_lock);
 
-       if (folder != NULL) {
-               mailbox = camel_imapx_folder_ref_mailbox (folder);
-               g_object_unref (folder);
-       }
-
        return mailbox;
 }
 
@@ -7885,7 +8043,7 @@ imapx_disconnect (CamelIMAPXServer *is)
        g_mutex_unlock (&is->priv->stream_lock);
 
        g_mutex_lock (&is->priv->select_lock);
-       g_weak_ref_set (&is->priv->select_folder, NULL);
+       g_weak_ref_set (&is->priv->select_mailbox, NULL);
        g_weak_ref_set (&is->priv->select_pending, NULL);
        g_mutex_unlock (&is->priv->select_lock);
 
@@ -7907,6 +8065,8 @@ camel_imapx_server_connect (CamelIMAPXServer *is,
                             GCancellable *cancellable,
                             GError **error)
 {
+       g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), FALSE);
+
        if (is->state == IMAPX_SHUTDOWN) {
                g_set_error (
                        error, CAMEL_SERVICE_ERROR,
@@ -7929,23 +8089,25 @@ camel_imapx_server_connect (CamelIMAPXServer *is,
 
 static CamelStream *
 imapx_server_get_message (CamelIMAPXServer *is,
-                          CamelFolder *folder,
-                          const gchar *uid,
+                          CamelIMAPXMailbox *mailbox,
+                          CamelFolderSummary *summary,
+                          CamelDataCache *message_cache,
+                          const gchar *message_uid,
                           gint pri,
                           GCancellable *cancellable,
                           GError **error)
 {
        CamelStream *stream = NULL;
-       CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) folder;
        CamelIMAPXJob *job;
        CamelMessageInfo *mi;
        GetMessageData *data;
        gboolean registered;
-       gboolean success;
 
        QUEUE_LOCK (is);
 
-       job = imapx_is_job_in_queue (is, folder, IMAPX_JOB_GET_MESSAGE, uid);
+       job = imapx_is_job_in_queue (
+               is, mailbox, IMAPX_JOB_GET_MESSAGE, message_uid);
+
        if (job != NULL) {
                /* Promote the existing GET_MESSAGE
                 * job's priority if ours is higher. */
@@ -7961,27 +8123,29 @@ imapx_server_get_message (CamelIMAPXServer *is,
                 * message from cache (implying the job we were waiting
                 * on failed or got cancelled), we'll just re-fetch it. */
                stream = camel_data_cache_get (
-                       ifolder->cache, "cur", uid, NULL);
+                       message_cache, "cur", message_uid, NULL);
                if (stream != NULL)
                        return stream;
 
                QUEUE_LOCK (is);
        }
 
-       mi = camel_folder_summary_get (folder->summary, uid);
-       if (!mi) {
+       mi = camel_folder_summary_get (summary, message_uid);
+       if (mi == NULL) {
                g_set_error (
                        error, CAMEL_FOLDER_ERROR,
                        CAMEL_FOLDER_ERROR_INVALID_UID,
                        _("Cannot get message with message ID %s: %s"),
-                       uid, _("No such message available."));
+                       message_uid, _("No such message available."));
                QUEUE_UNLOCK (is);
                return NULL;
        }
 
        data = g_slice_new0 (GetMessageData);
-       data->uid = g_strdup (uid);
-       data->stream = camel_data_cache_add (ifolder->cache, "tmp", uid, NULL);
+       data->uid = g_strdup (message_uid);
+       data->message_cache = g_object_ref (message_cache);
+       data->stream = camel_data_cache_add (
+               message_cache, "tmp", message_uid, NULL);
        data->size = ((CamelMessageInfoBase *) mi)->size;
        if (data->size > MULTI_SIZE)
                data->use_multi_fetch = TRUE;
@@ -7992,7 +8156,7 @@ imapx_server_get_message (CamelIMAPXServer *is,
        job->start = imapx_job_get_message_start;
        job->matches = imapx_job_get_message_matches;
 
-       camel_imapx_job_set_folder (job, folder);
+       camel_imapx_job_set_mailbox (job, mailbox);
 
        camel_imapx_job_set_data (
                job, data, (GDestroyNotify) get_message_data_free);
@@ -8002,9 +8166,7 @@ imapx_server_get_message (CamelIMAPXServer *is,
 
        QUEUE_UNLOCK (is);
 
-       success = registered && camel_imapx_job_run (job, is, error);
-
-       if (success)
+       if (registered && camel_imapx_job_run (job, is, error))
                stream = g_object_ref (data->stream);
 
        camel_imapx_job_unref (job);
@@ -8014,60 +8176,73 @@ imapx_server_get_message (CamelIMAPXServer *is,
 
 CamelStream *
 camel_imapx_server_get_message (CamelIMAPXServer *is,
-                                CamelFolder *folder,
-                                const gchar *uid,
+                                CamelIMAPXMailbox *mailbox,
+                                CamelFolderSummary *summary,
+                                CamelDataCache *message_cache,
+                                const gchar *message_uid,
                                 GCancellable *cancellable,
                                 GError **error)
 {
-       CamelStream *stream;
-
-       stream = imapx_server_get_message (
-               is, folder, uid,
+       g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), NULL);
+       g_return_val_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox), NULL);
+       g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), NULL);
+       g_return_val_if_fail (CAMEL_IS_DATA_CACHE (message_cache), NULL);
+       g_return_val_if_fail (message_uid != NULL, NULL);
+
+       return imapx_server_get_message (
+               is, mailbox, summary,
+               message_cache, message_uid,
                IMAPX_PRIORITY_GET_MESSAGE,
                cancellable, error);
-
-       return stream;
 }
 
 gboolean
 camel_imapx_server_sync_message (CamelIMAPXServer *is,
-                                 CamelFolder *folder,
-                                 const gchar *uid,
+                                 CamelIMAPXMailbox *mailbox,
+                                 CamelFolderSummary *summary,
+                                 CamelDataCache *message_cache,
+                                 const gchar *message_uid,
                                  GCancellable *cancellable,
                                  GError **error)
 {
        gchar *cache_file = NULL;
-       CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) folder;
-       CamelStream *stream;
        gboolean is_cached;
        struct stat st;
+       gboolean success = TRUE;
+
+       g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), FALSE);
+       g_return_val_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox), FALSE);
+       g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), FALSE);
+       g_return_val_if_fail (CAMEL_IS_DATA_CACHE (message_cache), FALSE);
+       g_return_val_if_fail (message_uid != NULL, FALSE);
 
        /* Check if the cache file already exists and is non-empty. */
        cache_file = camel_data_cache_get_filename (
-               ifolder->cache, "cur", uid);
+               message_cache, "cur", message_uid);
        is_cached = (g_stat (cache_file, &st) == 0 && st.st_size > 0);
        g_free (cache_file);
 
-       if (is_cached)
-               return TRUE;
+       if (!is_cached) {
+               CamelStream *stream;
 
-       stream = imapx_server_get_message (
-               is, folder, uid,
-               IMAPX_PRIORITY_SYNC_MESSAGE,
-               cancellable, error);
+               stream = imapx_server_get_message (
+                       is, mailbox, summary,
+                       message_cache, message_uid,
+                       IMAPX_PRIORITY_SYNC_MESSAGE,
+                       cancellable, error);
 
-       if (stream == NULL)
-               return FALSE;
+               success = (stream != NULL);
 
-       g_object_unref (stream);
+               g_clear_object (&stream);
+       }
 
-       return TRUE;
+       return success;
 }
 
 gboolean
 camel_imapx_server_copy_message (CamelIMAPXServer *is,
-                                 CamelFolder *source,
-                                 CamelFolder *dest,
+                                 CamelIMAPXMailbox *mailbox,
+                                 CamelIMAPXMailbox *destination,
                                  GPtrArray *uids,
                                  gboolean delete_originals,
                                  GCancellable *cancellable,
@@ -8077,8 +8252,13 @@ camel_imapx_server_copy_message (CamelIMAPXServer *is,
        CopyMessagesData *data;
        gint ii;
 
+       g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), FALSE);
+       g_return_val_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox), FALSE);
+       g_return_val_if_fail (CAMEL_IS_IMAPX_MAILBOX (destination), FALSE);
+       g_return_val_if_fail (uids != NULL, FALSE);
+
        data = g_slice_new0 (CopyMessagesData);
-       data->dest = g_object_ref (dest);
+       data->destination = g_object_ref (destination);
        data->uids = g_ptr_array_new ();
        data->delete_originals = delete_originals;
 
@@ -8098,7 +8278,7 @@ camel_imapx_server_copy_message (CamelIMAPXServer *is,
        job->type = IMAPX_JOB_COPY_MESSAGE;
        job->start = imapx_job_copy_messages_start;
 
-       camel_imapx_job_set_folder (job, source);
+       camel_imapx_job_set_mailbox (job, mailbox);
 
        camel_imapx_job_set_data (
                job, data, (GDestroyNotify) copy_messages_data_free);
@@ -8108,7 +8288,9 @@ camel_imapx_server_copy_message (CamelIMAPXServer *is,
 
 gboolean
 camel_imapx_server_append_message (CamelIMAPXServer *is,
-                                   CamelFolder *folder,
+                                   CamelIMAPXMailbox *mailbox,
+                                   CamelFolderSummary *summary,
+                                   CamelDataCache *message_cache,
                                    CamelMimeMessage *message,
                                    const CamelMessageInfo *mi,
                                    gchar **appended_uid,
@@ -8117,7 +8299,6 @@ camel_imapx_server_append_message (CamelIMAPXServer *is,
 {
        gchar *uid = NULL, *path = NULL;
        CamelStream *stream, *filter;
-       CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) folder;
        CamelMimeFilter *canon;
        CamelIMAPXJob *job;
        CamelMessageInfo *info;
@@ -8125,6 +8306,13 @@ camel_imapx_server_append_message (CamelIMAPXServer *is,
        gint res;
        gboolean success;
 
+       g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), FALSE);
+       g_return_val_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox), FALSE);
+       g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), FALSE);
+       g_return_val_if_fail (CAMEL_IS_DATA_CACHE (message_cache), FALSE);
+       g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), FALSE);
+       /* CamelMessageInfo can be NULL. */
+
        /* Append just assumes we have no/a dodgy connection.  We dump
         * stuff into the 'new' directory, and let the summary know it's
         * there.  Then we fire off a no-reply job which will asynchronously
@@ -8133,7 +8321,7 @@ camel_imapx_server_append_message (CamelIMAPXServer *is,
 
        /* chen cleanup this later */
        uid = imapx_get_temp_uid ();
-       stream = camel_data_cache_add (ifolder->cache, "new", uid, error);
+       stream = camel_data_cache_add (message_cache, "new", uid, error);
        if (stream == NULL) {
                g_prefix_error (error, _("Cannot create spool file: "));
                g_free (uid);
@@ -8151,15 +8339,16 @@ camel_imapx_server_append_message (CamelIMAPXServer *is,
 
        if (res == -1) {
                g_prefix_error (error, _("Cannot create spool file: "));
-               camel_data_cache_remove (ifolder->cache, "new", uid, NULL);
+               camel_data_cache_remove (message_cache, "new", uid, NULL);
                g_free (uid);
                return FALSE;
        }
 
-       path = camel_data_cache_get_filename (ifolder->cache, "new", uid);
-       info = camel_folder_summary_info_new_from_message ((CamelFolderSummary *) folder->summary, message, 
NULL);
+       path = camel_data_cache_get_filename (message_cache, "new", uid);
+       info = camel_folder_summary_info_new_from_message (
+               summary, message, NULL);
        info->uid = camel_pstring_strdup (uid);
-       if (mi) {
+       if (mi != NULL) {
                CamelMessageInfoBase *base_info = (CamelMessageInfoBase *) info;
 
                base_info->flags = camel_message_info_flags (mi);
@@ -8170,16 +8359,20 @@ camel_imapx_server_append_message (CamelIMAPXServer *is,
                        const CamelTag *tag;
 
                        flag = camel_message_info_user_flags (mi);
-                       while (flag) {
-                               if (flag->name && *flag->name)
-                                       camel_flag_set (&base_info->user_flags, flag->name, TRUE);
+                       while (flag != NULL) {
+                               if (flag->name != NULL && *flag->name != '\0')
+                                       camel_flag_set (
+                                               &base_info->user_flags,
+                                               flag->name, TRUE);
                                flag = flag->next;
                        }
 
                        tag = camel_message_info_user_tags (mi);
-                       while (tag) {
-                               if (tag->name && *tag->name)
-                                       camel_tag_set (&base_info->user_tags, tag->name, tag->value);
+                       while (tag != NULL) {
+                               if (tag->name != NULL && *tag->name != '\0')
+                                       camel_tag_set (
+                                               &base_info->user_tags,
+                                               tag->name, tag->value);
                                tag = tag->next;
                        }
                }
@@ -8203,7 +8396,7 @@ camel_imapx_server_append_message (CamelIMAPXServer *is,
        job->start = imapx_job_append_message_start;
        job->noreply = FALSE;
 
-       camel_imapx_job_set_folder (job, folder);
+       camel_imapx_job_set_mailbox (job, mailbox);
 
        camel_imapx_job_set_data (
                job, data, (GDestroyNotify) append_message_data_free);
@@ -8222,19 +8415,22 @@ camel_imapx_server_append_message (CamelIMAPXServer *is,
 
 gboolean
 camel_imapx_server_noop (CamelIMAPXServer *is,
-                         CamelFolder *folder,
+                         CamelIMAPXMailbox *mailbox,
                          GCancellable *cancellable,
                          GError **error)
 {
        CamelIMAPXJob *job;
        gboolean success;
 
+       g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), FALSE);
+       /* Mailbox may be NULL. */
+
        job = camel_imapx_job_new (cancellable);
        job->type = IMAPX_JOB_NOOP;
        job->start = imapx_job_noop_start;
        job->pri = IMAPX_PRIORITY_NOOP;
 
-       camel_imapx_job_set_folder (job, folder);
+       camel_imapx_job_set_mailbox (job, mailbox);
 
        success = imapx_submit_job (is, job, error);
 
@@ -8243,27 +8439,33 @@ camel_imapx_server_noop (CamelIMAPXServer *is,
        return success;
 }
 
-gboolean
+CamelFolderChangeInfo *
 camel_imapx_server_refresh_info (CamelIMAPXServer *is,
-                                 CamelFolder *folder,
+                                 CamelIMAPXMailbox *mailbox,
                                  GCancellable *cancellable,
                                  GError **error)
 {
        CamelIMAPXJob *job;
        RefreshInfoData *data;
+       CamelFolderChangeInfo *changes = NULL;
        gboolean registered = TRUE;
-       const gchar *full_name;
-       gboolean success = TRUE;
+       const gchar *mailbox_name;
 
-       full_name = camel_folder_get_full_name (folder);
+       g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), FALSE);
+       g_return_val_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox), FALSE);
 
        QUEUE_LOCK (is);
 
        /* Both RefreshInfo and Fetch messages can't operate simultaneously */
-       if (imapx_is_job_in_queue (is, folder, IMAPX_JOB_REFRESH_INFO, NULL) ||
-               imapx_is_job_in_queue (is, folder, IMAPX_JOB_FETCH_MESSAGES, NULL)) {
+       job = imapx_is_job_in_queue (
+               is, mailbox, IMAPX_JOB_REFRESH_INFO, NULL);
+       if (job == NULL)
+               job = imapx_is_job_in_queue (
+                       is, mailbox, IMAPX_JOB_FETCH_MESSAGES, NULL);
+
+       if (job != NULL) {
                QUEUE_UNLOCK (is);
-               return TRUE;
+               return camel_folder_change_info_new ();
        }
 
        data = g_slice_new0 (RefreshInfoData);
@@ -8275,9 +8477,11 @@ camel_imapx_server_refresh_info (CamelIMAPXServer *is,
        job->matches = imapx_job_refresh_info_matches;
        job->pri = IMAPX_PRIORITY_REFRESH_INFO;
 
-       camel_imapx_job_set_folder (job, folder);
+       camel_imapx_job_set_mailbox (job, mailbox);
 
-       if (g_ascii_strcasecmp (full_name, "INBOX") == 0)
+       mailbox_name = camel_imapx_mailbox_get_name (mailbox);
+
+       if (camel_imapx_mailbox_is_inbox (mailbox_name))
                job->pri += 10;
 
        camel_imapx_job_set_data (
@@ -8287,14 +8491,14 @@ camel_imapx_server_refresh_info (CamelIMAPXServer *is,
 
        QUEUE_UNLOCK (is);
 
-       success = registered && camel_imapx_job_run (job, is, error);
-
-       if (success && camel_folder_change_info_changed (data->changes))
-               camel_folder_changed (folder, data->changes);
+       if (registered && camel_imapx_job_run (job, is, error)) {
+               changes = data->changes;
+               data->changes = NULL;
+       }
 
        camel_imapx_job_unref (job);
 
-       return success;
+       return changes;
 }
 
 static void
@@ -8323,7 +8527,7 @@ imapx_sync_free_user (GArray *user_set)
 
 static gboolean
 imapx_server_sync_changes (CamelIMAPXServer *is,
-                           CamelFolder *folder,
+                           CamelIMAPXMailbox *mailbox,
                            guint32 job_type,
                            gint pri,
                            GCancellable *cancellable,
@@ -8332,6 +8536,7 @@ imapx_server_sync_changes (CamelIMAPXServer *is,
        guint i, on_orset, off_orset;
        GPtrArray *changed_uids;
        GArray *on_user = NULL, *off_user = NULL;
+       CamelFolder *folder;
        CamelIMAPXMessageInfo *info;
        CamelIMAPXJob *job;
        CamelIMAPXSettings *settings;
@@ -8342,6 +8547,9 @@ imapx_server_sync_changes (CamelIMAPXServer *is,
        gboolean registered;
        gboolean success = TRUE;
 
+       folder = imapx_server_ref_folder (is, mailbox);
+       g_return_val_if_fail (folder != NULL, FALSE);
+
        /* We calculate two masks, a mask of all flags which have been
         * turned off and a mask of all flags which have been turned
         * on. If either of these aren't 0, then we have work to do,
@@ -8356,6 +8564,7 @@ imapx_server_sync_changes (CamelIMAPXServer *is,
 
        if (changed_uids->len == 0) {
                camel_folder_free_uids (folder, changed_uids);
+               g_object_unref (folder);
                return TRUE;
        }
 
@@ -8480,6 +8689,7 @@ imapx_server_sync_changes (CamelIMAPXServer *is,
                imapx_sync_free_user (on_user);
                imapx_sync_free_user (off_user);
                camel_folder_free_uids (folder, changed_uids);
+               g_object_unref (folder);
                return TRUE;
        }
 
@@ -8487,7 +8697,9 @@ imapx_server_sync_changes (CamelIMAPXServer *is,
 
        QUEUE_LOCK (is);
 
-       if ((job = imapx_is_job_in_queue (is, folder, IMAPX_JOB_SYNC_CHANGES, NULL))) {
+       job = imapx_is_job_in_queue (is, mailbox, IMAPX_JOB_SYNC_CHANGES, NULL);
+
+       if (job != NULL) {
                if (pri > job->pri)
                        job->pri = pri;
 
@@ -8496,6 +8708,7 @@ imapx_server_sync_changes (CamelIMAPXServer *is,
                imapx_sync_free_user (on_user);
                imapx_sync_free_user (off_user);
                camel_folder_free_uids (folder, changed_uids);
+               g_object_unref (folder);
                return TRUE;
        }
 
@@ -8517,7 +8730,7 @@ imapx_server_sync_changes (CamelIMAPXServer *is,
        job->matches = imapx_job_sync_changes_matches;
        job->pri = pri;
 
-       camel_imapx_job_set_folder (job, folder);
+       camel_imapx_job_set_mailbox (job, mailbox);
 
        camel_imapx_job_set_data (
                job, data, (GDestroyNotify) sync_changes_data_free);
@@ -8530,17 +8743,22 @@ imapx_server_sync_changes (CamelIMAPXServer *is,
 
        camel_imapx_job_unref (job);
 
+       g_object_unref (folder);
+
        return success;
 }
 
 gboolean
 camel_imapx_server_sync_changes (CamelIMAPXServer *is,
-                                 CamelFolder *folder,
+                                 CamelIMAPXMailbox *mailbox,
                                  GCancellable *cancellable,
                                  GError **error)
 {
+       g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), FALSE);
+       g_return_val_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox), FALSE);
+
        return imapx_server_sync_changes (
-               is, folder,
+               is, mailbox,
                IMAPX_JOB_SYNC_CHANGES,
                IMAPX_PRIORITY_SYNC_CHANGES,
                cancellable, error);
@@ -8549,7 +8767,7 @@ camel_imapx_server_sync_changes (CamelIMAPXServer *is,
 /* expunge-uids? */
 gboolean
 camel_imapx_server_expunge (CamelIMAPXServer *is,
-                            CamelFolder *folder,
+                            CamelIMAPXMailbox *mailbox,
                             GCancellable *cancellable,
                             GError **error)
 {
@@ -8557,10 +8775,15 @@ camel_imapx_server_expunge (CamelIMAPXServer *is,
        gboolean registered;
        gboolean success;
 
+       g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), FALSE);
+       g_return_val_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox), FALSE);
+
        /* Do we really care to wait for this one to finish? */
        QUEUE_LOCK (is);
 
-       if (imapx_is_job_in_queue (is, folder, IMAPX_JOB_EXPUNGE, NULL)) {
+       job = imapx_is_job_in_queue (is, mailbox, IMAPX_JOB_EXPUNGE, NULL);
+
+       if (job != NULL) {
                QUEUE_UNLOCK (is);
                return TRUE;
        }
@@ -8571,7 +8794,7 @@ camel_imapx_server_expunge (CamelIMAPXServer *is,
        job->matches = imapx_job_expunge_matches;
        job->pri = IMAPX_PRIORITY_EXPUNGE;
 
-       camel_imapx_job_set_folder (job, folder);
+       camel_imapx_job_set_mailbox (job, mailbox);
 
        registered = imapx_register_job (is, job, error);
 
@@ -8596,6 +8819,9 @@ camel_imapx_server_list (CamelIMAPXServer *is,
        GPtrArray *folders = NULL;
        ListData *data;
 
+       g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), NULL);
+       g_return_val_if_fail (pattern != NULL, NULL);
+
        data = g_slice_new0 (ListData);
        data->pattern = g_strdup (pattern);
        data->flags = flags;
@@ -8640,27 +8866,28 @@ camel_imapx_server_list (CamelIMAPXServer *is,
 }
 
 gboolean
-camel_imapx_server_manage_subscription (CamelIMAPXServer *is,
-                                        const gchar *folder_name,
-                                        gboolean subscribe,
-                                        GCancellable *cancellable,
-                                        GError **error)
+camel_imapx_server_create_mailbox (CamelIMAPXServer *is,
+                                   const gchar *mailbox_name,
+                                   GCancellable *cancellable,
+                                   GError **error)
 {
        CamelIMAPXJob *job;
-       ManageSubscriptionsData *data;
+       MailboxData *data;
        gboolean success;
 
-       data = g_slice_new0 (ManageSubscriptionsData);
-       data->folder_name = g_strdup (folder_name);
-       data->subscribe = subscribe;
+       g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), FALSE);
+       g_return_val_if_fail (mailbox_name != NULL, FALSE);
+
+       data = g_slice_new0 (MailboxData);
+       data->mailbox_name = g_strdup (mailbox_name);
 
        job = camel_imapx_job_new (cancellable);
-       job->type = IMAPX_JOB_MANAGE_SUBSCRIPTION;
-       job->start = imapx_job_manage_subscription_start;
-       job->pri = IMAPX_PRIORITY_MANAGE_SUBSCRIPTION;
+       job->type = IMAPX_JOB_CREATE_MAILBOX;
+       job->start = imapx_job_create_mailbox_start;
+       job->pri = IMAPX_PRIORITY_MAILBOX_MGMT;
 
        camel_imapx_job_set_data (
-               job, data, (GDestroyNotify) manage_subscriptions_data_free);
+               job, data, (GDestroyNotify) mailbox_data_free);
 
        success = imapx_submit_job (is, job, error);
 
@@ -8670,25 +8897,31 @@ camel_imapx_server_manage_subscription (CamelIMAPXServer *is,
 }
 
 gboolean
-camel_imapx_server_create_folder (CamelIMAPXServer *is,
-                                  const gchar *folder_name,
-                                  GCancellable *cancellable,
-                                  GError **error)
+camel_imapx_server_delete_mailbox (CamelIMAPXServer *is,
+                                   CamelIMAPXMailbox *mailbox,
+                                   GCancellable *cancellable,
+                                   GError **error)
 {
        CamelIMAPXJob *job;
-       CreateFolderData *data;
+       MailboxData *data;
        gboolean success;
 
-       data = g_slice_new0 (CreateFolderData);
-       data->folder_name = g_strdup (folder_name);
+       g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), FALSE);
+       g_return_val_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox), FALSE);
+
+       /* Avoid camel_imapx_job_set_mailbox() here.  We
+        * don't want to select the mailbox to be deleted. */
+
+       data = g_slice_new0 (MailboxData);
+       data->mailbox = g_object_ref (mailbox);
 
        job = camel_imapx_job_new (cancellable);
-       job->type = IMAPX_JOB_CREATE_FOLDER;
-       job->start = imapx_job_create_folder_start;
-       job->pri = IMAPX_PRIORITY_CREATE_FOLDER;
+       job->type = IMAPX_JOB_DELETE_MAILBOX;
+       job->start = imapx_job_delete_mailbox_start;
+       job->pri = IMAPX_PRIORITY_MAILBOX_MGMT;
 
        camel_imapx_job_set_data (
-               job, data, (GDestroyNotify) create_folder_data_free);
+               job, data, (GDestroyNotify) mailbox_data_free);
 
        success = imapx_submit_job (is, job, error);
 
@@ -8698,25 +8931,102 @@ camel_imapx_server_create_folder (CamelIMAPXServer *is,
 }
 
 gboolean
-camel_imapx_server_delete_folder (CamelIMAPXServer *is,
-                                  const gchar *folder_name,
-                                  GCancellable *cancellable,
-                                  GError **error)
+camel_imapx_server_rename_mailbox (CamelIMAPXServer *is,
+                                   CamelIMAPXMailbox *mailbox,
+                                   const gchar *new_mailbox_name,
+                                   GCancellable *cancellable,
+                                   GError **error)
 {
        CamelIMAPXJob *job;
-       DeleteFolderData *data;
+       MailboxData *data;
        gboolean success;
 
-       data = g_slice_new0 (DeleteFolderData);
-       data->folder_name = g_strdup (folder_name);
+       g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), FALSE);
+       g_return_val_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox), FALSE);
+       g_return_val_if_fail (new_mailbox_name != NULL, FALSE);
+
+       /* Avoid camel_imapx_job_set_mailbox() here.  We
+        * don't want to select the mailbox to be renamed. */
+
+       data = g_slice_new0 (MailboxData);
+       data->mailbox = g_object_ref (mailbox);
+       data->mailbox_name = g_strdup (new_mailbox_name);
 
        job = camel_imapx_job_new (cancellable);
-       job->type = IMAPX_JOB_DELETE_FOLDER;
-       job->start = imapx_job_delete_folder_start;
-       job->pri = IMAPX_PRIORITY_DELETE_FOLDER;
+       job->type = IMAPX_JOB_RENAME_MAILBOX;
+       job->start = imapx_job_rename_mailbox_start;
+       job->pri = IMAPX_PRIORITY_MAILBOX_MGMT;
 
        camel_imapx_job_set_data (
-               job, data, (GDestroyNotify) delete_folder_data_free);
+               job, data, (GDestroyNotify) mailbox_data_free);
+
+       success = imapx_submit_job (is, job, error);
+
+       camel_imapx_job_unref (job);
+
+       return success;
+}
+
+gboolean
+camel_imapx_server_subscribe_mailbox (CamelIMAPXServer *is,
+                                      CamelIMAPXMailbox *mailbox,
+                                      GCancellable *cancellable,
+                                      GError **error)
+{
+       CamelIMAPXJob *job;
+       MailboxData *data;
+       gboolean success;
+
+       g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), FALSE);
+       g_return_val_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox), FALSE);
+
+       /* Avoid camel_imapx_job_set_mailbox() here.  We
+        * don't want to select the mailbox to be subscribed. */
+
+       data = g_slice_new0 (MailboxData);
+       data->mailbox = g_object_ref (mailbox);
+
+       job = camel_imapx_job_new (cancellable);
+       job->type = IMAPX_JOB_SUBSCRIBE_MAILBOX;
+       job->start = imapx_job_subscribe_mailbox_start;
+       job->pri = IMAPX_PRIORITY_MAILBOX_MGMT;
+
+       camel_imapx_job_set_data (
+               job, data, (GDestroyNotify) mailbox_data_free);
+
+       success = imapx_submit_job (is, job, error);
+
+       camel_imapx_job_unref (job);
+
+       return success;
+}
+
+gboolean
+camel_imapx_server_unsubscribe_mailbox (CamelIMAPXServer *is,
+                                        CamelIMAPXMailbox *mailbox,
+                                        GCancellable *cancellable,
+                                        GError **error)
+{
+       CamelIMAPXJob *job;
+       MailboxData *data;
+       gboolean success;
+
+       g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), FALSE);
+       g_return_val_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox), FALSE);
+
+       /* Avoid camel_imapx_job_set_mailbox() here.  We
+        * don't want to select the mailbox to be unsubscribed. */
+
+       data = g_slice_new0 (MailboxData);
+       data->mailbox = g_object_ref (mailbox);
+
+       job = camel_imapx_job_new (cancellable);
+       job->type = IMAPX_JOB_UNSUBSCRIBE_MAILBOX;
+       job->start = imapx_job_unsubscribe_mailbox_start;
+       job->pri = IMAPX_PRIORITY_MAILBOX_MGMT;
+
+       camel_imapx_job_set_data (
+               job, data, (GDestroyNotify) mailbox_data_free);
 
        success = imapx_submit_job (is, job, error);
 
@@ -8727,15 +9037,15 @@ camel_imapx_server_delete_folder (CamelIMAPXServer *is,
 
 static gboolean
 imapx_job_fetch_messages_matches (CamelIMAPXJob *job,
-                                  CamelFolder *folder,
+                                  CamelIMAPXMailbox *mailbox,
                                   const gchar *uid)
 {
-       return camel_imapx_job_has_folder (job, folder);
+       return camel_imapx_job_has_mailbox (job, mailbox);
 }
 
-gboolean
+CamelFolderChangeInfo *
 camel_imapx_server_fetch_messages (CamelIMAPXServer *is,
-                                   CamelFolder *folder,
+                                   CamelIMAPXMailbox *mailbox,
                                    CamelFetchType type,
                                    gint limit,
                                    GCancellable *cancellable,
@@ -8743,25 +9053,25 @@ camel_imapx_server_fetch_messages (CamelIMAPXServer *is,
 {
        CamelIMAPXJob *job;
        RefreshInfoData *data;
+       CamelFolderChangeInfo *changes = NULL;
        gboolean registered = TRUE;
-       const gchar *full_name;
-       gboolean success = TRUE;
-       guint64 firstuid, newfirstuid;
-       gchar *uid;
-       gint old_len;
+       const gchar *mailbox_name;
 
-       old_len = camel_folder_summary_count (folder->summary);
-       uid = camel_imapx_dup_uid_from_summary_index (folder, 0);
-       firstuid = strtoull (uid, NULL, 10);
-       g_free (uid);
+       g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), NULL);
+       g_return_val_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox), NULL);
 
        QUEUE_LOCK (is);
 
        /* Both RefreshInfo and Fetch messages can't operate simultaneously */
-       if (imapx_is_job_in_queue (is, folder, IMAPX_JOB_REFRESH_INFO, NULL) ||
-               imapx_is_job_in_queue (is, folder, IMAPX_JOB_FETCH_MESSAGES, NULL)) {
+       job = imapx_is_job_in_queue (
+               is, mailbox, IMAPX_JOB_REFRESH_INFO, NULL);
+       if (job == NULL)
+               job = imapx_is_job_in_queue (
+                       is, mailbox, IMAPX_JOB_FETCH_MESSAGES, NULL);
+
+       if (job != NULL) {
                QUEUE_UNLOCK (is);
-               return TRUE;
+               return camel_folder_change_info_new ();
        }
 
        data = g_slice_new0 (RefreshInfoData);
@@ -8775,11 +9085,11 @@ camel_imapx_server_fetch_messages (CamelIMAPXServer *is,
        job->matches = imapx_job_fetch_messages_matches;
        job->pri = IMAPX_PRIORITY_NEW_MESSAGES;
 
-       camel_imapx_job_set_folder (job, folder);
+       camel_imapx_job_set_mailbox (job, mailbox);
 
-       full_name = camel_folder_get_full_name (folder);
+       mailbox_name = camel_imapx_mailbox_get_name (mailbox);
 
-       if (g_ascii_strcasecmp (full_name, "INBOX") == 0)
+       if (camel_imapx_mailbox_is_inbox (mailbox_name))
                job->pri += 10;
 
        camel_imapx_job_set_data (
@@ -8789,68 +9099,27 @@ camel_imapx_server_fetch_messages (CamelIMAPXServer *is,
 
        QUEUE_UNLOCK (is);
 
-       success = registered && camel_imapx_job_run (job, is, error);
-
-       if (success && camel_folder_change_info_changed (data->changes))
-               camel_folder_changed (folder, data->changes);
-
-       uid = camel_imapx_dup_uid_from_summary_index (folder, 0);
-       newfirstuid = strtoull (uid, NULL, 10);
-       g_free (uid);
-
-       camel_imapx_job_unref (job);
-
-       if (type == CAMEL_FETCH_OLD_MESSAGES && firstuid == newfirstuid)
-               return FALSE; /* No more old messages */
-       else if (type == CAMEL_FETCH_NEW_MESSAGES &&
-                       old_len == camel_folder_summary_count (folder->summary))
-               return FALSE; /* No more new messages */
-
-       return TRUE;
-}
-
-gboolean
-camel_imapx_server_rename_folder (CamelIMAPXServer *is,
-                                  const gchar *old_name,
-                                  const gchar *new_name,
-                                  GCancellable *cancellable,
-                                  GError **error)
-{
-       CamelIMAPXJob *job;
-       RenameFolderData *data;
-       gboolean success;
-
-       data = g_slice_new0 (RenameFolderData);
-       data->old_folder_name = g_strdup (old_name);
-       data->new_folder_name = g_strdup (new_name);
-
-       job = camel_imapx_job_new (cancellable);
-       job->type = IMAPX_JOB_RENAME_FOLDER;
-       job->start = imapx_job_rename_folder_start;
-       job->pri = IMAPX_PRIORITY_RENAME_FOLDER;
-
-       camel_imapx_job_set_data (
-               job, data, (GDestroyNotify) rename_folder_data_free);
-
-       success = imapx_submit_job (is, job, error);
+       if (registered && camel_imapx_job_run (job, is, error)) {
+               changes = data->changes;
+               data->changes = NULL;
+       }
 
        camel_imapx_job_unref (job);
 
-       return success;
+       return changes;
 }
 
 gboolean
 camel_imapx_server_update_quota_info (CamelIMAPXServer *is,
-                                      const gchar *folder_name,
+                                      CamelIMAPXMailbox *mailbox,
                                       GCancellable *cancellable,
                                       GError **error)
 {
        CamelIMAPXJob *job;
-       QuotaData *data;
        gboolean success;
 
        g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), FALSE);
-       g_return_val_if_fail (folder_name != NULL, FALSE);
+       g_return_val_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox), FALSE);
 
        if (CAMEL_IMAPX_LACK_CAPABILITY (is->cinfo, QUOTA)) {
                g_set_error_literal (
@@ -8859,16 +9128,12 @@ camel_imapx_server_update_quota_info (CamelIMAPXServer *is,
                return FALSE;
        }
 
-       data = g_slice_new0 (QuotaData);
-       data->folder_name = g_strdup (folder_name);
-
        job = camel_imapx_job_new (cancellable);
        job->type = IMAPX_JOB_UPDATE_QUOTA_INFO;
        job->start = imapx_job_update_quota_info_start;
        job->pri = IMAPX_PRIORITY_UPDATE_QUOTA_INFO;
 
-       camel_imapx_job_set_data (
-               job, data, (GDestroyNotify) quota_data_free);
+       camel_imapx_job_set_mailbox (job, mailbox);
 
        success = imapx_submit_job (is, job, error);
 
@@ -8879,7 +9144,7 @@ camel_imapx_server_update_quota_info (CamelIMAPXServer *is,
 
 GPtrArray *
 camel_imapx_server_uid_search (CamelIMAPXServer *is,
-                               CamelFolder *folder,
+                               CamelIMAPXMailbox *mailbox,
                                const gchar *criteria,
                                GCancellable *cancellable,
                                GError **error)
@@ -8889,7 +9154,7 @@ camel_imapx_server_uid_search (CamelIMAPXServer *is,
        GPtrArray *results = NULL;
 
        g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), NULL);
-       g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL);
+       g_return_val_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox), NULL);
        g_return_val_if_fail (criteria != NULL, NULL);
 
        data = g_slice_new0 (SearchData);
@@ -8900,7 +9165,7 @@ camel_imapx_server_uid_search (CamelIMAPXServer *is,
        job->start = imapx_job_uid_search_start;
        job->pri = IMAPX_PRIORITY_SEARCH;
 
-       camel_imapx_job_set_folder (job, folder);
+       camel_imapx_job_set_mailbox (job, mailbox);
 
        camel_imapx_job_set_data (
                job, data, (GDestroyNotify) search_data_free);
diff --git a/camel/camel-imapx-server.h b/camel/camel-imapx-server.h
index c56896f..48fe293 100644
--- a/camel/camel-imapx-server.h
+++ b/camel/camel-imapx-server.h
@@ -24,6 +24,7 @@
 #ifndef CAMEL_IMAPX_SERVER_H
 #define CAMEL_IMAPX_SERVER_H
 
+#include <camel/camel-data-cache.h>
 #include <camel/camel-session.h>
 #include <camel/camel-store.h>
 
@@ -183,83 +184,95 @@ GPtrArray *       camel_imapx_server_list         (CamelIMAPXServer *is,
                                                 const gchar *ext,
                                                 GCancellable *cancellable,
                                                 GError **error);
-gboolean       camel_imapx_server_refresh_info (CamelIMAPXServer *is,
-                                                CamelFolder *folder,
+CamelFolderChangeInfo *
+               camel_imapx_server_refresh_info (CamelIMAPXServer *is,
+                                                CamelIMAPXMailbox *mailbox,
                                                 GCancellable *cancellable,
                                                 GError **error);
 gboolean       camel_imapx_server_sync_changes (CamelIMAPXServer *is,
-                                                CamelFolder *folder,
+                                                CamelIMAPXMailbox *mailbox,
                                                 GCancellable *cancellable,
                                                 GError **error);
 gboolean       camel_imapx_server_expunge      (CamelIMAPXServer *is,
-                                                CamelFolder *folder,
+                                                CamelIMAPXMailbox *mailbox,
                                                 GCancellable *cancellable,
                                                 GError **error);
-gboolean       camel_imapx_server_fetch_messages
+CamelFolderChangeInfo *
+               camel_imapx_server_fetch_messages
                                                (CamelIMAPXServer *is,
-                                                CamelFolder *folder,
+                                                CamelIMAPXMailbox *mailbox,
                                                 CamelFetchType type,
                                                 gint limit,
                                                 GCancellable *cancellable,
                                                 GError **error);
 gboolean       camel_imapx_server_noop         (CamelIMAPXServer *is,
-                                                CamelFolder *folder,
+                                                CamelIMAPXMailbox *mailbox,
                                                 GCancellable *cancellable,
                                                 GError **error);
 CamelStream *  camel_imapx_server_get_message  (CamelIMAPXServer *is,
-                                                CamelFolder *folder,
-                                                const gchar *uid,
+                                                CamelIMAPXMailbox *mailbox,
+                                                CamelFolderSummary *summary,
+                                                CamelDataCache *message_cache,
+                                                const gchar *message_uid,
                                                 GCancellable *cancellable,
                                                 GError **error);
 gboolean       camel_imapx_server_copy_message (CamelIMAPXServer *is,
-                                                CamelFolder *source,
-                                                CamelFolder *dest,
+                                                CamelIMAPXMailbox *mailbox,
+                                                CamelIMAPXMailbox *destination,
                                                 GPtrArray *uids,
                                                 gboolean delete_originals,
                                                 GCancellable *cancellable,
                                                 GError **error);
 gboolean       camel_imapx_server_append_message
                                                (CamelIMAPXServer *is,
-                                                CamelFolder *folder,
+                                                CamelIMAPXMailbox *mailbox,
+                                                CamelFolderSummary *summary,
+                                                CamelDataCache *message_cache,
                                                 CamelMimeMessage *message,
                                                 const CamelMessageInfo *mi,
                                                 gchar **append_uid,
                                                 GCancellable *cancellable,
                                                 GError **error);
 gboolean       camel_imapx_server_sync_message (CamelIMAPXServer *is,
-                                                CamelFolder *folder,
-                                                const gchar *uid,
+                                                CamelIMAPXMailbox *mailbox,
+                                                CamelFolderSummary *summary,
+                                                CamelDataCache *message_cache,
+                                                const gchar *message_uid,
                                                 GCancellable *cancellable,
                                                 GError **error);
-gboolean       camel_imapx_server_manage_subscription
+gboolean       camel_imapx_server_create_mailbox
                                                (CamelIMAPXServer *is,
-                                                const gchar *folder_name,
-                                                gboolean subscribe,
+                                                const gchar *mailbox_name,
                                                 GCancellable *cancellable,
                                                 GError **error);
-gboolean       camel_imapx_server_create_folder
+gboolean       camel_imapx_server_delete_mailbox
                                                (CamelIMAPXServer *is,
-                                                const gchar *folder_name,
+                                                CamelIMAPXMailbox *mailbox,
                                                 GCancellable *cancellable,
                                                 GError **error);
-gboolean       camel_imapx_server_delete_folder
+gboolean       camel_imapx_server_rename_mailbox
                                                (CamelIMAPXServer *is,
-                                                const gchar *folder_name,
+                                                CamelIMAPXMailbox *mailbox,
+                                                const gchar *new_mailbox_name,
                                                 GCancellable *cancellable,
                                                 GError **error);
-gboolean       camel_imapx_server_rename_folder
+gboolean       camel_imapx_server_subscribe_mailbox
                                                (CamelIMAPXServer *is,
-                                                const gchar *old_name,
-                                                const gchar *new_name,
+                                                CamelIMAPXMailbox *mailbox,
+                                                GCancellable *cancellable,
+                                                GError **error);
+gboolean       camel_imapx_server_unsubscribe_mailbox
+                                               (CamelIMAPXServer *is,
+                                                CamelIMAPXMailbox *mailbox,
                                                 GCancellable *cancellable,
                                                 GError **error);
 gboolean       camel_imapx_server_update_quota_info
                                                (CamelIMAPXServer *is,
-                                                const gchar *folder_name,
+                                                CamelIMAPXMailbox *mailbox,
                                                 GCancellable *cancellable,
                                                 GError **error);
 GPtrArray *    camel_imapx_server_uid_search   (CamelIMAPXServer *is,
-                                                CamelFolder *folder,
+                                                CamelIMAPXMailbox *mailbox,
                                                 const gchar *criteria,
                                                 GCancellable *cancellable,
                                                 GError **error);
diff --git a/camel/camel-imapx-store.c b/camel/camel-imapx-store.c
index 2e55669..1bbf98e 100644
--- a/camel/camel-imapx-store.c
+++ b/camel/camel-imapx-store.c
@@ -537,11 +537,6 @@ imapx_store_process_mailbox_status (CamelIMAPXStore *store,
 {
        CamelFolder *folder = NULL;
        const gchar *mailbox_name;
-       guint32 messages;
-       guint32 unseen;
-       guint32 uidnext;
-       guint32 uidvalidity;
-       guint64 highestmodseq;
        gchar *folder_path;
        gchar separator;
        GError *local_error = NULL;
@@ -549,12 +544,6 @@ imapx_store_process_mailbox_status (CamelIMAPXStore *store,
        mailbox_name = camel_imapx_mailbox_get_name (mailbox);
        separator = camel_imapx_mailbox_get_separator (mailbox);
 
-       messages = camel_imapx_mailbox_get_messages (mailbox);
-       unseen = camel_imapx_mailbox_get_unseen (mailbox);
-       uidnext = camel_imapx_mailbox_get_uidnext (mailbox);
-       uidvalidity = camel_imapx_mailbox_get_uidvalidity (mailbox);
-       highestmodseq = camel_imapx_mailbox_get_highestmodseq (mailbox);
-
        folder_path = camel_imapx_mailbox_to_folder_path (
                mailbox_name, separator);
 
@@ -569,15 +558,12 @@ imapx_store_process_mailbox_status (CamelIMAPXStore *store,
        if (folder != NULL) {
                CamelIMAPXFolder *imapx_folder;
                CamelIMAPXSummary *imapx_summary;
+               guint32 uidvalidity;
 
                imapx_folder = CAMEL_IMAPX_FOLDER (folder);
                imapx_summary = CAMEL_IMAPX_SUMMARY (folder->summary);
 
-               imapx_folder->exists_on_server = messages;
-               imapx_folder->unread_on_server = unseen;
-               imapx_folder->uidnext_on_server = uidnext;
-               imapx_folder->uidvalidity_on_server = uidvalidity;
-               imapx_folder->modseq_on_server = highestmodseq;
+               uidvalidity = camel_imapx_mailbox_get_uidvalidity (mailbox);
 
                if (uidvalidity > 0 && uidvalidity != imapx_summary->validity)
                        camel_imapx_folder_invalidate_local_cache (
@@ -1089,22 +1075,29 @@ fill_fi (CamelStore *store,
 
        folder = camel_object_bag_peek (store->folders, fi->full_name);
        if (folder) {
+               CamelIMAPXFolder *imapx_folder;
                CamelIMAPXSummary *ims;
+               CamelIMAPXMailbox *mailbox;
 
                if (folder->summary)
                        ims = (CamelIMAPXSummary *) folder->summary;
                else
                        ims = (CamelIMAPXSummary *) camel_imapx_summary_new (folder);
 
+               imapx_folder = CAMEL_IMAPX_FOLDER (folder);
+               mailbox = camel_imapx_folder_ref_mailbox (imapx_folder);
+
                /* Mobile clients would still love to see the total unread of actual mails
                 * than what they just have downloaded. So we override that information by giving 
                 * what the server has instead of what we have downloaded. */
-               if (mobile_mode)
-                       fi->unread = ((CamelIMAPXFolder *) folder)->unread_on_server;
+               if (mobile_mode && mailbox != NULL)
+                       fi->unread = camel_imapx_mailbox_get_unseen (mailbox);
                else
                        fi->unread = camel_folder_summary_get_unread_count ((CamelFolderSummary *) ims);
                fi->total = camel_folder_summary_get_saved_count ((CamelFolderSummary *) ims);
 
+               g_clear_object (&mailbox);
+
                if (!folder->summary)
                        g_object_unref (ims);
                g_object_unref (folder);
@@ -1177,101 +1170,6 @@ imapx_unmark_folder_subscribed (CamelIMAPXStore *imapx_store,
 }
 
 static void
-imapx_mark_folder_subscribed (CamelIMAPXStore *imapx_store,
-                              const gchar *folder_path,
-                              gboolean emit_signal)
-{
-       CamelStoreSummary *store_summary;
-       CamelStoreInfo *si;
-
-       store_summary = CAMEL_STORE_SUMMARY (imapx_store->summary);
-
-       si = camel_store_summary_path (store_summary, folder_path);
-       if (si != NULL) {
-               if ((si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) == 0) {
-                       si->flags |= CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
-                       camel_store_summary_touch (store_summary);
-                       camel_store_summary_save (store_summary);
-               }
-               camel_store_summary_info_unref (store_summary, si);
-       }
-
-       if (emit_signal) {
-               CamelFolderInfo *fi;
-
-               fi = imapx_store_build_folder_info (
-                       imapx_store, folder_path, 0);
-               camel_subscribable_folder_subscribed (
-                       CAMEL_SUBSCRIBABLE (imapx_store), fi);
-               camel_folder_info_free (fi);
-       }
-}
-
-static gboolean
-imapx_subscribe_folder (CamelStore *store,
-                        const gchar *folder_path,
-                        gboolean emit_signal,
-                        GCancellable *cancellable,
-                        GError **error)
-{
-       CamelIMAPXStore *imapx_store;
-       CamelIMAPXServer *imapx_server;
-       gboolean success = FALSE;
-
-       imapx_store = CAMEL_IMAPX_STORE (store);
-       imapx_server = camel_imapx_store_ref_server (imapx_store, error);
-
-       if (folder_path != NULL && *folder_path == '/')
-               folder_path++;
-
-       if (imapx_server != NULL) {
-               success = camel_imapx_server_manage_subscription (
-                       imapx_server, folder_path, TRUE, cancellable, error);
-       }
-
-       if (success) {
-               imapx_mark_folder_subscribed (
-                       imapx_store, folder_path, emit_signal);
-       }
-
-       g_clear_object (&imapx_server);
-
-       return success;
-}
-
-static gboolean
-imapx_unsubscribe_folder (CamelStore *store,
-                          const gchar *folder_path,
-                          gboolean emit_signal,
-                          GCancellable *cancellable,
-                          GError **error)
-{
-       CamelIMAPXStore *imapx_store;
-       CamelIMAPXServer *imapx_server;
-       gboolean success = FALSE;
-
-       imapx_store = CAMEL_IMAPX_STORE (store);
-       imapx_server = camel_imapx_store_ref_server (imapx_store, error);
-
-       if (folder_path != NULL && *folder_path == '/')
-               folder_path++;
-
-       if (imapx_server != NULL) {
-               success = camel_imapx_server_manage_subscription (
-                       imapx_server, folder_path, FALSE, cancellable, error);
-       }
-
-       if (success) {
-               imapx_unmark_folder_subscribed (
-                       imapx_store, folder_path, emit_signal);
-       }
-
-       g_clear_object (&imapx_server);
-
-       return success;
-}
-
-static void
 imapx_delete_folder_from_cache (CamelIMAPXStore *imapx_store,
                                 const gchar *folder_path)
 {
@@ -1801,26 +1699,32 @@ exit:
 }
 
 static void
-discover_inbox (CamelStore *store,
+discover_inbox (CamelIMAPXStore *imapx_store,
                 GCancellable *cancellable)
 {
-       CamelStoreInfo *si;
-       CamelIMAPXStore *imapx_store;
+       CamelIMAPXServer *imapx_server;
+       CamelIMAPXMailbox *mailbox = NULL;
+       const gchar *attribute;
 
-       imapx_store = CAMEL_IMAPX_STORE (store);
+       imapx_server = camel_imapx_store_ref_server (imapx_store, NULL);
 
-       si = camel_store_summary_path (
-               (CamelStoreSummary *) imapx_store->summary, "INBOX");
-       if (si == NULL || (si->flags & CAMEL_FOLDER_SUBSCRIBED) == 0) {
-               if (imapx_subscribe_folder (store, "INBOX", FALSE, cancellable, NULL) && !si)
-                       sync_folders (
-                               imapx_store, "INBOX",
-                               TRUE, cancellable, NULL);
+       if (imapx_server == NULL)
+               return;
+
+       mailbox = camel_imapx_server_ref_mailbox (imapx_server, "INBOX");
 
-               if (si)
-                       camel_store_summary_info_unref (
-                               (CamelStoreSummary *) imapx_store->summary, si);
+       if (mailbox == NULL)
+               goto exit;
+
+       attribute = CAMEL_IMAPX_LIST_ATTR_SUBSCRIBED;
+       if (!camel_imapx_mailbox_has_attribute (mailbox, attribute)) {
+               camel_imapx_server_subscribe_mailbox (
+                       imapx_server, mailbox, cancellable, NULL);
        }
+
+exit:
+       g_clear_object (&mailbox);
+       g_clear_object (&imapx_server);
 }
 
 static gboolean
@@ -1874,6 +1778,10 @@ imapx_store_get_folder_sync (CamelStore *store,
        gboolean use_real_junk_path = FALSE;
        gboolean use_real_trash_path = FALSE;
 
+       /* XXX This should be taken care of before we get this far. */
+       if (*folder_name == '/')
+               folder_name++;
+
        folder = get_folder_offline (store, folder_name, flags, error);
 
        /* Configure the folder flags according to IMAPX settings.
@@ -2036,7 +1944,7 @@ imapx_store_get_folder_info_sync (CamelStore *store,
 
        /* ensure the INBOX is subscribed if lsub was preferred*/
        if (initial_setup && use_subscriptions)
-               discover_inbox (store, cancellable);
+               discover_inbox (imapx_store, cancellable);
 
        fi = get_folder_info_offline (store, top, flags, error);
 
@@ -2119,15 +2027,18 @@ imapx_store_create_folder_sync (CamelStore *store,
                                 GCancellable *cancellable,
                                 GError **error)
 {
-       CamelStoreInfo *si;
-       CamelIMAPXStoreNamespace *ns;
+       CamelIMAPXNamespaceResponse *namespace_response;
+       CamelIMAPXNamespace *namespace;
        CamelIMAPXStore *imapx_store;
        CamelIMAPXServer *imapx_server;
-       gchar *mailbox;
-       gchar *child_mailbox;
-       gchar *parent_mailbox;
+       CamelFolder *folder;
+       CamelIMAPXMailbox *parent_mailbox = NULL;
        CamelFolderInfo *fi = NULL;
-       gchar dir_sep = 0;
+       GList *list;
+       const gchar *namespace_prefix;
+       const gchar *parent_mailbox_name;
+       gchar *mailbox_name = NULL;
+       gchar separator;
        gboolean success;
 
        imapx_store = CAMEL_IMAPX_STORE (store);
@@ -2136,57 +2047,74 @@ imapx_store_create_folder_sync (CamelStore *store,
        if (imapx_server == NULL)
                return NULL;
 
-       if (parent_name == NULL)
-               parent_name = "";
+       if (parent_name == NULL || *parent_name == '\0')
+               goto check_namespace;
 
-       ns = camel_imapx_store_summary_namespace_find_by_path (
-               imapx_store->summary, parent_name);
-       if (ns)
-               dir_sep = ns->sep;
+       /* Obtain the separator from the parent CamelIMAPXMailbox. */
 
-       if (!dir_sep)
-               dir_sep = '/';
+       folder = camel_store_get_folder_sync (
+               store, parent_name, 0, cancellable, error);
 
-       if (strchr (folder_name, dir_sep)) {
-               g_set_error (
-                       error, CAMEL_FOLDER_ERROR,
-                       CAMEL_FOLDER_ERROR_INVALID_PATH,
-                       _("The folder name \"%s\" is invalid because it contains the character \"%c\""),
-                       folder_name, dir_sep);
-               goto exit;
+       if (folder != NULL) {
+               parent_mailbox = camel_imapx_folder_list_mailbox (
+                       CAMEL_IMAPX_FOLDER (folder), cancellable, error);
+               g_object_unref (folder);
        }
 
-       parent_mailbox = camel_imapx_store_summary_mailbox_from_path (
-               imapx_store->summary, parent_name);
-       if (parent_mailbox == NULL) {
-               g_set_error (
-                       error, CAMEL_FOLDER_ERROR,
-                       CAMEL_FOLDER_ERROR_INVALID_STATE,
-                       _("Unknown parent folder: %s"), parent_name);
+       if (parent_mailbox == NULL)
                goto exit;
-       }
 
-       si = camel_store_summary_path (
-               (CamelStoreSummary *) imapx_store->summary, parent_name);
-       if (si && si->flags & CAMEL_STORE_INFO_FOLDER_NOINFERIORS) {
+       separator = camel_imapx_mailbox_get_separator (parent_mailbox);
+       parent_mailbox_name = camel_imapx_mailbox_get_name (parent_mailbox);
+
+       mailbox_name = g_strdup_printf (
+               "%s%c%s", parent_mailbox_name, separator, folder_name);
+
+       g_object_unref (parent_mailbox);
+
+       goto check_separator;
+
+check_namespace:
+
+       /* Obtain the separator from the first personal namespace.
+        *
+        * FIXME The CamelFolder API provides no way to specify a
+        *       namespace prefix when creating a top-level mailbox,
+        *       This needs fixed to properly support IMAP namespaces.
+        */
+
+       namespace_response = camel_imapx_server_ref_namespaces (imapx_server);
+       g_return_val_if_fail (namespace_response != NULL, NULL);
+
+       list = camel_imapx_namespace_response_list (namespace_response);
+       g_return_val_if_fail (list != NULL, NULL);
+
+       /* The namespace list is in the order received in the NAMESPACE
+        * response so the first element should be a personal namespace. */
+       namespace = CAMEL_IMAPX_NAMESPACE (list->data);
+
+       separator = camel_imapx_namespace_get_separator (namespace);
+       namespace_prefix = camel_imapx_namespace_get_prefix (namespace);
+
+       mailbox_name = g_strconcat (namespace_prefix, folder_name, NULL);
+
+       g_list_free_full (list, (GDestroyNotify) g_object_unref);
+       g_object_unref (namespace_response);
+
+check_separator:
+
+       if (strchr (folder_name, separator) != NULL) {
                g_set_error (
                        error, CAMEL_FOLDER_ERROR,
-                       CAMEL_FOLDER_ERROR_INVALID_STATE,
-                       _("The parent folder is not allowed to contain subfolders"));
+                       CAMEL_FOLDER_ERROR_INVALID_PATH,
+                       _("The folder name \"%s\" is invalid "
+                       "because it contains the character \"%c\""),
+                       folder_name, separator);
                goto exit;
        }
 
-       if (si)
-               camel_store_summary_info_unref (
-                       (CamelStoreSummary *) imapx_store->summary, si);
-
-       child_mailbox = camel_imapx_store_summary_path_to_mailbox (
-               imapx_store->summary, folder_name, dir_sep);
-       mailbox = imapx_concat (imapx_store, parent_mailbox, child_mailbox);
-       g_free (child_mailbox);
-
-       success = camel_imapx_server_create_folder (
-               imapx_server, mailbox, cancellable, error);
+       success = camel_imapx_server_create_mailbox (
+               imapx_server, mailbox_name, cancellable, error);
 
        if (success) {
                CamelStoreSummary *summary;
@@ -2196,7 +2124,7 @@ imapx_store_create_folder_sync (CamelStore *store,
                summary = CAMEL_STORE_SUMMARY (imapx_store->summary);
 
                si = camel_imapx_store_summary_add_from_mailbox (
-                       imapx_store->summary, mailbox, dir_sep);
+                       imapx_store->summary, mailbox_name, separator);
                camel_store_summary_save (summary);
                folder_path = camel_store_info_path (
                        summary, (CamelStoreInfo *) si);
@@ -2206,10 +2134,9 @@ imapx_store_create_folder_sync (CamelStore *store,
                camel_store_folder_created (store, fi);
        }
 
-       g_free (mailbox);
-       g_free (parent_mailbox);
-
 exit:
+       g_free (mailbox_name);
+
        g_clear_object (&imapx_server);
 
        return fi;
@@ -2221,22 +2148,38 @@ imapx_store_delete_folder_sync (CamelStore *store,
                                 GCancellable *cancellable,
                                 GError **error)
 {
+       CamelFolder *folder;
        CamelIMAPXStore *imapx_store;
        CamelIMAPXServer *imapx_server;
+       CamelIMAPXMailbox *mailbox = NULL;
        gboolean success = FALSE;
 
+       folder = camel_store_get_folder_sync (
+               store, folder_name, 0, cancellable, error);
+
+       if (folder == NULL)
+               return FALSE;
+
        imapx_store = CAMEL_IMAPX_STORE (store);
        imapx_server = camel_imapx_store_ref_server (imapx_store, error);
 
-       if (imapx_server != NULL) {
-               success = camel_imapx_server_delete_folder (
-                       imapx_server, folder_name, cancellable, error);
-       }
+       if (imapx_server == NULL)
+               goto exit;
 
-       if (success) {
+       mailbox = camel_imapx_folder_list_mailbox (
+               CAMEL_IMAPX_FOLDER (folder), cancellable, error);
+       if (mailbox == NULL)
+               goto exit;
+
+       success = camel_imapx_server_delete_mailbox (
+               imapx_server, mailbox, cancellable, error);
+
+       if (success)
                imapx_delete_folder_from_cache (imapx_store, folder_name);
-       }
 
+exit:
+       g_clear_object (&folder);
+       g_clear_object (&mailbox);
        g_clear_object (&imapx_server);
 
        return success;
@@ -2249,10 +2192,15 @@ imapx_store_rename_folder_sync (CamelStore *store,
                                 GCancellable *cancellable,
                                 GError **error)
 {
+       CamelFolder *folder;
        CamelService *service;
        CamelSettings *settings;
        CamelIMAPXStore *imapx_store;
        CamelIMAPXServer *imapx_server;
+       CamelIMAPXMailbox *mailbox = NULL;
+       CamelIMAPXMailbox *cloned_mailbox;
+       gchar *new_mailbox_name = NULL;
+       gchar separator;
        gboolean use_subscriptions;
        gboolean success = FALSE;
 
@@ -2269,31 +2217,60 @@ imapx_store_rename_folder_sync (CamelStore *store,
        imapx_store = CAMEL_IMAPX_STORE (store);
        imapx_server = camel_imapx_store_ref_server (imapx_store, error);
 
-       if (imapx_server != NULL) {
-               if (use_subscriptions)
-                       imapx_unsubscribe_folder (
-                               store, old, FALSE, cancellable, NULL);
+       if (imapx_server == NULL)
+               goto exit;
 
-               success = camel_imapx_server_rename_folder (
-                       imapx_server, old, new, cancellable, error);
+       folder = camel_store_get_folder_sync (
+               store, old, 0, cancellable, error);
 
-               if (!success) {
-                       imapx_subscribe_folder (
-                               store, old, FALSE, cancellable, NULL);
-                       goto exit;
-               }
+       if (folder != NULL) {
+               mailbox = camel_imapx_folder_list_mailbox (
+                       CAMEL_IMAPX_FOLDER (folder), cancellable, error);
+               g_object_unref (folder);
+       }
 
-               /* Rename summary, and handle broken server. */
-               imapx_store_rename_folder_info (imapx_store, old, new);
+       if (mailbox == NULL)
+               goto exit;
+
+       /* Assume the renamed mailbox will remain in the same namespace,
+        * and therefore use the same separator character.  XXX I'm not
+        * sure if IMAP even allows inter-namespace mailbox renames. */
+       separator = camel_imapx_mailbox_get_separator (mailbox);
+       new_mailbox_name = camel_imapx_folder_path_to_mailbox (new, separator);
 
-               if (use_subscriptions)
-                       success = imapx_subscribe_folder (
-                               store, new, FALSE, cancellable, error);
+       if (use_subscriptions)
+               camel_imapx_server_unsubscribe_mailbox (
+                       imapx_server, mailbox, cancellable, NULL);
 
-               imapx_store_rename_storage_path (imapx_store, old, new);
+       success = camel_imapx_server_rename_mailbox (
+               imapx_server, mailbox, new_mailbox_name, cancellable, error);
+
+       if (!success) {
+               camel_imapx_server_subscribe_mailbox (
+                       imapx_server, mailbox, cancellable, NULL);
+               goto exit;
        }
 
+       /* Rename summary, and handle broken server. */
+       imapx_store_rename_folder_info (imapx_store, old, new);
+       imapx_store_rename_storage_path (imapx_store, old, new);
+
+       /* Create a cloned CamelIMAPXMailbox with the new mailbox name. */
+       cloned_mailbox = camel_imapx_mailbox_clone (mailbox, new_mailbox_name);
+
+       camel_imapx_folder_set_mailbox (
+               CAMEL_IMAPX_FOLDER (folder), cloned_mailbox);
+
+       if (use_subscriptions)
+               success = camel_imapx_server_subscribe_mailbox (
+                       imapx_server, cloned_mailbox, cancellable, error);
+
+       g_clear_object (&cloned_mailbox);
+
 exit:
+       g_free (new_mailbox_name);
+
+       g_clear_object (&mailbox);
        g_clear_object (&imapx_server);
 
        return success;
@@ -2455,9 +2432,48 @@ imapx_store_subscribe_folder_sync (CamelSubscribable *subscribable,
                                    GCancellable *cancellable,
                                    GError **error)
 {
-       return imapx_subscribe_folder (
+       CamelFolder *folder;
+       CamelIMAPXStore *imapx_store;
+       CamelIMAPXServer *imapx_server;
+       CamelIMAPXMailbox *mailbox = NULL;
+       gboolean success = FALSE;
+
+       imapx_store = CAMEL_IMAPX_STORE (subscribable);
+       imapx_server = camel_imapx_store_ref_server (imapx_store, error);
+
+       if (imapx_server == NULL)
+               goto exit;
+
+       folder = camel_store_get_folder_sync (
                CAMEL_STORE (subscribable),
-               folder_name, TRUE, cancellable, error);
+               folder_name, 0, cancellable, error);
+
+       if (folder != NULL) {
+               mailbox = camel_imapx_folder_list_mailbox (
+                       CAMEL_IMAPX_FOLDER (folder), cancellable, error);
+               g_object_unref (folder);
+       }
+
+       if (mailbox == NULL)
+               goto exit;
+
+       success = camel_imapx_server_subscribe_mailbox (
+               imapx_server, mailbox, cancellable, error);
+
+       if (success) {
+               CamelFolderInfo *fi;
+
+               fi = imapx_store_build_folder_info (
+                       CAMEL_IMAPX_STORE (subscribable), folder_name, 0);
+               camel_subscribable_folder_subscribed (subscribable, fi);
+               camel_folder_info_free (fi);
+       }
+
+exit:
+       g_clear_object (&mailbox);
+       g_clear_object (&imapx_server);
+
+       return success;
 }
 
 static gboolean
@@ -2466,9 +2482,48 @@ imapx_store_unsubscribe_folder_sync (CamelSubscribable *subscribable,
                                      GCancellable *cancellable,
                                      GError **error)
 {
-       return imapx_unsubscribe_folder (
+       CamelFolder *folder;
+       CamelIMAPXStore *imapx_store;
+       CamelIMAPXServer *imapx_server;
+       CamelIMAPXMailbox *mailbox = NULL;
+       gboolean success = FALSE;
+
+       imapx_store = CAMEL_IMAPX_STORE (subscribable);
+       imapx_server = camel_imapx_store_ref_server (imapx_store, error);
+
+       if (imapx_server == NULL)
+               goto exit;
+
+       folder = camel_store_get_folder_sync (
                CAMEL_STORE (subscribable),
-               folder_name, TRUE, cancellable, error);
+               folder_name, 0, cancellable, error);
+
+       if (folder != NULL) {
+               mailbox = camel_imapx_folder_list_mailbox (
+                       CAMEL_IMAPX_FOLDER (folder), cancellable, error);
+               g_object_unref (folder);
+       }
+
+       if (mailbox == NULL)
+               goto exit;
+
+       success = camel_imapx_server_unsubscribe_mailbox (
+               imapx_server, mailbox, cancellable, error);
+
+       if (success) {
+               CamelFolderInfo *fi;
+
+               fi = imapx_store_build_folder_info (
+                       CAMEL_IMAPX_STORE (subscribable), folder_name, 0);
+               camel_subscribable_folder_unsubscribed (subscribable, fi);
+               camel_folder_info_free (fi);
+       }
+
+exit:
+       g_clear_object (&mailbox);
+       g_clear_object (&imapx_server);
+
+       return success;
 }
 
 static void
diff --git a/camel/camel-imapx-utils.c b/camel/camel-imapx-utils.c
index fcff59e..eaacc5d 100644
--- a/camel/camel-imapx-utils.c
+++ b/camel/camel-imapx-utils.c
@@ -339,14 +339,10 @@ void
 imapx_update_store_summary (CamelFolder *folder)
 {
        CamelStoreInfo *si;
-       CamelService *service;
        CamelStore *parent_store;
        CamelStoreSummary *store_summary;
-       CamelSettings *settings;
        CamelIMAPXStore *imapx_store;
-       CamelIMAPXFolder *imapx_folder;
        const gchar *full_name;
-       gboolean mobile_mode;
        guint32 total;
        guint32 unread;
 
@@ -354,16 +350,8 @@ imapx_update_store_summary (CamelFolder *folder)
 
        full_name = camel_folder_get_full_name (folder);
        parent_store = camel_folder_get_parent_store (folder);
-       service = CAMEL_SERVICE (parent_store);
-
-       settings = camel_service_ref_settings (service);
-       mobile_mode = camel_imapx_settings_get_mobile_mode (
-               CAMEL_IMAPX_SETTINGS (settings));
-       g_object_unref (settings);
 
-       imapx_folder = CAMEL_IMAPX_FOLDER (folder);
        imapx_store = CAMEL_IMAPX_STORE (parent_store);
-
        store_summary = CAMEL_STORE_SUMMARY (imapx_store->summary);
 
        si = camel_store_summary_path (store_summary, full_name);
@@ -374,12 +362,7 @@ imapx_update_store_summary (CamelFolder *folder)
        unread = camel_folder_summary_get_unread_count (folder->summary);
 
        if (si->unread != unread || si->total != total) {
-
-               /* XXX Why is this different for mobile mode? */
-               if (mobile_mode)
-                       si->unread = imapx_folder->unread_on_server;
-               else
-                       si->unread = unread;
+               si->unread = unread;
                si->total = total;
 
                camel_store_summary_touch (store_summary);
@@ -1968,7 +1951,7 @@ imapx_parse_status_copyuid (CamelIMAPXStream *is,
 
 static gboolean
 imapx_parse_status_highestmodseq (CamelIMAPXStream *is,
-                                  struct _status_info *sinfo,
+                                  CamelIMAPXMailbox *mailbox,
                                   GCancellable *cancellable,
                                   GError **error)
 {
@@ -1977,7 +1960,7 @@ imapx_parse_status_highestmodseq (CamelIMAPXStream *is,
        if (!camel_imapx_stream_number (is, &number, cancellable, error))
                return FALSE;
 
-       sinfo->u.highestmodseq = number;
+       camel_imapx_mailbox_set_highestmodseq (mailbox, number);
 
        return TRUE;
 }
@@ -2024,7 +2007,7 @@ imapx_parse_status_permanentflags (CamelIMAPXStream *is,
 
 static gboolean
 imapx_parse_status_uidnext (CamelIMAPXStream *is,
-                            struct _status_info *sinfo,
+                            CamelIMAPXMailbox *mailbox,
                             GCancellable *cancellable,
                             GError **error)
 {
@@ -2033,14 +2016,14 @@ imapx_parse_status_uidnext (CamelIMAPXStream *is,
        if (!camel_imapx_stream_number (is, &number, cancellable, error))
                return FALSE;
 
-       sinfo->u.uidnext = (guint32) number;
+       camel_imapx_mailbox_set_uidnext (mailbox, (guint32) number);
 
        return TRUE;
 }
 
 static gboolean
 imapx_parse_status_uidvalidity (CamelIMAPXStream *is,
-                                struct _status_info *sinfo,
+                                CamelIMAPXMailbox *mailbox,
                                 GCancellable *cancellable,
                                 GError **error)
 {
@@ -2049,14 +2032,14 @@ imapx_parse_status_uidvalidity (CamelIMAPXStream *is,
        if (!camel_imapx_stream_number (is, &number, cancellable, error))
                return FALSE;
 
-       sinfo->u.uidvalidity = number;
+       camel_imapx_mailbox_set_uidvalidity (mailbox, (guint32) number);
 
        return TRUE;
 }
 
 static gboolean
 imapx_parse_status_unseen (CamelIMAPXStream *is,
-                           struct _status_info *sinfo,
+                           CamelIMAPXMailbox *mailbox,
                            GCancellable *cancellable,
                            GError **error)
 {
@@ -2065,7 +2048,7 @@ imapx_parse_status_unseen (CamelIMAPXStream *is,
        if (!camel_imapx_stream_number (is, &number, cancellable, error))
                return FALSE;
 
-       sinfo->u.unseen = (guint32) number;
+       camel_imapx_mailbox_set_unseen (mailbox, (guint32) number);
 
        return TRUE;
 }
@@ -2074,6 +2057,7 @@ imapx_parse_status_unseen (CamelIMAPXStream *is,
 /* should this start after [ or before the [? token_unget anyone? */
 struct _status_info *
 imapx_parse_status (CamelIMAPXStream *is,
+                    CamelIMAPXMailbox *mailbox,
                     GCancellable *cancellable,
                     GError **error)
 {
@@ -2153,7 +2137,7 @@ imapx_parse_status (CamelIMAPXStream *is,
 
                        case IMAPX_HIGHESTMODSEQ:
                                success = imapx_parse_status_highestmodseq (
-                                       is, sinfo, cancellable, error);
+                                       is, mailbox, cancellable, error);
                                break;
 
                        case IMAPX_NEWNAME:
@@ -2168,17 +2152,17 @@ imapx_parse_status (CamelIMAPXStream *is,
 
                        case IMAPX_UIDNEXT:
                                success = imapx_parse_status_uidnext (
-                                       is, sinfo, cancellable, error);
+                                       is, mailbox, cancellable, error);
                                break;
 
                        case IMAPX_UIDVALIDITY:
                                success = imapx_parse_status_uidvalidity (
-                                       is, sinfo, cancellable, error);
+                                       is, mailbox, cancellable, error);
                                break;
 
                        case IMAPX_UNSEEN:
                                success = imapx_parse_status_unseen (
-                                       is, sinfo, cancellable, error);
+                                       is, mailbox, cancellable, error);
                                break;
 
                        /* RFC 5530 Response Codes */
@@ -2289,6 +2273,7 @@ camel_imapx_command_add_qresync_parameter (CamelIMAPXCommand *ic,
 
        CamelIMAPXFolder *imapx_folder;
        CamelIMAPXSummary *imapx_summary;
+       CamelIMAPXMailbox *mailbox;
        guint64 last_known_uidvalidity;
        guint64 last_known_modsequence;
        guint32 last_known_message_cnt;
@@ -2303,9 +2288,11 @@ camel_imapx_command_add_qresync_parameter (CamelIMAPXCommand *ic,
        imapx_folder = CAMEL_IMAPX_FOLDER (folder);
        imapx_summary = CAMEL_IMAPX_SUMMARY (folder->summary);
 
-       last_known_uidvalidity = imapx_folder->uidvalidity_on_server;
+       mailbox = camel_imapx_folder_ref_mailbox (imapx_folder);
+
+       last_known_uidvalidity = camel_imapx_mailbox_get_uidvalidity (mailbox);
        last_known_modsequence = imapx_summary->modseq;
-       last_known_message_cnt = imapx_folder->exists_on_server;
+       last_known_message_cnt = camel_imapx_mailbox_get_messages (mailbox);
 
        /* XXX This should return an unsigned integer to
         *     avoid the possibility of a negative count. */
@@ -2406,6 +2393,8 @@ camel_imapx_command_add_qresync_parameter (CamelIMAPXCommand *ic,
 exit:
        g_free (known_uid_set);
 
+       g_object_unref (mailbox);
+
        return parameter_added;
 }
 
@@ -2695,7 +2684,7 @@ gboolean
 camel_imapx_parse_quotaroot (CamelIMAPXStream *is,
                              GCancellable *cancellable,
                              gchar **out_mailbox_name,
-                             gchar ***out_quota_root_names,
+                             gchar ***out_quota_roots,
                              GError **error)
 {
        GQueue queue = G_QUEUE_INIT;
@@ -2703,12 +2692,12 @@ camel_imapx_parse_quotaroot (CamelIMAPXStream *is,
        guint len;
        guchar *token;
        gchar *mailbox_name = NULL;
-       gchar **quota_root_names = NULL;
+       gchar **quota_roots = NULL;
        gint ii = 0;
 
        g_return_val_if_fail (CAMEL_IS_IMAPX_STREAM (is), FALSE);
        g_return_val_if_fail (out_mailbox_name != NULL, FALSE);
-       g_return_val_if_fail (out_quota_root_names != NULL, FALSE);
+       g_return_val_if_fail (out_quota_roots != NULL, FALSE);
 
        /* quotaroot_response ::= "QUOTAROOT" SP astring *(SP astring) */
 
@@ -2735,12 +2724,12 @@ camel_imapx_parse_quotaroot (CamelIMAPXStream *is,
                g_queue_push_tail (&queue, g_strdup ((gchar *) token));
        }
 
-       quota_root_names = g_new0 (gchar *, queue.length + 1);
+       quota_roots = g_new0 (gchar *, queue.length + 1);
        while (!g_queue_is_empty (&queue))
-               quota_root_names[ii++] = g_queue_pop_head (&queue);
+               quota_roots[ii++] = g_queue_pop_head (&queue);
 
        *out_mailbox_name = mailbox_name;
-       *out_quota_root_names = quota_root_names;
+       *out_quota_roots = quota_roots;
 
        return TRUE;
 
diff --git a/camel/camel-imapx-utils.h b/camel/camel-imapx-utils.h
index 1ff1685..d80faff 100644
--- a/camel/camel-imapx-utils.h
+++ b/camel/camel-imapx-utils.h
@@ -25,6 +25,7 @@
 #define CAMEL_IMAPX_UTILS_H
 
 #include <camel/camel-store.h>
+#include <camel/camel-imapx-mailbox.h>
 
 G_BEGIN_DECLS
 
@@ -283,10 +284,6 @@ struct _status_info {
                        gchar *newname;
                } newname;
                guint32 permanentflags;
-               guint64 uidvalidity;
-               guint32 uidnext;
-               guint32 unseen;
-               guint64 highestmodseq;
                struct {
                        guint64 uidvalidity;
                        guint32 uid;
@@ -304,6 +301,7 @@ struct _status_info {
 
 struct _status_info *
                imapx_parse_status              (struct _CamelIMAPXStream *is,
+                                                CamelIMAPXMailbox *mailbox,
                                                 GCancellable *cancellable,
                                                 GError **error);
 struct _status_info *
@@ -342,7 +340,7 @@ gboolean    camel_imapx_parse_quota         (struct _CamelIMAPXStream *is,
 gboolean       camel_imapx_parse_quotaroot     (struct _CamelIMAPXStream *is,
                                                 GCancellable *cancellable,
                                                 gchar **out_mailbox_name,
-                                                gchar ***out_quota_root_names,
+                                                gchar ***out_quota_roots,
                                                 GError **error);
 
 /* ********************************************************************** */
diff --git a/docs/reference/camel/camel-sections.txt b/docs/reference/camel/camel-sections.txt
index fb203fe..e502e50 100644
--- a/docs/reference/camel/camel-sections.txt
+++ b/docs/reference/camel/camel-sections.txt
@@ -748,6 +748,7 @@ camel_imapx_command_check
 camel_imapx_command_compare
 camel_imapx_command_get_job
 camel_imapx_command_set_job
+camel_imapx_command_ref_mailbox
 camel_imapx_command_add
 camel_imapx_command_addv
 camel_imapx_command_add_part
@@ -814,9 +815,9 @@ camel_imapx_job_run
 camel_imapx_job_matches
 camel_imapx_job_get_data
 camel_imapx_job_set_data
-camel_imapx_job_has_folder
-camel_imapx_job_ref_folder
-camel_imapx_job_set_folder
+camel_imapx_job_has_mailbox
+camel_imapx_job_ref_mailbox
+camel_imapx_job_set_mailbox
 camel_imapx_job_get_cancellable
 camel_imapx_job_take_error
 <SUBSECTION Private>
@@ -996,10 +997,11 @@ camel_imapx_server_get_message
 camel_imapx_server_copy_message
 camel_imapx_server_append_message
 camel_imapx_server_sync_message
-camel_imapx_server_manage_subscription
-camel_imapx_server_create_folder
-camel_imapx_server_delete_folder
-camel_imapx_server_rename_folder
+camel_imapx_server_create_mailbox
+camel_imapx_server_delete_mailbox
+camel_imapx_server_rename_mailbox
+camel_imapx_server_subscribe_mailbox
+camel_imapx_server_unsubscribe_mailbox
 camel_imapx_server_update_quota_info
 camel_imapx_server_uid_search
 CamelIMAPXUntaggedRespHandlerDesc


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